Hygienic type for DesugaredLibraryRetargeter

Bug: 188767735
Change-Id: I52cf1e9c57178575c38d24270e2f8318d265921b
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index fea728d..1843cea 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -397,10 +397,9 @@
     }
   }
 
-  private void synthesizeRetargetClass(Builder<?> builder, ExecutorService executorService)
-      throws ExecutionException {
+  private void synthesizeRetargetClass(ExecutorService executorService) throws ExecutionException {
     if (desugaredLibraryRetargeter != null) {
-      desugaredLibraryRetargeter.synthesizeRetargetClasses(builder, executorService, this);
+      desugaredLibraryRetargeter.synthesizeRetargetClasses(executorService, this);
     }
   }
 
@@ -442,7 +441,7 @@
     Builder<?> builder = application.builder().setHighestSortingString(highestSortingString);
 
     desugarInterfaceMethods(builder, ExcludeDexResources, executor);
-    synthesizeRetargetClass(builder, executor);
+    synthesizeRetargetClass(executor);
     processCovariantReturnTypeAnnotations(builder);
     generateDesugaredLibraryAPIWrappers(builder, executor);
 
@@ -780,7 +779,7 @@
     feedback.updateVisibleOptimizationInfo();
 
     printPhase("Utility classes synthesis");
-    synthesizeRetargetClass(builder, executorService);
+    synthesizeRetargetClass(executorService);
     synthesizeEnumUnboxingUtilityMethods(executorService);
 
     printPhase("Desugared library API Conversion finalization");
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 9ec7242..a069091 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
@@ -153,6 +153,17 @@
     return synthesizedLibraryClassesPackagePrefix;
   }
 
+  // TODO(b/183918843): We are currently computing a new name for the class by replacing the
+  //  initial package prefix by the synthesized library class package prefix, it would be better
+  //  to make the rewriting explicit in the desugared library json file.
+  public String convertJavaNameToDesugaredLibrary(DexType type) {
+    String prefix =
+        DescriptorUtils.getJavaTypeFromBinaryName(getSynthesizedLibraryClassesPackagePrefix());
+    String interfaceType = type.toString();
+    int firstPackage = interfaceType.indexOf('.');
+    return prefix + interfaceType.substring(firstPackage + 1);
+  }
+
   public String getIdentifier() {
     return identifier;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
index 5a96760..2460c25 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
@@ -8,11 +8,9 @@
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.ClassAccessFlags;
+import com.android.tools.r8.graph.ClasspathOrLibraryClass;
 import com.android.tools.r8.graph.DexAnnotationSet;
-import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.graph.DexApplication.Builder;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexClassAndMethod;
 import com.android.tools.r8.graph.DexEncodedField;
@@ -21,7 +19,6 @@
 import com.android.tools.r8.graph.DexLibraryClass;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexProgramClass.ChecksumSupplier;
 import com.android.tools.r8.graph.DexProto;
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
@@ -45,12 +42,15 @@
 import com.android.tools.r8.ir.conversion.IRConverter;
 import com.android.tools.r8.ir.synthetic.EmulateInterfaceSyntheticCfCodeProvider;
 import com.android.tools.r8.origin.SynthesizedOrigin;
-import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.synthesis.SyntheticClassBuilder;
+import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
+import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.StringDiagnostic;
 import com.android.tools.r8.utils.WorkList;
 import com.android.tools.r8.utils.collections.DexClassAndMethodSet;
 import com.android.tools.r8.utils.collections.SortedProgramMethodSet;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -67,10 +67,6 @@
 
 public class DesugaredLibraryRetargeter {
 
-  private static final String RETARGET_PACKAGE = "retarget/";
-  public static final String DESUGAR_LIB_RETARGET_CLASS_NAME_PREFIX =
-      "$r8$retargetLibraryMember$virtualDispatch";
-
   private final AppView<?> appView;
   private final Map<DexMethod, DexMethod> retargetLibraryMember = new IdentityHashMap<>();
   // Map nonFinalRewrite hold a methodName -> method mapping for methods which are rewritten while
@@ -80,27 +76,16 @@
   // Non final virtual library methods requiring generation of emulated dispatch.
   private final DexClassAndMethodSet emulatedDispatchMethods = DexClassAndMethodSet.create();
 
-  private final String packageAndClassDescriptorPrefix;
+  private final Set<DexProgramClass> programSynthesizedClasses = Sets.newConcurrentHashSet();
 
   public DesugaredLibraryRetargeter(AppView<?> appView) {
     this.appView = appView;
-    packageAndClassDescriptorPrefix =
-        getRetargetPackageAndClassPrefixDescriptor(appView.options().desugaredLibraryConfiguration);
     if (appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember().isEmpty()) {
       return;
     }
     new RetargetingSetup().setUpRetargeting();
   }
 
-  public static boolean isRetargetType(DexType type, InternalOptions options) {
-    if (options.desugaredLibraryConfiguration == null) {
-      return false;
-    }
-    return type.toDescriptorString()
-        .startsWith(
-            getRetargetPackageAndClassPrefixDescriptor(options.desugaredLibraryConfiguration));
-  }
-
   public static void checkForAssumedLibraryTypes(AppView<?> appView) {
     Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
         appView.options().desugaredLibraryConfiguration.getRetargetCoreLibMember();
@@ -225,50 +210,6 @@
     appView.options().reporter.warning(warning);
   }
 
-  private static void synthesizeClassWithUniqueMethod(
-      Builder<?> builder,
-      ClassAccessFlags accessFlags,
-      DexType type,
-      DexEncodedMethod uniqueMethod,
-      String origin,
-      AppView<?> appView) {
-    DexItemFactory factory = appView.dexItemFactory();
-    DexProgramClass newClass =
-        new DexProgramClass(
-            type,
-            null,
-            new SynthesizedOrigin(origin, BackportedMethodRewriter.class),
-            accessFlags,
-            factory.objectType,
-            DexTypeList.empty(),
-            null,
-            null,
-            Collections.emptyList(),
-            null,
-            Collections.emptyList(),
-            ClassSignature.noSignature(),
-            DexAnnotationSet.empty(),
-            DexEncodedField.EMPTY_ARRAY,
-            DexEncodedField.EMPTY_ARRAY,
-            uniqueMethod.isStatic()
-                ? new DexEncodedMethod[] {uniqueMethod}
-                : DexEncodedMethod.EMPTY_ARRAY,
-            uniqueMethod.isStatic()
-                ? DexEncodedMethod.EMPTY_ARRAY
-                : new DexEncodedMethod[] {uniqueMethod},
-            factory.getSkipNameValidationForTesting(),
-            getChecksumSupplier(uniqueMethod, appView));
-    appView.appInfo().addSynthesizedClassForLibraryDesugaring(newClass);
-    builder.addSynthesizedClass(newClass);
-  }
-
-  private static ChecksumSupplier getChecksumSupplier(DexEncodedMethod method, AppView<?> appView) {
-    if (!appView.options().encodeChecksums) {
-      return DexProgramClass::invalidChecksumRequest;
-    }
-    return c -> method.getReference().hashCode();
-  }
-
   // Used by the ListOfBackportedMethods utility.
   void visit(Consumer<DexMethod> consumer) {
     retargetLibraryMember.keySet().forEach(consumer);
@@ -386,8 +327,9 @@
                   } else if (!method.getAccessFlags().isFinal()) {
                     // Virtual rewrites require emulated dispatch for inheritance.
                     // The call is rewritten to the dispatch holder class instead.
-                    handleEmulateDispatch(appView, method);
-                    newHolder = dispatchHolderTypeFor(method);
+                    emulatedDispatchMethods.add(method);
+                    // TODO(b/188767735): Postpone until needed.
+                    newHolder = ensureEmulatedHolderDispatchMethod(method).type;
                   }
                 }
               }
