Trace kotlin.Metadata annotations in trace references
Fixes: b/409260720
Change-Id: I60f4c126007494a4361451625dae9a330a438d97
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 018c084..09f0679 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
@@ -21,6 +21,7 @@
import com.android.tools.r8.utils.StringDiagnostic;
import java.util.IdentityHashMap;
import java.util.Map;
+import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Supplier;
import kotlin.Metadata;
@@ -39,7 +40,7 @@
AppView<?> appView,
DexClass clazz,
Consumer<DexEncodedMethod> keepByteCode,
- Supplier<Boolean> reportUnknownMetadata) {
+ BooleanSupplier reportUnknownMetadata) {
DexAnnotation meta =
clazz.annotations().getFirstMatching(appView.dexItemFactory().kotlinMetadataType);
if (meta == null) {
@@ -53,11 +54,11 @@
DexClass clazz,
DexAnnotation meta,
Consumer<DexEncodedMethod> keepByteCode,
- Supplier<Boolean> reportUnknownMetadata) {
+ BooleanSupplier reportUnknownMetadata) {
try {
return getKotlinInfo(appView, clazz, keepByteCode, meta);
} catch (KotlinMetadataException e) {
- if (reportUnknownMetadata.get()) {
+ if (reportUnknownMetadata.getAsBoolean()) {
appView.reporter().warning(KotlinMetadataDiagnostic.unknownMetadataVersion());
}
appView
@@ -70,7 +71,7 @@
+ e.getMessage()));
return getInvalidKotlinInfo();
} catch (Throwable e) {
- if (reportUnknownMetadata.get()) {
+ if (reportUnknownMetadata.getAsBoolean()) {
appView.reporter().warning(KotlinMetadataDiagnostic.unknownMetadataVersion());
}
appView
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
index ae75ef0..874e219 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
@@ -176,13 +176,17 @@
if (metadata == null) {
return;
}
+ // In D8 of R8 partial the kotlin.Metadata annotations have already been read during trace
+ // references.
KotlinClassLevelInfo kotlinInfo =
- KotlinClassMetadataReader.getKotlinInfoFromAnnotation(
- appView,
- clazz,
- metadata,
- ConsumerUtils.emptyConsumer(),
- reportedUnknownMetadataVersion::getAndSet);
+ appView.options().partialSubCompilationConfiguration != null
+ ? clazz.getKotlinInfo()
+ : KotlinClassMetadataReader.getKotlinInfoFromAnnotation(
+ appView,
+ clazz,
+ metadata,
+ ConsumerUtils.emptyConsumer(),
+ reportedUnknownMetadataVersion::getAndSet);
if (kotlinInfo == getNoKotlinInfo()) {
return;
}
diff --git a/src/main/java/com/android/tools/r8/tracereferences/UseCollector.java b/src/main/java/com/android/tools/r8/tracereferences/UseCollector.java
index 257ff73..0a4f712 100644
--- a/src/main/java/com/android/tools/r8/tracereferences/UseCollector.java
+++ b/src/main/java/com/android/tools/r8/tracereferences/UseCollector.java
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.tracereferences;
+import static com.android.tools.r8.utils.ConsumerUtils.emptyConsumer;
+
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.diagnostic.DefinitionContext;
import com.android.tools.r8.diagnostic.internal.DefinitionContextUtils;
@@ -38,6 +40,9 @@
import com.android.tools.r8.graph.lens.GraphLens;
import com.android.tools.r8.graph.lens.MethodLookupResult;
import com.android.tools.r8.ir.desugar.LambdaDescriptor;
+import com.android.tools.r8.kotlin.KotlinClassLevelInfo;
+import com.android.tools.r8.kotlin.KotlinClassMetadataReader;
+import com.android.tools.r8.kotlin.KotlinMetadataUseRegistry;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.FieldReference;
import com.android.tools.r8.references.MethodReference;
@@ -53,6 +58,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
+import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -106,6 +112,28 @@
for (DexAnnotation annotation : clazz.annotations().getAnnotations()) {
registerAnnotation(annotation, clazz, classContext);
}
+ traceKotlinMetadata(clazz, classContext);
+ }
+
+ private void traceKotlinMetadata(DexProgramClass clazz, DefinitionContext classContext) {
+ if (parseKotlinMetadata(clazz)) {
+ KotlinMetadataUseRegistry registry = type -> addType(type, classContext);
+ clazz.getKotlinInfo().trace(registry);
+ clazz.forEachProgramMember(member -> member.getDefinition().getKotlinInfo().trace(registry));
+ }
+ }
+
+ private boolean parseKotlinMetadata(DexProgramClass clazz) {
+ DexAnnotation metadata = clazz.annotations().getFirstMatching(factory.kotlinMetadataType);
+ if (metadata == null) {
+ return false;
+ }
+ BooleanSupplier reportUnknownMetadata = () -> false;
+ KotlinClassLevelInfo kotlinInfo =
+ KotlinClassMetadataReader.getKotlinInfoFromAnnotation(
+ appView, clazz, metadata, emptyConsumer(), reportUnknownMetadata);
+ clazz.setKotlinInfo(kotlinInfo);
+ return true;
}
protected void notifyPresentClass(DexClass clazz, DefinitionContext referencedFrom) {
diff --git a/src/test/java/com/android/tools/r8/partial/kotlin/PartialCompilationKotlinMetadataTest.java b/src/test/java/com/android/tools/r8/partial/kotlin/PartialCompilationKotlinMetadataTest.java
index 356ff33..272905c 100644
--- a/src/test/java/com/android/tools/r8/partial/kotlin/PartialCompilationKotlinMetadataTest.java
+++ b/src/test/java/com/android/tools/r8/partial/kotlin/PartialCompilationKotlinMetadataTest.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.partial.kotlin;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -88,7 +87,7 @@
assertThat(message1Class, isPresent());
ClassSubject message2Class = inspector.clazz(MESSAGE2_NAME);
- assertThat(message2Class, isAbsent());
+ assertThat(message2Class, isPresent());
ClassSubject greetingClass = inspector.clazz(GREETING_NAME);
assertThat(greetingClass, isPresent());
@@ -96,11 +95,11 @@
assertNotNull(kotlinClassMetadata);
String metadata = KotlinMetadataWriter.kotlinMetadataToString("", kotlinClassMetadata);
assertThat(metadata, containsString(greetingClass.getFinalBinaryName()));
- // TODO(b/409260720): Message2 should be referenced.
assertThat(metadata, containsString(message1Class.getFinalBinaryName()));
+ assertThat(metadata, containsString(message2Class.getFinalBinaryName()));
}
- private static KotlinCompileMemoizer compiledJars =
+ private static final KotlinCompileMemoizer compiledJars =
getCompileMemoizer(
Paths.get(
ToolHelper.TESTS_DIR,