Use DexString/Type in RetargetCoreLib

Bug: 134732760
Change-Id: I25751fb53a0758d6360464b3e2fc6390b0b25c4b
diff --git a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
index 9918583..fc8d448 100644
--- a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
+++ b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
@@ -458,10 +458,10 @@
         if (desugaredLibraryConfigurationResource.getString().equals("default")) {
           if (libraryCompilation) {
             return DesugaredLibraryConfigurationForTesting
-                .configureLibraryDesugaringForLibraryCompilation(minAPILevel);
+                .configureLibraryDesugaringForLibraryCompilation(minAPILevel, factory);
           }
           return DesugaredLibraryConfigurationForTesting
-              .configureLibraryDesugaringForProgramCompilation(minAPILevel);
+              .configureLibraryDesugaringForProgramCompilation(minAPILevel, factory);
         }
       } catch (ResourceException e) {
         throw new RuntimeException(e);
@@ -473,8 +473,8 @@
       return libraryParser.parse(desugaredLibraryConfigurationResource);
     }
 
-    boolean hasDesugaredLibraryConfiguration(){
-      return desugaredLibraryConfigurationResources.size() == 1;
+    boolean hasDesugaredLibraryConfiguration() {
+      return !desugaredLibraryConfigurationResources.isEmpty();
     }
 
     /** Encodes checksum for each class when generating dex files. */
@@ -520,7 +520,7 @@
         }
         reporter.error(builder.toString());
       }
-      if (!desugaredLibraryConfigurationResources.isEmpty()) {
+      if (hasDesugaredLibraryConfiguration()) {
         reporter.warning(
             new StringDiagnostic("Desugared library configuration is still work in progress"));
       }
diff --git a/src/main/java/com/android/tools/r8/DesugaredLibraryConfigurationForTesting.java b/src/main/java/com/android/tools/r8/DesugaredLibraryConfigurationForTesting.java
index 90d232b..4229c4d 100644
--- a/src/main/java/com/android/tools/r8/DesugaredLibraryConfigurationForTesting.java
+++ b/src/main/java/com/android/tools/r8/DesugaredLibraryConfigurationForTesting.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8;
 
+import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.ir.desugar.DesugaredLibraryConfiguration;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.google.common.collect.ImmutableList;
@@ -184,8 +185,7 @@
   }
 
   public static DesugaredLibraryConfiguration configureLibraryDesugaringForProgramCompilation(
-      int minApiLevel) {
-    // TODO(b/134732760): Make assertions in D8/R8 commands.
+      int minApiLevel, DexItemFactory factory) {
     if (minApiLevel >= AndroidApiLevel.O.getLevel()) {
       return DesugaredLibraryConfiguration.empty();
     }
@@ -206,7 +206,8 @@
       rewritePrefix = buildPrefixRewritingForProgramCompilationAndroidNPlus();
       retargetCoreLibMember = buildRetargetCoreLibraryMemberForProgramCompilationAndroidNPlus();
     }