@@ -476,23 +418,129 @@
       assert !found.isEmpty() : "Should have found a method (library specifications).";
       return found;
     }
-
-    private void handleEmulateDispatch(AppView<?> appView, DexClassAndMethod method) {
-      emulatedDispatchMethods.add(method);
-      if (!appView.options().isDesugaredLibraryCompilation()) {
-        // Add rewrite rules so keeps rules are correctly generated in the program.
-        DexType dispatchInterfaceType = dispatchInterfaceTypeFor(method);
-        appView.rewritePrefix.rewriteType(dispatchInterfaceType, dispatchInterfaceType);
-        DexType dispatchHolderType = dispatchHolderTypeFor(method);
-        appView.rewritePrefix.rewriteType(dispatchHolderType, dispatchHolderType);
-      }
-    }
   }
 
-  public void synthesizeRetargetClasses(
-      DexApplication.Builder<?> builder, ExecutorService executorService, IRConverter converter)
+  public void synthesizeRetargetClasses(ExecutorService executorService, IRConverter converter)
       throws ExecutionException {
-    new EmulatedDispatchTreeFixer().fixApp(builder, executorService, converter);
+    new EmulatedDispatchTreeFixer().fixApp(executorService, converter);
+    converter.optimizeSynthesizedClasses(programSynthesizedClasses, executorService);
+  }
+
+  private void rewriteType(DexType type) {
+    String newName =
+        appView.options().desugaredLibraryConfiguration.convertJavaNameToDesugaredLibrary(type);
+    DexType newType =
+        appView.dexItemFactory().createType(DescriptorUtils.javaTypeToDescriptor(newName));
+    appView.rewritePrefix.rewriteType(type, newType);
+  }
+
+  public DexClass ensureEmulatedHolderDispatchMethod(DexClassAndMethod emulatedDispatchMethod) {
+    DexClass interfaceClass = ensureEmulatedInterfaceDispatchMethod(emulatedDispatchMethod);
+    DexMethod itfMethod =
+        interfaceClass.lookupMethod(emulatedDispatchMethod.getReference()).getReference();
+    DexClass holderDispatch;
+    if (appView.options().isDesugaredLibraryCompilation()) {
+      holderDispatch =
+          appView
+              .getSyntheticItems()
+              .ensureFixedClass(
+                  SyntheticKind.RETARGET_CLASS,
+                  emulatedDispatchMethod.getHolder(),
+                  appView,
+                  classBuilder ->
+                      buildHolderDispatchMethod(classBuilder, emulatedDispatchMethod, itfMethod));
+      programSynthesizedClasses.add(holderDispatch.asProgramClass());
+    } else {
+      ClasspathOrLibraryClass context =
+          emulatedDispatchMethod.getHolder().asClasspathOrLibraryClass();
+      assert context != null;
+      holderDispatch =
+          appView
+              .getSyntheticItems()
+              .ensureFixedClasspathClass(
+                  SyntheticKind.RETARGET_CLASS,
+                  context,
+                  appView,
+                  classBuilder ->
+                      buildHolderDispatchMethod(classBuilder, emulatedDispatchMethod, itfMethod));
+    }
+    rewriteType(holderDispatch.type);
+    return holderDispatch;
+  }
+
+  public DexClass ensureEmulatedInterfaceDispatchMethod(DexClassAndMethod emulatedDispatchMethod) {
+    DexClass interfaceDispatch;
+    if (appView.options().isDesugaredLibraryCompilation()) {
+      interfaceDispatch =
+          appView
+              .getSyntheticItems()
+              .ensureFixedClass(
+                  SyntheticKind.RETARGET_INTERFACE,
+                  emulatedDispatchMethod.getHolder(),
+                  appView,
+                  classBuilder ->
+                      this.buildInterfaceDispatchMethod(classBuilder, emulatedDispatchMethod));
+      programSynthesizedClasses.add(interfaceDispatch.asProgramClass());
+    } else {
+      ClasspathOrLibraryClass context =
+          emulatedDispatchMethod.getHolder().asClasspathOrLibraryClass();
+      assert context != null;
+      interfaceDispatch =
+          appView
+              .getSyntheticItems()
+              .ensureFixedClasspathClass(
+                  SyntheticKind.RETARGET_INTERFACE,
+                  context,
+                  appView,
+                  classBuilder ->
+                      this.buildInterfaceDispatchMethod(classBuilder, emulatedDispatchMethod));
+    }
+    rewriteType(interfaceDispatch.type);
+    return interfaceDispatch;
+  }
+
+  private void buildInterfaceDispatchMethod(
+      SyntheticClassBuilder<?, ?> classBuilder, DexClassAndMethod emulatedDispatchMethod) {
+    classBuilder
+        .setInterface()
+        .addMethod(
+            methodBuilder -> {
+              MethodAccessFlags flags =
+                  MethodAccessFlags.fromSharedAccessFlags(
+                      Constants.ACC_PUBLIC | Constants.ACC_ABSTRACT | Constants.ACC_SYNTHETIC,
+                      false);
+              methodBuilder
+                  .setName(emulatedDispatchMethod.getName())
+                  .setProto(emulatedDispatchMethod.getProto())
+                  .setAccessFlags(flags);
+            });
+  }
+
+  private <SCB extends SyntheticClassBuilder<?, ?>> void buildHolderDispatchMethod(
+      SCB classBuilder, DexClassAndMethod emulatedDispatchMethod, DexMethod itfMethod) {
+    classBuilder.addMethod(
+        methodBuilder -> {
+          DexMethod desugarMethod =
+              appView
+                  .options()
+                  .desugaredLibraryConfiguration
+                  .retargetMethod(emulatedDispatchMethod, appView);
+          assert desugarMethod
+              != null; // This method is reached only for retarget core lib members.
+          methodBuilder
+              .setName(emulatedDispatchMethod.getName())
+              .setProto(desugarMethod.proto)
+              .setAccessFlags(MethodAccessFlags.createPublicStaticSynthetic())
+              .setCode(
+                  methodSig ->
+                      new EmulateInterfaceSyntheticCfCodeProvider(
+                              emulatedDispatchMethod.getHolderType(),
+                              desugarMethod,
+                              itfMethod,
+                              Collections.emptyList(),
+                              appView)
+                          .generateCfCode());
+        });
   }
 
   // The rewrite of virtual calls requires to go through emulate dispatch. This class is responsible
