Handle renaming of types in Signature annotations after vertical class merging
Bug: 124357885
Change-Id: Ic677192883c5f9c889b87ba49831dfabfe570b05
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 4d79275..065ad10 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -628,9 +628,7 @@
NamingLens namingLens;
if (options.enableMinification) {
timing.begin("Minification");
- namingLens =
- new Minifier(appView.appInfo().withLiveness(), rootSet, desugaredCallSites, options)
- .run(timing);
+ namingLens = new Minifier(appView.withLiveness(), rootSet, desugaredCallSites).run(timing);
timing.end();
} else {
namingLens = NamingLens.getIdentityLens();
diff --git a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
index bc81538..b59b79b 100644
--- a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
@@ -9,6 +9,7 @@
import static com.android.tools.r8.utils.DescriptorUtils.getDescriptorFromClassBinaryName;
import static com.android.tools.r8.utils.DescriptorUtils.getPackageBinaryNameFromJavaType;
+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.DexClass;
@@ -50,6 +51,7 @@
class ClassNameMinifier {
+ private final AppView<AppInfoWithLiveness> appView;
private final AppInfoWithLiveness appInfo;
private final Reporter reporter;
private final PackageObfuscationMode packageObfuscationMode;
@@ -74,11 +76,10 @@
private final GenericSignatureParser<DexType> genericSignatureParser =
new GenericSignatureParser<>(genericSignatureRewriter);
- ClassNameMinifier(
- AppInfoWithLiveness appInfo,
- RootSet rootSet,
- InternalOptions options) {
- this.appInfo = appInfo;
+ ClassNameMinifier(AppView<AppInfoWithLiveness> appView, RootSet rootSet) {
+ this.appView = appView;
+ this.appInfo = appView.appInfo();
+ InternalOptions options = appView.options();
this.reporter = options.reporter;
this.packageObfuscationMode = options.getProguardConfiguration().getPackageObfuscationMode();
this.isAccessModificationAllowed =
@@ -546,6 +547,7 @@
@Override
public DexType parsedTypeName(String name) {
DexType type = appInfo.dexItemFactory.createType(getDescriptorFromClassBinaryName(name));
+ type = appView.graphLense().lookupType(type);
DexString renamedDescriptor = renaming.getOrDefault(type, type.descriptor);
renamedSignature.append(getClassBinaryNameFromDescriptor(renamedDescriptor.toString()));
return type;
@@ -564,6 +566,7 @@
String enclosingRenamedBinaryName =
getClassBinaryNameFromDescriptor(
renaming.getOrDefault(enclosingType, enclosingType.descriptor).toString());
+ type = appView.graphLense().lookupType(type);
DexString renamedDescriptor = renaming.get(type);
if (renamedDescriptor != null) {
// Pick the renamed inner class from the fully renamed binary name.
diff --git a/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java b/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
index be339b6..e2127dd 100644
--- a/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.naming;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
@@ -10,7 +11,6 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
-import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
@@ -19,8 +19,8 @@
class FieldNameMinifier extends MemberNameMinifier<DexField, DexType> {
- FieldNameMinifier(AppInfoWithLiveness appInfo, RootSet rootSet, InternalOptions options) {
- super(appInfo, rootSet, options);
+ FieldNameMinifier(AppView<AppInfoWithLiveness> appView, RootSet rootSet) {
+ super(appView, rootSet);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/naming/MemberNameMinifier.java b/src/main/java/com/android/tools/r8/naming/MemberNameMinifier.java
index 419bfbb..53957e4 100644
--- a/src/main/java/com/android/tools/r8/naming/MemberNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/MemberNameMinifier.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.naming;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CachedHashValueDexItem;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
@@ -18,6 +19,7 @@
abstract class MemberNameMinifier<MemberType, StateType extends CachedHashValueDexItem> {
+ protected final AppView<AppInfoWithLiveness> appView;
protected final AppInfoWithLiveness appInfo;
protected final RootSet rootSet;
protected final InternalOptions options;
@@ -34,10 +36,11 @@
// which is useful for debugging.
private final BiMap<DexType, NamingState<StateType, ?>> states = HashBiMap.create();
- MemberNameMinifier(AppInfoWithLiveness appInfo, RootSet rootSet, InternalOptions options) {
- this.appInfo = appInfo;
+ MemberNameMinifier(AppView<AppInfoWithLiveness> appView, RootSet rootSet) {
+ this.appView = appView;
+ this.appInfo = appView.appInfo();
this.rootSet = rootSet;
- this.options = options;
+ this.options = appView.options();
this.dictionary = options.getProguardConfiguration().getObfuscationDictionary();
this.useUniqueMemberNames = options.getProguardConfiguration().isUseUniqueClassMemberNames();
this.overloadAggressively =
diff --git a/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java b/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
index 8864271..2cd8712 100644
--- a/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/MethodNameMinifier.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.naming;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -91,11 +92,8 @@
private final FrontierState frontierState = new FrontierState();
- MethodNameMinifier(
- AppInfoWithLiveness appInfo,
- RootSet rootSet,
- InternalOptions options) {
- super(appInfo, rootSet, options);
+ MethodNameMinifier(AppView<AppInfoWithLiveness> appView, RootSet rootSet) {
+ super(appView, rootSet);
equivalence =
overloadAggressively
? MethodSignatureEquivalence.get()
diff --git a/src/main/java/com/android/tools/r8/naming/Minifier.java b/src/main/java/com/android/tools/r8/naming/Minifier.java
index 5333125..af18595 100644
--- a/src/main/java/com/android/tools/r8/naming/Minifier.java
+++ b/src/main/java/com/android/tools/r8/naming/Minifier.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.naming;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -35,26 +36,27 @@
static final char INNER_CLASS_SEPARATOR = '$';
+ private final AppView<AppInfoWithLiveness> appView;
private final AppInfoWithLiveness appInfo;
private final RootSet rootSet;
private final Set<DexCallSite> desugaredCallSites;
private final InternalOptions options;
public Minifier(
- AppInfoWithLiveness appInfo,
+ AppView<AppInfoWithLiveness> appView,
RootSet rootSet,
- Set<DexCallSite> desugaredCallSites,
- InternalOptions options) {
- this.appInfo = appInfo;
+ Set<DexCallSite> desugaredCallSites) {
+ this.appView = appView;
+ this.appInfo = appView.appInfo();
this.rootSet = rootSet;
this.desugaredCallSites = desugaredCallSites;
- this.options = options;
+ this.options = appView.options();
}
public NamingLens run(Timing timing) {
assert options.enableMinification;
timing.begin("MinifyClasses");
- ClassNameMinifier classNameMinifier = new ClassNameMinifier(appInfo, rootSet, options);
+ ClassNameMinifier classNameMinifier = new ClassNameMinifier(appView, rootSet);
ClassRenaming classRenaming = classNameMinifier.computeRenaming(timing);
timing.end();
@@ -64,16 +66,14 @@
timing.begin("MinifyMethods");
MethodRenaming methodRenaming =
- new MethodNameMinifier(appInfo, rootSet, options)
- .computeRenaming(desugaredCallSites, timing);
+ new MethodNameMinifier(appView, rootSet).computeRenaming(desugaredCallSites, timing);
timing.end();
assert new MinifiedRenaming(classRenaming, methodRenaming, FieldRenaming.empty(), appInfo)
.verifyNoCollisions(appInfo.classes(), appInfo.dexItemFactory);
timing.begin("MinifyFields");
- FieldRenaming fieldRenaming =
- new FieldNameMinifier(appInfo, rootSet, options).computeRenaming(timing);
+ FieldRenaming fieldRenaming = new FieldNameMinifier(appView, rootSet).computeRenaming(timing);
timing.end();
NamingLens lens = new MinifiedRenaming(classRenaming, methodRenaming, fieldRenaming, appInfo);
diff --git a/src/test/java/com/android/tools/r8/naming/NamingTestBase.java b/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
index 7b6052a..4dcb52f 100644
--- a/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
+++ b/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.shaking.Enqueuer;
+import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.shaking.ProguardConfiguration;
import com.android.tools.r8.shaking.RootSetBuilder;
import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
@@ -74,9 +75,12 @@
new RootSetBuilder(appView, program, configuration.getRules(), options).run(executor);
Enqueuer enqueuer = new Enqueuer(appView, options, null, options.forceProguardCompatibility);
- AppInfoWithSubtyping appInfo =
+ AppInfoWithLiveness appInfo =
enqueuer.traceApplication(rootSet, configuration.getDontWarnPatterns(), executor, timing);
- return new Minifier(appInfo.withLiveness(), rootSet, Collections.emptySet(), options)
+ return new Minifier(
+ new AppView<>(appInfo, GraphLense.getIdentityLense(), options),
+ rootSet,
+ Collections.emptySet())
.run(timing);
}
diff --git a/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java b/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java
index 32e8e4d..659a8fc 100644
--- a/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java
+++ b/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java
@@ -7,20 +7,21 @@
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
import static org.hamcrest.CoreMatchers.allOf;
-import static org.hamcrest.CoreMatchers.anyOf;
-import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.graph.DexAnnotationElement;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.DexValue.DexValueArray;
import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.AnnotationSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
@@ -28,7 +29,7 @@
public class B124357885Test extends TestBase {
- private void checkSignatureAnnotation(AnnotationSubject signature) {
+ private void checkSignatureAnnotation(CodeInspector inspector, AnnotationSubject signature) {
DexAnnotationElement[] elements = signature.getAnnotation().elements;
assertEquals(1, elements.length);
assertEquals("value", elements[0].name.toString());
@@ -39,20 +40,22 @@
assertTrue(value instanceof DexValueString);
builder.append(((DexValueString) value).value);
}
- // TODO(124357885): This should be the minified name for FooImpl instead of Foo.
- String fooDescriptor = DescriptorUtils.javaTypeToDescriptor(Foo.class.getTypeName());
+ String fooImplFinalDescriptor =
+ DescriptorUtils.javaTypeToDescriptor(inspector.clazz(FooImpl.class).getFinalName());
StringBuilder expected =
new StringBuilder()
.append("()")
- .append(fooDescriptor.substring(0, fooDescriptor.length() - 1)) // Remove the ;.
+ // Remove the final ; from the descriptor to add the generic type.
+ .append(fooImplFinalDescriptor.substring(0, fooImplFinalDescriptor.length() - 1))
.append("<Ljava/lang/String;>")
- .append(";"); // Add the ; here.
+ // Add the ; after the generic type.
+ .append(";");
assertEquals(expected.toString(), builder.toString());
}
@Test
public void test() throws Exception {
- testForR8(Backend.DEX)
+ R8TestCompileResult compileResult = testForR8(Backend.DEX)
.addProgramClasses(Main.class, Service.class, Foo.class, FooImpl.class)
.addKeepMainRule(Main.class)
.addKeepRules("-keepattributes Signature,InnerClasses,EnclosingMethod")
@@ -66,17 +69,14 @@
assertEquals(1, inspector.clazz(Service.class).allMethods().size());
MethodSubject fooList = inspector.clazz(Service.class).allMethods().get(0);
AnnotationSubject signature = fooList.annotation("dalvik.annotation.Signature");
- checkSignatureAnnotation(signature);
- })
- .run(Main.class)
- .assertFailureWithErrorThatMatches(
- anyOf(
- containsString(
- "java.lang.ClassNotFoundException: "
- + "Didn't find class \"com.android.tools.r8.naming.b124357885.Foo\""),
- containsString(
- "java.lang.NoClassDefFoundError: "
- + "com/android/tools/r8/naming/b124357885/Foo")));
+ checkSignatureAnnotation(inspector, signature);
+ });
+
+ String fooImplFinalName = compileResult.inspector().clazz(FooImpl.class).getFinalName();
+
+ compileResult
+ .run(Main.class)
+ .assertSuccessWithOutput(StringUtils.lines(fooImplFinalName, fooImplFinalName));
}
}
@@ -89,7 +89,7 @@
// Convince R8 we only use subtypes to get class merging of Foo into FooImpl.
Foo<String> foo = new FooImpl<>();
- System.out.println(foo);
+ System.out.println(foo.getClass().getTypeName());
}
}