Make ResolutionResult a class.
This is in preparation for refactoring resolution and lookup to have a
single definitive implementation.
Bug: 140204899
Change-Id: I33caf64c8af3929229629aed0738052f48976213
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 773f4ad..d569852 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfo.java
@@ -6,8 +6,9 @@
import com.android.tools.r8.graph.ResolutionResult.ArrayCloneMethodResult;
import com.android.tools.r8.graph.ResolutionResult.ClassNotFoundResult;
import com.android.tools.r8.graph.ResolutionResult.IncompatibleClassResult;
-import com.android.tools.r8.graph.ResolutionResult.MultiResult;
+import com.android.tools.r8.graph.ResolutionResult.MultiResolutionResult;
import com.android.tools.r8.graph.ResolutionResult.NoSuchMethodResult;
+import com.android.tools.r8.graph.ResolutionResult.SingleResolutionResult;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.InternalOptions;
@@ -190,7 +191,7 @@
public DexEncodedMethod lookupStaticTarget(DexMethod method) {
assert checkIfObsolete();
ResolutionResult resolutionResult = resolveMethod(method.holder, method);
- DexEncodedMethod target = resolutionResult.asSingleTarget();
+ DexEncodedMethod target = resolutionResult.getSingleTarget();
return target == null || target.isStatic() ? target : null;
}
@@ -215,7 +216,7 @@
// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokespecial, use
// the "symbolic reference" if the "symbolic reference" does not name a class.
if (definitionFor(method.holder).isInterface()) {
- return resolveMethodOnInterface(method.holder, method).asSingleTarget();
+ return resolveMethodOnInterface(method.holder, method).getSingleTarget();
}
// Then, resume on the search, but this time, starting from the holder of the caller.
DexClass contextClass = definitionFor(invocationContext);
@@ -223,7 +224,7 @@
return null;
}
resolutionResult = resolveMethod(contextClass.superType, method);
- DexEncodedMethod target = resolutionResult.asSingleTarget();
+ DexEncodedMethod target = resolutionResult.getSingleTarget();
return target == null || !target.isStatic() ? target : null;
}
@@ -238,7 +239,7 @@
public DexEncodedMethod lookupDirectTarget(DexMethod method) {
assert checkIfObsolete();
ResolutionResult resolutionResult = resolveMethod(method.holder, method);
- DexEncodedMethod target = resolutionResult.asSingleTarget();
+ DexEncodedMethod target = resolutionResult.getSingleTarget();
return target == null || target.isDirectMethod() ? target : null;
}
@@ -252,7 +253,7 @@
assert checkIfObsolete();
assert type.isClassType() || type.isArrayType();
ResolutionResult resolutionResult = resolveMethod(type, method);
- DexEncodedMethod target = resolutionResult.asSingleTarget();
+ DexEncodedMethod target = resolutionResult.getSingleTarget();
return target == null || target.isVirtualMethod() ? target : null;
}
@@ -352,7 +353,7 @@
// Step 2:
DexEncodedMethod singleTarget = resolveMethodOnClassStep2(clazz, method);
if (singleTarget != null) {
- return singleTarget;
+ return new SingleResolutionResult(singleTarget);
}
// Finally Step 3:
return resolveMethodStep3(clazz, method);
@@ -414,7 +415,7 @@
return result;
}
// Return any of the non-default methods.
- return anyTarget == null ? NoSuchMethodResult.INSTANCE : anyTarget;
+ return anyTarget == null ? NoSuchMethodResult.INSTANCE : new SingleResolutionResult(anyTarget);
}
/**
@@ -491,7 +492,7 @@
// Step 2: Look for exact method on interface.
DexEncodedMethod result = definition.lookupMethod(desc);
if (result != null) {
- return result;
+ return new SingleResolutionResult(result);
}
// Step 3: Look for matching method on object class.
DexClass objectClass = definitionFor(dexItemFactory.objectType);
@@ -500,7 +501,7 @@
}
result = objectClass.lookupMethod(desc);
if (result != null && result.accessFlags.isPublic() && !result.accessFlags.isAbstract()) {
- return result;
+ return new SingleResolutionResult(result);
}
// Step 3: Look for maximally-specific superinterface methods or any interface definition.
// This is the same for classes and interfaces.
@@ -583,7 +584,7 @@
*/
public DexEncodedMethod dispatchStaticInvoke(ResolutionResult resolvedMethod) {
assert checkIfObsolete();
- DexEncodedMethod target = resolvedMethod.asSingleTarget();
+ DexEncodedMethod target = resolvedMethod.getSingleTarget();
if (target != null && target.accessFlags.isStatic()) {
return target;
}
@@ -597,7 +598,7 @@
*/
public DexEncodedMethod dispatchDirectInvoke(ResolutionResult resolvedMethod) {
assert checkIfObsolete();
- DexEncodedMethod target = resolvedMethod.asSingleTarget();
+ DexEncodedMethod target = resolvedMethod.getSingleTarget();
if (target != null && !target.accessFlags.isStatic()) {
return target;
}
@@ -669,10 +670,12 @@
ResolutionResult build() {
if (builder != null) {
- return new MultiResult(builder.build().asList());
- } else {
- return singleResult;
+ return new MultiResolutionResult(builder.build().asList());
}
+ if (singleResult != null) {
+ return new SingleResolutionResult(singleResult);
+ }
+ return null;
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/AppInfoWithSubtyping.java b/src/main/java/com/android/tools/r8/graph/AppInfoWithSubtyping.java
index 3425946..edec812 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfoWithSubtyping.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfoWithSubtyping.java
@@ -746,7 +746,7 @@
if (clazz.isProgramClass()) {
if (lookUpwards) {
DexEncodedMethod resolutionResult =
- resolveMethod(type, dexItemFactory().objectMethods.finalize).asSingleTarget();
+ resolveMethod(type, dexItemFactory().objectMethods.finalize).getSingleTarget();
if (resolutionResult != null && resolutionResult.isProgramMethod(this)) {
mayHaveFinalizeMethodDirectlyOrIndirectlyCache.put(type, true);
return true;
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 200240c..776cbaf 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -77,7 +77,7 @@
import java.util.function.IntPredicate;
import org.objectweb.asm.Opcodes;
-public class DexEncodedMethod extends KeyedDexItem<DexMethod> implements ResolutionResult {
+public class DexEncodedMethod extends KeyedDexItem<DexMethod> {
public static final String CONFIGURATION_DEBUGGING_PREFIX = "Shaking error: Missing method in ";
@@ -1311,46 +1311,4 @@
return result;
}
}
-
- @Override
- public boolean isValidVirtualTarget(InternalOptions options) {
- return options.canUseNestBasedAccess()
- ? (!accessFlags.isStatic() && !accessFlags.isConstructor())
- : isVirtualMethod();
- }
-
- @Override
- public boolean isValidVirtualTargetForDynamicDispatch() {
- return isVirtualMethod();
- }
-
- @Override
- public DexEncodedMethod asResultOfResolve() {
- checkIfObsolete();
- return this;
- }
-
- @Override
- public DexEncodedMethod asSingleTarget() {
- checkIfObsolete();
- return this;
- }
-
- @Override
- public boolean hasSingleTarget() {
- checkIfObsolete();
- return true;
- }
-
- @Override
- public List<DexEncodedMethod> asListOfTargets() {
- checkIfObsolete();
- return Collections.singletonList(this);
- }
-
- @Override
- public void forEachTarget(Consumer<DexEncodedMethod> consumer) {
- checkIfObsolete();
- consumer.accept(this);
- }
}
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 dfd31fb..6a9a22a 100644
--- a/src/main/java/com/android/tools/r8/graph/ResolutionResult.java
+++ b/src/main/java/com/android/tools/r8/graph/ResolutionResult.java
@@ -11,30 +11,30 @@
import java.util.Set;
import java.util.function.Consumer;
-public interface ResolutionResult {
+public abstract class ResolutionResult {
// TODO(b/140214802): Remove this method as its usage is questionable.
- DexEncodedMethod asResultOfResolve();
+ public abstract DexEncodedMethod asResultOfResolve();
- DexEncodedMethod asSingleTarget();
+ public abstract DexEncodedMethod getSingleTarget();
- boolean hasSingleTarget();
+ public abstract boolean hasSingleTarget();
- List<DexEncodedMethod> asListOfTargets();
+ public abstract List<DexEncodedMethod> asListOfTargets();
- void forEachTarget(Consumer<DexEncodedMethod> consumer);
+ public abstract void forEachTarget(Consumer<DexEncodedMethod> consumer);
- boolean isValidVirtualTarget(InternalOptions options);
+ public abstract boolean isValidVirtualTarget(InternalOptions options);
- boolean isValidVirtualTargetForDynamicDispatch();
+ public abstract boolean isValidVirtualTargetForDynamicDispatch();
- default Set<DexEncodedMethod> lookupVirtualDispatchTargets(
+ public Set<DexEncodedMethod> lookupVirtualDispatchTargets(
boolean isInterface, AppInfoWithSubtyping appInfo) {
return isInterface ? lookupInterfaceTargets(appInfo) : lookupVirtualTargets(appInfo);
}
// TODO(b/140204899): Leverage refined receiver type if available.
- default Set<DexEncodedMethod> lookupVirtualTargets(AppInfoWithSubtyping appInfo) {
+ public Set<DexEncodedMethod> lookupVirtualTargets(AppInfoWithSubtyping appInfo) {
assert isValidVirtualTarget(appInfo.app().options);
// First add the target for receiver type method.type.
Set<DexEncodedMethod> result = Sets.newIdentityHashSet();
@@ -60,7 +60,7 @@
}
// TODO(b/140204899): Leverage refined receiver type if available.
- default Set<DexEncodedMethod> lookupInterfaceTargets(AppInfoWithSubtyping appInfo) {
+ public Set<DexEncodedMethod> lookupInterfaceTargets(AppInfoWithSubtyping appInfo) {
assert isValidVirtualTarget(appInfo.app().options);
Set<DexEncodedMethod> result = Sets.newIdentityHashSet();
if (hasSingleTarget()) {
@@ -86,7 +86,7 @@
// public void bar() { }
// }
//
- DexEncodedMethod singleTarget = asSingleTarget();
+ DexEncodedMethod singleTarget = getSingleTarget();
if (singleTarget.getCode() != null
&& appInfo.hasAnyInstantiatedLambdas(singleTarget.method.holder)) {
result.add(singleTarget);
@@ -128,11 +128,61 @@
return result;
}
- class MultiResult implements ResolutionResult {
+ public static class SingleResolutionResult extends ResolutionResult {
+ final DexEncodedMethod resolutionTarget;
+
+ public static boolean isValidVirtualTarget(InternalOptions options, DexEncodedMethod target) {
+ return options.canUseNestBasedAccess()
+ ? (!target.accessFlags.isStatic() && !target.accessFlags.isConstructor())
+ : target.isVirtualMethod();
+ }
+
+ public SingleResolutionResult(DexEncodedMethod resolutionTarget) {
+ assert resolutionTarget != null;
+ this.resolutionTarget = resolutionTarget;
+ }
+
+ @Override
+ public boolean isValidVirtualTarget(InternalOptions options) {
+ return isValidVirtualTarget(options, resolutionTarget);
+ }
+
+ @Override
+ public boolean isValidVirtualTargetForDynamicDispatch() {
+ return resolutionTarget.isVirtualMethod();
+ }
+
+ @Override
+ public DexEncodedMethod asResultOfResolve() {
+ return resolutionTarget;
+ }
+
+ @Override
+ public DexEncodedMethod getSingleTarget() {
+ return resolutionTarget;
+ }
+
+ @Override
+ public boolean hasSingleTarget() {
+ return true;
+ }
+
+ @Override
+ public List<DexEncodedMethod> asListOfTargets() {
+ return Collections.singletonList(resolutionTarget);
+ }
+
+ @Override
+ public void forEachTarget(Consumer<DexEncodedMethod> consumer) {
+ consumer.accept(resolutionTarget);
+ }
+ }
+
+ public static class MultiResolutionResult extends ResolutionResult {
private final ImmutableList<DexEncodedMethod> methods;
- MultiResult(ImmutableList<DexEncodedMethod> results) {
+ public MultiResolutionResult(ImmutableList<DexEncodedMethod> results) {
assert results.size() > 1;
this.methods = results;
}
@@ -140,7 +190,7 @@
@Override
public boolean isValidVirtualTarget(InternalOptions options) {
for (DexEncodedMethod method : methods) {
- if (!method.isValidVirtualTarget(options)) {
+ if (!SingleResolutionResult.isValidVirtualTarget(options, method)) {
return false;
}
}
@@ -164,7 +214,7 @@
}
@Override
- public DexEncodedMethod asSingleTarget() {
+ public DexEncodedMethod getSingleTarget() {
// There is no single target that is guaranteed to be called.
return null;
}
@@ -185,7 +235,7 @@
}
}
- abstract class EmptyResult implements ResolutionResult {
+ public abstract static class EmptyResult extends ResolutionResult {
@Override
public DexEncodedMethod asResultOfResolve() {
@@ -193,7 +243,7 @@
}
@Override
- public DexEncodedMethod asSingleTarget() {
+ public DexEncodedMethod getSingleTarget() {
return null;
}
@@ -223,7 +273,7 @@
}
}
- class ArrayCloneMethodResult extends EmptyResult {
+ public static class ArrayCloneMethodResult extends EmptyResult {
static final ArrayCloneMethodResult INSTANCE = new ArrayCloneMethodResult();
@@ -242,7 +292,7 @@
}
}
- abstract class FailedResolutionResult extends EmptyResult {
+ public abstract static class FailedResolutionResult extends EmptyResult {
@Override
public boolean isValidVirtualTarget(InternalOptions options) {
@@ -255,7 +305,7 @@
}
}
- class ClassNotFoundResult extends FailedResolutionResult {
+ public static class ClassNotFoundResult extends FailedResolutionResult {
static final ClassNotFoundResult INSTANCE = new ClassNotFoundResult();
private ClassNotFoundResult() {
@@ -263,7 +313,7 @@
}
}
- class IncompatibleClassResult extends FailedResolutionResult {
+ public static class IncompatibleClassResult extends FailedResolutionResult {
static final IncompatibleClassResult INSTANCE = new IncompatibleClassResult();
private IncompatibleClassResult() {
@@ -271,7 +321,7 @@
}
}
- class NoSuchMethodResult extends FailedResolutionResult {
+ public static class NoSuchMethodResult extends FailedResolutionResult {
static final NoSuchMethodResult INSTANCE = new NoSuchMethodResult();
private NoSuchMethodResult() {
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java
index e8583f6..827529a 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java
@@ -339,7 +339,7 @@
if (!resolutionResult.hasSingleTarget()) {
return false;
}
- DexType holder = resolutionResult.asSingleTarget().method.holder;
+ DexType holder = resolutionResult.getSingleTarget().method.holder;
return appView.isSubtype(holder, type).isTrue();
}
@@ -397,7 +397,7 @@
if (!resolutionResult.hasSingleTarget()) {
return false;
}
- DexType holder = resolutionResult.asSingleTarget().method.holder;
+ DexType holder = resolutionResult.getSingleTarget().method.holder;
return appView.isSubtype(holder, type).isTrue();
}
@@ -433,7 +433,7 @@
if (!resolutionResult.hasSingleTarget()) {
return false;
}
- DexType holder = resolutionResult.asSingleTarget().method.holder;
+ DexType holder = resolutionResult.getSingleTarget().method.holder;
return appView.isSubtype(holder, type).isTrue();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java b/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java
index 72e4c9d..0e0c975 100644
--- a/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java
@@ -191,7 +191,7 @@
DexEncodedMethod resolutionResult =
appInfo
.resolveMethod(clazz.type, dexItemFactory.objectMethods.finalize)
- .asSingleTarget();
+ .getSingleTarget();
return resolutionResult != null && resolutionResult.isProgramMethod(appInfo);
}
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 6c22405..c6f919d 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
@@ -109,7 +109,7 @@
ResolutionResult refinedResolution =
appView.appInfo().resolveMethod(refinedReceiverType, method);
if (refinedResolution.hasSingleTarget()) {
- DexEncodedMethod refinedTarget = refinedResolution.asSingleTarget();
+ DexEncodedMethod refinedTarget = refinedResolution.getSingleTarget();
Set<DexEncodedMethod> result = Sets.newIdentityHashSet();
for (DexEncodedMethod target : targets) {
if (target == refinedTarget
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewInstance.java b/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
index 7a38882..d9d65e5 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
@@ -176,7 +176,7 @@
ResolutionResult finalizeResolutionResult =
appView.appInfo().resolveMethod(clazz, dexItemFactory.objectMethods.finalize);
if (finalizeResolutionResult.hasSingleTarget()) {
- DexMethod finalizeMethod = finalizeResolutionResult.asSingleTarget().method;
+ DexMethod finalizeMethod = finalizeResolutionResult.getSingleTarget().method;
if (finalizeMethod != dexItemFactory.enumMethods.finalize
&& finalizeMethod != dexItemFactory.objectMethods.finalize) {
return true;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
index cea6258..adc1112 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
@@ -270,7 +270,7 @@
// references that have actual definitions are marked by the root set builder. So, here, we
// try again with a resolved target, not the direct definition, which may not exist.
DexEncodedMethod resolutionTarget =
- appView.appInfo().resolveMethod(invokedHolder, invokedMethod).asSingleTarget();
+ appView.appInfo().resolveMethod(invokedHolder, invokedMethod).getSingleTarget();
lookup = lookupMemberRule(resolutionTarget);
}
boolean invokeReplaced = false;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
index 084f3d3..40cb024 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
@@ -733,7 +733,7 @@
// signature of the invocation resolves to a private or static method.
ResolutionResult resolutionResult = appView.appInfo().resolveMethod(callee.holder, callee);
if (resolutionResult.hasSingleTarget()
- && !resolutionResult.asSingleTarget().isVirtualMethod()) {
+ && !resolutionResult.getSingleTarget().isVirtualMethod()) {
return null;
}
diff --git a/src/main/java/com/android/tools/r8/optimize/VisibilityBridgeRemover.java b/src/main/java/com/android/tools/r8/optimize/VisibilityBridgeRemover.java
index 8101b6b..942cb91 100644
--- a/src/main/java/com/android/tools/r8/optimize/VisibilityBridgeRemover.java
+++ b/src/main/java/com/android/tools/r8/optimize/VisibilityBridgeRemover.java
@@ -85,7 +85,7 @@
if (kind == InvokeKind.SUPER) {
// This is a visibility forward, so check for the direct target.
DexEncodedMethod targetMethod =
- appView.appInfo().resolveMethod(target.holder, target).asSingleTarget();
+ appView.appInfo().resolveMethod(target.holder, target).getSingleTarget();
if (targetMethod != null && targetMethod.accessFlags.isPublic()) {
if (Log.ENABLED) {
Log.info(
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index 829c227..77d29ab 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -26,6 +26,7 @@
import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.graph.PresortedComparable;
import com.android.tools.r8.graph.ResolutionResult;
+import com.android.tools.r8.graph.ResolutionResult.SingleResolutionResult;
import com.android.tools.r8.ir.analysis.type.ClassTypeLatticeElement;
import com.android.tools.r8.ir.code.Invoke.Type;
import com.android.tools.r8.ir.optimize.NestUtils;
@@ -904,7 +905,7 @@
private DexEncodedMethod validateSingleVirtualTarget(
DexEncodedMethod singleTarget, DexEncodedMethod resolutionResult) {
- assert resolutionResult.isValidVirtualTarget(options());
+ assert SingleResolutionResult.isValidVirtualTarget(options(), resolutionResult);
if (singleTarget == null || singleTarget == DexEncodedMethod.SENTINEL) {
return null;
@@ -921,7 +922,7 @@
private boolean isInvalidSingleVirtualTarget(
DexEncodedMethod singleTarget, DexEncodedMethod resolutionResult) {
- assert resolutionResult.isValidVirtualTarget(options());
+ assert SingleResolutionResult.isValidVirtualTarget(options(), resolutionResult);
// Art978_virtual_interfaceTest correctly expects an IncompatibleClassChangeError exception
// at runtime.
return !singleTarget.accessFlags.isAtLeastAsVisibleAs(resolutionResult.accessFlags);
@@ -956,7 +957,7 @@
if (refinedResolutionResult.hasSingleTarget()
&& refinedResolutionResult.isValidVirtualTargetForDynamicDispatch()) {
return validateSingleVirtualTarget(
- refinedResolutionResult.asSingleTarget(), resolutionResult.asSingleTarget());
+ refinedResolutionResult.getSingleTarget(), resolutionResult.getSingleTarget());
}
}
return null;
@@ -998,7 +999,7 @@
// Now, resolve the target with the refined receiver type.
ResolutionResult refinedResolutionResult =
refinedReceiverIsStrictSubType ? resolveMethodOnClass(refinedHolder, method) : topMethod;
- DexEncodedMethod topSingleTarget = refinedResolutionResult.asSingleTarget();
+ DexEncodedMethod topSingleTarget = refinedResolutionResult.getSingleTarget();
DexClass topHolder = definitionFor(topSingleTarget.method.holder);
// We need to know whether the top method is from an interface, as that would allow it to be
// shadowed by a default method from an interface further down.
@@ -1012,7 +1013,7 @@
topSingleTarget,
!refinedHolder.accessFlags.isAbstract(),
topIsFromInterface),
- topMethod.asSingleTarget());
+ topMethod.getSingleTarget());
assert result != DexEncodedMethod.SENTINEL;
method.setSingleVirtualMethodCache(refinedReceiverType, result);
return result;
@@ -1154,7 +1155,7 @@
if (refinedResolutionResult.hasSingleTarget()
&& refinedResolutionResult.isValidVirtualTargetForDynamicDispatch()) {
return validateSingleVirtualTarget(
- refinedResolutionResult.asSingleTarget(), resolutionResult.asSingleTarget());
+ refinedResolutionResult.getSingleTarget(), resolutionResult.getSingleTarget());
}
}
return null;
@@ -1170,8 +1171,8 @@
}
// First check that there is a target for this invoke-interface to hit. If there is none,
// this will fail at runtime.
- DexEncodedMethod topTarget = resolveMethodOnInterface(holder, method).asSingleTarget();
- if (topTarget == null || !topTarget.isValidVirtualTarget(options())) {
+ DexEncodedMethod topTarget = resolveMethodOnInterface(holder, method).getSingleTarget();
+ if (topTarget == null || !SingleResolutionResult.isValidVirtualTarget(options(), topTarget)) {
return null;
}
// For kept types we cannot ensure a single target.
@@ -1200,7 +1201,7 @@
// override them, so we ignore interface methods here. Otherwise, we would look up
// default methods that are factually never used.
} else if (!clazz.accessFlags.isAbstract()) {
- DexEncodedMethod resolutionResult = resolveMethodOnClass(clazz, method).asSingleTarget();
+ DexEncodedMethod resolutionResult = resolveMethodOnClass(clazz, method).getSingleTarget();
if (resolutionResult == null || isInvalidSingleVirtualTarget(resolutionResult, topTarget)) {
// This will fail at runtime.
return null;
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index e7ab7ed..46895aa 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -39,6 +39,7 @@
import com.android.tools.r8.graph.KeyedDexItem;
import com.android.tools.r8.graph.PresortedComparable;
import com.android.tools.r8.graph.ResolutionResult;
+import com.android.tools.r8.graph.ResolutionResult.SingleResolutionResult;
import com.android.tools.r8.graph.analysis.EnqueuerAnalysis;
import com.android.tools.r8.ir.analysis.proto.schema.ProtoEnqueuerExtension;
import com.android.tools.r8.ir.code.ArrayPut;
@@ -1305,7 +1306,7 @@
reportMissingMethod(method);
return;
}
- DexEncodedMethod encodedMethod = resolutionResult.asSingleTarget();
+ DexEncodedMethod encodedMethod = resolutionResult.getSingleTarget();
if (encodedMethod == null) {
// Note: should this be reported too? Or is this unreachable?
return;
@@ -1927,7 +1928,8 @@
// Otherwise, the resolution target is marked and cached, and all possible targets identified.
resolution = findAndMarkResolutionTarget(method, interfaceInvoke, reason);
virtualTargetsMarkedAsReachable.put(method, resolution);
- if (resolution.isUnresolved() || !resolution.method.isValidVirtualTarget(options)) {
+ if (resolution.isUnresolved()
+ || !SingleResolutionResult.isValidVirtualTarget(options, resolution.method)) {
// There is no valid resolution, so any call will lead to a runtime exception.
return;
}
@@ -1940,7 +1942,9 @@
assert interfaceInvoke == holder.isInterface();
Set<DexEncodedMethod> possibleTargets =
- resolution.method.lookupVirtualDispatchTargets(interfaceInvoke, appInfo);
+ // TODO(b/140214802): Call on the resolution once proper resolution and lookup is resolved.
+ new SingleResolutionResult(resolution.method)
+ .lookupVirtualDispatchTargets(interfaceInvoke, appInfo);
if (possibleTargets == null || possibleTargets.isEmpty()) {
return;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index 85da345..a9ec234 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -1283,7 +1283,7 @@
abortMerge = true;
return null;
}
- DexEncodedMethod actual = resolutionResult.asSingleTarget();
+ DexEncodedMethod actual = resolutionResult.getSingleTarget();
if (actual != method) {
assert actual.isVirtualMethod() == method.isVirtualMethod();
return actual;
diff --git a/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfPrivateStaticMethodTest.java b/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfPrivateStaticMethodTest.java
index e914a7b..ccdb49b 100644
--- a/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfPrivateStaticMethodTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfPrivateStaticMethodTest.java
@@ -84,7 +84,7 @@
public void lookupSingleTarget() {
ResolutionResult resolutionResult = appInfo.resolveMethodOnClass(methodOnB.holder, methodOnB);
assertFalse(resolutionResult.isValidVirtualTarget(appInfo.app().options));
- DexEncodedMethod resolved = resolutionResult.asSingleTarget();
+ DexEncodedMethod resolved = resolutionResult.getSingleTarget();
assertEquals(methodOnA, resolved.method);
DexEncodedMethod singleVirtualTarget =
appInfo.lookupSingleVirtualTarget(methodOnB, methodOnB.holder);
@@ -94,7 +94,7 @@
@Test
public void lookupVirtualTargets() {
ResolutionResult resolutionResult = appInfo.resolveMethodOnClass(methodOnB.holder, methodOnB);
- DexEncodedMethod resolved = resolutionResult.asSingleTarget();
+ DexEncodedMethod resolved = resolutionResult.getSingleTarget();
assertEquals(methodOnA, resolved.method);
assertFalse(resolutionResult.isValidVirtualTarget(appInfo.app().options));
}
diff --git a/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfPrivateStaticMethodWithVirtualParentTest.java b/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfPrivateStaticMethodWithVirtualParentTest.java
index 8d867d8..952cfe7 100644
--- a/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfPrivateStaticMethodWithVirtualParentTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfPrivateStaticMethodWithVirtualParentTest.java
@@ -143,7 +143,7 @@
@Test
public void lookupVirtualTargets() {
ResolutionResult resolutionResult = appInfo.resolveMethodOnClass(methodOnB.holder, methodOnB);
- DexEncodedMethod resolved = resolutionResult.asSingleTarget();
+ DexEncodedMethod resolved = resolutionResult.getSingleTarget();
assertEquals(methodOnA, resolved.method);
assertFalse(resolutionResult.isValidVirtualTarget(appInfo.app().options));
}
diff --git a/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentInterfaceTest.java b/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentInterfaceTest.java
index f968c03..7c435d3 100644
--- a/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentInterfaceTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentInterfaceTest.java
@@ -121,7 +121,7 @@
public void lookupSingleTarget() {
ResolutionResult resolutionResult =
appInfo.resolveMethodOnInterface(methodOnB.holder, methodOnB);
- DexEncodedMethod resolved = resolutionResult.asSingleTarget();
+ DexEncodedMethod resolved = resolutionResult.getSingleTarget();
assertEquals(methodOnB, resolved.method);
assertFalse(resolutionResult.isValidVirtualTarget(appInfo.app().options));
DexEncodedMethod singleVirtualTarget =
@@ -132,7 +132,7 @@
@Test
public void lookupVirtualTargets() {
ResolutionResult resolutionResult = appInfo.resolveMethodOnInterface(methodOnB.holder, methodOnB);
- DexEncodedMethod resolved = resolutionResult.asSingleTarget();
+ DexEncodedMethod resolved = resolutionResult.getSingleTarget();
assertEquals(methodOnB, resolved.method);
assertFalse(resolutionResult.isValidVirtualTarget(appInfo.app().options));
}
diff --git a/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentTest.java b/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentTest.java
index 20c3cab..c17ed49 100644
--- a/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentTest.java
@@ -167,7 +167,7 @@
@Test
public void lookupSingleTarget() {
ResolutionResult resolutionResult = appInfo.resolveMethodOnClass(methodOnB.holder, methodOnB);
- DexEncodedMethod resolved = resolutionResult.asSingleTarget();
+ DexEncodedMethod resolved = resolutionResult.getSingleTarget();
assertEquals(methodOnA, resolved.method);
assertFalse(resolutionResult.isValidVirtualTarget(appInfo.app().options));
DexEncodedMethod singleVirtualTarget =