@@ -500,11 +548,9 @@
   // synthesize the interfaces and emulated dispatch classes in the desugared library.
   class EmulatedDispatchTreeFixer {
 
-    void fixApp(
-        DexApplication.Builder<?> builder, ExecutorService executorService, IRConverter converter)
-        throws ExecutionException {
+    void fixApp(ExecutorService executorService, IRConverter converter) throws ExecutionException {
       if (appView.options().isDesugaredLibraryCompilation()) {
-        synthesizeEmulatedDispatchMethods(builder);
+        synthesizeEmulatedDispatchMethods();
       } else {
         addInterfacesAndForwardingMethods(executorService, converter);
       }
@@ -574,8 +620,8 @@
       // We cannot use the ClassProcessor since this applies up to 26, while the ClassProcessor
       // applies up to 24.
       for (DexClassAndMethod method : methods) {
-        clazz.addExtraInterfaces(
-            Collections.singletonList(new ClassTypeSignature(dispatchInterfaceTypeFor(method))));
+        DexClass dexClass = ensureEmulatedInterfaceDispatchMethod(method);
+        clazz.addExtraInterfaces(Collections.singletonList(new ClassTypeSignature(dexClass.type)));
         if (clazz.lookupVirtualMethod(method.getReference()) == null) {
           DexEncodedMethod newMethod = createForwardingMethod(method, clazz);
           clazz.addVirtualMethod(newMethod);
@@ -596,156 +642,38 @@
           target, clazz, forwardMethod, appView.dexItemFactory());
     }
 
-    private void synthesizeEmulatedDispatchMethods(DexApplication.Builder<?> builder) {
+    private void synthesizeEmulatedDispatchMethods() {
       assert appView.options().isDesugaredLibraryCompilation();
       if (emulatedDispatchMethods.isEmpty()) {
         return;
       }
-      ClassAccessFlags itfAccessFlags =
-          ClassAccessFlags.fromSharedAccessFlags(
-              Constants.ACC_PUBLIC
-                  | Constants.ACC_SYNTHETIC
-                  | Constants.ACC_ABSTRACT
-                  | Constants.ACC_INTERFACE);
-      ClassAccessFlags holderAccessFlags =
-          ClassAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC);
       for (DexClassAndMethod emulatedDispatchMethod : emulatedDispatchMethods) {
-        // Dispatch interface.
-        DexType interfaceType = dispatchInterfaceTypeFor(emulatedDispatchMethod);
-        DexEncodedMethod itfMethod =
-            generateInterfaceDispatchMethod(emulatedDispatchMethod, interfaceType);
-        synthesizeClassWithUniqueMethod(
-            builder,
-            itfAccessFlags,
-            interfaceType,
-            itfMethod,
-            "desugared library dispatch interface",
-            appView);
-        // Dispatch holder.
-        DexType holderType = dispatchHolderTypeFor(emulatedDispatchMethod);
-        DexEncodedMethod dispatchMethod =
-            generateHolderDispatchMethod(
-                emulatedDispatchMethod, holderType, itfMethod.getReference());
-        synthesizeClassWithUniqueMethod(
-            builder,
-            holderAccessFlags,
-            holderType,
-            dispatchMethod,
-            "desugared library dispatch class",
-            appView);
+        ensureEmulatedInterfaceDispatchMethod(emulatedDispatchMethod);
+        ensureEmulatedHolderDispatchMethod(emulatedDispatchMethod);
       }
     }
 
-    private DexEncodedMethod generateInterfaceDispatchMethod(
-        DexClassAndMethod emulatedDispatchMethod, DexType interfaceType) {
-      MethodAccessFlags flags =
-          MethodAccessFlags.fromSharedAccessFlags(
-              Constants.ACC_PUBLIC | Constants.ACC_ABSTRACT | Constants.ACC_SYNTHETIC, false);
-      DexMethod newMethod =
-          appView
-              .dexItemFactory()
-              .createMethod(
-                  interfaceType,
-                  emulatedDispatchMethod.getProto(),
-                  emulatedDispatchMethod.getName());
-      return new DexEncodedMethod(
-          newMethod,
-          flags,
-          MethodTypeSignature.noSignature(),
-          DexAnnotationSet.empty(),
-          ParameterAnnotationsList.empty(),
-          null,
-          true);
+    private void reportInvalidLibrarySupertype(
+        DexLibraryClass libraryClass, DexClassAndMethodSet retarget) {
+      DexClass dexClass = appView.definitionFor(libraryClass.superType);
+      String message;
+      if (dexClass == null) {
+        message = "missing";
+      } else if (dexClass.isClasspathClass()) {
+        message = "a classpath class";
+      } else {
+        message = "INVALID";
+        assert false;
+      }
+      appView
+          .options()
+          .warningInvalidLibrarySuperclassForDesugar(
+              dexClass == null ? libraryClass.getOrigin() : dexClass.getOrigin(),
+              libraryClass.type,
+              libraryClass.superType,
+              message,
+              retarget);
     }
 
-    private DexEncodedMethod generateHolderDispatchMethod(
-        DexClassAndMethod emulatedDispatchMethod, DexType dispatchHolder, DexMethod itfMethod) {
-      // The method should look like:
-      // static foo(rcvr, arg0, arg1) {
-      //    if (rcvr instanceof interfaceType) {
-      //      return invoke-interface receiver.foo(arg0, arg1);
-      //    } else {
-      //      return DesugarX.foo(rcvr, arg0, arg1)
-      //    }
-      // We do not deal with complex cases (multiple retargeting of the same signature in the
-      // same inheritance tree, etc., since they do not happen in the most common desugared library.
-      DexMethod desugarMethod =
-          appView
-              .options()
-              .desugaredLibraryConfiguration
-              .retargetMethod(emulatedDispatchMethod, appView);
-      assert desugarMethod != null; // This method is reached only for retarget core lib members.
-      DexMethod newMethod =
-          appView
-              .dexItemFactory()
-              .createMethod(dispatchHolder, desugarMethod.proto, emulatedDispatchMethod.getName());
-      CfCode code =
-          new EmulateInterfaceSyntheticCfCodeProvider(
-                  emulatedDispatchMethod.getHolderType(),
-                  desugarMethod,
-                  itfMethod,
-                  Collections.emptyList(),
-                  appView)
-              .generateCfCode();
-      return new DexEncodedMethod(
-          newMethod,
-          MethodAccessFlags.createPublicStaticSynthetic(),
-          MethodTypeSignature.noSignature(),
-          DexAnnotationSet.empty(),
-          ParameterAnnotationsList.empty(),
-          code,
-          true);
-    }
-  }
-
-  private void reportInvalidLibrarySupertype(
-      DexLibraryClass libraryClass, DexClassAndMethodSet retarget) {
-    DexClass dexClass = appView.definitionFor(libraryClass.superType);
-    String message;
-    if (dexClass == null) {
-      message = "missing";
-    } else if (dexClass.isClasspathClass()) {
-      message = "a classpath class";
-    } else {
-      message = "INVALID";
-      assert false;
-    }
-    appView
-        .options()
-        .warningInvalidLibrarySuperclassForDesugar(
-            dexClass == null ? libraryClass.getOrigin() : dexClass.getOrigin(),
-            libraryClass.type,
-            libraryClass.superType,
-            message,
-            retarget);
-  }
-
-  private DexType dispatchInterfaceTypeFor(DexClassAndMethod method) {
-    return dispatchTypeFor(method, "dispatchInterface");
-  }
-
-  private DexType dispatchHolderTypeFor(DexClassAndMethod method) {
-    return dispatchTypeFor(method, "dispatchHolder");
-  }
-
-  public static String getRetargetPackageAndClassPrefixDescriptor(
-      DesugaredLibraryConfiguration config) {
-    return "L"
-        + config.getSynthesizedLibraryClassesPackagePrefix()
-        + RETARGET_PACKAGE
-        + DESUGAR_LIB_RETARGET_CLASS_NAME_PREFIX;
-  }
-
-  private DexType dispatchTypeFor(DexClassAndMethod method, String suffix) {
-    String descriptor =
-        packageAndClassDescriptorPrefix
-            + '$'
-            + method.getHolderType().getName()
-            + '$'
-            + method.getName()
-            + '$'
-            + suffix
-            + ';';
-    return appView.dexItemFactory().createSynthesizedType(descriptor);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceProcessor.java
index 5929db5..7e029ed 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceProcessor.java
@@ -21,7 +21,6 @@
 import com.android.tools.r8.ir.synthetic.EmulateInterfaceSyntheticCfCodeProvider;
 import com.android.tools.r8.synthesis.SyntheticMethodBuilder;
 import com.android.tools.r8.synthesis.SyntheticNaming;
-import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.IterableUtils;
 import com.android.tools.r8.utils.Pair;
 import com.android.tools.r8.utils.StringDiagnostic;
@@ -308,19 +307,11 @@
           && !rewriter.isEmulatedInterface(clazz.type)
           && !appView.rewritePrefix.hasRewrittenType(clazz.type, appView)
           && isEmulatedInterfaceSubInterface(clazz)) {
-        String prefix =
-            DescriptorUtils.getJavaTypeFromBinaryName(
-                appView
-                    .options()
-                    .desugaredLibraryConfiguration
-                    .getSynthesizedLibraryClassesPackagePrefix());
-        String interfaceType = clazz.type.toString();
-        // TODO(b/183918843): We are currently computing a new name for the companion class
-        // by replacing the initial package prefix by the synthesized library class package
-        // prefix, it would be better to make the rewriting explicit in the desugared library
-        // json file.
-        int firstPackage = interfaceType.indexOf('.');
-        String newName = prefix + interfaceType.substring(firstPackage + 1);
+        String newName =
+            appView
+                .options()
+                .desugaredLibraryConfiguration
+                .convertJavaNameToDesugaredLibrary(clazz.type);
         rewriter.addCompanionClassRewriteRule(clazz.type, newName);
       } else {
         filteredProgramClasses.add(clazz);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
index bdd6064..679a099 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
@@ -9,7 +9,6 @@
 import static com.android.tools.r8.ir.code.Invoke.Type.STATIC;
 import static com.android.tools.r8.ir.code.Invoke.Type.SUPER;
 import static com.android.tools.r8.ir.code.Invoke.Type.VIRTUAL;
-import static com.android.tools.r8.ir.desugar.DesugaredLibraryRetargeter.getRetargetPackageAndClassPrefixDescriptor;
 import static com.android.tools.r8.ir.desugar.DesugaredLibraryWrapperSynthesizer.TYPE_WRAPPER_SUFFIX;
 import static com.android.tools.r8.ir.desugar.DesugaredLibraryWrapperSynthesizer.VIVIFIED_TYPE_WRAPPER_SUFFIX;
 
@@ -1323,9 +1322,6 @@
   private Predicate<DexType> getShouldIgnoreFromReportsPredicate(AppView<?> appView) {
     DexItemFactory dexItemFactory = appView.dexItemFactory();
     InternalOptions options = appView.options();
-    DexString retargetPackageAndClassPrefixDescriptor =
-        dexItemFactory.createString(
-            getRetargetPackageAndClassPrefixDescriptor(options.desugaredLibraryConfiguration));
     DexString typeWrapperClassNameDescriptorSuffix =
         dexItemFactory.createString(TYPE_WRAPPER_SUFFIX + ';');
     DexString vivifiedTypeWrapperClassNameDescriptorSuffix =
@@ -1341,8 +1337,7 @@
           || descriptor.endsWith(companionClassNameDescriptorSuffix)
           || emulatedInterfaces.containsValue(type)
           || options.desugaredLibraryConfiguration.getCustomConversions().containsValue(type)
-          || appView.getDontWarnConfiguration().matches(type)
-          || descriptor.startsWith(retargetPackageAndClassPrefixDescriptor);
+          || appView.getDontWarnConfiguration().matches(type);
     };
   }
 
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index 239c0da..a4478d6 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -47,7 +47,6 @@
 import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
 import com.android.tools.r8.ir.code.Invoke.Type;
 import com.android.tools.r8.ir.desugar.DesugaredLibraryAPIConverter;
-import com.android.tools.r8.ir.desugar.DesugaredLibraryRetargeter;
 import com.android.tools.r8.ir.desugar.LambdaDescriptor;
 import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter;
 import com.android.tools.r8.synthesis.CommittedItems;
@@ -522,7 +521,6 @@
             // TODO(b/150693139): Remove these exceptions once fixed.
             || InterfaceMethodRewriter.isCompanionClassType(type)
             || InterfaceMethodRewriter.isEmulatedLibraryClassType(type)
-            || DesugaredLibraryRetargeter.isRetargetType(type, options())
             // TODO(b/150736225): Not sure how to remove these.
             || DesugaredLibraryAPIConverter.isVivifiedType(type)
         : "Failed lookup of non-missing type: " + type;
diff --git a/src/main/java/com/android/tools/r8/shaking/MissingClasses.java b/src/main/java/com/android/tools/r8/shaking/MissingClasses.java
index 0ec8c27..2cc626d 100644
--- a/src/main/java/com/android/tools/r8/shaking/MissingClasses.java
+++ b/src/main/java/com/android/tools/r8/shaking/MissingClasses.java
@@ -5,7 +5,6 @@
 package com.android.tools.r8.shaking;
 
 import static com.android.tools.r8.ir.desugar.DesugaredLibraryAPIConverter.DESCRIPTOR_VIVIFIED_PREFIX;
-import static com.android.tools.r8.ir.desugar.DesugaredLibraryRetargeter.getRetargetPackageAndClassPrefixDescriptor;
 import static com.android.tools.r8.utils.collections.IdentityHashSetFromMap.newProgramDerivedContextSet;
 
 import com.android.tools.r8.diagnostic.MissingDefinitionsDiagnostic;
@@ -23,7 +22,6 @@
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.synthesis.CommittedItems;
 import com.android.tools.r8.synthesis.SyntheticItems.SynthesizingContextOracle;
-import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.SetUtils;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
@@ -280,15 +278,10 @@
     private static Predicate<DexType> getIsCompilerSynthesizedAllowedMissingClassesPredicate(
         AppView<?> appView) {
       DexItemFactory dexItemFactory = appView.dexItemFactory();
-      InternalOptions options = appView.options();
-      DexString retargetPackageAndClassPrefixDescriptor =
-          dexItemFactory.createString(
-              getRetargetPackageAndClassPrefixDescriptor(options.desugaredLibraryConfiguration));
       DexString vivifiedClassNamePrefix = dexItemFactory.createString(DESCRIPTOR_VIVIFIED_PREFIX);
       return type -> {
         DexString descriptor = type.getDescriptor();
-        return descriptor.startsWith(retargetPackageAndClassPrefixDescriptor)
-            || descriptor.startsWith(vivifiedClassNamePrefix);
+        return descriptor.startsWith(vivifiedClassNamePrefix);
       };
     }
 
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
index 8e78b09..65c510c 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
@@ -22,19 +22,23 @@
 import com.android.tools.r8.graph.NestHostClassAttribute;
 import com.android.tools.r8.graph.NestMemberClassAttribute;
 import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.function.Consumer;
 
-abstract class SyntheticClassBuilder<B extends SyntheticClassBuilder<B, C>, C extends DexClass> {
+public abstract class SyntheticClassBuilder<
+    B extends SyntheticClassBuilder<B, C>, C extends DexClass> {
 
   private final DexItemFactory factory;
 
   private final DexType type;
+  private final SyntheticKind syntheticKind;
   private final Origin origin;
 
   private boolean isAbstract = false;
+  private boolean isInterface = false;
   private Kind originKind;
   private DexType superType;
   private DexTypeList interfaces = DexTypeList.empty();
@@ -46,9 +50,14 @@
   private List<SyntheticMethodBuilder> methods = new ArrayList<>();
   private ClassSignature signature = ClassSignature.noSignature();
 
-  SyntheticClassBuilder(DexType type, SynthesizingContext context, DexItemFactory factory) {
+  SyntheticClassBuilder(
+      DexType type,
+      SyntheticKind syntheticKind,
+      SynthesizingContext context,
+      DexItemFactory factory) {
     this.factory = factory;
     this.type = type;
+    this.syntheticKind = syntheticKind;
     this.origin = context.getInputContextOrigin();
     this.superType = factory.objectType;
   }
@@ -65,6 +74,10 @@
     return type;
   }
 
+  public SyntheticKind getSyntheticKind() {
+    return syntheticKind;
+  }
+
   public B setInterfaces(List<DexType> interfaces) {
     this.interfaces =
         interfaces.isEmpty()
@@ -78,6 +91,12 @@
     return self();
   }
 
+  public B setInterface() {
+    setAbstract();
+    isInterface = true;
+    return self();
+  }
+
   public B setOriginKind(Kind originKind) {
     this.originKind = originKind;
     return self();
@@ -126,9 +145,11 @@
 
   public C build() {
     int flag = isAbstract ? Constants.ACC_ABSTRACT : Constants.ACC_FINAL;
+    int itfFlag = isInterface ? Constants.ACC_INTERFACE : 0;
+    assert !isInterface || isAbstract;
     ClassAccessFlags accessFlags =
         ClassAccessFlags.fromSharedAccessFlags(
-            flag | Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC);
+            flag | itfFlag | Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC);
     NestHostClassAttribute nestHost = null;
     List<NestMemberClassAttribute> nestMembers = Collections.emptyList();
     EnclosingMethodAttribute enclosingMembers = null;
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticClasspathClassBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticClasspathClassBuilder.java
index 20cd075..b888913 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticClasspathClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticClasspathClassBuilder.java
@@ -8,13 +8,17 @@
 import com.android.tools.r8.graph.DexClasspathClass;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
 
 public class SyntheticClasspathClassBuilder
     extends SyntheticClassBuilder<SyntheticClasspathClassBuilder, DexClasspathClass> {
 
   SyntheticClasspathClassBuilder(
-      DexType type, SynthesizingContext context, DexItemFactory factory) {
-    super(type, context, factory);
+      DexType type,
+      SyntheticKind syntheticKind,
+      SynthesizingContext context,
+      DexItemFactory factory) {
+    super(type, syntheticKind, context, factory);
     setOriginKind(Kind.CF);
   }
 
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
index 15719ce..e1f4b12 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
@@ -462,7 +462,7 @@
       DexType type,
       DexItemFactory factory) {
     SyntheticProgramClassBuilder classBuilder =
-        new SyntheticProgramClassBuilder(type, outerContext, factory);
+        new SyntheticProgramClassBuilder(type, kind, outerContext, factory);
     fn.accept(classBuilder);
     DexProgramClass clazz = classBuilder.build();
     addPendingDefinition(new SyntheticProgramClassDefinition(kind, outerContext, clazz));
@@ -503,16 +503,19 @@
    */
   public DexProgramClass ensureFixedClass(
       SyntheticKind kind,
-      DexProgramClass context,
+      DexClass context,
       AppView<?> appView,
       Consumer<SyntheticProgramClassBuilder> fn) {
     assert kind.isFixedSuffixSynthetic;
     // Obtain the outer synthesizing context in the case the context itself is synthetic.
     // This is to ensure a flat input-type -> synthetic-item mapping.
-    SynthesizingContext outerContext = getSynthesizingContext(context, appView);
+    SynthesizingContext outerContext =
+        context.isProgramClass()
+            ? getSynthesizingContext(context.asProgramClass(), appView)
+            : SynthesizingContext.fromNonSyntheticInputContext(context.asClasspathOrLibraryClass());
     DexType type = SyntheticNaming.createFixedType(kind, outerContext, appView.dexItemFactory());
     // Fast path is that the synthetic is already present. If so it must be a program class.
-    DexClass clazz = appView.definitionFor(type, context);
+    DexClass clazz = appView.definitionFor(type);
     if (clazz != null) {
       assert isSyntheticClass(type);
       assert clazz.isProgramClass();
@@ -521,7 +524,7 @@
     // Slow path creates the class using the context to make it thread safe.
     synchronized (context) {
       // Recheck if it is present now the lock is held.
-      clazz = appView.definitionFor(type, context);
+      clazz = appView.definitionFor(type);
       if (clazz != null) {
         assert isSyntheticClass(type);
         assert clazz.isProgramClass();
@@ -539,12 +542,41 @@
     SynthesizingContext outerContext = SynthesizingContext.fromNonSyntheticInputContext(context);
     DexType type = SyntheticNaming.createFixedType(kind, outerContext, factory);
     SyntheticClasspathClassBuilder classBuilder =
-        new SyntheticClasspathClassBuilder(type, outerContext, factory);
+        new SyntheticClasspathClassBuilder(type, kind, outerContext, factory);
     DexClasspathClass clazz = classBuilder.build();
     addPendingDefinition(new SyntheticClasspathClassDefinition(kind, outerContext, clazz));
     return clazz;
   }
 
+  public DexClasspathClass ensureFixedClasspathClass(
+      SyntheticKind kind,
+      ClasspathOrLibraryClass context,
+      AppView<?> appView,
+      Consumer<SyntheticClasspathClassBuilder> classConsumer) {
+    SynthesizingContext outerContext = SynthesizingContext.fromNonSyntheticInputContext(context);
+    DexType type = SyntheticNaming.createFixedType(kind, outerContext, appView.dexItemFactory());
+    DexClass dexClass = appView.appInfo().definitionForWithoutExistenceAssert(type);
+    if (dexClass != null) {
+      assert dexClass.isClasspathClass();
+      return dexClass.asClasspathClass();
+    }
+    synchronized (context) {
+      dexClass = appView.appInfo().definitionForWithoutExistenceAssert(type);
+      if (dexClass != null) {
+        assert dexClass.isClasspathClass();
+        return dexClass.asClasspathClass();
+      }
+      // Obtain the outer synthesizing context in the case the context itself is synthetic.
+      // This is to ensure a flat input-type -> synthetic-item mapping.
+      SyntheticClasspathClassBuilder classBuilder =
+          new SyntheticClasspathClassBuilder(type, kind, outerContext, appView.dexItemFactory());
+      classConsumer.accept(classBuilder);
+      DexClasspathClass clazz = classBuilder.build();
+      addPendingDefinition(new SyntheticClasspathClassDefinition(kind, outerContext, clazz));
+      return clazz;
+    }
+  }
+
   // This is a temporary API for migration to the hygienic synthetic, the classes created behave
   // like a hygienic synthetic, but use the legacyType passed as parameter instead of the
   // hygienic type.
@@ -560,7 +592,8 @@
       // This is to ensure a flat input-type -> synthetic-item mapping.
       SynthesizingContext outerContext = SynthesizingContext.fromNonSyntheticInputContext(context);
       SyntheticClasspathClassBuilder classBuilder =
-          new SyntheticClasspathClassBuilder(legacyType, outerContext, appView.dexItemFactory());
+          new SyntheticClasspathClassBuilder(
+              legacyType, kind, outerContext, appView.dexItemFactory());
       DexClasspathClass clazz = classBuilder.build();
       addPendingDefinition(new SyntheticClasspathClassDefinition(kind, outerContext, clazz));
       return clazz;
@@ -584,7 +617,7 @@
         return;
       }
       SyntheticMethodBuilder syntheticMethodBuilder =
-          new SyntheticMethodBuilder(appView.dexItemFactory(), syntheticClass.type);
+          new SyntheticMethodBuilder(appView.dexItemFactory(), syntheticClass.type, kind);
       builderConsumer.accept(syntheticMethodBuilder);
       syntheticClass.addDirectMethod(syntheticMethodBuilder.build());
     }
@@ -625,7 +658,7 @@
         SyntheticNaming.createInternalType(
             kind, outerContext, syntheticIdSupplier.get(), appView.dexItemFactory());
     SyntheticProgramClassBuilder classBuilder =
-        new SyntheticProgramClassBuilder(type, outerContext, appView.dexItemFactory());
+        new SyntheticProgramClassBuilder(type, kind, outerContext, appView.dexItemFactory());
     DexProgramClass clazz =
         classBuilder
             .addMethod(fn.andThen(m -> m.setName(SyntheticNaming.INTERNAL_SYNTHETIC_METHOD_PREFIX)))
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java
index ffaad01..a06fdb7 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java
@@ -128,7 +128,7 @@
         return NO_MARKER;
       }
       for (DexEncodedMethod method : clazz.methods()) {
-        if (!SyntheticMethodBuilder.isValidSyntheticMethod(method)) {
+        if (!SyntheticMethodBuilder.isValidSingleSyntheticMethod(method)) {
           return NO_MARKER;
         }
       }
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
index 67bd52c..e2cd6eb 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
@@ -15,6 +15,7 @@
 import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
+import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
 import java.util.function.Consumer;
 
 public class SyntheticMethodBuilder {
@@ -25,6 +26,7 @@
 
   private final DexItemFactory factory;
   private final DexType holderType;
+  private final SyntheticKind syntheticKind;
   private DexString name = null;
   private DexProto proto = null;
   private CfVersion classFileVersion;
@@ -38,11 +40,13 @@
   SyntheticMethodBuilder(SyntheticClassBuilder<?, ?> parent) {
     this.factory = parent.getFactory();
     this.holderType = parent.getType();
+    this.syntheticKind = parent.getSyntheticKind();
   }
 
-  SyntheticMethodBuilder(DexItemFactory factory, DexType holderType) {
+  SyntheticMethodBuilder(DexItemFactory factory, DexType holderType, SyntheticKind syntheticKind) {
     this.factory = factory;
     this.holderType = holderType;
+    this.syntheticKind = syntheticKind;
   }
 
   public SyntheticMethodBuilder setName(String name) {
@@ -101,20 +105,18 @@
     assert name != null;
     boolean isCompilerSynthesized = true;
     DexMethod methodSignature = getMethodSignature();
+    MethodAccessFlags accessFlags = getAccessFlags();
     DexEncodedMethod method =
         new DexEncodedMethod(
             methodSignature,
-            getAccessFlags(),
+            accessFlags,
             genericSignature,
             annotations,
             parameterAnnotationsList,
-            getCodeObject(methodSignature),
+            accessFlags.isAbstract() ? null : getCodeObject(methodSignature),
             isCompilerSynthesized,
             classFileVersion);
-    // Companion class method may have different properties.
-    assert isValidSyntheticMethod(method)
-        || SyntheticNaming.isSynthetic(
-            holderType.asClassReference(), null, SyntheticNaming.SyntheticKind.COMPANION_CLASS);
+    assert isValidSyntheticMethod(method, syntheticKind);
     if (onBuildConsumer != null) {
       onBuildConsumer.accept(method);
     }
@@ -126,8 +128,16 @@
    *
    * <p>This method is used when identifying synthetic methods in the program input and should be as
    * narrow as possible.
+   *
+   * <p>Methods in fixed suffix synthetics are identified differently (through the class name) and
+   * can have different properties.
    */
-  public static boolean isValidSyntheticMethod(DexEncodedMethod method) {
+  public static boolean isValidSyntheticMethod(
+      DexEncodedMethod method, SyntheticKind syntheticKind) {
+    return isValidSingleSyntheticMethod(method) || syntheticKind.isFixedSuffixSynthetic;
+  }
+
+  public static boolean isValidSingleSyntheticMethod(DexEncodedMethod method) {
     return method.isStatic()
         && method.isNonAbstractNonNativeMethod()
         && method.isPublic()
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodDefinition.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodDefinition.java
index 87393f7..a9d11c7 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodDefinition.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodDefinition.java
@@ -70,7 +70,7 @@
 
   @Override
   public boolean isValid() {
-    return SyntheticMethodBuilder.isValidSyntheticMethod(method.getDefinition());
+    return SyntheticMethodBuilder.isValidSyntheticMethod(method.getDefinition(), getKind());
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
index 6ed6c0e..33530e6 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
@@ -26,6 +26,8 @@
     RECORD_TAG("", 1, false, true, true),
     COMPANION_CLASS("$-CC", 2, false, true),
     EMULATED_INTERFACE_CLASS("$-EL", 3, false, true),
+    RETARGET_CLASS("RetargetClass", 20, false, true),
+    RETARGET_INTERFACE("RetargetInterface", 21, false, true),
     LAMBDA("Lambda", 4, false),
     INIT_TYPE_ARGUMENT("-IA", 5, false, true),
     HORIZONTAL_INIT_TYPE_ARGUMENT_1(SYNTHETIC_CLASS_SEPARATOR + "IA$1", 6, false, true),
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticProgramClassBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticProgramClassBuilder.java
index 6408621..8c07884 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticProgramClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticProgramClassBuilder.java
@@ -7,12 +7,17 @@
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
 
 public class SyntheticProgramClassBuilder
     extends SyntheticClassBuilder<SyntheticProgramClassBuilder, DexProgramClass> {
 
-  SyntheticProgramClassBuilder(DexType type, SynthesizingContext context, DexItemFactory factory) {
-    super(type, context, factory);
+  SyntheticProgramClassBuilder(
+      DexType type,
+      SyntheticKind syntheticKind,
+      SynthesizingContext context,
+      DexItemFactory factory) {
+    super(type, syntheticKind, context, factory);
   }
 
   @Override