Update naming convention for desugared library synthetic types
Bug: 184026720
Change-Id: I94e5f685f85c077072dcd87d2ef2d678d6f32fb7
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/PrefixRewritingMapper.java b/src/main/java/com/android/tools/r8/ir/desugar/PrefixRewritingMapper.java
index eb4f662..f5861d7 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/PrefixRewritingMapper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/PrefixRewritingMapper.java
@@ -11,9 +11,9 @@
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.ir.desugar.desugaredlibrary.legacyspecification.LegacyDesugaredLibrarySpecification;
import com.android.tools.r8.utils.DescriptorUtils;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import java.util.Map;
import java.util.Set;
@@ -30,6 +30,8 @@
public abstract DexType rewrittenType(DexType type, AppView<?> appView);
+ public abstract DexType rewrittenContextType(DexType type, AppView<?> appView);
+
public boolean hasRewrittenType(DexType type, AppView<?> appView) {
return rewrittenType(type, appView) != null;
}
@@ -48,8 +50,6 @@
public abstract boolean isRewriting();
- public abstract boolean shouldRewriteTypeName(String typeName);
-
public abstract void forAllRewrittenTypes(Consumer<DexType> consumer);
public static class DesugarPrefixRewritingMapper extends PrefixRewritingMapper {
@@ -57,7 +57,6 @@
private final Set<DexType> notRewritten = Sets.newConcurrentHashSet();
private final Map<DexType, DexType> rewritten = new ConcurrentHashMap<>();
private final Map<DexString, DexString> initialPrefixes;
- private final Set<String> initialPrefixStrings;
private final DexItemFactory factory;
private final boolean l8Compilation;
@@ -67,13 +66,10 @@
this.factory = itemFactory;
this.l8Compilation = libraryCompilation;
ImmutableMap.Builder<DexString, DexString> builder = ImmutableMap.builder();
- ImmutableSet.Builder<String> prefixStringBuilder = ImmutableSet.builder();
for (String key : prefixes.keySet()) {
- prefixStringBuilder.add(key);
builder.put(toDescriptorPrefix(key), toDescriptorPrefix(prefixes.get(key)));
}
this.initialPrefixes = builder.build();
- this.initialPrefixStrings = prefixStringBuilder.build();
validatePrefixes(prefixes);
}
@@ -129,6 +125,36 @@
return computePrefix(type, appView);
}
+ @Override
+ public DexType rewrittenContextType(DexType type, AppView<?> appView) {
+ DexType rewritten = rewrittenType(type, appView);
+ if (rewritten != null) {
+ return rewritten;
+ }
+ LegacyDesugaredLibrarySpecification desugaredLibrarySpecification =
+ appView.options().desugaredLibrarySpecification;
+ if (desugaredLibrarySpecification.getEmulateLibraryInterface().containsKey(type)) {
+ return desugaredLibrarySpecification.getEmulateLibraryInterface().get(type);
+ }
+ for (Map<DexType, DexType> value :
+ desugaredLibrarySpecification.getRetargetCoreLibMember().values()) {
+ if (value.containsKey(type)) {
+ // Hack until machine specification are ready.
+ String prefix =
+ DescriptorUtils.getJavaTypeFromBinaryName(
+ desugaredLibrarySpecification.getSynthesizedLibraryClassesPackagePrefix());
+ String interfaceType = type.toString();
+ int firstPackage = interfaceType.indexOf('.');
+ return appView
+ .dexItemFactory()
+ .createType(
+ DescriptorUtils.javaTypeToDescriptor(
+ prefix + interfaceType.substring(firstPackage + 1)));
+ }
+ }
+ return null;
+ }
+
// Besides L8 compilation, program types should not be rewritten.
private void failIfRewritingProgramType(DexType type, AppView<?> appView) {
if (l8Compilation) {
@@ -192,17 +218,6 @@
public boolean isRewriting() {
return true;
}
-
- @Override
- public boolean shouldRewriteTypeName(String typeName) {
- // TODO(b/154800164): We could use tries instead of looking-up everywhere.
- for (DexString prefix : initialPrefixes.keySet()) {
- if (typeName.startsWith(prefix.toString())) {
- return true;
- }
- }
- return false;
- }
}
public static class EmptyPrefixRewritingMapper extends PrefixRewritingMapper {
@@ -213,6 +228,11 @@
}
@Override
+ public DexType rewrittenContextType(DexType type, AppView<?> appView) {
+ return null;
+ }
+
+ @Override
public void rewriteType(DexType type, DexType rewrittenType) {}
@Override
@@ -221,11 +241,6 @@
}
@Override
- public boolean shouldRewriteTypeName(String typeName) {
- return false;
- }
-
- @Override
public void forAllRewrittenTypes(Consumer<DexType> consumer) {}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryAPIConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryAPIConverter.java
index 558faf7..987dc8d 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryAPIConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryAPIConverter.java
@@ -235,6 +235,7 @@
.dexItemFactory()
.createSynthesizedType(
DescriptorUtils.javaTypeToDescriptor(VIVIFIED_PREFIX + type.toString()));
+ // We would need to ensure a classpath class for each type to remove this rewriteType call.
appView.rewritePrefix.rewriteType(vivifiedType, type);
return vivifiedType;
}
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 8f7d25f..5519d95 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
@@ -19,7 +19,6 @@
import com.android.tools.r8.ir.synthetic.EmulateDispatchSyntheticCfCodeProvider;
import com.android.tools.r8.synthesis.SyntheticClassBuilder;
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
-import com.android.tools.r8.utils.DescriptorUtils;
import java.util.LinkedHashMap;
public class DesugaredLibraryRetargeterSyntheticHelper {
@@ -85,10 +84,7 @@
context,
appView,
classBuilder -> buildHolderDispatchMethod(classBuilder, itfClass, descriptor),
- clazz -> {
- eventConsumer.acceptDesugaredLibraryRetargeterDispatchClasspathClass(clazz);
- rewriteType(clazz.type);
- });
+ eventConsumer::acceptDesugaredLibraryRetargeterDispatchClasspathClass);
}
DexMethod dispatchMethod =
emulatedHolderDispatchMethod(syntheticClass.type, emulatedDispatchMethod);
@@ -112,10 +108,7 @@
holderContext,
appView,
classBuilder -> buildHolderDispatchMethod(classBuilder, itfClass, descriptor),
- clazz -> {
- eventConsumer.acceptDesugaredLibraryRetargeterDispatchProgramClass(clazz);
- rewriteType(clazz.type);
- });
+ eventConsumer::acceptDesugaredLibraryRetargeterDispatchProgramClass);
}
public DexClass ensureEmulatedInterfaceDispatchMethod(
@@ -138,10 +131,7 @@
context,
appView,
classBuilder -> buildInterfaceDispatchMethod(classBuilder, descriptor),
- clazz -> {
- eventConsumer.acceptDesugaredLibraryRetargeterDispatchClasspathClass(clazz);
- rewriteType(clazz.type);
- });
+ eventConsumer::acceptDesugaredLibraryRetargeterDispatchClasspathClass);
}
public DexClass ensureEmulatedInterfaceDispatchMethod(
@@ -158,10 +148,7 @@
itfContext,
appView,
classBuilder -> buildInterfaceDispatchMethod(classBuilder, descriptor),
- clazz -> {
- eventConsumer.acceptDesugaredLibraryRetargeterDispatchProgramClass(clazz);
- rewriteType(clazz.type);
- });
+ eventConsumer::acceptDesugaredLibraryRetargeterDispatchProgramClass);
}
private void buildInterfaceDispatchMethod(
@@ -216,12 +203,4 @@
methodSig.getHolderType(), forwardingMethod, itfMethod, new LinkedHashMap<>(), appView)
.generateCfCode();
}
-
- private void rewriteType(DexType type) {
- String newName =
- appView.options().desugaredLibrarySpecification.convertJavaNameToDesugaredLibrary(type);
- DexType newType =
- appView.dexItemFactory().createType(DescriptorUtils.javaTypeToDescriptor(newName));
- appView.rewritePrefix.rewriteType(type, newType);
- }
}
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 a40d69a..d30f717 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
@@ -43,7 +43,6 @@
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.position.MethodPosition;
import com.android.tools.r8.synthesis.SyntheticNaming;
-import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.collections.ProgramMethodSet;
import com.android.tools.r8.utils.structural.Ordered;
@@ -160,8 +159,6 @@
Map<DexType, DexType> emulateLibraryInterface =
options.desugaredLibrarySpecification.getEmulateLibraryInterface();
for (DexType interfaceType : emulateLibraryInterface.keySet()) {
- addRewriteRulesForEmulatedInterface(
- interfaceType, emulateLibraryInterface.get(interfaceType).toSourceString());
DexClass emulatedInterfaceClass = appView.definitionFor(interfaceType);
if (emulatedInterfaceClass != null) {
for (DexEncodedMethod encodedMethod :
@@ -172,35 +169,6 @@
}
}
- void addRewriteRulesForEmulatedInterface(
- DexType emulatedInterface, String rewrittenEmulatedInterface) {
- addCompanionClassRewriteRule(emulatedInterface, rewrittenEmulatedInterface);
- appView.rewritePrefix.rewriteType(
- InterfaceDesugaringSyntheticHelper.getEmulateLibraryInterfaceClassType(
- emulatedInterface, factory),
- factory.createType(
- DescriptorUtils.javaTypeToDescriptor(
- rewrittenEmulatedInterface
- + InterfaceDesugaringSyntheticHelper.EMULATE_LIBRARY_CLASS_NAME_SUFFIX)));
- }
-
- private void addCompanionClassRewriteRule(DexType interfaceType, String rewrittenType) {
- addCompanionClassRewriteRule(interfaceType, rewrittenType, appView);
- }
-
- static void addCompanionClassRewriteRule(
- DexType interfaceType, String rewrittenType, AppView<?> appView) {
- appView.rewritePrefix.rewriteType(
- InterfaceDesugaringSyntheticHelper.getCompanionClassType(
- interfaceType, appView.dexItemFactory()),
- appView
- .dexItemFactory()
- .createType(
- DescriptorUtils.javaTypeToDescriptor(
- rewrittenType
- + InterfaceDesugaringSyntheticHelper.COMPANION_CLASS_NAME_SUFFIX)));
- }
-
private boolean isAlreadyDesugared(CfInvoke invoke, ProgramMethod context) {
return Iterables.any(
precedingDesugarings, desugaring -> desugaring.needsDesugaring(invoke, context));
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 a29bfcf..10e3e32 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
@@ -16,7 +16,6 @@
import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexClasspathClass;
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.DexProgramClass;
@@ -419,13 +418,15 @@
// Addition and creation of synthetic items.
- private DexProgramClass internalEnsureDexProgramClass(
+ private DexProgramClass internalEnsureFixedProgramClass(
SyntheticKind kind,
Consumer<SyntheticProgramClassBuilder> classConsumer,
Consumer<DexProgramClass> onCreationConsumer,
SynthesizingContext outerContext,
- DexType type,
AppView<?> appView) {
+ Function<SynthesizingContext, DexType> contextToType =
+ c -> SyntheticNaming.createFixedType(kind, c, appView.dexItemFactory());
+ DexType type = contextToType.apply(outerContext);
// Fast path is that the synthetic is already present. If so it must be a program class.
DexClass dexClass = appView.definitionFor(type);
if (dexClass != null) {
@@ -452,7 +453,8 @@
},
outerContext,
type,
- appView.dexItemFactory());
+ contextToType,
+ appView);
onCreationConsumer.accept(dexProgramClass);
return dexProgramClass;
}
@@ -463,15 +465,33 @@
Consumer<SyntheticProgramClassBuilder> fn,
SynthesizingContext outerContext,
DexType type,
- DexItemFactory factory) {
+ Function<SynthesizingContext, DexType> contextToType,
+ AppView<?> appView) {
+ registerSyntheticTypeRewriting(outerContext, contextToType, appView, type);
SyntheticProgramClassBuilder classBuilder =
- new SyntheticProgramClassBuilder(type, kind, outerContext, factory);
+ new SyntheticProgramClassBuilder(type, kind, outerContext, appView.dexItemFactory());
fn.accept(classBuilder);
DexProgramClass clazz = classBuilder.build();
addPendingDefinition(new SyntheticProgramClassDefinition(kind, outerContext, clazz));
return clazz;
}
+ private void registerSyntheticTypeRewriting(
+ SynthesizingContext outerContext,
+ Function<SynthesizingContext, DexType> contextToType,
+ AppView<?> appView,
+ DexType type) {
+ DexType rewrittenContextType =
+ appView.rewritePrefix.rewrittenContextType(
+ outerContext.getSynthesizingContextType(), appView);
+ if (rewrittenContextType == null) {
+ return;
+ }
+ SynthesizingContext synthesizingContext = SynthesizingContext.fromType(rewrittenContextType);
+ DexType rewrittenType = contextToType.apply(synthesizingContext);
+ appView.rewritePrefix.rewriteType(type, rewrittenType);
+ }
+
public DexProgramClass createClass(
SyntheticKind kind,
UniqueContext context,
@@ -480,10 +500,12 @@
// Obtain the outer synthesizing context in the case the context itself is synthetic.
// This is to ensure a flat input-type -> synthetic-item mapping.
SynthesizingContext outerContext = getSynthesizingContext(context.getClassContext(), appView);
- DexType type =
- SyntheticNaming.createInternalType(
- kind, outerContext, context.getSyntheticSuffix(), appView.dexItemFactory());
- return internalCreateProgramClass(kind, fn, outerContext, type, appView.dexItemFactory());
+ Function<SynthesizingContext, DexType> contextToType =
+ c ->
+ SyntheticNaming.createInternalType(
+ kind, c, context.getSyntheticSuffix(), appView.dexItemFactory());
+ return internalCreateProgramClass(
+ kind, fn, outerContext, contextToType.apply(outerContext), contextToType, appView);
}
// TODO(b/172194101): Make this take a unique context.
@@ -493,8 +515,10 @@
AppView<?> appView,
Consumer<SyntheticProgramClassBuilder> fn) {
SynthesizingContext outerContext = internalGetOuterContext(context, appView);
- DexType type = SyntheticNaming.createFixedType(kind, outerContext, appView.dexItemFactory());
- return internalCreateProgramClass(kind, fn, outerContext, type, appView.dexItemFactory());
+ Function<SynthesizingContext, DexType> contextToType =
+ c -> SyntheticNaming.createFixedType(kind, c, appView.dexItemFactory());
+ return internalCreateProgramClass(
+ kind, fn, outerContext, contextToType.apply(outerContext), contextToType, appView);
}
public DexProgramClass getExistingFixedClass(
@@ -530,8 +554,7 @@
Consumer<DexProgramClass> onCreationConsumer) {
assert kind.isFixedSuffixSynthetic;
SynthesizingContext outerContext = internalGetOuterContext(context, appView);
- DexType type = SyntheticNaming.createFixedType(kind, outerContext, appView.dexItemFactory());
- return internalEnsureDexProgramClass(kind, fn, onCreationConsumer, outerContext, type, appView);
+ return internalEnsureFixedProgramClass(kind, fn, onCreationConsumer, outerContext, appView);
}
public ProgramMethod ensureFixedClassMethod(
@@ -589,13 +612,15 @@
+ " class.");
}
- private DexClasspathClass internalEnsureDexClasspathClass(
+ private DexClasspathClass internalEnsureFixedClasspathClass(
SyntheticKind kind,
Consumer<SyntheticClasspathClassBuilder> classConsumer,
Consumer<DexClasspathClass> onCreationConsumer,
SynthesizingContext outerContext,
- DexType type,
AppView<?> appView) {
+ Function<SynthesizingContext, DexType> contextToType =
+ (c) -> SyntheticNaming.createFixedType(kind, c, appView.dexItemFactory());
+ DexType type = contextToType.apply(outerContext);
synchronized (type) {
DexClass clazz = appView.definitionFor(type);
if (clazz != null) {
@@ -604,6 +629,7 @@
}
return clazz.asClasspathClass();
}
+ registerSyntheticTypeRewriting(outerContext, contextToType, appView, type);
SyntheticClasspathClassBuilder classBuilder =
new SyntheticClasspathClassBuilder(type, kind, outerContext, appView.dexItemFactory());
classConsumer.accept(classBuilder);
@@ -620,9 +646,8 @@
AppView<?> appView,
Consumer<SyntheticClasspathClassBuilder> classConsumer) {
SynthesizingContext outerContext = SynthesizingContext.fromType(contextType);
- DexType type = SyntheticNaming.createFixedType(kind, outerContext, appView.dexItemFactory());
- return internalEnsureDexClasspathClass(
- kind, classConsumer, ignored -> {}, outerContext, type, appView);
+ return internalEnsureFixedClasspathClass(
+ kind, classConsumer, ignored -> {}, outerContext, appView);
}
public DexClasspathClass ensureFixedClasspathClass(
@@ -634,9 +659,8 @@
// Obtain the outer synthesizing context in the case the context itself is synthetic.
// This is to ensure a flat input-type -> synthetic-item mapping.
SynthesizingContext outerContext = SynthesizingContext.fromNonSyntheticInputContext(context);
- DexType type = SyntheticNaming.createFixedType(kind, outerContext, appView.dexItemFactory());
- return internalEnsureDexClasspathClass(
- kind, classConsumer, onCreationConsumer, outerContext, type, appView);
+ return internalEnsureFixedClasspathClass(
+ kind, classConsumer, onCreationConsumer, outerContext, appView);
}
public DexClassAndMethod ensureFixedClasspathClassMethod(
@@ -703,8 +727,7 @@
// Obtain the outer synthesizing context in the case the context itself is synthetic.
// This is to ensure a flat input-type -> synthetic-item mapping.
SynthesizingContext outerContext = SynthesizingContext.fromType(contextType);
- DexType type = SyntheticNaming.createFixedType(kind, outerContext, appView.dexItemFactory());
- return internalEnsureDexProgramClass(kind, fn, onCreationConsumer, outerContext, type, appView);
+ return internalEnsureFixedProgramClass(kind, fn, onCreationConsumer, outerContext, appView);
}
/** Create a single synthetic method item. */