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)
+}