Merge "Refactor member pool collection."
diff --git a/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java b/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
index f00787b..bbb3391 100644
--- a/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
+import com.google.common.collect.Sets;
import java.util.Map;
import java.util.function.Function;
@@ -45,11 +46,15 @@
DexType.forAllInterfaces(appInfo.dexItemFactory,
iface -> reserveNamesInSubtypes(iface, globalState));
timing.end();
- // Now rename the rest.
- timing.begin("rename");
+ // Rename the definitions.
+ timing.begin("rename-definitions");
renameFieldsInSubtypes(appInfo.dexItemFactory.objectType);
DexType.forAllInterfaces(appInfo.dexItemFactory, this::renameFieldsInSubtypes);
timing.end();
+ // Rename the references that are not rebound to definitions for some reasons.
+ timing.begin("rename-references");
+ renameNonReboundReferences();
+ timing.end();
return renaming;
}
@@ -92,4 +97,44 @@
state.assignNewNameFor(field.name, field.type, useUniqueMemberNames));
}
}
+
+ private void renameNonReboundReferences() {
+ // TODO(b/123068484): Collect non-rebound references instead of visiting all references.
+ Sets.union(
+ Sets.union(appInfo.staticFieldReads.keySet(), appInfo.staticFieldWrites.keySet()),
+ Sets.union(appInfo.instanceFieldReads.keySet(), appInfo.instanceFieldWrites.keySet()))
+ .forEach(this::renameNonReboundReference);
+ }
+
+ private void renameNonReboundReference(DexField field) {
+ // Already renamed
+ if (renaming.containsKey(field)) {
+ return;
+ }
+ DexEncodedField definition = appInfo.definitionFor(field);
+ if (definition != null) {
+ assert definition.field == field;
+ return;
+ }
+ // Now, `field` is reference. Find its definition and check if it's renamed.
+ DexType holderType = field.getHolder();
+ DexClass holder = appInfo.definitionFor(holderType);
+ // We don't care pruned types or library classes.
+ if (holder == null || holder.isLibraryClass()) {
+ return;
+ }
+ definition = appInfo.resolveFieldOn(holderType, field);
+ if (definition == null) {
+ // The program is already broken in the sense that it has an unresolvable field reference.
+ // Leave it as-is.
+ return;
+ }
+ assert definition.field != field;
+ assert definition.field.getHolder() != holderType;
+ // If the definition is renamed,
+ if (renaming.containsKey(definition.field)) {
+ // Assign the same, renamed name as the definition to the reference.
+ renaming.put(field, renaming.get(definition.field));
+ }
+ }
}
diff --git a/src/test/java/com/android/tools/r8/naming/b123068484/FieldRenamingTest.java b/src/test/java/com/android/tools/r8/naming/b123068484/FieldRenamingTest.java
index d0aef41..119cb98 100644
--- a/src/test/java/com/android/tools/r8/naming/b123068484/FieldRenamingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/b123068484/FieldRenamingTest.java
@@ -20,7 +20,6 @@
import java.util.LinkedList;
import java.util.List;
import org.junit.BeforeClass;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -63,7 +62,6 @@
.assertSuccessWithOutput(EXPECTED_OUTPUT);
}
- @Ignore("b/123068484")
@Test
public void testR8() throws Exception {
testForR8(backend)