Version 2.0.85

Cherry pick: Add test reproducing lack of signature rewriting when
desugaring
CL: https://r8-review.googlesource.com/52041

Cherry pick: Change GenericSignatureRewriter to use a naming lens
CL: https://r8-review.googlesource.com/52044

Cherry pick: Should not use withLiveness as input to GenericSignatureRewriter
CL: https://r8-review.googlesource.com/52090

Bug: 158124557
Change-Id: Ib475c534bc3e5f5bd7aba54d50ea33dbe2a72c3f
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index cf5e6c8..713f1eb 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -20,7 +20,9 @@
 import com.android.tools.r8.ir.desugar.PrefixRewritingMapper;
 import com.android.tools.r8.ir.optimize.AssertionsRewriter;
 import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
+import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.naming.PrefixRewritingNamingLens;
+import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
 import com.android.tools.r8.origin.CommandLineOrigin;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.CfgPrinter;
@@ -172,8 +174,8 @@
         }
       }
 
-      IRConverter converter =
-          new IRConverter(AppView.createForD8(appInfo, options, rewritePrefix), timing, printer);
+      AppView<AppInfo> appView = AppView.createForD8(appInfo, options, rewritePrefix);
+      IRConverter converter = new IRConverter(appView, timing, printer);
       app = converter.convert(app, executor);
 
       if (options.printCfg) {
@@ -212,13 +214,18 @@
         markers.add(marker);
       }
 
+      NamingLens namingLens =
+          PrefixRewritingNamingLens.createPrefixRewritingNamingLens(options, rewritePrefix);
+
+      new GenericSignatureRewriter(appView, namingLens).run(appView.appInfo().classes());
+
       new ApplicationWriter(
               app,
               null,
               options,
               marker == null ? null : ImmutableList.copyOf(markers),
               GraphLense.getIdentityLense(),
-              PrefixRewritingNamingLens.createPrefixRewritingNamingLens(options, rewritePrefix),
+              namingLens,
               null)
           .write(executor);
       options.printWarnings();
diff --git a/src/main/java/com/android/tools/r8/L8.java b/src/main/java/com/android/tools/r8/L8.java
index a692e1d..9fcccc6 100644
--- a/src/main/java/com/android/tools/r8/L8.java
+++ b/src/main/java/com/android/tools/r8/L8.java
@@ -15,7 +15,9 @@
 import com.android.tools.r8.ir.conversion.IRConverter;
 import com.android.tools.r8.ir.desugar.PrefixRewritingMapper;
 import com.android.tools.r8.jar.CfApplicationWriter;
+import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.naming.PrefixRewritingNamingLens;
+import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
 import com.android.tools.r8.origin.CommandLineOrigin;
 import com.android.tools.r8.shaking.AnnotationRemover;
 import com.android.tools.r8.shaking.L8TreePruner;
@@ -127,13 +129,17 @@
       app = converter.convert(app, executor);
       assert appView.appInfo() == appInfo;
 
+      NamingLens namingLens =
+          PrefixRewritingNamingLens.createPrefixRewritingNamingLens(options, rewritePrefix);
+      new GenericSignatureRewriter(appView, namingLens).run(appInfo.classes());
+
       new CfApplicationWriter(
               app,
               appView,
               options,
               options.getMarker(Tool.L8),
               GraphLense.getIdentityLense(),
-              PrefixRewritingNamingLens.createPrefixRewritingNamingLens(options, rewritePrefix),
+              namingLens,
               null)
           .write(options.getClassFileConsumer(), executor);
       options.printWarnings();
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 462a4ae..e9ea099 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -719,11 +719,6 @@
             new Minifier(appView.withLiveness(), desugaredCallSites).run(executorService, timing);
         timing.end();
       } else {
-        // Rewrite signature annotations for applications that are not minified.
-        if (appView.appInfo().hasLiveness()) {
-          // TODO(b/124726014): Rewrite signature annotations in lens rewriting instead of here?
-          new GenericSignatureRewriter(appView.withLiveness()).run(appView.appInfo().classes());
-        }
         namingLens = NamingLens.getIdentityLens();
       }
 
@@ -784,14 +779,20 @@
         options.syntheticProguardRulesConsumer.accept(synthesizedProguardRules);
       }
 
