Add prefix rewriting of synthetics in emulated interfaces.

Bug: 158159959
Change-Id: I7c237a7bb9078fb41a2632440ae548e620e0240c
diff --git a/src/main/java/com/android/tools/r8/synthesis/SynthesizingContext.java b/src/main/java/com/android/tools/r8/synthesis/SynthesizingContext.java
index 93d1248..3625fbb 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SynthesizingContext.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SynthesizingContext.java
@@ -3,6 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.synthesis;
 
+import static com.android.tools.r8.utils.DescriptorUtils.getBinaryNameFromDescriptor;
+import static com.android.tools.r8.utils.DescriptorUtils.getDescriptorFromClassBinaryName;
+
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
@@ -91,6 +95,33 @@
     return synthesizingContextType;
   }
 
+  void registerPrefixRewriting(DexType hygienicType, AppView<?> appView) {
+    assert hygienicType.toSourceString().startsWith(synthesizingContextType.toSourceString());
+    if (!appView.options().isDesugaredLibraryCompilation()) {
+      return;
+    }
+    DexType rewrittenContext =
+        appView
+            .options()
+            .desugaredLibraryConfiguration
+            .getEmulateLibraryInterface()
+            .get(synthesizingContextType);
+    if (rewrittenContext == null) {
+      return;
+    }
+    String contextPrefix =
+        getBinaryNameFromDescriptor(synthesizingContextType.toDescriptorString());
+    String rewrittenPrefix = getBinaryNameFromDescriptor(rewrittenContext.toDescriptorString());
+    String suffix =
+        getBinaryNameFromDescriptor(hygienicType.toDescriptorString())
+            .substring(contextPrefix.length());
+    DexType rewrittenType =
+        appView
+            .dexItemFactory()
+            .createType(getDescriptorFromClassBinaryName(rewrittenPrefix + suffix));
+    appView.rewritePrefix.rewriteType(hygienicType, rewrittenType);
+  }
+
   void addIfDerivedFromMainDexClass(
       DexProgramClass externalSyntheticClass,
       MainDexClasses mainDexClasses,
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
index f8c58b7..5beed30 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
@@ -111,12 +111,11 @@
     List<DexProgramClass> finalSyntheticClasses = new ArrayList<>();
     Set<DexType> derivedMainDexTypesToIgnore = Sets.newIdentityHashSet();
     buildLensAndProgram(
-        application,
+        appView,
         equivalences,
         syntheticItems::containsKey,
         mainDexClasses,
         lensBuilder,
-        options,
         newProgramClasses,
         finalSyntheticClasses,
         derivedMainDexTypesToIgnore);
@@ -241,18 +240,17 @@
   }
 
   private static void buildLensAndProgram(
-      DexApplication app,
+      AppView<?> appView,
       Map<DexType, EquivalenceGroup<SyntheticMethodDefinition>> syntheticMethodGroups,
       Predicate<DexType> isSyntheticType,
       MainDexClasses mainDexClasses,
       Builder lensBuilder,
-      InternalOptions options,
       List<DexProgramClass> normalClasses,
       List<DexProgramClass> newSyntheticClasses,
       Set<DexType> derivedMainDexTypesToIgnore) {
-    DexItemFactory factory = options.itemFactory;
+    DexItemFactory factory = appView.dexItemFactory();
 
-    for (DexProgramClass clazz : app.classes()) {
+    for (DexProgramClass clazz : appView.appInfo().classes()) {
       if (!isSyntheticType.test(clazz.type)) {
         normalClasses.add(clazz);
       }
@@ -264,10 +262,10 @@
         mainDexType -> {
           derivedMainDexTypes.add(mainDexType);
           DexProgramClass mainDexClass =
-              DexProgramClass.asProgramClassOrNull(app.definitionFor(mainDexType));
+              DexProgramClass.asProgramClassOrNull(appView.definitionFor(mainDexType));
           if (mainDexClass != null) {
             derivedMainDexTypes.addAll(
-                DexAnnotation.readAnnotationSynthesizedClassMap(mainDexClass, options.itemFactory));
+                DexAnnotation.readAnnotationSynthesizedClassMap(mainDexClass, factory));
           }
         });
 
@@ -275,6 +273,7 @@
         (syntheticType, syntheticGroup) -> {
           SyntheticMethodDefinition representative = syntheticGroup.getRepresentative();
           SynthesizingContext context = representative.getContext();
+          context.registerPrefixRewriting(syntheticType, appView);
           SyntheticClassBuilder builder =
               new SyntheticClassBuilder(syntheticType, context, factory);
           // TODO(b/158159959): Support grouping multiple methods per synthetic class.
@@ -287,7 +286,7 @@
                     .setCode(m -> definition.getCode());
               });
           DexProgramClass externalSyntheticClass = builder.build();
-          if (shouldAnnotateSynthetics(options)) {
+          if (shouldAnnotateSynthetics(appView.options())) {
             externalSyntheticClass.setAnnotations(
                 externalSyntheticClass
                     .annotations()
@@ -313,7 +312,7 @@
             // TODO(b/168584485): Remove this once class-mapping support is removed.
             DexProgramClass from =
                 DexProgramClass.asProgramClassOrNull(
-                    app.definitionFor(member.getContext().getSynthesizingContextType()));
+                    appView.definitionFor(member.getContext().getSynthesizingContextType()));
             if (from != null) {
               externalSyntheticClass.addSynthesizedFrom(from);
             }