Share resolution checks for holder in interface desugaring.

Bug: 199135051
Bug: 198267586
Change-Id: Ie5cff55fd6b9db3007b8ecebd17177914a994bbe
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 6117eb7..c9b9a70 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
@@ -292,44 +292,16 @@
   }
 
   private DesugarDescription computeDescription(CfInstruction instruction, ProgramMethod context) {
+    // Interface desugaring is only interested in invokes and should not be double processed.
     CfInvoke invoke = instruction.asInvoke();
     if (invoke == null || isAlreadyDesugared(invoke, context)) {
       return DesugarDescription.nothing();
     }
-    if (invoke.isInvokeStatic()) {
-      return computeInvokeStatic(invoke, context);
-    }
-    if (invoke.isInvokeSpecial()) {
-      return computeInvokeSpecial(invoke, context);
-    }
-    if (invoke.isInvokeVirtual() || invoke.isInvokeInterface()) {
-      return computeInvokeVirtualDispatch(invoke, context);
-    }
-    return DesugarDescription.nothing();
-  }
-
-  private DesugarDescription computeInvokeSpecial(CfInvoke invoke, ProgramMethod context) {
-    if (invoke.isInvokeConstructor(factory)) {
+    // There should never be any calls to interface initializers.
+    if (invoke.isInvokeSpecial() && invoke.isInvokeConstructor(factory)) {
       return DesugarDescription.nothing();
     }
-    DexClass holder = appView.definitionForHolder(invoke.getMethod(), context);
-    if (holder == null) {
-      // NOTE: For invoke-super, this leaves 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.
-      // For invoke-direct, this reports the missing class since we don't know if it is an
-      // interface.
-      return DesugarDescription.builder()
-          .addScanEffect(() -> warnMissingType(context, invoke.getMethod().getHolderType()))
-          .build();
-    }
-    if (invoke.isInvokeSuper(context.getHolderType())) {
-      return rewriteInvokeSuper(invoke, context);
-    }
-    return computeInvokeDirect(invoke, context);
-  }
-
-  private DesugarDescription computeInvokeStatic(CfInvoke invoke, ProgramMethod context) {
+    // If the target holder does not resolve we may want to issue diagnostics.
     DexClass holder = appView.definitionForHolder(invoke.getMethod(), context);
     if (holder == null) {
       // NOTE: leave unchanged those calls to undefined targets. This may lead to runtime
@@ -339,13 +311,38 @@
         return DesugarDescription.builder()
             .addScanEffect(
                 () -> {
-                  leavingStaticInvokeToInterface(context);
+                  if (invoke.isInvokeStatic()) {
+                    leavingStaticInvokeToInterface(context);
+                  }
                   warnMissingType(context, invoke.getMethod().getHolderType());
                 })
             .build();
       }
       return DesugarDescription.nothing();
     }
+    // Continue with invoke type logic.
+    if (invoke.isInvokeStatic()) {
+      return computeInvokeStatic(holder, invoke, context);
+    }
+    if (invoke.isInvokeSpecial()) {
+      return computeInvokeSpecial(holder, invoke, context);
+    }
+    if (invoke.isInvokeVirtual() || invoke.isInvokeInterface()) {
+      return computeInvokeVirtualDispatch(holder, invoke, context);
+    }
+    return DesugarDescription.nothing();
+  }
+
+  private DesugarDescription computeInvokeSpecial(
+      DexClass holder, CfInvoke invoke, ProgramMethod context) {
+    if (invoke.isInvokeSuper(context.getHolderType())) {
+      return rewriteInvokeSuper(invoke, context);
+    }
+    return computeInvokeDirect(holder, invoke, context);
+  }
+
+  private DesugarDescription computeInvokeStatic(
+      DexClass holder, CfInvoke invoke, ProgramMethod context) {
     if (!holder.isInterface()) {
       if (invoke.isInterface()) {
         return DesugarDescription.builder()
@@ -449,7 +446,8 @@
         .build();
   }
 
-  private DesugarDescription computeInvokeVirtualDispatch(CfInvoke invoke, ProgramMethod context) {
+  private DesugarDescription computeInvokeVirtualDispatch(
+      DexClass holder, CfInvoke invoke, ProgramMethod context) {
     AppInfoWithClassHierarchy appInfoForDesugaring = appView.appInfoForDesugaring();
     SingleResolutionResult resolution =
         appInfoForDesugaring
@@ -459,12 +457,11 @@
         && resolution.getResolvedMethod().isPrivate()
         && resolution.isAccessibleFrom(context, appInfoForDesugaring).isTrue()) {
       // TODO(b/198267586): What about the private in-accessible case?
-      return computeInvokeDirect(invoke, context);
+      return computeInvokeDirect(holder, invoke, context);
     }
     if (resolution != null && resolution.getResolvedMethod().isStatic()) {
       return computeInvokeAsThrowRewrite(invoke, resolution);
     }
-    // TODO(b/198267586): What about an invoke <init>?
     DexClassAndMethod defaultMethod =
         defaultMethodForEmulatedDispatchOrNull(invoke.getMethod(), invoke.isInterface());
     if (defaultMethod != null) {
@@ -485,18 +482,9 @@
     return DesugarDescription.nothing();
   }
 
-  private DesugarDescription computeInvokeDirect(CfInvoke invoke, ProgramMethod context) {
-    if (invoke.isInvokeConstructor(factory)) {
-      return DesugarDescription.nothing();
-    }
+  private DesugarDescription computeInvokeDirect(
+      DexClass clazz, CfInvoke invoke, ProgramMethod context) {
     DexMethod invokedMethod = invoke.getMethod();
-    DexClass clazz = appView.definitionForHolder(invokedMethod, context);
-    if (clazz == null) {
-      // Report missing class since we don't know if it is an interface.
-      return DesugarDescription.builder()
-          .addScanEffect(() -> warnMissingType(context, invokedMethod.getHolderType()))
-          .build();
-    }
     if (!clazz.isInterface()) {
       return DesugarDescription.nothing();
     }