+      NamingLens prefixRewritingNamingLens =
+          PrefixRewritingNamingLens.createPrefixRewritingNamingLens(
+              options, appView.rewritePrefix, namingLens);
+
+      new GenericSignatureRewriter(appView, prefixRewritingNamingLens)
+          .run(appView.appInfo().classes());
+
       // Generate the resulting application resources.
       writeApplication(
           executorService,
           application,
           appView,
           appView.graphLense(),
-          PrefixRewritingNamingLens.createPrefixRewritingNamingLens(
-              options, appView.rewritePrefix, namingLens),
+          prefixRewritingNamingLens,
           options,
           proguardMapSupplier);
 
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 492d049..bc4c231 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.0.84";
+  public static final String LABEL = "2.0.85";
 
   private Version() {
   }
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 512dde8..468cdcc 100644
--- a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
@@ -13,26 +13,22 @@
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexProto;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.InnerClassAttribute;
 import com.android.tools.r8.kotlin.KotlinMetadataRewriter;
-import com.android.tools.r8.naming.signature.GenericSignatureRewriter;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.shaking.ProguardPackageNameList;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.InternalOptions.PackageObfuscationMode;
-import com.android.tools.r8.utils.IteratorUtils;
 import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -145,18 +141,6 @@
     }
     timing.end();
 
-    timing.begin("rename-generic");
-    new GenericSignatureRewriter(appView, renaming)
-        .run(
-            new Iterable<DexProgramClass>() {
-              @Override
-              public Iterator<DexProgramClass> iterator() {
-                return IteratorUtils.<DexClass, DexProgramClass>filter(
-                    classes.iterator(), DexClass::isProgramClass);
-              }
-            });
-    timing.end();
-
     timing.begin("rename-arrays");
     appView.dexItemFactory().forAllTypes(this::renameArrayTypeIfNeeded);
     timing.end();
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 7747eda..1851249 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
@@ -14,14 +14,13 @@
 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.naming.NamingLens;
 import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.Reporter;
 import com.android.tools.r8.utils.StringDiagnostic;
-import com.google.common.collect.Maps;
 import java.lang.reflect.GenericSignatureFormatError;
