Move jdk 11 nest test to jdk 11 test folder
- Merge FullNestOnProgramPath and MinimumNumberOfBridgesTest
Bug: b/344503104
Change-Id: Ibb433e37c25cfa9200d577ccd008ac2be92b6ef4
diff --git a/d8_r8/test_modules/tests_java_11/build.gradle.kts b/d8_r8/test_modules/tests_java_11/build.gradle.kts
index d8f620f..3c99b88 100644
--- a/d8_r8/test_modules/tests_java_11/build.gradle.kts
+++ b/d8_r8/test_modules/tests_java_11/build.gradle.kts
@@ -21,7 +21,15 @@
targetCompatibility = JavaVersion.VERSION_11
}
-dependencies { }
+val testbaseJavaCompileTask = projectTask("testbase", "compileJava")
+val testbaseDepsJarTask = projectTask("testbase", "depsJar")
+val mainCompileTask = projectTask("main", "compileJava")
+
+dependencies {
+ implementation(files(testbaseDepsJarTask.outputs.files.getSingleFile()))
+ implementation(testbaseJavaCompileTask.outputs.files)
+ implementation(mainCompileTask.outputs.files)
+}
// We just need to register the examples jars for it to be referenced by other modules.
val buildExampleJars = buildExampleJars("examplesJava11")
@@ -33,5 +41,19 @@
options.forkOptions.memoryMaximumSize = "3g"
options.forkOptions.executable = getCompilerPath(Jdk.JDK_11)
}
+
+ withType<Test> {
+ notCompatibleWithConfigurationCache(
+ "Failure storing the configuration cache: cannot serialize object of type 'org.gradle.api.internal.project.DefaultProject', a subtype of 'org.gradle.api.Project', as these are not supported with the configuration cache")
+ TestingState.setUpTestingState(this)
+ javaLauncher = getJavaLauncher(Jdk.JDK_11)
+ systemProperty("TEST_DATA_LOCATION",
+ // This should be
+ // layout.buildDirectory.dir("classes/java/test").get().toString()
+ // once the use of 'buildExampleJars' above is removed.
+ getRoot().resolveAll("build", "test", "examplesJava11", "classes"))
+ systemProperty("TESTBASE_DATA_LOCATION",
+ testbaseJavaCompileTask.outputs.files.getAsPath().split(File.pathSeparator)[0])
+ }
}
diff --git a/d8_r8/test_modules/tests_java_11/settings.gradle.kts b/d8_r8/test_modules/tests_java_11/settings.gradle.kts
index 98af16e..e0c1ff3 100644
--- a/d8_r8/test_modules/tests_java_11/settings.gradle.kts
+++ b/d8_r8/test_modules/tests_java_11/settings.gradle.kts
@@ -23,4 +23,7 @@
rootProject.name = "tests_java_11"
val root = rootProject.projectDir.parentFile.parentFile
+
includeBuild(root.resolve("shared"))
+includeBuild(root.resolve("main"))
+includeBuild(root.resolve("test_modules").resolve("testbase"))
diff --git a/src/test/examplesJava11/nesthostexample/BasicNestHostWithAnonymousInnerClass.java b/src/test/examplesJava11/nesthostexample/BasicNestHostWithAnonymousInnerClass.java
index f014507..93ad558 100644
--- a/src/test/examplesJava11/nesthostexample/BasicNestHostWithAnonymousInnerClass.java
+++ b/src/test/examplesJava11/nesthostexample/BasicNestHostWithAnonymousInnerClass.java
@@ -4,6 +4,8 @@
package nesthostexample;
+import java.util.List;
+
public class BasicNestHostWithAnonymousInnerClass {
private String method() {
@@ -40,4 +42,8 @@
BasicNestHostWithAnonymousInnerClass.createAnonymousNestedInstance();
System.out.println(anonymousInner.accessOuter(outer));
}
+
+ public static List<String> getExpectedResult() {
+ return List.of("fieldstaticFieldstaticFieldhostMethodstaticHostMethodstaticHostMethod");
+ }
}
diff --git a/src/test/examplesJava11/nesthostexample/BasicNestHostWithInnerClassConstructors.java b/src/test/examplesJava11/nesthostexample/BasicNestHostWithInnerClassConstructors.java
index 1326c8f..80fe3fe 100644
--- a/src/test/examplesJava11/nesthostexample/BasicNestHostWithInnerClassConstructors.java
+++ b/src/test/examplesJava11/nesthostexample/BasicNestHostWithInnerClassConstructors.java
@@ -4,6 +4,8 @@
package nesthostexample;
+import java.util.List;
+
public class BasicNestHostWithInnerClassConstructors {
public String field;
@@ -59,4 +61,8 @@
System.out.println(unusedParamConstructor.field);
System.out.println(uninstantiatedParamConstructor.field);
}
+
+ public static List<String> getExpectedResult() {
+ return List.of("field", "nest1SField", "1", "innerFieldUnusedConstructor", "nothing");
+ }
}
diff --git a/src/test/examplesJava11/nesthostexample/BasicNestHostWithInnerClassFields.java b/src/test/examplesJava11/nesthostexample/BasicNestHostWithInnerClassFields.java
index a174723..070d886 100644
--- a/src/test/examplesJava11/nesthostexample/BasicNestHostWithInnerClassFields.java
+++ b/src/test/examplesJava11/nesthostexample/BasicNestHostWithInnerClassFields.java
@@ -4,6 +4,8 @@
package nesthostexample;
+import java.util.List;
+
public class BasicNestHostWithInnerClassFields {
private String fieldWithoutBridge = "noBridge";
@@ -37,4 +39,9 @@
System.out.println(outer.accessNested(inner));
System.out.println(inner.accessOuter(outer));
}
+
+ public static List<String> getExpectedResult() {
+ return List.of(
+ "RWnestFieldRWRWnestFieldRWRWnestFieldnoBridge", "RWfieldRWRWfieldRWRWnestField");
+ }
}
diff --git a/src/test/examplesJava11/nesthostexample/BasicNestHostWithInnerClassMethods.java b/src/test/examplesJava11/nesthostexample/BasicNestHostWithInnerClassMethods.java
index e22088a..2766914 100644
--- a/src/test/examplesJava11/nesthostexample/BasicNestHostWithInnerClassMethods.java
+++ b/src/test/examplesJava11/nesthostexample/BasicNestHostWithInnerClassMethods.java
@@ -4,6 +4,8 @@
package nesthostexample;
+import java.util.List;
+
public class BasicNestHostWithInnerClassMethods {
private String methodWithoutBridge() {
@@ -45,4 +47,10 @@
System.out.println(outer.accessNested(inner));
System.out.println(inner.accessOuter(outer));
}
+
+ public static List<String> getExpectedResult() {
+ return List.of(
+ "nestMethodstaticNestMethodstaticNestMethodnoBridge",
+ "hostMethodstaticHostMethodstaticNestMethod");
+ }
}
diff --git a/src/test/examplesJava11/nesthostexample/FullNestOnProgramPathTest.java b/src/test/examplesJava11/nesthostexample/FullNestOnProgramPathTest.java
new file mode 100644
index 0000000..c36a73b
--- /dev/null
+++ b/src/test/examplesJava11/nesthostexample/FullNestOnProgramPathTest.java
@@ -0,0 +1,240 @@
+// 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 nesthostexample;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.D8TestCompileResult;
+import com.android.tools.r8.JdkClassFileProvider;
+import com.android.tools.r8.JvmTestBuilder;
+import com.android.tools.r8.R8TestCompileResult;
+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.graph.DexClass;
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.ir.desugar.nest.NestBasedAccessDesugaring;
+import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class FullNestOnProgramPathTest extends TestBase {
+
+ public static final ImmutableMap<Class<?>, String> NEST_MAIN_RESULT =
+ ImmutableMap.<Class<?>, String>builder()
+ .put(
+ BasicNestHostWithInnerClassFields.class,
+ StringUtils.lines(BasicNestHostWithInnerClassFields.getExpectedResult()))
+ .put(
+ BasicNestHostWithInnerClassMethods.class,
+ StringUtils.lines(BasicNestHostWithInnerClassMethods.getExpectedResult()))
+ .put(
+ BasicNestHostWithInnerClassConstructors.class,
+ StringUtils.lines(BasicNestHostWithInnerClassConstructors.getExpectedResult()))
+ .put(
+ BasicNestHostWithAnonymousInnerClass.class,
+ StringUtils.lines(BasicNestHostWithAnonymousInnerClass.getExpectedResult()))
+ .put(NestHostExample.class, StringUtils.lines(NestHostExample.getExpectedResult()))
+ .build();
+
+ public FullNestOnProgramPathTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ private final TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters()
+ .withCfRuntimesStartingFromIncluding(CfVm.JDK11)
+ .withDexRuntimes()
+ .withApiLevelsStartingAtIncluding(apiLevelWithInvokeCustomSupport())
+ .enableApiLevelsForCf()
+ .build();
+ }
+
+ @Test
+ public void testAllNestsReference() throws Exception {
+ parameters.assumeJvmTestParameters();
+ JvmTestBuilder jvmTestBuilder =
+ testForJvm(parameters).addProgramClassesAndInnerClasses(NEST_MAIN_RESULT.keySet());
+ for (Class<?> clazz : NEST_MAIN_RESULT.keySet()) {
+ jvmTestBuilder
+ .run(parameters.getRuntime(), clazz)
+ .assertSuccessWithOutput(NEST_MAIN_RESULT.get(clazz));
+ }
+ }
+
+ @Test
+ public void testAllNestsD8() throws Exception {
+ D8TestCompileResult compileResult =
+ testForD8(parameters.getBackend())
+ .addProgramClassesAndInnerClasses(NEST_MAIN_RESULT.keySet())
+ .setMinApi(parameters)
+ .compile()
+ .applyIf(parameters.isDexRuntime(), b -> b.inspect(this::assertOnlyRequiredBridges));
+ for (Class<?> clazz : NEST_MAIN_RESULT.keySet()) {
+ compileResult
+ .run(parameters.getRuntime(), clazz)
+ .assertSuccessWithOutput(NEST_MAIN_RESULT.get(clazz));
+ }
+ }
+
+ @Test
+ public void testAllNestsR8() throws Exception {
+ parameters.assumeR8TestParameters();
+ R8TestCompileResult compileResult =
+ testForR8(parameters.getBackend())
+ .noTreeShaking()
+ .addDontObfuscate()
+ .addKeepAllAttributes()
+ .addOptionsModification(options -> options.enableNestReduction = false)
+ .addProgramClassesAndInnerClasses(NEST_MAIN_RESULT.keySet())
+ .applyIf(
+ parameters.isCfRuntime(),
+ b -> b.addLibraryProvider(JdkClassFileProvider.fromSystemJdk()))
+ .setMinApi(parameters)
+ .compile()
+ .inspect(this::assertOnlyRequiredBridges)
+ .applyIf(
+ parameters.isCfRuntime(),
+ b -> b.inspect(FullNestOnProgramPathTest::checkNestMateAttributes));
+ for (Class<?> clazz : NEST_MAIN_RESULT.keySet()) {
+ compileResult
+ .run(parameters.getRuntime(), clazz)
+ .assertSuccessWithOutput(NEST_MAIN_RESULT.get(clazz));
+ }
+ }
+
+ // Single Nest test compile only the nest into dex,
+ // then run the main class from this dex.
+ @Test
+ public void testSingleNestR8() throws Exception {
+ parameters.assumeR8TestParameters();
+ for (Class<?> clazz : NEST_MAIN_RESULT.keySet()) {
+ testForR8(parameters.getBackend())
+ .noTreeShaking()
+ .addDontObfuscate()
+ .addKeepAllAttributes()
+ .setMinApi(parameters)
+ .addProgramClassesAndInnerClasses(clazz)
+ .addOptionsModification(options -> options.enableNestReduction = false)
+ .applyIf(
+ parameters.isCfRuntime(),
+ b -> b.addLibraryProvider(JdkClassFileProvider.fromSystemJdk()))
+ .compile()
+ .run(parameters.getRuntime(), clazz)
+ .assertSuccessWithOutput(NEST_MAIN_RESULT.get(clazz));
+ }
+ }
+
+ @Test
+ public void testSingleNestD8() throws Exception {
+ for (Class<?> clazz : NEST_MAIN_RESULT.keySet()) {
+ testForD8(parameters.getBackend())
+ .setMinApi(parameters)
+ .addProgramClassesAndInnerClasses(clazz)
+ .compile()
+ .run(parameters.getRuntime(), clazz)
+ .assertSuccessWithOutput(NEST_MAIN_RESULT.get(clazz));
+ }
+ }
+
+ private static int minNumberOfTestClasses() {
+ return NEST_MAIN_RESULT.keySet().stream()
+ .mapToInt(
+ c -> {
+ try {
+ return ToolHelper.getClassFilesForInnerClasses(c).size() + 1;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ })
+ .sum();
+ }
+
+ private static void checkNestMateAttributes(CodeInspector inspector) {
+ // Interface method desugaring may add extra classes
+ assertTrue(minNumberOfTestClasses() <= inspector.allClasses().size());
+ List<String> outerClassNames =
+ NEST_MAIN_RESULT.keySet().stream().map(Class::getSimpleName).collect(Collectors.toList());
+ ImmutableList<String> nonNestClasses =
+ ImmutableList.of("NeverInline", "OutsideInliningNoAccess", "OutsideInliningWithAccess");
+ inspector.forAllClasses(
+ classSubject -> {
+ DexClass dexClass = classSubject.getDexProgramClass();
+ if (!nonNestClasses.contains(dexClass.type.getName())) {
+ assertTrue(dexClass.isInANest());
+ if (outerClassNames.contains(dexClass.type.getName())) {
+ assertNull(dexClass.getNestHostClassAttribute());
+ assertFalse(dexClass.getNestMembersClassAttributes().isEmpty());
+ } else {
+ assertTrue(dexClass.getNestMembersClassAttributes().isEmpty());
+ assertTrue(
+ outerClassNames.contains(
+ dexClass.getNestHostClassAttribute().getNestHost().getName()));
+ }
+ }
+ });
+ }
+
+ private void assertOnlyRequiredBridges(CodeInspector inspector) {
+ // The following 2 classes have an extra private member which does not require a bridge.
+
+ // Two bridges for method and staticMethod.
+ int methodNumBridges = parameters.isCfRuntime() ? 0 : 2;
+ ClassSubject methodMainClass = inspector.clazz(BasicNestHostWithInnerClassMethods.class);
+ assertEquals(methodNumBridges, methodMainClass.allMethods(this::isNestBridge).size());
+
+ // Two bridges for method and staticMethod.
+ int constructorNumBridges = parameters.isCfRuntime() ? 0 : 1;
+ ClassSubject constructorMainClass =
+ inspector.clazz(BasicNestHostWithInnerClassConstructors.class);
+ assertEquals(constructorNumBridges, constructorMainClass.allMethods(this::isNestBridge).size());
+
+ // Four bridges for field and staticField, both get & set.
+ int fieldNumBridges = parameters.isCfRuntime() ? 0 : 4;
+ ClassSubject fieldMainClass = inspector.clazz(BasicNestHostWithInnerClassFields.class);
+ assertEquals(fieldNumBridges, fieldMainClass.allMethods(this::isNestBridge).size());
+ }
+
+ private boolean isNestBridge(FoundMethodSubject methodSubject) {
+ DexEncodedMethod method = methodSubject.getMethod();
+ if (method.isInstanceInitializer()) {
+ if (method.getReference().proto.parameters.isEmpty()) {
+ return false;
+ }
+ DexType[] formals = method.getReference().proto.parameters.values;
+ DexType lastFormal = formals[formals.length - 1];
+ return lastFormal.isClassType()
+ && SyntheticItemsTestUtils.isInitializerTypeArgument(
+ Reference.classFromDescriptor(lastFormal.toDescriptorString()));
+ }
+ return method
+ .getReference()
+ .name
+ .toString()
+ .startsWith(NestBasedAccessDesugaring.NEST_ACCESS_NAME_PREFIX);
+ }
+}
diff --git a/src/test/examplesJava11/nesthostexample/NestHostExample.java b/src/test/examplesJava11/nesthostexample/NestHostExample.java
index ee5c2ce..b892be3 100644
--- a/src/test/examplesJava11/nesthostexample/NestHostExample.java
+++ b/src/test/examplesJava11/nesthostexample/NestHostExample.java
@@ -4,8 +4,8 @@
package nesthostexample;
+import java.util.List;
-// Warning: This requires Java 9+ to be compiled (private interface methods)
// This file builds all the possible combinations of private members:
// - static VS non-static
// - fields VS methods
@@ -17,6 +17,34 @@
@SuppressWarnings("WeakerAccess")
public class NestHostExample {
+ public static final String ALL_RESULT_LINE =
+ String.join(
+ ", ",
+ new String[] {
+ "field",
+ "staticField",
+ "staticField",
+ "hostMethod",
+ "staticHostMethod",
+ "staticHostMethod",
+ "nest1SField",
+ "staticNest1SField",
+ "staticNest1SField",
+ "nest1SMethod",
+ "staticNest1SMethod",
+ "staticNest1SMethod",
+ "nest2SField",
+ "staticNest2SField",
+ "staticNest2SField",
+ "nest2SMethod",
+ "staticNest2SMethod",
+ "staticNest2SMethod",
+ "nest1Field",
+ "nest1Method",
+ "nest2Field",
+ "nest2Method"
+ });
+
private String method() {
return "hostMethod";
}
@@ -321,4 +349,17 @@
System.out.println(ExampleEnumCompilation.values().length);
}
+
+ public static List<String> getExpectedResult() {
+ return List.of(
+ ALL_RESULT_LINE,
+ ALL_RESULT_LINE,
+ ALL_RESULT_LINE,
+ ALL_RESULT_LINE,
+ "staticInterfaceMethodstaticStaticInterfaceMethod",
+ "staticInterfaceMethodstaticStaticInterfaceMethod",
+ "staticInterfaceMethodstaticStaticInterfaceMethod",
+ "staticInterfaceMethodstaticStaticInterfaceMethod",
+ "3");
+ }
}
diff --git a/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/FullNestOnProgramPathTest.java b/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/FullNestOnProgramPathTest.java
deleted file mode 100644
index f90b2cf..0000000
--- a/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/FullNestOnProgramPathTest.java
+++ /dev/null
@@ -1,186 +0,0 @@
-// 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.desugar.nestaccesscontrol.NestAccessControlTestUtils.JAR;
-import static com.android.tools.r8.desugar.nestaccesscontrol.NestAccessControlTestUtils.MAIN_CLASSES;
-import static com.android.tools.r8.desugar.nestaccesscontrol.NestAccessControlTestUtils.NEST_IDS;
-import static com.android.tools.r8.desugar.nestaccesscontrol.NestAccessControlTestUtils.NUMBER_OF_TEST_CLASSES;
-import static com.android.tools.r8.desugar.nestaccesscontrol.NestAccessControlTestUtils.classesOfNest;
-import static com.android.tools.r8.desugar.nestaccesscontrol.NestAccessControlTestUtils.getExpectedResult;
-import static com.android.tools.r8.desugar.nestaccesscontrol.NestAccessControlTestUtils.getMainClass;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import com.android.tools.r8.CompilationFailedException;
-import com.android.tools.r8.D8TestCompileResult;
-import com.android.tools.r8.Jdk9TestUtils;
-import com.android.tools.r8.R8FullTestBuilder;
-import com.android.tools.r8.R8TestCompileResult;
-import com.android.tools.r8.R8TestRunResult;
-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.ThrowableConsumer;
-import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.google.common.collect.ImmutableList;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class FullNestOnProgramPathTest extends TestBase {
-
- public FullNestOnProgramPathTest(TestParameters parameters) {
- this.parameters = parameters;
- }
-
- private final TestParameters parameters;
-
- @Parameters(name = "{0}")
- public static TestParametersCollection data() {
- return getTestParameters()
- .withCfRuntimesStartingFromIncluding(CfVm.JDK11)
- .withDexRuntimes()
- .withApiLevelsStartingAtIncluding(apiLevelWithInvokeCustomSupport())
- .enableApiLevelsForCf()
- .build();
- }
-
- public static Function<AndroidApiLevel, D8TestCompileResult> d8CompilationResult =
- memoizeFunction(FullNestOnProgramPathTest::compileAllNestsD8);
-
- public static BiFunction<Backend, AndroidApiLevel, R8TestCompileResult> r8CompilationResult =
- memoizeBiFunction(FullNestOnProgramPathTest::compileAllNestsR8);
-
- // All Nests tests compile all the nests into dex,
- // and run the main class from this dex
- @Test
- @Ignore("b/141075451")
- public void testAllNestsJavaAndD8() throws Exception {
- for (String nestID : NEST_IDS) {
- if (parameters.isCfRuntime()) {
- testForJvm(parameters)
- .addProgramFiles(JAR)
- .run(parameters.getRuntime(), getMainClass(nestID))
- .assertSuccessWithOutput(getExpectedResult(nestID));
- } else {
- assert parameters.isDexRuntime();
- d8CompilationResult
- .apply(parameters.getApiLevel())
- .run(parameters.getRuntime(), getMainClass(nestID))
- .assertSuccessWithOutput(getExpectedResult(nestID));
- }
- }
- }
-
- @Test
- @Ignore("b/141075451")
- public void testAllNestsR8() throws Exception {
- for (String nestID : NEST_IDS) {
- R8TestRunResult result =
- r8CompilationResult
- .apply(parameters.getBackend(), parameters.getApiLevel())
- .run(parameters.getRuntime(), getMainClass(nestID));
- result.assertSuccessWithOutput(getExpectedResult(nestID));
- if (parameters.isCfRuntime()) {
- result.inspect(FullNestOnProgramPathTest::checkNestMateAttributes);
- }
- }
- }
-
- // Single Nest test compile only the nest into dex,
- // then run the main class from this dex.
- @Test
- public void testSingleNestR8() throws Exception {
- parameters.assumeR8TestParameters();
- for (String nestID : NEST_IDS) {
- testForR8(parameters.getBackend())
- .noTreeShaking()
- .addDontObfuscate()
- .addKeepAllAttributes()
- .setMinApi(parameters)
- .addProgramFiles(classesOfNest(nestID))
- .addOptionsModification(options -> options.enableNestReduction = false)
- .applyIf(parameters.isCfRuntime(), Jdk9TestUtils.addJdk9LibraryFiles(temp))
- .compile()
- .run(parameters.getRuntime(), getMainClass(nestID))
- .assertSuccessWithOutput(getExpectedResult(nestID));
- }
- }
-
- @Test
- public void testSingleNestD8() throws Exception {
- for (String nestID : NEST_IDS) {
- testForD8(parameters.getBackend())
- .setMinApi(parameters)
- .addProgramFiles(classesOfNest(nestID))
- .compile()
- .run(parameters.getRuntime(), getMainClass(nestID))
- .assertSuccessWithOutput(getExpectedResult(nestID));
- }
- }
-
- private static D8TestCompileResult compileAllNestsD8(AndroidApiLevel minApi)
- throws CompilationFailedException {
- return testForD8(getStaticTemp())
- .addProgramFiles(JAR)
- .setMinApi(minApi)
- .compile();
- }
-
- static R8TestCompileResult compileAllNestsR8(Backend backend, AndroidApiLevel minApi)
- throws CompilationFailedException {
- return compileAllNestsR8(backend, minApi, null);
- }
-
- static R8TestCompileResult compileAllNestsR8(
- Backend backend, AndroidApiLevel minApi, ThrowableConsumer<R8FullTestBuilder> configuration)
- throws CompilationFailedException {
- return testForR8(getStaticTemp(), backend)
- .apply(configuration)
- .noTreeShaking()
- .addDontObfuscate()
- .addKeepAllAttributes()
- .addOptionsModification(options -> options.enableNestReduction = false)
- .addProgramFiles(JAR)
- .addInliningAnnotations()
- .addMemberValuePropagationAnnotations()
- .setMinApi(minApi)
- .compile();
- }
-
- private static void checkNestMateAttributes(CodeInspector inspector) {
- // Interface method desugaring may add extra classes
- assertTrue(NUMBER_OF_TEST_CLASSES <= inspector.allClasses().size());
- ImmutableList<String> outerClassNames = MAIN_CLASSES.values().asList();
- ImmutableList<String> nonNestClasses =
- ImmutableList.of("NeverInline", "OutsideInliningNoAccess", "OutsideInliningWithAccess");
- inspector.forAllClasses(
- classSubject -> {
- DexClass dexClass = classSubject.getDexProgramClass();
- if (!nonNestClasses.contains(dexClass.type.getName())) {
- assertTrue(dexClass.isInANest());
- if (outerClassNames.contains(dexClass.type.getName())) {
- assertNull(dexClass.getNestHostClassAttribute());
- assertFalse(dexClass.getNestMembersClassAttributes().isEmpty());
- } else {
- assertTrue(dexClass.getNestMembersClassAttributes().isEmpty());
- assertTrue(
- outerClassNames.contains(
- dexClass.getNestHostClassAttribute().getNestHost().getName()));
- }
- }
- });
- }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/MinimumNumberOfBridgesGenerated.java b/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/MinimumNumberOfBridgesGenerated.java
deleted file mode 100644
index ffaca18..0000000
--- a/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/MinimumNumberOfBridgesGenerated.java
+++ /dev/null
@@ -1,105 +0,0 @@
-// 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.desugar.nestaccesscontrol.NestAccessControlTestUtils.getMainClass;
-import static org.junit.Assert.assertEquals;
-
-import com.android.tools.r8.Jdk9TestUtils;
-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.DexVm;
-import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.desugar.nest.NestBasedAccessDesugaring;
-import com.android.tools.r8.references.Reference;
-import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class MinimumNumberOfBridgesGenerated extends TestBase {
-
- public MinimumNumberOfBridgesGenerated(TestParameters parameters) {
- this.parameters = parameters;
- }
-
- private final TestParameters parameters;
-
- @Parameters(name = "{0}")
- public static TestParametersCollection data() {
- return getTestParameters()
- .withCfRuntimesStartingFromIncluding(CfVm.JDK11)
- .withDexRuntime(DexVm.Version.first())
- .withDexRuntime(DexVm.Version.last())
- .withApiLevelsStartingAtIncluding(apiLevelWithInvokeCustomSupport())
- .enableApiLevelsForCf()
- .build();
- }
-
- @Test
- public void testOnlyRequiredBridges() throws Exception {
- if (parameters.isDexRuntime()) {
- FullNestOnProgramPathTest.d8CompilationResult
- .apply(parameters.getApiLevel())
- .inspect(this::assertOnlyRequiredBridges);
- }
- FullNestOnProgramPathTest.compileAllNestsR8(
- parameters.getBackend(),
- parameters.getApiLevel(),
- builder ->
- builder.applyIf(parameters.isCfRuntime(), Jdk9TestUtils.addJdk9LibraryFiles(temp)))
- .inspect(this::assertOnlyRequiredBridges);
- }
-
- private void assertOnlyRequiredBridges(CodeInspector inspector) {
- // The following 2 classes have an extra private member which does not require a bridge.
-
- // Two bridges for method and staticMethod.
- int methodNumBridges = parameters.isCfRuntime() ? 0 : 2;
- ClassSubject methodMainClass = inspector.clazz(getMainClass("methods"));
- assertEquals(
- methodNumBridges, methodMainClass.allMethods(this::isNestBridge).size());
-
- // Two bridges for method and staticMethod.
- int constructorNumBridges = parameters.isCfRuntime() ? 0 : 1;
- ClassSubject constructorMainClass = inspector.clazz(getMainClass("constructors"));
- assertEquals(
- constructorNumBridges,
- constructorMainClass.allMethods(this::isNestBridge).size());
-
- // Four bridges for field and staticField, both get & set.
- int fieldNumBridges = parameters.isCfRuntime() ? 0 : 4;
- ClassSubject fieldMainClass = inspector.clazz(getMainClass("fields"));
- assertEquals(
- fieldNumBridges, fieldMainClass.allMethods(this::isNestBridge).size());
- }
-
- private boolean isNestBridge(FoundMethodSubject methodSubject) {
- DexEncodedMethod method = methodSubject.getMethod();
- if (method.isInstanceInitializer()) {
- if (method.getReference().proto.parameters.isEmpty()) {
- return false;
- }
- DexType[] formals = method.getReference().proto.parameters.values;
- DexType lastFormal = formals[formals.length - 1];
- return lastFormal.isClassType()
- && SyntheticItemsTestUtils.isInitializerTypeArgument(
- Reference.classFromDescriptor(lastFormal.toDescriptorString()));
- }
- return method
- .getReference()
- .name
- .toString()
- .startsWith(NestBasedAccessDesugaring.NEST_ACCESS_NAME_PREFIX);
- }
-}