Account for invalid type references in kotlin metadata

Bug: 157091933
Bug: 155536535
Change-Id: Id130b12356457c44fd0923db84fd4884ce860abb
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 a4bc5b0..e0a8d22 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinAnnotationInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinAnnotationInfo.java
@@ -4,12 +4,8 @@
 
 package com.android.tools.r8.kotlin;
 
-import static com.android.tools.r8.kotlin.KotlinMetadataUtils.referenceTypeFromBinaryName;
-
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexDefinitionSupplier;
-import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.utils.DescriptorUtils;
@@ -24,12 +20,12 @@
 
   private static final List<KotlinAnnotationInfo> EMPTY_ANNOTATIONS = ImmutableList.of();
 
-  private final DexType annotationType;
+  private final KotlinTypeReference annotationType;
   // TODO(b/155053894): Model KmAnnotationArgument.
   private final Map<String, KmAnnotationArgument<?>> arguments;
 
   private KotlinAnnotationInfo(
-      DexType annotationType, Map<String, KmAnnotationArgument<?>> arguments) {
+      KotlinTypeReference annotationType, Map<String, KmAnnotationArgument<?>> arguments) {
     this.annotationType = annotationType;
     this.arguments = arguments;
   }
@@ -37,7 +33,7 @@
   private static KotlinAnnotationInfo create(
       KmAnnotation annotation, DexDefinitionSupplier definitionSupplier) {
     return new KotlinAnnotationInfo(
-        referenceTypeFromBinaryName(annotation.getClassName(), definitionSupplier),
+        KotlinTypeReference.createFromBinaryName(annotation.getClassName(), definitionSupplier),
         annotation.getArguments());
   }
 
