Reland "Parsing and emitting of modeled generic signature"
Bug: 129925954
Change-Id: I1e990244433095157cff1c31e649ef9d11111d01
diff --git a/src/main/java/com/android/tools/r8/GenerateLintFiles.java b/src/main/java/com/android/tools/r8/GenerateLintFiles.java
index 17b7485..c295175 100644
--- a/src/main/java/com/android/tools/r8/GenerateLintFiles.java
+++ b/src/main/java/com/android/tools/r8/GenerateLintFiles.java
@@ -24,6 +24,7 @@
import com.android.tools.r8.graph.DexProgramClass.ChecksumSupplier;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.LazyLoadedDexApplication;
import com.android.tools.r8.graph.ParameterAnnotationsList;
@@ -173,6 +174,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
DexEncodedField.EMPTY_ARRAY,
DexEncodedField.EMPTY_ARRAY,
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 075e0ce..9bee3f3 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -892,12 +892,14 @@
|| options.getProguardConfiguration().hasApplyMappingFile()) {
assert appView.rootSet().verifyKeptItemsAreKept(appView);
}
- assert appView
- .graphLens()
- .verifyMappingToOriginalProgram(
- appView,
- new ApplicationReader(inputApp.withoutMainDexList(), options, timing)
- .read(executorService));
+
+ assert options.testing.disableMappingToOriginalProgramVerification
+ || appView
+ .graphLens()
+ .verifyMappingToOriginalProgram(
+ appView,
+ new ApplicationReader(inputApp.withoutMainDexList(), options, timing)
+ .read(executorService));
// Report synthetic rules (only for testing).
// TODO(b/120959039): Move this to being reported through the graph consumer.
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
index b0f836c..6073b28 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -48,6 +48,7 @@
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.PredicateUtils;
import com.android.tools.r8.utils.StringDiagnostic;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.ThreadUtils;
@@ -66,6 +67,7 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
public class ApplicationWriter {
@@ -76,6 +78,7 @@
public final NamingLens namingLens;
public final InternalOptions options;
private final CodeToKeep desugaredLibraryCodeToKeep;
+ private final Predicate<DexType> isTypeMissing;
public List<Marker> markers;
public List<DexString> markerStrings;
@@ -179,6 +182,8 @@
this.namingLens = namingLens;
this.proguardMapSupplier = proguardMapSupplier;
this.programConsumer = consumer;
+ this.isTypeMissing =
+ PredicateUtils.isNull(appView.appInfo()::definitionForWithoutExistenceAssert);
}
private List<VirtualFile> distribute(ExecutorService executorService)
@@ -454,12 +459,14 @@
for (DexProgramClass clazz : appView.appInfo().classes()) {
EnclosingMethodAttribute enclosingMethod = clazz.getEnclosingMethodAttribute();
List<InnerClassAttribute> innerClasses = clazz.getInnerClasses();
- if (enclosingMethod == null && innerClasses.isEmpty()) {
+ if (enclosingMethod == null
+ && innerClasses.isEmpty()
+ && clazz.getClassSignature().hasNoSignature()) {
continue;
}
// EnclosingMember translates directly to an enclosing class/method if present.
- List<DexAnnotation> annotations = new ArrayList<>(1 + innerClasses.size());
+ List<DexAnnotation> annotations = new ArrayList<>(2 + innerClasses.size());
if (enclosingMethod != null) {
if (enclosingMethod.getEnclosingMethod() != null) {
annotations.add(
@@ -507,6 +514,13 @@
}
}
+ if (clazz.getClassSignature().hasSignature()) {
+ annotations.add(
+ DexAnnotation.createSignatureAnnotation(
+ clazz.getClassSignature().toRenamedString(namingLens, isTypeMissing),
+ options.itemFactory));
+ }
+
if (!annotations.isEmpty()) {
// Append the annotations to annotations array of the class.
DexAnnotation[] copy =
@@ -520,6 +534,7 @@
// Clear the attribute structures now that they are represented in annotations.
clazz.clearEnclosingMethodAttribute();
clazz.clearInnerClasses();
+ clazz.clearClassSignature();
}
}
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 978a7e7..711eb47 100644
--- a/src/main/java/com/android/tools/r8/dex/DexParser.java
+++ b/src/main/java/com/android/tools/r8/dex/DexParser.java
@@ -51,6 +51,8 @@
import com.android.tools.r8.graph.DexValue.DexValueNull;
import com.android.tools.r8.graph.EnclosingMethodAttribute;
import com.android.tools.r8.graph.FieldAccessFlags;
+import com.android.tools.r8.graph.GenericSignature;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.OffsetToObjectMapping;
@@ -60,6 +62,7 @@
import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Pair;
+import com.android.tools.r8.utils.Reporter;
import com.google.common.io.ByteStreams;
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
@@ -757,7 +760,8 @@
}
AttributesAndAnnotations attrs =
- new AttributesAndAnnotations(type, annotationsDirectory.clazz, options.itemFactory);
+ new AttributesAndAnnotations(
+ type, origin, annotationsDirectory.clazz, options.itemFactory, options.reporter);
Long finalChecksum = checksum;
ChecksumSupplier checksumSupplier =
@@ -776,6 +780,7 @@
Collections.emptyList(),
attrs.getEnclosingMethodAttribute(),
attrs.getInnerClasses(),
+ attrs.classSignature,
attrs.getAnnotations(),
staticFields,
instanceFields,
@@ -1327,6 +1332,7 @@
private EnclosingMethodAttribute enclosingMethodAttribute = null;
private List<InnerClassAttribute> innerClasses = null;
private List<DexAnnotation> lazyAnnotations = null;
+ private ClassSignature classSignature = ClassSignature.NO_CLASS_SIGNATURE;
public DexAnnotationSet getAnnotations() {
if (lazyAnnotations != null) {
@@ -1346,8 +1352,16 @@
return enclosingMethodAttribute;
}
+ public ClassSignature getClassSignature() {
+ return classSignature;
+ }
+
public AttributesAndAnnotations(
- DexType type, DexAnnotationSet annotations, DexItemFactory factory) {
+ DexType type,
+ Origin origin,
+ DexAnnotationSet annotations,
+ DexItemFactory factory,
+ Reporter reporter) {
this.originalAnnotations = annotations;
DexType enclosingClass = null;
DexMethod enclosingMethod = null;
@@ -1378,6 +1392,12 @@
} else {
memberClasses.addAll(members);
}
+ } else if (DexAnnotation.isSignatureAnnotation(annotation, factory)) {
+ ensureAnnotations(i);
+ String signature = DexAnnotation.getSignature(annotation);
+ classSignature =
+ GenericSignature.parseClassSignature(
+ type.getName(), signature, origin, factory, reporter);
} else {
copyAnnotation(annotation);
}
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 14fa13e..3929cfb 100644
--- a/src/main/java/com/android/tools/r8/graph/ClassKind.java
+++ b/src/main/java/com/android/tools/r8/graph/ClassKind.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.graph.DexProgramClass.ChecksumSupplier;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.origin.Origin;
import java.util.List;
import java.util.function.Consumer;
@@ -26,6 +27,7 @@
nestMembers,
enclosingMember,
innerClasses,
+ classSignature,
annotations,
staticFields,
instanceFields,
@@ -45,6 +47,7 @@
nestMembers,
enclosingMember,
innerClasses,
+ classSignature,
annotations,
staticFields,
instanceFields,
@@ -65,6 +68,7 @@
nestMembers,
enclosingMember,
innerClasses,
+ classSignature,
annotations,
staticFields,
instanceFields,
@@ -84,6 +88,7 @@
nestMembers,
enclosingMember,
innerClasses,
+ classSignature,
annotations,
staticFields,
instanceFields,
@@ -106,6 +111,7 @@
List<NestMemberClassAttribute> nestMembers,
EnclosingMethodAttribute enclosingMember,
List<InnerClassAttribute> innerClasses,
+ ClassSignature classSignature,
DexAnnotationSet annotations,
DexEncodedField[] staticFields,
DexEncodedField[] instanceFields,
@@ -135,6 +141,7 @@
List<NestMemberClassAttribute> nestMembers,
EnclosingMethodAttribute enclosingMember,
List<InnerClassAttribute> innerClasses,
+ ClassSignature classSignature,
DexAnnotationSet annotations,
DexEncodedField[] staticFields,
DexEncodedField[] instanceFields,
@@ -154,6 +161,7 @@
nestMembers,
enclosingMember,
innerClasses,
+ classSignature,
annotations,
staticFields,
instanceFields,
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index 7d18ce8..d883e3e 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.kotlin.KotlinClassLevelInfo;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.InternalOptions;
@@ -61,6 +62,9 @@
private NestHostClassAttribute nestHost;
private final List<NestMemberClassAttribute> nestMembers;
+ /** Generic signature information if the attribute is present in the input */
+ protected ClassSignature classSignature;
+
public DexClass(
DexString sourceFile,
DexTypeList interfaces,
@@ -75,6 +79,7 @@
List<NestMemberClassAttribute> nestMembers,
EnclosingMethodAttribute enclosingMethod,
List<InnerClassAttribute> innerClasses,
+ ClassSignature classSignature,
DexAnnotationSet annotations,
Origin origin,
boolean skipNameValidationForTesting) {
@@ -94,6 +99,9 @@
assert nestMembers != null;
this.enclosingMethod = enclosingMethod;
this.innerClasses = innerClasses;
+ assert classSignature != null;
+ this.classSignature = classSignature;
+ assert GenericSignatureUtils.verifyNoDuplicateGenericDefinitions(classSignature, annotations);
if (type == superType) {
throw new CompilationError("Class " + type.toString() + " cannot extend itself");
}
@@ -760,6 +768,10 @@
innerClasses.clear();
}
+ public void clearClassSignature() {
+ classSignature = ClassSignature.NO_CLASS_SIGNATURE;
+ }
+
public void removeInnerClasses(Predicate<InnerClassAttribute> predicate) {
innerClasses.removeIf(predicate::test);
}
@@ -785,6 +797,14 @@
throw new Unreachable();
}
+ public ClassSignature getClassSignature() {
+ return classSignature;
+ }
+
+ public void setClassSignature(ClassSignature classSignature) {
+ this.classSignature = classSignature;
+ }
+
public boolean isLocalClass() {
InnerClassAttribute innerClass = getInnerClassAttributeForThisClass();
// The corresponding enclosing-method attribute might be not available, e.g., CF version 50.
diff --git a/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java b/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
index 118a04d..410f985 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.kotlin.KotlinClassLevelInfo;
import com.android.tools.r8.origin.Origin;
import java.util.List;
@@ -26,6 +27,7 @@
List<NestMemberClassAttribute> nestMembers,
EnclosingMethodAttribute enclosingMember,
List<InnerClassAttribute> innerClasses,
+ ClassSignature classSignature,
DexAnnotationSet annotations,
DexEncodedField[] staticFields,
DexEncodedField[] instanceFields,
@@ -46,6 +48,7 @@
nestMembers,
enclosingMember,
innerClasses,
+ classSignature,
annotations,
origin,
skipNameValidationForTesting);
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index 00dfa0b..cdf97ab 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -62,6 +62,7 @@
public class DexItemFactory {
public static final String throwableDescriptorString = "Ljava/lang/Throwable;";
+ public static final String dalvikAnnotationSignatureString = "Ldalvik/annotation/Signature;";
/** Set of types that may be synthesized during compilation. */
private final Set<DexType> possibleCompilerSynthesizedTypes = Sets.newIdentityHashSet();
@@ -541,7 +542,7 @@
public final DexType annotationMethodParameters =
createStaticallyKnownType("Ldalvik/annotation/MethodParameters;");
public final DexType annotationSignature =
- createStaticallyKnownType("Ldalvik/annotation/Signature;");
+ createStaticallyKnownType(dalvikAnnotationSignatureString);
public final DexType annotationSourceDebugExtension =
createStaticallyKnownType("Ldalvik/annotation/SourceDebugExtension;");
public final DexType annotationThrows = createStaticallyKnownType("Ldalvik/annotation/Throws;");
diff --git a/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java b/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java
index 22920eb..dcb4ed3 100644
--- a/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.kotlin.KotlinClassLevelInfo;
import com.android.tools.r8.origin.Origin;
import java.util.Arrays;
@@ -27,6 +28,7 @@
List<NestMemberClassAttribute> nestMembers,
EnclosingMethodAttribute enclosingMember,
List<InnerClassAttribute> innerClasses,
+ ClassSignature classSignature,
DexAnnotationSet annotations,
DexEncodedField[] staticFields,
DexEncodedField[] instanceFields,
@@ -47,6 +49,7 @@
nestMembers,
enclosingMember,
innerClasses,
+ classSignature,
annotations,
origin,
skipNameValidationForTesting);
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 51959bc..e61ff61 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;
+import static com.android.tools.r8.graph.GenericSignature.EMPTY_TYPE_ARGUMENTS;
import static com.android.tools.r8.kotlin.KotlinMetadataUtils.NO_KOTLIN_INFO;
import static com.google.common.base.Predicates.alwaysTrue;
@@ -11,12 +12,15 @@
import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.GenericSignature.ClassTypeSignature;
import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
import com.android.tools.r8.kotlin.KotlinClassLevelInfo;
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.utils.TraversalContinuation;
+import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -62,6 +66,7 @@
List<NestMemberClassAttribute> nestMembers,
EnclosingMethodAttribute enclosingMember,
List<InnerClassAttribute> innerClasses,
+ ClassSignature classSignature,
DexAnnotationSet classAnnotations,
DexEncodedField[] staticFields,
DexEncodedField[] instanceFields,
@@ -81,6 +86,7 @@
nestMembers,
enclosingMember,
innerClasses,
+ classSignature,
classAnnotations,
staticFields,
instanceFields,
@@ -103,6 +109,7 @@
List<NestMemberClassAttribute> nestMembers,
EnclosingMethodAttribute enclosingMember,
List<InnerClassAttribute> innerClasses,
+ ClassSignature classSignature,
DexAnnotationSet classAnnotations,
DexEncodedField[] staticFields,
DexEncodedField[] instanceFields,
@@ -125,6 +132,7 @@
nestMembers,
enclosingMember,
innerClasses,
+ classSignature,
classAnnotations,
origin,
skipNameValidationForTesting);
@@ -283,6 +291,7 @@
for (InnerClassAttribute attribute : getInnerClasses()) {
attribute.collectIndexedItems(indexedItems);
}
+ // We are explicitly not adding items referenced in signatures.
forEachProgramField(field -> field.collectIndexedItems(indexedItems));
forEachProgramMethod(method -> method.collectIndexedItems(indexedItems, graphLens, rewriter));
}
@@ -296,6 +305,7 @@
void collectMixedSectionItems(MixedSectionCollection mixedItems) {
assert getEnclosingMethodAttribute() == null;
assert getInnerClasses().isEmpty();
+ assert !classSignature.hasSignature();
if (hasClassOrMemberAnnotations()) {
mixedItems.setAnnotationsDirectoryForClass(this, new DexAnnotationDirectory(this));
}
@@ -305,6 +315,7 @@
public void addDependencies(MixedSectionCollection collector) {
assert getEnclosingMethodAttribute() == null;
assert getInnerClasses().isEmpty();
+ assert !classSignature.hasSignature();
// We only have a class data item if there are methods or fields.
if (hasMethodsOrFields()) {
collector.add(this);
@@ -474,7 +485,7 @@
return;
}
addExtraInterfacesToInterfacesArray(extraInterfaces);
- addExtraInterfacesToSignatureAnnotationIfPresent(extraInterfaces, factory);
+ addExtraInterfacesToSignatureIfPresent(extraInterfaces);
}
private void addExtraInterfacesToInterfacesArray(List<DexType> extraInterfaces) {
@@ -486,31 +497,22 @@
interfaces = new DexTypeList(newInterfaces);
}
- private void addExtraInterfacesToSignatureAnnotationIfPresent(
- List<DexType> extraInterfaces, DexItemFactory factory) {
- // We need to introduce in the dalvik.annotation.Signature annotation the extra interfaces.
+ private void addExtraInterfacesToSignatureIfPresent(List<DexType> extraInterfaces) {
+ // We need to introduce the extra interfaces to the generic signature.
// At this point we cheat and pretend the extraInterfaces simply don't use any generic types.
- DexAnnotation[] annotations = annotations().annotations;
- for (int i = 0; i < annotations.length; i++) {
- DexAnnotation annotation = annotations[i];
- if (DexAnnotation.isSignatureAnnotation(annotation, factory)) {
- DexAnnotation[] rewrittenAnnotations = annotations.clone();
- rewrittenAnnotations[i] = rewriteSignatureAnnotation(annotation, extraInterfaces, factory);
- setAnnotations(new DexAnnotationSet(rewrittenAnnotations));
- // There is at most one signature annotation, so we can return here.
- return;
- }
+ if (classSignature.hasNoSignature() || extraInterfaces.isEmpty()) {
+ return;
}
- }
-
- private DexAnnotation rewriteSignatureAnnotation(
- DexAnnotation annotation, List<DexType> extraInterfaces, DexItemFactory factory) {
- String signature = DexAnnotation.getSignature(annotation);
- StringBuilder newSignatureBuilder = new StringBuilder(signature);
+ ImmutableList.Builder<ClassTypeSignature> interfacesBuilder =
+ ImmutableList.<ClassTypeSignature>builder().addAll(classSignature.superInterfaceSignatures);
for (DexType extraInterface : extraInterfaces) {
- newSignatureBuilder.append(extraInterface.descriptor.toString());
+ interfacesBuilder.add(new ClassTypeSignature(extraInterface, EMPTY_TYPE_ARGUMENTS));
}
- return DexAnnotation.createSignatureAnnotation(newSignatureBuilder.toString(), factory);
+ classSignature =
+ new ClassSignature(
+ classSignature.formalTypeParameters,
+ classSignature.superClassSignature,
+ interfacesBuilder.build());
}
@Override
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignature.java b/src/main/java/com/android/tools/r8/graph/GenericSignature.java
index 8ad3c8c..5cd3f8f 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignature.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignature.java
@@ -5,6 +5,7 @@
import static com.android.tools.r8.utils.DescriptorUtils.getClassBinaryNameFromDescriptor;
import static com.android.tools.r8.utils.DescriptorUtils.getDescriptorFromClassBinaryName;
+import static com.google.common.base.Predicates.alwaysTrue;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.naming.NamingLens;
@@ -15,6 +16,7 @@
import java.lang.reflect.GenericSignatureFormatError;
import java.nio.CharBuffer;
import java.util.List;
+import java.util.function.Predicate;
/**
* Internal encoding of the generics signature attribute as defined by JVMS 7 $ 4.3.4.
@@ -219,18 +221,19 @@
}
}
- public String toRenamedString(NamingLens namingLens) {
+ public String toRenamedString(NamingLens namingLens, Predicate<DexType> isTypeMissing) {
if (hasNoSignature()) {
return null;
}
- GenericSignaturePrinter genericSignaturePrinter = new GenericSignaturePrinter(namingLens);
+ GenericSignaturePrinter genericSignaturePrinter =
+ new GenericSignaturePrinter(namingLens, isTypeMissing);
genericSignaturePrinter.visitClassSignature(this);
return genericSignaturePrinter.toString();
}
@Override
public String toString() {
- return toRenamedString(NamingLens.getIdentityLens());
+ return toRenamedString(NamingLens.getIdentityLens(), alwaysTrue());
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignaturePrinter.java b/src/main/java/com/android/tools/r8/graph/GenericSignaturePrinter.java
index b671a7b..1b23c85 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignaturePrinter.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignaturePrinter.java
@@ -13,13 +13,16 @@
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.utils.DescriptorUtils;
import java.util.List;
+import java.util.function.Predicate;
public class GenericSignaturePrinter implements GenericSignatureVisitor {
private final NamingLens namingLens;
+ private final Predicate<DexType> isTypeMissing;
- public GenericSignaturePrinter(NamingLens namingLens) {
+ public GenericSignaturePrinter(NamingLens namingLens, Predicate<DexType> isTypeMissing) {
this.namingLens = namingLens;
+ this.isTypeMissing = isTypeMissing;
}
private final StringBuilder sb = new StringBuilder();
@@ -117,9 +120,14 @@
sb.append("L").append(DescriptorUtils.getBinaryNameFromDescriptor(renamedString));
} else {
assert classTypeSignature.enclosingTypeSignature != null;
- String outerDescriptor =
- namingLens.lookupDescriptor(classTypeSignature.enclosingTypeSignature.type).toString();
+ DexType enclosingType = classTypeSignature.enclosingTypeSignature.type;
+ String outerDescriptor = namingLens.lookupDescriptor(enclosingType).toString();
String innerClassName = DescriptorUtils.getInnerClassName(outerDescriptor, renamedString);
+ if (innerClassName == null && isTypeMissing.test(classTypeSignature.type)) {
+ assert renamedString.equals(classTypeSignature.type.toDescriptorString());
+ innerClassName =
+ DescriptorUtils.getInnerClassName(enclosingType.toDescriptorString(), renamedString);
+ }
if (innerClassName == null) {
// We can no longer encode the inner name in the generic signature.
return;
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java b/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java
new file mode 100644
index 0000000..ddabc37
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java
@@ -0,0 +1,241 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.graph;
+
+import static com.android.tools.r8.graph.GenericSignature.EMPTY_SUPER_INTERFACES;
+import static com.android.tools.r8.graph.GenericSignature.EMPTY_TYPE_ARGUMENTS;
+import static com.android.tools.r8.graph.GenericSignature.EMPTY_TYPE_PARAMS;
+import static com.android.tools.r8.graph.GenericSignature.NO_FIELD_TYPE_SIGNATURE;
+import static com.android.tools.r8.graph.GenericSignature.StarFieldTypeSignature.STAR_FIELD_TYPE_SIGNATURE;
+
+import com.android.tools.r8.graph.GenericSignature.ArrayTypeSignature;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.GenericSignature.ClassTypeSignature;
+import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
+import com.android.tools.r8.graph.GenericSignature.FormalTypeParameter;
+import com.android.tools.r8.graph.GenericSignature.TypeSignature;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import java.util.ArrayList;
+import java.util.List;
+
+public class GenericSignatureTypeRewriter {
+
+ private final AppView<?> appView;
+ private final DexProgramClass context;
+
+ private final FieldTypeSignature objectTypeSignature;
+
+ public GenericSignatureTypeRewriter(AppView<?> appView, DexProgramClass context) {
+ this.appView = appView;
+ this.context = context;
+ objectTypeSignature =
+ new ClassTypeSignature(appView.dexItemFactory().objectType, EMPTY_TYPE_ARGUMENTS);
+ }
+
+ public ClassSignature rewrite(ClassSignature classSignature) {
+ if (classSignature.hasNoSignature() || appView.graphLens().isIdentityLens()) {
+ return classSignature;
+ }
+ return new ClassSignatureRewriter().run(classSignature);
+ }
+
+ private class ClassSignatureRewriter implements GenericSignatureVisitor {
+
+ private final List<FormalTypeParameter> rewrittenTypeParameters = new ArrayList<>();
+ private ClassTypeSignature rewrittenSuperClass;
+ private final List<ClassTypeSignature> rewrittenSuperInterfaces = new ArrayList<>();
+
+ @Override
+ public void visitClassSignature(ClassSignature classSignature) {
+ classSignature.visit(this);
+ }
+
+ @Override
+ public void visitFormalTypeParameters(List<FormalTypeParameter> formalTypeParameters) {
+ for (FormalTypeParameter formalTypeParameter : formalTypeParameters) {
+ rewrittenTypeParameters.add(new FormalTypeParameterRewriter().run(formalTypeParameter));
+ }
+ }
+
+ @Override
+ public void visitSuperClass(ClassTypeSignature classTypeSignature) {
+ rewrittenSuperClass = new ClassTypeSignatureRewriter(true).run(classTypeSignature);
+ if (rewrittenSuperClass == null) {
+ rewrittenSuperClass =
+ new ClassTypeSignature(appView.dexItemFactory().objectType, EMPTY_TYPE_ARGUMENTS);
+ }
+ }
+
+ @Override
+ public void visitSuperInterface(ClassTypeSignature classTypeSignature) {
+ ClassTypeSignature superInterface =
+ new ClassTypeSignatureRewriter(true).run(classTypeSignature);
+ if (superInterface != null) {
+ rewrittenSuperInterfaces.add(superInterface);
+ }
+ }
+
+ private ClassSignature run(ClassSignature classSignature) {
+ classSignature.visit(this);
+ if (rewrittenTypeParameters.isEmpty()
+ && rewrittenSuperInterfaces.isEmpty()
+ && rewrittenSuperClass.isNoSignature()
+ && rewrittenSuperClass.type == appView.dexItemFactory().objectType) {
+ return ClassSignature.NO_CLASS_SIGNATURE;
+ }
+ return new ClassSignature(
+ rewrittenTypeParameters.isEmpty() ? EMPTY_TYPE_PARAMS : rewrittenTypeParameters,
+ rewrittenSuperClass,
+ rewrittenSuperInterfaces.isEmpty() ? EMPTY_SUPER_INTERFACES : rewrittenSuperInterfaces);
+ }
+ }
+
+ private class FormalTypeParameterRewriter implements GenericSignatureVisitor {
+
+ private FieldTypeSignature rewrittenClassBound = NO_FIELD_TYPE_SIGNATURE;
+ private final List<FieldTypeSignature> rewrittenInterfaceBounds = new ArrayList<>();
+
+ @Override
+ public void visitClassBound(FieldTypeSignature fieldSignature) {
+ rewrittenClassBound = new TypeSignatureRewriter().run(fieldSignature);
+ }
+
+ @Override
+ public void visitInterfaceBound(FieldTypeSignature fieldSignature) {
+ FieldTypeSignature interfaceBound = new TypeSignatureRewriter().run(fieldSignature);
+ if (interfaceBound != null) {
+ rewrittenInterfaceBounds.add(interfaceBound);
+ }
+ }
+
+ private FormalTypeParameter run(FormalTypeParameter formalTypeParameter) {
+ formalTypeParameter.visit(this);
+ // Guard against the case where we have <T::...> that is, no class or interfaces bounds.
+ if (rewrittenInterfaceBounds.isEmpty()
+ && (rewrittenClassBound == null || !rewrittenClassBound.hasSignature())) {
+ rewrittenClassBound = objectTypeSignature;
+ }
+ return new FormalTypeParameter(
+ formalTypeParameter.name,
+ rewrittenClassBound == null ? NO_FIELD_TYPE_SIGNATURE : rewrittenClassBound,
+ rewrittenInterfaceBounds.isEmpty() ? EMPTY_TYPE_ARGUMENTS : rewrittenInterfaceBounds);
+ }
+ }
+
+ private class TypeSignatureRewriter implements GenericSignatureVisitor {
+
+ private TypeSignature run(TypeSignature typeSignature) {
+ if (typeSignature.isBaseTypeSignature()) {
+ return typeSignature;
+ }
+ assert typeSignature.isFieldTypeSignature();
+ return run(typeSignature.asFieldTypeSignature());
+ }
+
+ private FieldTypeSignature run(FieldTypeSignature fieldTypeSignature) {
+ if (fieldTypeSignature.isStar()) {
+ return fieldTypeSignature;
+ }
+ if (fieldTypeSignature.isTypeVariableSignature()) {
+ return fieldTypeSignature;
+ }
+ if (fieldTypeSignature.isArrayTypeSignature()) {
+ ArrayTypeSignature arrayTypeSignature = fieldTypeSignature.asArrayTypeSignature();
+ TypeSignature rewrittenElement = run(arrayTypeSignature.elementSignature);
+ if (rewrittenElement == null) {
+ return new ArrayTypeSignature(objectTypeSignature);
+ }
+ return rewrittenElement.toArrayTypeSignature();
+ }
+ assert fieldTypeSignature.isClassTypeSignature();
+ ClassTypeSignature classTypeSignature = fieldTypeSignature.asClassTypeSignature();
+ if (classTypeSignature.isNoSignature()) {
+ return classTypeSignature;
+ }
+ return new ClassTypeSignatureRewriter(false).run(classTypeSignature);
+ }
+ }
+
+ private class ClassTypeSignatureRewriter implements GenericSignatureVisitor {
+
+ private final AppInfoWithLiveness appInfoWithLiveness;
+ private final boolean isSuperClassOrInterface;
+
+ // These fields are updated when iterating the modeled structure.
+ private DexType currentType;
+
+ // The following references are used to have a head and tail pointer to the classTypeSignature
+ // link we are building. The topClassSignature will have a reference to the top-most package
+ // and class-name. The parentClassSignature is a pointer pointing to the tail always and will
+ // be linked and updated when calling ClassTypeSignature.link.
+ private ClassTypeSignature topClassSignature;
+ private ClassTypeSignature parentClassSignature;
+
+ private ClassTypeSignatureRewriter(boolean isSuperClassOrInterface) {
+ appInfoWithLiveness =
+ appView.appInfo().hasLiveness() ? appView.appInfo().withLiveness() : null;
+ this.isSuperClassOrInterface = isSuperClassOrInterface;
+ }
+
+ @Override
+ public void visitSimpleClass(ClassTypeSignature classTypeSignature) {
+ currentType = getTarget(classTypeSignature.type);
+ if (currentType == null) {
+ return;
+ }
+ classTypeSignature.visit(this);
+ }
+
+ @Override
+ public void visitTypeArguments(List<FieldTypeSignature> typeArguments) {
+ ClassTypeSignature newClassTypeSignature;
+ if (typeArguments.isEmpty()) {
+ newClassTypeSignature = new ClassTypeSignature(currentType, EMPTY_TYPE_ARGUMENTS);
+ } else {
+ List<FieldTypeSignature> rewrittenTypeArguments = new ArrayList<>(typeArguments.size());
+ for (FieldTypeSignature typeArgument : typeArguments) {
+ if (typeArgument.isStar()) {
+ rewrittenTypeArguments.add(typeArgument);
+ continue;
+ }
+ FieldTypeSignature rewritten = new TypeSignatureRewriter().run(typeArgument);
+ if (rewritten != null) {
+ rewrittenTypeArguments.add(rewritten.asArgument(typeArgument.getWildcardIndicator()));
+ } else {
+ rewrittenTypeArguments.add(STAR_FIELD_TYPE_SIGNATURE);
+ }
+ }
+ newClassTypeSignature = new ClassTypeSignature(currentType, rewrittenTypeArguments);
+ }
+ if (topClassSignature == null) {
+ topClassSignature = newClassTypeSignature;
+ parentClassSignature = newClassTypeSignature;
+ } else {
+ ClassTypeSignature.link(parentClassSignature, newClassTypeSignature);
+ parentClassSignature = newClassTypeSignature;
+ }
+ }
+
+ private ClassTypeSignature run(ClassTypeSignature classTypeSignature) {
+ currentType = getTarget(classTypeSignature.type);
+ if (currentType == null) {
+ return null;
+ }
+ classTypeSignature.visit(this);
+ return topClassSignature;
+ }
+
+ private DexType getTarget(DexType type) {
+ if (appInfoWithLiveness != null && appInfoWithLiveness.wasPruned(type)) {
+ return null;
+ }
+ DexType rewrittenType = appView.graphLens().lookupType(type);
+ if (isSuperClassOrInterface && context.type == rewrittenType) {
+ return null;
+ }
+ return rewrittenType;
+ }
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignatureUtils.java b/src/main/java/com/android/tools/r8/graph/GenericSignatureUtils.java
new file mode 100644
index 0000000..7c0dcd2
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignatureUtils.java
@@ -0,0 +1,34 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.graph;
+
+import static com.android.tools.r8.graph.GenericSignature.ClassSignature.NO_CLASS_SIGNATURE;
+import static com.android.tools.r8.graph.GenericSignature.MethodTypeSignature.NO_METHOD_TYPE_SIGNATURE;
+import static com.android.tools.r8.graph.GenericSignature.NO_FIELD_TYPE_SIGNATURE;
+
+import com.android.tools.r8.graph.GenericSignature.DexDefinitionSignature;
+
+public class GenericSignatureUtils {
+
+ public static boolean verifyNoDuplicateGenericDefinitions(
+ DexDefinitionSignature<?> signature, DexAnnotationSet annotations) {
+ assert signature != null;
+ if (signature == NO_METHOD_TYPE_SIGNATURE
+ || signature == NO_FIELD_TYPE_SIGNATURE
+ || signature == NO_CLASS_SIGNATURE
+ || annotations == null) {
+ return true;
+ }
+ // The check is on the string descriptor to allow for not passing in a factory.
+ for (DexAnnotation annotation : annotations.annotations) {
+ assert !annotation
+ .getAnnotationType()
+ .descriptor
+ .toString()
+ .equals(DexItemFactory.dalvikAnnotationSignatureString);
+ }
+ return true;
+ }
+}
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 ea58f8d..4382eaa 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -32,6 +32,7 @@
import com.android.tools.r8.graph.DexValue.DexValueShort;
import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.graph.DexValue.DexValueType;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.jar.CfApplicationWriter;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.ProguardKeepAttributes;
@@ -206,6 +207,7 @@
private final List<NestMemberClassAttribute> nestMembers = new ArrayList<>();
private EnclosingMethodAttribute enclosingMember = null;
private final List<InnerClassAttribute> innerClasses = new ArrayList<>();
+ private ClassSignature classSignature = ClassSignature.NO_CLASS_SIGNATURE;
private List<DexAnnotation> annotations = null;
private List<DexAnnotationElement> defaultAnnotations = null;
private final List<DexEncodedField> staticFields = new ArrayList<>();
@@ -329,9 +331,9 @@
assert superName != null || name.equals(Constants.JAVA_LANG_OBJECT_NAME);
superType = superName == null ? null : application.getTypeFromName(superName);
this.interfaces = application.getTypeListFromNames(interfaces);
- if (signature != null && !signature.isEmpty()) {
- addAnnotation(DexAnnotation.createSignatureAnnotation(signature, application.getFactory()));
- }
+ classSignature =
+ GenericSignature.parseClassSignature(
+ name, signature, origin, application.getFactory(), application.options.reporter);
}
@Override
@@ -410,6 +412,7 @@
nestMembers,
enclosingMember,
innerClasses,
+ classSignature,
createAnnotationSet(annotations, application.options),
staticFields.toArray(DexEncodedField.EMPTY_ARRAY),
instanceFields.toArray(DexEncodedField.EMPTY_ARRAY),
@@ -567,8 +570,8 @@
this.desc = desc;
this.value = value;
if (signature != null && !signature.isEmpty()) {
- addAnnotation(DexAnnotation.createSignatureAnnotation(
- signature, parent.application.getFactory()));
+ addAnnotation(
+ DexAnnotation.createSignatureAnnotation(signature, parent.application.getFactory()));
}
}
@@ -648,7 +651,6 @@
private void addAnnotation(DexAnnotation annotation) {
getAnnotations().add(annotation);
}
-
private List<DexAnnotation> getAnnotations() {
if (annotations == null) {
annotations = new ArrayList<>();
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java
index db92416..ec8d495 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java
@@ -14,6 +14,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.origin.SynthesizedOrigin;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.Collections;
@@ -75,6 +76,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
DexEncodedField.EMPTY_ARRAY,
DexEncodedField.EMPTY_ARRAY,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
index 5280f61..2d4fb70 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
@@ -22,6 +22,7 @@
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ParameterAnnotationsList;
import com.android.tools.r8.graph.ResolutionResult;
@@ -111,6 +112,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
DexEncodedField.EMPTY_ARRAY,
DexEncodedField.EMPTY_ARRAY,
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 7936ffd..f2ea71d 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
@@ -25,6 +25,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.FieldAccessFlags;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ParameterAnnotationsList;
import com.android.tools.r8.ir.conversion.IRConverter;
@@ -230,6 +231,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
DexEncodedField.EMPTY_ARRAY, // No static fields.
new DexEncodedField[] {wrapperField},
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
index e58eeba..6d37c32 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
@@ -26,6 +26,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.DexValue;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
@@ -712,6 +713,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
DexEncodedField.EMPTY_ARRAY,
DexEncodedField.EMPTY_ARRAY,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
index 20c3ae4..67d389f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
@@ -26,6 +26,7 @@
import com.android.tools.r8.graph.DexProgramClass.ChecksumSupplier;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
import com.android.tools.r8.graph.MethodAccessFlags;
@@ -213,6 +214,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
DexEncodedField.EMPTY_ARRAY,
DexEncodedField.EMPTY_ARRAY,
@@ -299,6 +301,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
DexEncodedField.EMPTY_ARRAY,
DexEncodedField.EMPTY_ARRAY,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
index ecad620..cc6fec7 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -23,6 +23,7 @@
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.DexValue.DexValueNull;
import com.android.tools.r8.graph.FieldAccessFlags;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ParameterAnnotationsList;
import com.android.tools.r8.graph.ProgramMethod;
@@ -160,6 +161,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
synthesizeStaticFields(),
synthesizeInstanceFields(),
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
index 89dc96c..01b87d2 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
@@ -23,6 +23,7 @@
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.NestMemberClassAttribute;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.UseRegistry;
@@ -185,6 +186,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
DexEncodedField.EMPTY_ARRAY,
DexEncodedField.EMPTY_ARRAY,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java
index 613fac6..7b0d6b0 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java
@@ -19,6 +19,7 @@
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ParameterAnnotationsList;
import com.android.tools.r8.ir.code.IRCode;
@@ -151,6 +152,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
DexEncodedField.EMPTY_ARRAY,
DexEncodedField.EMPTY_ARRAY,
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
index 655ee2f..56d0a08 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
@@ -25,6 +25,7 @@
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ParameterAnnotationsList;
@@ -1391,7 +1392,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
- // TODO: Build dex annotations structure.
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
DexEncodedField.EMPTY_ARRAY, // Static fields.
DexEncodedField.EMPTY_ARRAY, // Instance fields.
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
index b1fcc81..7a81edc 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
@@ -18,6 +18,7 @@
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.MethodCollection;
import com.android.tools.r8.graph.ParameterAnnotationsList;
@@ -252,6 +253,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
DexEncodedField.EMPTY_ARRAY, // Static fields.
DexEncodedField.EMPTY_ARRAY, // Instance fields.
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/UnboxedEnumMemberRelocator.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/UnboxedEnumMemberRelocator.java
index 16c9118..b199c47 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/UnboxedEnumMemberRelocator.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/UnboxedEnumMemberRelocator.java
@@ -14,6 +14,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.ProgramPackage;
import com.android.tools.r8.graph.ProgramPackageCollection;
import com.android.tools.r8.origin.SynthesizedOrigin;
@@ -121,6 +122,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
DexEncodedField.EMPTY_ARRAY,
DexEncodedField.EMPTY_ARRAY,
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaGroupClassBuilder.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaGroupClassBuilder.java
index 5ddc8dd..92f0972 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaGroupClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaGroupClassBuilder.java
@@ -15,6 +15,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.EnclosingMethodAttribute;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedback;
import com.android.tools.r8.origin.SynthesizedOrigin;
@@ -50,7 +51,8 @@
Collections.emptyList(),
buildEnclosingMethodAttribute(),
buildInnerClasses(),
- buildAnnotations(),
+ buildClassSignature(),
+ DexAnnotationSet.empty(),
buildStaticFields(appView, feedback),
buildInstanceFields(),
buildDirectMethods(),
@@ -68,7 +70,7 @@
protected abstract List<InnerClassAttribute> buildInnerClasses();
- protected abstract DexAnnotationSet buildAnnotations();
+ protected abstract ClassSignature buildClassSignature();
protected abstract DexEncodedMethod[] buildVirtualMethods();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java
index 5b0b0b4..db7f56c 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java
@@ -10,7 +10,6 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.Code;
-import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -23,6 +22,8 @@
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.DexValue.DexValueNull;
import com.android.tools.r8.graph.EnclosingMethodAttribute;
+import com.android.tools.r8.graph.GenericSignature;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ParameterAnnotationsList;
@@ -33,6 +34,7 @@
import com.android.tools.r8.ir.optimize.lambda.LambdaGroupClassBuilder;
import com.android.tools.r8.ir.synthetic.SynthesizedCode;
import com.android.tools.r8.ir.synthetic.SyntheticSourceCode;
+import com.android.tools.r8.origin.SynthesizedOrigin;
import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.IntBox;
import com.android.tools.r8.utils.InternalOptions;
@@ -84,14 +86,11 @@
}
@Override
- protected DexAnnotationSet buildAnnotations() {
+ protected ClassSignature buildClassSignature() {
// Kotlin-style lambdas supported by the merged may only contain optional signature and
// kotlin metadata annotations. We remove the latter, but keep the signature if present.
- String signature = id.signature;
- return signature == null
- ? DexAnnotationSet.empty()
- : new DexAnnotationSet(
- new DexAnnotation[]{DexAnnotation.createSignatureAnnotation(signature, factory)});
+ return GenericSignature.parseClassSignature(
+ origin, id.signature, new SynthesizedOrigin(origin, getClass()), factory, options.reporter);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupIdFactory.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupIdFactory.java
index 049748f..5a90f80 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupIdFactory.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupIdFactory.java
@@ -91,9 +91,6 @@
public static boolean hasValidAnnotations(Kotlin kotlin, DexClass lambda) {
for (DexAnnotation annotation : lambda.annotations().annotations) {
- if (DexAnnotation.isSignatureAnnotation(annotation, kotlin.factory)) {
- continue;
- }
if (annotation.annotation.type == kotlin.factory.kotlinMetadataType) {
continue;
}
@@ -104,13 +101,7 @@
String validateAnnotations(AppView<AppInfoWithLiveness> appView, Kotlin kotlin, DexClass lambda)
throws LambdaStructureError {
- String signature = null;
for (DexAnnotation annotation : lambda.liveAnnotations(appView).annotations) {
- if (DexAnnotation.isSignatureAnnotation(annotation, kotlin.factory)) {
- signature = DexAnnotation.getSignature(annotation);
- continue;
- }
-
if (annotation.annotation.type == appView.dexItemFactory().kotlinMetadataType) {
// Ignore kotlin metadata on lambda classes. Metadata on synthetic
// classes exists but is not used in the current Kotlin version (1.2.21)
@@ -123,7 +114,7 @@
"unexpected annotation: " + annotation.annotation.type.toSourceString());
}
assert hasValidAnnotations(kotlin, lambda);
- return signature;
+ return lambda.getClassSignature().toString();
}
void validateStaticFields(Kotlin kotlin, DexClass lambda) throws LambdaStructureError {
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 e28734b..06e3679 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -46,11 +46,13 @@
import com.android.tools.r8.utils.AsmUtils;
import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.PredicateUtils;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Optional;
+import java.util.function.Predicate;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassTooLargeException;
@@ -79,6 +81,7 @@
private final NamingLens namingLens;
private final InternalOptions options;
private final Marker marker;
+ private final Predicate<DexType> isTypeMissing;
public final ProguardMapSupplier proguardMapSupplier;
@@ -96,6 +99,8 @@
assert marker != null;
this.marker = marker;
this.proguardMapSupplier = proguardMapSupplier;
+ this.isTypeMissing =
+ PredicateUtils.isNull(appView.appInfo()::definitionForWithoutExistenceAssert);
}
public void write(ClassFileConsumer consumer) {
@@ -179,7 +184,7 @@
}
String desc = namingLens.lookupDescriptor(clazz.type).toString();
String name = namingLens.lookupInternalName(clazz.type);
- String signature = getSignature(clazz.annotations());
+ String signature = clazz.getClassSignature().toRenamedString(namingLens, isTypeMissing);
String superName =
clazz.type == options.itemFactory.objectType
? null
diff --git a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
index 92b4402..e1a49d8 100644
--- a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
+++ b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
@@ -13,6 +13,8 @@
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.GenericSignatureTypeRewriter;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
@@ -27,7 +29,7 @@
import java.util.function.Predicate;
import java.util.function.Supplier;
-// TODO(b/129925954): Reimplement this by using the internal encoding and transformation logic.
+// TODO(b/169516860): We should generalize this to handle rewriting of attributes in general.
public class GenericSignatureRewriter {
private final AppView<?> appView;
@@ -56,17 +58,27 @@
ThreadUtils.processItems(
classes,
clazz -> {
+ GenericSignatureTypeRewriter genericSignatureTypeRewriter =
+ new GenericSignatureTypeRewriter(appView, clazz);
GenericSignatureCollector genericSignatureCollector =
new GenericSignatureCollector(clazz);
GenericSignatureParser<DexType> genericSignatureParser =
new GenericSignatureParser<>(genericSignatureCollector);
- clazz.setAnnotations(
- rewriteGenericSignatures(
- clazz.annotations(),
- genericSignatureParser::parseClassSignature,
- genericSignatureCollector::getRenamedSignature,
- (signature, e) ->
- options.warningInvalidSignature(clazz, clazz.getOrigin(), signature, e)));
+ ClassSignature classSignature = clazz.getClassSignature();
+ if (classSignature.hasSignature()) {
+ // TODO(b/129925954): We still have to rewrite to capture the lastWrittenType.
+ // The design is utterly broken.
+ DexAnnotation classSignatureAnnotation =
+ DexAnnotation.createSignatureAnnotation(
+ classSignature.toString(), options.itemFactory);
+ rewriteGenericSignatures(
+ new DexAnnotationSet(new DexAnnotation[] {classSignatureAnnotation}),
+ genericSignatureParser::parseClassSignature,
+ genericSignatureCollector::getRenamedSignature,
+ (signature, e) ->
+ options.warningInvalidSignature(clazz, clazz.getOrigin(), signature, e));
+ }
+ clazz.setClassSignature(genericSignatureTypeRewriter.rewrite(classSignature));
clazz.forEachField(
field ->
field.setAnnotations(
@@ -91,6 +103,7 @@
executorService);
}
+ // TODO(b/129925954): Remove this when using modeled signatures for methods and fields.
private DexAnnotationSet rewriteGenericSignatures(
DexAnnotationSet annotations,
Consumer<String> parser,
diff --git a/src/main/java/com/android/tools/r8/repackaging/RepackagingTreeFixer.java b/src/main/java/com/android/tools/r8/repackaging/RepackagingTreeFixer.java
index f519f01..6bde745 100644
--- a/src/main/java/com/android/tools/r8/repackaging/RepackagingTreeFixer.java
+++ b/src/main/java/com/android/tools/r8/repackaging/RepackagingTreeFixer.java
@@ -73,6 +73,7 @@
fixupNestMemberAttributes(clazz.getNestMembersClassAttributes()),
fixupEnclosingMethodAttribute(clazz.getEnclosingMethodAttribute()),
fixupInnerClassAttributes(clazz.getInnerClasses()),
+ clazz.getClassSignature(),
clazz.annotations(),
DexEncodedField.EMPTY_ARRAY,
DexEncodedField.EMPTY_ARRAY,
diff --git a/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java b/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
index 5ae46e8..4fa3212 100644
--- a/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
+++ b/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
@@ -83,6 +83,9 @@
assert !DexAnnotation.isMemberClassesAnnotation(annotation, dexItemFactory);
assert !DexAnnotation.isEnclosingMethodAnnotation(annotation, dexItemFactory);
assert !DexAnnotation.isEnclosingClassAnnotation(annotation, dexItemFactory);
+ // TODO(b/129925954): Signature is being represented as a class attribute.
+ assert !holder.isDexClass()
+ || !DexAnnotation.isSignatureAnnotation(annotation, dexItemFactory);
if (config.exceptions && DexAnnotation.isThrowingAnnotation(annotation, dexItemFactory)) {
return true;
}
@@ -184,15 +187,6 @@
}
}
- private static boolean hasSignatureAnnotation(DexProgramClass clazz, DexItemFactory itemFactory) {
- for (DexAnnotation annotation : clazz.annotations().annotations) {
- if (DexAnnotation.isSignatureAnnotation(annotation, itemFactory)) {
- return true;
- }
- }
- return false;
- }
-
public void run() {
for (DexProgramClass clazz : appView.appInfo().classes()) {
stripAttributes(clazz);
@@ -291,6 +285,9 @@
hasInnerClassesFromSet(clazz, classesToRetainInnerClassAttributeFor);
}
if (keptAnyway || keepForThisInnerClass || keepForThisEnclosingClass) {
+ if (!keep.signature) {
+ clazz.clearClassSignature();
+ }
if (!keep.enclosingMethod) {
clazz.clearEnclosingMethodAttribute();
}
@@ -325,6 +322,7 @@
// reflection. (Note that clearing these attributes can enable more vertical class merging.)
clazz.clearEnclosingMethodAttribute();
clazz.clearInnerClasses();
+ clazz.clearClassSignature();
}
}
@@ -368,7 +366,7 @@
Map<DexType, DexProgramClass> enclosingClasses = new IdentityHashMap<>();
Set<DexProgramClass> genericClasses = Sets.newIdentityHashSet();
for (DexProgramClass clazz : appView.appInfo().classes()) {
- if (hasSignatureAnnotation(clazz, appView.dexItemFactory())) {
+ if (clazz.getClassSignature().hasSignature()) {
genericClasses.add(clazz);
}
for (InnerClassAttribute innerClassAttribute : clazz.getInnerClasses()) {
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 1091d09..80c47f2 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
@@ -15,6 +15,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.EnclosingMethodAttribute;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.graph.NestHostClassAttribute;
import com.android.tools.r8.graph.NestMemberClassAttribute;
@@ -71,7 +72,6 @@
List<NestMemberClassAttribute> nestMembers = Collections.emptyList();
EnclosingMethodAttribute enclosingMembers = null;
List<InnerClassAttribute> innerClasses = Collections.emptyList();
- DexAnnotationSet classAnnotations = DexAnnotationSet.empty();
DexEncodedField[] staticFields = DexEncodedField.EMPTY_ARRAY;
DexEncodedField[] instanceFields = DexEncodedField.EMPTY_ARRAY;
DexEncodedMethod[] directMethods = DexEncodedMethod.EMPTY_ARRAY;
@@ -106,7 +106,8 @@
nestMembers,
enclosingMembers,
innerClasses,
- classAnnotations,
+ ClassSignature.NO_CLASS_SIGNATURE,
+ DexAnnotationSet.empty(),
staticFields,
instanceFields,
directMethods,
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index af11559..091325a 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -1280,6 +1280,7 @@
public int verificationSizeLimitInBytesOverride = -1;
public boolean forceIRForCfToCfDesugar =
System.getProperty("com.android.tools.r8.forceIRForCfToCfDesugar") != null;
+ public boolean disableMappingToOriginalProgramVerification = false;
// Flag to allow processing of resources in D8. A data resource consumer still needs to be
// specified.
diff --git a/src/main/java/com/android/tools/r8/utils/PredicateUtils.java b/src/main/java/com/android/tools/r8/utils/PredicateUtils.java
index 880da5e..f219259 100644
--- a/src/main/java/com/android/tools/r8/utils/PredicateUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/PredicateUtils.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.utils;
+import java.util.function.Function;
import java.util.function.Predicate;
public class PredicateUtils {
@@ -20,4 +21,8 @@
public static <T> Predicate<T> not(Predicate<T> predicate) {
return t -> !predicate.test(t);
}
+
+ public static <T, R> Predicate<T> isNull(Function<T, R> func) {
+ return t -> func.apply(t) == null;
+ }
}
diff --git a/src/test/java/com/android/tools/r8/cf/bootstrap/BootstrapCurrentEqualityTest.java b/src/test/java/com/android/tools/r8/cf/bootstrap/BootstrapCurrentEqualityTest.java
index 4baa16c..b3ff5a3 100644
--- a/src/test/java/com/android/tools/r8/cf/bootstrap/BootstrapCurrentEqualityTest.java
+++ b/src/test/java/com/android/tools/r8/cf/bootstrap/BootstrapCurrentEqualityTest.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.cf.bootstrap;
+import static com.android.tools.r8.graph.GenericSignatureIdentityTest.testParseSignaturesInJar;
import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
import static com.google.common.io.ByteStreams.toByteArray;
import static org.hamcrest.CoreMatchers.anyOf;
@@ -208,6 +209,11 @@
}
@Test
+ public void testSignatures() throws Exception {
+ testParseSignaturesInJar(r8R8Release.getFirst());
+ }
+
+ @Test
public void test() throws Exception {
expectThrowsWithHorizontalClassMerging();
Path helloJar = Paths.get(ToolHelper.EXAMPLES_BUILD_DIR, "hello" + JAR_EXTENSION);
diff --git a/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java b/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
index b567056..b134ae5 100644
--- a/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
+++ b/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
@@ -25,6 +25,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.LazyLoadedDexApplication;
@@ -112,6 +113,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
DexEncodedField.EMPTY_ARRAY,
DexEncodedField.EMPTY_ARRAY,
diff --git a/src/test/java/com/android/tools/r8/graph/GenericSignatureTest.java b/src/test/java/com/android/tools/r8/graph/GenericSignatureTest.java
index 366e98b..ddff057 100644
--- a/src/test/java/com/android/tools/r8/graph/GenericSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/graph/GenericSignatureTest.java
@@ -43,23 +43,28 @@
@RunWith(Parameterized.class)
public class GenericSignatureTest extends TestBase {
+ private final TestParameters parameters;
+
@Parameters(name = "{0}")
public static TestParametersCollection data() {
- return getTestParameters().withNoneRuntime().build();
+ return getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build();
}
- public GenericSignatureTest(TestParameters parameters) {}
+ public GenericSignatureTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
@Test
public void test() throws Exception {
AndroidApp app =
- testForD8()
+ testForD8(parameters.getBackend())
.debug()
.addProgramClassesAndInnerClasses(
GenericSignatureTestClassA.class,
GenericSignatureTestClassB.class,
GenericSignatureTestClassCY.class,
GenericSignatureTestClassCYY.class)
+ .setMinApi(parameters.getApiLevel())
.compile()
.app;
AppView<AppInfoWithLiveness> appView = computeAppViewWithLiveness(app);
@@ -103,13 +108,7 @@
// class <T:GenericSignatureTestClassA<T>.Y>CYY<T extends A<T>.Y> extends CY<T>
DexClass clazz = cyy.getDexProgramClass();
assertNotNull(clazz);
- classSignature =
- GenericSignature.parseClassSignature(
- clazz.getType().getName(),
- getGenericSignature(clazz, appView),
- clazz.origin,
- appView.dexItemFactory(),
- appView.options().reporter);
+ classSignature = clazz.classSignature;
assertNotNull(classSignature);
assertEquals(1, classSignature.formalTypeParameters.size());
diff --git a/src/test/java/com/android/tools/r8/graph/genericsignature/ClassSignatureTest.java b/src/test/java/com/android/tools/r8/graph/genericsignature/ClassSignatureTest.java
index e11a02a..fade8ed 100644
--- a/src/test/java/com/android/tools/r8/graph/genericsignature/ClassSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/graph/genericsignature/ClassSignatureTest.java
@@ -6,6 +6,7 @@
import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
import static com.android.tools.r8.graph.GenericSignature.ClassSignature.NO_CLASS_SIGNATURE;
+import static com.google.common.base.Predicates.alwaysFalse;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
@@ -155,7 +156,7 @@
GenericSignature.parseClassSignature(
"A", signature, Origin.unknown(), new DexItemFactory(), new Reporter());
GenericSignaturePrinter genericSignaturePrinter =
- new GenericSignaturePrinter(NamingLens.getIdentityLens());
+ new GenericSignaturePrinter(NamingLens.getIdentityLens(), alwaysFalse());
genericSignaturePrinter.visitClassSignature(parsed);
String outSignature = genericSignaturePrinter.toString();
assertEquals(signature, outSignature);
diff --git a/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java b/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java
index 0465bc5..99b186f 100644
--- a/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java
+++ b/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexTypeList;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ParameterAnnotationsList;
import com.android.tools.r8.graph.ProgramMethod;
@@ -35,6 +36,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
DexEncodedField.EMPTY_ARRAY,
DexEncodedField.EMPTY_ARRAY,
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index e03e056..fd09ef3 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -46,6 +46,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.MethodAccessFlags;
@@ -830,6 +831,7 @@
Collections.emptyList(),
null,
Collections.emptyList(),
+ ClassSignature.NO_CLASS_SIGNATURE,
DexAnnotationSet.empty(),
DexEncodedField.EMPTY_ARRAY,
DexEncodedField.EMPTY_ARRAY,
diff --git a/src/test/java/com/android/tools/r8/naming/MinifierClassSignatureTest.java b/src/test/java/com/android/tools/r8/naming/MinifierClassSignatureTest.java
index b2ec374..e3e965c 100644
--- a/src/test/java/com/android/tools/r8/naming/MinifierClassSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/naming/MinifierClassSignatureTest.java
@@ -322,6 +322,9 @@
ProguardKeepAttributes.SIGNATURE)
.addKeepAllClassesRuleWithAllowObfuscation()
.allowDiagnosticMessages()
+ .addOptionsModification(
+ internalOptions ->
+ internalOptions.testing.disableMappingToOriginalProgramVerification = true)
.compile();
compileResult.assertNoInfoMessages();
diff --git a/src/test/java/com/android/tools/r8/naming/signature/SignatureOfMergedClassesTest.java b/src/test/java/com/android/tools/r8/naming/signature/SignatureOfMergedClassesTest.java
index 01a95ba..7511e28 100644
--- a/src/test/java/com/android/tools/r8/naming/signature/SignatureOfMergedClassesTest.java
+++ b/src/test/java/com/android/tools/r8/naming/signature/SignatureOfMergedClassesTest.java
@@ -58,7 +58,7 @@
L.class,
ImplL.class)
.addKeepMainRule(Main.class)
- .addKeepClassRules(InterfaceToKeep.class)
+ .addKeepClassRules(InterfaceToKeep.class, ImplI.class, K.class)
.addKeepAttributes("Signature, InnerClasses, EnclosingMethod, *Annotation*")
.setMinApi(parameters.getApiLevel())
.noMinification()
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
index 6a5b949..d1e934f 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
@@ -245,12 +245,10 @@
}
public String getOriginalSignatureAttribute(
- DexAnnotationSet annotations, BiConsumer<GenericSignatureParser, String> parse) {
- String finalSignature = getFinalSignatureAttribute(annotations);
+ String finalSignature, BiConsumer<GenericSignatureParser, String> parse) {
if (finalSignature == null || mapping == null) {
return finalSignature;
}
-
GenericSignatureGenerator rewriter = new GenericSignatureGenerator();
GenericSignatureParser<String> parser = new GenericSignatureParser<>(rewriter);
parse.accept(parser, finalSignature);
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
index ab1d03b..8e961c7 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
@@ -359,12 +359,12 @@
@Override
public String getOriginalSignatureAttribute() {
return codeInspector.getOriginalSignatureAttribute(
- dexClass.annotations(), GenericSignatureParser::parseClassSignature);
+ dexClass.getClassSignature().toString(), GenericSignatureParser::parseClassSignature);
}
@Override
public String getFinalSignatureAttribute() {
- return codeInspector.getFinalSignatureAttribute(dexClass.annotations());
+ return dexClass.getClassSignature().toString();
}
@Override
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java
index 411dad2..9ef7938 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java
@@ -134,7 +134,8 @@
@Override
public String getOriginalSignatureAttribute() {
return codeInspector.getOriginalSignatureAttribute(
- dexField.annotations(), GenericSignatureParser::parseFieldSignature);
+ codeInspector.getFinalSignatureAttribute(dexField.annotations()),
+ GenericSignatureParser::parseFieldSignature);
}
@Override
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
index 536aa5e3..4e49582 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
@@ -186,7 +186,8 @@
@Override
public String getOriginalSignatureAttribute() {
return codeInspector.getOriginalSignatureAttribute(
- dexMethod.annotations(), GenericSignatureParser::parseMethodSignature);
+ codeInspector.getFinalSignatureAttribute(dexMethod.annotations()),
+ GenericSignatureParser::parseMethodSignature);
}
public DexMethod getOriginalDexMethod(DexItemFactory dexItemFactory) {