Reland "Account for invalid type references in kotlin metadata"
This reverts commit 8ab5a5e9011ccf04f864c163cd3a9af475e8dd17.
Bug: 157448903
Bug: 155536535
Bug: 157091933
Change-Id: I71e483e2258686cf03a0dcc52a9d3bbc3fd32f49
diff --git a/src/main/java/com/android/tools/r8/kotlin/Kotlin.java b/src/main/java/com/android/tools/r8/kotlin/Kotlin.java
index 602165c..07f6b0b 100644
--- a/src/main/java/com/android/tools/r8/kotlin/Kotlin.java
+++ b/src/main/java/com/android/tools/r8/kotlin/Kotlin.java
@@ -42,7 +42,7 @@
public static final class ClassClassifiers {
public static final String arrayBinaryName = NAME + "/Array";
- public static final String anyName = NAME + "/Any";
+ public static final String anyDescriptor = "L" + NAME + "/Any;";
}
// Mappings from JVM types to Kotlin types (of type DexType)
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..90ed44a 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinAnnotationInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinAnnotationInfo.java
@@ -4,14 +4,12 @@
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.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import com.android.tools.r8.utils.DescriptorUtils;
import com.google.common.collect.ImmutableList;
import java.util.List;
@@ -20,35 +18,33 @@
import kotlinx.metadata.KmAnnotationArgument;
// Holds information about a KmAnnotation
-public class KotlinAnnotationInfo {
+public class KotlinAnnotationInfo implements EnqueuerMetadataTraceable {
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;
}
- private static KotlinAnnotationInfo create(
- KmAnnotation annotation, DexDefinitionSupplier definitionSupplier) {
+ private static KotlinAnnotationInfo create(KmAnnotation annotation, DexItemFactory factory) {
return new KotlinAnnotationInfo(
- referenceTypeFromBinaryName(annotation.getClassName(), definitionSupplier),
+ KotlinTypeReference.fromBinaryName(annotation.getClassName(), factory),
annotation.getArguments());
}
- static List<KotlinAnnotationInfo> create(
- List<KmAnnotation> annotations, DexDefinitionSupplier definitionSupplier) {
+ static List<KotlinAnnotationInfo> create(List<KmAnnotation> annotations, DexItemFactory factory) {
if (annotations.isEmpty()) {
return EMPTY_ANNOTATIONS;
}
ImmutableList.Builder<KotlinAnnotationInfo> builder = ImmutableList.builder();
for (KmAnnotation annotation : annotations) {
- builder.add(create(annotation, definitionSupplier));
+ builder.add(create(annotation, factory));
}
return builder.build();
}
@@ -57,12 +53,20 @@
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);
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ annotationType.trace(definitionSupplier);
+ // TODO(b/155053894): Trace annotation arguments.
+ }
}
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..b0b381e 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinClassInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClassInfo.java
@@ -4,17 +4,17 @@
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;
+import static com.android.tools.r8.utils.FunctionUtils.forEachApply;
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.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexItemFactory;
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 +41,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 +56,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;
@@ -79,7 +79,7 @@
KmClass kmClass,
String packageName,
DexClass hostClass,
- DexDefinitionSupplier definitionSupplier,
+ DexItemFactory factory,
Reporter reporter,
Consumer<DexEncodedMethod> keepByteCode) {
Map<String, DexEncodedField> fieldMap = new HashMap<>();
@@ -93,7 +93,7 @@
ImmutableList.Builder<KotlinConstructorInfo> notBackedConstructors = ImmutableList.builder();
for (KmConstructor kmConstructor : kmClass.getConstructors()) {
KotlinConstructorInfo constructorInfo =
- KotlinConstructorInfo.create(kmConstructor, definitionSupplier, reporter);
+ KotlinConstructorInfo.create(kmConstructor, factory, reporter);
JvmMethodSignature signature = JvmExtensionsKt.getSignature(kmConstructor);
if (signature != null) {
DexEncodedMethod method = methodMap.get(signature.asString());
@@ -107,60 +107,60 @@
}
KotlinDeclarationContainerInfo container =
KotlinDeclarationContainerInfo.create(
- kmClass, methodMap, fieldMap, definitionSupplier, reporter, keepByteCode);
+ kmClass, methodMap, fieldMap, factory, reporter, keepByteCode);
setCompanionObject(kmClass, hostClass, reporter);
return new KotlinClassInfo(
kmClass.getFlags(),
kmClass.name,
JvmExtensionsKt.getModuleName(kmClass),
container,
- KotlinTypeParameterInfo.create(kmClass.getTypeParameters(), definitionSupplier, reporter),
+ KotlinTypeParameterInfo.create(kmClass.getTypeParameters(), factory, reporter),
notBackedConstructors.build(),
- getSuperTypes(kmClass.getSupertypes(), definitionSupplier, reporter),
- getSealedSubClasses(hostClass, kmClass.getSealedSubclasses(), definitionSupplier),
- getNestedClasses(hostClass, kmClass.getNestedClasses(), definitionSupplier),
+ getSuperTypes(kmClass.getSupertypes(), factory, reporter),
+ getSealedSubClasses(kmClass.getSealedSubclasses(), factory),
+ getNestedClasses(hostClass, kmClass.getNestedClasses(), factory),
kmClass.getEnumEntries(),
- getAnonymousObjectOrigin(kmClass, definitionSupplier),
+ getAnonymousObjectOrigin(kmClass, factory),
packageName);
}
- private static DexType getAnonymousObjectOrigin(
- KmClass kmClass, DexDefinitionSupplier definitionSupplier) {
+ private static KotlinTypeReference getAnonymousObjectOrigin(
+ KmClass kmClass, DexItemFactory factory) {
String anonymousObjectOriginName = JvmExtensionsKt.getAnonymousObjectOriginName(kmClass);
if (anonymousObjectOriginName != null) {
- return referenceTypeFromBinaryName(anonymousObjectOriginName, definitionSupplier);
+ return KotlinTypeReference.fromBinaryName(anonymousObjectOriginName, factory);
}
return null;
}
- private static List<DexType> getNestedClasses(
- DexClass clazz, List<String> nestedClasses, DexDefinitionSupplier definitionSupplier) {
- ImmutableList.Builder<DexType> nestedTypes = ImmutableList.builder();
+ private static List<KotlinTypeReference> getNestedClasses(
+ DexClass clazz, List<String> nestedClasses, DexItemFactory factory) {
+ 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.fromBinaryName(binaryName, factory));
}
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, DexItemFactory factory) {
+ 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.fromBinaryName(binaryName, factory));
}
return sealedTypes.build();
}
private static List<KotlinTypeInfo> getSuperTypes(
- List<KmType> superTypes, DexDefinitionSupplier definitionSupplier, Reporter reporter) {
+ List<KmType> superTypes, DexItemFactory factory, Reporter reporter) {
ImmutableList.Builder<KotlinTypeInfo> superTypeInfos = ImmutableList.builder();
for (KmType superType : superTypes) {
- superTypeInfos.add(KotlinTypeInfo.create(superType, definitionSupplier, reporter));
+ superTypeInfos.add(KotlinTypeInfo.create(superType, factory, reporter));
}
return superTypeInfos.build();
}
@@ -205,7 +205,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 +240,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 +264,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();
@@ -279,4 +280,18 @@
public String getPackageName() {
return packageName;
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ forEachApply(constructorsWithNoBacking, constructor -> constructor::trace, definitionSupplier);
+ declarationContainerInfo.trace(definitionSupplier);
+ forEachApply(typeParameters, param -> param::trace, definitionSupplier);
+ forEachApply(superTypes, type -> type::trace, definitionSupplier);
+ forEachApply(sealedSubClasses, sealed -> sealed::trace, definitionSupplier);
+ forEachApply(nestedClasses, nested -> nested::trace, definitionSupplier);
+ // TODO(b/154347404): trace enum entries.
+ if (anonymousObjectOrigin != null) {
+ anonymousObjectOrigin.trace(definitionSupplier);
+ }
+ }
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinClassLevelInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinClassLevelInfo.java
index f9662ef..1a24001 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinClassLevelInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClassLevelInfo.java
@@ -8,9 +8,14 @@
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import kotlinx.metadata.jvm.KotlinClassHeader;
-public interface KotlinClassLevelInfo {
+public interface KotlinClassLevelInfo extends EnqueuerMetadataTraceable {
+
+ default boolean isNoKotlinInformation() {
+ return false;
+ }
default boolean isClass() {
return false;
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java b/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
index 5fe02b2..2171a00 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedAnnotation;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.DexValue.DexValueArray;
@@ -31,22 +32,18 @@
public static KotlinClassLevelInfo getKotlinInfo(
Kotlin kotlin,
DexClass clazz,
- DexDefinitionSupplier definitionSupplier,
+ DexItemFactory factory,
Reporter reporter,
boolean onlyProcessLambda,
Consumer<DexEncodedMethod> keepByteCode) {
- DexAnnotation meta =
- clazz
- .annotations()
- .getFirstMatching(definitionSupplier.dexItemFactory().kotlinMetadataType);
+ DexAnnotation meta = clazz.annotations().getFirstMatching(factory.kotlinMetadataType);
if (meta != null) {
try {
KotlinClassMetadata kMetadata = toKotlinClassMetadata(kotlin, meta.annotation);
if (onlyProcessLambda && kMetadata.getHeader().getKind() != KOTLIN_METADATA_KIND_LAMBDA) {
return NO_KOTLIN_INFO;
}
- return createKotlinInfo(
- kotlin, clazz, kMetadata, definitionSupplier, reporter, keepByteCode);
+ return createKotlinInfo(kotlin, clazz, kMetadata, factory, reporter, keepByteCode);
} catch (ClassCastException | InconsistentKotlinMetadataException | MetadataError e) {
reporter.info(
new StringDiagnostic(
@@ -68,6 +65,14 @@
return NO_KOTLIN_INFO;
}
+ public static boolean hasKotlinClassMetadataAnnotation(
+ DexClass clazz, DexDefinitionSupplier definitionSupplier) {
+ return clazz
+ .annotations()
+ .getFirstMatching(definitionSupplier.dexItemFactory().kotlinMetadataType)
+ != null;
+ }
+
public static KotlinClassMetadata toKotlinClassMetadata(
Kotlin kotlin, DexEncodedAnnotation metadataAnnotation) {
Map<DexString, DexAnnotationElement> elementMap = new IdentityHashMap<>();
@@ -103,7 +108,7 @@
Kotlin kotlin,
DexClass clazz,
KotlinClassMetadata kMetadata,
- DexDefinitionSupplier definitionSupplier,
+ DexItemFactory factory,
Reporter reporter,
Consumer<DexEncodedMethod> keepByteCode) {
String packageName = kMetadata.getHeader().getPackageName();
@@ -112,7 +117,7 @@
((KotlinClassMetadata.Class) kMetadata).toKmClass(),
packageName,
clazz,
- definitionSupplier,
+ factory,
reporter,
keepByteCode);
} else if (kMetadata instanceof KotlinClassMetadata.FileFacade) {
@@ -121,20 +126,20 @@
(KotlinClassMetadata.FileFacade) kMetadata,
packageName,
clazz,
- definitionSupplier,
+ factory,
reporter,
keepByteCode);
} else if (kMetadata instanceof KotlinClassMetadata.MultiFileClassFacade) {
// multi-file class with the same @JvmName.
return KotlinMultiFileClassFacadeInfo.create(
- (KotlinClassMetadata.MultiFileClassFacade) kMetadata, packageName, definitionSupplier);
+ (KotlinClassMetadata.MultiFileClassFacade) kMetadata, packageName, factory);
} else if (kMetadata instanceof KotlinClassMetadata.MultiFileClassPart) {
// A single file, which is part of multi-file class.
return KotlinMultiFileClassPartInfo.create(
(KotlinClassMetadata.MultiFileClassPart) kMetadata,
packageName,
clazz,
- definitionSupplier,
+ factory,
reporter,
keepByteCode);
} else if (kMetadata instanceof KotlinClassMetadata.SyntheticClass) {
@@ -143,7 +148,7 @@
packageName,
clazz,
kotlin,
- definitionSupplier,
+ factory,
reporter);
} else {
throw new MetadataError("unsupported 'k' value: " + kMetadata.getHeader().getKind());
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..ac19e28 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinClassifierInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClassifierInfo.java
@@ -4,15 +4,13 @@
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.graph.DexItemFactory;
import com.android.tools.r8.kotlin.Kotlin.ClassClassifiers;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.Reporter;
import kotlinx.metadata.KmClassifier;
@@ -20,10 +18,10 @@
import kotlinx.metadata.KmClassifier.TypeParameter;
import kotlinx.metadata.KmTypeVisitor;
-public abstract class KotlinClassifierInfo {
+public abstract class KotlinClassifierInfo implements EnqueuerMetadataTraceable {
public static KotlinClassifierInfo create(
- KmClassifier classifier, DexDefinitionSupplier definitionSupplier, Reporter reporter) {
+ KmClassifier classifier, DexItemFactory factory, Reporter reporter) {
if (classifier instanceof KmClassifier.Class) {
String originalTypeName = ((KmClassifier.Class) classifier).getName();
// If this name starts with '.', it represents a local class or an anonymous object. This is
@@ -35,7 +33,7 @@
isLocalOrAnonymous ? originalTypeName.substring(1) : originalTypeName);
if (DescriptorUtils.isClassDescriptor(descriptor)) {
return new KotlinClassClassifierInfo(
- referenceTypeFromDescriptor(descriptor, definitionSupplier), isLocalOrAnonymous);
+ KotlinTypeReference.fromDescriptor(descriptor, factory), isLocalOrAnonymous);
} else {
return new KotlinUnknownClassClassifierInfo(originalTypeName);
}
@@ -54,10 +52,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,20 +63,21 @@
@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.anyDescriptor);
// 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));
}
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ type.trace(definitionSupplier);
+ }
}
public static class KotlinTypeParameterClassifierInfo extends KotlinClassifierInfo {
@@ -94,6 +93,11 @@
KmTypeVisitor visitor, AppView<AppInfoWithLiveness> appView, NamingLens namingLens) {
visitor.visitTypeParameter(typeId);
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ // Intentionally empty.
+ }
}
public static class KotlinTypeAliasClassifierInfo extends KotlinClassifierInfo {
@@ -109,6 +113,11 @@
KmTypeVisitor visitor, AppView<AppInfoWithLiveness> appView, NamingLens namingLens) {
visitor.visitTypeAlias(typeAlias);
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ // Intentionally empty.
+ }
}
public static class KotlinUnknownClassClassifierInfo extends KotlinClassifierInfo {
@@ -123,6 +132,11 @@
KmTypeVisitor visitor, AppView<AppInfoWithLiveness> appView, NamingLens namingLens) {
visitor.visitClass(classifier);
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ // Intentionally empty.
+ }
}
public static class KotlinUnknownClassifierInfo extends KotlinClassifierInfo {
@@ -137,5 +151,10 @@
KmTypeVisitor visitor, AppView<AppInfoWithLiveness> appView, NamingLens namingLens) {
visitor.visitTypeAlias(classifier);
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ // Intentionally empty.
+ }
}
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinCompanionInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinCompanionInfo.java
index 2f97b4f..1e19f1a 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinCompanionInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinCompanionInfo.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.kotlin;
+import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.naming.NamingLens;
@@ -27,4 +28,9 @@
String finalName = dexString.toString();
visitor.visitCompanionObject(finalName);
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ // Do nothing.
+ }
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinConstructorInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinConstructorInfo.java
index 6f9f366..857ef39 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinConstructorInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinConstructorInfo.java
@@ -4,9 +4,12 @@
package com.android.tools.r8.kotlin;
+import static com.android.tools.r8.utils.FunctionUtils.forEachApply;
+
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.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.Reporter;
@@ -35,13 +38,11 @@
}
public static KotlinConstructorInfo create(
- KmConstructor kmConstructor, DexDefinitionSupplier definitionSupplier, Reporter reporter) {
+ KmConstructor kmConstructor, DexItemFactory factory, Reporter reporter) {
return new KotlinConstructorInfo(
kmConstructor.getFlags(),
- KotlinValueParameterInfo.create(
- kmConstructor.getValueParameters(), definitionSupplier, reporter),
- KotlinJvmMethodSignatureInfo.create(
- JvmExtensionsKt.getSignature(kmConstructor), definitionSupplier));
+ KotlinValueParameterInfo.create(kmConstructor.getValueParameters(), factory, reporter),
+ KotlinJvmMethodSignatureInfo.create(JvmExtensionsKt.getSignature(kmConstructor), factory));
}
public void rewrite(
@@ -71,4 +72,12 @@
public KotlinConstructorInfo asConstructor() {
return this;
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ forEachApply(valueParameterInfos, param -> param::trace, definitionSupplier);
+ if (signature != null) {
+ signature.trace(definitionSupplier);
+ }
+ }
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinDeclarationContainerInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinDeclarationContainerInfo.java
index cd349ab..a83f77a 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinDeclarationContainerInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinDeclarationContainerInfo.java
@@ -5,15 +5,18 @@
package com.android.tools.r8.kotlin;
import static com.android.tools.r8.kotlin.KotlinMetadataUtils.isValidMethodDescriptor;
+import static com.android.tools.r8.utils.FunctionUtils.forEachApply;
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.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.kotlin.KotlinMetadataUtils.KmPropertyProcessor;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import com.android.tools.r8.utils.Reporter;
import com.google.common.collect.ImmutableList;
import java.util.IdentityHashMap;
@@ -29,7 +32,7 @@
import kotlinx.metadata.jvm.JvmMethodSignature;
// Holds information about KmDeclarationContainer
-public class KotlinDeclarationContainerInfo {
+public class KotlinDeclarationContainerInfo implements EnqueuerMetadataTraceable {
private final List<KotlinTypeAliasInfo> typeAliases;
// The functions in notBackedFunctions are KmFunctions where we could not find a representative.
@@ -51,7 +54,7 @@
KmDeclarationContainer container,
Map<String, DexEncodedMethod> methodSignatureMap,
Map<String, DexEncodedField> fieldSignatureMap,
- DexDefinitionSupplier definitionSupplier,
+ DexItemFactory factory,
Reporter reporter,
Consumer<DexEncodedMethod> keepByteCode) {
ImmutableList.Builder<KotlinFunctionInfo> notBackedFunctions = ImmutableList.builder();
@@ -62,7 +65,7 @@
continue;
}
KotlinFunctionInfo kotlinFunctionInfo =
- KotlinFunctionInfo.create(kmFunction, definitionSupplier, reporter);
+ KotlinFunctionInfo.create(kmFunction, factory, reporter);
DexEncodedMethod method = methodSignatureMap.get(signature.asString());
if (method == null) {
notBackedFunctions.add(kotlinFunctionInfo);
@@ -85,7 +88,7 @@
ImmutableList.Builder<KotlinPropertyInfo> notBackedProperties = ImmutableList.builder();
for (KmProperty kmProperty : container.getProperties()) {
KotlinPropertyInfo kotlinPropertyInfo =
- KotlinPropertyInfo.create(kmProperty, definitionSupplier, reporter);
+ KotlinPropertyInfo.create(kmProperty, factory, reporter);
KmPropertyProcessor propertyProcessor = new KmPropertyProcessor(kmProperty);
boolean hasBacking = false;
if (propertyProcessor.fieldSignature() != null) {
@@ -119,7 +122,7 @@
}
}
return new KotlinDeclarationContainerInfo(
- getTypeAliases(container.getTypeAliases(), definitionSupplier, reporter),
+ getTypeAliases(container.getTypeAliases(), factory, reporter),
notBackedFunctions.build(),
notBackedProperties.build());
}
@@ -139,10 +142,10 @@
}
private static List<KotlinTypeAliasInfo> getTypeAliases(
- List<KmTypeAlias> aliases, DexDefinitionSupplier definitionSupplier, Reporter reporter) {
+ List<KmTypeAlias> aliases, DexItemFactory factory, Reporter reporter) {
ImmutableList.Builder<KotlinTypeAliasInfo> builder = ImmutableList.builder();
for (KmTypeAlias alias : aliases) {
- builder.add(KotlinTypeAliasInfo.create(alias, definitionSupplier, reporter));
+ builder.add(KotlinTypeAliasInfo.create(alias, factory, reporter));
}
return builder.build();
}
@@ -208,6 +211,13 @@
}
}
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ forEachApply(typeAliases, alias -> alias::trace, definitionSupplier);
+ forEachApply(functionsWithNoBacking, function -> function::trace, definitionSupplier);
+ forEachApply(propertiesWithNoBacking, property -> property::trace, definitionSupplier);
+ }
+
public static class KotlinPropertyGroup {
private DexEncodedField backingField = null;
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinFieldLevelInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinFieldLevelInfo.java
index 7df7afb..8d9d468 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinFieldLevelInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinFieldLevelInfo.java
@@ -4,7 +4,9 @@
package com.android.tools.r8.kotlin;
-public interface KotlinFieldLevelInfo {
+import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
+
+public interface KotlinFieldLevelInfo extends EnqueuerMetadataTraceable {
default boolean isCompanion() {
return false;
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinFileFacadeInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinFileFacadeInfo.java
index c31df8c..94617e1 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinFileFacadeInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinFileFacadeInfo.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.Reporter;
@@ -32,12 +33,12 @@
FileFacade kmFileFacade,
String packageName,
DexClass clazz,
- DexDefinitionSupplier definitionSupplier,
+ DexItemFactory factory,
Reporter reporter,
Consumer<DexEncodedMethod> keepByteCode) {
return new KotlinFileFacadeInfo(
KotlinPackageInfo.create(
- kmFileFacade.toKmPackage(), clazz, definitionSupplier, reporter, keepByteCode),
+ kmFileFacade.toKmPackage(), clazz, factory, reporter, keepByteCode),
packageName);
}
@@ -65,4 +66,9 @@
public String getPackageName() {
return packageName;
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ packageInfo.trace(definitionSupplier);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinFlexibleTypeUpperBoundInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinFlexibleTypeUpperBoundInfo.java
index c8c8836..da2e960 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinFlexibleTypeUpperBoundInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinFlexibleTypeUpperBoundInfo.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexDefinitionSupplier;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.Reporter;
@@ -45,22 +46,20 @@
}
static KotlinFlexibleTypeUpperBoundInfo create(
- KmFlexibleTypeUpperBound flexibleTypeUpperBound,
- DexDefinitionSupplier definitionSupplier,
- Reporter reporter) {
+ KmFlexibleTypeUpperBound flexibleTypeUpperBound, DexItemFactory factory, Reporter reporter) {
if (flexibleTypeUpperBound == null) {
return NO_FLEXIBLE_UPPER_BOUND;
}
KmType kmType = flexibleTypeUpperBound.getType();
return new KotlinFlexibleTypeUpperBoundInfo(
kmType.getFlags(),
- KotlinClassifierInfo.create(kmType.classifier, definitionSupplier, reporter),
- KotlinTypeInfo.create(kmType.getAbbreviatedType(), definitionSupplier, reporter),
- KotlinTypeInfo.create(kmType.getOuterType(), definitionSupplier, reporter),
- getArguments(kmType.getArguments(), definitionSupplier, reporter),
- KotlinAnnotationInfo.create(JvmExtensionsKt.getAnnotations(kmType), definitionSupplier),
+ KotlinClassifierInfo.create(kmType.classifier, factory, reporter),
+ KotlinTypeInfo.create(kmType.getAbbreviatedType(), factory, reporter),
+ KotlinTypeInfo.create(kmType.getOuterType(), factory, reporter),
+ getArguments(kmType.getArguments(), factory, reporter),
+ KotlinAnnotationInfo.create(JvmExtensionsKt.getAnnotations(kmType), factory),
KotlinFlexibleTypeUpperBoundInfo.create(
- kmType.getFlexibleTypeUpperBound(), definitionSupplier, reporter),
+ kmType.getFlexibleTypeUpperBound(), factory, reporter),
flexibleTypeUpperBound.getTypeFlexibilityId());
}
@@ -74,4 +73,12 @@
}
super.rewrite(flags -> visitorProvider.get(flags, typeFlexibilityId), appView, namingLens);
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ if (this == NO_FLEXIBLE_UPPER_BOUND) {
+ return;
+ }
+ super.trace(definitionSupplier);
+ }
}
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..341d7b0 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,12 @@
package com.android.tools.r8.kotlin;
-import static com.android.tools.r8.kotlin.KotlinMetadataUtils.referenceTypeFromBinaryName;
+import static com.android.tools.r8.utils.FunctionUtils.forEachApply;
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.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.Reporter;
@@ -36,7 +36,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 +46,7 @@
List<KotlinValueParameterInfo> valueParameters,
List<KotlinTypeParameterInfo> typeParameters,
KotlinJvmMethodSignatureInfo signature,
- DexType lambdaClassOrigin) {
+ KotlinTypeReference lambdaClassOrigin) {
this.flags = flags;
this.name = name;
this.returnType = returnType;
@@ -58,26 +58,23 @@
}
static KotlinFunctionInfo create(
- KmFunction kmFunction, DexDefinitionSupplier definitionSupplier, Reporter reporter) {
+ KmFunction kmFunction, DexItemFactory factory, Reporter reporter) {
return new KotlinFunctionInfo(
kmFunction.getFlags(),
kmFunction.getName(),
- KotlinTypeInfo.create(kmFunction.getReturnType(), definitionSupplier, reporter),
- KotlinTypeInfo.create(kmFunction.getReceiverParameterType(), definitionSupplier, reporter),
- KotlinValueParameterInfo.create(
- kmFunction.getValueParameters(), definitionSupplier, reporter),
- KotlinTypeParameterInfo.create(
- kmFunction.getTypeParameters(), definitionSupplier, reporter),
- KotlinJvmMethodSignatureInfo.create(
- JvmExtensionsKt.getSignature(kmFunction), definitionSupplier),
- getlambdaClassOrigin(kmFunction, definitionSupplier));
+ KotlinTypeInfo.create(kmFunction.getReturnType(), factory, reporter),
+ KotlinTypeInfo.create(kmFunction.getReceiverParameterType(), factory, reporter),
+ KotlinValueParameterInfo.create(kmFunction.getValueParameters(), factory, reporter),
+ KotlinTypeParameterInfo.create(kmFunction.getTypeParameters(), factory, reporter),
+ KotlinJvmMethodSignatureInfo.create(JvmExtensionsKt.getSignature(kmFunction), factory),
+ getlambdaClassOrigin(kmFunction, factory));
}
- private static DexType getlambdaClassOrigin(
- KmFunction kmFunction, DexDefinitionSupplier definitionSupplier) {
+ private static KotlinTypeReference getlambdaClassOrigin(
+ KmFunction kmFunction, DexItemFactory factory) {
String lambdaClassOriginName = JvmExtensionsKt.getLambdaClassOriginName(kmFunction);
if (lambdaClassOriginName != null) {
- return referenceTypeFromBinaryName(lambdaClassOriginName, definitionSupplier);
+ return KotlinTypeReference.fromBinaryName(lambdaClassOriginName, factory);
}
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);
+ }
}
}
@@ -132,4 +132,24 @@
public boolean isExtensionFunction() {
return receiverParameterType != null;
}
+
+ public KotlinJvmMethodSignatureInfo getSignature() {
+ return signature;
+ }
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ forEachApply(valueParameters, param -> param::trace, definitionSupplier);
+ returnType.trace(definitionSupplier);
+ if (receiverParameterType != null) {
+ receiverParameterType.trace(definitionSupplier);
+ }
+ forEachApply(typeParameters, param -> param::trace, definitionSupplier);
+ if (signature != null) {
+ signature.trace(definitionSupplier);
+ }
+ if (lambdaClassOrigin != null) {
+ lambdaClassOrigin.trace(definitionSupplier);
+ }
+ }
}
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..6daf3d7 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinJvmFieldSignatureInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinJvmFieldSignatureInfo.java
@@ -4,39 +4,37 @@
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.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import kotlinx.metadata.jvm.JvmFieldSignature;
/**
* The JvmSignature for a method or property does not always correspond to the actual signature, see
* b/154201250. We therefore need to model the signature as well.
*/
-public class KotlinJvmFieldSignatureInfo {
+public class KotlinJvmFieldSignatureInfo implements EnqueuerMetadataTraceable {
- 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;
}
public static KotlinJvmFieldSignatureInfo create(
- JvmFieldSignature fieldSignature, DexDefinitionSupplier definitionSupplier) {
+ JvmFieldSignature fieldSignature, DexItemFactory factory) {
if (fieldSignature == null) {
return null;
}
return new KotlinJvmFieldSignatureInfo(
fieldSignature.getName(),
- referenceTypeFromDescriptor(fieldSignature.getDesc(), definitionSupplier));
+ KotlinTypeReference.fromDescriptor(fieldSignature.getDesc(), factory));
}
public JvmFieldSignature rewrite(
@@ -51,6 +49,11 @@
}
String defValue = appView.dexItemFactory().objectType.toDescriptorString();
return new JvmFieldSignature(
- finalName, toRenamedDescriptorOrDefault(type, appView, namingLens, defValue));
+ finalName, type.toRenamedDescriptorOrDefault(appView, namingLens, defValue));
+ }
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ type.trace(definitionSupplier);
}
}
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..f4674a1 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinJvmMethodSignatureInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinJvmMethodSignatureInfo.java
@@ -4,15 +4,15 @@
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 static com.android.tools.r8.utils.FunctionUtils.forEachApply;
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.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import com.android.tools.r8.utils.DescriptorUtils;
import com.google.common.collect.ImmutableList;
import java.util.List;
@@ -22,36 +22,51 @@
* The JvmSignature for a method or property does not always correspond to the actual signature, see
* b/154201250. We therefore need to model the signature as well.
*/
-public class KotlinJvmMethodSignatureInfo {
+public class KotlinJvmMethodSignatureInfo implements EnqueuerMetadataTraceable {
- 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 final String invalidDescriptor;
- 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;
+ this.invalidDescriptor = null;
+ }
+
+ private KotlinJvmMethodSignatureInfo(String name, String invalidDescriptor) {
+ this.name = name;
+ this.invalidDescriptor = invalidDescriptor;
+ this.parameters = EMPTY_PARAMETERS_LIST;
+ this.returnType = null;
}
public static KotlinJvmMethodSignatureInfo create(
- JvmMethodSignature methodSignature, DexDefinitionSupplier definitionSupplier) {
+ JvmMethodSignature methodSignature, DexItemFactory factory) {
if (methodSignature == null) {
return null;
}
String kotlinDescriptor = methodSignature.getDesc();
+ if (!KotlinMetadataUtils.isValidMethodDescriptor(kotlinDescriptor)) {
+ // If the method descriptor is invalid, keep it as invalid.
+ return new KotlinJvmMethodSignatureInfo(methodSignature.getName(), kotlinDescriptor);
+ }
String returnTypeDescriptor = DescriptorUtils.getReturnTypeDescriptor(kotlinDescriptor);
- DexType returnType = referenceTypeFromDescriptor(returnTypeDescriptor, definitionSupplier);
+ KotlinTypeReference returnType =
+ KotlinTypeReference.fromDescriptor(returnTypeDescriptor, factory);
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.fromDescriptor(descriptor, factory));
}
return new KotlinJvmMethodSignatureInfo(
methodSignature.getName(), returnType, parameters.build());
@@ -59,6 +74,10 @@
public JvmMethodSignature rewrite(
DexEncodedMethod method, AppView<AppInfoWithLiveness> appView, NamingLens namingLens) {
+ if (invalidDescriptor != null) {
+ return new JvmMethodSignature(name, invalidDescriptor);
+ }
+ assert returnType != null;
String finalName = name;
if (method != null) {
String methodName = method.method.name.toString();
@@ -70,11 +89,38 @@
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());
}
+
+ @Override
+ public String toString() {
+ if (invalidDescriptor != null) {
+ return name + "(" + invalidDescriptor + ")";
+ }
+ assert returnType != null;
+ StringBuilder descBuilder = new StringBuilder();
+ descBuilder.append(name);
+ descBuilder.append("(");
+ for (KotlinTypeReference parameter : parameters) {
+ descBuilder.append(parameter.toString());
+ }
+ descBuilder.append(")");
+ descBuilder.append(returnType.toString());
+ return descBuilder.toString();
+ }
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ if (invalidDescriptor != null) {
+ return;
+ }
+ assert returnType != null;
+ returnType.trace(definitionSupplier);
+ forEachApply(parameters, param -> param::trace, definitionSupplier);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinLambdaInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinLambdaInfo.java
index d25f105..459599b 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinLambdaInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinLambdaInfo.java
@@ -10,48 +10,44 @@
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import com.android.tools.r8.utils.Reporter;
import kotlinx.metadata.KmLambda;
-import kotlinx.metadata.KmLambdaVisitor;
import kotlinx.metadata.jvm.JvmExtensionsKt;
import kotlinx.metadata.jvm.JvmMethodSignature;
// Holds information about a KmLambda
-public class KotlinLambdaInfo {
+public class KotlinLambdaInfo implements EnqueuerMetadataTraceable {
private final KotlinFunctionInfo function;
+ private final boolean hasBacking;
- private KotlinLambdaInfo(KotlinFunctionInfo function) {
+ private KotlinLambdaInfo(KotlinFunctionInfo function, boolean hasBacking) {
this.function = function;
+ this.hasBacking = hasBacking;
}
static KotlinLambdaInfo create(
- DexClass clazz,
- KmLambda lambda,
- DexDefinitionSupplier definitionSupplier,
- Reporter reporter) {
+ DexClass clazz, KmLambda lambda, DexItemFactory factory, Reporter reporter) {
if (lambda == null) {
assert false;
return null;
}
+ KotlinFunctionInfo kotlinFunctionInfo =
+ KotlinFunctionInfo.create(lambda.function, factory, reporter);
JvmMethodSignature signature = JvmExtensionsKt.getSignature(lambda.function);
- if (signature == null) {
- assert false;
- return null;
- }
- for (DexEncodedMethod method : clazz.methods()) {
- if (toJvmMethodSignature(method.method).asString().equals(signature.asString())) {
- KotlinFunctionInfo kotlinFunctionInfo =
- KotlinFunctionInfo.create(lambda.function, definitionSupplier, reporter);
- method.setKotlinMemberInfo(kotlinFunctionInfo);
- return new KotlinLambdaInfo(kotlinFunctionInfo);
+ if (signature != null) {
+ for (DexEncodedMethod method : clazz.methods()) {
+ if (toJvmMethodSignature(method.method).asString().equals(signature.asString())) {
+ method.setKotlinMemberInfo(kotlinFunctionInfo);
+ return new KotlinLambdaInfo(kotlinFunctionInfo, true);
+ }
}
}
- // TODO(b/155536535): Resolve this assert for NestTreeShakeJarVerificationTest.
- // assert false;
- return null;
+ return new KotlinLambdaInfo(kotlinFunctionInfo, false);
}
boolean rewrite(
@@ -59,13 +55,31 @@
DexClass clazz,
AppView<AppInfoWithLiveness> appView,
NamingLens namingLens) {
+ if (!hasBacking) {
+ function.rewrite(visitorProvider.get()::visitFunction, null, appView, namingLens);
+ return true;
+ }
+ DexEncodedMethod backing = null;
for (DexEncodedMethod method : clazz.methods()) {
if (method.getKotlinMemberInfo() == function) {
- KmLambdaVisitor kmLambdaVisitor = visitorProvider.get();
- function.rewrite(kmLambdaVisitor::visitFunction, method, appView, namingLens);
- return true;
+ backing = method;
+ break;
}
}
- return false;
+ if (backing == null) {
+ appView
+ .options()
+ .reporter
+ .info(
+ KotlinMetadataDiagnostic.lambdaBackingNotFound(clazz.type, function.getSignature()));
+ return false;
+ }
+ function.rewrite(visitorProvider.get()::visitFunction, backing, appView, namingLens);
+ return true;
+ }
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ function.trace(definitionSupplier);
}
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataDiagnostic.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataDiagnostic.java
index 83947d7..3415e13 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataDiagnostic.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataDiagnostic.java
@@ -73,4 +73,18 @@
+ StringUtils.LINE_SEPARATOR
+ StringUtils.stacktraceAsString(t));
}
+
+ static KotlinMetadataDiagnostic lambdaBackingNotFound(
+ DexType type, KotlinJvmMethodSignatureInfo signatureInfo) {
+ return new KotlinMetadataDiagnostic(
+ Origin.unknown(),
+ Position.UNKNOWN,
+ "The lambda function "
+ + signatureInfo.toString()
+ + " could no longer be found in "
+ + type.toSourceString()
+ + " . The method is most likely pruned and would require a specific keep rule to keep"
+ + " alive. As a result, the metadata information regarding the lambda structure has"
+ + " been discarded.");
+ }
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataEnqueuerExtension.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataEnqueuerExtension.java
index 8b503e6..3fbf7ce 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataEnqueuerExtension.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataEnqueuerExtension.java
@@ -4,10 +4,22 @@
package com.android.tools.r8.kotlin;
+import static com.android.tools.r8.kotlin.KotlinClassMetadataReader.hasKotlinClassMetadataAnnotation;
+import static com.android.tools.r8.kotlin.KotlinMetadataUtils.NO_KOTLIN_INFO;
+import static com.android.tools.r8.utils.FunctionUtils.forEachApply;
+
+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.DexDefinition;
import com.android.tools.r8.graph.DexDefinitionSupplier;
+import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.DexEncodedMethod;
+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.DexProgramClass;
+import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.analysis.EnqueuerAnalysis;
import com.android.tools.r8.shaking.Enqueuer;
@@ -18,12 +30,11 @@
private final AppView<?> appView;
private final DexDefinitionSupplier definitionSupplier;
- private final Set<DexMethod> keepByteCodeFunctions = Sets.newIdentityHashSet();
public KotlinMetadataEnqueuerExtension(
- AppView<?> appView, DexDefinitionSupplier definitionSupplier) {
+ AppView<?> appView, DexDefinitionSupplier definitionSupplier, Set<DexType> prunedTypes) {
this.appView = appView;
- this.definitionSupplier = definitionSupplier;
+ this.definitionSupplier = new KotlinMetadataDefinitionSupplier(definitionSupplier, prunedTypes);
}
@Override
@@ -31,23 +42,99 @@
DexType kotlinMetadataType = appView.dexItemFactory().kotlinMetadataType;
DexClass kotlinMetadataClass =
appView.appInfo().definitionForWithoutExistenceAssert(kotlinMetadataType);
- // We will process kotlin.Metadata even if the type is not present in the program, as long as
- // the annotation will be in the output
+ // In the first round of tree shaking build up all metadata such that it can be traced later.
boolean keepMetadata =
kotlinMetadataClass == null
|| kotlinMetadataClass.isNotProgramClass()
|| enqueuer.isPinned(kotlinMetadataType);
+ if (enqueuer.getMode().isInitialTreeShaking()) {
+ Set<DexMethod> keepByteCodeFunctions = Sets.newIdentityHashSet();
+ enqueuer.forAllLiveClasses(
+ clazz -> {
+ boolean onlyProcessLambdas = !keepMetadata || !enqueuer.isPinned(clazz.type);
+ assert clazz.getKotlinInfo().isNoKotlinInformation();
+ clazz.setKotlinInfo(
+ KotlinClassMetadataReader.getKotlinInfo(
+ appView.dexItemFactory().kotlin,
+ clazz,
+ definitionSupplier.dexItemFactory(),
+ appView.options().reporter,
+ onlyProcessLambdas,
+ method -> keepByteCodeFunctions.add(method.method)));
+ });
+ appView.setCfByteCodePassThrough(keepByteCodeFunctions);
+ } else {
+ assert verifyKotlinMetadataModeledForAllClasses(enqueuer, keepMetadata);
+ }
+ // Trace through the modeled kotlin metadata.
enqueuer.forAllLiveClasses(
clazz -> {
- clazz.setKotlinInfo(
- KotlinClassMetadataReader.getKotlinInfo(
- appView.dexItemFactory().kotlin,
- clazz,
- definitionSupplier,
- appView.options().reporter,
- !keepMetadata || !enqueuer.isPinned(clazz.type),
- method -> keepByteCodeFunctions.add(method.method)));
+ clazz.getKotlinInfo().trace(definitionSupplier);
+ forEachApply(
+ clazz.methods(), method -> method.getKotlinMemberInfo()::trace, definitionSupplier);
+ forEachApply(
+ clazz.fields(), field -> field.getKotlinMemberInfo()::trace, definitionSupplier);
});
- appView.setCfByteCodePassThrough(keepByteCodeFunctions);
+ }
+
+ private boolean verifyKotlinMetadataModeledForAllClasses(
+ Enqueuer enqueuer, boolean keepMetadata) {
+ enqueuer.forAllLiveClasses(
+ clazz -> {
+ // Trace through class and member definitions
+ assert !hasKotlinClassMetadataAnnotation(clazz, definitionSupplier)
+ || !keepMetadata
+ || !enqueuer.isPinned(clazz.type)
+ || clazz.getKotlinInfo() != NO_KOTLIN_INFO;
+ });
+ return true;
+ }
+
+ public static class KotlinMetadataDefinitionSupplier implements DexDefinitionSupplier {
+
+ private final DexDefinitionSupplier baseSupplier;
+ private final Set<DexType> prunedTypes;
+
+ private KotlinMetadataDefinitionSupplier(
+ DexDefinitionSupplier baseSupplier, Set<DexType> prunedTypes) {
+ this.baseSupplier = baseSupplier;
+ this.prunedTypes = prunedTypes;
+ }
+
+ @Override
+ public DexDefinition definitionFor(DexReference reference) {
+ throw new Unreachable("Should not be called");
+ }
+
+ @Override
+ public DexEncodedField definitionFor(DexField field) {
+ throw new Unreachable("Should not be called");
+ }
+
+ @Override
+ public DexEncodedMethod definitionFor(DexMethod method) {
+ throw new Unreachable("Should not be called");
+ }
+
+ @Override
+ public DexClass definitionFor(DexType type) {
+ // TODO(b/157700128) Metadata cannot at this point keep anything alive. Therefore, if a type
+ // has been pruned it may still be referenced, so we do an early check here to ensure it will
+ // not end up as. Ideally, those types should be removed by a pass on the modeled data.
+ if (prunedTypes != null && prunedTypes.contains(type)) {
+ return null;
+ }
+ return baseSupplier.definitionFor(type);
+ }
+
+ @Override
+ public DexProgramClass definitionForProgramType(DexType type) {
+ throw new Unreachable("Should not be called");
+ }
+
+ @Override
+ public DexItemFactory dexItemFactory() {
+ return baseSupplier.dexItemFactory();
+ }
}
}
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..1ee78a5 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataUtils.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataUtils.java
@@ -12,7 +12,6 @@
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;
@@ -59,6 +58,16 @@
public String getPackageName() {
throw new Unreachable("Should never be called");
}
+
+ @Override
+ public boolean isNoKotlinInformation() {
+ return true;
+ }
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ // No information needed to trace.
+ }
}
static JvmFieldSignature toJvmFieldSignature(DexField field) {
@@ -137,41 +146,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/KotlinMethodLevelInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMethodLevelInfo.java
index 604374e..a02cb0a 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMethodLevelInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMethodLevelInfo.java
@@ -4,7 +4,9 @@
package com.android.tools.r8.kotlin;
-public interface KotlinMethodLevelInfo {
+import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
+
+public interface KotlinMethodLevelInfo extends EnqueuerMetadataTraceable {
default boolean isConstructor() {
return false;
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 3baea9c..1ccd35f 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMultiFileClassFacadeInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMultiFileClassFacadeInfo.java
@@ -4,14 +4,14 @@
package com.android.tools.r8.kotlin;
+import static com.android.tools.r8.utils.FunctionUtils.forEachApply;
+
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.DexString;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.DescriptorUtils;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
@@ -22,23 +22,20 @@
// Holds information about Metadata.MultiFileClassFace
public class KotlinMultiFileClassFacadeInfo implements KotlinClassLevelInfo {
- private final List<DexType> partClassNames;
+ private final List<KotlinTypeReference> partClassNames;
private final String packageName;
- private KotlinMultiFileClassFacadeInfo(List<DexType> partClassNames, String packageName) {
+ private KotlinMultiFileClassFacadeInfo(
+ List<KotlinTypeReference> partClassNames, String packageName) {
this.partClassNames = partClassNames;
this.packageName = packageName;
}
static KotlinMultiFileClassFacadeInfo create(
- MultiFileClassFacade kmMultiFileClassFacade,
- String packageName,
- DexDefinitionSupplier definitionSupplier) {
- ImmutableList.Builder<DexType> builder = ImmutableList.builder();
+ MultiFileClassFacade kmMultiFileClassFacade, String packageName, DexItemFactory factory) {
+ ImmutableList.Builder<KotlinTypeReference> builder = ImmutableList.builder();
for (String partClassName : kmMultiFileClassFacade.getPartClassNames()) {
- String descriptor = DescriptorUtils.getDescriptorFromClassBinaryName(partClassName);
- DexType type = definitionSupplier.dexItemFactory().createType(descriptor);
- builder.add(type);
+ builder.add(KotlinTypeReference.fromBinaryName(partClassName, factory));
}
return new KotlinMultiFileClassFacadeInfo(builder.build(), packageName);
}
@@ -59,11 +56,10 @@
KotlinClassMetadata.MultiFileClassFacade.Writer writer =
new KotlinClassMetadata.MultiFileClassFacade.Writer();
List<String> partClassNameStrings = new ArrayList<>(partClassNames.size());
- for (DexType partClassName : partClassNames) {
- if (appView.appInfo().isNonProgramTypeOrLiveProgramType(partClassName)) {
- DexString descriptor = namingLens.lookupDescriptor(partClassName);
- String classifier = DescriptorUtils.descriptorToKotlinClassifier(descriptor.toString());
- partClassNameStrings.add(classifier);
+ for (KotlinTypeReference partClassName : partClassNames) {
+ String binaryName = partClassName.toRenamedBinaryNameOrDefault(appView, namingLens, null);
+ if (binaryName != null) {
+ partClassNameStrings.add(binaryName);
}
}
return writer.write(partClassNameStrings).getHeader();
@@ -73,4 +69,9 @@
public String getPackageName() {
return packageName;
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ forEachApply(partClassNames, type -> type::trace, definitionSupplier);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMultiFileClassPartInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMultiFileClassPartInfo.java
index d4ec800..9470082 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMultiFileClassPartInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMultiFileClassPartInfo.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.Reporter;
@@ -20,6 +21,7 @@
// Holds information about Metadata.MultiFileClassPartInfo
public class KotlinMultiFileClassPartInfo implements KotlinClassLevelInfo {
+ // TODO(b/157630779): Maybe model facadeClassName.
private final String facadeClassName;
private final KotlinPackageInfo packageInfo;
private final String packageName;
@@ -35,13 +37,12 @@
MultiFileClassPart classPart,
String packageName,
DexClass clazz,
- DexDefinitionSupplier definitionSupplier,
+ DexItemFactory factory,
Reporter reporter,
Consumer<DexEncodedMethod> keepByteCode) {
return new KotlinMultiFileClassPartInfo(
classPart.getFacadeClassName(),
- KotlinPackageInfo.create(
- classPart.toKmPackage(), clazz, definitionSupplier, reporter, keepByteCode),
+ KotlinPackageInfo.create(classPart.toKmPackage(), clazz, factory, reporter, keepByteCode),
packageName);
}
@@ -70,4 +71,9 @@
public String getPackageName() {
return packageName;
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ packageInfo.trace(definitionSupplier);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinPackageInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinPackageInfo.java
index d98e109..8f0268a 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinPackageInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinPackageInfo.java
@@ -12,8 +12,10 @@
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import com.android.tools.r8.utils.Reporter;
import java.util.HashMap;
import java.util.Map;
@@ -22,7 +24,7 @@
import kotlinx.metadata.jvm.JvmExtensionsKt;
// Holds information about a KmPackage object.
-public class KotlinPackageInfo {
+public class KotlinPackageInfo implements EnqueuerMetadataTraceable {
private final String moduleName;
private final KotlinDeclarationContainerInfo containerInfo;
@@ -35,7 +37,7 @@
public static KotlinPackageInfo create(
KmPackage kmPackage,
DexClass clazz,
- DexDefinitionSupplier definitionSupplier,
+ DexItemFactory factory,
Reporter reporter,
Consumer<DexEncodedMethod> keepByteCode) {
Map<String, DexEncodedField> fieldMap = new HashMap<>();
@@ -49,7 +51,7 @@
return new KotlinPackageInfo(
JvmExtensionsKt.getModuleName(kmPackage),
KotlinDeclarationContainerInfo.create(
- kmPackage, methodMap, fieldMap, definitionSupplier, reporter, keepByteCode));
+ kmPackage, methodMap, fieldMap, factory, reporter, keepByteCode));
}
public void rewrite(
@@ -66,4 +68,9 @@
namingLens);
JvmExtensionsKt.setModuleName(kmPackage, moduleName);
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ containerInfo.trace(definitionSupplier);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinPropertyInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinPropertyInfo.java
index 802428a..94afee8 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinPropertyInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinPropertyInfo.java
@@ -4,10 +4,13 @@
package com.android.tools.r8.kotlin;
+import static com.android.tools.r8.utils.FunctionUtils.forEachApply;
+
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.DexEncodedMethod;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.Reporter;
@@ -81,27 +84,24 @@
}
public static KotlinPropertyInfo create(
- KmProperty kmProperty, DexDefinitionSupplier definitionSupplier, Reporter reporter) {
+ KmProperty kmProperty, DexItemFactory factory, Reporter reporter) {
return new KotlinPropertyInfo(
kmProperty.getFlags(),
kmProperty.getGetterFlags(),
kmProperty.getSetterFlags(),
kmProperty.getName(),
- KotlinTypeInfo.create(kmProperty.getReturnType(), definitionSupplier, reporter),
- KotlinTypeInfo.create(kmProperty.getReceiverParameterType(), definitionSupplier, reporter),
- KotlinValueParameterInfo.create(
- kmProperty.getSetterParameter(), definitionSupplier, reporter),
- KotlinTypeParameterInfo.create(
- kmProperty.getTypeParameters(), definitionSupplier, reporter),
+ KotlinTypeInfo.create(kmProperty.getReturnType(), factory, reporter),
+ KotlinTypeInfo.create(kmProperty.getReceiverParameterType(), factory, reporter),
+ KotlinValueParameterInfo.create(kmProperty.getSetterParameter(), factory, reporter),
+ KotlinTypeParameterInfo.create(kmProperty.getTypeParameters(), factory, reporter),
JvmExtensionsKt.getJvmFlags(kmProperty),
- KotlinJvmFieldSignatureInfo.create(
- JvmExtensionsKt.getFieldSignature(kmProperty), definitionSupplier),
+ KotlinJvmFieldSignatureInfo.create(JvmExtensionsKt.getFieldSignature(kmProperty), factory),
KotlinJvmMethodSignatureInfo.create(
- JvmExtensionsKt.getGetterSignature(kmProperty), definitionSupplier),
+ JvmExtensionsKt.getGetterSignature(kmProperty), factory),
KotlinJvmMethodSignatureInfo.create(
- JvmExtensionsKt.getSetterSignature(kmProperty), definitionSupplier),
+ JvmExtensionsKt.getSetterSignature(kmProperty), factory),
KotlinJvmMethodSignatureInfo.create(
- JvmExtensionsKt.getSyntheticMethodForAnnotations(kmProperty), definitionSupplier));
+ JvmExtensionsKt.getSyntheticMethodForAnnotations(kmProperty), factory));
}
@Override
@@ -160,4 +160,30 @@
}
}
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ if (returnType != null) {
+ returnType.trace(definitionSupplier);
+ }
+ if (receiverParameterType != null) {
+ receiverParameterType.trace(definitionSupplier);
+ }
+ if (setterParameter != null) {
+ setterParameter.trace(definitionSupplier);
+ }
+ forEachApply(typeParameters, param -> param::trace, definitionSupplier);
+ if (fieldSignature != null) {
+ fieldSignature.trace(definitionSupplier);
+ }
+ if (getterSignature != null) {
+ getterSignature.trace(definitionSupplier);
+ }
+ if (setterSignature != null) {
+ setterSignature.trace(definitionSupplier);
+ }
+ if (syntheticMethodForAnnotations != null) {
+ syntheticMethodForAnnotations.trace(definitionSupplier);
+ }
+ }
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinSyntheticClassInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinSyntheticClassInfo.java
index 38933b5..5af2a4c 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinSyntheticClassInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinSyntheticClassInfo.java
@@ -7,6 +7,7 @@
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.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.Reporter;
@@ -41,7 +42,7 @@
String packageName,
DexClass clazz,
Kotlin kotlin,
- DexDefinitionSupplier definitionSupplier,
+ DexItemFactory factory,
Reporter reporter) {
KmLambda lambda = null;
if (syntheticClass.isLambda()) {
@@ -49,9 +50,7 @@
assert lambda != null;
}
return new KotlinSyntheticClassInfo(
- lambda != null
- ? KotlinLambdaInfo.create(clazz, lambda, definitionSupplier, reporter)
- : null,
+ lambda != null ? KotlinLambdaInfo.create(clazz, lambda, factory, reporter) : null,
getFlavour(syntheticClass, clazz, kotlin),
packageName);
}
@@ -92,6 +91,13 @@
}
@Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ if (lambda != null) {
+ lambda.trace(definitionSupplier);
+ }
+ }
+
+ @Override
public String getPackageName() {
return packageName;
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeAliasInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeAliasInfo.java
index b4b5354..3872963 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeAliasInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeAliasInfo.java
@@ -4,17 +4,21 @@
package com.android.tools.r8.kotlin;
+import static com.android.tools.r8.utils.FunctionUtils.forEachApply;
+
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexDefinitionSupplier;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import com.android.tools.r8.utils.Reporter;
import java.util.List;
import kotlinx.metadata.KmTypeAlias;
import kotlinx.metadata.KmTypeAliasVisitor;
// Holds information about KmTypeAlias
-public class KotlinTypeAliasInfo {
+public class KotlinTypeAliasInfo implements EnqueuerMetadataTraceable {
private final int flags;
private final String name;
@@ -41,14 +45,14 @@
}
public static KotlinTypeAliasInfo create(
- KmTypeAlias alias, DexDefinitionSupplier definitionSupplier, Reporter reporter) {
+ KmTypeAlias alias, DexItemFactory factory, Reporter reporter) {
return new KotlinTypeAliasInfo(
alias.getFlags(),
alias.getName(),
- KotlinTypeInfo.create(alias.underlyingType, definitionSupplier, reporter),
- KotlinTypeInfo.create(alias.expandedType, definitionSupplier, reporter),
- KotlinTypeParameterInfo.create(alias.getTypeParameters(), definitionSupplier, reporter),
- KotlinAnnotationInfo.create(alias.getAnnotations(), definitionSupplier));
+ KotlinTypeInfo.create(alias.underlyingType, factory, reporter),
+ KotlinTypeInfo.create(alias.expandedType, factory, reporter),
+ KotlinTypeParameterInfo.create(alias.getTypeParameters(), factory, reporter),
+ KotlinAnnotationInfo.create(alias.getAnnotations(), factory));
}
void rewrite(
@@ -65,4 +69,12 @@
annotation.rewrite(kmTypeAliasVisitor::visitAnnotation, appView, namingLens);
}
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ underlyingType.trace(definitionSupplier);
+ expandedType.trace(definitionSupplier);
+ forEachApply(typeParameters, typeParam -> typeParam::trace, definitionSupplier);
+ forEachApply(annotations, annotation -> annotation::trace, definitionSupplier);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeInfo.java
index 8601667..f21db98 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeInfo.java
@@ -4,10 +4,14 @@
package com.android.tools.r8.kotlin;
+import static com.android.tools.r8.utils.FunctionUtils.forEachApply;
+
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexDefinitionSupplier;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import com.android.tools.r8.utils.Reporter;
import com.google.common.collect.ImmutableList;
import java.util.List;
@@ -18,7 +22,7 @@
import kotlinx.metadata.jvm.JvmTypeExtensionVisitor;
// Provides access to Kotlin information about a kotlin type.
-public class KotlinTypeInfo {
+public class KotlinTypeInfo implements EnqueuerMetadataTraceable {
private static final List<KotlinTypeProjectionInfo> EMPTY_ARGUMENTS = ImmutableList.of();
@@ -47,32 +51,29 @@
this.flexibleTypeUpperBoundInfo = flexibleTypeUpperBoundInfo;
}
- static KotlinTypeInfo create(
- KmType kmType, DexDefinitionSupplier definitionSupplier, Reporter reporter) {
+ static KotlinTypeInfo create(KmType kmType, DexItemFactory factory, Reporter reporter) {
if (kmType == null) {
return null;
}
return new KotlinTypeInfo(
kmType.getFlags(),
- KotlinClassifierInfo.create(kmType.classifier, definitionSupplier, reporter),
- KotlinTypeInfo.create(kmType.getAbbreviatedType(), definitionSupplier, reporter),
- KotlinTypeInfo.create(kmType.getOuterType(), definitionSupplier, reporter),
- getArguments(kmType.getArguments(), definitionSupplier, reporter),
- KotlinAnnotationInfo.create(JvmExtensionsKt.getAnnotations(kmType), definitionSupplier),
+ KotlinClassifierInfo.create(kmType.classifier, factory, reporter),
+ KotlinTypeInfo.create(kmType.getAbbreviatedType(), factory, reporter),
+ KotlinTypeInfo.create(kmType.getOuterType(), factory, reporter),
+ getArguments(kmType.getArguments(), factory, reporter),
+ KotlinAnnotationInfo.create(JvmExtensionsKt.getAnnotations(kmType), factory),
KotlinFlexibleTypeUpperBoundInfo.create(
- kmType.getFlexibleTypeUpperBound(), definitionSupplier, reporter));
+ kmType.getFlexibleTypeUpperBound(), factory, reporter));
}
static List<KotlinTypeProjectionInfo> getArguments(
- List<KmTypeProjection> projections,
- DexDefinitionSupplier definitionSupplier,
- Reporter reporter) {
+ List<KmTypeProjection> projections, DexItemFactory factory, Reporter reporter) {
if (projections.isEmpty()) {
return EMPTY_ARGUMENTS;
}
ImmutableList.Builder<KotlinTypeProjectionInfo> arguments = ImmutableList.builder();
for (KmTypeProjection projection : projections) {
- arguments.add(KotlinTypeProjectionInfo.create(projection, definitionSupplier, reporter));
+ arguments.add(KotlinTypeProjectionInfo.create(projection, factory, reporter));
}
return arguments.build();
}
@@ -107,4 +108,18 @@
}
}
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ classifier.trace(definitionSupplier);
+ if (abbreviatedType != null) {
+ abbreviatedType.trace(definitionSupplier);
+ }
+ if (outerType != null) {
+ outerType.trace(definitionSupplier);
+ }
+ forEachApply(arguments, argument -> argument::trace, definitionSupplier);
+ flexibleTypeUpperBoundInfo.trace(definitionSupplier);
+ forEachApply(annotations, annotation -> annotation::trace, definitionSupplier);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeParameterInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeParameterInfo.java
index fd11c11..53c2eb2 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeParameterInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeParameterInfo.java
@@ -4,10 +4,14 @@
package com.android.tools.r8.kotlin;
+import static com.android.tools.r8.utils.FunctionUtils.forEachApply;
+
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexDefinitionSupplier;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import com.android.tools.r8.utils.Reporter;
import com.google.common.collect.ImmutableList;
import java.util.List;
@@ -19,7 +23,7 @@
import kotlinx.metadata.jvm.JvmTypeParameterExtensionVisitor;
// Provides access to Kotlin information about a type-parameter.
-public class KotlinTypeParameterInfo {
+public class KotlinTypeParameterInfo implements EnqueuerMetadataTraceable {
private static final List<KotlinTypeParameterInfo> EMPTY_TYPE_PARAMETERS = ImmutableList.of();
private static final List<KotlinTypeInfo> EMPTY_UPPER_BOUNDS = ImmutableList.of();
@@ -47,41 +51,36 @@
}
private static KotlinTypeParameterInfo create(
- KmTypeParameter kmTypeParameter,
- DexDefinitionSupplier definitionSupplier,
- Reporter reporter) {
+ KmTypeParameter kmTypeParameter, DexItemFactory factory, Reporter reporter) {
return new KotlinTypeParameterInfo(
kmTypeParameter.getFlags(),
kmTypeParameter.getId(),
kmTypeParameter.getName(),
kmTypeParameter.getVariance(),
- getUpperBounds(kmTypeParameter.getUpperBounds(), definitionSupplier, reporter),
- KotlinAnnotationInfo.create(
- JvmExtensionsKt.getAnnotations(kmTypeParameter), definitionSupplier));
+ getUpperBounds(kmTypeParameter.getUpperBounds(), factory, reporter),
+ KotlinAnnotationInfo.create(JvmExtensionsKt.getAnnotations(kmTypeParameter), factory));
}
static List<KotlinTypeParameterInfo> create(
- List<KmTypeParameter> kmTypeParameters,
- DexDefinitionSupplier definitionSupplier,
- Reporter reporter) {
+ List<KmTypeParameter> kmTypeParameters, DexItemFactory factory, Reporter reporter) {
if (kmTypeParameters.isEmpty()) {
return EMPTY_TYPE_PARAMETERS;
}
ImmutableList.Builder<KotlinTypeParameterInfo> builder = ImmutableList.builder();
for (KmTypeParameter kmTypeParameter : kmTypeParameters) {
- builder.add(create(kmTypeParameter, definitionSupplier, reporter));
+ builder.add(create(kmTypeParameter, factory, reporter));
}
return builder.build();
}
private static List<KotlinTypeInfo> getUpperBounds(
- List<KmType> upperBounds, DexDefinitionSupplier definitionSupplier, Reporter reporter) {
+ List<KmType> upperBounds, DexItemFactory factory, Reporter reporter) {
if (upperBounds.isEmpty()) {
return EMPTY_UPPER_BOUNDS;
}
ImmutableList.Builder<KotlinTypeInfo> builder = ImmutableList.builder();
for (KmType upperBound : upperBounds) {
- builder.add(KotlinTypeInfo.create(upperBound, definitionSupplier, reporter));
+ builder.add(KotlinTypeInfo.create(upperBound, factory, reporter));
}
return builder.build();
}
@@ -104,4 +103,10 @@
annotation.rewrite(extensionVisitor::visitAnnotation, appView, namingLens);
}
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ forEachApply(originalUpperBounds, upperBound -> upperBound::trace, definitionSupplier);
+ forEachApply(annotations, annotation -> annotation::trace, definitionSupplier);
+ }
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeProjectionInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeProjectionInfo.java
index 68da5db..9ab3de0 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeProjectionInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeProjectionInfo.java
@@ -6,14 +6,16 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexDefinitionSupplier;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import com.android.tools.r8.utils.Reporter;
import kotlinx.metadata.KmTypeProjection;
import kotlinx.metadata.KmVariance;
// Provides access to Kotlin information about the type projection of a type (arguments).
-public class KotlinTypeProjectionInfo {
+public class KotlinTypeProjectionInfo implements EnqueuerMetadataTraceable {
final KmVariance variance;
final KotlinTypeInfo typeInfo;
@@ -24,12 +26,10 @@
}
static KotlinTypeProjectionInfo create(
- KmTypeProjection kmTypeProjection,
- DexDefinitionSupplier definitionSupplier,
- Reporter reporter) {
+ KmTypeProjection kmTypeProjection, DexItemFactory factory, Reporter reporter) {
return new KotlinTypeProjectionInfo(
kmTypeProjection.getVariance(),
- KotlinTypeInfo.create(kmTypeProjection.getType(), definitionSupplier, reporter));
+ KotlinTypeInfo.create(kmTypeProjection.getType(), factory, reporter));
}
private boolean isStarProjection() {
@@ -47,4 +47,11 @@
typeInfo.rewrite(flags -> visitorProvider.get(flags, variance), appView, namingLens);
}
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ if (typeInfo != null) {
+ typeInfo.trace(definitionSupplier);
+ }
+ }
}
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..f621afb
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeReference.java
@@ -0,0 +1,102 @@
+// 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.DexItemFactory;
+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.shaking.EnqueuerMetadataTraceable;
+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 implements EnqueuerMetadataTraceable {
+
+ 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 fromBinaryName(String binaryName, DexItemFactory factory) {
+ if (DescriptorUtils.isValidBinaryName(binaryName)) {
+ return fromDescriptor(DescriptorUtils.getDescriptorFromClassBinaryName(binaryName), factory);
+ }
+ return new KotlinTypeReference(binaryName);
+ }
+
+ static KotlinTypeReference fromDescriptor(String descriptor, DexItemFactory factory) {
+ if (DescriptorUtils.isDescriptor(descriptor)) {
+ DexType type = factory.createType(descriptor);
+ return new KotlinTypeReference(type);
+ }
+ return new KotlinTypeReference(descriptor);
+ }
+
+ String toRenamedDescriptorOrDefault(
+ AppView<AppInfoWithLiveness> appView, NamingLens namingLens, String defaultValue) {
+ if (unknown != null) {
+ return unknown;
+ }
+ assert known != null;
+ if (!known.isClassType()) {
+ return known.descriptor.toString();
+ }
+ 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);
+ }
+
+ @Override
+ public String toString() {
+ return known != null ? known.descriptor.toString() : unknown;
+ }
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ if (known != null && known.isClassType()) {
+ // Lookup the definition, ignoring the result. This populates the sets in the Enqueuer.
+ definitionSupplier.definitionFor(known);
+ }
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinValueParameterInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinValueParameterInfo.java
index ee2f99b..bd7daac 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinValueParameterInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinValueParameterInfo.java
@@ -6,8 +6,10 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexDefinitionSupplier;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.EnqueuerMetadataTraceable;
import com.android.tools.r8.utils.Reporter;
import com.google.common.collect.ImmutableList;
import java.util.List;
@@ -16,7 +18,7 @@
import kotlinx.metadata.KmValueParameterVisitor;
// Provides access to Kotlin information about value parameter.
-class KotlinValueParameterInfo {
+class KotlinValueParameterInfo implements EnqueuerMetadataTraceable {
private static final List<KotlinValueParameterInfo> EMPTY_VALUE_PARAMETERS = ImmutableList.of();
// Original parameter name.
final String name;
@@ -36,9 +38,7 @@
}
static KotlinValueParameterInfo create(
- KmValueParameter kmValueParameter,
- DexDefinitionSupplier definitionSupplier,
- Reporter reporter) {
+ KmValueParameter kmValueParameter, DexItemFactory factory, Reporter reporter) {
if (kmValueParameter == null) {
return null;
}
@@ -46,21 +46,18 @@
return new KotlinValueParameterInfo(
kmValueParameter.getFlags(),
kmValueParameter.getName(),
- KotlinTypeInfo.create(kmType, definitionSupplier, reporter),
- KotlinTypeInfo.create(
- kmValueParameter.getVarargElementType(), definitionSupplier, reporter));
+ KotlinTypeInfo.create(kmType, factory, reporter),
+ KotlinTypeInfo.create(kmValueParameter.getVarargElementType(), factory, reporter));
}
static List<KotlinValueParameterInfo> create(
- List<KmValueParameter> parameters,
- DexDefinitionSupplier definitionSupplier,
- Reporter reporter) {
+ List<KmValueParameter> parameters, DexItemFactory factory, Reporter reporter) {
if (parameters.isEmpty()) {
return EMPTY_VALUE_PARAMETERS;
}
ImmutableList.Builder<KotlinValueParameterInfo> builder = ImmutableList.builder();
for (KmValueParameter parameter : parameters) {
- builder.add(create(parameter, definitionSupplier, reporter));
+ builder.add(create(parameter, factory, reporter));
}
return builder.build();
}
@@ -76,4 +73,12 @@
kmValueParameterVisitor::visitVarargElementType, appView, namingLens);
}
}
+
+ @Override
+ public void trace(DexDefinitionSupplier definitionSupplier) {
+ type.trace(definitionSupplier);
+ if (varargElementType != null) {
+ varargElementType.trace(definitionSupplier);
+ }
+ }
}
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 484786f..ff991cf 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -2634,9 +2634,10 @@
this.dontWarnPatterns = dontWarnPatterns;
// Translate the result of root-set computation into enqueuer actions.
if (appView.options().getProguardConfiguration() != null
- && !options.kotlinOptimizationOptions().disableKotlinSpecificOptimizations
- && mode.isInitialTreeShaking()) {
- registerAnalysis(new KotlinMetadataEnqueuerExtension(appView, enqueuerDefinitionSupplier));
+ && !options.kotlinOptimizationOptions().disableKotlinSpecificOptimizations) {
+ registerAnalysis(
+ new KotlinMetadataEnqueuerExtension(
+ appView, enqueuerDefinitionSupplier, initialPrunedTypes));
}
if (appView.options().isShrinking() || appView.options().getProguardConfiguration() == null) {
enqueueRootItems(rootSet.noShrinking);
diff --git a/src/main/java/com/android/tools/r8/shaking/EnqueuerMetadataTraceable.java b/src/main/java/com/android/tools/r8/shaking/EnqueuerMetadataTraceable.java
new file mode 100644
index 0000000..e17e571
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/shaking/EnqueuerMetadataTraceable.java
@@ -0,0 +1,12 @@
+// 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.shaking;
+
+import com.android.tools.r8.graph.DexDefinitionSupplier;
+
+public interface EnqueuerMetadataTraceable {
+
+ void trace(DexDefinitionSupplier definitionSupplier);
+}
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;
diff --git a/src/main/java/com/android/tools/r8/utils/FunctionUtils.java b/src/main/java/com/android/tools/r8/utils/FunctionUtils.java
new file mode 100644
index 0000000..64e8537
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/utils/FunctionUtils.java
@@ -0,0 +1,18 @@
+// 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.utils;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+public class FunctionUtils {
+
+ public static <T, R> void forEachApply(
+ Iterable<T> list, Function<T, Consumer<R>> func, R argument) {
+ for (T t : list) {
+ func.apply(t).accept(argument);
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/kotlin/coroutines/KotlinxCoroutinesTestRunner.java b/src/test/java/com/android/tools/r8/kotlin/coroutines/KotlinxCoroutinesTestRunner.java
index f0179f8..7925c58 100644
--- a/src/test/java/com/android/tools/r8/kotlin/coroutines/KotlinxCoroutinesTestRunner.java
+++ b/src/test/java/com/android/tools/r8/kotlin/coroutines/KotlinxCoroutinesTestRunner.java
@@ -5,7 +5,6 @@
package com.android.tools.r8.kotlin.coroutines;
import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
-import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -88,16 +87,11 @@
.addKeepAllAttributes()
// The BASE_LIBRARY contains proguard rules that do not match.
.allowUnusedProguardConfigurationRules()
- .allowDiagnosticInfoMessages()
.addKeepRules(
"-dontwarn reactor.blockhound.integration.BlockHoundIntegration",
"-dontwarn org.junit.runners.model.Statement",
"-dontwarn org.junit.rules.TestRule")
.compile()
- .assertAllInfoMessagesMatch(
- anyOf(
- containsString("Unexpected error while reading kotlinx.coroutines"),
- containsString("Proguard configuration rule does not match anything")))
.writeToZip();
ProcessResult kotlincResult =
kotlinc(KOTLINC, targetVersion)
diff --git a/src/test/java/com/android/tools/r8/shaking/b134858535/EventPublisherTest.java b/src/test/java/com/android/tools/r8/shaking/b134858535/EventPublisherTest.java
index d4801ea..23a5616 100644
--- a/src/test/java/com/android/tools/r8/shaking/b134858535/EventPublisherTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/b134858535/EventPublisherTest.java
@@ -4,6 +4,8 @@
package com.android.tools.r8.shaking.b134858535;
+import static org.hamcrest.CoreMatchers.containsString;
+
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.utils.AndroidApiLevel;
@@ -26,7 +28,13 @@
.addProgramClassFileData(EventPublisher$bDump.dump())
.addKeepClassRules(Interface.class)
.addKeepMainRule(Main.class)
+ .allowDiagnosticInfoMessages()
.setMinApi(AndroidApiLevel.L)
- .compile();
+ .compile()
+ // TODO(b/157537996): Handle JStyle lambdas with private methods.
+ .assertAllInfoMessagesMatch(
+ containsString(
+ "Unrecognized Kotlin lambda"
+ + " [com.android.tools.r8.shaking.b134858535.EventPublisher$b]"));
}
}