More desugared library tests

Bug: 134732760
Change-Id: I7a2bffca1561876be98f639252d57395a0554a7b
diff --git a/src/test/java/com/android/tools/r8/D8TestBuilder.java b/src/test/java/com/android/tools/r8/D8TestBuilder.java
index e3db7cc..cb1a8c4 100644
--- a/src/test/java/com/android/tools/r8/D8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/D8TestBuilder.java
@@ -5,6 +5,8 @@
 
 import com.android.tools.r8.D8Command.Builder;
 import com.android.tools.r8.TestBase.Backend;
+import com.android.tools.r8.desugar.corelib.CoreLibDesugarTestBase.KeepRuleConsumer;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
 import java.nio.file.Path;
@@ -62,4 +64,16 @@
     builder.setIntermediate(intermediate);
     return self();
   }
+
+  @Override
+  public D8TestBuilder enableCoreLibraryDesugaring(
+      AndroidApiLevel minAPILevel, KeepRuleConsumer keepRuleConsumer) {
+    if (minAPILevel.getLevel() < AndroidApiLevel.O.getLevel()) {
+      // Use P to mimic current Android Studio.
+      builder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P));
+      builder.addSpecialLibraryConfiguration("default");
+      builder.setDesugaredLibraryKeepRuleConsumer(keepRuleConsumer);
+    }
+    return self();
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index 0c23d42..f5ee649 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -5,11 +5,13 @@
 
 import com.android.tools.r8.R8Command.Builder;
 import com.android.tools.r8.TestBase.Backend;
+import com.android.tools.r8.desugar.corelib.CoreLibDesugarTestBase.KeepRuleConsumer;
 import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.shaking.CollectingGraphConsumer;
 import com.android.tools.r8.shaking.ProguardConfiguration;
 import com.android.tools.r8.shaking.ProguardConfigurationRule;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.FileUtils;
 import com.android.tools.r8.utils.InternalOptions;
@@ -329,4 +331,16 @@
     // We don't add these to the keep-rule set for other test provided rules.
     builder.addProguardConfiguration(Arrays.asList(rules), Origin.unknown());
   }
+
+  @Override
+  public T enableCoreLibraryDesugaring(
+      AndroidApiLevel minAPILevel, KeepRuleConsumer keepRuleConsumer) {
+    if (minAPILevel.getLevel() < AndroidApiLevel.O.getLevel()) {
+      // Use P to mimic current Android Studio.
+      builder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P));
+      builder.addSpecialLibraryConfiguration("default");
+      builder.setDesugaredLibraryKeepRuleConsumer(keepRuleConsumer);
+    }
+    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 8498704..363f70d 100644
--- a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
@@ -5,6 +5,8 @@
 
 import com.android.tools.r8.TestBase.Backend;
 import com.android.tools.r8.debug.DebugTestConfig;
+import com.android.tools.r8.desugar.corelib.CoreLibDesugarTestBase.KeepRuleConsumer;
+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.AndroidAppConsumers;
@@ -273,10 +275,11 @@
   }
 
   public T enableCoreLibraryDesugaring(AndroidApiLevel minAPILevel) {
-    if (minAPILevel.getLevel() < AndroidApiLevel.O.getLevel()) {
-      builder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.O));
-      builder.addSpecialLibraryConfiguration("default");
-    }
-    return self();
+    return enableCoreLibraryDesugaring(minAPILevel, null);
+  }
+
+  public T enableCoreLibraryDesugaring(
+      AndroidApiLevel minAPILevel, KeepRuleConsumer keepRuleConsumer) {
+    throw new Unreachable("Should be overridden or is unsupported.");
   }
 }
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 ff0237f..1eca0f4 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
@@ -7,12 +7,15 @@
 import static junit.framework.TestCase.assertEquals;
 import static junit.framework.TestCase.assertTrue;
 
+import com.android.tools.r8.DiagnosticsHandler;
 import com.android.tools.r8.L8Command;
 import com.android.tools.r8.OutputMode;
+import com.android.tools.r8.StringConsumer;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestDiagnosticMessagesImpl;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.google.common.collect.ImmutableList;
@@ -108,4 +111,54 @@
       assertEquals(lines[i], lines[i + 1]);
     }
   }
