Revert "Stub retargeter"

This reverts commit e83d09622b71ae8183106c925c997a364ed71c4d.

Reason for revert: break bots

Change-Id: Idaebe22da56a772c56a5914459b15ebcf82c58dc
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 5a95c61..85c05f6 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -49,6 +49,7 @@
 import com.android.tools.r8.ir.desugar.BackportedMethodRewriter;
 import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringCollection;
 import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeterLibraryTypeSynthesizer;
 import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter;
 import com.android.tools.r8.ir.desugar.records.RecordDesugaring;
 import com.android.tools.r8.ir.desugar.records.RecordFieldValuesRewriter;
@@ -310,6 +311,10 @@
       if (!options.mainDexKeepRules.isEmpty()) {
         MainDexListBuilder.checkForAssumedLibraryTypes(appView.appInfo());
       }
+      if (options.machineDesugaredLibrarySpecification.hasRetargeting()) {
+        DesugaredLibraryRetargeterLibraryTypeSynthesizer.checkForAssumedLibraryTypes(appView);
+        DesugaredLibraryRetargeterLibraryTypeSynthesizer.amendLibraryWithRetargetedMembers(appView);
+      }
       InterfaceMethodRewriter.checkForAssumedLibraryTypes(appView.appInfo(), options);
       BackportedMethodRewriter.registerAssumedLibraryTypes(options);
       if (options.enableEnumUnboxing) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
index 064e614..5fcf037 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
@@ -11,11 +11,10 @@
 import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.MethodResolutionResult;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.desugar.CfInstructionDesugaring;
@@ -25,7 +24,6 @@
 import com.android.tools.r8.ir.desugar.LocalStackAllocator;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.EmulatedDispatchMethodDescriptor;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterInstructionEventConsumer;
-import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
@@ -89,41 +87,6 @@
     return computeNewInvokeTarget(instruction, context).hasNewInvokeTarget();
   }
 
-  private void ensureRetargetMethod(
-      DexMethod retarget, DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
-    DexClass holderClass = appView.definitionFor(retarget.getHolderType());
-    if (holderClass != null && holderClass.isProgramClass()) {
-      assert holderClass.lookupMethod(retarget) != null;
-      return;
-    }
-    appView
-        .getSyntheticItems()
-        .ensureFixedClasspathMethodFromType(
-            retarget.getName(),
-            retarget.getProto(),
-            SyntheticKind.RETARGET_STUB,
-            retarget.getHolderType(),
-            appView,
-            ignored -> {},
-            eventConsumer::acceptDesugaredLibraryRetargeterDispatchClasspathClass,
-            methodBuilder ->
-                methodBuilder
-                    .setAccessFlags(MethodAccessFlags.createPublicStaticSynthetic())
-                    .setCode(null));
-  }
-
-  InvokeRetargetingResult ensureInvokeRetargetingResult(DexMethod retarget) {
-    if (retarget == null) {
-      return NO_REWRITING;
-    }
-    return new InvokeRetargetingResult(
-        true,
-        eventConsumer -> {
-          ensureRetargetMethod(retarget, eventConsumer);
-          return retarget;
-        });
-  }
-
   static class InvokeRetargetingResult {
 
     static InvokeRetargetingResult NO_REWRITING =
@@ -185,33 +148,44 @@
     assert singleTarget != null;
     if (cfInvoke.isInvokeStatic()) {
       DexMethod retarget = staticRetarget.get(singleTarget);
-      return retarget == null ? NO_REWRITING : ensureInvokeRetargetingResult(retarget);
+      return retarget == null
+          ? NO_REWRITING
+          : InvokeRetargetingResult.createInvokeRetargetingResult(retarget);
     }
-    InvokeRetargetingResult retarget = computeNonStaticRetarget(singleTarget, false);
+    InvokeRetargetingResult retarget = computeNonStaticRetarget(singleTarget);
     if (!retarget.hasNewInvokeTarget()) {
       return NO_REWRITING;
     }
     if (cfInvoke.isInvokeSuper(context.getHolderType())) {
       DexClassAndMethod superTarget = appInfo.lookupSuperTarget(invokedMethod, context);
       if (superTarget != null) {
-        assert !superTarget.getDefinition().isStatic();
-        return computeNonStaticRetarget(superTarget.getReference(), true);
+        return computeSuperRetarget(superTarget.getDefinition());
       }
     }
     return retarget;
   }
 