-    return new DesugaredLibraryConfiguration(
+    return createDesugaredLibraryConfiguration(
+        factory,
         false,
         rewritePrefix,
         emulateLibraryInterface,
@@ -216,8 +217,7 @@
   }
 
   public static DesugaredLibraryConfiguration configureLibraryDesugaringForLibraryCompilation(
-      int minApiLevel) {
-    // TODO(b/134732760): Make assertions in L8 commands.
+      int minApiLevel, DexItemFactory factory) {
     if (minApiLevel >= AndroidApiLevel.O.getLevel()) {
       return DesugaredLibraryConfiguration.empty();
     }
@@ -238,7 +238,8 @@
     } else {
       rewritePrefix = buildPrefixRewritingForCoreLibCompilationAndroidNPlus();
     }
-    return new DesugaredLibraryConfiguration(
+    return createDesugaredLibraryConfiguration(
+        factory,
         true,
         rewritePrefix,
         emulateLibraryInterface,
@@ -246,4 +247,36 @@
         backportCoreLibraryMembers,
         dontRewriteInvocations);
   }
+
+  public static DesugaredLibraryConfiguration createDesugaredLibraryConfiguration(
+      DexItemFactory factory,
+      boolean libraryCompilation,
+      Map<String, String> rewritePrefix,
+      Map<String, String> emulateLibraryInterface,
+      Map<String, String> retargetCoreLibMember,
+      Map<String, String> backportCoreLibraryMembers,
+      List<String> dontRewriteInvocations) {
+    DesugaredLibraryConfiguration.Builder builder = DesugaredLibraryConfiguration.builder(factory);
+    if (libraryCompilation) {
+      builder.setLibraryCompilation();
+    } else {
+      builder.setProgramCompilation();
+    }
+    for (String key : rewritePrefix.keySet()) {
+      builder.putRewritePrefix(key, rewritePrefix.get(key));
+    }
+    for (String key : emulateLibraryInterface.keySet()) {
+      builder.putEmulateLibraryInterface(key, emulateLibraryInterface.get(key));
+    }
+    for (String key : retargetCoreLibMember.keySet()) {
+      builder.putRetargetCoreLibMember(key, retargetCoreLibMember.get(key));
+    }
+    for (String key : backportCoreLibraryMembers.keySet()) {
+      builder.putBackportCoreLibraryMember(key, backportCoreLibraryMembers.get(key));
+    }
+    for (String key : dontRewriteInvocations) {
+      builder.addDontRewriteInvocation(key);
+    }
+    return builder.build();
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
index 95724de..72bba94 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
@@ -936,10 +936,8 @@
     }
 
     private void initializeRetargetCoreLibraryMembers(AppView<?> appView) {
-      Map<DexString, Map<DexType, DexType>> retargetCoreLibMember = new IdentityHashMap<>();
-      appView
-          .options()
-          .populateRetargetCoreLibMember(appView.dexItemFactory(), retargetCoreLibMember);
+      Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
+          appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember();
       for (DexString methodName : retargetCoreLibMember.keySet()) {
         for (DexType inType : retargetCoreLibMember.get(methodName).keySet()) {
           DexClass typeClass = appView.definitionFor(inType);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfiguration.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfiguration.java
index c98378a..6174129 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfiguration.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfiguration.java
@@ -4,12 +4,16 @@
 
 package com.android.tools.r8.ir.desugar;
 
+import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.utils.Reporter;
+import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.utils.DescriptorUtils;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -19,12 +23,12 @@
   private final boolean libraryCompilation;
   private final Map<String, String> rewritePrefix;
   private final Map<String, String> emulateLibraryInterface;
-  private final Map<String, String> retargetCoreLibMember;
+  private final Map<DexString, Map<DexType, DexType>> retargetCoreLibMember;
   private final Map<String, String> backportCoreLibraryMember;
   private final List<String> dontRewriteInvocation;
 
-  public static Builder builder(DexItemFactory dexItemFactory, Reporter reporter) {
-    return new Builder(dexItemFactory, reporter);
+  public static Builder builder(DexItemFactory dexItemFactory) {
+    return new Builder(dexItemFactory);
   }
 
   public static DesugaredLibraryConfiguration empty() {
@@ -41,7 +45,7 @@
       boolean libraryCompilation,
       Map<String, String> rewritePrefix,
       Map<String, String> emulateLibraryInterface,
-      Map<String, String> retargetCoreLibMember,
+      Map<DexString, Map<DexType, DexType>> retargetCoreLibMember,
       Map<String, String> backportCoreLibraryMember,
       List<String> dontRewriteInvocation) {
     this.libraryCompilation = libraryCompilation;
@@ -64,7 +68,7 @@
     return emulateLibraryInterface;
   }
 
-  public Map<String, String> getRetargetCoreLibMember() {
+  public Map<DexString, Map<DexType, DexType>> getRetargetCoreLibMember() {
     return retargetCoreLibMember;
   }
 
@@ -79,18 +83,16 @@
   public static class Builder {
 
     private final DexItemFactory factory;
-    private final Reporter reporter;
 
     private boolean libraryCompilation = false;
     private Map<String, String> rewritePrefix = new HashMap<>();
     private Map<String, String> emulateLibraryInterface = new HashMap<>();
-    private Map<String, String> retargetCoreLibMember = new HashMap<>();
+    private Map<DexString, Map<DexType, DexType>> retargetCoreLibMember = new IdentityHashMap<>();
     private Map<String, String> backportCoreLibraryMember = new HashMap<>();
     private List<String> dontRewriteInvocation = new ArrayList<>();
 
-    public Builder(DexItemFactory dexItemFactory, Reporter reporter) {
+    public Builder(DexItemFactory dexItemFactory) {
       this.factory = dexItemFactory;
-      this.reporter = reporter;
     }
 
     public Builder setProgramCompilation() {
@@ -115,7 +117,20 @@
     }
 
     public Builder putRetargetCoreLibMember(String retarget, String rewrittenRetarget) {
-      retargetCoreLibMember.put(retarget, rewrittenRetarget);
+      int index = retarget.lastIndexOf('#');
+      if (index <= 0 || index >= retarget.length() - 1) {
+        throw new CompilationError(
+            "Invalid retarget core library member specification (# position) in " + retarget + ".");
+      }
+      DexString methodName = factory.createString(retarget.substring(index + 1));
+      retargetCoreLibMember.putIfAbsent(methodName, new IdentityHashMap<>());
+      Map<DexType, DexType> typeMap = retargetCoreLibMember.get(methodName);
+      DexType originalType =
+          factory.createType(DescriptorUtils.javaTypeToDescriptor(retarget.substring(0, index)));
+      DexType finalType =
+          factory.createType(DescriptorUtils.javaTypeToDescriptor(rewrittenRetarget));
+      assert !typeMap.containsKey(originalType);
+      typeMap.put(originalType, finalType);
       return this;
     }
 
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfigurationParser.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfigurationParser.java
index 73ddfa2..f5664d3 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryConfigurationParser.java
@@ -29,7 +29,7 @@
       boolean libraryCompilation,
       int minAPILevel) {
     this.reporter = reporter;
-    this.configurationBuilder = DesugaredLibraryConfiguration.builder(dexItemFactory, reporter);
+    this.configurationBuilder = DesugaredLibraryConfiguration.builder(dexItemFactory);
     this.minAPILevel = minAPILevel;
     this.libraryCompilation = libraryCompilation;
     if (libraryCompilation) {
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 e812686..5d3ac38 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
@@ -102,7 +102,6 @@
   private final Map<DexType, DexType> emulatedInterfaces = new IdentityHashMap<>();
   private final List<Pair<DexType, DexString>> dontRewriteCoreInvocations = new ArrayList<>();
   private final Map<String, String> prefixRewritingInterfaces = new IdentityHashMap<>();
-  private final Map<DexString, Map<DexType, DexType>> retargetCoreMember = new IdentityHashMap<>();
   // The emulatedMethod set is there to avoid doing the emulated look-up too often.
   private final Set<DexString> emulatedMethods = Sets.newIdentityHashSet();
   private ConcurrentHashMap<DexMethod, DexType> nearestEmulatedInterfaceCache =
@@ -165,9 +164,6 @@
         }
       }
     }
-    if (appView.options().isDesugaredLibraryCompilation()) {
-      options.populateRetargetCoreLibMember(factory, retargetCoreMember);
-    }
     for (String dontRewrite : options.desugaredLibraryConfiguration.getDontRewriteInvocation()) {
       int index = dontRewrite.lastIndexOf('#');
       if (index <= 0 || index >= dontRewrite.length() - 1) {
@@ -681,16 +677,18 @@
         List<Pair<DexType, DexMethod>> extraDispatchCases = new ArrayList<>();
         // In practice, there is usually a single case (except for tests),
         // so we do not bother to make the following loop more clever.
-        for (DexString methodName : retargetCoreMember.keySet()) {
+        Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
+            options.desugaredLibraryConfiguration.getRetargetCoreLibMember();
+        for (DexString methodName : retargetCoreLibMember.keySet()) {
           if (method.method.name == methodName) {
-            for (DexType inType : retargetCoreMember.get(methodName).keySet()) {
+            for (DexType inType : retargetCoreLibMember.get(methodName).keySet()) {
               DexClass inClass = appView.definitionFor(inType);
               if (inClass != null && implementsInterface(inClass, theInterface.type)) {
                 extraDispatchCases.add(
                     new Pair<>(
                         inType,
                         factory.createMethod(
-                            retargetCoreMember.get(methodName).get(inType),
+                            retargetCoreLibMember.get(methodName).get(inType),
                             factory.protoWithDifferentFirstParameter(
                                 originalCompanionMethod.proto, inType),
                             method.method.name)));
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 998e9c2..37a1060 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -29,7 +29,6 @@
 import com.android.tools.r8.graph.DexItem;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.desugar.DesugaredLibraryConfiguration;
@@ -54,7 +53,6 @@
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.HashMap;
-import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -444,29 +442,6 @@
    */
   public boolean enableInheritanceClassInDexDistributor = true;
 
-  public void populateRetargetCoreLibMember(
-      DexItemFactory factory, Map<DexString, Map<DexType, DexType>> dest) {
-    Map<String, String> retargetCoreLibMember =
-        desugaredLibraryConfiguration.getRetargetCoreLibMember();
-    for (String inputString : retargetCoreLibMember.keySet()) {
-      int index = inputString.lastIndexOf('#');
-      if (index <= 0 || index >= inputString.length() - 1) {
-        throw new CompilationError(
-            "Invalid retarget core library member specification (# position).");
-      }
-      DexString methodName = factory.createString(inputString.substring(index + 1));
-      dest.putIfAbsent(methodName, new IdentityHashMap<>());
-      Map<DexType, DexType> typeMap = dest.get(methodName);
-      DexType originalType =
-          factory.createType(DescriptorUtils.javaTypeToDescriptor(inputString.substring(0, index)));
-      DexType finalType =
-          factory.createType(
-              DescriptorUtils.javaTypeToDescriptor(retargetCoreLibMember.get(inputString)));
-      assert !typeMap.containsKey(originalType);
-      typeMap.put(originalType, finalType);
-    }
-  }
-
   public LineNumberOptimization lineNumberOptimization = LineNumberOptimization.ON;
 
   public static boolean shouldEnableKeepRuleSynthesisForRecompilation() {
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/JsonCompatibilityTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/JsonCompatibilityTest.java
index 7f78f21..1f0da0b 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/JsonCompatibilityTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/JsonCompatibilityTest.java
@@ -13,6 +13,8 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.desugar.DesugaredLibraryConfigurationParser;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.Reporter;
@@ -38,13 +40,13 @@
 
   @Test
   public void testCompatibilityProgram() {
-    InternalOptions options1 = new InternalOptions(new DexItemFactory(), new Reporter());
+    DexItemFactory factory = new DexItemFactory();
+    InternalOptions options1 = new InternalOptions(factory, new Reporter());
     options1.minApiLevel = parameters.getApiLevel().getLevel();
     options1.desugaredLibraryConfiguration =
         DesugaredLibraryConfigurationForTesting.configureLibraryDesugaringForProgramCompilation(
-            parameters.getApiLevel().getLevel());
+            parameters.getApiLevel().getLevel(), factory);
 
-    DexItemFactory factory = new DexItemFactory();
     Reporter reporter = new Reporter();
     InternalOptions options2 = new InternalOptions(factory, reporter);
     options2.minApiLevel = parameters.getApiLevel().getLevel();
@@ -62,13 +64,13 @@
 
   @Test
   public void testCompatibilityLibrary() {
-    InternalOptions options1 = new InternalOptions(new DexItemFactory(), new Reporter());
+    DexItemFactory factory = new DexItemFactory();
+    InternalOptions options1 = new InternalOptions(factory, new Reporter());
     options1.minApiLevel = parameters.getApiLevel().getLevel();
     options1.desugaredLibraryConfiguration =
         DesugaredLibraryConfigurationForTesting.configureLibraryDesugaringForLibraryCompilation(
-            parameters.getApiLevel().getLevel());
+            parameters.getApiLevel().getLevel(), factory);
 
-    DexItemFactory factory = new DexItemFactory();
     Reporter reporter = new Reporter();
     InternalOptions options2 = new InternalOptions(factory, reporter);
     options2.minApiLevel = parameters.getApiLevel().getLevel();
@@ -95,7 +97,7 @@
     assertDictEquals(
         libraryConfiguration1.getBackportCoreLibraryMember(),
         libraryConfiguration2.getBackportCoreLibraryMember());
-    assertDictEquals(
+    assertRetargetEquals(
         libraryConfiguration1.getRetargetCoreLibMember(),
         libraryConfiguration2.getRetargetCoreLibMember());
     assertEquals(
@@ -103,9 +105,19 @@
         libraryConfiguration1.getDontRewriteInvocation().size());
   }
 
-  private void assertDictEquals(Map<String, String> map1, Map<String, String> map2) {
+  private void assertRetargetEquals(
+      Map<DexString, Map<DexType, DexType>> retarget1,
+      Map<DexString, Map<DexType, DexType>> retarget2) {
+    assertEquals(retarget1.size(), retarget2.size());
+    for (DexString dexString : retarget1.keySet()) {
+      assert retarget2.containsKey(dexString);
+      assertDictEquals(retarget1.get(dexString), retarget2.get(dexString));
+    }
+  }
+
+  private <E> void assertDictEquals(Map<E, E> map1, Map<E, E> map2) {
     assertEquals(map1.size(), map2.size());
-    for (String key : map1.keySet()) {
+    for (E key : map1.keySet()) {
       assertTrue(map2.containsKey(key) && map1.get(key).equals(map2.get(key)));
     }
   }