[Metadata] Add test for rewriting unit, primitives and arrays
Bug: 196179629
Change-Id: Ibad79cecd75cb8c0c9c6d95a532d3ca9efa7f5e6
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteUnitPrimitiveTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteUnitPrimitiveTest.java
new file mode 100644
index 0000000..66760d1
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteUnitPrimitiveTest.java
@@ -0,0 +1,159 @@
+// Copyright (c) 2021, 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.KotlinCompilerVersion.MIN_SUPPORTED_VERSION;
+import static com.android.tools.r8.ToolHelper.KotlinTargetVersion.JAVA_8;
+import static com.android.tools.r8.ToolHelper.getKotlinAnnotationJar;
+import static com.android.tools.r8.ToolHelper.getKotlinReflectJar;
+import static com.android.tools.r8.ToolHelper.getKotlinStdlibJar;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertNull;
+
+import com.android.tools.r8.KotlinTestParameters;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.shaking.ProguardKeepAttributes;
+import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Collection;
+import junit.framework.TestCase;
+import kotlinx.metadata.jvm.KotlinClassHeader;
+import kotlinx.metadata.jvm.KotlinClassMetadata;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class MetadataRewriteUnitPrimitiveTest extends KotlinMetadataTestBase {
+
+ private static final String PKG_LIB = PKG + ".unit_primitive_lib";
+ private static final String PKG_APP = PKG + ".unit_primitive_app";
+ private final TestParameters parameters;
+
+ private static final String EXPECTED =
+ StringUtils.lines(
+ "fun " + PKG_LIB + ".Lib.testInt(): kotlin.Int",
+ "42",
+ "fun " + PKG_LIB + ".Lib.testIntArray(): kotlin.IntArray",
+ "42",
+ "fun " + PKG_LIB + ".Lib.testUInt(): kotlin.UInt",
+ "42",
+ "fun " + PKG_LIB + ".Lib.testUIntArray(): kotlin.UIntArray",
+ "UIntArray(storage=[42])",
+ "fun " + PKG_LIB + ".Lib.testUnit(): kotlin.Unit",
+ "testUnit",
+ "kotlin.Unit");
+
+ @Parameterized.Parameters(name = "{0}, {1}")
+ public static Collection<Object[]> data() {
+ return buildParameters(
+ getTestParameters().withCfRuntimes().build(),
+ getKotlinTestParameters()
+ .withCompilersStartingFromIncluding(MIN_SUPPORTED_VERSION)
+ .withTargetVersion(JAVA_8)
+ .build());
+ }
+
+ public MetadataRewriteUnitPrimitiveTest(
+ TestParameters parameters, KotlinTestParameters kotlinParameters) {
+ super(kotlinParameters);
+ this.parameters = parameters;
+ }
+
+ private static final KotlinCompileMemoizer kotlincLibJar =
+ getCompileMemoizer(
+ getKotlinFileInTest(DescriptorUtils.getBinaryNameFromJavaType(PKG_LIB), "lib"));
+
+ @Test
+ public void smokeTest() throws Exception {
+ Path output =
+ kotlinc(parameters.getRuntime().asCf(), kotlinc, targetVersion)
+ .addClasspathFiles(kotlincLibJar.getForConfiguration(kotlinc, targetVersion))
+ .addSourceFiles(
+ getKotlinFileInTest(DescriptorUtils.getBinaryNameFromJavaType(PKG_APP), "main"))
+ .setOutputPath(temp.newFolder().toPath())
+ .compile();
+ testForJvm()
+ .addRunClasspathFiles(
+ getKotlinStdlibJar(kotlinc),
+ getKotlinReflectJar(kotlinc),
+ kotlincLibJar.getForConfiguration(kotlinc, targetVersion))
+ .addClasspath(output)
+ .run(parameters.getRuntime(), PKG_APP + ".MainKt")
+ .assertSuccessWithOutput(EXPECTED);
+ }
+
+ @Test
+ public void testMetadataForLib() throws Exception {
+ Path libJar =
+ testForR8(parameters.getBackend())
+ .addClasspathFiles(getKotlinAnnotationJar(kotlinc))
+ .addProgramFiles(
+ kotlincLibJar.getForConfiguration(kotlinc, targetVersion),
+ getKotlinStdlibJar(kotlinc))
+ .addKeepClassAndMembersRules(PKG_LIB + ".*")
+ .addKeepAttributes(
+ ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS,
+ ProguardKeepAttributes.SIGNATURE,
+ ProguardKeepAttributes.INNER_CLASSES,
+ ProguardKeepAttributes.ENCLOSING_METHOD)
+ .addKeepKotlinMetadata()
+ .allowDiagnosticWarningMessages()
+ .compile()
+ .assertAllWarningMessagesMatch(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
+ .inspect(this::inspect)
+ .writeToZip();
+ Path main =
+ kotlinc(parameters.getRuntime().asCf(), kotlinc, targetVersion)
+ .addClasspathFiles(libJar)
+ .addSourceFiles(
+ getKotlinFileInTest(DescriptorUtils.getBinaryNameFromJavaType(PKG_APP), "main"))
+ .setOutputPath(temp.newFolder().toPath())
+ .compile();
+ testForJvm()
+ .addRunClasspathFiles(
+ getKotlinStdlibJar(kotlinc), ToolHelper.getKotlinReflectJar(kotlinc), libJar)
+ .addClasspath(main)
+ .run(parameters.getRuntime(), PKG_APP + ".MainKt")
+ // TODO(b/196179629): Should not fail.
+ .assertFailureWithErrorThatMatches(
+ containsString("Could not compute caller for function: public final fun testUnit()"));
+ }
+
+ private void inspect(CodeInspector inspector) throws IOException {
+ CodeInspector stdLibInspector =
+ new CodeInspector(kotlincLibJar.getForConfiguration(kotlinc, targetVersion));
+ for (FoundClassSubject clazzSubject : stdLibInspector.allClasses()) {
+ ClassSubject r8Clazz = inspector.clazz(clazzSubject.getOriginalName());
+ assertThat(r8Clazz, isPresent());
+ KotlinClassMetadata originalMetadata = clazzSubject.getKotlinClassMetadata();
+ KotlinClassMetadata rewrittenMetadata = r8Clazz.getKotlinClassMetadata();
+ if (originalMetadata == null) {
+ assertNull(rewrittenMetadata);
+ continue;
+ }
+ TestCase.assertNotNull(rewrittenMetadata);
+ KotlinClassHeader originalHeader = originalMetadata.getHeader();
+ KotlinClassHeader rewrittenHeader = rewrittenMetadata.getHeader();
+ TestCase.assertEquals(originalHeader.getKind(), rewrittenHeader.getKind());
+ TestCase.assertEquals(originalHeader.getPackageName(), rewrittenHeader.getPackageName());
+ // TODO(b/196179629): There should not be any rewriting of the data since the return type
+ // should not change. Therefore we should be able to assert everything to be equal.
+ Assert.assertNotEquals(originalHeader.getData1(), rewrittenHeader.getData1());
+ Assert.assertNotEquals(originalHeader.getData2(), rewrittenHeader.getData2());
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/unit_primitive_app/main.kt b/src/test/java/com/android/tools/r8/kotlin/metadata/unit_primitive_app/main.kt
new file mode 100644
index 0000000..b3d5d3c
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/unit_primitive_app/main.kt
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, 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.unit_primitive_app
+
+import com.android.tools.r8.kotlin.metadata.unit_primitive_lib.Lib
+import kotlin.reflect.full.declaredFunctions
+
+fun main() {
+ var lib = Lib();
+ lib::class.declaredFunctions.forEach({
+ println(it)
+ var msg = it.call(lib)
+ if (msg is IntArray) {
+ println(msg[0])
+ } else {
+ println(msg)
+ }
+ })
+}
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/unit_primitive_lib/lib.kt b/src/test/java/com/android/tools/r8/kotlin/metadata/unit_primitive_lib/lib.kt
new file mode 100644
index 0000000..65ae861
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/unit_primitive_lib/lib.kt
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, 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.unit_primitive_lib
+
+class Lib {
+ fun testUnit() : Unit {
+ println("testUnit")
+ }
+
+ fun testInt() : Int {
+ return 42
+ }
+
+ fun testIntArray() : IntArray {
+ return intArrayOf(42)
+ }
+
+ fun testUInt() : UInt {
+ return 42u
+ }
+
+ fun testUIntArray() : UIntArray {
+ return uintArrayOf(42u)
+ }
+}