Internalize compilation of debug kotlin tests

This CL removes the compilation of debugTestResourcesKotlin and moves
all of the files into kotlinR8TestResources. Additionally, the kotlin
files are now compiled when needed by the tests by passing in the
kotlin compilation and target.

Bug: 174292935
Change-Id: I98a01a91ea3db61e917b03214544483762bc6ccd
diff --git a/build.gradle b/build.gradle
index f4881c2..1077080 100644
--- a/build.gradle
+++ b/build.gradle
@@ -108,12 +108,6 @@
         }
         output.resourcesDir = 'build/classes/debugTestResourcesJava8'
     }
-    debugTestResourcesKotlin {
-        java {
-            srcDirs = ['src/test/debugTestResourcesKotlin']
-        }
-        output.resourcesDir = 'build/classes/debugTestResourcesKotlin'
-    }
     examples {
         java {
             srcDirs = ['src/test/examples']
@@ -280,7 +274,6 @@
     supportLibs "com.android.support.test.espresso:espresso-core:$espressoVersion"
     apiUsageSampleCompile sourceSets.main.output
     apiUsageSampleCompile "com.google.guava:guava:$guavaVersion"
-    debugTestResourcesKotlinCompileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
     examplesKotlinCompileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
     kotlinR8TestResourcesCompileOnly "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
     errorprone("com.google.errorprone:error_prone_core:$errorproneVersion")
@@ -1222,16 +1215,9 @@
         from "build/test/debugTestResourcesJava8/classes"
         include "**/*.class"
     }
-    def kotlinResourcesDir = file("src/test/debugTestResourcesKotlin")
-    def kotlinHostJar = "debug_test_resources_kotlin.jar"
-    task "jar_debugTestResourcesKotlin"(type: kotlin.Kotlinc, dependsOn: downloadDeps) {
-        source = fileTree(dir: kotlinResourcesDir, include: '**/*.kt')
-        destination = file("build/test/${kotlinHostJar}")
-    }
     dependsOn downloadDeps
     dependsOn jar_debugTestResources
     dependsOn jar_debugTestResourcesJava8
-    dependsOn jar_debugTestResourcesKotlin
 }
 
 // Examples used by tests, where Android specific APIs are used.
diff --git a/src/test/java/com/android/tools/r8/KotlinTestBase.java b/src/test/java/com/android/tools/r8/KotlinTestBase.java
index f018f74..37f4222 100644
--- a/src/test/java/com/android/tools/r8/KotlinTestBase.java
+++ b/src/test/java/com/android/tools/r8/KotlinTestBase.java
@@ -66,11 +66,11 @@
     return Paths.get(ToolHelper.TESTS_DIR, "java", folder, fileName + FileUtils.KT_EXTENSION);
   }
 
