Handle MultiResolutionResult when tracing InvokeSuper
Bug: b/226170842
Change-Id: Icc474143cbbd4691c3f2bcdfbf2cc8ece089cfcd
diff --git a/src/main/java/com/android/tools/r8/tracereferences/Tracer.java b/src/main/java/com/android/tools/r8/tracereferences/Tracer.java
index 3a25350..af4717d 100644
--- a/src/main/java/com/android/tools/r8/tracereferences/Tracer.java
+++ b/src/main/java/com/android/tools/r8/tracereferences/Tracer.java
@@ -31,6 +31,7 @@
import com.android.tools.r8.graph.GraphLens.FieldLookupResult;
import com.android.tools.r8.graph.GraphLens.MethodLookupResult;
import com.android.tools.r8.graph.MethodResolutionResult;
+import com.android.tools.r8.graph.MethodResolutionResult.SingleResolutionResult;
import com.android.tools.r8.graph.ProgramField;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.UseRegistry;
@@ -51,6 +52,7 @@
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
+import java.util.function.Function;
import java.util.function.Predicate;
public class Tracer {
@@ -314,7 +316,9 @@
assert lookupResult.getType().isStatic();
DexMethod rewrittenMethod = lookupResult.getReference();
handleRewrittenMethodResolution(
- rewrittenMethod, appInfo().unsafeResolveMethodDueToDexFormat(rewrittenMethod));
+ rewrittenMethod,
+ appInfo().unsafeResolveMethodDueToDexFormat(rewrittenMethod),
+ SingleResolutionResult::getResolutionPair);
}
@Override
@@ -322,16 +326,10 @@
MethodLookupResult lookupResult = graphLens().lookupInvokeSuper(method, getContext());
assert lookupResult.getType().isSuper();
DexMethod rewrittenMethod = lookupResult.getReference();
- MethodResolutionResult resolutionResult =
- appInfo().unsafeResolveMethodDueToDexFormat(rewrittenMethod);
- if (resolutionResult.isFailedResolution()
- && resolutionResult.asFailedResolution().hasMethodsCausingError()) {
- handleRewrittenMethodResolution(rewrittenMethod, resolutionResult);
- return;
- }
- handleRewrittenMethodReference(
- rewrittenMethod,
- resolutionResult.lookupInvokeSuperTarget(getContext().getHolder(), appInfo()));
+ handleRewrittenMethodResolution(
+ method,
+ appInfo().unsafeResolveMethodDueToDexFormat(rewrittenMethod),
+ result -> result.lookupInvokeSuperTarget(getContext().getHolder(), appInfo()));
}
@Override
@@ -353,24 +351,29 @@
method,
lookupResult.getType().isInterface()
? appInfo().resolveMethodOnInterfaceHolder(method)
- : appInfo().resolveMethodOnClassHolder(method));
+ : appInfo().resolveMethodOnClassHolder(method),
+ SingleResolutionResult::getResolutionPair);
}
private void handleRewrittenMethodResolution(
- DexMethod method, MethodResolutionResult resolutionResult) {
+ DexMethod method,
+ MethodResolutionResult resolutionResult,
+ Function<SingleResolutionResult<?>, DexClassAndMethod> getResult) {
resolutionResult.forEachMethodResolutionResult(
result -> {
- if (result.isFailedResolution()
- && result.asFailedResolution().hasTypesOrMethodsCausingError()) {
+ if (result.isFailedResolution()) {
result
.asFailedResolution()
.forEachFailureDependency(
type -> addType(type, referencedFrom),
methodCausingFailure ->
handleRewrittenMethodReference(method, methodCausingFailure));
+ if (!result.asFailedResolution().hasTypesOrMethodsCausingError()) {
+ handleRewrittenMethodReference(method, (DexEncodedMethod) null);
+ }
return;
}
- handleRewrittenMethodReference(method, result.getResolutionPair());
+ handleRewrittenMethodReference(method, getResult.apply(result.asSingleResolution()));
});
}
diff --git a/src/test/java/com/android/tools/r8/tracereferences/TraceSuperMethodResolutionWithLibraryAndProgramClassTest.java b/src/test/java/com/android/tools/r8/tracereferences/TraceSuperMethodResolutionWithLibraryAndProgramClassTest.java
index d232833..fbfe603 100644
--- a/src/test/java/com/android/tools/r8/tracereferences/TraceSuperMethodResolutionWithLibraryAndProgramClassTest.java
+++ b/src/test/java/com/android/tools/r8/tracereferences/TraceSuperMethodResolutionWithLibraryAndProgramClassTest.java
@@ -4,20 +4,20 @@
package com.android.tools.r8.tracereferences;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.StringContains.containsString;
-import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertEquals;
-import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.references.MethodReference;
+import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.ZipUtils.ZipBuilder;
+import com.google.common.collect.ImmutableSet;
import java.nio.file.Path;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.junit.Test;
@@ -82,24 +82,21 @@
InternalOptions internalOptions = new InternalOptions();
internalOptions.loadAllClassDefinitions = true;
// TODO(b/231928368): Remove this when enabled by default.
- CompilationFailedException compilationFailedException =
- assertThrows(
- CompilationFailedException.class,
- () ->
- TraceReferences.runForTesting(
- TraceReferencesCommand.builder()
- .addLibraryFiles(ToolHelper.getMostRecentAndroidJar())
- .addLibraryFiles(libJar)
- .addTargetFiles(targetJar)
- .addSourceFiles(sourceJar)
- .setConsumer(consumer)
- .build(),
- internalOptions));
- Throwable cause = compilationFailedException.getCause();
- // TODO(b/226170842): Handle InvokeSuper.
- assertThat(
- cause.getMessage(),
- containsString("Should not be called on MultipleFieldResolutionResult"));
+ TraceReferences.runForTesting(
+ TraceReferencesCommand.builder()
+ .addLibraryFiles(ToolHelper.getMostRecentAndroidJar())
+ .addLibraryFiles(libJar)
+ .addTargetFiles(targetJar)
+ .addSourceFiles(sourceJar)
+ .setConsumer(consumer)
+ .build(),
+ internalOptions);
+ ImmutableSet<MethodReference> foundSet =
+ ImmutableSet.of(
+ Reference.methodFromMethod(A.class.getMethod("foo")),
+ Reference.methodFromMethod(A.class.getConstructor()));
+ assertEquals(foundSet, consumer.seenMethods);
+ assertEquals(Collections.emptySet(), consumer.seenMissingMethods);
}
// A is added to both library and program.