[Compose] Wait with removal of field signatures until finish
Bug: b/241763080
Change-Id: I3911606aa43552cff1ee2515c3bc41c750e15d69
diff --git a/src/main/java/com/android/tools/r8/naming/ComposingBuilder.java b/src/main/java/com/android/tools/r8/naming/ComposingBuilder.java
index 37ae9d2..fc4fd33 100644
--- a/src/main/java/com/android/tools/r8/naming/ComposingBuilder.java
+++ b/src/main/java/com/android/tools/r8/naming/ComposingBuilder.java
@@ -7,6 +7,7 @@
import static com.android.tools.r8.naming.MappedRangeUtils.isInlineMappedRange;
import static com.android.tools.r8.utils.FunctionUtils.ignoreArgument;
+import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.naming.ClassNamingForNameMapper.MappedRange;
import com.android.tools.r8.naming.ClassNamingForNameMapper.MappedRangesOfName;
import com.android.tools.r8.naming.MemberNaming.FieldSignature;
@@ -128,9 +129,8 @@
composingClassBuilder.compose(classNameMapper, classMapping);
}
-
- @Override
- public String toString() {
+ public String finish() {
+ committed.finish();
List<ComposingClassBuilder> classBuilders = new ArrayList<>(committed.classBuilders.values());
classBuilders.sort(Comparator.comparing(ComposingClassBuilder::getOriginalName));
StringBuilder sb = new StringBuilder();
@@ -167,6 +167,12 @@
private final Map<ClassTypeNameAndMethodName, UpdateOutlineCallsiteInformation>
outlineSourcePositionsUpdated = new HashMap<>();
+ /**
+ * Map of signatures that should be removed when finalizing the composed map. The key is the
+ * original name of a class.
+ */
+ private final Map<String, Set<Signature>> signaturesToRemove = new HashMap<>();
+
private final List<String> preamble = new ArrayList<>();
public void commit(ComposingData current, ClassNameMapper classNameMapper)
@@ -175,6 +181,7 @@
commitClassBuilders(current, classNameMapper);
commitRewriteFrameInformation(current, classNameMapper);
commitOutlineCallsiteInformation(current, classNameMapper);
+ commitSignaturesToRemove(current);
}
private void commitClassBuilders(ComposingData current, ClassNameMapper classNameMapper)
@@ -211,6 +218,28 @@
classBuilders = newClassBuilders;
}
+ private void commitSignaturesToRemove(ComposingData current) {
+ current.signaturesToRemove.forEach(
+ (originalName, signatures) -> {
+ signaturesToRemove.merge(
+ originalName,
+ signatures,
+ (signatures1, signatures2) -> {
+ Set<Signature> joinedSignatures = Sets.newHashSet(signatures1);
+ joinedSignatures.addAll(signatures2);
+ return joinedSignatures;
+ });
+ });
+ }
+
+ public void addSignatureToRemove(
+ ComposingClassBuilder composingClassBuilder, Signature signature) {
+ signaturesToRemove
+ .computeIfAbsent(
+ composingClassBuilder.getOriginalName(), ignoreArgument(Sets::newHashSet))
+ .add(signature);
+ }
+
private void commitRewriteFrameInformation(
ComposingData current, ClassNameMapper classNameMapper) {
// First update the existing frame information to have new class name mappings.
@@ -313,6 +342,25 @@
return newTypeName == null ? typeReference : Reference.classFromTypeName(newTypeName);
}
}
+
+ public void finish() {
+ classBuilders.forEach(
+ (ignored, classBuilder) -> {
+ Set<Signature> signatures = signaturesToRemove.get(classBuilder.getOriginalName());
+ if (signatures == null) {
+ return;
+ }
+ signatures.forEach(
+ signature -> {
+ if (signature.isFieldSignature()) {
+ classBuilder.fieldMembers.remove(signature.asFieldSignature());
+ } else {
+ // TODO(b/241763080): Define removal of methods with and without signatures.
+ throw new Unreachable();
+ }
+ });
+ });
+ }
}
private static class ClassTypeNameAndMethodName {
@@ -498,10 +546,13 @@
if (composingClassBuilder == null) {
return null;
}
- return composingClassBuilder.fieldMembers.remove(
- originalSignature.isQualified()
- ? originalSignature.toUnqualifiedSignature()
- : originalSignature);
+ FieldSignature signature =
+ (originalSignature.isQualified()
+ ? originalSignature.toUnqualifiedSignature()
+ : originalSignature)
+ .asFieldSignature();
+ current.addSignatureToRemove(composingClassBuilder, signature);
+ return composingClassBuilder.fieldMembers.get(signature);
}
private void composeMethodNamings(
diff --git a/src/main/java/com/android/tools/r8/naming/MappingComposer.java b/src/main/java/com/android/tools/r8/naming/MappingComposer.java
index 636e699..2068902 100644
--- a/src/main/java/com/android/tools/r8/naming/MappingComposer.java
+++ b/src/main/java/com/android/tools/r8/naming/MappingComposer.java
@@ -23,6 +23,6 @@
for (ClassNameMapper classNameMapper : classNameMappers) {
builder.compose(classNameMapper);
}
- return builder.toString();
+ return builder.finish();
}
}
diff --git a/src/test/java/com/android/tools/r8/mappingcompose/ComposeDuplicateMovedFieldTest.java b/src/test/java/com/android/tools/r8/mappingcompose/ComposeDuplicateMovedFieldTest.java
index d6fad75..355dbf4 100644
--- a/src/test/java/com/android/tools/r8/mappingcompose/ComposeDuplicateMovedFieldTest.java
+++ b/src/test/java/com/android/tools/r8/mappingcompose/ComposeDuplicateMovedFieldTest.java
@@ -47,14 +47,13 @@
" boolean b.g2 -> h2");
private static final String mappingResult =
StringUtils.unixLines(
- // TODO(b/241763080): We should support duplicating fields.
"# {'id':'com.android.tools.r8.mapping','version':'experimental'}",
"com.bar -> c:",
" boolean f2 -> h2",
" int some.other.Class.f1 -> h1",
"com.baz -> d:",
- " int a.g1 -> h1", // This should be int some.other.Class.f1 -> h1
- " boolean b.g2 -> h2", // This should be boolean com.bar.f2 -> h2.
+ " boolean com.bar.f2 -> h2",
+ " int some.other.Class.f1 -> h1",
"com.foo -> a:");
@Test