Introduce DexClassAndMethod result object
Change-Id: Ie8c7c52a6d5efbcf341f12af330359cccdd99aa4
diff --git a/src/main/java/com/android/tools/r8/graph/DexClassAndMethod.java b/src/main/java/com/android/tools/r8/graph/DexClassAndMethod.java
new file mode 100644
index 0000000..9d07cc6
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/DexClassAndMethod.java
@@ -0,0 +1,52 @@
+// Copyright (c) 2020, 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.graph;
+
+import com.android.tools.r8.errors.Unreachable;
+
+public class DexClassAndMethod<C extends DexClass> {
+
+ private static final DexClassAndMethod<?> NO_RESULT = new DexClassAndMethod<>(null, null);
+
+ public final C holder;
+ public final DexEncodedMethod method;
+
+ protected DexClassAndMethod(C holder, DexEncodedMethod method) {
+ assert (holder == null && method == null)
+ || (holder != null && method != null && holder.type == method.method.holder);
+ this.holder = holder;
+ this.method = method;
+ }
+
+ public static <C extends DexClass> DexClassAndMethod<C> createResult(
+ C c, DexEncodedMethod method) {
+ assert c != null;
+ assert method != null;
+ assert c.type == method.method.holder;
+ return new DexClassAndMethod<C>(c, method);
+ }
+
+ public static DexClassAndMethod<?> createNoResult() {
+ return NO_RESULT;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ throw new Unreachable("Unsupported attempt at comparing Class and DexClassAndMethod");
+ }
+
+ @Override
+ public int hashCode() {
+ throw new Unreachable("Unsupported attempt at computing the hashcode of DexClassAndMethod");
+ }
+
+ public boolean hasResult() {
+ return this != NO_RESULT;
+ }
+
+ public boolean hasNoResult() {
+ return this == NO_RESULT;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/graph/ProgramMethod.java b/src/main/java/com/android/tools/r8/graph/ProgramMethod.java
index 1e33e66..8a68ee5 100644
--- a/src/main/java/com/android/tools/r8/graph/ProgramMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/ProgramMethod.java
@@ -3,26 +3,10 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;
-import com.android.tools.r8.errors.Unreachable;
-
/** Type representing a method definition in the programs compilation unit and its holder. */
-public class ProgramMethod {
- public final DexProgramClass holder;
- public final DexEncodedMethod method;
+public final class ProgramMethod extends DexClassAndMethod<DexProgramClass> {
- public ProgramMethod(DexProgramClass holder, DexEncodedMethod method) {
- assert holder.type == method.method.holder;
- this.holder = holder;
- this.method = method;
- }
-
- @Override
- public boolean equals(Object obj) {
- throw new Unreachable("Unsupported attempt at comparing ProgramMethod");
- }
-
- @Override
- public int hashCode() {
- throw new Unreachable("Unsupported attempt at computing the hashcode of ProgramMethod");
+ public ProgramMethod(DexProgramClass holder, DexEncodedMethod method) {
+ super(holder, method);
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/ResolutionResult.java b/src/main/java/com/android/tools/r8/graph/ResolutionResult.java
index 0941f92..1f5c91b 100644
--- a/src/main/java/com/android/tools/r8/graph/ResolutionResult.java
+++ b/src/main/java/com/android/tools/r8/graph/ResolutionResult.java
@@ -86,7 +86,7 @@
return lookupVirtualDispatchTargets(context, appView, appView.appInfo());
}
- public abstract DexEncodedMethod lookupVirtualDispatchTarget(
+ public abstract DexClassAndMethod<?> lookupVirtualDispatchTarget(
DexProgramClass dynamicInstance, AppView<? extends AppInfoWithClassHierarchy> appView);
/** Result for a resolution that succeeds with a known declaration/definition. */
@@ -356,11 +356,11 @@
instantiatedInfo.forEachInstantiatedSubType(
resolvedHolder.type,
subClass -> {
- DexEncodedMethod lookupTarget = lookupVirtualDispatchTarget(subClass, appView);
- if (lookupTarget == null) {
- return;
+ DexClassAndMethod<?> dexClassAndMethod = lookupVirtualDispatchTarget(subClass, appView);
+ if (dexClassAndMethod.hasResult()) {
+ addVirtualDispatchTarget(
+ dexClassAndMethod.method, resolvedHolder.isInterface(), result);
}
- addVirtualDispatchTarget(lookupTarget, resolvedHolder.isInterface(), result);
},
dexCallSite -> {
// TODO(b/148769279): We need to look at the call site to see if it overrides
@@ -416,7 +416,7 @@
* we have an object ref on the stack.
*/
@Override
- public DexEncodedMethod lookupVirtualDispatchTarget(
+ public DexClassAndMethod<?> lookupVirtualDispatchTarget(
DexProgramClass dynamicInstance, AppView<? extends AppInfoWithClassHierarchy> appView) {
// TODO(b/148591377): Enable this assertion.
// The dynamic type cannot be an interface.
@@ -434,16 +434,21 @@
if (candidate == null || candidate == DexEncodedMethod.SENTINEL) {
// We cannot find a target above the resolved method.
if (current.type == overrideTarget.method.holder) {
- return null;
+ return DexClassAndMethod.createNoResult();
}
current = current.superType == null ? null : appView.definitionFor(current.superType);
continue;
}
- return candidate;
+ return DexClassAndMethod.createResult(current, candidate);
}
// TODO(b/149557233): Enable assertion.
// assert resolvedHolder.isInterface();
- return lookupMaximallySpecificDispatchTarget(dynamicInstance, appView);
+ DexEncodedMethod maximalSpecific =
+ lookupMaximallySpecificDispatchTarget(dynamicInstance, appView);
+ return maximalSpecific == null
+ ? DexClassAndMethod.createNoResult()
+ : DexClassAndMethod.createResult(
+ appView.definitionFor(maximalSpecific.method.holder), maximalSpecific);
}
private DexEncodedMethod lookupMaximallySpecificDispatchTarget(
@@ -550,9 +555,9 @@
}
@Override
- public DexEncodedMethod lookupVirtualDispatchTarget(
+ public DexClassAndMethod<?> lookupVirtualDispatchTarget(
DexProgramClass dynamicInstance, AppView<? extends AppInfoWithClassHierarchy> appView) {
- return null;
+ return DexClassAndMethod.createNoResult();
}
}