Add test and fix for kotlin property with type-parameter
Bug: 153050655
Bug: 152715309
Change-Id: I74ef5bbc1b83da7d88c52845682792683f691833
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinClassifierInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinClassifierInfo.java
new file mode 100644
index 0000000..c7c3701
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClassifierInfo.java
@@ -0,0 +1,49 @@
+// 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;
+
+import kotlinx.metadata.KmClassifier;
+
+// Provides access to information about a kotlin classifier
+public class KotlinClassifierInfo {
+
+ private static boolean isClass(KmClassifier classifier) {
+ return classifier instanceof KmClassifier.Class;
+ }
+
+ private static KmClassifier.Class getClassClassifier(KmClassifier classifier) {
+ return (KmClassifier.Class) classifier;
+ }
+
+ private static boolean isTypeAlias(KmClassifier classifier) {
+ return classifier instanceof KmClassifier.TypeAlias;
+ }
+
+ private static KmClassifier.TypeAlias getTypeAlias(KmClassifier classifier) {
+ return (KmClassifier.TypeAlias) classifier;
+ }
+
+ private static boolean isTypeParameter(KmClassifier classifier) {
+ return classifier instanceof KmClassifier.TypeParameter;
+ }
+
+ private static KmClassifier.TypeParameter getTypeParameter(KmClassifier classifier) {
+ return (KmClassifier.TypeParameter) classifier;
+ }
+
+ public static boolean equals(KmClassifier one, KmClassifier other) {
+ if (isClass(one)) {
+ return isClass(other)
+ && getClassClassifier(one).getName().equals(getClassClassifier(other).getName());
+ }
+ if (isTypeAlias(one)) {
+ return isTypeAlias(other)
+ && getTypeAlias(one).getName().equals(getTypeAlias(other).getName());
+ }
+ assert isTypeParameter(one);
+ return isTypeParameter(other)
+ && getTypeParameter(one).getId() == getTypeParameter(other).getId();
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizer.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizer.java
index 65d7f7e..bed05c0 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizer.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizer.java
@@ -10,7 +10,6 @@
import static com.android.tools.r8.kotlin.KotlinMetadataSynthesizerUtils.toClassifier;
import static com.android.tools.r8.utils.DescriptorUtils.descriptorToKotlinClassifier;
import static com.android.tools.r8.utils.DescriptorUtils.getBinaryNameFromDescriptor;
-import static com.android.tools.r8.utils.DescriptorUtils.getDescriptorFromKmType;
import static kotlinx.metadata.Flag.Property.IS_VAR;
import static kotlinx.metadata.FlagsKt.flagsOf;
@@ -599,8 +598,8 @@
synthesizer.toRenamedKmType(receiverType, receiverSignature, null, typeParameters);
if (kmProperty.getReceiverParameterType() != null) {
// If the receiver type for the extension property is set already make sure it's consistent.
- return getDescriptorFromKmType(kmReceiverType)
- .equals(getDescriptorFromKmType(kmProperty.getReceiverParameterType()));
+ return KotlinMetadataSynthesizerUtils.hasEqualClassifier(
+ kmReceiverType, kmProperty.getReceiverParameterType());
}
kmProperty.setReceiverParameterType(kmReceiverType);
return true;
@@ -644,8 +643,8 @@
if (kmProperty.getReturnType() == defaultPropertyType) {
// The property type is not set yet.
kmProperty.setReturnType(kmPropertyType);
- } else if (!getDescriptorFromKmType(kmPropertyType)
- .equals(getDescriptorFromKmType(kmProperty.getReturnType()))) {
+ } else if (!KotlinMetadataSynthesizerUtils.hasEqualClassifier(
+ kmPropertyType, kmProperty.getReturnType())) {
// If property type is set already (via backing field), make sure it's consistent.
return null;
}
@@ -700,8 +699,8 @@
kmProperty.setReturnType(kmPropertyType);
} else {
// If property type is set already make sure it's consistent.
- if (!getDescriptorFromKmType(kmPropertyType)
- .equals(getDescriptorFromKmType(kmProperty.getReturnType()))) {
+ if (!KotlinMetadataSynthesizerUtils.hasEqualClassifier(
+ kmPropertyType, kmProperty.getReturnType())) {
return null;
}
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizerUtils.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizerUtils.java
index 3b04e91..e773cef 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizerUtils.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizerUtils.java
@@ -20,6 +20,7 @@
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
+import kotlinx.metadata.KmType;
import kotlinx.metadata.KmTypeParameter;
import kotlinx.metadata.KmTypeVisitor;
import kotlinx.metadata.KmVariance;
@@ -276,4 +277,14 @@
factory,
AddKotlinAnyType.DISREGARD);
}
+
+ public static boolean hasEqualClassifier(KmType one, KmType other) {
+ if (one == null && other == null) {
+ return true;
+ }
+ if (one == null || other == null) {
+ return false;
+ }
+ return KotlinClassifierInfo.equals(one.classifier, other.classifier);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java b/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java
index 6aca533..de25a3b 100644
--- a/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java
@@ -17,8 +17,6 @@
import java.io.File;
import java.nio.file.Path;
import java.util.Map;
-import kotlinx.metadata.KmType;
-import kotlinx.metadata.KmTypeVisitor;
public class DescriptorUtils {
@@ -379,36 +377,6 @@
}
/**
- * Get a fully qualified name from a classifier in Kotlin metadata.
- * @param kmType where classifier contains Kotlin internal name, like "org/foo/bar/Baz.Nested"
- * @return a class descriptor like "Lorg/foo/bar/Baz$Nested;"
- */
- public static String getDescriptorFromKmType(KmType kmType) {
- if (kmType == null) {
- return null;
- }
- Box<String> descriptor = new Box<>(null);
- kmType.accept(new KmTypeVisitor() {
- @Override
- public void visitClass(String name) {
- // TODO(b/151195430): Remove this if metadata lib is resilient to namespace relocation.
- // See b/70169921#comment25 for more details.
- assert descriptor.get() == null : descriptor.get();
- descriptor.set(getDescriptorFromKotlinClassifier(backwardRelocatedName(name)));
- }
-
- @Override
- public void visitTypeAlias(String name) {
- // TODO(b/151195430): Remove this if metadata lib is resilient to namespace relocation.
- // See b/70169921#comment25 for more details.
- assert descriptor.get() == null : descriptor.get();
- descriptor.set(getDescriptorFromKotlinClassifier(backwardRelocatedName(name)));
- }
- });
- return descriptor.get();
- }
-
- /**
* Get unqualified class name from its binary name.
*
* @param classBinaryName a class binary name i.e. "java/lang/Object" or "a/b/C$Inner"
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
index 365bcb1..a158b99 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeArgumentsTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInTypeArgumentsTest.java
@@ -74,7 +74,9 @@
"3",
"7",
"9",
- "42");
+ "42",
+ "42",
+ "7");
private final TestParameters parameters;
@@ -131,6 +133,7 @@
.addKeepRules("-keep,allowobfuscation class **ClassThatWillBeObfuscated")
.addKeepRules("-keepclassmembers class **ClassThatWillBeObfuscated { *; }")
// Keep all other classes.
+ .addKeepRules("-keep class **typeargument_lib.PlainBox { *; }")
.addKeepRules("-keep class **typeargument_lib.SomeClass { *; }")
.addKeepRules("-keep class **typeargument_lib.CoVariant { *; }")
.addKeepRules("-keep class **typeargument_lib.ContraVariant { *; }")
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
index e94ab44..2129081 100644
--- 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
@@ -7,6 +7,7 @@
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.PlainBox
import com.android.tools.r8.kotlin.metadata.typeargument_lib.SomeClass
import com.android.tools.r8.kotlin.metadata.typeargument_lib.asList
import com.android.tools.r8.kotlin.metadata.typeargument_lib.asListWithVarargs
@@ -60,9 +61,17 @@
println(CoVariant(42).asStar().t)
}
+fun testPlainBox() {
+ var plainBox = PlainBox(42)
+ println(plainBox.plainBox)
+ plainBox.plainBox = 7
+ println(plainBox.plainBox)
+}
+
fun main() {
testInvariant()
testCoVariant()
testContraVariant();
testExtension()
+ testPlainBox()
}
\ 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
index 85af523..d9d3bea 100644
--- 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
@@ -6,6 +6,8 @@
open class SomeClass
+class PlainBox<T>(var plainBox : T)
+
class ClassThatWillBeObfuscated(val x : Int)
class Invariant<T, C> {