More tests desugared library

- Time and CustomCollection core library shrinking tests.
- Change API where library desugaring is not required from P to O.
- Removed Objects from library desugaring (already desugared by the
  backported method rewriter).
- Disable vertical class merging in R8 library shrinking (crashes).

Change-Id: Ia2b67a4ef63f020b0e03ae0fd5a9af2cf731ff53
diff --git a/src/main/java/com/android/tools/r8/L8Command.java b/src/main/java/com/android/tools/r8/L8Command.java
index fecebda..93fa4fc 100644
--- a/src/main/java/com/android/tools/r8/L8Command.java
+++ b/src/main/java/com/android/tools/r8/L8Command.java
@@ -233,6 +233,8 @@
                 .setDisableMinification(true)
                 .setMode(getMode())
                 .setProgramConsumer(getProgramConsumer());
+        // TODO(b/134732760) Investigate why vertical class merging crashes and enable it.
+        r8Builder.setDisableVerticalClassMerging(true);
         for (ClassFileResourceProvider libraryResourceProvider :
             inputs.getLibraryResourceProviders()) {
           r8Builder.addLibraryResourceProvider(libraryResourceProvider);
diff --git a/src/main/java/com/android/tools/r8/SpecialLibraryConfiguration.java b/src/main/java/com/android/tools/r8/SpecialLibraryConfiguration.java
index 9ec6cde..b501325 100644
--- a/src/main/java/com/android/tools/r8/SpecialLibraryConfiguration.java
+++ b/src/main/java/com/android/tools/r8/SpecialLibraryConfiguration.java
@@ -26,6 +26,7 @@
         // .put("java.lang.Integer8", "j$.lang.Integer8")
         // .put("java.lang.Long8", "j$.lang.Long8")
         // .put("java.lang.Math8", "j$.lang.Math8")
+        // .put("java.util.Objects", "j$.util.Objects")
         .put("java.time.", "j$.time.")
         .put("java.util.stream.", "j$.util.stream.")
         .put("java.util.function.", "j$.util.function.")
@@ -33,7 +34,6 @@
         .put("java.util.DoubleSummaryStatistics", "j$.util.DoubleSummaryStatistics")
         .put("java.util.IntSummaryStatistics", "j$.util.IntSummaryStatistics")
         .put("java.util.LongSummaryStatistics", "j$.util.LongSummaryStatistics")
-        .put("java.util.Objects", "j$.util.Objects")
         .put("java.util.Optional", "j$.util.Optional")
         .put("java.util.PrimitiveIterator", "j$.util.PrimitiveIterator")
         .put("java.util.Spliterator", "j$.util.Spliterator")
@@ -271,10 +271,10 @@
 
   public static void configureLibraryDesugaringForProgramCompilation(InternalOptions options) {
     // TODO(b/134732760): Make assertions in D8/R8 commands.
-    if (options.minApiLevel >= AndroidApiLevel.P.getLevel()) {
+    if (options.minApiLevel >= AndroidApiLevel.O.getLevel()) {
       options.reporter.warning(
           new StringDiagnostic(
-              "Desugaring core libraries for Android P and over is possible but not required."));
+              "Desugaring core libraries for Android O and over is possible but not required."));
     }
     options.coreLibraryCompilation = false;
     if (options.minApiLevel < AndroidApiLevel.N.getLevel()) {
@@ -291,10 +291,10 @@
 
   public static void configureLibraryDesugaringForLibraryCompilation(InternalOptions options) {
     // TODO(b/134732760): Make assertions in L8 commands.
-    if (options.minApiLevel >= AndroidApiLevel.P.getLevel()) {
+    if (options.minApiLevel >= AndroidApiLevel.O.getLevel()) {
       options.reporter.warning(
           new StringDiagnostic(
-              "Desugaring core libraries for Android P and over is possible but not required."));
+              "Desugaring core libraries for Android O and over is possible but not required."));
     }
     options.coreLibraryCompilation = true;
     options.backportCoreLibraryMembers = buildBackportCoreLibraryMembers();
diff --git a/src/test/java/com/android/tools/r8/TestCompileResult.java b/src/test/java/com/android/tools/r8/TestCompileResult.java
index 3adf685..31cdf50 100644
--- a/src/test/java/com/android/tools/r8/TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/TestCompileResult.java
@@ -167,7 +167,7 @@
 
   public CR addDesugaredCoreLibraryRunClassPath(
       Function<AndroidApiLevel, Path> classPathSupplier, AndroidApiLevel minAPILevel) {
-    if (minAPILevel.getLevel() < AndroidApiLevel.P.getLevel()) {
+    if (minAPILevel.getLevel() < AndroidApiLevel.O.getLevel()) {
       addRunClasspathFiles(classPathSupplier.apply(minAPILevel));
     }
     return self();
@@ -178,7 +178,7 @@
       AndroidApiLevel minAPILevel,
       String keepRules,
       boolean shrink) {
-    if (minAPILevel.getLevel() < AndroidApiLevel.P.getLevel()) {
+    if (minAPILevel.getLevel() < AndroidApiLevel.O.getLevel()) {
       addRunClasspathFiles(classPathSupplier.apply(minAPILevel, keepRules, shrink));
     }
     return self();
diff --git a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
index c418f28..8498704 100644
--- a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
@@ -273,8 +273,8 @@
   }
 
   public T enableCoreLibraryDesugaring(AndroidApiLevel minAPILevel) {
-    if (minAPILevel.getLevel() < AndroidApiLevel.P.getLevel()) {
-      builder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P));
+    if (minAPILevel.getLevel() < AndroidApiLevel.O.getLevel()) {
+      builder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.O));
       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 e7b3f92..3e13a86 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
@@ -33,7 +33,7 @@
   }
 
   protected boolean requiresRetargetCoreLibMemberDesugaring(TestParameters parameters) {
-    return parameters.getApiLevel().getLevel() < AndroidApiLevel.P.getLevel();
+    return parameters.getApiLevel().getLevel() < AndroidApiLevel.O.getLevel();
   }
 
   protected boolean requiresAnyCoreLibDesugaring(TestParameters parameters) {
@@ -57,7 +57,6 @@
   protected Path buildDesugaredLibrary(
       AndroidApiLevel apiLevel, String keepRules, boolean shrink, List<Path> additionalProgramFiles)
       throws RuntimeException {
-    // TODO(b/134732760): Support Shrinking.
     // We wrap exceptions in a RuntimeException to call this from a lambda.
     try {
       Path desugaredLib = temp.newFolder().toPath().resolve("desugar_jdk_libs_dex.zip");
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 5682d45..099c560 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
@@ -8,6 +8,7 @@
 import static org.junit.Assert.fail;
 
 import com.android.tools.r8.D8TestRunResult;
+import com.android.tools.r8.R8TestRunResult;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.Box;
@@ -46,7 +47,7 @@
       "com.android.tools.r8.desugar.corelib.CustomCollectionTest$Executor";
 
   @Test
-  public void testCustomCollection() throws Exception {
+  public void testCustomCollectionD8() throws Exception {
     Box<String> keepRulesHolder = new Box<>("");
     D8TestRunResult d8TestRunResult =
         testForD8()
@@ -58,7 +59,7 @@
                         (string, handler) -> keepRulesHolder.set(keepRulesHolder.get() + string))
             .enableCoreLibraryDesugaring(parameters.getApiLevel())
             .compile()
-            .inspect(this::assertCustomCollectionCallsCorrect)
+            .inspect(inspector -> this.assertCustomCollectionCallsCorrect(inspector, false))
             .addDesugaredCoreLibraryRunClassPath(
                 this::buildDesugaredLibrary,
                 parameters.getApiLevel(),
@@ -79,10 +80,61 @@
     }
   }
 
-  private void assertCustomCollectionCallsCorrect(CodeInspector inspector) {
+  @Test
+  public void testCustomCollectionR8() throws Exception {
+    Box<String> keepRulesHolder = new Box<>("");
+    R8TestRunResult r8TestRunResult =
+        testForR8(Backend.DEX)
+            .addInnerClasses(CustomCollectionTest.class)
+            .setMinApi(parameters.getApiLevel())
+            .addKeepClassAndMembersRules(Executor.class)
+            .addOptionsModification(
+                options ->
+                    options.testing.desugaredLibraryKeepRuleConsumer =
+                        (string, handler) -> keepRulesHolder.set(keepRulesHolder.get() + string))
+            .enableCoreLibraryDesugaring(parameters.getApiLevel())
+            .compile()
+            .inspect(inspector -> this.assertCustomCollectionCallsCorrect(inspector, true))
+            .addDesugaredCoreLibraryRunClassPath(
+                this::buildDesugaredLibrary,
+                parameters.getApiLevel(),
+                keepRulesHolder.get(),
+                shrinkCoreLibrary)
+            .run(parameters.getRuntime(), EXECUTOR)
+            .assertSuccess();
+    if (requiresEmulatedInterfaceCoreLibDesugaring(parameters)) {
+      // Expected output is emulated interfaces expected output.
+      assertLines2By2Correct(r8TestRunResult.getStdOut());
+    }
+    String[] split = r8TestRunResult.getStdErr().split("Could not find method");
+    if (split.length > 2) {
+      fail("Could not find multiple methods");
+    } else if (split.length == 2) {
+      // On some VMs the Serialized lambda code is missing.
+      assertTrue(r8TestRunResult.getStdErr().contains("SerializedLambda"));
+    }
+  }
+
+  private void assertCustomCollectionCallsCorrect(CodeInspector inspector, boolean r8) {
     MethodSubject direct = inspector.clazz(EXECUTOR).uniqueMethodWithName("directTypes");
-    Assert.assertFalse(
-        direct.streamInstructions().anyMatch(instr -> instr.toString().contains("$-EL")));
+    // TODO(b/134732760): Due to memberRebinding, R8 is not as precise as D8 regarding
+    // desugaring of invokes. This will be fixed when creation of desugared method is moved
+    // ahead of R8 compilation pipeline.
+    if (!r8) {
+      Assert.assertFalse(
+          direct.streamInstructions().anyMatch(instr -> instr.toString().contains("$-EL")));
+    } else if (requiresEmulatedInterfaceCoreLibDesugaring(parameters)) {
+      assertTrue(
+          direct
+              .streamInstructions()
+              .filter(InstructionSubject::isInvokeStatic)
+              .allMatch(
+                  instr ->
+                      instr.toString().contains("$-EL")
+                          || instr.toString().contains("Comparator$-CC")));
+    } else {
+      assertTrue(direct.streamInstructions().noneMatch(instr -> instr.toString().contains("$-EL")));
+    }
     MethodSubject inherited = inspector.clazz(EXECUTOR).uniqueMethodWithName("inheritedTypes");
     if (!requiresEmulatedInterfaceCoreLibDesugaring(parameters)) {
       assertTrue(
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/JavaTimeTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/JavaTimeTest.java
index 9c0e7b0..fb1c722 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/JavaTimeTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/JavaTimeTest.java
@@ -9,34 +9,42 @@
 import static org.junit.Assert.assertTrue;
 
 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.BooleanUtils;
+import com.android.tools.r8.utils.Box;
 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.InstructionSubject;
 import com.android.tools.r8.utils.codeinspector.InvokeInstructionSubject;
 import java.util.Iterator;
+import java.util.List;
 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 JavaTimeTest extends CoreLibDesugarTestBase {
 
   private final TestParameters parameters;
+  private final boolean shrinkCoreLibrary;
+  private static final String expectedOutput = StringUtils.lines("Hello, world");
 
-  @Parameterized.Parameters(name = "{0}")
-  public static TestParametersCollection data() {
-    return getTestParameters().withDexRuntimes().withAllApiLevels().build();
+  @Parameters(name = "{1}, shrinkCoreLibrary: {0}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        BooleanUtils.values(), getTestParameters().withDexRuntimes().withAllApiLevels().build());
   }
 
-  public JavaTimeTest(TestParameters parameters) {
+  public JavaTimeTest(boolean shrinkDesugaredLibrary, TestParameters parameters) {
+    this.shrinkCoreLibrary = shrinkDesugaredLibrary;
     this.parameters = parameters;
   }
 
   private void checkRewrittenInvokes(CodeInspector inspector) {
+    if (parameters.getApiLevel().getLevel() >= 26) {
+      return;
+    }
     ClassSubject classSubject = inspector.clazz(TestClass.class);
     assertThat(classSubject, isPresent());
     Iterator<InvokeInstructionSubject> iterator =
@@ -46,16 +54,46 @@
   }
 
   @Test
-  public void test() throws Exception {
-    String expectedOutput = StringUtils.lines("Hello, world");
+  public void testTimeD8() throws Exception {
+    Box<String> keepRulesHolder = new Box<>("");
     testForD8()
         .addInnerClasses(JavaTimeTest.class)
-        .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
-        .setMinApi(parameters.getRuntime())
-        .enableCoreLibraryDesugaring()
+        .setMinApi(parameters.getApiLevel())
+        .enableCoreLibraryDesugaring(parameters.getApiLevel())
+        .addOptionsModification(
+            options ->
+                options.testing.desugaredLibraryKeepRuleConsumer =
+                    (string, handler) -> keepRulesHolder.set(keepRulesHolder.get() + string))
         .compile()
         .inspect(this::checkRewrittenInvokes)
-        .addRunClasspathFiles(buildDesugaredLibrary(parameters.getApiLevel()))
+        .addDesugaredCoreLibraryRunClassPath(
+            this::buildDesugaredLibrary,
+            parameters.getApiLevel(),
+            keepRulesHolder.get(),
+            shrinkCoreLibrary)
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutput(expectedOutput);
+  }
+
+  @Test
+  public void testTimeR8() throws Exception {
+    Box<String> keepRulesHolder = new Box<>("");
+    testForR8(parameters.getBackend())
+        .addInnerClasses(JavaTimeTest.class)
+        .addKeepMainRule(TestClass.class)
+        .setMinApi(parameters.getApiLevel())
+        .enableCoreLibraryDesugaring(parameters.getApiLevel())
+        .addOptionsModification(
+            options ->
+                options.testing.desugaredLibraryKeepRuleConsumer =
+                    (string, handler) -> keepRulesHolder.set(keepRulesHolder.get() + string))
+        .compile()
+        .inspect(this::checkRewrittenInvokes)
+        .addDesugaredCoreLibraryRunClassPath(
+            this::buildDesugaredLibrary,
+            parameters.getApiLevel(),
+            keepRulesHolder.get(),
+            shrinkCoreLibrary)
         .run(parameters.getRuntime(), TestClass.class)
         .assertSuccessWithOutput(expectedOutput);
   }