Fix AndroidO.lambdaDesugaring by moving legacy classes into third_party

Bug: b/270105162
Change-Id: I634c97ff65c775d47bc789c6e28366e22d6c1b70
diff --git a/.gitignore b/.gitignore
index edb84ad..78a056c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -96,6 +96,8 @@
 third_party/dependencies_new.tar.gz
 third_party/desugar/desugar_*.tar.gz
 third_party/desugar/desugar_*/
+third_party/examplesAndroidOLegacy
+third_party/examplesAndroidOLegacy.tar.gz
 third_party/framework
 third_party/framework.tar.gz
 third_party/gmail/*
diff --git a/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt b/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt
index 12fd28d..c0d6e1f 100644
--- a/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt
+++ b/d8_r8/commonBuildSrc/src/main/kotlin/DependenciesPlugin.kt
@@ -356,6 +356,10 @@
     "ddmlib",
     Paths.get("third_party", "ddmlib").toFile(),
     Paths.get("third_party", "ddmlib.tar.gz.sha1").toFile())
+  val examplesAndroidOLegacy = ThirdPartyDependency(
+    "examplesAndroidOLegacy",
+    Paths.get("third_party", "examplesAndroidOLegacy").toFile(),
+    Paths.get("third_party", "examplesAndroidOLegacy.tar.gz.sha1").toFile())
   val desugarJdkLibs = ThirdPartyDependency(
     "desugar-jdk-libs",
     Paths.get("third_party", "openjdk", "desugar_jdk_libs").toFile(),
diff --git a/d8_r8/test_modules/tests_java_8/build.gradle.kts b/d8_r8/test_modules/tests_java_8/build.gradle.kts
index 3070aa1..0d9db78 100644
--- a/d8_r8/test_modules/tests_java_8/build.gradle.kts
+++ b/d8_r8/test_modules/tests_java_8/build.gradle.kts
@@ -75,6 +75,7 @@
     ThirdPartyDeps.desugarJdkLibs,
     ThirdPartyDeps.desugarJdkLibsLegacy,
     ThirdPartyDeps.desugarJdkLibs11,
+    ThirdPartyDeps.examplesAndroidOLegacy,
     ThirdPartyDeps.gson,
     ThirdPartyDeps.jacoco,
     ThirdPartyDeps.java8Runtime,
@@ -189,6 +190,7 @@
     exclude("com/android/tools/r8/classmerging/vertical/ForceInlineConstructorWithRetargetedLibMemberTest**")
     exclude("com/android/tools/r8/ir/optimize/inliner/InlineMethodWithRetargetedLibMemberTest**")
     exclude("com/android/tools/r8/profile/art/DesugaredLibraryArtProfileRewritingTest**")
+    exclude("com/android/tools/r8/profile/art/dump/DumpArtProfileProvidersTest**")
   }
 
   val testJar by registering(Jar::class) {
diff --git a/d8_r8/test_modules/tests_java_examplesAndroidO/build.gradle.kts b/d8_r8/test_modules/tests_java_examplesAndroidO/build.gradle.kts
index 048fc5d..062128c 100644
--- a/d8_r8/test_modules/tests_java_examplesAndroidO/build.gradle.kts
+++ b/d8_r8/test_modules/tests_java_examplesAndroidO/build.gradle.kts
@@ -22,8 +22,14 @@
   targetCompatibility = JavaVersion.VERSION_1_8
 }
 
+// NOTE: we want to enable a scenario when test needs to reference some classes generated by legacy
+// (1.6) Java compiler to test some specific behaviour. To do so we compile all the java files
+// located in a sub-directory called 'legacy' with Java 1.6, then compile the rest of the files with
+// Java 1.8 and a reference to previously generated 1.6 classes.
+
 dependencies {
   testCompileOnly(Deps.asm)
+  testCompileOnly(resolve(ThirdPartyDeps.examplesAndroidOLegacy))
   testCompileOnly(resolve(getThirdPartyAndroidJar("lib-v26"),"android.jar"))
 }
 
@@ -33,6 +39,7 @@
 val thirdPartyCompileDependenciesTask = ensureThirdPartyDependencies(
   "compileDeps",
   listOf(
+    ThirdPartyDeps.examplesAndroidOLegacy,
     Jdk.JDK_11.getThirdPartyDependency(),
     getThirdPartyAndroidJar("lib-v26")))
 
diff --git a/src/test/examplesAndroidOLegacy/README.txt b/src/test/examplesAndroidOLegacy/README.txt
new file mode 100644
index 0000000..5a90476
--- /dev/null
+++ b/src/test/examplesAndroidOLegacy/README.txt
@@ -0,0 +1,13 @@
+// Copyright (c) 2023, 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.
+
+The examplesAndroidOLegacy source set is no longer included in build.gradle
+after transitioning to gradle v8. If we need to update the project, one should
+generate new class files and place in third_party/examplesAndroidOLegacy or
+make a direct dependency on the generated jars.
+
+See this commit where we check in the class files to get a sense of how to
+compile the source sets:
+https://r8-review.git.corp.google.com/c/r8/+/83161
+
diff --git a/src/test/examplesAndroidO/lambdadesugaring/legacy/Legacy.java b/src/test/examplesAndroidOLegacy/lambdadesugaring/legacy/Legacy.java
similarity index 100%
rename from src/test/examplesAndroidO/lambdadesugaring/legacy/Legacy.java
rename to src/test/examplesAndroidOLegacy/lambdadesugaring/legacy/Legacy.java
diff --git a/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java
index 646e805..dd3311b 100644
--- a/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8IncrementalRunExamplesAndroidOTest.java
@@ -27,7 +27,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.nio.file.DirectoryStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -118,8 +117,10 @@
     private Path makeRelative(Path testJarFile, Path classFile) {
       Path regularParent =
           testJarFile.getParent().resolve(Paths.get("classes"));
-      Path legacyParent = regularParent.resolve(Paths.get("..",
-          regularParent.getFileName().toString() + "Legacy", "classes"));
+      Path legacyParent =
+          regularParent.resolve(
+              Paths.get(
+                  ToolHelper.THIRD_PARTY_DIR, regularParent.getFileName().toString() + "Legacy"));
 
       if (classFile.startsWith(regularParent)) {
         return regularParent.relativize(classFile);
@@ -131,9 +132,10 @@
     private List<String> collectClassFiles(Path testJarFile) {
       List<String> result = new ArrayList<>();
       // Collect Java 8 classes.
-      collectClassFiles(getClassesRoot(testJarFile), result, false);
+      visitFiles(getClassesRoot(testJarFile), path -> result.add(path.toString()));
       // Collect legacy classes.
-      collectClassFiles(getLegacyClassesRoot(testJarFile), result, true);
+      visitFiles(
+          getLegacyClassesRoot(testJarFile, packageName), path -> result.add(path.toString()));
       Collections.sort(result);
       return result;
     }
@@ -143,32 +145,6 @@
       return parent.resolve(Paths.get("classes", packageName));
     }
 
-    Path getLegacyClassesRoot(Path testJarFile) {
-      Path parent = testJarFile.getParent();
-      Path legacyPath = Paths.get("..",
-          parent.getFileName().toString() + "Legacy", "classes", packageName);
-      return parent.resolve(legacyPath);
-    }
-
-    private void collectClassFiles(Path dir, List<String> result, boolean takeLegacy) {
-      if (Files.exists(dir)) {
-        try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
-          for (Path entry: stream) {
-            if (Files.isDirectory(entry)) {
-              if (entry.getFileName().toString().equals("legacy") && !takeLegacy) {
-                return;
-              }
-              collectClassFiles(entry, result, takeLegacy);
-            } else {
-              result.add(entry.toString());
-            }
-          }
-        } catch (IOException x) {
-          throw new AssertionError(x);
-        }
-      }
-    }
-
     AndroidApp compileClassFilesInIntermediate(
         Path testJarFile, List<String> inputFiles, Path outputPath, OutputMode outputMode)
         throws Throwable {
diff --git a/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java
index 78bbcf3..a803a91 100644
--- a/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java
@@ -38,7 +38,7 @@
     @Override
     void addClasspathReference(Path testJarFile, D8Command.Builder builder) {
       addClasspathPath(getClassesRoot(testJarFile), builder);
-      addClasspathPath(getLegacyClassesRoot(testJarFile), builder);
+      addClasspathPath(getLegacyClassesRoot(testJarFile, packageName), builder);
     }
 
     private void addClasspathPath(Path location, D8Command.Builder builder) {
diff --git a/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java
index b4cc992..b8e9066 100644
--- a/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java
@@ -41,13 +41,10 @@
           ToolHelper.getAndroidJar(
               androidJarVersion == null ? builder.getMinApiLevel() : androidJarVersion.getLevel()));
       builder.addProgramFiles(inputFile);
+      visitFiles(getLegacyClassesRoot(inputFile, packageName), builder::addProgramFiles);
       ToolHelper.runD8(builder, this::combinedOptionConsumer);
     }
 
-    D8TestRunner withIntermediate(boolean intermediate) {
-      return withBuilderTransformation(builder -> builder.setIntermediate(intermediate));
-    }
-
     @Override
     D8TestRunner self() {
       return this;
diff --git a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
index fa1d579..9acb6cf 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
@@ -129,7 +129,7 @@
         .withBuilderTransformation(
             b -> b.addProguardConfiguration(PROGUARD_OPTIONS, Origin.unknown()))
         .withDexCheck(inspector -> checkLambdaCount(inspector, 10, "lambdadesugaring"))
-        .run();
+        .run(Paths.get(ToolHelper.THIRD_PARTY_DIR, "examplesAndroidOLegacy"));
 
     test("lambdadesugaring", "lambdadesugaring", "LambdaDesugaring")
         .withOptionConsumer(o -> o.testing.enableLir())
@@ -137,7 +137,7 @@
         .withBuilderTransformation(
             b -> b.addProguardConfiguration(PROGUARD_OPTIONS, Origin.unknown()))
         .withDexCheck(inspector -> checkLambdaCount(inspector, 1, "lambdadesugaring"))
-        .run();
+        .run(Paths.get(ToolHelper.THIRD_PARTY_DIR, "examplesAndroidOLegacy"));
   }
 
   @Test
@@ -157,7 +157,7 @@
                         "}"),
                     Origin.unknown()))
         .withDexCheck(inspector -> checkTestMultipleInterfacesCheckCastCount(inspector, 0))
-        .run();
+        .run(Paths.get(ToolHelper.THIRD_PARTY_DIR, "examplesAndroidOLegacy"));
   }
 
   @Test
@@ -169,7 +169,7 @@
         .withBuilderTransformation(
             b -> b.addProguardConfiguration(PROGUARD_OPTIONS, Origin.unknown()))
         .withDexCheck(inspector -> checkLambdaCount(inspector, 10, "lambdadesugaring"))
-        .run();
+        .run(Paths.get(ToolHelper.THIRD_PARTY_DIR, "examplesAndroidOLegacy"));
 
     test("lambdadesugaring", "lambdadesugaring", "LambdaDesugaring")
         .withMinApiLevel(AndroidApiLevel.N)
@@ -177,7 +177,7 @@
         .withBuilderTransformation(
             b -> b.addProguardConfiguration(PROGUARD_OPTIONS, Origin.unknown()))
         .withDexCheck(inspector -> checkLambdaCount(inspector, 1, "lambdadesugaring"))
-        .run();
+        .run(Paths.get(ToolHelper.THIRD_PARTY_DIR, "examplesAndroidOLegacy"));
   }
 
   @Override
@@ -326,9 +326,9 @@
       for (Consumer<R8Command.Builder> transformation : builderTransformations) {
         transformation.accept(builder);
       }
-
       builder.addLibraryFiles(ToolHelper.getAndroidJar(
           androidJarVersion == null ? builder.getMinApiLevel() : androidJarVersion.getLevel()));
+      visitFiles(getLegacyClassesRoot(inputFile, packageName), builder::addProgramFiles);
       R8Command command = builder.addProgramFiles(inputFile).build();
       ToolHelper.runR8(command, this::combinedOptionConsumer);
     }
diff --git a/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
index 59e0d13..276f815 100644
--- a/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
@@ -12,6 +12,7 @@
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeFalse;
 
+import com.android.tools.r8.TestRuntime.CfRuntime;
 import com.android.tools.r8.ToolHelper.DexVm;
 import com.android.tools.r8.ToolHelper.DexVm.Version;
 import com.android.tools.r8.origin.Origin;
@@ -37,6 +38,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
@@ -168,7 +171,7 @@
       return Paths.get(EXAMPLE_DIR, packageName + JAR_EXTENSION);
     }
 
-    void run() throws Throwable {
+    void run(Path... additionalJavaClasspaths) throws Throwable {
       if (minSdkErrorExpected(testName)) {
         thrown.expect(CompilationFailedException.class);
       }
@@ -190,7 +193,11 @@
         }
       }
 
-      execute(testName, qualifiedMainClass, new Path[]{inputFile}, new Path[]{out}, args);
+      List<Path> paths = new ArrayList<>();
+      paths.add(inputFile);
+      paths.addAll(Arrays.asList(additionalJavaClasspaths));
+
+      execute(testName, qualifiedMainClass, paths.toArray(new Path[0]), new Path[] {out}, args);
     }
 
     abstract C withMinApiLevel(AndroidApiLevel minApiLevel);
@@ -368,7 +375,7 @@
     test("lambdadesugaring", "lambdadesugaring", "LambdaDesugaring")
         .withMinApiLevel(ToolHelper.getMinApiLevelForDexVmNoHigherThan(AndroidApiLevel.K))
         .withKeepAll()
-        .run();
+        .run(Paths.get(ToolHelper.THIRD_PARTY_DIR, "examplesAndroidOLegacy"));
   }
 
   @Test
@@ -599,6 +606,7 @@
         .addLibraryFiles(ToolHelper.getAndroidJar(minApi))
         .setIntermediate(true)
         .addProgramFiles(input);
+    visitFiles(getLegacyClassesRoot(input, packageName), command::addProgramFiles);
     ToolHelper.runD8(command, option -> {
       option.interfaceMethodDesugaring = OffOrAuto.Auto;
     });
@@ -645,7 +653,9 @@
         javaArgs.add(0, qualifiedMainClass);
         ToolHelper.ProcessResult javaResult =
             ToolHelper.runJava(
-                ImmutableList.copyOf(jars), javaArgs.toArray(StringUtils.EMPTY_ARRAY));
+                CfRuntime.getCheckedInJdk11(),
+                ImmutableList.copyOf(jars),
+                javaArgs.toArray(StringUtils.EMPTY_ARRAY));
         assertEquals("JVM run failed", javaResult.exitCode, 0);
         assertTrue(
             "JVM output does not match art output.\n\tjvm: "
@@ -671,4 +681,25 @@
     }
   }
 
+  protected Path getLegacyClassesRoot(Path testJarFile, String packageName) {
+    Path parent = testJarFile.getParent();
+    return Paths.get(
+        ToolHelper.THIRD_PARTY_DIR, parent.getFileName().toString() + "Legacy", packageName);
+  }
+
+  public void visitFiles(Path dir, Consumer<Path> consumer) {
+    if (Files.exists(dir)) {
+      try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
+        for (Path entry : stream) {
+          if (Files.isDirectory(entry)) {
+            visitFiles(entry, consumer);
+          } else {
+            consumer.accept(entry);
+          }
+        }
+      } catch (IOException x) {
+        throw new AssertionError(x);
+      }
+    }
+  }
 }
diff --git a/third_party/examplesAndroidOLegacy.tar.gz.sha1 b/third_party/examplesAndroidOLegacy.tar.gz.sha1
new file mode 100644
index 0000000..6a750e4
--- /dev/null
+++ b/third_party/examplesAndroidOLegacy.tar.gz.sha1
@@ -0,0 +1 @@
+8b3f21b30f966d72d47925f2156e4912d9e68d97
\ No newline at end of file