Store scoped mapping info on the side.
Bug: 172014416
Change-Id: Ia90fc8a032202497d16918f0e21f0385375ea035
diff --git a/src/main/java/com/android/tools/r8/naming/ClassNameMapper.java b/src/main/java/com/android/tools/r8/naming/ClassNameMapper.java
index af62c60..14c2179 100644
--- a/src/main/java/com/android/tools/r8/naming/ClassNameMapper.java
+++ b/src/main/java/com/android/tools/r8/naming/ClassNameMapper.java
@@ -15,14 +15,16 @@
import com.android.tools.r8.naming.MemberNaming.FieldSignature;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.naming.MemberNaming.Signature;
+import com.android.tools.r8.naming.mappinginformation.MappingInformation;
import com.android.tools.r8.naming.mappinginformation.ScopedMappingInformation;
+import com.android.tools.r8.naming.mappinginformation.ScopedMappingInformation.ScopeReference;
import com.android.tools.r8.position.Position;
import com.android.tools.r8.utils.BiMapContainer;
import com.android.tools.r8.utils.ChainableStringConsumer;
-import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.Reporter;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.CharSource;
import java.io.BufferedReader;
@@ -31,7 +33,6 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
@@ -48,7 +49,7 @@
public static class Builder extends ProguardMap.Builder {
private final Map<String, ClassNamingForNameMapper.Builder> mapping = new HashMap<>();
- private final Map<String, List<ScopedMappingInformation>> scopedMappingInfo = new HashMap<>();
+ private final Map<ScopeReference, List<MappingInformation>> scopedMappingInfo = new HashMap<>();
private Builder() {
@@ -72,26 +73,28 @@
@Override
public ClassNameMapper build() {
- return new ClassNameMapper(buildClassNameMappings());
+ return new ClassNameMapper(buildClassNameMappings(), buildScopedMappingInfo());
+ }
+
+ private ImmutableMap<ScopeReference, ImmutableList<MappingInformation>>
+ buildScopedMappingInfo() {
+ ImmutableMap.Builder<ScopeReference, ImmutableList<MappingInformation>> builder =
+ ImmutableMap.builder();
+ scopedMappingInfo.forEach((ref, infos) -> builder.put(ref, ImmutableList.copyOf(infos)));
+ return builder.build();
}
private ImmutableMap<String, ClassNamingForNameMapper> buildClassNameMappings() {
// Ensure that all scoped references have at least the identity in the final mapping.
- for (String descriptor : scopedMappingInfo.keySet()) {
- String typename = DescriptorUtils.descriptorToJavaType(descriptor);
- mapping.computeIfAbsent(typename, t -> ClassNamingForNameMapper.builder(t, t));
+ for (ScopeReference reference : scopedMappingInfo.keySet()) {
+ mapping.computeIfAbsent(
+ reference.getHolderReference().getTypeName(),
+ t -> ClassNamingForNameMapper.builder(t, t));
}
- // Build the final mapping while amending any entries with the scoped info.
ImmutableMap.Builder<String, ClassNamingForNameMapper> builder = ImmutableMap.builder();
builder.orderEntriesByValue(Comparator.comparing(x -> x.originalName));
mapping.forEach(
- (renamedName, valueBuilder) -> {
- String descriptor = DescriptorUtils.javaTypeToDescriptor(renamedName);
- scopedMappingInfo
- .getOrDefault(descriptor, Collections.emptyList())
- .forEach(valueBuilder::addMappingInformation);
- builder.put(renamedName, valueBuilder.build());
- });
+ (renamedName, valueBuilder) -> builder.put(renamedName, valueBuilder.build()));
return builder.build();
}
}
@@ -152,17 +155,26 @@
}
private final ImmutableMap<String, ClassNamingForNameMapper> classNameMappings;
+ private final ImmutableMap<ScopeReference, ImmutableList<MappingInformation>>
+ additionalMappingInfo;
private BiMapContainer<String, String> nameMapping;
private final Map<Signature, Signature> signatureMap = new HashMap<>();
- private ClassNameMapper(ImmutableMap<String, ClassNamingForNameMapper> classNameMappings) {
+ private ClassNameMapper(
+ ImmutableMap<String, ClassNamingForNameMapper> classNameMappings,
+ ImmutableMap<ScopeReference, ImmutableList<MappingInformation>> additionalMappingInfo) {
this.classNameMappings = classNameMappings;
+ this.additionalMappingInfo = additionalMappingInfo;
}
public Map<String, ClassNamingForNameMapper> getClassNameMappings() {
return classNameMappings;
}
+ public List<MappingInformation> getAdditionalMappingInfo(ScopeReference reference) {
+ return additionalMappingInfo.getOrDefault(reference, ImmutableList.of());
+ }
+
private Signature canonicalizeSignature(Signature signature) {
Signature result = signatureMap.get(signature);
if (result != null) {
@@ -232,7 +244,7 @@
ImmutableMap.Builder<String, ClassNamingForNameMapper> builder = ImmutableMap.builder();
builder.orderEntriesByValue(Comparator.comparing(x -> x.originalName));
classNameMappings.forEach(builder::put);
- return new ClassNameMapper(builder.build());
+ return new ClassNameMapper(builder.build(), additionalMappingInfo);
}
public boolean verifyIsSorted() {
diff --git a/src/main/java/com/android/tools/r8/naming/mappinginformation/ScopedMappingInformation.java b/src/main/java/com/android/tools/r8/naming/mappinginformation/ScopedMappingInformation.java
index deb0440..4385f5a 100644
--- a/src/main/java/com/android/tools/r8/naming/mappinginformation/ScopedMappingInformation.java
+++ b/src/main/java/com/android/tools/r8/naming/mappinginformation/ScopedMappingInformation.java
@@ -22,15 +22,28 @@
// to map to java.lang.String with the post-minification names.
public abstract static class ScopeReference {
+ public static ScopeReference fromClassReference(ClassReference reference) {
+ return new ClassScopeReference(reference);
+ }
+
+ // Method for reading in the serialized reference format.
public static ScopeReference fromReferenceString(String referenceString) {
if (DescriptorUtils.isClassDescriptor(referenceString)) {
- return new ClassScopeReference(Reference.classFromDescriptor(referenceString));
+ return fromClassReference(Reference.classFromDescriptor(referenceString));
}
throw new Unimplemented("No support for reference: " + referenceString);
}
public abstract String toReferenceString();
+ public abstract ClassReference getHolderReference();
+
+ @Override
+ public abstract boolean equals(Object other);
+
+ @Override
+ public abstract int hashCode();
+
@Override
public String toString() {
return toReferenceString();
@@ -38,9 +51,10 @@
}
public static class ClassScopeReference extends ScopeReference {
- final ClassReference reference;
+ private final ClassReference reference;
public ClassScopeReference(ClassReference reference) {
+ assert reference != null;
this.reference = reference;
}
@@ -48,6 +62,22 @@
public String toReferenceString() {
return reference.getDescriptor();
}
+
+ @Override
+ public ClassReference getHolderReference() {
+ return reference;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other instanceof ClassScopeReference
+ && reference.equals(((ClassScopeReference) other).reference);
+ }
+
+ @Override
+ public int hashCode() {
+ return reference.hashCode();
+ }
}
public abstract static class Builder<B extends Builder<B>> {
@@ -109,9 +139,9 @@
return this;
}
- public void forEach(BiConsumer<String, ScopedMappingInformation> fn) {
+ public void forEach(BiConsumer<ScopeReference, MappingInformation> fn) {
for (ScopeReference reference : scopeReferences) {
- fn.accept(reference.toReferenceString(), this);
+ fn.accept(reference, this);
}
}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
index c830cf6..b782ae2 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
@@ -28,6 +28,8 @@
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.naming.ClassNamingForNameMapper;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
+import com.android.tools.r8.naming.mappinginformation.MappingInformation;
+import com.android.tools.r8.naming.mappinginformation.ScopedMappingInformation.ScopeReference;
import com.android.tools.r8.naming.signature.GenericSignatureAction;
import com.android.tools.r8.naming.signature.GenericSignatureParser;
import com.android.tools.r8.origin.Origin;
@@ -248,6 +250,49 @@
return clazz(Reference.classFromTypeName(name));
}
+ // Simple wrapper to more easily change the implementation for retracing subjects.
+ // This should in time be replaced by use of the Retrace API.
+ public static class MappingWrapper {
+
+ private static final MappingWrapper EMPTY =
+ new MappingWrapper(null, null) {
+ @Override
+ public Collection<MappingInformation> getAdditionalMappings() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public ClassNamingForNameMapper getNaming() {
+ return null;
+ }
+ };
+
+ static MappingWrapper create(ClassNameMapper mapper, ClassNamingForNameMapper naming) {
+ if (mapper == null || naming == null) {
+ return EMPTY;
+ }
+ return new MappingWrapper(mapper, naming);
+ }
+
+ private final ClassNameMapper mapper;
+ private final ClassNamingForNameMapper naming;
+
+ private MappingWrapper(ClassNameMapper mapper, ClassNamingForNameMapper naming) {
+ this.mapper = mapper;
+ this.naming = naming;
+ }
+
+ public Collection<MappingInformation> getAdditionalMappings() {
+ return mapper.getAdditionalMappingInfo(
+ ScopeReference.fromClassReference(Reference.classFromTypeName(naming.renamedName)));
+ }
+
+ public ClassNamingForNameMapper getNaming() {
+ assert naming != null;
+ return naming;
+ }
+ }
+
public ClassSubject clazz(ClassReference reference) {
String descriptor = reference.getDescriptor();
String name = DescriptorUtils.descriptorToJavaType(descriptor);
@@ -269,7 +314,7 @@
if (clazz == null) {
return new AbsentClassSubject(this, reference);
}
- return new FoundClassSubject(this, clazz, naming, reference);
+ return new FoundClassSubject(this, clazz, MappingWrapper.create(mapping, naming), reference);
}
public ClassSubject companionClassFor(Class<?> clazz) {
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
index 40deb3d..c69c4a0 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
@@ -40,6 +40,7 @@
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.ZipUtils;
+import com.android.tools.r8.utils.codeinspector.CodeInspector.MappingWrapper;
import com.google.common.collect.Sets;
import java.io.File;
import java.nio.file.Paths;
@@ -54,16 +55,16 @@
public class FoundClassSubject extends ClassSubject {
private final DexClass dexClass;
- final ClassNamingForNameMapper naming;
+ private final MappingWrapper mapping;
FoundClassSubject(
CodeInspector codeInspector,
DexClass dexClass,
- ClassNamingForNameMapper naming,
+ MappingWrapper mapping,
ClassReference reference) {
super(codeInspector, reference);
this.dexClass = dexClass;
- this.naming = naming;
+ this.mapping = mapping;
}
@Override
@@ -100,10 +101,10 @@
DexProto proto =
codeInspector.dexItemFactory.createProto(
codeInspector.toDexType(codeInspector.getObfuscatedTypeName(returnType)), parameterTypes);
- if (naming != null) {
+ if (getNaming() != null) {
Signature signature =
new MethodSignature(name, returnType, parameters.toArray(StringUtils.EMPTY_ARRAY));
- MemberNaming methodNaming = naming.lookupByOriginalSignature(signature);
+ MemberNaming methodNaming = getNaming().lookupByOriginalSignature(signature);
if (methodNaming != null) {
name = methodNaming.getRenamedName();
}
@@ -191,8 +192,8 @@
public FieldSubject field(String type, String name) {
String obfuscatedType = codeInspector.getObfuscatedTypeName(type);
MemberNaming fieldNaming = null;
- if (naming != null) {
- fieldNaming = naming.lookupByOriginalSignature(new FieldSignature(name, type));
+ if (getNaming() != null) {
+ fieldNaming = getNaming().lookupByOriginalSignature(new FieldSignature(name, type));
}
String obfuscatedName = fieldNaming == null ? name : fieldNaming.getRenamedName();
@@ -357,8 +358,8 @@
@Override
public String getOriginalName() {
- if (naming != null) {
- return naming.originalName;
+ if (getNaming() != null) {
+ return getNaming().originalName;
} else {
return getFinalName();
}
@@ -366,8 +367,8 @@
@Override
public String getOriginalDescriptor() {
- if (naming != null) {
- return DescriptorUtils.javaTypeToDescriptor(naming.originalName);
+ if (getNaming() != null) {
+ return DescriptorUtils.javaTypeToDescriptor(getNaming().originalName);
} else {
return getFinalDescriptor();
}
@@ -409,15 +410,12 @@
@Override
public boolean isRenamed() {
- return naming != null && !getFinalDescriptor().equals(getOriginalDescriptor());
+ return getNaming() != null && !getFinalDescriptor().equals(getOriginalDescriptor());
}
@Override
public boolean isCompilerSynthesized() {
- if (naming == null) {
- return false;
- }
- for (MappingInformation info : naming.getAdditionalMappings()) {
+ for (MappingInformation info : mapping.getAdditionalMappings()) {
if (info.isCompilerSynthesizedMappingInformation()) {
return true;
}
@@ -467,7 +465,7 @@
public int hashCode() {
int result = codeInspector.hashCode();
result = 31 * result + dexClass.hashCode();
- result = 31 * result + (naming != null ? naming.hashCode() : 0);
+ result = 31 * result + (getNaming() != null ? getNaming().hashCode() : 0);
return result;
}
@@ -479,7 +477,7 @@
FoundClassSubject otherSubject = (FoundClassSubject) other;
return codeInspector == otherSubject.codeInspector
&& dexClass == otherSubject.dexClass
- && naming == otherSubject.naming;
+ && getNaming() == otherSubject.getNaming();
}
@Override
@@ -538,7 +536,7 @@
@Override
public ClassNamingForNameMapper getNaming() {
- return naming;
+ return mapping.getNaming();
}
@Override
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java
index 023f412..26466c1 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java
@@ -39,7 +39,8 @@
@Override
public boolean isRenamed() {
- return clazz.naming != null && !getFinalSignature().name.equals(getOriginalSignature().name);
+ return clazz.getNaming() != null
+ && !getFinalSignature().name.equals(getOriginalSignature().name);
}
public TypeSubject type() {
@@ -49,7 +50,7 @@
@Override
public FieldSignature getOriginalSignature() {
FieldSignature signature = getFinalSignature();
- if (clazz.naming == null) {
+ if (clazz.getNaming() == null) {
return signature;
}
@@ -66,7 +67,7 @@
String fieldType = originalType != null ? originalType : obfuscatedType;
FieldSignature lookupSignature = new FieldSignature(signature.name, fieldType);
- MemberNaming memberNaming = clazz.naming.lookup(lookupSignature);
+ MemberNaming memberNaming = clazz.getNaming().lookup(lookupSignature);
return memberNaming != null
? (FieldSignature) memberNaming.getOriginalSignature()
: lookupSignature;
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
index f215cca..268c51a 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
@@ -78,7 +78,8 @@
@Override
public boolean isRenamed() {
- return clazz.naming != null && !getFinalSignature().name.equals(getOriginalSignature().name);
+ return clazz.getNaming() != null
+ && !getFinalSignature().name.equals(getOriginalSignature().name);
}
@Override
@@ -129,7 +130,7 @@
@Override
public MethodSignature getOriginalSignature() {
MethodSignature signature = getFinalSignature();
- if (clazz.naming == null) {
+ if (clazz.getNaming() == null) {
return signature;
}
@@ -149,7 +150,7 @@
MethodSignature lookupSignature =
new MethodSignature(signature.name, returnType, originalParameters);
- MemberNaming memberNaming = clazz.naming.lookup(lookupSignature);
+ MemberNaming memberNaming = clazz.getNaming().lookup(lookupSignature);
return memberNaming != null ? (MethodSignature) memberNaming.getOriginalSignature() : signature;
}