Cleanup resolution in InterfaceMethodRewriter

Change-Id: Idfbe3f8c9ad063bd464967c88352a18da44f7940
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 6338270..17e354e 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
@@ -33,7 +33,6 @@
 import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.InvalidCode;
 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.graph.ThrowNullCode;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.DerivedMethod;
@@ -268,13 +267,6 @@
             .containsKey(method.getReference());
   }
 
-  DerivedMethod computeEmulatedInterfaceDispatchMethod(MethodResolutionResult resolutionResult) {
-    EmulatedDispatchMethodDescriptor descriptor =
-        getEmulatedDispatchDescriptor(
-            resolutionResult.getInitialResolutionHolder(), resolutionResult.getResolutionPair());
-    return descriptor == null ? null : descriptor.getEmulatedDispatchMethod();
-  }
-
   DerivedMethod computeEmulatedInterfaceForwardingMethod(
       DexClass initialResolutionHolder, DexClassAndMethod method) {
     if (method == null) {
@@ -337,8 +329,10 @@
   }
 
   DexClassAndMethod ensureEmulatedInterfaceDispatchMethod(
-      DerivedMethod emulatedDispatchMethod,
+      EmulatedDispatchMethodDescriptor emulatedDispatchMethodDescriptor,
       ClasspathEmulatedInterfaceSynthesizerEventConsumer eventConsumer) {
+    DerivedMethod emulatedDispatchMethod =
+        emulatedDispatchMethodDescriptor.getEmulatedDispatchMethod();
     assert verifyKind(emulatedDispatchMethod, kinds -> kinds.EMULATED_INTERFACE_CLASS);
     DexClassAndMethod method =
         appView
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 8f72669..b81a5f6 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
@@ -39,6 +39,7 @@
 import com.android.tools.r8.ir.desugar.DesugarDescription;
 import com.android.tools.r8.ir.desugar.ProgramAdditions;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.DerivedMethod;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.EmulatedDispatchMethodDescriptor;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineDesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.icce.AlwaysThrowingInstructionDesugaring;
 import com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringSyntheticHelper.InterfaceMethodDesugaringMode;
@@ -291,10 +292,14 @@
           .addScanEffect(() -> warnMissingType(context, invoke.getMethod().getHolderType()))
           .build();
     }
+    MethodResolutionResult resolutionResult =
+        appView
+            .appInfoForDesugaring()
+            .resolveMethodLegacy(invoke.getMethod(), invoke.isInterface());
     if (invoke.isInvokeSuper(context.getHolderType())) {
-      return rewriteInvokeSuper(invoke, context);
+      return rewriteInvokeSuper(holder, invoke, context, resolutionResult.asSingleResolution());
     } else {
-      return computeInvokeDirect(holder, invoke, context);
+      return computeInvokeDirect(holder, invoke, context, resolutionResult);
     }
   }
 
@@ -423,24 +428,26 @@
       // For virtual targets we should not report anything as any virtual dispatch just remains.
       return DesugarDescription.nothing();
     }
-    if (desugaringMode == EMULATED_INTERFACE_ONLY) {
-      return computeEmulatedInterfaceVirtualDispatch(invoke);
-    }
     AppInfoWithClassHierarchy appInfoForDesugaring = appView.appInfoForDesugaring();
-    SingleResolutionResult<?> resolution =
+    SingleResolutionResult<?> resolutionResult =
         appInfoForDesugaring
             .resolveMethodLegacy(invoke.getMethod(), invoke.isInterface())
             .asSingleResolution();
