Nest Access Control application tests
- Add flag to force nest desugaring
- Compile Hello/R8 with production R8,
with R8 compiled with Java 11 (R811),
with R8 11 shrunk without desugaring,
with R8 11 shrunk with desugaring
and ensure all the outputs are identical.
Bug:133608609
Change-Id: I67d101a7c23f6504cb54b0509027db5d5998eaf1
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 5bd0cc2..af1d2e9 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -441,7 +441,8 @@
AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
appView.setGraphLense(new MemberRebindingAnalysis(appViewWithLiveness).run());
- if (options.enableNestBasedAccessDesugaring && !options.canUseNestBasedAccess()) {
+ if (options.testing.enableForceNestBasedAccessDesugaringForTest
+ || (options.enableNestBasedAccessDesugaring && !options.canUseNestBasedAccess())) {
timing.begin("NestBasedAccessDesugaring");
R8NestBasedAccessDesugaring analyzer = new R8NestBasedAccessDesugaring(appViewWithLiveness);
boolean changed =
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 cc92f99..e32efa4 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -818,6 +818,9 @@
// TODO(b/129458850) When fixed, remove this and change all usages to "true".
public boolean enableStatefulLambdaCreateInstanceMethod = false;
+ // Flag to turn on/off JDK11+ nest-access control even when not required (Cf backend)
+ public boolean enableForceNestBasedAccessDesugaringForTest = false;
+
public boolean desugarLambdasThroughLensCodeRewriter() {
return enableStatefulLambdaCreateInstanceMethod;
}
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 9fef6f1..448d698 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -128,6 +128,8 @@
public static final Path R8_JAR = Paths.get(LIBS_DIR, "r8.jar");
public static final Path R8_WITH_RELOCATED_DEPS_JAR =
Paths.get(LIBS_DIR, "r8_with_relocated_deps.jar");
+ public static final Path R8_WITH_RELOCATED_DEPS_JAR_11 =
+ Paths.get(LIBS_DIR, "r8_with_relocated_deps_11.jar");
public static final Path R8LIB_JAR = Paths.get(LIBS_DIR, "r8lib.jar");
public static final Path R8LIB_EXCLUDE_DEPS_JAR = Paths.get(LIBS_DIR, "r8lib-exclude-deps.jar");
public static final Path DEPS_NOT_RELOCATED = Paths.get(LIBS_DIR, "deps-not-relocated.jar");
diff --git a/src/test/java/com/android/tools/r8/cf/BootstrapCurrentEqualityTest.java b/src/test/java/com/android/tools/r8/cf/BootstrapCurrentEqualityTest.java
index 7503774..a30d0bd 100644
--- a/src/test/java/com/android/tools/r8/cf/BootstrapCurrentEqualityTest.java
+++ b/src/test/java/com/android/tools/r8/cf/BootstrapCurrentEqualityTest.java
@@ -27,7 +27,6 @@
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.junit.BeforeClass;
@@ -195,7 +194,7 @@
assertProgramsEqual(result.outputJar(), runR8R8.outputJar());
}
- private static void assertProgramsEqual(Path expectedJar, Path actualJar) throws Exception {
+ public static void assertProgramsEqual(Path expectedJar, Path actualJar) throws Exception {
if (filesAreEqual(expectedJar, actualJar)) {
return;
}
diff --git a/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/Java11BootstrapTest.java b/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/Java11BootstrapTest.java
new file mode 100644
index 0000000..8af6abf
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/Java11BootstrapTest.java
@@ -0,0 +1,138 @@
+// 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.nestaccesscontrol;
+
+import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertTrue;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.cf.BootstrapCurrentEqualityTest;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.google.common.collect.ImmutableList;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * This test relies on a freshly built build/libs/r8_with_relocated_deps_11.jar.
+ *
+ * <p>The test compiles Hello/R8 with the same settings using R8 compiled with Java 11 (non shrunk),
+ * and the same but shrunk with/without nest desugaring. All generated jars should be run correctly
+ * and identical.
+ */
+@RunWith(Parameterized.class)
+public class Java11BootstrapTest extends TestBase {
+
+ private static final Path MAIN_KEEP = Paths.get("src/main/keep.txt");
+ private static final String[] HELLO_KEEP = {
+ "-keep class hello.Hello { public static void main(...);}"
+ };
+
+ private static Path r8Lib11NoDesugar;
+ private static Path r8Lib11Desugar;
+
+ public Java11BootstrapTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ private final TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withCfRuntime(CfVm.JDK11).build();
+ }
+
+ @BeforeClass
+ public static void beforeAll() throws Exception {
+ r8Lib11NoDesugar = compileR8(false);
+ r8Lib11Desugar = compileR8(true);
+ }
+
+ private static Path compileR8(boolean desugar) throws Exception {
+ // Shrink R8 11 with R8 11
+ return testForExternalR8(TestBase.getStaticTemp(), Backend.CF)
+ .useProvidedR8(ToolHelper.R8_WITH_RELOCATED_DEPS_JAR_11)
+ .addProgramFiles(ToolHelper.R8_WITH_RELOCATED_DEPS_JAR_11)
+ .addKeepRuleFiles(MAIN_KEEP)
+ .addOptionsModification(
+ options -> options.testing.enableForceNestBasedAccessDesugaringForTest = desugar)
+ .compile()
+ .inspect(inspector -> assertNests(inspector, desugar))
+ .outputJar();
+ }
+
+ private static void assertNests(CodeInspector inspector, boolean desugar) {
+ if (desugar) {
+ assertTrue(inspector.allClasses().stream().noneMatch(subj -> subj.getDexClass().isInANest()));
+ } else {
+ assertTrue(inspector.allClasses().stream().anyMatch(subj -> subj.getDexClass().isInANest()));
+ }
+ }
+
+ private Path[] jarsToCompare() {
+ return new Path[] {
+ ToolHelper.R8_WITH_RELOCATED_DEPS_JAR,
+ ToolHelper.R8_WITH_RELOCATED_DEPS_JAR_11,
+ r8Lib11NoDesugar,
+ r8Lib11Desugar
+ };
+ }
+
+ @Test
+ public void testHello() throws Exception {
+ Path prevGeneratedJar = null;
+ String prevRunResult = null;
+ for (Path jar : jarsToCompare()) {
+ Path generatedJar =
+ testForExternalR8(Backend.CF)
+ .useProvidedR8(jar)
+ .addProgramFiles(Paths.get(ToolHelper.EXAMPLES_BUILD_DIR, "hello" + JAR_EXTENSION))
+ .addKeepRules(HELLO_KEEP)
+ .compile()
+ .outputJar();
+ String runResult =
+ ToolHelper.runJava(
+ parameters.getRuntime().asCf().getVm(),
+ ImmutableList.of(generatedJar),
+ "hello.Hello")
+ .toString();
+ if (prevRunResult != null) {
+ assertEquals(prevRunResult, runResult);
+ }
+ prevRunResult = runResult;
+ if (prevGeneratedJar != null) {
+ BootstrapCurrentEqualityTest.assertProgramsEqual(prevGeneratedJar, generatedJar);
+ }
+ prevGeneratedJar = generatedJar;
+ }
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ Path prevGeneratedJar = null;
+ for (Path jar : jarsToCompare()) {
+ Path generatedJar =
+ testForExternalR8(Backend.CF)
+ .useProvidedR8(jar)
+ .addProgramFiles(Paths.get(ToolHelper.EXAMPLES_BUILD_DIR, "hello" + JAR_EXTENSION))
+ .addKeepRules(HELLO_KEEP)
+ .compile()
+ .outputJar();
+ if (prevGeneratedJar != null) {
+ BootstrapCurrentEqualityTest.assertProgramsEqual(prevGeneratedJar, generatedJar);
+ }
+ prevGeneratedJar = generatedJar;
+ }
+ }
+}
diff --git a/tools/test.py b/tools/test.py
index 015e53e..be271f2 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -212,6 +212,7 @@
# Build an R8 with dependencies for bootstrapping tests before adding test sources.
gradle_args.append('r8WithRelocatedDeps')
+ gradle_args.append('r8WithRelocatedDeps11')
# Add Gradle tasks
gradle_args.append('cleanTest')