Reproduce wrong LambdaMethodAnnotations
When D8 decides to rename lambda methods for access the renames and not
the original method is reported for the lambda.
Bug: b/417709154
Change-Id: I9050a55701b55ef6a285c11a902ef46443673193
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
index 4f16005..ab3652f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -386,6 +386,9 @@
}
private boolean doesNotNeedAccessor(ProgramMethod accessedFrom) {
+ if (appView.testing().forceLambdaAccessorInD8) {
+ return false;
+ }
return canAccessModifyLambdaImplMethod()
|| isPrivateOrStaticInterfaceMethodInvokeThatWillBeDesugared()
|| !descriptor.needsAccessor(accessedFrom);
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 8ce35a4..cdc3d45 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -2493,6 +2493,8 @@
// Used by unit tests.
public boolean listIterationRewritingRewriteCustomIterators =
listIterationRewritingRewriteInterfaces;
+ // Testing flag to always generate D8 lambda accessors.
+ public boolean forceLambdaAccessorInD8 = false;
}
public MapVersion getMapFileVersion() {
diff --git a/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaCallTargetAnnotationTest.java b/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaCallTargetAnnotationTest.java
index 6dac5dd..6c6aa65 100644
--- a/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaCallTargetAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaCallTargetAnnotationTest.java
@@ -32,17 +32,37 @@
@Parameter(1)
public boolean intermediate;
- @Parameterized.Parameters(name = "{0}, intermediate = {1}")
+ @Parameter(2)
+ public boolean forceLambdaAccessor;
+
+ @Parameterized.Parameters(name = "{0}, intermediate = {1}, forceLambdaAccessor = {2}")
public static List<Object[]> data() {
- return buildParameters(getTestParameters().withNoneRuntime().build(), BooleanUtils.values());
+ return buildParameters(
+ getTestParameters().withNoneRuntime().build(),
+ BooleanUtils.values(),
+ BooleanUtils.values());
}
- private static void checkAnnotationField(
+ private void checkAnnotationField(
DexEncodedAnnotation encodedAnnotation, int index, String name, String value) {
assertEquals(name, encodedAnnotation.getElement(index).getName().toString());
- DexValue holderElementValue = encodedAnnotation.getElement(index).getValue();
- assertTrue(holderElementValue.isDexValueString());
- assertEquals(value, holderElementValue.asDexValueString().getValue().toString());
+ DexValue elementValue = encodedAnnotation.getElement(index).getValue();
+ assertTrue(elementValue.isDexValueString());
+ if (!forceLambdaAccessor) {
+ assertEquals(value, elementValue.asDexValueString().getValue().toString());
+ } else {
+ // Only check method names for reproduction of wrong annotation values.
+ if (!name.equals("method")) {
+ return;
+ }
+ if (value.equals("methodReturningJ")
+ || value.equals("methodReturningI")
+ || value.equals("<init>")) {
+ assertTrue(elementValue.asDexValueString().getValue().toString().startsWith("$r8$lambda"));
+ } else {
+ assertEquals(value, elementValue.asDexValueString().getValue().toString());
+ }
+ }
}
private void checkAnnotation(
@@ -68,6 +88,8 @@
.setIntermediate(intermediate)
.addOptionsModification(options -> options.emitLambdaMethodAnnotations = true)
.applyIf(intermediate, b -> b.getBuilder().setGlobalSyntheticsConsumer(globals))
+ .addOptionsModification(
+ options -> options.testing.forceLambdaAccessorInD8 = forceLambdaAccessor)
.compile()
.inspect(
inspector -> {