Version 2.1.79
Revert "Cherry-pick signature visitor"
This reverts commit e10f769fe0101a610803fed3287cb797c663f044.
Change-Id: I86d42f3a5cc1dae913eec0220935e5499479c054
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index ae3d5a4..d9cf88d 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
// This field is accessed from release scripts using simple pattern matching.
// Therefore, changing this field could break our release scripts.
- public static final String LABEL = "2.1.78";
+ public static final String LABEL = "2.1.79";
private Version() {
}
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 24a99a0..2b75c58 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -341,7 +341,7 @@
appView.options().reporter);
}
}
- return ClassSignature.noSignature();
+ return ClassSignature.NO_CLASS_SIGNATURE;
}
private boolean verifyCorrectnessOfFieldHolder(DexEncodedField field) {
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 a92dc75..9c34474 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignature.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignature.java
@@ -174,7 +174,7 @@
public static class ClassSignature implements DexDefinitionSignature<DexClass> {
- private static final ClassSignature NO_CLASS_SIGNATURE =
+ public static final ClassSignature NO_CLASS_SIGNATURE =
new ClassSignature(EMPTY_TYPE_PARAMS, NO_FIELD_TYPE_SIGNATURE, EMPTY_SUPER_INTERFACES);
final List<FormalTypeParameter> formalTypeParameters;
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java b/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java
deleted file mode 100644
index c95ce02..0000000
--- a/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java
+++ /dev/null
@@ -1,326 +0,0 @@
-// 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.EMPTY_TYPE_SIGNATURES;
-import static com.android.tools.r8.graph.GenericSignature.FieldTypeSignature.noSignature;
-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.MethodTypeSignature;
-import com.android.tools.r8.graph.GenericSignature.ReturnType;
-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()) {
- return classSignature;
- }
- return new ClassSignatureRewriter().run(classSignature);
- }
-
- public FieldTypeSignature rewrite(FieldTypeSignature fieldTypeSignature) {
- if (fieldTypeSignature.hasNoSignature()) {
- return fieldTypeSignature;
- }
- return new TypeSignatureRewriter().run(fieldTypeSignature);
- }
-
- public MethodTypeSignature rewrite(MethodTypeSignature methodTypeSignature) {
- if (methodTypeSignature.hasNoSignature()) {
- return methodTypeSignature;
- }
- return new MethodTypeSignatureRewriter().run(methodTypeSignature);
- }
-
- 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.noSignature();
- }
- return new ClassSignature(
- rewrittenTypeParameters.isEmpty() ? EMPTY_TYPE_PARAMS : rewrittenTypeParameters,
- rewrittenSuperClass,
- rewrittenSuperInterfaces.isEmpty() ? EMPTY_SUPER_INTERFACES : rewrittenSuperInterfaces);
- }
- }
-
- private class MethodTypeSignatureRewriter implements GenericSignatureVisitor {
-
- private final List<FormalTypeParameter> rewrittenTypeParameters = new ArrayList<>();
- private final List<TypeSignature> rewrittenTypeSignatures = new ArrayList<>();
-
- ReturnType rewrittenReturnType = null;
- private final List<TypeSignature> rewrittenThrowsSignatures = new ArrayList<>();
-
- @Override
- public void visitFormalTypeParameters(List<FormalTypeParameter> formalTypeParameters) {
- for (FormalTypeParameter formalTypeParameter : formalTypeParameters) {
- rewrittenTypeParameters.add(new FormalTypeParameterRewriter().run(formalTypeParameter));
- }
- }
-
- @Override
- public void visitMethodTypeSignatures(List<TypeSignature> typeSignatures) {
- for (TypeSignature typeSignature : typeSignatures) {
- TypeSignature rewrittenType = new TypeSignatureRewriter().run(typeSignature);
- rewrittenTypeSignatures.add(rewrittenType == null ? objectTypeSignature : rewrittenType);
- }
- }
-
- @Override
- public void visitReturnType(ReturnType returnType) {
- if (returnType.isVoidDescriptor()) {
- rewrittenReturnType = ReturnType.VOID;
- } else {
- TypeSignature originalType = returnType.typeSignature();
- TypeSignature rewrittenType = new TypeSignatureRewriter().run(originalType);
- if (rewrittenType == null) {
- rewrittenReturnType = ReturnType.VOID;
- } else if (rewrittenType == originalType) {
- rewrittenReturnType = returnType;
- } else {
- rewrittenReturnType = new ReturnType(rewrittenType);
- }
- }
- }
-
- @Override
- public void visitThrowsSignatures(List<TypeSignature> typeSignatures) {
- for (TypeSignature typeSignature : typeSignatures) {
- TypeSignature rewrittenType = new TypeSignatureRewriter().run(typeSignature);
- // If a throwing type is no longer found we remove it from the signature.
- if (rewrittenType != null) {
- rewrittenThrowsSignatures.add(rewrittenType);
- }
- }
- }
-
- private MethodTypeSignature run(MethodTypeSignature methodTypeSignature) {
- methodTypeSignature.visit(this);
- assert rewrittenReturnType != null;
- if (rewrittenTypeParameters.isEmpty()
- && rewrittenTypeSignatures.isEmpty()
- && rewrittenReturnType.isVoidDescriptor()
- && rewrittenThrowsSignatures.isEmpty()) {
- return MethodTypeSignature.noSignature();
- }
- return new MethodTypeSignature(
- rewrittenTypeParameters.isEmpty() ? EMPTY_TYPE_PARAMS : rewrittenTypeParameters,
- rewrittenTypeSignatures.isEmpty() ? EMPTY_TYPE_SIGNATURES : rewrittenTypeSignatures,
- rewrittenReturnType,
- rewrittenThrowsSignatures.isEmpty() ? EMPTY_TYPE_SIGNATURES : rewrittenThrowsSignatures);
- }
- }
-
- private class FormalTypeParameterRewriter implements GenericSignatureVisitor {
-
- private FieldTypeSignature rewrittenClassBound = noSignature();
- 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 ? noSignature() : 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) {
- DexType rewrittenType = appView.graphLense().lookupType(type);
- if (appInfoWithLiveness != null && appInfoWithLiveness.wasPruned(rewrittenType)) {
- return null;
- }
- if (isSuperClassOrInterface && context.type == rewrittenType) {
- return null;
- }
- return rewrittenType;
- }
- }
-}
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 fd5dc11..1f66108 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
@@ -4,25 +4,28 @@
package com.android.tools.r8.naming.signature;
+import static com.android.tools.r8.utils.DescriptorUtils.getClassBinaryNameFromDescriptor;
+import static com.android.tools.r8.utils.DescriptorUtils.getDescriptorFromClassBinaryName;
+
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationSet;
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;
-import com.android.tools.r8.graph.GenericSignature.ClassSignature;
-import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
-import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
-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;
-import com.android.tools.r8.utils.PredicateUtils;
import com.android.tools.r8.utils.Reporter;
+import com.android.tools.r8.utils.StringDiagnostic;
import com.android.tools.r8.utils.ThreadUtils;
+import java.lang.reflect.GenericSignatureFormatError;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
-import java.util.function.Function;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
import java.util.function.Predicate;
+import java.util.function.Supplier;
// TODO(b/129925954): Reimplement this by using the internal encoding and transformation logic.
public class GenericSignatureRewriter {
@@ -31,14 +34,12 @@
private final NamingLens namingLens;
private final InternalOptions options;
private final Reporter reporter;
- private final Predicate<DexType> isTypeMissing;
public GenericSignatureRewriter(AppView<?> appView, NamingLens namingLens) {
this.appView = appView;
this.namingLens = namingLens;
this.options = appView.options();
this.reporter = options.reporter;
- isTypeMissing = PredicateUtils.isNull(appView.appInfo()::definitionForWithoutExistenceAssert);
}
public void run(Iterable<? extends DexProgramClass> classes, ExecutorService executorService)
@@ -55,77 +56,51 @@
ThreadUtils.processItems(
classes,
clazz -> {
- GenericSignatureTypeRewriter typeRewriter =
- new GenericSignatureTypeRewriter(appView, clazz);
+ GenericSignatureCollector genericSignatureCollector =
+ new GenericSignatureCollector(clazz);
+ GenericSignatureParser<DexType> genericSignatureParser =
+ new GenericSignatureParser<>(genericSignatureCollector);
clazz.setAnnotations(
rewriteGenericSignatures(
clazz.annotations(),
- signature -> {
- ClassSignature classSignature =
- GenericSignature.parseClassSignature(
- clazz.toSourceString(),
- signature,
- clazz.origin,
- appView.dexItemFactory(),
- options.reporter);
- if (classSignature.hasNoSignature()) {
- return null;
- }
- return typeRewriter
- .rewrite(classSignature)
- .toRenamedString(namingLens, isTypeMissing);
- }));
+ genericSignatureParser::parseClassSignature,
+ genericSignatureCollector::getRenamedSignature,
+ (signature, e) ->
+ options.warningInvalidSignature(clazz, clazz.getOrigin(), signature, e)));
clazz.forEachField(
field ->
field.setAnnotations(
rewriteGenericSignatures(
field.annotations(),
- signature -> {
- FieldTypeSignature fieldSignature =
- GenericSignature.parseFieldTypeSignature(
- field.toSourceString(),
- signature,
- clazz.origin,
- appView.dexItemFactory(),
- options.reporter);
- if (fieldSignature.hasNoSignature()) {
- return null;
- }
- return typeRewriter
- .rewrite(fieldSignature)
- .toRenamedString(namingLens, isTypeMissing);
- })));
+ genericSignatureParser::parseFieldSignature,
+ genericSignatureCollector::getRenamedSignature,
+ (signature, e) ->
+ options.warningInvalidSignature(
+ field, clazz.getOrigin(), signature, e))));
clazz.forEachMethod(
method ->
method.setAnnotations(
rewriteGenericSignatures(
method.annotations(),
- signature -> {
- MethodTypeSignature methodSignature =
- GenericSignature.parseMethodSignature(
- method.toSourceString(),
- signature,
- clazz.origin,
- appView.dexItemFactory(),
- options.reporter);
- if (methodSignature.hasNoSignature()) {
- return null;
- }
- return typeRewriter
- .rewrite(methodSignature)
- .toRenamedString(namingLens, isTypeMissing);
- })));
+ genericSignatureParser::parseMethodSignature,
+ genericSignatureCollector::getRenamedSignature,
+ (signature, e) ->
+ options.warningInvalidSignature(
+ method, clazz.getOrigin(), signature, e))));
},
executorService);
}
private DexAnnotationSet rewriteGenericSignatures(
- DexAnnotationSet annotations, Function<String, String> rewrite) {
+ DexAnnotationSet annotations,
+ Consumer<String> parser,
+ Supplier<String> collector,
+ BiConsumer<String, GenericSignatureFormatError> parseError) {
// There can be no more than one signature annotation in an annotation set.
final int VALID = -1;
- int invalidOrPrunedIndex = VALID;
+ int invalid = VALID;
DexAnnotation[] rewrittenAnnotations = null;
- for (int i = 0; i < annotations.annotations.length && invalidOrPrunedIndex == VALID; i++) {
+ for (int i = 0; i < annotations.annotations.length && invalid == VALID; i++) {
DexAnnotation annotation = annotations.annotations[i];
if (DexAnnotation.isSignatureAnnotation(annotation, appView.dexItemFactory())) {
if (rewrittenAnnotations == null) {
@@ -133,12 +108,16 @@
System.arraycopy(annotations.annotations, 0, rewrittenAnnotations, 0, i);
}
String signature = DexAnnotation.getSignature(annotation);
- String rewrittenSignature = rewrite.apply(signature);
- if (rewrittenSignature != null) {
- rewrittenAnnotations[i] =
- DexAnnotation.createSignatureAnnotation(rewrittenSignature, appView.dexItemFactory());
- } else {
- invalidOrPrunedIndex = i;
+ try {
+ parser.accept(signature);
+ String renamedSignature = collector.get();
+ assert verifyConsistentRenaming(parser, collector, renamedSignature);
+ DexAnnotation signatureAnnotation =
+ DexAnnotation.createSignatureAnnotation(renamedSignature, appView.dexItemFactory());
+ rewrittenAnnotations[i] = signatureAnnotation;
+ } catch (GenericSignatureFormatError e) {
+ parseError.accept(signature, e);
+ invalid = i;
}
} else if (rewrittenAnnotations != null) {
rewrittenAnnotations[i] = annotation;
@@ -146,7 +125,7 @@
}
// Return the rewritten signatures if it was valid and could be rewritten.
- if (invalidOrPrunedIndex == VALID) {
+ if (invalid == VALID) {
return rewrittenAnnotations != null
? new DexAnnotationSet(rewrittenAnnotations)
: annotations;
@@ -156,11 +135,156 @@
new DexAnnotation[annotations.annotations.length - 1];
int dest = 0;
for (int i = 0; i < annotations.annotations.length; i++) {
- if (i != invalidOrPrunedIndex) {
+ if (i != invalid) {
prunedAnnotations[dest++] = annotations.annotations[i];
}
}
assert dest == prunedAnnotations.length;
return new DexAnnotationSet(prunedAnnotations);
}
+
+ /**
+ * Calling this method will clobber the parsed signature in the collector - ideally with the same
+ * string. Only use this after the original result has been collected.
+ */
+ private boolean verifyConsistentRenaming(
+ Consumer<String> parser, Supplier<String> collector, String renamedSignature) {
+ if (!options.testing.assertConsistentRenamingOfSignature) {
+ return true;
+ }
+ parser.accept(renamedSignature);
+ String reRenamedSignature = collector.get();
+ assert renamedSignature.equals(reRenamedSignature);
+ return true;
+ }
+
+ private class GenericSignatureCollector implements GenericSignatureAction<DexType> {
+ private StringBuilder renamedSignature;
+ private final DexProgramClass currentClassContext;
+ private DexType lastWrittenType = null;
+
+ GenericSignatureCollector(DexProgramClass clazz) {
+ this.currentClassContext = clazz;
+ }
+
+ String getRenamedSignature() {
+ return renamedSignature.toString();
+ }
+
+ @Override
+ public void parsedSymbol(char symbol) {
+ if (symbol == ';' && lastWrittenType == null) {
+ // The type was never written (maybe because it was merged with it's subtype).
+ return;
+ }
+ // If the super-class or interface has been merged, we will stop writing out type
+ // arguments, resulting in a signature on the form '<>' if we do not remove it.
+ if (symbol == '>' && removeWrittenCharacter(c -> c == '<')) {
+ return;
+ }
+ renamedSignature.append(symbol);
+ }
+
+ @Override
+ public void parsedIdentifier(String identifier) {
+ renamedSignature.append(identifier);
+ }
+
+ @Override
+ public DexType parsedTypeName(String name, ParserPosition parserPosition) {
+ if (parserPosition == ParserPosition.ENCLOSING_INNER_OR_TYPE_ANNOTATION
+ && lastWrittenType == null) {
+ // We are writing type-arguments for a merged class.
+ removeWrittenClassCharacter();
+ return null;
+ }
+ String originalDescriptor = getDescriptorFromClassBinaryName(name);
+ DexType type =
+ appView.graphLense().lookupType(appView.dexItemFactory().createType(originalDescriptor));
+ if (appView.appInfo().hasLiveness() && appView.withLiveness().appInfo().wasPruned(type)) {
+ type = appView.dexItemFactory().objectType;
+ }
+ DexString renamedDescriptor = namingLens.lookupDescriptor(type);
+ if (parserPosition == ParserPosition.CLASS_SUPER_OR_INTERFACE_ANNOTATION
+ && currentClassContext != null) {
+ // We may have merged the type down to the current class type.
+ DexString classDescriptor = currentClassContext.type.descriptor;
+ if (!originalDescriptor.equals(classDescriptor.toString())
+ && renamedDescriptor.equals(classDescriptor)) {
+ lastWrittenType = null;
+ removeWrittenClassCharacter();
+ return type;
+ }
+ }
+ renamedSignature.append(getClassBinaryNameFromDescriptor(renamedDescriptor.toString()));
+ lastWrittenType = type;
+ return type;
+ }
+
+ private boolean removeWrittenCharacter(Predicate<Character> removeIf) {
+ int index = renamedSignature.length() - 1;
+ if (index < 0 || !removeIf.test(renamedSignature.charAt(index))) {
+ return false;
+ }
+ renamedSignature.deleteCharAt(index);
+ return true;
+ }
+
+ private void removeWrittenClassCharacter() {
+ removeWrittenCharacter(c -> c == 'L');
+ }
+
+ @Override
+ public DexType parsedInnerTypeName(DexType enclosingType, String name) {
+ if (enclosingType == null) {
+ // We are writing inner type names
+ removeWrittenClassCharacter();
+ return null;
+ }
+ assert enclosingType.isClassType();
+ String enclosingDescriptor = enclosingType.toDescriptorString();
+ DexType type =
+ appView
+ .dexItemFactory()
+ .createType(
+ getDescriptorFromClassBinaryName(
+ getClassBinaryNameFromDescriptor(enclosingDescriptor)
+ + DescriptorUtils.INNER_CLASS_SEPARATOR
+ + name));
+ type = appView.graphLense().lookupType(type);
+ String renamedDescriptor = namingLens.lookupDescriptor(type).toString();
+ if (!renamedDescriptor.equals(type.toDescriptorString())) {
+ // TODO(b/147504070): If this is a merged class equal to the class context, do not add.
+ // Pick the renamed inner class from the fully renamed binary name.
+ String fullRenamedBinaryName = getClassBinaryNameFromDescriptor(renamedDescriptor);
+ String enclosingRenamedBinaryName =
+ getClassBinaryNameFromDescriptor(namingLens.lookupDescriptor(enclosingType).toString());
+ int innerClassPos = enclosingRenamedBinaryName.length() + 1;
+ if (innerClassPos < fullRenamedBinaryName.length()) {
+ renamedSignature.append(fullRenamedBinaryName.substring(innerClassPos));
+ } else if (appView.options().keepInnerClassStructure()) {
+ reporter.warning(
+ new StringDiagnostic(
+ "Should have retained InnerClasses attribute of " + type + ".",
+ appView.appInfo().originFor(type)));
+ renamedSignature.append(name);
+ }
+ } else {
+ // Did not find the class - keep the inner class name as is.
+ // TODO(b/110085899): Warn about missing classes in signatures?
+ renamedSignature.append(name);
+ }
+ return type;
+ }
+
+ @Override
+ public void start() {
+ renamedSignature = new StringBuilder();
+ }
+
+ @Override
+ public void stop() {
+ // nothing to do
+ }
+ }
}
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 14788ba..af62b23 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -28,6 +28,7 @@
import com.android.tools.r8.features.FeatureSplitConfiguration;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexDefinition;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItem;
import com.android.tools.r8.graph.DexItemFactory;
@@ -56,6 +57,7 @@
import com.google.common.collect.Sets;
import java.io.IOException;
import java.io.PrintStream;
+import java.lang.reflect.GenericSignatureFormatError;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
@@ -909,6 +911,31 @@
}
}
+ public void warningInvalidSignature(
+ DexDefinition item, Origin origin, String signature, GenericSignatureFormatError e) {
+ StringBuilder message = new StringBuilder("Invalid signature '");
+ message.append(signature);
+ message.append("' for ");
+ if (item.isDexClass()) {
+ message.append("class ");
+ message.append((item.asDexClass()).getType().toSourceString());
+ } else if (item.isDexEncodedField()) {
+ message.append("field ");
+ message.append(item.toSourceString());
+ } else {
+ assert item.isDexEncodedMethod();
+ message.append("method ");
+ message.append(item.toSourceString());
+ }
+ message.append(".");
+ message.append(System.lineSeparator());
+ message.append("Signature is ignored and will not be present in the output.");
+ message.append(System.lineSeparator());
+ message.append("Parser error: ");
+ message.append(e.getMessage());
+ reporter.warning(new StringDiagnostic(message.toString(), origin));
+ }
+
public boolean printWarnings() {
boolean printed = false;
boolean printOutdatedToolchain = false;
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 f219259..880da5e 100644
--- a/src/main/java/com/android/tools/r8/utils/PredicateUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/PredicateUtils.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.utils;
-import java.util.function.Function;
import java.util.function.Predicate;
public class PredicateUtils {
@@ -21,8 +20,4 @@
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/graph/genericsignature/ClassSignatureTest.java b/src/test/java/com/android/tools/r8/graph/genericsignature/ClassSignatureTest.java
index eb76047..cd057d2 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
@@ -5,6 +5,7 @@
package com.android.tools.r8.graph.genericsignature;
import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
+import static com.android.tools.r8.graph.GenericSignature.ClassSignature.NO_CLASS_SIGNATURE;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
@@ -170,7 +171,7 @@
Origin.unknown(),
new DexItemFactory(),
new Reporter(testDiagnosticMessages));
- assertEquals(ClassSignature.noSignature(), parsed);
+ assertEquals(NO_CLASS_SIGNATURE, parsed);
return testDiagnosticMessages;
}
}
diff --git a/src/test/java/com/android/tools/r8/naming/b126592786/B126592786.java b/src/test/java/com/android/tools/r8/naming/b126592786/B126592786.java
index 20e13bf..d44fcd1 100644
--- a/src/test/java/com/android/tools/r8/naming/b126592786/B126592786.java
+++ b/src/test/java/com/android/tools/r8/naming/b126592786/B126592786.java
@@ -57,7 +57,7 @@
.compile()
.inspect(
inspector -> {
- String genericTypeDescriptor = "*";
+ String genericTypeDescriptor = "Ljava/lang/Object;";
if (genericTypeLive) {
ClassSubject genericType = inspector.clazz(GenericType.class);
assertThat(genericType, isRenamed(minify));
diff --git a/src/test/java/com/android/tools/r8/naming/signature/GenericSignatureRenamingTest.java b/src/test/java/com/android/tools/r8/naming/signature/GenericSignatureRenamingTest.java
index e945182..adf7ba7 100644
--- a/src/test/java/com/android/tools/r8/naming/signature/GenericSignatureRenamingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/signature/GenericSignatureRenamingTest.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.naming.signature;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assume.assumeTrue;
import com.android.tools.r8.CompilationMode;
@@ -70,13 +71,18 @@
}
@Test
- public void testR8WithAssertEnabled() throws Exception {
- test(
- testForR8(parameters.getBackend())
- .addKeepRules("-dontobfuscate")
- .addOptionsModification(
- internalOptions ->
- internalOptions.testing.assertConsistentRenamingOfSignature = true));
+ public void testR8WithAssertEnabled() {
+ // TODO(b/154793333): Enable assertions always when resolved.
+ assertThrows(
+ AssertionError.class,
+ () -> {
+ test(
+ testForR8(parameters.getBackend())
+ .addKeepRules("-dontobfuscate")
+ .addOptionsModification(
+ internalOptions ->
+ internalOptions.testing.assertConsistentRenamingOfSignature = true));
+ });
}
private void test(R8TestBuilder<?> builder) throws Exception {