Support Stream#toList

Change-Id: I9f307b69f84a27709742726ebaca61207ff3e224
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs.json b/src/library_desugar/jdk11/desugar_jdk_libs.json
index 360bb74..9cd5553 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs.json
@@ -7,12 +7,6 @@
   "common_flags": [
     {
       "api_level_below_or_equal": 10000,
-      "amend_library_method": [
-        "public java.lang.Object[] java.util.Collection#toArray(java.util.function.IntFunction)"
-      ]
-    },
-    {
-      "api_level_below_or_equal": 10000,
       "api_level_greater_or_equal": 26,
       "rewrite_prefix": {
         "java.time.DesugarLocalDate": "j$.time.DesugarLocalDate",
@@ -59,6 +53,12 @@
       }
     },
     {
+      "api_level_below_or_equal": 33,
+      "amend_library_method": [
+        "public java.util.List java.util.stream.Stream#toList()"
+      ]
+    },
+    {
       "api_level_below_or_equal": 32,
       "rewrite_prefix": {
         "java.util.concurrent.DesugarTimeUnit": "j$.util.concurrent.DesugarTimeUnit"
@@ -70,6 +70,7 @@
       },
       "amend_library_method": [
         "public static java.util.concurrent.TimeUnit java.util.concurrent.TimeUnit#of(java.time.temporal.ChronoUnit)",
+        "public java.lang.Object[] java.util.Collection#toArray(java.util.function.IntFunction)",
         "public java.time.temporal.ChronoUnit java.util.concurrent.TimeUnit#toChronoUnit()",
         "public long java.util.concurrent.TimeUnit#convert(java.time.Duration)"
       ]
@@ -86,6 +87,18 @@
       ]
     },
     {
+      "api_level_below_or_equal": 33,
+      "api_level_greater_or_equal": 24,
+      "emulate_interface": {
+        "java.util.stream.Stream": {
+          "rewrittenType": "j$.util.stream.Stream",
+          "emulatedMethods": [
+            "public java.util.List java.util.stream.Stream#toList()"
+          ]
+        }
+      }
+    },
+    {
       "api_level_below_or_equal": 32,
       "api_level_greater_or_equal": 24,
       "rewrite_prefix": {
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs_nio.json b/src/library_desugar/jdk11/desugar_jdk_libs_nio.json
index b75ec43..fde52e9 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_nio.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_nio.json
@@ -8,7 +8,6 @@
     {
       "api_level_below_or_equal": 10000,
       "amend_library_method": [
-        "public java.lang.Object[] java.util.Collection#toArray(java.util.function.IntFunction)",
         "public static java.nio.file.Path java.nio.file.Path#of(java.lang.String, java.lang.String[])",
         "public static java.nio.file.Path java.nio.file.Path#of(java.net.URI)"
       ]
@@ -70,6 +69,12 @@
       }
     },
     {
+      "api_level_below_or_equal": 33,
+      "amend_library_method": [
+        "public java.util.List java.util.stream.Stream#toList()"
+      ]
+    },
+    {
       "api_level_below_or_equal": 32,
       "rewrite_prefix": {
         "java.net.URLDecoder": "j$.net.URLDecoder",
@@ -88,6 +93,7 @@
       },
       "amend_library_method": [
         "public static java.util.concurrent.TimeUnit java.util.concurrent.TimeUnit#of(java.time.temporal.ChronoUnit)",
+        "public java.lang.Object[] java.util.Collection#toArray(java.util.function.IntFunction)",
         "public java.time.temporal.ChronoUnit java.util.concurrent.TimeUnit#toChronoUnit()",
         "public long java.util.concurrent.TimeUnit#convert(java.time.Duration)",
         "public long java.io.InputStream#transferTo(java.io.OutputStream)",
@@ -106,6 +112,18 @@
       ]
     },
     {
+      "api_level_below_or_equal": 33,
+      "api_level_greater_or_equal": 24,
+      "emulate_interface": {
+        "java.util.stream.Stream": {
+          "rewrittenType": "j$.util.stream.Stream",
+          "emulatedMethods": [
+            "public java.util.List java.util.stream.Stream#toList()"
+          ]
+        }
+      }
+    },
+    {
       "api_level_below_or_equal": 32,
       "api_level_greater_or_equal": 24,
       "rewrite_prefix": {
diff --git a/src/test/examplesJava17/desugaredlibrary/StreamToListTest.java b/src/test/examplesJava17/desugaredlibrary/StreamToListTest.java
new file mode 100644
index 0000000..e9e4786
--- /dev/null
+++ b/src/test/examplesJava17/desugaredlibrary/StreamToListTest.java
@@ -0,0 +1,65 @@
+// Copyright (c) 2025, 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 desugaredlibrary;
+
+import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.SPECIFICATIONS_WITH_CF2CF;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK11;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK11_PATH;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
+import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
+import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
+import com.android.tools.r8.utils.StringUtils;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.stream.Stream;
+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 StreamToListTest extends DesugaredLibraryTestBase {
+
+  private final TestParameters parameters;
+  private final LibraryDesugaringSpecification libraryDesugaringSpecification;
+  private final CompilationSpecification compilationSpecification;
+
+  private static final String EXPECTED_OUTPUT = StringUtils.lines("a - c");
+
+  @Parameters(name = "{0}, spec: {1}, {2}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withDexRuntimes().withAllApiLevels().build(),
+        ImmutableList.of(JDK11, JDK11_PATH),
+        SPECIFICATIONS_WITH_CF2CF);
+  }
+
+  public StreamToListTest(
+      TestParameters parameters,
+      LibraryDesugaringSpecification libraryDesugaringSpecification,
+      CompilationSpecification compilationSpecification) {
+    this.parameters = parameters;
+    this.libraryDesugaringSpecification = libraryDesugaringSpecification;
+    this.compilationSpecification = compilationSpecification;
+  }
+
+  @Test
+  public void test() throws Throwable {
+    testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
+        .addInnerClassesAndStrippedOuter(getClass())
+        .addKeepMainRule(Main.class)
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutput(EXPECTED_OUTPUT);
+  }
+
+  public static class Main {
+    public static void main(String[] args) {
+      List<String> strings = Stream.of("a", "b", "c").toList();
+      System.out.println(strings.get(0) + " - " + strings.get(2));
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryInvokeAllResolveTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryInvokeAllResolveTest.java
index a6e298f..8893a42 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryInvokeAllResolveTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryInvokeAllResolveTest.java
@@ -68,8 +68,9 @@
               + " java.util.stream.LongStream.takeWhile(java.util.function.LongPredicate)",
           "java.util.stream.DoubleStream"
               + " java.util.stream.DoubleStream.dropWhile(java.util.function.DoublePredicate)",
+          // Stream.toList() and FileStore.getBlockSize() were added in 33 which confuses the
+          // required library (30).
           "java.util.List java.util.stream.Stream.toList()",
-          // FileStore.getBlockSize() was added in 33 which confuses the required library (30).
           "long java.nio.file.FileStore.getBlockSize()",
           // The call is present but unreachable above 26.
           "java.nio.channels.FileChannel"