Revert "Check shape and class type before parsing metadata for lambdas"
This reverts commit 8c6c4d33222300fa1490badc713adbd00f7583ad.
Reason for revert: Bot failures
Change-Id: I4fe0dcf91d05e9f204a13689aff0a2a95f8bfe67
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 7f4c47d..bfabd6c 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
@@ -33,8 +33,6 @@
public final class KotlinClassMetadataReader {
- private static final int SYNTHETIC_CLASS_KIND = 3;
-
public static KotlinClassLevelInfo getKotlinInfo(
DexClass clazz, AppView<?> appView, Consumer<DexEncodedMethod> keepByteCode) {
DexAnnotation meta =
@@ -77,25 +75,16 @@
public static boolean isLambda(AppView<?> appView, DexClass clazz) {
DexItemFactory dexItemFactory = appView.dexItemFactory();
Kotlin kotlin = dexItemFactory.kotlin;
- Flavour flavour = getFlavour(clazz, kotlin);
- if (flavour == Flavour.Unclassified) {
- return false;
- }
DexAnnotation metadataAnnotation =
clazz.annotations().getFirstMatching(dexItemFactory.kotlinMetadataType);
- if (metadataAnnotation == null) {
- return false;
- }
- Map<DexString, DexAnnotationElement> elementMap = toElementMap(metadataAnnotation.annotation);
- if (getKind(kotlin, elementMap) == SYNTHETIC_CLASS_KIND) {
- KotlinClassMetadata kMetadata = toKotlinClassMetadata(kotlin, elementMap);
+ if (metadataAnnotation != null) {
+ KotlinClassMetadata kMetadata = toKotlinClassMetadata(kotlin, metadataAnnotation.annotation);
if (kMetadata instanceof SyntheticClass) {
- return ((SyntheticClass) kMetadata).isLambda();
+ SyntheticClass syntheticClass = (SyntheticClass) kMetadata;
+ return syntheticClass.isLambda()
+ && getFlavour(syntheticClass, clazz, kotlin) != Flavour.Unclassified;
}
}
- assert toKotlinClassMetadata(kotlin, elementMap) instanceof SyntheticClass
- == (getKind(kotlin, elementMap) == SYNTHETIC_CLASS_KIND)
- : "Synthetic class kinds should agree";
return false;
}
@@ -109,21 +98,16 @@
public static KotlinClassMetadata toKotlinClassMetadata(
Kotlin kotlin, DexEncodedAnnotation metadataAnnotation) {
- return toKotlinClassMetadata(kotlin, toElementMap(metadataAnnotation));
- }
-
- private static Map<DexString, DexAnnotationElement> toElementMap(
- DexEncodedAnnotation metadataAnnotation) {
Map<DexString, DexAnnotationElement> elementMap = new IdentityHashMap<>();
for (DexAnnotationElement element : metadataAnnotation.elements) {
elementMap.put(element.name, element);
}
- return elementMap;
- }
- private static KotlinClassMetadata toKotlinClassMetadata(
- Kotlin kotlin, Map<DexString, DexAnnotationElement> elementMap) {
- int k = getKind(kotlin, elementMap);
+ DexAnnotationElement kind = elementMap.get(kotlin.metadata.kind);
+ if (kind == null) {
+ throw new MetadataError("element 'k' is missing.");
+ }
+ Integer k = (Integer) kind.value.getBoxedValue();
DexAnnotationElement metadataVersion = elementMap.get(kotlin.metadata.metadataVersion);
int[] mv = metadataVersion == null ? null : getUnboxedIntArray(metadataVersion.value, "mv");
DexAnnotationElement bytecodeVersion = elementMap.get(kotlin.metadata.bytecodeVersion);
@@ -143,14 +127,6 @@
return KotlinClassMetadata.read(header);
}
- private static int getKind(Kotlin kotlin, Map<DexString, DexAnnotationElement> elementMap) {
- DexAnnotationElement kind = elementMap.get(kotlin.metadata.kind);
- if (kind == null) {
- throw new MetadataError("element 'k' is missing.");
- }
- return (Integer) kind.value.getBoxedValue();
- }
-
public static KotlinClassLevelInfo createKotlinInfo(
Kotlin kotlin,
DexClass clazz,
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 ee55f8b..08e95b3 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinSyntheticClassInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinSyntheticClassInfo.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.utils.Pair;
import kotlinx.metadata.KmLambda;
import kotlinx.metadata.jvm.KotlinClassHeader;
+import kotlinx.metadata.jvm.KotlinClassMetadata;
import kotlinx.metadata.jvm.KotlinClassMetadata.SyntheticClass;
import kotlinx.metadata.jvm.KotlinClassMetadata.SyntheticClass.Writer;
@@ -54,7 +55,7 @@
? KotlinLambdaInfo.create(
clazz, lambda, appView.dexItemFactory(), appView.reporter(), extensionInformation)
: null,
- getFlavour(clazz, kotlin),
+ getFlavour(syntheticClass, clazz, kotlin),
packageName,
metadataVersion);
}
@@ -63,6 +64,14 @@
return lambda != null && flavour != Flavour.Unclassified;
}
+ public boolean isKotlinStyleLambda() {
+ return flavour == Flavour.KotlinStyleLambda;
+ }
+
+ public boolean isJavaStyleLambda() {
+ return flavour == Flavour.JavaStyleLambda;
+ }
+
@Override
public boolean isSyntheticClass() {
return true;
@@ -103,17 +112,23 @@
return metadataVersion;
}
- public static Flavour getFlavour(DexClass clazz, Kotlin kotlin) {
- // Returns KotlinStyleLambda if the given clazz has shape of a Kotlin-style lambda:
- // a class that directly extends kotlin.jvm.internal.Lambda
- if (clazz.superType == kotlin.functional.lambdaType) {
+ public static Flavour getFlavour(
+ KotlinClassMetadata.SyntheticClass metadata, DexClass clazz, Kotlin kotlin) {
+ // Returns KotlinStyleLambda if the given clazz is a Kotlin-style lambda:
+ // a class that
+ // 1) is recognized as lambda in its Kotlin metadata;
+ // 2) directly extends kotlin.jvm.internal.Lambda
+ if (metadata.isLambda() && clazz.superType == kotlin.functional.lambdaType) {
return Flavour.KotlinStyleLambda;
}
- // Returns JavaStyleLambda if the given clazz has shape of a Java-style lambda:
+ // Returns JavaStyleLambda if the given clazz is a Java-style lambda:
// a class that
- // 1) doesn't extend any other class;
- // 2) directly implements only one Java SAM.
- if (clazz.superType == kotlin.factory.objectType && clazz.interfaces.size() == 1) {
+ // 1) is recognized as lambda in its Kotlin metadata;
+ // 2) doesn't extend any other class;
+ // 3) directly implements only one Java SAM.
+ if (metadata.isLambda()
+ && clazz.superType == kotlin.factory.objectType
+ && clazz.interfaces.size() == 1) {
return Flavour.JavaStyleLambda;
}
return Flavour.Unclassified;