-import java.util.Map;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
@@ -29,22 +28,24 @@
 
 public class GenericSignatureRewriter {
 
-  private final AppView<AppInfoWithLiveness> appView;
-  private final Map<DexType, DexString> renaming;
+  private final AppView<?> appView;
+  private final NamingLens namingLens;
+  private final InternalOptions options;
   private final Reporter reporter;
 
-  public GenericSignatureRewriter(AppView<AppInfoWithLiveness> appView) {
-    this(appView, Maps.newIdentityHashMap());
-  }
-
-  public GenericSignatureRewriter(
-      AppView<AppInfoWithLiveness> appView, Map<DexType, DexString> renaming) {
+  public GenericSignatureRewriter(AppView<?> appView, NamingLens namingLens) {
     this.appView = appView;
-    this.renaming = renaming;
-    this.reporter = appView.options().reporter;
+    this.namingLens = namingLens;
+    this.options = appView.options();
+    this.reporter = options.reporter;
   }
 
   public void run(Iterable<? extends DexProgramClass> classes) {
+    // Rewrite signature annotations for applications that are minified or if we have liveness
+    // information, since we could have pruned types.
+    if (namingLens.isIdentityLens() && !appView.appInfo().hasLiveness()) {
+      return;
+    }
     final GenericSignatureCollector genericSignatureCollector = new GenericSignatureCollector();
     final GenericSignatureParser<DexType> genericSignatureParser =
         new GenericSignatureParser<>(genericSignatureCollector);
@@ -195,10 +196,10 @@
       String originalDescriptor = getDescriptorFromClassBinaryName(name);
       DexType type =
           appView.graphLense().lookupType(appView.dexItemFactory().createType(originalDescriptor));
-      if (appView.appInfo().wasPruned(type)) {
+      if (appView.appInfo().hasLiveness() && appView.appInfo().withLiveness().wasPruned(type)) {
         type = appView.dexItemFactory().objectType;
       }
-      DexString renamedDescriptor = renaming.getOrDefault(type, type.descriptor);
+      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.
@@ -245,16 +246,14 @@
                       getClassBinaryNameFromDescriptor(enclosingDescriptor)
                           + DescriptorUtils.INNER_CLASS_SEPARATOR
                           + name));
-      String enclosingRenamedBinaryName =
-          getClassBinaryNameFromDescriptor(
-              renaming.getOrDefault(enclosingType, enclosingType.descriptor).toString());
       type = appView.graphLense().lookupType(type);
-      DexString renamedDescriptor = renaming.get(type);
-      if (renamedDescriptor != null) {
+      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.toString());
+        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));
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredGenericSignatureTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredGenericSignatureTest.java
new file mode 100644
index 0000000..ff07b24
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredGenericSignatureTest.java
@@ -0,0 +1,129 @@
+// 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.desugar.desugaredlibrary;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.shaking.ProguardKeepAttributes;
+import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import java.time.LocalDate;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class DesugaredGenericSignatureTest extends DesugaredLibraryTestBase {
+
+  private final TestParameters parameters;
+  private final boolean shrinkDesugaredLibrary;
+  private static final String EXPECTED = StringUtils.lines("1970", "1", "2");
+
+  @Parameters(name = "{1}, shrinkDesugaredLibrary: {0}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withDexRuntimes().withAllApiLevels().build(), BooleanUtils.values());
+  }
+
+  public DesugaredGenericSignatureTest(TestParameters parameters, boolean shrinkDesugaredLibrary) {
+    this.parameters = parameters;
+    this.shrinkDesugaredLibrary = shrinkDesugaredLibrary;
+  }
+
+  @Test
+  public void testD8() throws Exception {
+    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
+    testForD8()
+        .addInnerClasses(DesugaredGenericSignatureTest.class)
+        .setMinApi(parameters.getApiLevel())
+        .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
+        .setIncludeClassesChecksum(true)
+        .compile()
+        .inspect(this::checkRewrittenSignature)
+        .addDesugaredCoreLibraryRunClassPath(
+            this::buildDesugaredLibrary,
+            parameters.getApiLevel(),
+            keepRuleConsumer.get(),
+            shrinkDesugaredLibrary)
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutput(EXPECTED);
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
+    testForR8(parameters.getBackend())
+        .addInnerClasses(DesugaredGenericSignatureTest.class)
+        .addKeepMainRule(Main.class)
+        .addKeepAllClassesRuleWithAllowObfuscation()
+        .addKeepAttributes(
+            ProguardKeepAttributes.SIGNATURE,
+            ProguardKeepAttributes.INNER_CLASSES,
+            ProguardKeepAttributes.ENCLOSING_METHOD)
+        .enableInliningAnnotations()
+        .setMinApi(parameters.getApiLevel())
+        .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
+        .compile()
+        .inspect(this::checkRewrittenSignature)
+        .addDesugaredCoreLibraryRunClassPath(
+            this::buildDesugaredLibrary,
+            parameters.getApiLevel(),
+            keepRuleConsumer.get(),
+            shrinkDesugaredLibrary)
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutput(EXPECTED);
+  }
+
+  private void checkRewrittenSignature(CodeInspector inspector) {
+    if (!requiresEmulatedInterfaceCoreLibDesugaring(parameters)) {
+      return;
+    }
+    ClassSubject javaTimeBox = inspector.clazz(JavaTimeDateBox.class);
+    assertThat(javaTimeBox, isPresent());
+    ClassSubject box = inspector.clazz(Box.class);
+    assertThat(box, isPresent());
+    String finalBoxDescriptor = box.getFinalDescriptor();
+    assertEquals(
+        "Ljava/lang/Object;"
+            + finalBoxDescriptor.substring(0, finalBoxDescriptor.length() - 1)
+            + "<Lj$/time/LocalDate;>;",
+        javaTimeBox.getFinalSignatureAttribute());
+  }
+
+  public interface Box<T> {
+    T addOne(T t);
+  }
+
+  public static class JavaTimeDateBox implements Box<java.time.LocalDate> {
+
+    @Override
+    @NeverInline
+    public LocalDate addOne(LocalDate localDate) {
+      return localDate.plusDays(1);
+    }
+  }
+
+  public static class Main {
+
+    public static Box<java.time.LocalDate> bar() {
+      return new JavaTimeDateBox();
+    }
+
+    public static void main(String[] args) {
+      LocalDate localDate = bar().addOne(LocalDate.of(1970, 1, 1));
+      System.out.println(localDate.getYear());
+      System.out.println(localDate.getMonthValue());
+      System.out.println(localDate.getDayOfMonth());
+    }
+  }
+}