+
+  protected KeepRuleConsumer createKeepRuleConsumer(TestParameters parameters) {
+    if (requiresAnyCoreLibDesugaring(parameters)) {
+      return new PresentKeepRuleConsumer();
+    }
+    return new AbsentKeepRuleConsumer();
+  }
+
+  public interface KeepRuleConsumer extends StringConsumer {
+
+    String get();
+  }
+
+  public static class AbsentKeepRuleConsumer implements KeepRuleConsumer {
+
+    public String get() {
+      return null;
+    }
+
+    @Override
+    public void accept(String string, DiagnosticsHandler handler) {
+      throw new Unreachable("No desugaring on high API levels");
+    }
+  }
+
+  public static class PresentKeepRuleConsumer implements KeepRuleConsumer {
+
+    StringBuilder stringBuilder = new StringBuilder();
+    String result = null;
+
+    @Override
+    public void accept(String string, DiagnosticsHandler handler) {
+      assert stringBuilder != null;
+      assert result == null;
+      stringBuilder.append(string);
+    }
+
+    public void finished(DiagnosticsHandler handler) {
+      assert stringBuilder != null;
+      assert result == null;
+      result = stringBuilder.toString();
+      stringBuilder = null;
+    }
+
+    public String get() {
+      assert stringBuilder == null;
+      assert result != null;
+      return result;
+    }
+  }
 }
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 3625919..39d8451 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,9 +10,7 @@
 import com.android.tools.r8.D8TestRunResult;
 import com.android.tools.r8.R8TestRunResult;
 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.Box;
 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;