-    if (resolution != null
-        && resolution.getResolvedMethod().isPrivate()
-        && resolution.isAccessibleFrom(context, appView, appInfoForDesugaring).isTrue()) {
+    if (resolutionResult == null) {
+      return DesugarDescription.nothing();
+    }
+    if (desugaringMode == EMULATED_INTERFACE_ONLY) {
+      return computeEmulatedInterfaceVirtualDispatch(resolutionResult);
+    }
+    if (resolutionResult.getResolvedMethod().isPrivate()
+        && resolutionResult.isAccessibleFrom(context, appView, appInfoForDesugaring).isTrue()) {
       // TODO(b/198267586): What about the private in-accessible case?
-      return computeInvokeDirect(holder, invoke, context);
+      return computeInvokeDirect(holder, invoke, context, resolutionResult);
     }
-    if (resolution != null && resolution.getResolvedMethod().isStatic()) {
-      return computeInvokeAsThrowRewrite(invoke, resolution, context);
+    if (resolutionResult.getResolvedMethod().isStatic()) {
+      return computeInvokeAsThrowRewrite(invoke, resolutionResult, context);
     }
-    return computeEmulatedInterfaceVirtualDispatch(invoke);
+    return computeEmulatedInterfaceVirtualDispatch(resolutionResult);
   }
 
   private DesugarDescription computeInvokeVirtual(
@@ -450,51 +457,47 @@
       // For virtual targets we should not report anything as any virtual dispatch just remains.
       return DesugarDescription.nothing();
     }
-    if (desugaringMode == EMULATED_INTERFACE_ONLY) {
-      AppInfoWithClassHierarchy appInfoForDesugaring = appView.appInfoForDesugaring();
-      SingleResolutionResult<?> resolution =
-          appInfoForDesugaring
-              .resolveMethodLegacy(invoke.getMethod(), invoke.isInterface())
-              .asSingleResolution();
-      if (resolution != null
-          && resolution.getResolvedMethod().isPrivate()
-          && resolution.isAccessibleFrom(context, appView, appInfoForDesugaring).isTrue()) {
-        return DesugarDescription.nothing();
-      }
-      if (resolution != null && resolution.getResolvedMethod().isStatic()) {
-        return DesugarDescription.nothing();
-      }
-      return computeEmulatedInterfaceVirtualDispatch(invoke);
+    AppInfoWithClassHierarchy appInfo = appView.appInfoForDesugaring();
+    SingleResolutionResult<?> resolutionResult =
+        appInfo.resolveMethodLegacy(invoke.getMethod(), invoke.isInterface()).asSingleResolution();
+    if (resolutionResult == null) {
+      return DesugarDescription.nothing();
     }
-    DesugarDescription description = computeEmulatedInterfaceVirtualDispatch(invoke);
+    if (desugaringMode == EMULATED_INTERFACE_ONLY) {
+      if (resolutionResult.getResolvedMethod().isPrivate()
+          && resolutionResult.isAccessibleFrom(context, appView, appInfo).isTrue()) {
+        return DesugarDescription.nothing();
+      }
+      if (resolutionResult.getResolvedMethod().isStatic()) {
+        return DesugarDescription.nothing();
+      }
+      return computeEmulatedInterfaceVirtualDispatch(resolutionResult);
+    }
+    DesugarDescription description = computeEmulatedInterfaceVirtualDispatch(resolutionResult);
     if (description != DesugarDescription.nothing()) {
       return description;
     }
     // It may be the case that a virtual invoke resolves to a static method. In such a case, if
     // a default method could give rise to a forwarding method in the resolution path, the program
     // would change behavior from throwing ICCE to dispatching to the companion class method.
-    AppInfoWithClassHierarchy appInfo = appView.appInfoForDesugaring();
-    SingleResolutionResult<?> resolution =
-        appInfo.resolveMethodLegacy(invoke.getMethod(), invoke.isInterface()).asSingleResolution();
-    if (resolution != null && resolution.getResolvedMethod().isStatic()) {
+    if (resolutionResult.getResolvedMethod().isStatic()) {
       DexClassAndMethod target = appInfo.lookupMaximallySpecificMethod(holder, invoke.getMethod());
       if (target != null && target.isDefaultMethod()) {
         // Rewrite the invoke to a throw ICCE as the default method forward would otherwise hide the
         // static / virtual mismatch.
-        return computeInvokeAsThrowRewrite(invoke, resolution.asSingleResolution(), context);
+        return computeInvokeAsThrowRewrite(invoke, resolutionResult.asSingleResolution(), context);
       }
     }
     return DesugarDescription.nothing();
   }
 
-  private DesugarDescription computeEmulatedInterfaceVirtualDispatch(CfInvoke invoke) {
-    MethodResolutionResult resolutionResult =
-        appView
-            .appInfoForDesugaring()
-            .resolveMethodLegacy(invoke.getMethod(), invoke.isInterface());
-    DerivedMethod emulatedDispatchMethod =
-        helper.computeEmulatedInterfaceDispatchMethod(resolutionResult);
-    if (emulatedDispatchMethod == null) {
+  private DesugarDescription computeEmulatedInterfaceVirtualDispatch(
+      SingleResolutionResult<?> resolutionResult) {
+    assert resolutionResult != null;
+    EmulatedDispatchMethodDescriptor emulatedDispatchMethodDescriptor =
+        helper.getEmulatedDispatchDescriptor(
+            resolutionResult.getInitialResolutionHolder(), resolutionResult.getResolutionPair());
+    if (emulatedDispatchMethodDescriptor == null) {
       return DesugarDescription.nothing();
     }
     return DesugarDescription.builder()
@@ -511,14 +514,16 @@
                 getInvokeStaticInstructions(
                     helper
                         .ensureEmulatedInterfaceDispatchMethod(
-                            emulatedDispatchMethod, eventConsumer)
+                            emulatedDispatchMethodDescriptor, eventConsumer)
                         .getReference()))
         .build();
   }
 
-  @SuppressWarnings("ReferenceEquality")
   private DesugarDescription computeInvokeDirect(
-      DexClass clazz, CfInvoke invoke, ProgramMethod context) {
+      DexClass clazz,
+      CfInvoke invoke,
+      ProgramMethod context,
+      MethodResolutionResult resolutionResult) {
     DexMethod invokedMethod = invoke.getMethod();
     if (!clazz.isInterface()) {
       return DesugarDescription.nothing();
@@ -532,13 +537,11 @@
           getMethodOrigin(context.getReference()));
     }
 
-    MethodResolutionResult resolution =
-        appView.appInfoForDesugaring().resolveMethodLegacy(invokedMethod, invoke.isInterface());
-    if (resolution.isFailedResolution()) {
+    if (resolutionResult.isFailedResolution()) {
       return computeInvokeAsThrowRewrite(invoke, null, context);
     }
 
-    SingleResolutionResult<?> singleResolution = resolution.asSingleResolution();
+    SingleResolutionResult<?> singleResolution = resolutionResult.asSingleResolution();
     if (singleResolution == null) {
       return DesugarDescription.nothing();
     }
@@ -673,28 +676,17 @@
   }
 
   @SuppressWarnings("ReferenceEquality")
-  private DesugarDescription rewriteInvokeSuper(CfInvoke invoke, ProgramMethod context) {
-    DexMethod invokedMethod = invoke.getMethod();
-    DexClass clazz = appView.definitionFor(invokedMethod.holder, context);
-    if (clazz == null) {
-      // NOTE: leave unchanged those calls to undefined targets. This may lead to runtime
-      // exception but we can not report it as error since it can also be the intended
-      // behavior.
-      return DesugarDescription.builder()
-          .addScanEffect(() -> warnMissingType(context, invokedMethod.holder))
-          .build();
-    }
-
-    SingleResolutionResult<?> resolutionResult =
-        appView
-            .appInfoForDesugaring()
-            .resolveMethodOnLegacy(clazz, invokedMethod)
-            .asSingleResolution();
-    if (clazz.isInterface() && shouldRewriteToInvokeToThrow(resolutionResult, false)) {
+  private DesugarDescription rewriteInvokeSuper(
+      DexClass holder,
+      CfInvoke invoke,
+      ProgramMethod context,
+      SingleResolutionResult<?> resolutionResult) {
+    if (holder.isInterface() && shouldRewriteToInvokeToThrow(resolutionResult, false)) {
       return computeInvokeAsThrowRewrite(invoke, resolutionResult, context);
     }
 
-    if (clazz.isInterface() && !resolutionResult.getResolutionPair().getHolder().isLibraryClass()) {
+    if (holder.isInterface()
+        && !resolutionResult.getResolutionPair().getHolder().isLibraryClass()) {
       // NOTE: we intentionally don't desugar super calls into interface methods
       // coming from android.jar since it is only possible in case v24+ version
       // of android.jar is provided.
@@ -755,7 +747,7 @@
                   //  that not be the correct target!? I think this is just legacy from before
                   //  resolution was implemented in full.
                   DexMethod amendedMethod =
-                      amendDefaultMethod(context12.getHolder(), invokedMethod);
+                      amendDefaultMethod(context12.getHolder(), invoke.getMethod());
                   assert method.getReference() == amendedMethod;
                   DexClassAndMethod companionMethod =
                       helper.ensureDefaultAsMethodOfCompanionClassStub(method, eventConsumer);
@@ -766,7 +758,7 @@
     }
 
     DesugarDescription emulatedInterfaceDesugaring =
-        computeEmulatedInterfaceInvokeSpecial(clazz, invokedMethod, context);
+        computeEmulatedInterfaceInvokeSpecial(holder, invoke.getMethod(), context);
     if (!emulatedInterfaceDesugaring.needsDesugaring()) {
       if (context.isDefaultMethod()) {
         return AlwaysThrowingInstructionDesugaring.computeInvokeAsThrowNSMERewrite(
@@ -796,11 +788,9 @@
     if (clazz == null) {
       return DesugarDescription.nothing();
     }
-    AppInfoWithClassHierarchy appInfoForDesugaring = appView.appInfoForDesugaring();
+    AppInfoWithClassHierarchy appInfo = appView.appInfoForDesugaring();
     DexClassAndMethod superTarget =
-        appView
-            .appInfoForDesugaring()
-            .lookupSuperTarget(invokedMethod, context, appView, appInfoForDesugaring);
+        appView.appInfoForDesugaring().lookupSuperTarget(invokedMethod, context, appView, appInfo);
     if (clazz.isInterface()
         && clazz.isLibraryClass()
         && helper.isInDesugaredLibrary(clazz)