Synthesize @Metadata signature of constructor and (extension) functions.
With that, when synthesizing @Metdata for constructor and (extension)
functions, we don't need original @Metadata anymore.
Bug: 70169921
Change-Id: I2965d78494c78ae6e8213c65a71b1f0d8c812aa3
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index 06f579c..779e3cc 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -14,7 +14,6 @@
import com.google.common.base.MoreObjects;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Sets;
@@ -24,12 +23,10 @@
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
-import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
-import kotlinx.metadata.KmConstructor;
import kotlinx.metadata.KmFunction;
import kotlinx.metadata.KmProperty;
@@ -214,24 +211,10 @@
return Arrays.asList(virtualMethods);
}
- public Map<DexEncodedMethod, KmConstructor> kotlinConstructors(
- List<KmConstructor> constructors, AppView<?> appView) {
- ImmutableMap.Builder<DexEncodedMethod, KmConstructor> builder = ImmutableMap.builder();
- for (DexEncodedMethod method : directMethods) {
- if (method.isInstanceInitializer()) {
- KmConstructor constructor = method.findCompatibleKotlinConstructor(constructors, appView);
- if (constructor != null) {
- // Found a compatible constructor that is likely asked to keep.
- builder.put(method, constructor);
- }
- }
- }
- return builder.build();
- }
-
- public Map<DexEncodedMethod, KmFunction> kotlinExtensions(
+ // TODO(b/70169921): mark/propagate extension function as a method metadata.
+ public List<DexEncodedMethod> kotlinExtensions(
List<KmFunction> extensions, AppView<?> appView) {
- ImmutableMap.Builder<DexEncodedMethod, KmFunction> builder = ImmutableMap.builder();
+ ImmutableList.Builder<DexEncodedMethod> builder = ImmutableList.builder();
for (DexEncodedMethod method : directMethods) {
if (method.isInitializer()) {
continue;
@@ -239,7 +222,7 @@
KmFunction extension = method.findCompatibleKotlinExtension(extensions, appView);
if (extension != null) {
// Found a compatible extension that is likely asked to keep.
- builder.put(method, extension);
+ builder.add(method);
}
}
return builder.build();
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 2ecc549..39f8eeb 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -74,7 +74,6 @@
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.IntPredicate;
-import kotlinx.metadata.KmConstructor;
import kotlinx.metadata.KmFunction;
import kotlinx.metadata.KmProperty;
import org.objectweb.asm.Opcodes;
@@ -395,20 +394,6 @@
}
// TODO(b/70169921): Handling JVM extensions as well.
- KmConstructor findCompatibleKotlinConstructor(
- List<KmConstructor> constructors, AppView<?> appView) {
- if (!isInstanceInitializer()) {
- return null;
- }
- for (KmConstructor constructor : constructors) {
- if (KotlinMetadataSynthesizer.isCompatibleConstructor(constructor, this, appView)) {
- return constructor;
- }
- }
- return null;
- }
-
- // TODO(b/70169921): Handling JVM extensions as well.
KmFunction findCompatibleKotlinExtension(List<KmFunction> extensions, AppView<?> appView) {
if (!isStaticMember()) {
return null;
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinClass.java b/src/main/java/com/android/tools/r8/kotlin/KotlinClass.java
index ff97c60..5f31c51 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinClass.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClass.java
@@ -15,9 +15,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import kotlinx.metadata.KmClass;
import kotlinx.metadata.KmConstructor;
import kotlinx.metadata.KmType;
@@ -70,12 +68,12 @@
return;
}
List<KmConstructor> constructors = kmClass.getConstructors();
- List<KmConstructor> originalConstructors = new ArrayList<>(constructors);
constructors.clear();
- for (Map.Entry<DexEncodedMethod, KmConstructor> entry :
- clazz.kotlinConstructors(originalConstructors, appView).entrySet()) {
- KmConstructor constructor =
- toRenamedKmConstructor(entry.getKey(), entry.getValue(), appView, lens);
+ for (DexEncodedMethod method : clazz.directMethods()) {
+ if (!method.isInstanceInitializer()) {
+ continue;
+ }
+ KmConstructor constructor = toRenamedKmConstructor(method, appView, lens);
if (constructor != null) {
constructors.add(constructor);
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinInfo.java
index 9cd71c3..548d2e2 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinInfo.java
@@ -14,7 +14,6 @@
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.List;
-import java.util.Map;
import java.util.stream.Collectors;
import kotlinx.metadata.KmDeclarationContainer;
import kotlinx.metadata.KmFunction;
@@ -118,15 +117,13 @@
List<KmProperty> properties = kmDeclarationContainer.getProperties();
for (DexEncodedMethod method : clazz.kotlinFunctions(originalFunctions, properties, appView)) {
- KmFunction function = toRenamedKmFunction(method, null, appView, lens);
+ KmFunction function = toRenamedKmFunction(method, appView, lens);
if (function != null) {
functions.add(function);
}
}
- for (Map.Entry<DexEncodedMethod, KmFunction> entry :
- clazz.kotlinExtensions(originalExtensions, appView).entrySet()) {
- KmFunction extension =
- toRenamedKmFunctionAsExtension(entry.getKey(), entry.getValue(), appView, lens);
+ for (DexEncodedMethod method : clazz.kotlinExtensions(originalExtensions, appView)) {
+ KmFunction extension = toRenamedKmFunctionAsExtension(method, appView, lens);
if (extension != null) {
functions.add(extension);
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataJvmExtensionUtils.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataJvmExtensionUtils.java
index 85e3540..e0ae783 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataJvmExtensionUtils.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataJvmExtensionUtils.java
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.kotlin;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexType;
import com.google.common.collect.ImmutableList;
import java.util.Arrays;
import java.util.List;
@@ -24,6 +26,17 @@
class KotlinMetadataJvmExtensionUtils {
+ static JvmMethodSignature toJvmMethodSignature(DexMethod method) {
+ StringBuilder descBuilder = new StringBuilder();
+ descBuilder.append("(");
+ for (DexType argType : method.proto.parameters.values) {
+ descBuilder.append(argType.toDescriptorString());
+ }
+ descBuilder.append(")");
+ descBuilder.append(method.proto.returnType.toDescriptorString());
+ return new JvmMethodSignature(method.name.toString(), descBuilder.toString());
+ }
+
private static boolean isValidJvmMethodSignature(String desc) {
return desc != null
&& !desc.isEmpty()
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizer.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizer.java
index 51b04d9..b3491a5 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizer.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizer.java
@@ -6,6 +6,7 @@
import static com.android.tools.r8.kotlin.Kotlin.addKotlinPrefix;
import static com.android.tools.r8.kotlin.KotlinMetadataJvmExtensionUtils.parameterTypesFromJvmMethodSignature;
import static com.android.tools.r8.kotlin.KotlinMetadataJvmExtensionUtils.returnTypeFromJvmMethodSignature;
+import static com.android.tools.r8.kotlin.KotlinMetadataJvmExtensionUtils.toJvmMethodSignature;
import static com.android.tools.r8.utils.DescriptorUtils.descriptorToInternalName;
import static com.android.tools.r8.utils.DescriptorUtils.getDescriptorFromKmType;
import static kotlinx.metadata.FlagsKt.flagsOf;
@@ -16,7 +17,6 @@
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.kotlin.KotlinMetadataJvmExtensionUtils.KmConstructorProcessor;
import com.android.tools.r8.kotlin.KotlinMetadataJvmExtensionUtils.KmFunctionProcessor;
import com.android.tools.r8.kotlin.KotlinMetadataJvmExtensionUtils.KmPropertyProcessor;
import com.android.tools.r8.naming.NamingLens;
@@ -28,6 +28,7 @@
import kotlinx.metadata.KmType;
import kotlinx.metadata.KmValueParameter;
import kotlinx.metadata.jvm.JvmMethodSignature;
+import kotlinx.metadata.jvm.JvmExtensionsKt;
public class KotlinMetadataSynthesizer {
@@ -254,7 +255,6 @@
static KmConstructor toRenamedKmConstructor(
DexEncodedMethod method,
- KmConstructor original,
AppView<AppInfoWithLiveness> appView,
NamingLens lens) {
// Make sure it is an instance initializer and live.
@@ -262,17 +262,9 @@
|| !appView.appInfo().liveMethods.contains(method.method)) {
return null;
}
- // TODO(b/70169921): {@link KmConstructor.extensions} is private, i.e., no way to alter!
- // Thus, we rely on original metadata for now.
- KmConstructorProcessor kmConstructorProcessor = new KmConstructorProcessor(original);
- JvmMethodSignature jvmMethodSignature = kmConstructorProcessor.signature();
- KmConstructor kmConstructor =
- jvmMethodSignature != null
- ? original
- // TODO(b/70169921): Consult kotlinx.metadata.Flag.Constructor to set IS_PRIMARY.
- : new KmConstructor(method.accessFlags.getAsKotlinFlags());
+ KmConstructor kmConstructor = new KmConstructor(method.accessFlags.getAsKotlinFlags());
+ JvmExtensionsKt.setSignature(kmConstructor, toJvmMethodSignature(method.method));
List<KmValueParameter> parameters = kmConstructor.getValueParameters();
- parameters.clear();
if (!populateKmValueParameters(parameters, method, appView, lens, false)) {
return null;
}
@@ -281,23 +273,20 @@
static KmFunction toRenamedKmFunction(
DexEncodedMethod method,
- KmFunction original,
AppView<AppInfoWithLiveness> appView,
NamingLens lens) {
- return toRenamedKmFunctionHelper(method, original, appView, lens, false);
+ return toRenamedKmFunctionHelper(method, appView, lens, false);
}
static KmFunction toRenamedKmFunctionAsExtension(
DexEncodedMethod method,
- KmFunction original,
AppView<AppInfoWithLiveness> appView,
NamingLens lens) {
- return toRenamedKmFunctionHelper(method, original, appView, lens, true);
+ return toRenamedKmFunctionHelper(method, appView, lens, true);
}
private static KmFunction toRenamedKmFunctionHelper(
DexEncodedMethod method,
- KmFunction original,
AppView<AppInfoWithLiveness> appView,
NamingLens lens,
boolean isExtension) {
@@ -311,14 +300,9 @@
// For a library method override, we should not have renamed it.
assert !method.isLibraryMethodOverride().isTrue() || renamedMethod == method.method
: method.toSourceString() + " -> " + renamedMethod.toSourceString();
- // TODO(b/70169921): {@link KmFunction.extensions} is private, i.e., no way to alter!
- // Thus, we rely on original metadata for now.
- assert !isExtension || original != null;
KmFunction kmFunction =
- isExtension
- ? original
- // TODO(b/70169921): Consult kotlinx.metadata.Flag.Function for kind (e.g., suspend).
- : new KmFunction(method.accessFlags.getAsKotlinFlags(), renamedMethod.name.toString());
+ new KmFunction(method.accessFlags.getAsKotlinFlags(), renamedMethod.name.toString());
+ JvmExtensionsKt.setSignature(kmFunction, toJvmMethodSignature(method.method));
KmType kmReturnType = toRenamedKmType(method.method.proto.returnType, appView, lens);
if (kmReturnType == null) {
return null;
@@ -334,7 +318,6 @@
kmFunction.setReceiverParameterType(kmReceiverType);
}
List<KmValueParameter> parameters = kmFunction.getValueParameters();
- parameters.clear();
if (!populateKmValueParameters(parameters, method, appView, lens, isExtension)) {
return null;
}