Add CF attribute to compiler synthetics in intermediate mode.
Bug: 147485959
Bug: 158159959
Change-Id: If6efe30512a033fb33e09854fc76004949c8f0b8
diff --git a/src/main/java/com/android/tools/r8/dex/DexParser.java b/src/main/java/com/android/tools/r8/dex/DexParser.java
index 26bbc5e..e2b7f93 100644
--- a/src/main/java/com/android/tools/r8/dex/DexParser.java
+++ b/src/main/java/com/android/tools/r8/dex/DexParser.java
@@ -819,7 +819,8 @@
directMethods,
virtualMethods,
dexItemFactory.getSkipNameValidationForTesting(),
- checksumSupplier);
+ checksumSupplier,
+ null);
classCollection.accept(clazz); // Update the application object.
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/ClassKind.java b/src/main/java/com/android/tools/r8/graph/ClassKind.java
index baf5365..3e29db5 100644
--- a/src/main/java/com/android/tools/r8/graph/ClassKind.java
+++ b/src/main/java/com/android/tools/r8/graph/ClassKind.java
@@ -8,13 +8,56 @@
import com.android.tools.r8.graph.DexProgramClass.ChecksumSupplier;
import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.synthesis.SyntheticMarker;
import java.util.List;
import java.util.function.Predicate;
/** Kind of the application class. Can be program, classpath or library. */
public class ClassKind<C extends DexClass> {
public static ClassKind<DexProgramClass> PROGRAM =
- new ClassKind<>(DexProgramClass::new, DexClass::isProgramClass);
+ new ClassKind<>(
+ (type,
+ originKind,
+ origin,
+ accessFlags,
+ superType,
+ interfaces,
+ sourceFile,
+ nestHost,
+ nestMembers,
+ enclosingMember,
+ innerClasses,
+ classSignature,
+ classAnnotations,
+ staticFields,
+ instanceFields,
+ directMethods,
+ virtualMethods,
+ skipNameValidationForTesting,
+ checksumSupplier,
+ syntheticMarker) ->
+ new DexProgramClass(
+ type,
+ originKind,
+ origin,
+ accessFlags,
+ superType,
+ interfaces,
+ sourceFile,
+ nestHost,
+ nestMembers,
+ enclosingMember,
+ innerClasses,
+ classSignature,
+ classAnnotations,
+ staticFields,
+ instanceFields,
+ directMethods,
+ virtualMethods,
+ skipNameValidationForTesting,
+ checksumSupplier,
+ syntheticMarker),
+ DexClass::isProgramClass);
public static ClassKind<DexClasspathClass> CLASSPATH =
new ClassKind<>(
(type,
@@ -35,7 +78,8 @@
directMethods,
virtualMethods,
skipNameValidationForTesting,
- checksumSupplier) ->
+ checksumSupplier,
+ syntheticMarker) ->
new DexClasspathClass(
type,
kind,
@@ -76,7 +120,8 @@
directMethods,
virtualMethods,
skipNameValidationForTesting,
- checksumSupplier) ->
+ checksumSupplier,
+ syntheticMarker) ->
new DexLibraryClass(
type,
kind,
@@ -118,7 +163,8 @@
DexEncodedMethod[] directMethods,
DexEncodedMethod[] virtualMethods,
boolean skipNameValidationForTesting,
- ChecksumSupplier checksumSupplier);
+ ChecksumSupplier checksumSupplier,
+ SyntheticMarker syntheticMarker);
}
private final Factory<C> factory;
@@ -148,7 +194,8 @@
DexEncodedMethod[] directMethods,
DexEncodedMethod[] virtualMethods,
boolean skipNameValidationForTesting,
- ChecksumSupplier checksumSupplier) {
+ ChecksumSupplier checksumSupplier,
+ SyntheticMarker syntheticMarker) {
return factory.create(
type,
kind,
@@ -168,7 +215,8 @@
directMethods,
virtualMethods,
skipNameValidationForTesting,
- checksumSupplier);
+ checksumSupplier,
+ syntheticMarker);
}
public boolean isOfKind(DexClass clazz) {
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 d1e6951..0576326 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
@@ -359,19 +359,12 @@
}
public static DexAnnotation createAnnotationSynthesizedClass(
- SyntheticKind kind, DexType synthesizingContext, DexItemFactory dexItemFactory) {
+ SyntheticKind kind, DexItemFactory dexItemFactory) {
DexAnnotationElement kindElement =
new DexAnnotationElement(
dexItemFactory.kindString,
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};
- }
+ DexAnnotationElement[] elements = new DexAnnotationElement[] {kindElement};
return new DexAnnotation(
VISIBILITY_BUILD,
new DexEncodedAnnotation(dexItemFactory.annotationSynthesizedClass, elements));
@@ -379,10 +372,10 @@
public static boolean hasSynthesizedClassAnnotation(
DexAnnotationSet annotations, DexItemFactory factory) {
- return getSynthesizedClassAnnotationContextType(annotations, factory) != null;
+ return getSynthesizedClassAnnotationInfo(annotations, factory) != null;
}
- public static Pair<SyntheticKind, DexType> getSynthesizedClassAnnotationContextType(
+ public static SyntheticKind getSynthesizedClassAnnotationInfo(
DexAnnotationSet annotations, DexItemFactory factory) {
if (annotations.size() != 1) {
return null;
@@ -392,7 +385,7 @@
return null;
}
int length = annotation.annotation.elements.length;
- if (length != 1 && length != 2) {
+ if (length != 1) {
return null;
}
assert factory.kindString.isLessThan(factory.valueString);
@@ -406,20 +399,7 @@
SyntheticKind kind =
SyntheticNaming.SyntheticKind.fromDescriptor(
kindElement.value.asDexValueString().getValue().toString());
- 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;
- }
- if (!valueElement.value.isDexValueType()) {
- return null;
- }
- return new Pair<>(kind, valueElement.value.asDexValueType().getValue());
+ return kind;
}
public DexAnnotation rewrite(Function<DexEncodedAnnotation, DexEncodedAnnotation> rewriter) {
diff --git a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
index 1a2bc2b..315b8a1 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -19,6 +19,7 @@
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.synthesis.SyntheticMarker;
import com.android.tools.r8.utils.TraversalContinuation;
import com.android.tools.r8.utils.structural.Ordered;
import com.android.tools.r8.utils.structural.StructuralItem;
@@ -53,6 +54,8 @@
private final ChecksumSupplier checksumSupplier;
+ private SyntheticMarker syntheticMarker;
+
public DexProgramClass(
DexType type,
Kind originKind,
@@ -72,7 +75,8 @@
DexEncodedMethod[] directMethods,
DexEncodedMethod[] virtualMethods,
boolean skipNameValidationForTesting,
- ChecksumSupplier checksumSupplier) {
+ ChecksumSupplier checksumSupplier,
+ SyntheticMarker syntheticMarker) {
super(
sourceFile,
interfaces,
@@ -95,6 +99,50 @@
assert classAnnotations != null;
this.originKind = originKind;
this.checksumSupplier = checksumSupplier;
+ this.syntheticMarker = syntheticMarker;
+ }
+
+ public DexProgramClass(
+ DexType type,
+ Kind originKind,
+ Origin origin,
+ ClassAccessFlags accessFlags,
+ DexType superType,
+ DexTypeList interfaces,
+ DexString sourceFile,
+ NestHostClassAttribute nestHost,
+ List<NestMemberClassAttribute> nestMembers,
+ EnclosingMethodAttribute enclosingMember,
+ List<InnerClassAttribute> innerClasses,
+ ClassSignature classSignature,
+ DexAnnotationSet classAnnotations,
+ DexEncodedField[] staticFields,
+ DexEncodedField[] instanceFields,
+ DexEncodedMethod[] directMethods,
+ DexEncodedMethod[] virtualMethods,
+ boolean skipNameValidationForTesting,
+ ChecksumSupplier checksumSupplier) {
+ this(
+ type,
+ originKind,
+ origin,
+ accessFlags,
+ superType,
+ interfaces,
+ sourceFile,
+ nestHost,
+ nestMembers,
+ enclosingMember,
+ innerClasses,
+ classSignature,
+ classAnnotations,
+ staticFields,
+ instanceFields,
+ directMethods,
+ virtualMethods,
+ skipNameValidationForTesting,
+ checksumSupplier,
+ null);
}
@Override
@@ -120,6 +168,15 @@
return DexProgramClass::specify;
}
+ public SyntheticMarker stripSyntheticInputMarker() {
+ SyntheticMarker marker = syntheticMarker;
+ // The synthetic input marker is "read once". It is stored only for identifying the input as
+ // synthetic and amending it to the SyntheticItems collection. After identification this field
+ // should not be used.
+ syntheticMarker = null;
+ return marker;
+ }
+
private static void specify(StructuralSpecification<DexProgramClass, ?> spec) {
spec.withItem(c -> c.type)
.withItem(c -> c.superType)
diff --git a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
index 4def125..3c01abb 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -37,6 +37,7 @@
import com.android.tools.r8.jar.CfApplicationWriter;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.ProguardKeepAttributes;
+import com.android.tools.r8.synthesis.SyntheticMarker;
import com.android.tools.r8.utils.AsmUtils;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.ExceptionUtils;
@@ -58,6 +59,7 @@
import java.util.function.Consumer;
import java.util.zip.CRC32;
import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
@@ -119,6 +121,7 @@
}
reader.accept(
new CreateDexClassVisitor<>(origin, classKind, reader.b, application, classConsumer),
+ new Attribute[] {SyntheticMarker.getMarkerAttributePrototype()},
parsingOptions);
// Read marker.
@@ -219,6 +222,7 @@
private final List<DexEncodedMethod> virtualMethods = new ArrayList<>();
private final Set<Wrapper<DexMethod>> methodSignatures = new HashSet<>();
private boolean hasReachabilitySensitiveMethod = false;
+ private SyntheticMarker syntheticMarker = null;
public CreateDexClassVisitor(
Origin origin,
@@ -235,6 +239,15 @@
}
@Override
+ public void visitAttribute(Attribute attribute) {
+ SyntheticMarker marker = SyntheticMarker.readMarkerAttribute(attribute);
+ if (marker != null) {
+ assert syntheticMarker == null;
+ syntheticMarker = marker;
+ }
+ }
+
+ @Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
if (outerName != null && innerName != null) {
String separator = DescriptorUtils.computeInnerClassSeparator(outerName, name, innerName);
@@ -452,7 +465,8 @@
directMethods.toArray(DexEncodedMethod.EMPTY_ARRAY),
virtualMethods.toArray(DexEncodedMethod.EMPTY_ARRAY),
application.getFactory().getSkipNameValidationForTesting(),
- getChecksumSupplier(classKind));
+ getChecksumSupplier(classKind),
+ syntheticMarker);
InnerClassAttribute innerClassAttribute = clazz.getInnerClassAttributeForThisClass();
// A member class should not be a local or anonymous class.
if (innerClassAttribute != null && innerClassAttribute.getOuter() != null) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java
index f5845d4..e0c6d41 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java
@@ -244,7 +244,8 @@
},
virtualMethods,
factory.getSkipNameValidationForTesting(),
- DexProgramClass::checksumFromType);
+ DexProgramClass::checksumFromType,
+ null);
}
private DexEncodedMethod[] synthesizeVirtualMethodsForVivifiedTypeWrapper(
diff --git a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
index 5f23e34..0206e81 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -199,6 +199,7 @@
}
assert SyntheticNaming.verifyNotInternalSynthetic(name);
writer.visit(version.raw(), access, name, signature, superName, interfaces);
+ appView.getSyntheticItems().writeAttributeIfIntermediateSyntheticClass(writer, clazz, appView);
writeAnnotations(writer::visitAnnotation, clazz.annotations().annotations);
ImmutableMap<DexString, DexValue> defaults = getAnnotationDefaults(clazz.annotations());
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
index c81ad1c..ef3b4d2 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
@@ -160,6 +160,7 @@
directMethods.toArray(DexEncodedMethod.EMPTY_ARRAY),
virtualMethods.toArray(DexEncodedMethod.EMPTY_ARRAY),
factory.getSkipNameValidationForTesting(),
- c -> checksum);
+ c -> checksum,
+ null);
}
}
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 cbdf447..de86111 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
@@ -362,8 +362,7 @@
SyntheticMethodDefinition representative = syntheticGroup.getRepresentative();
SynthesizingContext context = representative.getContext();
context.registerPrefixRewriting(syntheticType, appView);
- addSyntheticMarker(
- representative.getKind(), representative.getHolder(), context, appView);
+ addSyntheticMarker(representative.getKind(), representative.getHolder(), appView);
if (syntheticGroup.isDerivedFromMainDexList(mainDexInfo)) {
derivedMainDexSynthetics.add(syntheticType);
}
@@ -379,8 +378,7 @@
SyntheticProgramClassDefinition representative = syntheticGroup.getRepresentative();
SynthesizingContext context = representative.getContext();
context.registerPrefixRewriting(syntheticType, appView);
- addSyntheticMarker(
- representative.getKind(), representative.getHolder(), context, appView);
+ addSyntheticMarker(representative.getKind(), representative.getHolder(), appView);
if (syntheticGroup.isDerivedFromMainDexList(mainDexInfo)) {
derivedMainDexSynthetics.add(syntheticType);
}
@@ -474,24 +472,16 @@
private static void addSyntheticMarker(
SyntheticKind kind,
DexProgramClass externalSyntheticClass,
- SynthesizingContext context,
AppView<?> appView) {
if (shouldAnnotateSynthetics(appView.options())) {
- SyntheticMarker.addMarkerToClass(
- externalSyntheticClass,
- kind,
- context,
- appView.dexItemFactory(),
- appView.options().forceAnnotateSynthetics);
+ SyntheticMarker.addMarkerToClass(externalSyntheticClass, kind, appView.options());
}
}
private static boolean shouldAnnotateSynthetics(InternalOptions options) {
// Only intermediate builds have annotated synthetics to allow later sharing.
- // This is currently also disabled on non-L8 CF to CF desugaring to avoid missing class
- // references to the annotated classes.
- // TODO(b/147485959): Find an alternative encoding for synthetics to avoid missing-class refs.
- return options.intermediate && (!options.cfToCfDesugar || options.forceAnnotateSynthetics);
+ // Also, CF builds are marked in the writer using an attribute.
+ return options.intermediate && options.isGeneratingDex();
}
private <T extends SyntheticDefinition<?, T, ?>>
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
index f709533..4fe7c2c 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
@@ -30,6 +30,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -38,6 +39,7 @@
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
+import org.objectweb.asm.ClassWriter;
public class SyntheticItems implements SyntheticDefinitionsProvider {
@@ -119,12 +121,8 @@
assert synthetics.nextSyntheticId == 0;
assert synthetics.committed.isEmpty();
assert synthetics.pending.isEmpty();
- if (appView.options().intermediate) {
- // If the compilation is in intermediate mode the synthetics should just be passed through.
- return;
- }
CommittedSyntheticsCollection.Builder builder = synthetics.committed.builder();
- // TODO(b/158159959): Consider identifying synthetics in the input reader to speed this up.
+ // TODO(b/158159959): Consider populating the input synthetics when identified.
for (DexProgramClass clazz : appView.appInfo().classes()) {
SyntheticMarker marker = SyntheticMarker.stripMarkerFromClass(clazz, appView);
if (marker.isSyntheticMethods()) {
@@ -661,6 +659,23 @@
return true;
}
+ public void writeAttributeIfIntermediateSyntheticClass(
+ ClassWriter writer, DexProgramClass clazz, AppView<?> appView) {
+ if (!appView.options().intermediate || !appView.options().isGeneratingClassFiles()) {
+ return;
+ }
+ Iterator<SyntheticReference<?, ?, ?>> it =
+ committed.getNonLegacyItems(clazz.getType()).iterator();
+ if (it.hasNext()) {
+ SyntheticKind kind = it.next().getKind();
+ // When compiling intermediates there should not be any mergings as they may invalidate the
+ // single kind of a synthetic which is required for marking synthetics. This check could be
+ // relaxed to ensure that all kinds are equivalent if merging is possible.
+ assert !it.hasNext();
+ SyntheticMarker.writeMarkerAttribute(writer, kind);
+ }
+ }
+
// Finalization of synthetic items.
Result computeFinalSynthetics(AppView<?> appView) {
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 1d9b5b9..187b7dd 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java
@@ -13,27 +13,90 @@
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;
+import com.android.tools.r8.utils.InternalOptions;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ByteVector;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
public class SyntheticMarker {
+ private static final String SYNTHETIC_MARKER_ATTRIBUTE_TYPE_NAME = "R8SynthesizedClass";
+
+ public static Attribute getMarkerAttributePrototype() {
+ return MarkerAttribute.PROTOTYPE;
+ }
+
+ public static void writeMarkerAttribute(ClassWriter writer, SyntheticKind kind) {
+ writer.visitAttribute(new MarkerAttribute(kind));
+ }
+
+ public static SyntheticMarker readMarkerAttribute(Attribute attribute) {
+ if (attribute instanceof MarkerAttribute) {
+ MarkerAttribute marker = (MarkerAttribute) attribute;
+ return new SyntheticMarker(marker.kind, null);
+ }
+ return null;
+ }
+
+ private static class MarkerAttribute extends Attribute {
+
+ private static final MarkerAttribute PROTOTYPE = new MarkerAttribute(null);
+
+ private SyntheticKind kind;
+
+ public MarkerAttribute(SyntheticKind kind) {
+ super(SYNTHETIC_MARKER_ATTRIBUTE_TYPE_NAME);
+ this.kind = kind;
+ }
+
+ @Override
+ protected Attribute read(
+ ClassReader classReader,
+ int offset,
+ int length,
+ char[] charBuffer,
+ int codeAttributeOffset,
+ Label[] labels) {
+ String kindDescriptor = classReader.readUTF8(offset, charBuffer);
+ SyntheticKind kind = SyntheticKind.fromDescriptor(kindDescriptor);
+ return new MarkerAttribute(kind);
+ }
+
+ @Override
+ protected ByteVector write(
+ ClassWriter classWriter, byte[] code, int codeLength, int maxStack, int maxLocals) {
+ ByteVector byteVector = new ByteVector();
+ byteVector.putShort(classWriter.newUTF8(kind.descriptor));
+ return byteVector;
+ }
+ }
+
public static void addMarkerToClass(
- DexProgramClass clazz,
- SyntheticKind kind,
- SynthesizingContext context,
- DexItemFactory factory,
- boolean dontRecordSynthesizingContext) {
+ DexProgramClass clazz, SyntheticKind kind, InternalOptions options) {
+ // TODO(b/158159959): Consider moving this to the dex writer similar to the CF case.
+ assert !options.isGeneratingClassFiles();
clazz.setAnnotations(
clazz
.annotations()
.getWithAddedOrReplaced(
- DexAnnotation.createAnnotationSynthesizedClass(
- kind,
- dontRecordSynthesizingContext ? null : context.getSynthesizingContextType(),
- factory)));
+ DexAnnotation.createAnnotationSynthesizedClass(kind, options.itemFactory)));
}
public static SyntheticMarker stripMarkerFromClass(DexProgramClass clazz, AppView<?> appView) {
+ if (clazz.originatesFromClassResource()) {
+ SyntheticMarker marker = clazz.stripSyntheticInputMarker();
+ if (marker == null) {
+ return NO_MARKER;
+ }
+ assert marker.getContext() == null;
+ DexType contextType =
+ getSyntheticContextType(clazz.type, marker.kind, appView.dexItemFactory());
+ SynthesizingContext context =
+ SynthesizingContext.fromSyntheticInputClass(clazz, contextType, appView);
+ return new SyntheticMarker(marker.kind, context);
+ }
SyntheticMarker marker = internalStripMarkerFromClass(clazz, appView);
assert marker != NO_MARKER
|| !DexAnnotation.hasSynthesizedClassAnnotation(
@@ -50,15 +113,13 @@
if (!flags.isSynthetic() || flags.isAbstract() || flags.isEnum()) {
return NO_MARKER;
}
- Pair<SyntheticKind, DexType> info =
- DexAnnotation.getSynthesizedClassAnnotationContextType(
+ SyntheticKind kind =
+ DexAnnotation.getSynthesizedClassAnnotationInfo(
clazz.annotations(), appView.dexItemFactory());
- if (info == null) {
+ if (kind == null) {
return NO_MARKER;
}
assert clazz.annotations().size() == 1;
- SyntheticKind kind = info.getFirst();
- DexType context = info.getSecond();
if (kind.isSingleSyntheticMethod) {
if (!clazz.interfaces.isEmpty()) {
return NO_MARKER;
@@ -70,22 +131,17 @@
}
}
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));
- }
+ DexType context = getSyntheticContextType(clazz.type, kind, appView.dexItemFactory());
return new SyntheticMarker(
kind, SynthesizingContext.fromSyntheticInputClass(clazz, context, appView));
}
+ private static DexType getSyntheticContextType(
+ DexType type, SyntheticKind kind, DexItemFactory factory) {
+ String prefix = SyntheticNaming.getPrefixForExternalSyntheticType(kind, type);
+ return factory.createType(DescriptorUtils.getDescriptorFromClassBinaryName(prefix));
+ }
+
private static final SyntheticMarker NO_MARKER = new SyntheticMarker(null, null);
private final SyntheticKind kind;
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/BackportDuplicationTest.java b/src/test/java/com/android/tools/r8/desugar/backports/BackportDuplicationTest.java
index acfc021..00d6d45 100644
--- a/src/test/java/com/android/tools/r8/desugar/backports/BackportDuplicationTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/backports/BackportDuplicationTest.java
@@ -91,9 +91,6 @@
@Test
public void testD8Merging() throws Exception {
- assumeTrue(
- "b/147485959: Merging does not happen for CF due to lack of synthetic annotations",
- parameters.isDexRuntime());
boolean intermediate = true;
runD8Merging(intermediate);
}