-  protected static Path getKotlinFileInResource(String folder, String fileName) {
+  public static Path getKotlinFileInResource(String folder, String fileName) {
     return Paths.get(ToolHelper.TESTS_DIR, RSRC, folder, fileName + FileUtils.KT_EXTENSION);
   }
 
-  protected static List<Path> getKotlinFilesInResource(String folder) {
+  public static List<Path> getKotlinFilesInResource(String folder) {
     try {
       return Files.walk(Paths.get(ToolHelper.TESTS_DIR, RSRC, folder))
           .filter(path -> path.toString().endsWith(".kt") || path.toString().endsWith(".java"))
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index cf27791..e638abf 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -404,7 +404,7 @@
     return KotlinTestParameters.builder();
   }
 
-  protected static <S, T, E extends Throwable> Function<S, T> memoizeFunction(
+  public static <S, T, E extends Throwable> Function<S, T> memoizeFunction(
       ThrowingFunction<S, T, E> fn) {
     return CacheBuilder.newBuilder()
         .build(
@@ -418,7 +418,7 @@
                 }));
   }
 
-  protected static <S, T, U, E extends Throwable> BiFunction<S, T, U> memoizeBiFunction(
+  public static <S, T, U, E extends Throwable> BiFunction<S, T, U> memoizeBiFunction(
       ThrowingBiFunction<S, T, U, E> fn) {
     class Pair {
       final S first;
diff --git a/src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java b/src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java
index 069a504..4552be6 100644
--- a/src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java
+++ b/src/test/java/com/android/tools/r8/debug/ContinuousSteppingTest.java
@@ -4,6 +4,8 @@
 
 package com.android.tools.r8.debug;
 
+import com.android.tools.r8.KotlinTestParameters;
+import com.android.tools.r8.TestBase;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.ToolHelper.DexVm.Version;
 import com.android.tools.r8.utils.DescriptorUtils;
@@ -32,9 +34,10 @@
 import java.util.jar.JarInputStream;
 import java.util.stream.Collectors;
 import org.apache.harmony.jpda.tests.framework.jdwp.Value;
+import org.junit.AfterClass;
 import org.junit.Assert;
-import org.junit.BeforeClass;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
@@ -44,17 +47,22 @@
 
   private static final String MAIN_METHOD_NAME = "main";
 
+  private static final TemporaryFolder testTemp = ToolHelper.getTemporaryFolderForTest();
+
   // A list of self-contained jars to process (which do not depend on other jar files).
-  private static final List<Pair<Path, Predicate<Version>>> LIST_OF_JARS = new ConfigListBuilder()
-      .add(DebugTestBase.DEBUGGEE_JAR, ContinuousSteppingTest::allVersions)
-      .add(DebugTestBase.DEBUGGEE_JAVA8_JAR, ContinuousSteppingTest::allVersions)
-      .add(KotlinD8Config.DEBUGGEE_KOTLIN_JAR, ContinuousSteppingTest::allVersions)
-      .addAll(findAllJarsIn(Paths.get(ToolHelper.EXAMPLES_ANDROID_N_BUILD_DIR)),
-          ContinuousSteppingTest::fromAndroidN)
-      // TODO(b/79911828) Investigate timeout issues for Android O examples.
-      //  .addAll(findAllJarsIn(Paths.get(ToolHelper.EXAMPLES_ANDROID_O_BUILD_DIR)),
-      //      ContinuousSteppingTest::fromAndroidO)
-      .build();
+  private static List<Pair<Path, Predicate<Version>>> listOfJars() {
+    return new ConfigListBuilder()
+        .add(DebugTestBase.DEBUGGEE_JAR, ContinuousSteppingTest::allVersions)
+        .add(DebugTestBase.DEBUGGEE_JAVA8_JAR, ContinuousSteppingTest::allVersions)
+        .addAllKotlinDebugJars(testTemp, ContinuousSteppingTest::allVersions)
+        .addAll(
+            findAllJarsIn(Paths.get(ToolHelper.EXAMPLES_ANDROID_N_BUILD_DIR)),
+            ContinuousSteppingTest::fromAndroidN)
+        // TODO(b/79911828) Investigate timeout issues for Android O examples.
+        //  .addAll(findAllJarsIn(Paths.get(ToolHelper.EXAMPLES_ANDROID_O_BUILD_DIR)),
+        //      ContinuousSteppingTest::fromAndroidO)
+        .build();
+  }
 
   private static final Map<Path, DebugTestConfig> compiledJarConfig = new HashMap<>();
 
@@ -77,6 +85,15 @@
       return this;
     }
 
+    public ConfigListBuilder addAllKotlinDebugJars(
+        TemporaryFolder temp, Predicate<Version> predicate) {
+      for (KotlinTestParameters kotlinParameter :
+          TestBase.getKotlinTestParameters().withAllCompilersAndTargetVersions().build()) {
+        add(KotlinD8Config.compileKotlinMemoized.apply(temp, kotlinParameter), predicate);
+      }
+      return this;
+    }
+
     public List<Pair<Path, Predicate<Version>>> build() {
       return builder.build();
     }
@@ -100,27 +117,25 @@
     }
   }
 
-  @BeforeClass
-  public static void setup() {
-    LIST_OF_JARS.forEach(pair -> {
-      if (pair.getSecond().test(ToolHelper.getDexVm().getVersion())) {
-        Path jarPath = pair.getFirst();
-        DebugTestConfig config = new D8DebugTestConfig().compileAndAdd(temp, jarPath);
-        compiledJarConfig.put(jarPath, config);
-      }
-    });
+  @AfterClass
+  public static void tearDown() {
+    testTemp.delete();
   }
 
   @Parameters(name = "{0} from {1}")
   public static Collection<Object[]> getData() throws IOException {
+    testTemp.create();
     List<Object[]> testCases = new ArrayList<>();
-    for (Pair<Path, Predicate<Version>> pair : LIST_OF_JARS) {
+    for (Pair<Path, Predicate<Version>> pair : listOfJars()) {
       if (pair.getSecond().test(ToolHelper.getDexVm().getVersion())) {
         Path jarPath = pair.getFirst();
         List<String> mainClasses = getAllMainClassesFromJar(jarPath);
         for (String className : mainClasses) {
           testCases.add(new Object[]{className, jarPath});
         }
+
+        DebugTestConfig config = new D8DebugTestConfig().compileAndAdd(testTemp, jarPath);
+        compiledJarConfig.put(jarPath, config);
       }
     }
     return testCases;
diff --git a/src/test/java/com/android/tools/r8/debug/D8DebugTestConfig.java b/src/test/java/com/android/tools/r8/debug/D8DebugTestConfig.java
index 1f13006..ef2205a 100644
--- a/src/test/java/com/android/tools/r8/debug/D8DebugTestConfig.java
+++ b/src/test/java/com/android/tools/r8/debug/D8DebugTestConfig.java
@@ -20,16 +20,22 @@
 /** Test configuration with utilities for compiling with D8 and adding results to the classpath. */
 public class D8DebugTestConfig extends DexDebugTestConfig {
 
+  // Use the option with api-level below.
+  @Deprecated()
   public static AndroidApp d8Compile(List<Path> paths, Consumer<InternalOptions> optionsConsumer) {
+    return d8Compile(paths, ToolHelper.getMinApiLevelForDexVm(), optionsConsumer);
+  }
+
+  public static AndroidApp d8Compile(
+      List<Path> paths, AndroidApiLevel apiLevel, Consumer<InternalOptions> optionsConsumer) {
     try {
-      AndroidApiLevel minSdk = ToolHelper.getMinApiLevelForDexVm();
       D8Command.Builder builder = D8Command.builder();
       return ToolHelper.runD8(
           builder
               .addProgramFiles(paths)
-              .setMinApiLevel(minSdk.getLevel())
+              .setMinApiLevel(apiLevel.getLevel())
               .setMode(CompilationMode.DEBUG)
-              .addLibraryFiles(ToolHelper.getAndroidJar(minSdk)),
+              .addLibraryFiles(ToolHelper.getAndroidJar(apiLevel)),
           optionsConsumer);
     } catch (Exception e) {
       throw new RuntimeException(e);
diff --git a/src/test/java/com/android/tools/r8/debug/KotlinD8Config.java b/src/test/java/com/android/tools/r8/debug/KotlinD8Config.java
index d828a5e..a7e31a4 100644
--- a/src/test/java/com/android/tools/r8/debug/KotlinD8Config.java
+++ b/src/test/java/com/android/tools/r8/debug/KotlinD8Config.java
@@ -4,39 +4,58 @@
 
 package com.android.tools.r8.debug;
 
+import static com.android.tools.r8.TestBase.kotlinc;
+import static com.android.tools.r8.TestBase.memoizeBiFunction;
+
+import com.android.tools.r8.KotlinTestBase;
+import com.android.tools.r8.KotlinTestParameters;
 import com.android.tools.r8.OutputMode;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestRuntime;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.io.IOException;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.Collections;
+import java.util.function.BiFunction;
 import org.junit.rules.TemporaryFolder;
 
-/**
- * Shared test configuration for D8 compiled resources from the "debugTestResourcesKotlin" target.
- */
+/** Shared test configuration for D8 compiled resources from the "kotlinR8TestResources/debug". */
 class KotlinD8Config extends D8DebugTestConfig {
 
-  public static final Path DEBUGGEE_KOTLIN_JAR =
-      Paths.get(ToolHelper.BUILD_DIR, "test", "debug_test_resources_kotlin.jar");
+  public static BiFunction<TemporaryFolder, KotlinTestParameters, Path> compileKotlinMemoized =
+      memoizeBiFunction(KotlinD8Config::compileWithKotlinC);
 
-  private static AndroidApp compiledResources = null;
-
-  private static synchronized AndroidApp getCompiledResources() throws Throwable {
-    if (compiledResources == null) {
-      compiledResources =
-          D8DebugTestConfig.d8Compile(
-              Collections.singletonList(DEBUGGEE_KOTLIN_JAR), null);
-    }
-    return compiledResources;
+  private static Path compileWithKotlinC(TemporaryFolder temp, KotlinTestParameters parameters)
+      throws IOException {
+    return kotlinc(
+            TestRuntime.getCheckedInJdk9(),
+            temp,
+            parameters.getCompiler(),
+            parameters.getTargetVersion())
+        .addSourceFiles(KotlinTestBase.getKotlinFilesInResource("debug"))
+        .includeRuntime()
+        .compile();
   }
 
-  public KotlinD8Config(TemporaryFolder temp) {
-    super();
+  private static BiFunction<KotlinTestParameters, AndroidApiLevel, Path> compiledResourcesMemoized =
+      memoizeBiFunction(KotlinD8Config::getCompiledResources);
+
+  private static Path getCompiledResources(
+      KotlinTestParameters kotlinTestParameters, AndroidApiLevel apiLevel) throws IOException {
+    Path outputPath =
+        TestBase.getStaticTemp().newFolder().toPath().resolve("d8_debug_test_resources_kotlin.jar");
+    Path kotlinJar = compileKotlinMemoized.apply(TestBase.getStaticTemp(), kotlinTestParameters);
+    D8DebugTestConfig.d8Compile(Collections.singletonList(kotlinJar), apiLevel, null)
+        .write(outputPath, OutputMode.DexIndexed);
+    return outputPath;
+  }
+
+  public static KotlinD8Config build(
+      KotlinTestParameters kotlinTestParameters, AndroidApiLevel apiLevel) {
     try {
-      Path out = temp.newFolder().toPath().resolve("d8_debug_test_resources_kotlin.jar");
-      getCompiledResources().write(out, OutputMode.DexIndexed);
-      addPaths(out);
+      KotlinD8Config kotlinD8Config = new KotlinD8Config();
+      kotlinD8Config.addPaths(compiledResourcesMemoized.apply(kotlinTestParameters, apiLevel));
+      return kotlinD8Config;
     } catch (Throwable e) {
       throw new RuntimeException(e);
     }
diff --git a/src/test/java/com/android/tools/r8/debug/KotlinInlineTest.java b/src/test/java/com/android/tools/r8/debug/KotlinInlineTest.java
index 894e7d5..00333e0 100644
--- a/src/test/java/com/android/tools/r8/debug/KotlinInlineTest.java
+++ b/src/test/java/com/android/tools/r8/debug/KotlinInlineTest.java
@@ -6,28 +6,41 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.KotlinTestParameters;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.kotlin.AbstractR8KotlinTestBase;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
+import java.util.List;
 import org.apache.harmony.jpda.tests.framework.jdwp.Value;
-import org.junit.BeforeClass;
 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 KotlinInlineTest extends KotlinDebugTestBase {
 
   public static final String DEBUGGEE_CLASS = "KotlinInline";
   public static final String SOURCE_FILE = "KotlinInline.kt";
 
-  private static KotlinD8Config d8Config;
+  private final TestParameters parameters;
+  private final KotlinTestParameters kotlinParameters;
 
-  @BeforeClass
-  public static void setup() {
-    d8Config = new KotlinD8Config(temp);
+  @Parameters(name = "{0}, {1}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withDexRuntimes().withAllApiLevels().build(),
+        getKotlinTestParameters().withAllCompilersAndTargetVersions().build());
+  }
+
+  public KotlinInlineTest(TestParameters parameters, KotlinTestParameters kotlinParameters) {
+    this.parameters = parameters;
+    this.kotlinParameters = kotlinParameters;
   }
 
   protected KotlinD8Config getD8Config() {
-    return d8Config;
+    return KotlinD8Config.build(kotlinParameters, parameters.getApiLevel());
   }
 
   @Test
@@ -242,7 +255,8 @@
   public void testNestedInlining() throws Throwable {
     // Count the number of lines in the source file. This is needed to check that inlined code
     // refers to non-existing line numbers.
-    Path sourceFilePath = Paths.get(ToolHelper.TESTS_DIR, "debugTestResourcesKotlin", SOURCE_FILE);
+    Path sourceFilePath =
+        AbstractR8KotlinTestBase.getKotlinFileInResource("debug", SOURCE_FILE.replace(".kt", ""));
     assert sourceFilePath.toFile().exists();
     final int maxLineNumber = Files.readAllLines(sourceFilePath).size();
     final String inliningMethodName = "testNestedInlining";
diff --git a/src/test/java/com/android/tools/r8/debug/KotlinTest.java b/src/test/java/com/android/tools/r8/debug/KotlinTest.java
index f1482fb..07e9e05 100644
--- a/src/test/java/com/android/tools/r8/debug/KotlinTest.java
+++ b/src/test/java/com/android/tools/r8/debug/KotlinTest.java
@@ -5,21 +5,35 @@
 
 import static org.junit.Assert.assertEquals;
 
+import com.android.tools.r8.KotlinTestParameters;
+import com.android.tools.r8.TestParameters;
+import java.util.List;
 import org.apache.harmony.jpda.tests.framework.jdwp.Value;
-import org.junit.BeforeClass;
 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 KotlinTest extends KotlinDebugTestBase {
 
-  private static KotlinD8Config d8Config;
+  private final TestParameters parameters;
+  private final KotlinTestParameters kotlinParameters;
 
-  @BeforeClass
-  public static void setup() {
-    d8Config = new KotlinD8Config(temp);
+  @Parameters(name = "{0}, {1}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withDexRuntimes().withAllApiLevels().build(),
+        getKotlinTestParameters().withAllCompilersAndTargetVersions().build());
+  }
+
+  public KotlinTest(TestParameters parameters, KotlinTestParameters kotlinParameters) {
+    this.parameters = parameters;
+    this.kotlinParameters = kotlinParameters;
   }
 
   protected KotlinD8Config getD8Config() {
-    return d8Config;
+    return KotlinD8Config.build(kotlinParameters, parameters.getApiLevel());
   }
 
   // TODO(shertz) simplify test
diff --git a/src/test/debugTestResourcesKotlin/KotlinApp.kt b/src/test/kotlinR8TestResources/debug/KotlinApp.kt
similarity index 100%
rename from src/test/debugTestResourcesKotlin/KotlinApp.kt
rename to src/test/kotlinR8TestResources/debug/KotlinApp.kt
diff --git a/src/test/debugTestResourcesKotlin/KotlinInline.kt b/src/test/kotlinR8TestResources/debug/KotlinInline.kt
similarity index 100%
rename from src/test/debugTestResourcesKotlin/KotlinInline.kt
rename to src/test/kotlinR8TestResources/debug/KotlinInline.kt