Reland "Stub retargeter"
This reverts commit 4cb874265aec9256c3f9cb4b301df4e87b14f5bf.
Bug:198273164
Change-Id: I2cdfa360e3b399fc5401b536f193fe60d7a40e4d
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 85c05f6..5a95c61 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -49,7 +49,6 @@
import com.android.tools.r8.ir.desugar.BackportedMethodRewriter;
import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringCollection;
import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeterLibraryTypeSynthesizer;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter;
import com.android.tools.r8.ir.desugar.records.RecordDesugaring;
import com.android.tools.r8.ir.desugar.records.RecordFieldValuesRewriter;
@@ -311,10 +310,6 @@
if (!options.mainDexKeepRules.isEmpty()) {
MainDexListBuilder.checkForAssumedLibraryTypes(appView.appInfo());
}
- if (options.machineDesugaredLibrarySpecification.hasRetargeting()) {
- DesugaredLibraryRetargeterLibraryTypeSynthesizer.checkForAssumedLibraryTypes(appView);
- DesugaredLibraryRetargeterLibraryTypeSynthesizer.amendLibraryWithRetargetedMembers(appView);
- }
InterfaceMethodRewriter.checkForAssumedLibraryTypes(appView.appInfo(), options);
BackportedMethodRewriter.registerAssumedLibraryTypes(options);
if (options.enableEnumUnboxing) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
index 5fcf037..56167d8 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
@@ -12,7 +12,6 @@
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClassAndMethod;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.MethodResolutionResult;
@@ -87,6 +86,18 @@
return computeNewInvokeTarget(instruction, context).hasNewInvokeTarget();
}
+ InvokeRetargetingResult ensureInvokeRetargetingResult(DexMethod retarget) {
+ if (retarget == null) {
+ return NO_REWRITING;
+ }
+ return new InvokeRetargetingResult(
+ true,
+ eventConsumer -> {
+ syntheticHelper.ensureRetargetMethod(retarget, eventConsumer);
+ return retarget;
+ });
+ }
+
static class InvokeRetargetingResult {
static InvokeRetargetingResult NO_REWRITING =
@@ -96,13 +107,6 @@
private final Function<DesugaredLibraryRetargeterInstructionEventConsumer, DexMethod>
newInvokeTargetSupplier;
- static InvokeRetargetingResult createInvokeRetargetingResult(DexMethod retarget) {
- if (retarget == null) {
- return NO_REWRITING;
- }
- return new InvokeRetargetingResult(true, ignored -> retarget);
- }
-
private InvokeRetargetingResult(
boolean hasNewInvokeTarget,
Function<DesugaredLibraryRetargeterInstructionEventConsumer, DexMethod>
@@ -148,44 +152,33 @@
assert singleTarget != null;
if (cfInvoke.isInvokeStatic()) {
DexMethod retarget = staticRetarget.get(singleTarget);
- return retarget == null
- ? NO_REWRITING
- : InvokeRetargetingResult.createInvokeRetargetingResult(retarget);
+ return retarget == null ? NO_REWRITING : ensureInvokeRetargetingResult(retarget);
}
- InvokeRetargetingResult retarget = computeNonStaticRetarget(singleTarget);
+ InvokeRetargetingResult retarget = computeNonStaticRetarget(singleTarget, false);
if (!retarget.hasNewInvokeTarget()) {
return NO_REWRITING;
}
if (cfInvoke.isInvokeSuper(context.getHolderType())) {
DexClassAndMethod superTarget = appInfo.lookupSuperTarget(invokedMethod, context);
if (superTarget != null) {
- return computeSuperRetarget(superTarget.getDefinition());
+ assert !superTarget.getDefinition().isStatic();
+ return computeNonStaticRetarget(superTarget.getReference(), true);
}
}
return retarget;
}
- private InvokeRetargetingResult computeNonStaticRetarget(DexMethod singleTarget) {
+ private InvokeRetargetingResult computeNonStaticRetarget(
+ DexMethod singleTarget, boolean superInvoke) {
EmulatedDispatchMethodDescriptor descriptor = emulatedVirtualRetarget.get(singleTarget);
if (descriptor != null) {
return new InvokeRetargetingResult(
true,
eventConsumer ->
- syntheticHelper.ensureEmulatedHolderDispatchMethod(descriptor, eventConsumer));
+ superInvoke
+ ? syntheticHelper.ensureForwardingMethod(descriptor, eventConsumer)
+ : syntheticHelper.ensureEmulatedHolderDispatchMethod(descriptor, eventConsumer));
}
- return InvokeRetargetingResult.createInvokeRetargetingResult(
- nonEmulatedVirtualRetarget.get(singleTarget));
- }
-
- private InvokeRetargetingResult computeSuperRetarget(DexEncodedMethod singleTarget) {
- assert !singleTarget.isStatic();
- DexMethod reference = singleTarget.getReference();
- EmulatedDispatchMethodDescriptor descriptor = emulatedVirtualRetarget.get(reference);
- if (descriptor != null) {
- return InvokeRetargetingResult.createInvokeRetargetingResult(
- syntheticHelper.ensureForwardingMethod(descriptor));
- }
- return InvokeRetargetingResult.createInvokeRetargetingResult(
- nonEmulatedVirtualRetarget.get(reference));
+ return ensureInvokeRetargetingResult(nonEmulatedVirtualRetarget.get(singleTarget));
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterLibraryTypeSynthesizer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterLibraryTypeSynthesizer.java
deleted file mode 100644
index bfb423a..0000000
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterLibraryTypeSynthesizer.java
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright (c) 2021, 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.retargeter;
-
-import com.android.tools.r8.ProgramResource.Kind;
-import com.android.tools.r8.dex.Constants;
-import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.ClassAccessFlags;
-import com.android.tools.r8.graph.DexAnnotationSet;
-import com.android.tools.r8.graph.DexClass;
-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.DexLibraryClass;
-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.graph.DexTypeList;
-import com.android.tools.r8.graph.DirectMappedDexApplication;
-import com.android.tools.r8.graph.EnclosingMethodAttribute;
-import com.android.tools.r8.graph.GenericSignature.ClassSignature;
-import com.android.tools.r8.graph.InnerClassAttribute;
-import com.android.tools.r8.graph.MethodAccessFlags;
-import com.android.tools.r8.graph.NestHostClassAttribute;
-import com.android.tools.r8.graph.NestMemberClassAttribute;
-import com.android.tools.r8.origin.SynthesizedOrigin;
-import com.android.tools.r8.utils.StringDiagnostic;
-import java.util.Comparator;
-import java.util.IdentityHashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeSet;
-
-public class DesugaredLibraryRetargeterLibraryTypeSynthesizer {
-
- public static void checkForAssumedLibraryTypes(AppView<?> appView) {
- appView
- .options()
- .machineDesugaredLibrarySpecification
- .forEachRetargetHolder(
- inType -> {
- DexClass typeClass = appView.definitionFor(inType);
- if (typeClass == null) {
- warnMissingRetargetCoreLibraryMember(inType, appView);
- }
- });
- }
-
- public static void amendLibraryWithRetargetedMembers(AppView<AppInfoWithClassHierarchy> appView) {
- Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
- appView.options().desugaredLibrarySpecification.getRetargetCoreLibMember();
- Map<DexType, DexLibraryClass> synthesizedLibraryClasses =
- synthesizeLibraryClassesForRetargetedMembers(appView, retargetCoreLibMember);
- Map<DexLibraryClass, Set<DexEncodedMethod>> synthesizedLibraryMethods =
- synthesizedMembersForRetargetClasses(
- appView, retargetCoreLibMember, synthesizedLibraryClasses);
- synthesizedLibraryMethods.forEach(DexLibraryClass::addDirectMethods);
- DirectMappedDexApplication newApplication =
- appView
- .appInfo()
- .app()
- .asDirect()
- .builder()
- .addLibraryClasses(synthesizedLibraryClasses.values())
- .build();
- appView.setAppInfo(appView.appInfo().rebuildWithClassHierarchy(app -> newApplication));
- }
-
- private static Map<DexType, DexLibraryClass> synthesizeLibraryClassesForRetargetedMembers(
- AppView<AppInfoWithClassHierarchy> appView,
- Map<DexString, Map<DexType, DexType>> retargetCoreLibMember) {
- DexItemFactory dexItemFactory = appView.dexItemFactory();
- Map<DexType, DexLibraryClass> synthesizedLibraryClasses = new LinkedHashMap<>();
- for (Map<DexType, DexType> oldToNewTypeMap : retargetCoreLibMember.values()) {
- for (DexType newType : oldToNewTypeMap.values()) {
- if (appView.definitionFor(newType) == null) {
- synthesizedLibraryClasses.computeIfAbsent(
- newType,
- type ->
- // Synthesize a library class with the given name. Note that this is assuming that
- // the library class inherits directly from java.lang.Object, does not implement
- // any interfaces, etc.
- new DexLibraryClass(
- type,
- Kind.CF,
- new SynthesizedOrigin(
- "Desugared library retargeter", DesugaredLibraryRetargeter.class),
- ClassAccessFlags.fromCfAccessFlags(Constants.ACC_PUBLIC),
- dexItemFactory.objectType,
- DexTypeList.empty(),
- dexItemFactory.createString("DesugaredLibraryRetargeter"),
- NestHostClassAttribute.none(),
- NestMemberClassAttribute.emptyList(),
- EnclosingMethodAttribute.none(),
- InnerClassAttribute.emptyList(),
- ClassSignature.noSignature(),
- DexAnnotationSet.empty(),
- DexEncodedField.EMPTY_ARRAY,
- DexEncodedField.EMPTY_ARRAY,
- DexEncodedMethod.EMPTY_ARRAY,
- DexEncodedMethod.EMPTY_ARRAY,
- dexItemFactory.getSkipNameValidationForTesting()));
- }
- }
- }
- return synthesizedLibraryClasses;
- }
-
- private static Map<DexLibraryClass, Set<DexEncodedMethod>> synthesizedMembersForRetargetClasses(
- AppView<AppInfoWithClassHierarchy> appView,
- Map<DexString, Map<DexType, DexType>> retargetCoreLibMember,
- Map<DexType, DexLibraryClass> synthesizedLibraryClasses) {
- DexItemFactory dexItemFactory = appView.dexItemFactory();
- Map<DexLibraryClass, Set<DexEncodedMethod>> synthesizedMembers = new IdentityHashMap<>();
- for (Entry<DexString, Map<DexType, DexType>> entry : retargetCoreLibMember.entrySet()) {
- DexString methodName = entry.getKey();
- Map<DexType, DexType> types = entry.getValue();
- types.forEach(
- (oldType, newType) -> {
- DexClass oldClass = appView.definitionFor(oldType);
- DexLibraryClass newClass = synthesizedLibraryClasses.get(newType);
- if (oldClass == null || newClass == null) {
- return;
- }
- for (DexEncodedMethod method :
- oldClass.methods(method -> method.getName() == methodName)) {
- DexMethod retargetMethod = method.getReference().withHolder(newType, dexItemFactory);
- if (!method.isStatic()) {
- retargetMethod = retargetMethod.withExtraArgumentPrepended(oldType, dexItemFactory);
- }
- synthesizedMembers
- .computeIfAbsent(
- newClass,
- ignore -> new TreeSet<>(Comparator.comparing(DexEncodedMethod::getReference)))
- .add(
- DexEncodedMethod.syntheticBuilder()
- .setMethod(retargetMethod)
- .setAccessFlags(
- MethodAccessFlags.fromCfAccessFlags(
- Constants.ACC_PUBLIC | Constants.ACC_STATIC, false))
- .setCode(null)
- .setApiLevelForDefinition(method.getApiLevelForDefinition())
- .build());
- }
- });
- }
- return synthesizedMembers;
- }
-
- private static void warnMissingRetargetCoreLibraryMember(DexType type, AppView<?> appView) {
- StringDiagnostic warning =
- new StringDiagnostic(
- "Cannot retarget core library member "
- + type.getName()
- + " because the class is missing.");
- appView.options().reporter.warning(warning);
- }
-}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterPostProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterPostProcessor.java
index d1e64ec..3d70140 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterPostProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterPostProcessor.java
@@ -136,7 +136,7 @@
Collections.singletonList(new ClassTypeSignature(newInterface.type)));
eventConsumer.acceptInterfaceInjection(clazz, newInterface);
DexMethod itfMethod =
- syntheticHelper.getEmulatedInterfaceDispatchMethod(newInterface, descriptor);
+ syntheticHelper.emulatedInterfaceDispatchMethod(newInterface, descriptor);
if (clazz.lookupVirtualMethod(method) == null) {
DexEncodedMethod newMethod = createForwardingMethod(itfMethod, descriptor, clazz);
clazz.addVirtualMethod(newMethod);
@@ -150,7 +150,7 @@
// NOTE: Never add a forwarding method to methods of classes unknown or coming from android.jar
// even if this results in invalid code, these classes are never desugared.
// In desugared library, emulated interface methods can be overridden by retarget lib members.
- DexMethod forwardMethod = syntheticHelper.ensureForwardingMethod(descriptor);
+ DexMethod forwardMethod = syntheticHelper.forwardingMethod(descriptor);
assert forwardMethod != null && forwardMethod != target;
DexEncodedMethod resolvedMethod =
appView.appInfoForDesugaring().resolveMethod(target, true).getResolvedMethod();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSyntheticHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSyntheticHelper.java
index 5519d95..6102e1a 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSyntheticHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeterSyntheticHelper.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
+import com.android.tools.r8.graph.ClasspathMethod;
import com.android.tools.r8.graph.ClasspathOrLibraryClass;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexMethod;
@@ -29,12 +30,46 @@
this.appView = appView;
}
- public DexMethod ensureForwardingMethod(EmulatedDispatchMethodDescriptor descriptor) {
- // TODO(b/184026720): We may synthesize a stub on the classpath if absent.
+ public DexMethod ensureRetargetMethod(
+ DexMethod retarget, DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
+ DexClass holderClass = appView.definitionFor(retarget.getHolderType());
+ if (holderClass != null && !holderClass.isClasspathClass()) {
+ // The holder class is a library class in orthodox set-ups where the L8 compilation
+ // is done in multiple steps, this is only partially supported (most notably for tests).
+ assert holderClass.lookupMethod(retarget) != null;
+ return retarget;
+ }
+ assert eventConsumer != null;
+ ClasspathMethod ensuredMethod =
+ appView
+ .getSyntheticItems()
+ .ensureFixedClasspathMethodFromType(
+ retarget.getName(),
+ retarget.getProto(),
+ SyntheticKind.RETARGET_STUB,
+ retarget.getHolderType(),
+ appView,
+ ignored -> {},
+ eventConsumer::acceptDesugaredLibraryRetargeterDispatchClasspathClass,
+ methodBuilder ->
+ methodBuilder
+ .setAccessFlags(MethodAccessFlags.createPublicStaticSynthetic())
+ .setCode(null));
+ assert ensuredMethod.getReference() == retarget;
+ return retarget;
+ }
+
+ DexMethod forwardingMethod(EmulatedDispatchMethodDescriptor descriptor) {
assert descriptor.getForwardingMethod().getHolderKind() == null;
return descriptor.getForwardingMethod().getMethod();
}
+ public DexMethod ensureForwardingMethod(
+ EmulatedDispatchMethodDescriptor descriptor,
+ DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
+ return ensureRetargetMethod(forwardingMethod(descriptor), eventConsumer);
+ }
+
private DexMethod emulatedHolderDispatchMethod(DexType holder, DerivedMethod method) {
assert method.getHolderKind() == SyntheticKind.RETARGET_CLASS;
DexProto newProto = appView.dexItemFactory().prependHolderToProto(method.getMethod());
@@ -46,7 +81,7 @@
return appView.dexItemFactory().createMethod(holder, method.getProto(), method.getName());
}
- public DexMethod getEmulatedInterfaceDispatchMethod(
+ public DexMethod emulatedInterfaceDispatchMethod(
DexClass newInterface, EmulatedDispatchMethodDescriptor descriptor) {
DexMethod method =
emulatedInterfaceDispatchMethod(newInterface.type, descriptor.getInterfaceMethod());
@@ -83,7 +118,8 @@
SyntheticKind.RETARGET_CLASS,
context,
appView,
- classBuilder -> buildHolderDispatchMethod(classBuilder, itfClass, descriptor),
+ classBuilder ->
+ buildHolderDispatchMethod(classBuilder, itfClass, descriptor, eventConsumer),
eventConsumer::acceptDesugaredLibraryRetargeterDispatchClasspathClass);
}
DexMethod dispatchMethod =
@@ -107,7 +143,7 @@
emulatedDispatchMethod.getHolderKind(),
holderContext,
appView,
- classBuilder -> buildHolderDispatchMethod(classBuilder, itfClass, descriptor),
+ classBuilder -> buildHolderDispatchMethod(classBuilder, itfClass, descriptor, null),
eventConsumer::acceptDesugaredLibraryRetargeterDispatchProgramClass);
}
@@ -174,7 +210,10 @@
}
private <SCB extends SyntheticClassBuilder<?, ?>> void buildHolderDispatchMethod(
- SCB classBuilder, DexClass itfClass, EmulatedDispatchMethodDescriptor descriptor) {
+ SCB classBuilder,
+ DexClass itfClass,
+ EmulatedDispatchMethodDescriptor descriptor,
+ DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
classBuilder.addMethod(
methodBuilder -> {
DexMethod dispatchMethod =
@@ -189,15 +228,19 @@
.setCode(
methodSig ->
appView.options().isDesugaredLibraryCompilation()
- ? generateEmulatedDispatchCfCode(descriptor, itfClass, methodSig)
+ ? generateEmulatedDispatchCfCode(
+ descriptor, itfClass, methodSig, eventConsumer)
: null);
});
}
private CfCode generateEmulatedDispatchCfCode(
- EmulatedDispatchMethodDescriptor descriptor, DexClass itfClass, DexMethod methodSig) {
- DexMethod forwardingMethod = ensureForwardingMethod(descriptor);
- DexMethod itfMethod = getEmulatedInterfaceDispatchMethod(itfClass, descriptor);
+ EmulatedDispatchMethodDescriptor descriptor,
+ DexClass itfClass,
+ DexMethod methodSig,
+ DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
+ DexMethod forwardingMethod = ensureForwardingMethod(descriptor, eventConsumer);
+ DexMethod itfMethod = emulatedInterfaceDispatchMethod(itfClass, descriptor);
assert descriptor.getDispatchCases().isEmpty();
return new EmulateDispatchSyntheticCfCodeProvider(
methodSig.getHolderType(), forwardingMethod, itfMethod, new LinkedHashMap<>(), appView)
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
index cb4a537..7c3303b 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
@@ -171,7 +171,8 @@
SyntheticKind.EMULATED_INTERFACE_MARKER_CLASS,
type,
appView,
- SyntheticClassBuilder::setInterface);
+ SyntheticClassBuilder::setInterface,
+ ignored -> {});
}
DexClassAndMethod lookupMaximallySpecificIncludingSelf(
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
index 6d45ee1..9b67476 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.features.ClassToFeatureSplitMap;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.ClasspathMethod;
import com.android.tools.r8.graph.ClasspathOrLibraryClass;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
@@ -649,10 +650,11 @@
SyntheticKind kind,
DexType contextType,
AppView<?> appView,
- Consumer<SyntheticClasspathClassBuilder> classConsumer) {
+ Consumer<SyntheticClasspathClassBuilder> classConsumer,
+ Consumer<DexClasspathClass> onCreationConsumer) {
SynthesizingContext outerContext = SynthesizingContext.fromType(contextType);
return internalEnsureFixedClasspathClass(
- kind, classConsumer, ignored -> {}, outerContext, appView);
+ kind, classConsumer, onCreationConsumer, outerContext, appView);
}
public DexClasspathClass ensureFixedClasspathClass(
@@ -668,7 +670,23 @@
kind, classConsumer, onCreationConsumer, outerContext, appView);
}
- public DexClassAndMethod ensureFixedClasspathClassMethod(
+ public ClasspathMethod ensureFixedClasspathMethodFromType(
+ DexString methodName,
+ DexProto methodProto,
+ SyntheticKind kind,
+ DexType contextType,
+ AppView<?> appView,
+ Consumer<SyntheticClasspathClassBuilder> classConsumer,
+ Consumer<DexClasspathClass> onCreationConsumer,
+ Consumer<SyntheticMethodBuilder> buildMethodCallback) {
+ DexClasspathClass clazz =
+ ensureFixedClasspathClassFromType(
+ kind, contextType, appView, classConsumer, onCreationConsumer);
+ return internalEnsureFixedClasspathMethod(
+ methodName, methodProto, kind, appView, buildMethodCallback, clazz);
+ }
+
+ public ClasspathMethod ensureFixedClasspathClassMethod(
DexString methodName,
DexProto methodProto,
SyntheticKind kind,
@@ -680,6 +698,17 @@
DexClasspathClass clazz =
ensureFixedClasspathClass(
kind, context, appView, buildClassCallback, onClassCreationCallback);
+ return internalEnsureFixedClasspathMethod(
+ methodName, methodProto, kind, appView, buildMethodCallback, clazz);
+ }
+
+ private ClasspathMethod internalEnsureFixedClasspathMethod(
+ DexString methodName,
+ DexProto methodProto,
+ SyntheticKind kind,
+ AppView<?> appView,
+ Consumer<SyntheticMethodBuilder> buildMethodCallback,
+ DexClasspathClass clazz) {
DexMethod methodReference =
appView.dexItemFactory().createMethod(clazz.getType(), methodProto, methodName);
DexEncodedMethod methodDefinition =
@@ -694,7 +723,7 @@
buildMethodCallback.accept(methodBuilder.disableAndroidApiLevelCheck());
},
emptyConsumer());
- return DexClassAndMethod.create(clazz, methodDefinition);
+ return new ClasspathMethod(clazz, methodDefinition);
}
@SuppressWarnings("unchecked")
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
index b7861e3..ec8a010 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
@@ -180,6 +180,10 @@
}
private Code getCodeObject(DexMethod methodSignature) {
+ if (codeGenerator == null) {
+ // If the method is on the classpath then no code is needed.
+ return null;
+ }
return codeGenerator.generate(methodSignature);
}
}
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
index 62c7c6f..4d8b529 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
@@ -31,6 +31,7 @@
COMPANION_CLASS("$-CC", 2, false, true),
EMULATED_INTERFACE_CLASS("$-EL", 3, false, true),
RETARGET_CLASS("RetargetClass", 20, false, true),
+ RETARGET_STUB("", 36, false, true),
RETARGET_INTERFACE("RetargetInterface", 21, false, true),
WRAPPER("$Wrapper", 22, false, true),
VIVIFIED_WRAPPER("$VivifiedWrapper", 23, false, true),
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/RetargetAndBackportTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/RetargetAndBackportTest.java
index 9b1804e..27762ea 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/RetargetAndBackportTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/RetargetAndBackportTest.java
@@ -46,7 +46,6 @@
* {
* "rewrite_prefix":{"java.time.": "j$.time."},
* "backport": {"java.lang.DesugarMath": "java.lang.Math"},
- * "retarget_lib_member": {"java.util.Date#toInstant": "java.util.DesugarDate"}
* }
* ],
*/
@@ -55,7 +54,6 @@
LegacyRewritingFlags.builder(options.itemFactory, options.reporter, Origin.unknown())
.putRewritePrefix("java.time.", "j$.time.")
.putBackportCoreLibraryMember("java.lang.DesugarMath", "java.lang.Math")
- .putRetargetCoreLibMember("java.util.Date#toInstant", "java.util.DesugarDate")
.build();
try {
options.setDesugaredLibrarySpecificationForTesting(
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/ConversionsPresentTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/ConversionsPresentTest.java
index 01f9b80..6972449 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/ConversionsPresentTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/ConversionsPresentTest.java
@@ -46,6 +46,7 @@
L8Command.builder(diagnosticsHandler)
.addLibraryFiles(getLibraryFile())
.addProgramFiles(ToolHelper.DESUGAR_LIB_CONVERSIONS)
+ .addProgramFiles(ToolHelper.getDesugarJDKLibs())
.addDesugaredLibraryConfiguration(
StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
.setMinApiLevel(parameters.getApiLevel().getLevel())