@@ -57,11 +53,13 @@
       KmVisitorProviders.KmAnnotationVisitorProvider visitorProvider,
       AppView<AppInfoWithLiveness> appView,
       NamingLens namingLens) {
-    if (appView.appInfo().wasPruned(annotationType)) {
+    String renamedDescriptor =
+        annotationType.toRenamedDescriptorOrDefault(appView, namingLens, null);
+    if (renamedDescriptor == null) {
+      // The type has been pruned
       return;
     }
-    DexString descriptor = namingLens.lookupDescriptor(annotationType);
-    String classifier = DescriptorUtils.descriptorToKotlinClassifier(descriptor.toString());
+    String classifier = DescriptorUtils.descriptorToKotlinClassifier(renamedDescriptor);
     KmAnnotation annotation = new KmAnnotation(classifier, arguments);
     visitorProvider.get(annotation);
   }
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 b507093..21d4cb3 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinClassInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClassInfo.java
@@ -4,7 +4,6 @@
 
 package com.android.tools.r8.kotlin;
 
-import static com.android.tools.r8.kotlin.KotlinMetadataUtils.referenceTypeFromBinaryName;
 import static com.android.tools.r8.kotlin.KotlinMetadataUtils.toJvmFieldSignature;
 import static com.android.tools.r8.kotlin.KotlinMetadataUtils.toJvmMethodSignature;
 
@@ -14,7 +13,6 @@
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.utils.DescriptorUtils;
@@ -41,14 +39,14 @@
   private final KotlinDeclarationContainerInfo declarationContainerInfo;
   private final List<KotlinTypeParameterInfo> typeParameters;
   private final List<KotlinTypeInfo> superTypes;
-  private final List<DexType> sealedSubClasses;
-  private final List<DexType> nestedClasses;
+  private final List<KotlinTypeReference> sealedSubClasses;
+  private final List<KotlinTypeReference> nestedClasses;
   // TODO(b/154347404): Understand enum entries.
   private final List<String> enumEntries;
-  private final DexType anonymousObjectOrigin;
+  private final KotlinTypeReference anonymousObjectOrigin;
   private final String packageName;
 
-  public KotlinClassInfo(
+  private KotlinClassInfo(
       int flags,
       String name,
       String moduleName,
@@ -56,10 +54,10 @@
       List<KotlinTypeParameterInfo> typeParameters,
       List<KotlinConstructorInfo> constructorsWithNoBacking,
       List<KotlinTypeInfo> superTypes,
-      List<DexType> sealedSubClasses,
-      List<DexType> nestedClasses,
+      List<KotlinTypeReference> sealedSubClasses,
+      List<KotlinTypeReference> nestedClasses,
       List<String> enumEntries,
-      DexType anonymousObjectOrigin,
+      KotlinTypeReference anonymousObjectOrigin,
       String packageName) {
     this.flags = flags;
     this.name = name;
@@ -117,41 +115,42 @@
         KotlinTypeParameterInfo.create(kmClass.getTypeParameters(), definitionSupplier, reporter),
         notBackedConstructors.build(),
         getSuperTypes(kmClass.getSupertypes(), definitionSupplier, reporter),
-        getSealedSubClasses(hostClass, kmClass.getSealedSubclasses(), definitionSupplier),
+        getSealedSubClasses(kmClass.getSealedSubclasses(), definitionSupplier),
         getNestedClasses(hostClass, kmClass.getNestedClasses(), definitionSupplier),
         kmClass.getEnumEntries(),
         getAnonymousObjectOrigin(kmClass, definitionSupplier),
         packageName);
   }
 
-  private static DexType getAnonymousObjectOrigin(
+  private static KotlinTypeReference getAnonymousObjectOrigin(
       KmClass kmClass, DexDefinitionSupplier definitionSupplier) {
     String anonymousObjectOriginName = JvmExtensionsKt.getAnonymousObjectOriginName(kmClass);
     if (anonymousObjectOriginName != null) {
-      return referenceTypeFromBinaryName(anonymousObjectOriginName, definitionSupplier);
+      return KotlinTypeReference.createFromBinaryName(
+          anonymousObjectOriginName, definitionSupplier);
     }
     return null;
   }
 
-  private static List<DexType> getNestedClasses(
+  private static List<KotlinTypeReference> getNestedClasses(
       DexClass clazz, List<String> nestedClasses, DexDefinitionSupplier definitionSupplier) {
-    ImmutableList.Builder<DexType> nestedTypes = ImmutableList.builder();
+    ImmutableList.Builder<KotlinTypeReference> nestedTypes = ImmutableList.builder();
     for (String nestedClass : nestedClasses) {
       String binaryName =
           clazz.type.toBinaryName() + DescriptorUtils.INNER_CLASS_SEPARATOR + nestedClass;
-      nestedTypes.add(referenceTypeFromBinaryName(binaryName, definitionSupplier));
+      nestedTypes.add(KotlinTypeReference.createFromBinaryName(binaryName, definitionSupplier));
     }
     return nestedTypes.build();
   }
 
-  private static List<DexType> getSealedSubClasses(
-      DexClass clazz, List<String> sealedSubclasses, DexDefinitionSupplier definitionSupplier) {
-    ImmutableList.Builder<DexType> sealedTypes = ImmutableList.builder();
+  private static List<KotlinTypeReference> getSealedSubClasses(
+      List<String> sealedSubclasses, DexDefinitionSupplier definitionSupplier) {
+    ImmutableList.Builder<KotlinTypeReference> sealedTypes = ImmutableList.builder();
     for (String sealedSubClass : sealedSubclasses) {
       String binaryName =
           sealedSubClass.replace(
               DescriptorUtils.JAVA_PACKAGE_SEPARATOR, DescriptorUtils.INNER_CLASS_SEPARATOR);
-      sealedTypes.add(referenceTypeFromBinaryName(binaryName, definitionSupplier));
+      sealedTypes.add(KotlinTypeReference.createFromBinaryName(binaryName, definitionSupplier));
     }
     return sealedTypes.build();
   }
@@ -205,7 +204,7 @@
     kmClass.setName(
         originalDescriptor.equals(rewrittenDescriptor)
             ? this.name
-            : KotlinMetadataUtils.kotlinNameFromDescriptor(rewrittenDescriptor));
+            : DescriptorUtils.getBinaryNameFromDescriptor(rewrittenDescriptor.toString()));
     // Find a companion object.
     for (DexEncodedField field : clazz.fields()) {
       if (field.getKotlinMemberInfo().isCompanion()) {
@@ -240,24 +239,22 @@
       superType.rewrite(kmClass::visitSupertype, appView, namingLens);
     }
     // Rewrite nested classes.
-    for (DexType nestedClass : nestedClasses) {
-      if (appView.appInfo().isNonProgramTypeOrLiveProgramType(nestedClass)) {
-        String descriptor =
-            KotlinMetadataUtils.kotlinNameFromDescriptor(namingLens.lookupDescriptor(nestedClass));
+    for (KotlinTypeReference nestedClass : nestedClasses) {
+      String nestedDescriptor = nestedClass.toRenamedBinaryNameOrDefault(appView, namingLens, null);
+      if (nestedDescriptor != null) {
         // If the class is a nested class, it should be on the form Foo.Bar$Baz, where Baz is the
         // name we should record.
-        int innerClassIndex = descriptor.lastIndexOf(DescriptorUtils.INNER_CLASS_SEPARATOR);
-        kmClass.visitNestedClass(descriptor.substring(innerClassIndex + 1));
+        int innerClassIndex = nestedDescriptor.lastIndexOf(DescriptorUtils.INNER_CLASS_SEPARATOR);
+        kmClass.visitNestedClass(nestedDescriptor.substring(innerClassIndex + 1));
       }
     }
     // Rewrite sealed sub classes.
-    for (DexType sealedSubClass : sealedSubClasses) {
-      if (appView.appInfo().isNonProgramTypeOrLiveProgramType(sealedSubClass)) {
-        String descriptor =
-            KotlinMetadataUtils.kotlinNameFromDescriptor(
-                namingLens.lookupDescriptor(sealedSubClass));
+    for (KotlinTypeReference sealedSubClass : sealedSubClasses) {
+      String sealedDescriptor =
+          sealedSubClass.toRenamedBinaryNameOrDefault(appView, namingLens, null);
+      if (sealedDescriptor != null) {
         kmClass.visitSealedSubclass(
-            descriptor.replace(
+            sealedDescriptor.replace(
                 DescriptorUtils.INNER_CLASS_SEPARATOR, DescriptorUtils.JAVA_PACKAGE_SEPARATOR));
       }
     }
@@ -266,8 +263,11 @@
 
     JvmExtensionsKt.setModuleName(kmClass, moduleName);
     if (anonymousObjectOrigin != null) {
-      JvmExtensionsKt.setAnonymousObjectOriginName(
-          kmClass, KotlinMetadataUtils.kotlinNameFromDescriptor(anonymousObjectOrigin.descriptor));
+      String renamedAnon =
+          anonymousObjectOrigin.toRenamedBinaryNameOrDefault(appView, namingLens, null);
+      if (renamedAnon != null) {
+        JvmExtensionsKt.setAnonymousObjectOriginName(kmClass, renamedAnon);
+      }
     }
 
     KotlinClassMetadata.Class.Writer writer = new KotlinClassMetadata.Class.Writer();
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinClassifierInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinClassifierInfo.java
index d6ff5b4..a091e52 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinClassifierInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClassifierInfo.java
@@ -4,12 +4,8 @@
 
 package com.android.tools.r8.kotlin;
 
-import static com.android.tools.r8.kotlin.KotlinMetadataUtils.referenceTypeFromDescriptor;
-
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexDefinitionSupplier;
-import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.kotlin.Kotlin.ClassClassifiers;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -35,7 +31,8 @@
               isLocalOrAnonymous ? originalTypeName.substring(1) : originalTypeName);
       if (DescriptorUtils.isClassDescriptor(descriptor)) {
         return new KotlinClassClassifierInfo(
-            referenceTypeFromDescriptor(descriptor, definitionSupplier), isLocalOrAnonymous);
+            KotlinTypeReference.createFromDescriptor(descriptor, definitionSupplier),
+            isLocalOrAnonymous);
       } else {
         return new KotlinUnknownClassClassifierInfo(originalTypeName);
       }
@@ -54,10 +51,10 @@
 
   public static class KotlinClassClassifierInfo extends KotlinClassifierInfo {
 
-    private final DexType type;
+    private final KotlinTypeReference type;
     private final boolean isLocalOrAnonymous;
 
-    private KotlinClassClassifierInfo(DexType type, boolean isLocalOrAnonymous) {
+    private KotlinClassClassifierInfo(KotlinTypeReference type, boolean isLocalOrAnonymous) {
       this.type = type;
       this.isLocalOrAnonymous = isLocalOrAnonymous;
     }
@@ -65,18 +62,14 @@
     @Override
     void rewrite(
         KmTypeVisitor visitor, AppView<AppInfoWithLiveness> appView, NamingLens namingLens) {
-      if (appView.appInfo().wasPruned(type)) {
-        visitor.visitClass(ClassClassifiers.anyName);
-        return;
-      }
-      DexString descriptor = namingLens.lookupDescriptor(type);
+      String descriptor =
+          type.toRenamedDescriptorOrDefault(appView, namingLens, ClassClassifiers.anyName);
       // For local or anonymous classes, the classifier is prefixed with '.' and inner classes are
       // separated with '$'.
       if (isLocalOrAnonymous) {
-        visitor.visitClass(
-            "." + DescriptorUtils.getBinaryNameFromDescriptor(descriptor.toString()));
+        visitor.visitClass("." + DescriptorUtils.getBinaryNameFromDescriptor(descriptor));
       } else {
-        visitor.visitClass(DescriptorUtils.descriptorToKotlinClassifier(descriptor.toString()));
+        visitor.visitClass(DescriptorUtils.descriptorToKotlinClassifier(descriptor));
       }
     }
   }
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 58b07cb..6756be4 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinFunctionInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinFunctionInfo.java
@@ -4,12 +4,9 @@
 
 package com.android.tools.r8.kotlin;
 
-import static com.android.tools.r8.kotlin.KotlinMetadataUtils.referenceTypeFromBinaryName;
-
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexDefinitionSupplier;
 import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.utils.Reporter;
@@ -36,7 +33,7 @@
   // Information about the signature
   private final KotlinJvmMethodSignatureInfo signature;
   // Information about the lambdaClassOrigin.
-  private final DexType lambdaClassOrigin;
+  private final KotlinTypeReference lambdaClassOrigin;
 
   private KotlinFunctionInfo(
       int flags,
@@ -46,7 +43,7 @@
       List<KotlinValueParameterInfo> valueParameters,
       List<KotlinTypeParameterInfo> typeParameters,
       KotlinJvmMethodSignatureInfo signature,
-      DexType lambdaClassOrigin) {
+      KotlinTypeReference lambdaClassOrigin) {
     this.flags = flags;
     this.name = name;
     this.returnType = returnType;
@@ -73,11 +70,11 @@
         getlambdaClassOrigin(kmFunction, definitionSupplier));
   }
 
-  private static DexType getlambdaClassOrigin(
+  private static KotlinTypeReference getlambdaClassOrigin(
       KmFunction kmFunction, DexDefinitionSupplier definitionSupplier) {
     String lambdaClassOriginName = JvmExtensionsKt.getLambdaClassOriginName(kmFunction);
     if (lambdaClassOriginName != null) {
-      return referenceTypeFromBinaryName(lambdaClassOriginName, definitionSupplier);
+      return KotlinTypeReference.createFromBinaryName(lambdaClassOriginName, definitionSupplier);
     }
     return null;
   }
@@ -114,8 +111,11 @@
       extensionVisitor.visit(signature.rewrite(method, appView, namingLens));
     }
     if (lambdaClassOrigin != null && extensionVisitor != null) {
-      extensionVisitor.visitLambdaClassOriginName(
-          KotlinMetadataUtils.kotlinNameFromDescriptor(lambdaClassOrigin.descriptor));
+      String lambdaClassOriginName =
+          lambdaClassOrigin.toRenamedBinaryNameOrDefault(appView, namingLens, null);
+      if (lambdaClassOriginName != null) {
+        extensionVisitor.visitLambdaClassOriginName(lambdaClassOriginName);
+      }
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinJvmFieldSignatureInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinJvmFieldSignatureInfo.java
index 69c0442..7603c36 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinJvmFieldSignatureInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinJvmFieldSignatureInfo.java
@@ -4,13 +4,9 @@
 
 package com.android.tools.r8.kotlin;
 
-import static com.android.tools.r8.kotlin.KotlinMetadataUtils.referenceTypeFromDescriptor;
-import static com.android.tools.r8.kotlin.KotlinMetadataUtils.toRenamedDescriptorOrDefault;
-
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexDefinitionSupplier;
 import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import kotlinx.metadata.jvm.JvmFieldSignature;
@@ -21,10 +17,10 @@
  */
 public class KotlinJvmFieldSignatureInfo {
 
-  private final DexType type;
+  private final KotlinTypeReference type;
   private final String name;
 
-  private KotlinJvmFieldSignatureInfo(String name, DexType type) {
+  private KotlinJvmFieldSignatureInfo(String name, KotlinTypeReference type) {
     this.name = name;
     this.type = type;
   }
@@ -36,7 +32,7 @@
     }
     return new KotlinJvmFieldSignatureInfo(
         fieldSignature.getName(),
-        referenceTypeFromDescriptor(fieldSignature.getDesc(), definitionSupplier));
+        KotlinTypeReference.createFromDescriptor(fieldSignature.getDesc(), definitionSupplier));
   }
 
   public JvmFieldSignature rewrite(
@@ -51,6 +47,6 @@
     }
     String defValue = appView.dexItemFactory().objectType.toDescriptorString();
     return new JvmFieldSignature(
-        finalName, toRenamedDescriptorOrDefault(type, appView, namingLens, defValue));
+        finalName, type.toRenamedDescriptorOrDefault(appView, namingLens, defValue));
   }
 }
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinJvmMethodSignatureInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinJvmMethodSignatureInfo.java
index d9d5c9d..cb5557e 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinJvmMethodSignatureInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinJvmMethodSignatureInfo.java
@@ -4,13 +4,9 @@
 
 package com.android.tools.r8.kotlin;
 
-import static com.android.tools.r8.kotlin.KotlinMetadataUtils.referenceTypeFromDescriptor;
-import static com.android.tools.r8.kotlin.KotlinMetadataUtils.toRenamedDescriptorOrDefault;
-
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexDefinitionSupplier;
 import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.utils.DescriptorUtils;
@@ -24,13 +20,14 @@
  */
 public class KotlinJvmMethodSignatureInfo {
 
-  private static final List<DexType> EMPTY_PARAMETERS_LIST = ImmutableList.of();
+  private static final List<KotlinTypeReference> EMPTY_PARAMETERS_LIST = ImmutableList.of();
 
   private final String name;
-  private final DexType returnType;
-  private final List<DexType> parameters;
+  private final KotlinTypeReference returnType;
+  private final List<KotlinTypeReference> parameters;
 
-  private KotlinJvmMethodSignatureInfo(String name, DexType returnType, List<DexType> parameters) {
+  private KotlinJvmMethodSignatureInfo(
+      String name, KotlinTypeReference returnType, List<KotlinTypeReference> parameters) {
     this.name = name;
     this.returnType = returnType;
     this.parameters = parameters;
@@ -43,15 +40,16 @@
     }
     String kotlinDescriptor = methodSignature.getDesc();
     String returnTypeDescriptor = DescriptorUtils.getReturnTypeDescriptor(kotlinDescriptor);
-    DexType returnType = referenceTypeFromDescriptor(returnTypeDescriptor, definitionSupplier);
+    KotlinTypeReference returnType =
+        KotlinTypeReference.createFromDescriptor(returnTypeDescriptor, definitionSupplier);
     String[] descriptors = DescriptorUtils.getArgumentTypeDescriptors(kotlinDescriptor);
     if (descriptors.length == 0) {
       return new KotlinJvmMethodSignatureInfo(
           methodSignature.getName(), returnType, EMPTY_PARAMETERS_LIST);
     }
-    ImmutableList.Builder<DexType> parameters = ImmutableList.builder();
+    ImmutableList.Builder<KotlinTypeReference> parameters = ImmutableList.builder();
     for (String descriptor : descriptors) {
-      parameters.add(referenceTypeFromDescriptor(descriptor, definitionSupplier));
+      parameters.add(KotlinTypeReference.createFromDescriptor(descriptor, definitionSupplier));
     }
     return new KotlinJvmMethodSignatureInfo(
         methodSignature.getName(), returnType, parameters.build());
@@ -70,11 +68,11 @@
     StringBuilder descBuilder = new StringBuilder();
     descBuilder.append("(");
     String defValue = appView.dexItemFactory().objectType.toDescriptorString();
-    for (DexType parameter : parameters) {
-      descBuilder.append(toRenamedDescriptorOrDefault(parameter, appView, namingLens, defValue));
+    for (KotlinTypeReference parameter : parameters) {
+      descBuilder.append(parameter.toRenamedDescriptorOrDefault(appView, namingLens, defValue));
     }
     descBuilder.append(")");
-    descBuilder.append(toRenamedDescriptorOrDefault(returnType, appView, namingLens, defValue));
+    descBuilder.append(returnType.toRenamedDescriptorOrDefault(appView, namingLens, defValue));
     return new JvmMethodSignature(finalName, descBuilder.toString());
   }
 }
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataUtils.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataUtils.java
index 1f21451..a8d0ed7 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataUtils.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataUtils.java
@@ -8,11 +8,9 @@
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexDefinitionSupplier;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -137,41 +135,6 @@
     }
   }
 
-  static String toRenamedDescriptorOrDefault(
-      DexType type,
-      AppView<AppInfoWithLiveness> appView,
-      NamingLens namingLens,
-      String defaultValue) {
-    if (appView.appInfo().wasPruned(type)) {
-      return defaultValue;
-    }
-    DexString descriptor = namingLens.lookupDescriptor(type);
-    if (descriptor != null) {
-      return descriptor.toString();
-    }
-    return defaultValue;
-  }
-
-  static String kotlinNameFromDescriptor(DexString descriptor) {
-    return DescriptorUtils.getBinaryNameFromDescriptor(descriptor.toString());
-  }
-
-  static DexType referenceTypeFromBinaryName(
-      String binaryName, DexDefinitionSupplier definitionSupplier) {
-    return referenceTypeFromDescriptor(
-        DescriptorUtils.getDescriptorFromClassBinaryName(binaryName), definitionSupplier);
-  }
-
-  static DexType referenceTypeFromDescriptor(
-      String descriptor, DexDefinitionSupplier definitionSupplier) {
-    DexType type = definitionSupplier.dexItemFactory().createType(descriptor);
-    // Lookup the definition, ignoring the result. This populates the sets in the Enqueuer.
-    if (type.isClassType()) {
-      definitionSupplier.definitionFor(type);
-    }
-    return type;
-  }
-
   public static boolean mayProcessKotlinMetadata(AppView<?> appView) {
     // This can run before we have determined the pinned items, because we may need to load the
     // stack-map table on input. This is therefore a conservative guess on kotlin.Metadata is kept.
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeReference.java b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeReference.java
new file mode 100644
index 0000000..79bf0a7
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeReference.java
@@ -0,0 +1,90 @@
+// 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 com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexDefinitionSupplier;
+import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.utils.DescriptorUtils;
+
+/**
+ * To account for invalid type references in kotlin metadata, the class KotlinTypeReference will
+ * either hold a DexType reference, or a String, with the original name reference, which is not a
+ * valid jvm descriptor/name. The values will be disjoint.
+ */
+class KotlinTypeReference {
+
+  private final DexType known;
+  private final String unknown;
+
+  private KotlinTypeReference(DexType known) {
+    this.known = known;
+    this.unknown = null;
+    assert known != null;
+  }
+
+  private KotlinTypeReference(String unknown) {
+    this.known = null;
+    this.unknown = unknown;
+    assert unknown != null;
+  }
+
+  static KotlinTypeReference createFromBinaryName(
+      String binaryName, DexDefinitionSupplier definitionSupplier) {
+    if (DescriptorUtils.isValidBinaryName(binaryName)) {
+      return createFromDescriptor(
+          DescriptorUtils.getDescriptorFromClassBinaryName(binaryName), definitionSupplier);
+    }
+    return new KotlinTypeReference(binaryName);
+  }
+
+  static KotlinTypeReference createFromDescriptor(
+      String descriptor, DexDefinitionSupplier definitionSupplier) {
+    if (DescriptorUtils.isDescriptor(descriptor)) {
+      DexType type = definitionSupplier.dexItemFactory().createType(descriptor);
+      // Lookup the definition, ignoring the result. This populates the sets in the Enqueuer.
+      if (type.isClassType()) {
+        definitionSupplier.definitionFor(type);
+      }
+      return new KotlinTypeReference(type);
+    }
+    return new KotlinTypeReference(descriptor);
+  }
+
+  String toRenamedDescriptorOrDefault(
+      AppView<AppInfoWithLiveness> appView, NamingLens namingLens, String defaultValue) {
+    if (unknown != null) {
+      return unknown;
+    }
+    if (!appView.appInfo().isNonProgramTypeOrLiveProgramType(known)) {
+      return defaultValue;
+    }
+    DexString descriptor = namingLens.lookupDescriptor(known);
+    if (descriptor != null) {
+      return descriptor.toString();
+    }
+    return defaultValue;
+  }
+
+  String toRenamedBinaryNameOrDefault(
+      AppView<AppInfoWithLiveness> appView, NamingLens namingLens, String defaultValue) {
+    if (unknown != null) {
+      // Unknown values are always on the input form, so we can just return it.
+      return unknown;
+    }
+    String descriptor = toRenamedDescriptorOrDefault(appView, namingLens, defaultValue);
+    if (descriptor == null) {
+      return null;
+    }
+    if (descriptor.equals(defaultValue)) {
+      // We assume that the default value passed in is already a binary name.
+      return descriptor;
+    }
+    return DescriptorUtils.getBinaryNameFromDescriptor(descriptor);
+  }
+}
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 196091e..2d78c0d 100644
--- a/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/DescriptorUtils.java
@@ -369,13 +369,6 @@
     return 'L' + className.replace(JAVA_PACKAGE_SEPARATOR, INNER_CLASS_SEPARATOR) + ';';
   }
 
-  // TODO(b/151195430): Remove once a new version of kotlinx-metadata is released.
-  // Kotlin @Metadata deserialization has plain "kotlin", which will be relocated in r8lib.
-  // See b/70169921#comment25 for more details.
-  private static String backwardRelocatedName(String name) {
-    return name.replace("com/android/tools/r8/jetbrains/", "");
-  }
-
   /**
    * Get unqualified class name from its binary name.
    *
@@ -512,6 +505,11 @@
     return 'L' + descriptor + ';';
   }
 
+  public static boolean isValidBinaryName(String binaryName) {
+    return isValidJavaType(
+        binaryName.replace(DESCRIPTOR_PACKAGE_SEPARATOR, JAVA_PACKAGE_SEPARATOR));
+  }
+
   public static class ModuleAndDescriptor {
     private final String module;
     private final String descriptor;