Make custom conversion methods
- Custom conversion can now be different methods in both ways
Bug: 184026720
Change-Id: I290ed8c5737b15538bc88329bacfb86267746a26
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizer.java
index e3444a6..1581f83 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryWrapperSynthesizer.java
@@ -19,7 +19,6 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
-import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.FieldAccessFlags;
import com.android.tools.r8.graph.MethodAccessFlags;
@@ -28,6 +27,7 @@
import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryWrapperSynthesizerEventConsumer.DesugaredLibraryClasspathWrapperSynthesizeEventConsumer;
import com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryWrapperSynthesizerEventConsumer.DesugaredLibraryL8ProgramWrapperSynthesizerEventConsumer;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.CustomConversionDescriptor;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineDesugaredLibrarySpecification;
import com.android.tools.r8.ir.synthetic.DesugaredLibraryAPIConversionCfCodeProvider.APIConverterConstructorCfCodeProvider;
import com.android.tools.r8.ir.synthetic.DesugaredLibraryAPIConversionCfCodeProvider.APIConverterVivifiedWrapperCfCodeProvider;
@@ -39,7 +39,6 @@
import com.android.tools.r8.synthesis.SyntheticClassBuilder;
import com.android.tools.r8.synthesis.SyntheticMethodBuilder;
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
-import com.android.tools.r8.utils.Pair;
import com.android.tools.r8.utils.StringDiagnostic;
import java.util.ArrayList;
import java.util.Collection;
@@ -173,13 +172,19 @@
private DexMethod getCustomConversion(DexType type, DexType srcType, DexType destType) {
// ConversionType holds the methods "rewrittenType convert(type)" and the other way around.
// But everything is going to be rewritten, so we need to use vivifiedType and type".
- Pair<DexType, DexString> pair =
+ CustomConversionDescriptor descriptor =
appView.options().machineDesugaredLibrarySpecification.getCustomConversions().get(type);
- if (pair != null) {
- return factory.createMethod(
- pair.getFirst(), factory.createProto(destType, srcType), pair.getSecond());
+ if (descriptor == null) {
+ return null;
}
- return null;
+ // Because the conversion have rewritten types instead of vivified type we cannot use the
+ // specification content directly until the rewriting is done upfront in the compilation.
+ DexMethod conversion = type == srcType ? descriptor.getTo() : descriptor.getFrom();
+ assert type == srcType
+ ? type == conversion.getReturnType()
+ : type == conversion.getArgumentType(0, true);
+ return factory.createMethod(
+ conversion.getHolderType(), factory.createProto(destType, srcType), conversion.getName());
}
private boolean canConvert(DexType type) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/CustomConversionDescriptor.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/CustomConversionDescriptor.java
new file mode 100644
index 0000000..e8c3ce3
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/CustomConversionDescriptor.java
@@ -0,0 +1,27 @@
+// Copyright (c) 2022, 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.ir.desugar.desugaredlibrary.machinespecification;
+
+import com.android.tools.r8.graph.DexMethod;
+
+public class CustomConversionDescriptor {
+ private final DexMethod to;
+ private final DexMethod from;
+
+ public CustomConversionDescriptor(DexMethod to, DexMethod from) {
+ this.to = to;
+ this.from = from;
+ assert to.getReturnType() == from.getArgumentType(0, true);
+ assert from.getReturnType() == to.getArgumentType(0, true);
+ }
+
+ public DexMethod getTo() {
+ return to;
+ }
+
+ public DexMethod getFrom() {
+ return from;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java
index c06ce2f..adc507f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java
@@ -6,10 +6,8 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexReference;
-import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.Pair;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -133,7 +131,7 @@
return rewritingFlags.getDontRetarget();
}
- public Map<DexType, Pair<DexType, DexString>> getCustomConversions() {
+ public Map<DexType, CustomConversionDescriptor> getCustomConversions() {
return rewritingFlags.getCustomConversions();
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java
index 240a548..f34634d 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java
@@ -5,9 +5,7 @@
package com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification;
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.utils.Pair;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@@ -35,7 +33,7 @@
Map<DexType, List<DexMethod>> wrappers,
Map<DexType, DexType> legacyBackport,
Set<DexType> dontRetarget,
- Map<DexType, Pair<DexType, DexString>> customConversions) {
+ Map<DexType, CustomConversionDescriptor> customConversions) {
this.rewriteType = rewriteType;
this.rewriteDerivedTypeOnly = rewriteDerivedTypeOnly;
this.staticRetarget = staticRetarget;
@@ -80,7 +78,7 @@
private final Map<DexType, DexType> legacyBackport;
private final Set<DexType> dontRetarget;
- private final Map<DexType, Pair<DexType, DexString>> customConversions;
+ private final Map<DexType, CustomConversionDescriptor> customConversions;
public Map<DexType, DexType> getRewriteType() {
return rewriteType;
@@ -129,10 +127,14 @@
}
public boolean isCustomConversionRewrittenType(DexType type) {
- return Iterables.any(customConversions.values(), pair -> pair.getFirst() == type);
+ return Iterables.any(
+ customConversions.values(),
+ descriptor ->
+ descriptor.getFrom().getHolderType() == type
+ || descriptor.getTo().getHolderType() == type);
}
- public Map<DexType, Pair<DexType, DexString>> getCustomConversions() {
+ public Map<DexType, CustomConversionDescriptor> getCustomConversions() {
return customConversions;
}
@@ -178,7 +180,7 @@
private final ImmutableMap.Builder<DexType, List<DexMethod>> wrappers = ImmutableMap.builder();
private final ImmutableMap.Builder<DexType, DexType> legacyBackport = ImmutableMap.builder();
private final ImmutableSet.Builder<DexType> dontRetarget = ImmutableSet.builder();
- private final ImmutableMap.Builder<DexType, Pair<DexType, DexString>> customConversions =
+ private final ImmutableMap.Builder<DexType, CustomConversionDescriptor> customConversions =
ImmutableMap.builder();
public void rewriteType(DexType src, DexType target) {
@@ -225,8 +227,12 @@
dontRetarget.add(type);
}
- public void putCustomConversion(DexType src, DexType conversionType, DexString conversionName) {
- customConversions.put(src, new Pair<>(conversionType, conversionName));
+ public void putCustomConversion(DexType src, CustomConversionDescriptor descriptor) {
+ customConversions.put(src, descriptor);
+ }
+
+ public DexType getRewrittenType(DexType type) {
+ return rewriteType.get(type);
}
public MachineRewritingFlags build() {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java
index 1d5deac..c668858 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java
@@ -11,11 +11,15 @@
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
+import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecification;
import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanRewritingFlags;
import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanTopLevelFlags;
+import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.CustomConversionDescriptor;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineDesugaredLibrarySpecification;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineRewritingFlags;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineTopLevelFlags;
@@ -109,13 +113,31 @@
.getCustomConversions()
.forEach(
(type, conversionType) ->
- builder.putCustomConversion(
- type, conversionType, appInfo.dexItemFactory().convertMethodName));
+ convertCustomConversion(appInfo, builder, type, conversionType));
rewritingFlags.getDontRetargetLibMember().forEach(builder::addDontRetarget);
rewritingFlags.getBackportCoreLibraryMember().forEach(builder::putLegacyBackport);
return builder.build();
}
+ private void convertCustomConversion(
+ AppInfoWithClassHierarchy appInfo,
+ MachineRewritingFlags.Builder builder,
+ DexType type,
+ DexType conversionType) {
+ DexType rewrittenType = builder.getRewrittenType(type);
+ DexProto fromProto = appInfo.dexItemFactory().createProto(rewrittenType, type);
+ DexMethod fromMethod =
+ appInfo
+ .dexItemFactory()
+ .createMethod(conversionType, fromProto, appInfo.dexItemFactory().convertMethodName);
+ DexProto toProto = appInfo.dexItemFactory().createProto(type, rewrittenType);
+ DexMethod toMethod =
+ appInfo
+ .dexItemFactory()
+ .createMethod(conversionType, toProto, appInfo.dexItemFactory().convertMethodName);
+ builder.putCustomConversion(type, new CustomConversionDescriptor(toMethod, fromMethod));
+ }
+
private DexApplication readApp(AndroidApp inputApp, InternalOptions options) throws IOException {
ApplicationReader applicationReader = new ApplicationReader(inputApp, options, Timing.empty());
ExecutorService executorService = ThreadUtils.getExecutorService(options);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
index 2cb9a6f..85efd2b 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
@@ -131,9 +131,10 @@
machineDesugaredLibrarySpecification
.getCustomConversions()
.forEach(
- (type, conversionPair) -> {
+ (type, descriptor) -> {
registerType(appInfo, type);
- registerType(appInfo, conversionPair.getFirst());
+ registerType(appInfo, descriptor.getTo().getHolderType());
+ registerType(appInfo, descriptor.getFrom().getHolderType());
});
}