Add test for rewriting of enclosing-method attr in desugarded interface.
Bug: 70293332
Change-Id: I57c3f1751dd1e07c43825eb1c4295ff7360911d7
diff --git a/src/test/java/com/android/tools/r8/desugar/enclosingmethod/EnclosingMethodRewriteTest.java b/src/test/java/com/android/tools/r8/desugar/enclosingmethod/EnclosingMethodRewriteTest.java
new file mode 100644
index 0000000..897f4a7
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/enclosingmethod/EnclosingMethodRewriteTest.java
@@ -0,0 +1,139 @@
+// Copyright (c) 2019, 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.desugar.enclosingmethod;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assume.assumeTrue;
+
+import com.android.tools.r8.ClassFileConsumer.ArchiveConsumer;
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.R8FullTestBuilder;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper.DexVm;
+import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.StringUtils;
+import java.nio.file.Path;
+import java.util.Collection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+interface A {
+ default int def() {
+ return new C() {
+ @Override
+ int number() {
+ Class<?> clazz = getClass();
+ System.out.println(clazz.getEnclosingClass());
+ System.out.println(clazz.getEnclosingMethod());
+ return 42;
+ }
+ }.getNumber();
+ }
+}
+
+abstract class C {
+ abstract int number();
+
+ public int getNumber() {
+ return number();
+ }
+}
+
+class TestClass implements A {
+ public static void main(String[] args) throws NoClassDefFoundError, ClassNotFoundException {
+ System.out.println(new TestClass().def());
+ }
+}
+
+@RunWith(Parameterized.class)
+public class EnclosingMethodRewriteTest extends TestBase {
+ private static final Class<?> MAIN = TestClass.class;
+ private static final String JAVA_OUTPUT = StringUtils.lines(
+ "interface " + A.class.getName(),
+ "public default int " + A.class.getName() + ".def()",
+ "42"
+ );
+
+ private final TestParameters parameters;
+ private final boolean enableMinification;
+
+ @Parameterized.Parameters(name = "{0} minification: {1}")
+ public static Collection<Object[]> data() {
+ return buildParameters(
+ getTestParameters().withAllRuntimes().withAllApiLevels().build(),
+ BooleanUtils.values());
+ }
+
+ public EnclosingMethodRewriteTest(TestParameters parameters, boolean enableMinification) {
+ this.parameters = parameters;
+ this.enableMinification = enableMinification;
+ }
+
+ @Test
+ public void testJVMOutput() throws Exception {
+ assumeTrue("Only run JVM reference on CF runtimes", parameters.isCfRuntime());
+ testForJvm()
+ .addTestClasspath()
+ .run(parameters.getRuntime(), MAIN)
+ .assertSuccessWithOutput(JAVA_OUTPUT);
+ }
+
+ @Test
+ public void testDesugarAndProguard() throws Exception {
+ assumeTrue("Only run on CF runtimes", parameters.isCfRuntime());
+ Path desugared = temp.newFile("desugared.jar").toPath().toAbsolutePath();
+ R8FullTestBuilder builder =
+ testForR8(parameters.getBackend())
+ .addProgramClasses(A.class, C.class, MAIN)
+ .addKeepMainRule(MAIN)
+ .addKeepRules("-keepattributes InnerClasses,EnclosingMethod")
+ .setProgramConsumer(new ArchiveConsumer(desugared))
+ .setMinApi(parameters.getApiLevel());
+ if (enableMinification) {
+ builder.addKeepAllClassesRuleWithAllowObfuscation();
+ } else {
+ builder.addKeepAllClassesRule();
+ }
+ builder.compile().assertNoMessages();
+ try {
+ testForProguard()
+ .addProgramFiles(desugared)
+ .addKeepMainRule(MAIN)
+ .addKeepRules("-keepattributes InnerClasses,EnclosingMethod")
+ .run(parameters.getRuntime(), MAIN)
+ .assertSuccessWithOutput(JAVA_OUTPUT);
+ } catch (CompilationFailedException e) {
+ // TODO(b/70293332)
+ assertThat(e.getMessage(), containsString("unresolved references"));
+ assertThat(e.getMessage(), containsString(A.class.getName() + "$1"));
+ }
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ R8FullTestBuilder builder =
+ testForR8(parameters.getBackend())
+ .addProgramClasses(A.class, C.class, MAIN)
+ .addKeepMainRule(MAIN)
+ .addKeepRules("-keepattributes InnerClasses,EnclosingMethod")
+ .setMinApi(parameters.getApiLevel());
+ if (enableMinification) {
+ builder.addKeepAllClassesRuleWithAllowObfuscation();
+ } else {
+ builder.addKeepAllClassesRule();
+ }
+ String errorType = "ClassNotFoundException";
+ if (parameters.isDexRuntime()
+ && parameters.getRuntime().asDex().getVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
+ errorType = "NoClassDefFoundError";
+ }
+ builder
+ .run(parameters.getRuntime(), MAIN)
+ // TODO(b/70293332)
+ .assertFailureWithErrorThatMatches(containsString(errorType));
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/shaking/EnclosingMethodTest.java b/src/test/java/com/android/tools/r8/shaking/EnclosingMethodTest.java
index 6b4c8fd..1ea65da 100644
--- a/src/test/java/com/android/tools/r8/shaking/EnclosingMethodTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/EnclosingMethodTest.java
@@ -6,6 +6,7 @@
import static org.junit.Assume.assumeTrue;
import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.InternalOptions;
@@ -41,7 +42,7 @@
@RunWith(Parameterized.class)
public class EnclosingMethodTest extends TestBase {
- private final Backend backend;
+ private final TestParameters parameters;
private final boolean enableMinification;
private Collection<Path> classPaths;
private static final String JAVA_OUTPUT = "-Returned-null-" + System.lineSeparator();
@@ -49,13 +50,14 @@
"com.android.tools.r8.shaking.GetNameClass$1" + System.lineSeparator();
private static final Class<?> MAIN = GetNameMain.class;
- @Parameterized.Parameters(name = "Backend: {0} minification: {1}")
+ @Parameterized.Parameters(name = "{0} minification: {1}")
public static Collection<Object[]> data() {
- return buildParameters(ToolHelper.getBackends(), BooleanUtils.values());
+ return buildParameters(getTestParameters().withAllRuntimes().build(), BooleanUtils.values());
}
- public EnclosingMethodTest(Backend backend, boolean enableMinification) throws Exception {
- this.backend = backend;
+ public EnclosingMethodTest(TestParameters parameters, boolean enableMinification)
+ throws Exception {
+ this.parameters = parameters;
this.enableMinification = enableMinification;
ImmutableList.Builder<Path> builder = ImmutableList.builder();
@@ -71,14 +73,17 @@
}
@Test
- public void testJVMoutput() throws Exception {
- assumeTrue("Only run JVM reference once (for CF backend)", backend == Backend.CF);
- testForJvm().addTestClasspath().run(MAIN).assertSuccessWithOutput(JAVA_OUTPUT);
+ public void testJVMOutput() throws Exception {
+ assumeTrue("Only run JVM reference on CF runtimes", parameters.isCfRuntime());
+ testForJvm()
+ .addTestClasspath()
+ .run(parameters.getRuntime(), MAIN)
+ .assertSuccessWithOutput(JAVA_OUTPUT);
}
@Test
public void testR8() throws Exception {
- testForR8(backend)
+ testForR8(parameters.getBackend())
.addProgramFiles(classPaths)
.enableInliningAnnotations()
.addOptionsModification(this::configure)
@@ -86,7 +91,8 @@
.addKeepRules("-keep class **.GetName*")
.addKeepRules("-keepattributes InnerClasses,EnclosingMethod")
.minification(enableMinification)
- .run(MAIN)
+ .setMinApi(parameters.getRuntime())
+ .run(parameters.getRuntime(), MAIN)
.assertSuccessWithOutput(OUTPUT_WITH_SHRUNK_ATTRIBUTES);
}
}