Don't annotate synthetics with contexts in L8.
Change-Id: I136085726ae64b6b8af5d0939879d66c52a19001
diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
index f2959bb..d1e6951 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
@@ -366,11 +366,15 @@
new DexValueString(dexItemFactory.createString(kind.descriptor)));
DexAnnotationElement typeElement =
new DexAnnotationElement(dexItemFactory.valueString, new DexValueType(synthesizingContext));
+ DexAnnotationElement[] elements;
+ if (synthesizingContext == null) {
+ elements = new DexAnnotationElement[] {kindElement};
+ } else {
+ elements = new DexAnnotationElement[] {kindElement, typeElement};
+ }
return new DexAnnotation(
VISIBILITY_BUILD,
- new DexEncodedAnnotation(
- dexItemFactory.annotationSynthesizedClass,
- new DexAnnotationElement[] {kindElement, typeElement}));
+ new DexEncodedAnnotation(dexItemFactory.annotationSynthesizedClass, elements));
}
public static boolean hasSynthesizedClassAnnotation(
@@ -387,7 +391,8 @@
if (annotation.annotation.type != factory.annotationSynthesizedClass) {
return null;
}
- if (annotation.annotation.elements.length != 2) {
+ int length = annotation.annotation.elements.length;
+ if (length != 1 && length != 2) {
return null;
}
assert factory.kindString.isLessThan(factory.valueString);
@@ -404,6 +409,9 @@
if (kind == null) {
return null;
}
+ if (length != 2) {
+ return new Pair<>(kind, null);
+ }
DexAnnotationElement valueElement = annotation.annotation.elements[1];
if (valueElement.name != factory.valueString) {
return null;
diff --git a/src/main/java/com/android/tools/r8/synthesis/SynthesizingContext.java b/src/main/java/com/android/tools/r8/synthesis/SynthesizingContext.java
index 6a611dc..3bf8883 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SynthesizingContext.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SynthesizingContext.java
@@ -67,7 +67,6 @@
static SynthesizingContext fromSyntheticInputClass(
DexProgramClass clazz, DexType synthesizingContextType, AppView<?> appView) {
- assert synthesizingContextType != null;
// A context that is itself synthetic must denote a synthesizing context from which to ensure
// hygiene. This synthesizing context type is encoded on the synthetic for intermediate builds.
FeatureSplit featureSplit =
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
index ac15138..cbdf447 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
@@ -478,7 +478,11 @@
AppView<?> appView) {
if (shouldAnnotateSynthetics(appView.options())) {
SyntheticMarker.addMarkerToClass(
- externalSyntheticClass, kind, context, appView.dexItemFactory());
+ externalSyntheticClass,
+ kind,
+ context,
+ appView.dexItemFactory(),
+ appView.options().forceAnnotateSynthetics);
}
}
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java
index d68558d..1d9b5b9 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
+import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.Pair;
public class SyntheticMarker {
@@ -20,21 +21,23 @@
DexProgramClass clazz,
SyntheticKind kind,
SynthesizingContext context,
- DexItemFactory factory) {
+ DexItemFactory factory,
+ boolean dontRecordSynthesizingContext) {
clazz.setAnnotations(
clazz
.annotations()
.getWithAddedOrReplaced(
DexAnnotation.createAnnotationSynthesizedClass(
- kind, context.getSynthesizingContextType(), factory)));
+ kind,
+ dontRecordSynthesizingContext ? null : context.getSynthesizingContextType(),
+ factory)));
}
public static SyntheticMarker stripMarkerFromClass(DexProgramClass clazz, AppView<?> appView) {
SyntheticMarker marker = internalStripMarkerFromClass(clazz, appView);
assert marker != NO_MARKER
- || DexAnnotation.getSynthesizedClassAnnotationContextType(
- clazz.annotations(), appView.dexItemFactory())
- == null;
+ || !DexAnnotation.hasSynthesizedClassAnnotation(
+ clazz.annotations(), appView.dexItemFactory());
return marker;
}
@@ -67,6 +70,18 @@
}
}
clazz.setAnnotations(DexAnnotationSet.empty());
+ if (context == null) {
+ // If the class is marked as synthetic but has no synthesizing context, then we read the
+ // context type as the prefix. This happens for desugared library builds where the context of
+ // the generated
+ // synthetics becomes themselves. Using the original context could otherwise have referenced
+ // a type in the non-rewritten library and cause an non-rewritten output type.
+ String prefix = SyntheticNaming.getPrefixForExternalSyntheticType(kind, clazz.type);
+ context =
+ appView
+ .dexItemFactory()
+ .createType(DescriptorUtils.getDescriptorFromClassBinaryName(prefix));
+ }
return new SyntheticMarker(
kind, SynthesizingContext.fromSyntheticInputClass(clazz, context, appView));
}