-  private InvokeRetargetingResult computeNonStaticRetarget(
-      DexMethod singleTarget, boolean superInvoke) {
+  private InvokeRetargetingResult computeNonStaticRetarget(DexMethod singleTarget) {
     EmulatedDispatchMethodDescriptor descriptor = emulatedVirtualRetarget.get(singleTarget);
     if (descriptor != null) {
       return new InvokeRetargetingResult(
           true,
           eventConsumer ->
-              superInvoke
-                  ? syntheticHelper.ensureForwardingMethod(descriptor)
-                  : syntheticHelper.ensureEmulatedHolderDispatchMethod(descriptor, eventConsumer));
+              syntheticHelper.ensureEmulatedHolderDispatchMethod(descriptor, eventConsumer));
     }
-    return ensureInvokeRetargetingResult(nonEmulatedVirtualRetarget.get(singleTarget));
+    return InvokeRetargetingResult.createInvokeRetargetingResult(
+        nonEmulatedVirtualRetarget.get(singleTarget));
+  }
+
+  private InvokeRetargetingResult computeSuperRetarget(DexEncodedMethod singleTarget) {
+    assert !singleTarget.isStatic();
+    DexMethod reference = singleTarget.getReference();
+    EmulatedDispatchMethodDescriptor descriptor = emulatedVirtualRetarget.get(reference);
+    if (descriptor != null) {
+      return InvokeRetargetingResult.createInvokeRetargetingResult(
+          syntheticHelper.ensureForwardingMethod(descriptor));
+    }
+    return InvokeRetargetingResult.createInvokeRetargetingResult(
+        nonEmulatedVirtualRetarget.get(reference));
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterLibraryTypeSynthesizer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterLibraryTypeSynthesizer.java
new file mode 100644
index 0000000..bfb423a
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterLibraryTypeSynthesizer.java
@@ -0,0 +1,163 @@
+// Copyright (c) 2021, 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.ir.desugar.desugaredlibrary.retargeter;
+
+import com.android.tools.r8.ProgramResource.Kind;
+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.ClassAccessFlags;
+import com.android.tools.r8.graph.DexAnnotationSet;
+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.DexItemFactory;
+import com.android.tools.r8.graph.DexLibraryClass;
+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.graph.DexTypeList;
+import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.EnclosingMethodAttribute;
+import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.InnerClassAttribute;
+import com.android.tools.r8.graph.MethodAccessFlags;
+import com.android.tools.r8.graph.NestHostClassAttribute;
+import com.android.tools.r8.graph.NestMemberClassAttribute;
+import com.android.tools.r8.origin.SynthesizedOrigin;
+import com.android.tools.r8.utils.StringDiagnostic;
+import java.util.Comparator;
+import java.util.IdentityHashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class DesugaredLibraryRetargeterLibraryTypeSynthesizer {
+
+  public static void checkForAssumedLibraryTypes(AppView<?> appView) {
+    appView
+        .options()
+        .machineDesugaredLibrarySpecification
+        .forEachRetargetHolder(
+            inType -> {
+              DexClass typeClass = appView.definitionFor(inType);
+              if (typeClass == null) {
+                warnMissingRetargetCoreLibraryMember(inType, appView);
+              }
+            });
+  }
+
+  public static void amendLibraryWithRetargetedMembers(AppView<AppInfoWithClassHierarchy> appView) {
+    Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
+        appView.options().desugaredLibrarySpecification.getRetargetCoreLibMember();
+    Map<DexType, DexLibraryClass> synthesizedLibraryClasses =
+        synthesizeLibraryClassesForRetargetedMembers(appView, retargetCoreLibMember);
+    Map<DexLibraryClass, Set<DexEncodedMethod>> synthesizedLibraryMethods =
+        synthesizedMembersForRetargetClasses(
+            appView, retargetCoreLibMember, synthesizedLibraryClasses);
+    synthesizedLibraryMethods.forEach(DexLibraryClass::addDirectMethods);
+    DirectMappedDexApplication newApplication =
+        appView
+            .appInfo()
+            .app()
+            .asDirect()
+            .builder()
+            .addLibraryClasses(synthesizedLibraryClasses.values())
+            .build();
+    appView.setAppInfo(appView.appInfo().rebuildWithClassHierarchy(app -> newApplication));
+  }
+
+  private static Map<DexType, DexLibraryClass> synthesizeLibraryClassesForRetargetedMembers(
+      AppView<AppInfoWithClassHierarchy> appView,
+      Map<DexString, Map<DexType, DexType>> retargetCoreLibMember) {
+    DexItemFactory dexItemFactory = appView.dexItemFactory();
+    Map<DexType, DexLibraryClass> synthesizedLibraryClasses = new LinkedHashMap<>();
+    for (Map<DexType, DexType> oldToNewTypeMap : retargetCoreLibMember.values()) {
+      for (DexType newType : oldToNewTypeMap.values()) {
+        if (appView.definitionFor(newType) == null) {
+          synthesizedLibraryClasses.computeIfAbsent(
+              newType,
+              type ->
+                  // Synthesize a library class with the given name. Note that this is assuming that
+                  // the library class inherits directly from java.lang.Object, does not implement
+                  // any interfaces, etc.
+                  new DexLibraryClass(
+                      type,
+                      Kind.CF,
+                      new SynthesizedOrigin(
+                          "Desugared library retargeter", DesugaredLibraryRetargeter.class),
+                      ClassAccessFlags.fromCfAccessFlags(Constants.ACC_PUBLIC),
+                      dexItemFactory.objectType,
+                      DexTypeList.empty(),
+                      dexItemFactory.createString("DesugaredLibraryRetargeter"),
+                      NestHostClassAttribute.none(),
+                      NestMemberClassAttribute.emptyList(),
+                      EnclosingMethodAttribute.none(),
+                      InnerClassAttribute.emptyList(),
+                      ClassSignature.noSignature(),
+                      DexAnnotationSet.empty(),
+                      DexEncodedField.EMPTY_ARRAY,
+                      DexEncodedField.EMPTY_ARRAY,
+                      DexEncodedMethod.EMPTY_ARRAY,
+                      DexEncodedMethod.EMPTY_ARRAY,
+                      dexItemFactory.getSkipNameValidationForTesting()));
+        }
+      }
+    }
+    return synthesizedLibraryClasses;
+  }
+
+  private static Map<DexLibraryClass, Set<DexEncodedMethod>> synthesizedMembersForRetargetClasses(
+      AppView<AppInfoWithClassHierarchy> appView,
+      Map<DexString, Map<DexType, DexType>> retargetCoreLibMember,
+      Map<DexType, DexLibraryClass> synthesizedLibraryClasses) {
+    DexItemFactory dexItemFactory = appView.dexItemFactory();
+    Map<DexLibraryClass, Set<DexEncodedMethod>> synthesizedMembers = new IdentityHashMap<>();
+    for (Entry<DexString, Map<DexType, DexType>> entry : retargetCoreLibMember.entrySet()) {
+      DexString methodName = entry.getKey();
+      Map<DexType, DexType> types = entry.getValue();
+      types.forEach(
+          (oldType, newType) -> {
+            DexClass oldClass = appView.definitionFor(oldType);
+            DexLibraryClass newClass = synthesizedLibraryClasses.get(newType);
+            if (oldClass == null || newClass == null) {
+              return;
+            }
+            for (DexEncodedMethod method :
+                oldClass.methods(method -> method.getName() == methodName)) {
+              DexMethod retargetMethod = method.getReference().withHolder(newType, dexItemFactory);
+              if (!method.isStatic()) {
+                retargetMethod = retargetMethod.withExtraArgumentPrepended(oldType, dexItemFactory);
+              }
+              synthesizedMembers
+                  .computeIfAbsent(
+                      newClass,
+                      ignore -> new TreeSet<>(Comparator.comparing(DexEncodedMethod::getReference)))
+                  .add(
+                      DexEncodedMethod.syntheticBuilder()
+                          .setMethod(retargetMethod)
+                          .setAccessFlags(
+                              MethodAccessFlags.fromCfAccessFlags(
+                                  Constants.ACC_PUBLIC | Constants.ACC_STATIC, false))
+                          .setCode(null)
+                          .setApiLevelForDefinition(method.getApiLevelForDefinition())
+                          .build());
+            }
+          });
+    }
+    return synthesizedMembers;
+  }
+
+  private static void warnMissingRetargetCoreLibraryMember(DexType type, AppView<?> appView) {
+    StringDiagnostic warning =
+        new StringDiagnostic(
+            "Cannot retarget core library member "
+                + type.getName()
+                + " because the class is missing.");
+    appView.options().reporter.warning(warning);
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
index 7c3303b..cb4a537 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
@@ -171,8 +171,7 @@
             SyntheticKind.EMULATED_INTERFACE_MARKER_CLASS,
             type,
             appView,
-            SyntheticClassBuilder::setInterface,
-            ignored -> {});
+            SyntheticClassBuilder::setInterface);
   }
 
   DexClassAndMethod lookupMaximallySpecificIncludingSelf(
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 9b67476..6d45ee1 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
@@ -10,7 +10,6 @@
 import com.android.tools.r8.features.ClassToFeatureSplitMap;
 import com.android.tools.r8.graph.AppInfo;
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ClasspathMethod;
 import com.android.tools.r8.graph.ClasspathOrLibraryClass;
 import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexClass;
@@ -650,11 +649,10 @@
       SyntheticKind kind,
       DexType contextType,
       AppView<?> appView,
-      Consumer<SyntheticClasspathClassBuilder> classConsumer,
-      Consumer<DexClasspathClass> onCreationConsumer) {
+      Consumer<SyntheticClasspathClassBuilder> classConsumer) {
     SynthesizingContext outerContext = SynthesizingContext.fromType(contextType);
     return internalEnsureFixedClasspathClass(
-        kind, classConsumer, onCreationConsumer, outerContext, appView);
+        kind, classConsumer, ignored -> {}, outerContext, appView);
   }
 
   public DexClasspathClass ensureFixedClasspathClass(
@@ -670,23 +668,7 @@
         kind, classConsumer, onCreationConsumer, outerContext, appView);
   }
 
