Rewrite Kotlin metadata annotation type using kotlin descriptor

Bug: b/299878903
Change-Id: Idfcf256aa29f3cecaa7d3c41e4c897a23404ffdd
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinAnnotationArgumentInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinAnnotationArgumentInfo.java
index 5d67400..2c05e8f 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinAnnotationArgumentInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinAnnotationArgumentInfo.java
@@ -68,7 +68,8 @@
 
     private static KotlinAnnotationClassValueInfo create(KClassValue arg, DexItemFactory factory) {
       return new KotlinAnnotationClassValueInfo(
-          KotlinTypeReference.fromBinaryName(arg.getClassName(), factory, arg.getClassName()),
+          KotlinTypeReference.fromBinaryNameOrKotlinClassifier(
+              arg.getClassName(), factory, arg.getClassName()),
           arg.getArrayDimensionCount());
     }
 
@@ -98,7 +99,7 @@
 
     private static KotlinAnnotationEnumValueInfo create(EnumValue arg, DexItemFactory factory) {
       return new KotlinAnnotationEnumValueInfo(
-          KotlinTypeReference.fromBinaryName(
+          KotlinTypeReference.fromBinaryNameOrKotlinClassifier(
               arg.getEnumClassName(), factory, arg.getEnumClassName()),
           arg.getEnumEntryName());
     }
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinAnnotationInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinAnnotationInfo.java
index 759ef69..0904502 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinAnnotationInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinAnnotationInfo.java
@@ -34,7 +34,7 @@
 
   static KotlinAnnotationInfo create(KmAnnotation annotation, DexItemFactory factory) {
     return new KotlinAnnotationInfo(
-        KotlinTypeReference.fromBinaryName(
+        KotlinTypeReference.fromBinaryNameOrKotlinClassifier(
             annotation.getClassName(), factory, annotation.getClassName()),
         KotlinAnnotationArgumentInfo.create(annotation.getArguments(), factory));
   }
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinClassInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinClassInfo.java
index 66c4f2e..8e60aa7 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinClassInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClassInfo.java
@@ -200,7 +200,7 @@
       KmClass kmClass, DexItemFactory factory) {
     String anonymousObjectOriginName = JvmExtensionsKt.getAnonymousObjectOriginName(kmClass);
     if (anonymousObjectOriginName != null) {
-      return KotlinTypeReference.fromBinaryName(
+      return KotlinTypeReference.fromBinaryNameOrKotlinClassifier(
           anonymousObjectOriginName, factory, anonymousObjectOriginName);
     }
     return null;
@@ -212,7 +212,8 @@
     for (String nestedClass : nestedClasses) {
       String binaryName =
           clazz.type.toBinaryName() + DescriptorUtils.INNER_CLASS_SEPARATOR + nestedClass;
-      nestedTypes.add(KotlinTypeReference.fromBinaryName(binaryName, factory, nestedClass));
+      nestedTypes.add(
+          KotlinTypeReference.fromBinaryNameOrKotlinClassifier(binaryName, factory, nestedClass));
     }
     return nestedTypes.build();
   }
@@ -224,7 +225,9 @@
       String binaryName =
           sealedSubClass.replace(
               DescriptorUtils.JAVA_PACKAGE_SEPARATOR, DescriptorUtils.INNER_CLASS_SEPARATOR);
-      sealedTypes.add(KotlinTypeReference.fromBinaryName(binaryName, factory, sealedSubClass));
+      sealedTypes.add(
+          KotlinTypeReference.fromBinaryNameOrKotlinClassifier(
+              binaryName, factory, sealedSubClass));
     }
     return sealedTypes.build();
   }
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinFunctionInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinFunctionInfo.java
index 1e387ff..dc949fc 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinFunctionInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinFunctionInfo.java
@@ -110,7 +110,7 @@
       KmFunction kmFunction, DexItemFactory factory) {
     String lambdaClassOriginName = JvmExtensionsKt.getLambdaClassOriginName(kmFunction);
     if (lambdaClassOriginName != null) {
-      return KotlinTypeReference.fromBinaryName(
+      return KotlinTypeReference.fromBinaryNameOrKotlinClassifier(
           lambdaClassOriginName, factory, lambdaClassOriginName);
     }
     return null;
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMultiFileClassFacadeInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMultiFileClassFacadeInfo.java
index 9757ef4..0833a1c 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMultiFileClassFacadeInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMultiFileClassFacadeInfo.java
@@ -40,7 +40,9 @@
       DexItemFactory factory) {
     ImmutableList.Builder<KotlinTypeReference> builder = ImmutableList.builder();
     for (String partClassName : kmMultiFileClassFacade.getPartClassNames()) {
-      builder.add(KotlinTypeReference.fromBinaryName(partClassName, factory, partClassName));
+      builder.add(
+          KotlinTypeReference.fromBinaryNameOrKotlinClassifier(
+              partClassName, factory, partClassName));
     }
     return new KotlinMultiFileClassFacadeInfo(builder.build(), packageName, metadataVersion);
   }
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 553c174..ecf67fa 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeReference.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeReference.java
@@ -46,13 +46,17 @@
     return originalName;
   }
 
-  static KotlinTypeReference fromBinaryName(
-      String binaryName, DexItemFactory factory, String originalName) {
-    if (DescriptorUtils.isValidBinaryName(binaryName)) {
+  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)) {
       return fromDescriptor(
-          DescriptorUtils.getDescriptorFromClassBinaryName(binaryName), factory, originalName);
+          DescriptorUtils.getDescriptorFromKotlinClassifier(binaryNameOrKotlinClassifier),
+          factory,
+          originalName);
     }
-    return new KotlinTypeReference(binaryName);
+    return new KotlinTypeReference(binaryNameOrKotlinClassifier);
   }
 
   static KotlinTypeReference fromDescriptor(String descriptor, DexItemFactory factory) {
diff --git a/src/test/java/com/android/tools/r8/kotlin/KotlinTypeReferenceTest.java b/src/test/java/com/android/tools/r8/kotlin/KotlinTypeReferenceTest.java
new file mode 100644
index 0000000..824d83b
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/KotlinTypeReferenceTest.java
@@ -0,0 +1,43 @@
+// Copyright (c) 2023, 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 com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.graph.DexItemFactory;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class KotlinTypeReferenceTest extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withNoneRuntime().build();
+  }
+
+  public KotlinTypeReferenceTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void testRef() {
+    // This is a unit test for b/299878903.
+    DexItemFactory factory = new DexItemFactory();
+    KotlinTypeReference bar =
+        KotlinTypeReference.fromBinaryNameOrKotlinClassifier(
+            "com/bar/Foo.Bar", factory, "com.bar.Foo.Bar");
+    Assert.assertEquals(bar.toString(), "Lcom/bar/Foo$Bar;");
+    KotlinTypeReference kotlinTypeReference =
+        KotlinTypeReference.fromBinaryNameOrKotlinClassifier(
+            "com/bar/Foo$Bar", factory, "com.bar.Foo.Bar");
+    Assert.assertEquals(kotlinTypeReference.toString(), "Lcom/bar/Foo$Bar;");
+  }
+}