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());
   }
 }