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,