@@ -55,22 +53,18 @@
 
   @Test
   public void testCustomCollectionD8() throws Exception {
-    Box<String> keepRulesHolder = new Box<>("");
+    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
     D8TestRunResult d8TestRunResult =
         testForD8()
             .addInnerClasses(CustomCollectionTest.class)
             .setMinApi(parameters.getApiLevel())
-            .addOptionsModification(
-                options ->
-                    options.desugaredLibraryKeepRuleConsumer =
-                        ToolHelper.consumeString(keepRulesHolder::set))
-            .enableCoreLibraryDesugaring(parameters.getApiLevel())
+            .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
             .compile()
             .inspect(inspector -> this.assertCustomCollectionCallsCorrect(inspector, false))
             .addDesugaredCoreLibraryRunClassPath(
                 this::buildDesugaredLibrary,
                 parameters.getApiLevel(),
-                keepRulesHolder.get(),
+                keepRuleConsumer.get(),
                 shrinkCoreLibrary)
             .run(parameters.getRuntime(), EXECUTOR)
             .assertSuccess();
@@ -89,23 +83,19 @@
 
   @Test
   public void testCustomCollectionR8() throws Exception {
-    Box<String> keepRulesHolder = new Box<>("");
+    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
     R8TestRunResult r8TestRunResult =
         testForR8(Backend.DEX)
             .addInnerClasses(CustomCollectionTest.class)
             .setMinApi(parameters.getApiLevel())
             .addKeepClassAndMembersRules(Executor.class)
-            .addOptionsModification(
-                options ->
-                    options.desugaredLibraryKeepRuleConsumer =
-                        ToolHelper.consumeString(keepRulesHolder::set))
-            .enableCoreLibraryDesugaring(parameters.getApiLevel())
+            .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
             .compile()
             .inspect(inspector -> this.assertCustomCollectionCallsCorrect(inspector, true))
             .addDesugaredCoreLibraryRunClassPath(
                 this::buildDesugaredLibrary,
                 parameters.getApiLevel(),
-                keepRulesHolder.get(),
+                keepRuleConsumer.get(),
                 shrinkCoreLibrary)
             .run(parameters.getRuntime(), EXECUTOR)
             .assertSuccess();
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 1c4f47a..34ab55c 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,9 +9,7 @@
 import static org.junit.Assert.assertTrue;
 
 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.Box;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -56,21 +54,17 @@
 
   @Test
   public void testTimeD8() throws Exception {
-    Box<String> keepRulesHolder = new Box<>("");
+    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
     testForD8()
         .addInnerClasses(JavaTimeTest.class)
         .setMinApi(parameters.getApiLevel())
-        .enableCoreLibraryDesugaring(parameters.getApiLevel())
-        .addOptionsModification(
-            options ->
-                options.desugaredLibraryKeepRuleConsumer =
-                    ToolHelper.consumeString(keepRulesHolder::set))
+        .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
         .compile()
         .inspect(this::checkRewrittenInvokes)
         .addDesugaredCoreLibraryRunClassPath(
             this::buildDesugaredLibrary,
             parameters.getApiLevel(),
-            keepRulesHolder.get(),
+            keepRuleConsumer.get(),
             shrinkCoreLibrary)
         .run(parameters.getRuntime(), TestClass.class)
         .assertSuccessWithOutput(expectedOutput);
@@ -78,22 +72,18 @@
 
   @Test
   public void testTimeR8() throws Exception {
-    Box<String> keepRulesHolder = new Box<>("");
+    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
     testForR8(parameters.getBackend())
         .addInnerClasses(JavaTimeTest.class)
         .addKeepMainRule(TestClass.class)
         .setMinApi(parameters.getApiLevel())
-        .enableCoreLibraryDesugaring(parameters.getApiLevel())
-        .addOptionsModification(
-            options ->
-                options.desugaredLibraryKeepRuleConsumer =
-                    ToolHelper.consumeString(keepRulesHolder::set))
+        .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
         .compile()
         .inspect(this::checkRewrittenInvokes)
         .addDesugaredCoreLibraryRunClassPath(
             this::buildDesugaredLibrary,
             parameters.getApiLevel(),
-            keepRulesHolder.get(),
+            keepRuleConsumer.get(),
             shrinkCoreLibrary)
         .run(parameters.getRuntime(), TestClass.class)
         .assertSuccessWithOutput(expectedOutput);
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 74a4efa..e574c7c 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
@@ -8,29 +8,35 @@
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
+import com.android.tools.r8.NeverInline;
 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.StringUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import java.util.List;
 import java.util.function.Function;
+import org.junit.Assume;
 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 JavaUtilFunctionTest extends CoreLibDesugarTestBase {
 
   private final TestParameters parameters;
+  private final boolean shrinkCoreLibrary;
+  private static final String expectedOutput = StringUtils.lines("Hello, world", "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 JavaUtilFunctionTest(TestParameters parameters) {
+  public JavaUtilFunctionTest(boolean shrinkDesugaredLibrary, TestParameters parameters) {
+    this.shrinkCoreLibrary = shrinkDesugaredLibrary;
     this.parameters = parameters;
   }
 
@@ -53,22 +59,50 @@
   }
 
   @Test
-  public void testJavaUtilFunction() throws Exception {
-    String expectedOutput = StringUtils.lines("Hello, world", "Hello, world");
+  public void testJavaUtilFunctionD8() throws Exception {
+    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
     testForD8()
         .addInnerClasses(JavaUtilFunctionTest.class)
-        .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
         .setMinApi(parameters.getApiLevel())
-        .enableCoreLibraryDesugaring()
+        .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
         .compile()
         .inspect(this::checkRewrittenArguments)
-        .addRunClasspathFiles(buildDesugaredLibrary(parameters.getApiLevel()))
+        .addDesugaredCoreLibraryRunClassPath(
+            this::buildDesugaredLibrary,
+            parameters.getApiLevel(),
+            keepRuleConsumer.get(),
+            shrinkCoreLibrary)
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutput(expectedOutput);
+  }
+
+  @Test
+  public void testJavaUtilFunctionR8() throws Exception {
+    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
+    // TODO(b/139398549): Enable test on API 26+.
+    Assume.assumeTrue(parameters.getApiLevel().getLevel() < 26);
+    testForR8(parameters.getBackend())
+        // Following two for checkRewrittenArguments.
+        .enableInliningAnnotations()
+        .noMinification()
+        .addKeepMainRule(TestClass.class)
+        .addInnerClasses(JavaUtilFunctionTest.class)
+        .setMinApi(parameters.getApiLevel())
+        .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
+        .compile()
+        .inspect(this::checkRewrittenArguments)
+        .addDesugaredCoreLibraryRunClassPath(
+            this::buildDesugaredLibrary,
+            parameters.getApiLevel(),
+            keepRuleConsumer.get(),
+            shrinkCoreLibrary)
         .run(parameters.getRuntime(), TestClass.class)
         .assertSuccessWithOutput(expectedOutput);
   }
 
   static class TestClass {
 
+    @NeverInline
     private static String applyFunction(Function<String, String> f) {
       return f.apply("Hello, world");
     }
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/ProgramRewritingTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/ProgramRewritingTest.java
index d608e44..118c17f 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/ProgramRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/ProgramRewritingTest.java
@@ -18,9 +18,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.ToolHelper.DexVm;
-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;
@@ -56,26 +54,21 @@
   @Test
   public void testProgramD8() throws Exception {
     Assume.assumeTrue("No desugaring for high API levels", requiresCoreLibDesugaring(parameters));
-    Box<String> keepRulesHolder = new Box<>("");
+    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
     D8TestRunResult d8TestRunResult =
         testForD8()
             .addProgramFiles(Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR + "stream.jar"))
-            .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
             .setMinApi(parameters.getApiLevel())
-            .addOptionsModification(
-                options ->
-                    options.desugaredLibraryKeepRuleConsumer =
-                        ToolHelper.consumeString(keepRulesHolder::set))
-            .enableCoreLibraryDesugaring()
+            .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
             .compile()
             .inspect(this::checkRewrittenInvokes)
             .addRunClasspathFiles(
                 buildDesugaredLibrary(
-                    parameters.getApiLevel(), keepRulesHolder.get(), shrinkCoreLibrary))
+                    parameters.getApiLevel(), keepRuleConsumer.get(), shrinkCoreLibrary))
             .run(parameters.getRuntime(), TEST_CLASS)
             .assertSuccess();
     assertLines2By2Correct(d8TestRunResult.getStdOut());
-    assertGeneratedKeepRulesAreCorrect(keepRulesHolder.get());
+    assertGeneratedKeepRulesAreCorrect(keepRuleConsumer.get());
     String stdErr = d8TestRunResult.getStdErr();
     if (parameters.getRuntime().asDex().getVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
       // Flaky: There might be a missing method on lambda deserialization.
@@ -91,28 +84,23 @@
   public void testProgramR8() throws Exception {
     Assume.assumeTrue("No desugaring for high API levels", requiresCoreLibDesugaring(parameters));
     for (Boolean minifying : BooleanUtils.values()) {
-      Box<String> keepRulesHolder = new Box<>("");
+      KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
       R8TestRunResult r8TestRunResult =
           testForR8(parameters.getBackend())
               .minification(minifying)
               .addKeepMainRule(TEST_CLASS)
               .addProgramFiles(Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR + "stream.jar"))
-              .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
               .setMinApi(parameters.getApiLevel())
-              .addOptionsModification(
-                  options ->
-                      options.desugaredLibraryKeepRuleConsumer =
-                          ToolHelper.consumeString(keepRulesHolder::set))
-              .enableCoreLibraryDesugaring()
+              .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
               .compile()
               .inspect(this::checkRewrittenInvokes)
               .addRunClasspathFiles(
                   buildDesugaredLibrary(
-                      parameters.getApiLevel(), keepRulesHolder.get(), shrinkCoreLibrary))
+                      parameters.getApiLevel(), keepRuleConsumer.get(), shrinkCoreLibrary))
               .run(parameters.getRuntime(), TEST_CLASS)
               .assertSuccess();
       assertLines2By2Correct(r8TestRunResult.getStdOut());
-      assertGeneratedKeepRulesAreCorrect(keepRulesHolder.get());
+      assertGeneratedKeepRulesAreCorrect(keepRuleConsumer.get());
       if (parameters.getRuntime().asDex().getVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
         // Flaky: There might be a missing method on lambda deserialization.
         r8TestRunResult.assertStderrMatches(