Introduce lookupXXOnItself

- Special lookup, local, used only in D8
  without desugaring.

Bug: 147578480
Change-Id: I86363e26119bdd85c1c678b2706122bbd2e764d4
diff --git a/src/main/java/com/android/tools/r8/graph/AppInfo.java b/src/main/java/com/android/tools/r8/graph/AppInfo.java
index 9bf667b..dcad411 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfo.java
@@ -201,6 +201,61 @@
     definitions.remove(type);
   }
 
+  // TODO(b/147578480): Temporary API since most of the code base use a type instead
+  // of a DexProgramClass as the invocationContext.
+  DexProgramClass toProgramClass(DexType type) {
+    assert type.isClassType();
+    return DexProgramClass.asProgramClassOrNull(definitionFor(type));
+  }
+
+  /**
+   * Lookup static method on the method holder, or answers null.
+   *
+   * @param method the method to lookup
+   * @param invocationContext the class the invoke is contained in, i.e., the holder of the caller.
+   * @return The actual target for {@code method} if on the holder, or {@code null}.
+   */
+  @Deprecated // TODO(b/147578480): Remove
+  public DexEncodedMethod lookupStaticTargetOnItself(DexMethod method, DexType invocationContext) {
+    return lookupStaticTargetOnItself(method, toProgramClass(invocationContext));
+  }
+
+  public final DexEncodedMethod lookupStaticTargetOnItself(
+      DexMethod method, DexProgramClass invocationContext) {
+    if (method.holder != invocationContext.type) {
+      return null;
+    }
+    DexEncodedMethod singleTarget = invocationContext.lookupDirectMethod(method);
+    if (singleTarget.isStatic()) {
+      return singleTarget;
+    }
+    return null;
+  }
+
+  /**
+   * Lookup direct method on the method holder, or answers null.
+   *
+   * @param method the method to lookup
+   * @param invocationContext the class the invoke is contained in, i.e., the holder of the caller.
+   * @return The actual target for {@code method} if on the holder, or {@code null}.
+   */
+  @Deprecated // TODO(b/147578480): Remove
+  public DexEncodedMethod lookupDirectTargetOnItself(DexMethod method, DexType invocationContext) {
+    return lookupDirectTargetOnItself(method, toProgramClass(invocationContext));
+  }
+
+  public final DexEncodedMethod lookupDirectTargetOnItself(
+      DexMethod method, DexProgramClass invocationContext) {
+    if (method.holder != invocationContext.type) {
+      return null;
+    }
+    DexEncodedMethod singleTarget = invocationContext.lookupDirectMethod(method);
+    if (!singleTarget.isStatic()) {
+      return singleTarget;
+    }
+    return null;
+  }
+
   // TODO(b/147578480): RemoveDeprecation Use AppInfoWithClassHierarchy and
   // lookupXX(DexMethod, DexProgramClass). The following 3 methods should either be removed or
   // return null.
diff --git a/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java b/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
index 945a773..87a2343 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
@@ -145,14 +145,4 @@
     assert checkIfObsolete();
     return resolveMethod(method.holder, method).lookupInvokeDirectTarget(invocationContext, this);
   }
-
-  private DexProgramClass toProgramClass(DexType type) {
-    assert type.isClassType();
-    DexClass clazz = definitionFor(type);
-    if (clazz == null) {
-      return null;
-    }
-    assert clazz.isProgramClass();
-    return clazz.asProgramClass();
-  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
index 29c6b76..db939e8 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
@@ -125,22 +125,14 @@
     DexMethod invokedMethod = getInvokedMethod();
     if (appView.appInfo().hasLiveness()) {
       AppInfoWithLiveness appInfo = appView.appInfo().withLiveness();
-      return appInfo.lookupDirectTarget(invokedMethod, invocationContext);
+      DexEncodedMethod result = appInfo.lookupDirectTarget(invokedMethod, invocationContext);
+      assert verifyD8LookupResult(
+          result, appView.appInfo().lookupDirectTargetOnItself(invokedMethod, invocationContext));
+      return result;
     }
     // In D8, we can treat invoke-direct instructions as having a single target if the invoke is
     // targeting a method in the enclosing class.
-    if (invokedMethod.holder == invocationContext) {
-      DexClass clazz = appView.definitionFor(invokedMethod.holder);
-      if (clazz != null && clazz.isProgramClass()) {
-        DexEncodedMethod singleTarget = clazz.lookupDirectMethod(invokedMethod);
-        if (!singleTarget.isStatic()) {
-          return singleTarget;
-        }
-      } else {
-        assert false;
-      }
-    }
-    return null;
+    return appView.appInfo().lookupDirectTargetOnItself(invokedMethod, invocationContext);
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java b/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
index e7d2ab1..451b9a5 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
@@ -199,4 +199,13 @@
     }
     return UnknownValue.getInstance();
   }
+
+  boolean verifyD8LookupResult(
+      DexEncodedMethod hierarchyResult, DexEncodedMethod lookupDirectTargetOnItself) {
+    if (lookupDirectTargetOnItself == null) {
+      return true;
+    }
+    assert lookupDirectTargetOnItself == hierarchyResult;
+    return true;
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java b/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
index 6893f5f..c8f8b49 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
@@ -8,7 +8,6 @@
 import com.android.tools.r8.cf.code.CfInvoke;
 import com.android.tools.r8.code.InvokeStaticRange;
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexType;
@@ -105,22 +104,14 @@
     DexMethod invokedMethod = getInvokedMethod();
     if (appView.appInfo().hasLiveness()) {
       AppInfoWithLiveness appInfo = appView.appInfo().withLiveness();
-      return appInfo.lookupStaticTarget(invokedMethod, invocationContext);
+      DexEncodedMethod result = appInfo.lookupStaticTarget(invokedMethod, invocationContext);
+      assert verifyD8LookupResult(
+          result, appView.appInfo().lookupStaticTargetOnItself(invokedMethod, invocationContext));
+      return result;
     }
     // In D8, we can treat invoke-static instructions as having a single target if the invoke is
     // targeting a method in the enclosing class.
-    if (invokedMethod.holder == invocationContext) {
-      DexClass clazz = appView.definitionFor(invokedMethod.holder);
-      if (clazz != null && clazz.isProgramClass()) {
-        DexEncodedMethod singleTarget = clazz.lookupDirectMethod(invokedMethod);
-        if (singleTarget.isStatic()) {
-          return singleTarget;
-        }
-      } else {
-        assert false;
-      }
-    }
-    return null;
+    return appView.appInfo().lookupStaticTargetOnItself(invokedMethod, invocationContext);
   }
 
   @Override