-  public ClasspathMethod ensureFixedClasspathMethodFromType(
-      DexString methodName,
-      DexProto methodProto,
-      SyntheticKind kind,
-      DexType contextType,
-      AppView<?> appView,
-      Consumer<SyntheticClasspathClassBuilder> classConsumer,
-      Consumer<DexClasspathClass> onCreationConsumer,
-      Consumer<SyntheticMethodBuilder> buildMethodCallback) {
-    DexClasspathClass clazz =
-        ensureFixedClasspathClassFromType(
-            kind, contextType, appView, classConsumer, onCreationConsumer);
-    return internalEnsureFixedClasspathMethod(
-        methodName, methodProto, kind, appView, buildMethodCallback, clazz);
-  }
-
-  public ClasspathMethod ensureFixedClasspathClassMethod(
+  public DexClassAndMethod ensureFixedClasspathClassMethod(
       DexString methodName,
       DexProto methodProto,
       SyntheticKind kind,
@@ -698,17 +680,6 @@
     DexClasspathClass clazz =
         ensureFixedClasspathClass(
             kind, context, appView, buildClassCallback, onClassCreationCallback);
-    return internalEnsureFixedClasspathMethod(
-        methodName, methodProto, kind, appView, buildMethodCallback, clazz);
-  }
-
-  private ClasspathMethod internalEnsureFixedClasspathMethod(
-      DexString methodName,
-      DexProto methodProto,
-      SyntheticKind kind,
-      AppView<?> appView,
-      Consumer<SyntheticMethodBuilder> buildMethodCallback,
-      DexClasspathClass clazz) {
     DexMethod methodReference =
         appView.dexItemFactory().createMethod(clazz.getType(), methodProto, methodName);
     DexEncodedMethod methodDefinition =
@@ -723,7 +694,7 @@
               buildMethodCallback.accept(methodBuilder.disableAndroidApiLevelCheck());
             },
             emptyConsumer());
-    return new ClasspathMethod(clazz, methodDefinition);
+    return DexClassAndMethod.create(clazz, methodDefinition);
   }
 
   @SuppressWarnings("unchecked")
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 6568eaa..62c7c6f 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
@@ -31,7 +31,6 @@
     COMPANION_CLASS("$-CC", 2, false, true),
     EMULATED_INTERFACE_CLASS("$-EL", 3, false, true),
     RETARGET_CLASS("RetargetClass", 20, false, true),
-    RETARGET_STUB("RetargetStub", 36, false, true),
     RETARGET_INTERFACE("RetargetInterface", 21, false, true),
     WRAPPER("$Wrapper", 22, false, true),
     VIVIFIED_WRAPPER("$VivifiedWrapper", 23, false, true),