Desugared library tests for all API levels
- So far desugared library tests were run
on pre-N devices only, this CL introduce
the ability to run them on all API levels
with different levels of desugaring based
on the API levels.
- A few tests updated to use new
test APIs (Other tests will be updated in
subsequent CLs).
- Introduced 2 desugared library
configuration, pre-N and N-O, so
that Interface emulation is optional
Bug: 134732760
Change-Id: I8bd94fe80f8eafd4d2a210faaac8748c8b5bacfd
diff --git a/src/main/java/com/android/tools/r8/SpecialLibraryConfiguration.java b/src/main/java/com/android/tools/r8/SpecialLibraryConfiguration.java
index 6468d16..9ec6cde 100644
--- a/src/main/java/com/android/tools/r8/SpecialLibraryConfiguration.java
+++ b/src/main/java/com/android/tools/r8/SpecialLibraryConfiguration.java
@@ -4,7 +4,9 @@
package com.android.tools.r8;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.StringDiagnostic;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.List;
@@ -42,6 +44,16 @@
.build();
}
+ private static Map<String, String> buildPrefixRewritingForProgramCompilationAndroidNPlus() {
+ // From Android O, emulated interfaces are not supported and are not required.
+ // Prefix rewriting is different to avoid rewriting classes to j$ while they should not,
+ // else Android cannot find the library methods because they use the incorrect types.
+ return ImmutableMap.<String, String>builder()
+ .put("java.time.", "j$.time.")
+ .put("java.util.Desugar", "j$.util.Desugar")
+ .build();
+ }
+
private static Map<String, String> buildPrefixRewritingForCoreLibCompilation() {
return ImmutableMap.<String, String>builder()
// --rewrite_core_library_prefix.
@@ -75,6 +87,18 @@
.build();
}
+ private static Map<String, String>
+ buildRetargetCoreLibraryMemberForProgramCompilationAndroidNPlus() {
+ // --retarget_core_library_member.
+ return ImmutableMap.<String, String>builder()
+ .put("java.util.Calendar#toInstant", "java.util.DesugarCalendar")
+ .put("java.util.Date#from", "java.util.DesugarDate")
+ .put("java.util.Date#toInstant", "java.util.DesugarDate")
+ .put("java.util.GregorianCalendar#from", "java.util.DesugarGregorianCalendar")
+ .put("java.util.GregorianCalendar#toZonedDateTime", "java.util.DesugarGregorianCalendar")
+ .build();
+ }
+
private static Map<String, String> buildRetargetCoreLibraryMemberForProgramCompilation() {
// --retarget_core_library_member.
return ImmutableMap.<String, String>builder()
@@ -246,19 +270,38 @@
}
public static void configureLibraryDesugaringForProgramCompilation(InternalOptions options) {
+ // TODO(b/134732760): Make assertions in D8/R8 commands.
+ if (options.minApiLevel >= AndroidApiLevel.P.getLevel()) {
+ options.reporter.warning(
+ new StringDiagnostic(
+ "Desugaring core libraries for Android P and over is possible but not required."));
+ }
options.coreLibraryCompilation = false;
- options.retargetCoreLibMember = buildRetargetCoreLibraryMemberForProgramCompilation();
- options.dontRewriteInvocations = buildDontRewriteInvocations();
- options.rewritePrefix = buildPrefixRewritingForProgramCompilation();
- options.emulateLibraryInterface = buildEmulateLibraryInterface();
+ if (options.minApiLevel < AndroidApiLevel.N.getLevel()) {
+ options.rewritePrefix = buildPrefixRewritingForProgramCompilation();
+ options.retargetCoreLibMember = buildRetargetCoreLibraryMemberForProgramCompilation();
+ options.emulateLibraryInterface = buildEmulateLibraryInterface();
+ options.dontRewriteInvocations = buildDontRewriteInvocations();
+ } else {
+ options.rewritePrefix = buildPrefixRewritingForProgramCompilationAndroidNPlus();
+ options.retargetCoreLibMember =
+ buildRetargetCoreLibraryMemberForProgramCompilationAndroidNPlus();
+ }
}
public static void configureLibraryDesugaringForLibraryCompilation(InternalOptions options) {
+ // TODO(b/134732760): Make assertions in L8 commands.
+ if (options.minApiLevel >= AndroidApiLevel.P.getLevel()) {
+ options.reporter.warning(
+ new StringDiagnostic(
+ "Desugaring core libraries for Android P and over is possible but not required."));
+ }
options.coreLibraryCompilation = true;
options.backportCoreLibraryMembers = buildBackportCoreLibraryMembers();
options.retargetCoreLibMember = buildRetargetCoreLibraryMemberForCoreLibCompilation();
- options.dontRewriteInvocations = buildDontRewriteInvocations();
options.rewritePrefix = buildPrefixRewritingForCoreLibCompilation();
+ // The following is ignored starting from Android O.
+ options.dontRewriteInvocations = buildDontRewriteInvocations();
options.emulateLibraryInterface = buildEmulateLibraryInterface();
}
}
diff --git a/src/test/java/com/android/tools/r8/TestCompileResult.java b/src/test/java/com/android/tools/r8/TestCompileResult.java
index dfde83b..8b303ad 100644
--- a/src/test/java/com/android/tools/r8/TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/TestCompileResult.java
@@ -16,6 +16,7 @@
import com.android.tools.r8.debug.DebugTestConfig;
import com.android.tools.r8.debug.DexDebugTestConfig;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
@@ -31,6 +32,7 @@
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
+import java.util.function.Function;
import java.util.stream.Collectors;
import org.hamcrest.Matcher;
@@ -162,6 +164,14 @@
}
}
+ public CR addDesugaredCoreLibraryRunClassPath(
+ Function<AndroidApiLevel, Path> classPathSupplier, AndroidApiLevel minAPILevel) {
+ if (minAPILevel.getLevel() < AndroidApiLevel.P.getLevel()) {
+ addRunClasspathFiles(classPathSupplier.apply(minAPILevel));
+ }
+ return self();
+ }
+
public CR enableRuntimeAssertions() {
assert getBackend() == Backend.CF;
if (!this.vmArguments.contains("-ea")) {
diff --git a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
index 7b6c7d2..c418f28 100644
--- a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
@@ -266,8 +266,17 @@
return self();
}
+ @Deprecated
public T enableCoreLibraryDesugaring() {
- builder.addSpecialLibraryConfiguration("default");
+ // TODO(b/134732760): Use the other API instead.
+ return enableCoreLibraryDesugaring(AndroidApiLevel.B);
+ }
+
+ public T enableCoreLibraryDesugaring(AndroidApiLevel minAPILevel) {
+ if (minAPILevel.getLevel() < AndroidApiLevel.P.getLevel()) {
+ builder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P));
+ builder.addSpecialLibraryConfiguration("default");
+ }
return self();
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/CoreLibDesugarTestBase.java b/src/test/java/com/android/tools/r8/desugar/corelib/CoreLibDesugarTestBase.java
index 4375976..fc2e5df 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/CoreLibDesugarTestBase.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/CoreLibDesugarTestBase.java
@@ -20,25 +20,39 @@
public class CoreLibDesugarTestBase extends TestBase {
protected boolean requiresCoreLibDesugaring(TestParameters parameters) {
+ // TODO(b/134732760): Use the two other APIS instead.
+ return requiresEmulatedInterfaceCoreLibDesugaring(parameters)
+ && requiresRetargetCoreLibMemberDesugaring(parameters);
+ }
+
+ protected boolean requiresEmulatedInterfaceCoreLibDesugaring(TestParameters parameters) {
return parameters.getApiLevel().getLevel() < AndroidApiLevel.N.getLevel();
}
- protected Path buildDesugaredLibrary(AndroidApiLevel apiLevel, List<Path> additionalProgramFiles)
- throws Exception {
- Path output = temp.newFolder().toPath().resolve("desugar_jdk_libs.zip");
- L8.run(
- L8Command.builder()
- .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
- .addProgramFiles(ToolHelper.getDesugarJDKLibs())
- .addProgramFiles(additionalProgramFiles)
- .addSpecialLibraryConfiguration("default")
- .setMinApiLevel(apiLevel.getLevel())
- .setOutput(output, OutputMode.DexIndexed)
- .build());
- return output;
+ protected boolean requiresRetargetCoreLibMemberDesugaring(TestParameters parameters) {
+ return parameters.getApiLevel().getLevel() < AndroidApiLevel.P.getLevel();
}
- protected Path buildDesugaredLibrary(AndroidApiLevel apiLevel) throws Exception {
+ protected Path buildDesugaredLibrary(
+ AndroidApiLevel apiLevel, List<Path> additionalProgramFiles) {
+ try {
+ Path output = temp.newFolder().toPath().resolve("desugar_jdk_libs.zip");
+ L8.run(
+ L8Command.builder()
+ .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
+ .addProgramFiles(ToolHelper.getDesugarJDKLibs())
+ .addProgramFiles(additionalProgramFiles)
+ .addSpecialLibraryConfiguration("default")
+ .setMinApiLevel(apiLevel.getLevel())
+ .setOutput(output, OutputMode.DexIndexed)
+ .build());
+ return output;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected Path buildDesugaredLibrary(AndroidApiLevel apiLevel) {
return buildDesugaredLibrary(apiLevel, ImmutableList.of());
}
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/CustomCollectionTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/CustomCollectionTest.java
index ff96100..445b1dd 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/CustomCollectionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/CustomCollectionTest.java
@@ -10,8 +10,6 @@
import com.android.tools.r8.D8TestRunResult;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import com.android.tools.r8.utils.codeinspector.InstructionSubject.JumboStringMode;
@@ -21,7 +19,6 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.Assert;
-import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -45,19 +42,21 @@
@Test
public void testCustomCollection() throws Exception {
- Assume.assumeTrue("No desugaring for high API levels", requiresCoreLibDesugaring(parameters));
D8TestRunResult d8TestRunResult =
testForD8()
.addInnerClasses(CustomCollectionTest.class)
- .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
.setMinApi(parameters.getApiLevel())
- .enableCoreLibraryDesugaring()
+ .enableCoreLibraryDesugaring(parameters.getApiLevel())
.compile()
.inspect(this::assertCustomCollectionCallsCorrect)
- .addRunClasspathFiles(buildDesugaredLibrary(parameters.getApiLevel()))
+ .addDesugaredCoreLibraryRunClassPath(
+ this::buildDesugaredLibrary, parameters.getApiLevel())
.run(parameters.getRuntime(), EXECUTOR)
.assertSuccess();
- assertLines2By2Correct(d8TestRunResult.getStdOut());
+ if (requiresEmulatedInterfaceCoreLibDesugaring(parameters)) {
+ // Expected output is emulated interfaces expected output.
+ assertLines2By2Correct(d8TestRunResult.getStdOut());
+ }
String[] split = d8TestRunResult.getStdErr().split("Could not find method");
if (split.length > 2) {
fail("Could not find multiple methods");
@@ -72,6 +71,11 @@
Assert.assertFalse(
direct.streamInstructions().anyMatch(instr -> instr.toString().contains("$-EL")));
MethodSubject inherited = inspector.clazz(EXECUTOR).uniqueMethodWithName("inheritedTypes");
+ if (!requiresEmulatedInterfaceCoreLibDesugaring(parameters)) {
+ assertTrue(
+ inherited.streamInstructions().noneMatch(instr -> instr.toString().contains("$-EL")));
+ return;
+ }
assertTrue(
inherited
.streamInstructions()
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilFunctionTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilFunctionTest.java
index cb2659e..74a4efa 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilFunctionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilFunctionTest.java
@@ -35,6 +35,9 @@
}
private void checkRewrittenArguments(CodeInspector inspector) {
+ if (!requiresEmulatedInterfaceCoreLibDesugaring(parameters)) {
+ return;
+ }
ClassSubject classSubject = inspector.clazz(TestClass.class);
assertThat(classSubject, isPresent());
assertEquals(
@@ -50,12 +53,12 @@
}
@Test
- public void testJavaUtilOptional() throws Exception {
+ public void testJavaUtilFunction() throws Exception {
String expectedOutput = StringUtils.lines("Hello, world", "Hello, world");
testForD8()
.addInnerClasses(JavaUtilFunctionTest.class)
.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
- .setMinApi(parameters.getRuntime())
+ .setMinApi(parameters.getApiLevel())
.enableCoreLibraryDesugaring()
.compile()
.inspect(this::checkRewrittenArguments)
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilOptionalTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilOptionalTest.java
index 0d838b3..9465aee 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilOptionalTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilOptionalTest.java
@@ -41,6 +41,9 @@
}
private void checkRewrittenInvokes(CodeInspector inspector) {
+ if (!requiresEmulatedInterfaceCoreLibDesugaring(parameters)) {
+ return;
+ }
ClassSubject classSubject = inspector.clazz(TestClass.class);
assertThat(classSubject, isPresent());
Iterator<InvokeInstructionSubject> iterator =
@@ -76,7 +79,7 @@
testForD8()
.addInnerClasses(JavaUtilOptionalTest.class)
.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
- .setMinApi(parameters.getRuntime())
+ .setMinApi(parameters.getApiLevel())
.enableCoreLibraryDesugaring()
.compile()
.inspect(this::checkRewrittenInvokes)
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/corelibjdktests/Jdk11TimeTests.java b/src/test/java/com/android/tools/r8/desugar/corelib/corelibjdktests/Jdk11TimeTests.java
index 1d37013..3aefe01 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/corelibjdktests/Jdk11TimeTests.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/corelibjdktests/Jdk11TimeTests.java
@@ -140,10 +140,11 @@
.addProgramFiles(Paths.get(JDK_TESTS_BUILD_DIR + "jcommander-1.48.jar"))
.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
.setMinApi(parameters.getApiLevel())
- .enableCoreLibraryDesugaring()
+ .enableCoreLibraryDesugaring(parameters.getApiLevel())
.compile()
.withArt6Plus64BitsLib()
- .addRunClasspathFiles(buildDesugaredLibrary(parameters.getApiLevel()));
+ .addDesugaredCoreLibraryRunClassPath(
+ this::buildDesugaredLibrary, parameters.getApiLevel());
for (String success : successes) {
D8TestRunResult result =
compileResult.run(parameters.getRuntime(), "TestNGMainRunner", verbosity, success);