Add kotlin metadata tests for type-arguments

We are stripping most type-arguments since we are never synthesizing
them. The tests added here will show that we cannot directly infer
them from the signatures, since we do not know there variance.

Bug: 151925520
Change-Id: I0a5adeddeddd3909a22432ad49ddc5b524385b2a
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeArgumentsTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeArgumentsTest.java
new file mode 100644
index 0000000..07fbdd9
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeArgumentsTest.java
@@ -0,0 +1,99 @@
+// Copyright (c) 2020, 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 com.android.tools.r8.kotlin.metadata;
+
+import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertNotEquals;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
+import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.utils.StringUtils;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class MetadataRewriteInTypeArgumentsTest extends KotlinMetadataTestBase {
+  private static final String EXPECTED =
+      StringUtils.lines("42", "1", "42", "42", "1", "42", "42", "42", "1", "42");
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0} target: {1}")
+  public static Collection<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withCfRuntimes().build(), KotlinTargetVersion.values());
+  }
+
+  public MetadataRewriteInTypeArgumentsTest(
+      TestParameters parameters, KotlinTargetVersion targetVersion) {
+    super(targetVersion);
+    this.parameters = parameters;
+  }
+
+  private static final Map<KotlinTargetVersion, Path> jarMap = new HashMap<>();
+
+  @BeforeClass
+  public static void createLibJar() throws Exception {
+    String typeAliasLibFolder = PKG_PREFIX + "/typeargument_lib";
+    for (KotlinTargetVersion targetVersion : KotlinTargetVersion.values()) {
+      Path typeAliasLibJar =
+          kotlinc(KOTLINC, targetVersion)
+              .addSourceFiles(getKotlinFileInTest(typeAliasLibFolder, "lib"))
+              .compile();
+      jarMap.put(targetVersion, typeAliasLibJar);
+    }
+  }
+
+  @Test
+  public void smokeTest() throws Exception {
+    Path libJar = jarMap.get(targetVersion);
+
+    Path output =
+        kotlinc(parameters.getRuntime().asCf(), KOTLINC, targetVersion)
+            .addClasspathFiles(libJar)
+            .addSourceFiles(getKotlinFileInTest(PKG_PREFIX + "/typeargument_app", "main"))
+            .setOutputPath(temp.newFolder().toPath())
+            .compile();
+
+    testForJvm()
+        .addRunClasspathFiles(ToolHelper.getKotlinStdlibJar(), libJar)
+        .addClasspath(output)
+        .run(parameters.getRuntime(), PKG + ".typeargument_app.MainKt")
+        .assertSuccessWithOutput(EXPECTED);
+  }
+
+  @Test
+  public void testMetadataInTypeAlias_renamed() throws Exception {
+    Path libJar =
+        testForR8(parameters.getBackend())
+            .addProgramFiles(jarMap.get(targetVersion))
+            .addKeepAllClassesRule()
+            .compile()
+            // TODO(b/151925520): Add inspections when program compiles
+            .writeToZip();
+
+    ProcessResult kotlinTestCompileResult =
+        kotlinc(parameters.getRuntime().asCf(), KOTLINC, targetVersion)
+            .addClasspathFiles(libJar)
+            .addSourceFiles(getKotlinFileInTest(PKG_PREFIX + "/typeargument_app", "main"))
+            .setOutputPath(temp.newFolder().toPath())
+            // TODO(b/151925520): update to just .compile() once fixed.
+            .compileRaw();
+    // TODO(b/151925520): should be able to compile!
+    assertNotEquals(0, kotlinTestCompileResult.exitCode);
+    assertThat(
+        kotlinTestCompileResult.stderr,
+        containsString("no type arguments expected for constructor Invariant()"));
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/typeargument_app/main.kt b/src/test/java/com/android/tools/r8/kotlin/metadata/typeargument_app/main.kt
new file mode 100644
index 0000000..7fc2b69
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/typeargument_app/main.kt
@@ -0,0 +1,53 @@
+// Copyright (c) 2020, 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 com.android.tools.r8.kotlin.metadata.typeargument_app
+
+import com.android.tools.r8.kotlin.metadata.typeargument_lib.CoVariant
+import com.android.tools.r8.kotlin.metadata.typeargument_lib.ContraVariant
+import com.android.tools.r8.kotlin.metadata.typeargument_lib.Invariant
+import com.android.tools.r8.kotlin.metadata.typeargument_lib.SomeClass
+import com.android.tools.r8.kotlin.metadata.typeargument_lib.unBoxAndBox
+import com.android.tools.r8.kotlin.metadata.typeargument_lib.update
+
+class SomeSubClass(val x : Int) : SomeClass(), Comparable<SomeClass> {
+
+  override fun compareTo(other: SomeClass): Int {
+    if (other !is SomeSubClass) {
+      return -1;
+    }
+    return x.compareTo(other.x);
+  }
+}
+
+fun testInvariant() {
+  val subtype1 = SomeSubClass(42)
+  val subtype2 = SomeSubClass(1)
+  val inv = Invariant<SomeSubClass>()
+  println(inv.classGenerics(subtype1).x)
+  println(inv.funGenerics(subtype2).x)
+  println(inv.funGenericsWithUpperBound(subtype1).x)
+  println(inv.funGenericsWithUpperBounds(subtype1, subtype2).x)
+  println(inv.mixedGenerics(subtype2).x)
+}
+
+fun testCoVariant() {
+ println(CoVariant(42).classGenerics().t)
+}
+
+fun testContraVariant() {
+  ContraVariant<Number>().classGenerics(42)
+}
+
+fun testExtension() {
+  println(CoVariant(42).unBoxAndBox().t)
+  println(CoVariant(1).update(42).t)
+}
+
+fun main() {
+  testInvariant()
+  testCoVariant()
+  testContraVariant();
+  testExtension()
+}
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/typeargument_lib/lib.kt b/src/test/java/com/android/tools/r8/kotlin/metadata/typeargument_lib/lib.kt
new file mode 100644
index 0000000..7c8b6cb
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/typeargument_lib/lib.kt
@@ -0,0 +1,63 @@
+// Copyright (c) 2020, 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 com.android.tools.r8.kotlin.metadata.typeargument_lib
+
+open class SomeClass
+
+class Invariant<T> {
+
+  fun classGenerics(t : T) : T {
+    return t
+  }
+
+  fun <R> funGenerics(r : R) : R {
+    return r
+  }
+
+  fun <R : SomeClass> funGenericsWithUpperBound(r : R) : R {
+    return r;
+  }
+
+  fun <R> funGenericsWithUpperBounds(r1 : R, r2 : R) : R
+    where R : SomeClass,
+          R : Comparable<SomeClass> {
+    return when {
+      r1 > r2 -> {
+        r1;
+      }
+      else -> {
+        r2;
+      }
+    }
+  }
+
+  fun <R : T> mixedGenerics(r : R) : T {
+    return r;
+  }
+}
+
+class CoVariant<out T>(val t : T) {
+
+  fun classGenerics() : CoVariant<T> {
+    return CoVariant(t);
+  }
+}
+
+class ContraVariant<in T> {
+
+  fun classGenerics(t : T) {
+    println(t)
+  }
+}
+
+
+fun <T> CoVariant<T>.unBoxAndBox() : CoVariant<T> {
+  return CoVariant(this.t)
+}
+
+fun <T, R> CoVariant<R>.update(t : T) : CoVariant<T> {
+  println(this.t)
+  return CoVariant(t)
+}