Fix KotlinTypeReference and KotlinClassifiers
KotlinTypeReference can now hold either a binary name or
a kotlin classifier, the output should match the input to
avoid changing identical metadata.
Bug: b/302999098
Change-Id: Ic1044c747dc76b9d00edb3ea1f9a8031818b3383
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeReference.java b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeReference.java
index ecf67fa..700b508 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeReference.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeReference.java
@@ -25,15 +25,22 @@
private final DexType known;
private final String originalName;
+ // A KotlinTypeReference may be either a Kotlin classifier or a binary name.
+ // We need to maintain the right type to avoid unnecessary difference between original and
+ // rewritten metadata.
+ private final boolean exportAsKotlinClassifier;
- private KotlinTypeReference(String originalName, DexType known) {
+ private KotlinTypeReference(
+ String originalName, DexType known, boolean exportAsKotlinClassifier) {
this.originalName = originalName;
this.known = known;
+ this.exportAsKotlinClassifier = exportAsKotlinClassifier;
assert known != null;
}
private KotlinTypeReference(String originalName) {
this.known = null;
+ this.exportAsKotlinClassifier = false;
this.originalName = originalName;
assert originalName != null;
}
@@ -49,25 +56,37 @@
static KotlinTypeReference fromBinaryNameOrKotlinClassifier(
String binaryNameOrKotlinClassifier, DexItemFactory factory, String originalName) {
// Kotlin classifiers are valid binary names.
- // The method getDescriptorFromKotlinClassifier also works for binary names.
if (DescriptorUtils.isValidBinaryName(binaryNameOrKotlinClassifier)) {
+ boolean interpretAsKotlinClassifier =
+ shouldBeInterpretedAsKotlinClassifier(binaryNameOrKotlinClassifier);
return fromDescriptor(
- DescriptorUtils.getDescriptorFromKotlinClassifier(binaryNameOrKotlinClassifier),
+ interpretAsKotlinClassifier
+ ? DescriptorUtils.getDescriptorFromKotlinClassifier(binaryNameOrKotlinClassifier)
+ : DescriptorUtils.getDescriptorFromClassBinaryName(binaryNameOrKotlinClassifier),
factory,
- originalName);
+ originalName,
+ interpretAsKotlinClassifier);
}
return new KotlinTypeReference(binaryNameOrKotlinClassifier);
}
+ private static boolean shouldBeInterpretedAsKotlinClassifier(
+ String binaryNameOrKotlinClassifier) {
+ return binaryNameOrKotlinClassifier.contains(".");
+ }
+
static KotlinTypeReference fromDescriptor(String descriptor, DexItemFactory factory) {
- return fromDescriptor(descriptor, factory, descriptor);
+ return fromDescriptor(descriptor, factory, descriptor, false);
}
static KotlinTypeReference fromDescriptor(
- String descriptor, DexItemFactory factory, String originalName) {
+ String descriptor,
+ DexItemFactory factory,
+ String originalName,
+ boolean exportAsKotlinClassifier) {
if (DescriptorUtils.isDescriptor(descriptor)) {
DexType type = factory.createType(descriptor);
- return new KotlinTypeReference(originalName, type);
+ return new KotlinTypeReference(originalName, type, exportAsKotlinClassifier);
}
return new KotlinTypeReference(originalName);
}
@@ -121,7 +140,11 @@
if (descriptor == null || descriptor.equals(defaultValue)) {
rewrittenConsumer.accept(descriptor);
} else {
- rewrittenConsumer.accept(DescriptorUtils.getBinaryNameFromDescriptor(descriptor));
+ String rewritten =
+ exportAsKotlinClassifier
+ ? DescriptorUtils.descriptorToKotlinClassifier(descriptor)
+ : DescriptorUtils.getBinaryNameFromDescriptor(descriptor);
+ rewrittenConsumer.accept(rewritten);
}
},
appView,