summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/analysis
diff options
context:
space:
mode:
authorGravatar gegy10002019-02-23 19:42:00 +0200
committerGravatar gegy10002019-02-23 19:42:00 +0200
commitbb20ce047a2e20866b9532c441c7433b1973ba5b (patch)
treeed9f5bd596e43a1fffeef0b174c5370c039a9b62 /src/main/java/cuchaz/enigma/analysis
parentTweak inheritance and implementation tree generation (diff)
downloadenigma-fork-bb20ce047a2e20866b9532c441c7433b1973ba5b.tar.gz
enigma-fork-bb20ce047a2e20866b9532c441c7433b1973ba5b.tar.xz
enigma-fork-bb20ce047a2e20866b9532c441c7433b1973ba5b.zip
Fix #110 and remap indices with matched bridge method names
Diffstat (limited to 'src/main/java/cuchaz/enigma/analysis')
-rw-r--r--src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java30
-rw-r--r--src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java12
-rw-r--r--src/main/java/cuchaz/enigma/analysis/index/JarIndex.java15
-rw-r--r--src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java3
-rw-r--r--src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java47
5 files changed, 78 insertions, 29 deletions
diff --git a/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java b/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java
index de2ba1e..649ce25 100644
--- a/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java
+++ b/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java
@@ -2,7 +2,6 @@ package cuchaz.enigma.analysis.index;
2 2
3import com.google.common.collect.Maps; 3import com.google.common.collect.Maps;
4import com.google.common.collect.Sets; 4import com.google.common.collect.Sets;
5import cuchaz.enigma.translation.mapping.EntryResolver;
6import cuchaz.enigma.translation.representation.AccessFlags; 5import cuchaz.enigma.translation.representation.AccessFlags;
7import cuchaz.enigma.translation.representation.MethodDescriptor; 6import cuchaz.enigma.translation.representation.MethodDescriptor;
8import cuchaz.enigma.translation.representation.TypeDescriptor; 7import cuchaz.enigma.translation.representation.TypeDescriptor;
@@ -11,10 +10,7 @@ import cuchaz.enigma.translation.representation.entry.MethodDefEntry;
11import cuchaz.enigma.translation.representation.entry.MethodEntry; 10import cuchaz.enigma.translation.representation.entry.MethodEntry;
12 11
13import javax.annotation.Nullable; 12import javax.annotation.Nullable;
14import java.util.Collection; 13import java.util.*;
15import java.util.List;
16import java.util.Map;
17import java.util.Set;
18 14
19public class BridgeMethodIndex implements JarIndexer { 15public class BridgeMethodIndex implements JarIndexer {
20 private final EntryIndex entryIndex; 16 private final EntryIndex entryIndex;
@@ -30,8 +26,7 @@ public class BridgeMethodIndex implements JarIndexer {
30 this.referenceIndex = referenceIndex; 26 this.referenceIndex = referenceIndex;
31 } 27 }
32 28
33 @Override 29 public void findBridgeMethods() {
34 public void processIndex(EntryResolver resolver) {
35 // look for access and bridged methods 30 // look for access and bridged methods
36 for (MethodEntry methodEntry : entryIndex.getMethods()) { 31 for (MethodEntry methodEntry : entryIndex.getMethods()) {
37 MethodDefEntry methodDefEntry = (MethodDefEntry) methodEntry; 32 MethodDefEntry methodDefEntry = (MethodDefEntry) methodEntry;
@@ -45,6 +40,23 @@ public class BridgeMethodIndex implements JarIndexer {
45 } 40 }
46 } 41 }
47 42
43 @Override
44 public void processIndex(JarIndex index) {
45 Map<MethodEntry, MethodEntry> copiedAccessToBridge = new HashMap<>(accessedToBridge);
46
47 for (Map.Entry<MethodEntry, MethodEntry> entry : copiedAccessToBridge.entrySet()) {
48 MethodEntry accessedEntry = entry.getKey();
49 MethodEntry bridgeEntry = entry.getValue();
50 if (bridgeEntry.getName().equals(accessedEntry.getName())) {
51 continue;
52 }
53
54 MethodEntry renamedAccessedEntry = accessedEntry.withName(bridgeEntry.getName());
55 bridgeMethods.add(renamedAccessedEntry);
56 accessedToBridge.put(renamedAccessedEntry, accessedToBridge.get(accessedEntry));
57 }
58 }
59
48 private void indexSyntheticMethod(MethodDefEntry syntheticMethod, AccessFlags access) { 60 private void indexSyntheticMethod(MethodDefEntry syntheticMethod, AccessFlags access) {
49 MethodEntry accessedMethod = findAccessMethod(syntheticMethod); 61 MethodEntry accessedMethod = findAccessMethod(syntheticMethod);
50 if (accessedMethod == null) { 62 if (accessedMethod == null) {
@@ -129,4 +141,8 @@ public class BridgeMethodIndex implements JarIndexer {
129 public MethodEntry getBridgeFromAccessed(MethodEntry entry) { 141 public MethodEntry getBridgeFromAccessed(MethodEntry entry) {
130 return accessedToBridge.get(entry); 142 return accessedToBridge.get(entry);
131 } 143 }
144
145 public Map<MethodEntry, MethodEntry> getAccessedToBridge() {
146 return Collections.unmodifiableMap(accessedToBridge);
147 }
132} 148}
diff --git a/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java b/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java
index 773eaf1..645110a 100644
--- a/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java
+++ b/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java
@@ -28,6 +28,18 @@ public class EntryIndex implements JarIndexer {
28 fields.put(fieldEntry, fieldEntry.getAccess()); 28 fields.put(fieldEntry, fieldEntry.getAccess());
29 } 29 }
30 30
31 @Override
32 public void processIndex(JarIndex index) {
33 Map<MethodEntry, MethodEntry> accessedToBridge = index.getBridgeMethodIndex().getAccessedToBridge();
34 for (Map.Entry<MethodEntry, MethodEntry> entry : accessedToBridge.entrySet()) {
35 MethodEntry accessedEntry = entry.getKey();
36 MethodEntry bridgeEntry = entry.getValue();
37
38 MethodEntry renamedAccessedEntry = accessedEntry.withName(bridgeEntry.getName());
39 methods.put(renamedAccessedEntry, methods.remove(accessedEntry));
40 }
41 }
42
31 public boolean hasClass(ClassEntry entry) { 43 public boolean hasClass(ClassEntry entry) {
32 return classes.containsKey(entry); 44 return classes.containsKey(entry);
33 } 45 }
diff --git a/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java b/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java
index cb58fce..a429ff6 100644
--- a/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java
+++ b/src/main/java/cuchaz/enigma/analysis/index/JarIndex.java
@@ -53,19 +53,22 @@ public class JarIndex implements JarIndexer {
53 } 53 }
54 54
55 public void indexJar(ParsedJar jar, Consumer<String> progress) { 55 public void indexJar(ParsedJar jar, Consumer<String> progress) {
56 progress.accept("Indexing entries (1/3)"); 56 progress.accept("Indexing entries (1/4)");
57 jar.visitReader(name -> new IndexClassVisitor(this, Opcodes.ASM5), ClassReader.SKIP_CODE); 57 jar.visitReader(name -> new IndexClassVisitor(this, Opcodes.ASM5), ClassReader.SKIP_CODE);
58 58
59 progress.accept("Indexing entry references (2/3)"); 59 progress.accept("Indexing entry references (2/4)");
60 jar.visitReader(name -> new IndexReferenceVisitor(this, Opcodes.ASM5), ClassReader.SKIP_FRAMES); 60 jar.visitReader(name -> new IndexReferenceVisitor(this, Opcodes.ASM5), ClassReader.SKIP_FRAMES);
61 61
62 progress.accept("Processing index (3/3)"); 62 progress.accept("Finding bridge methods (3/4)");
63 processIndex(entryResolver); 63 bridgeMethodIndex.findBridgeMethods();
64
65 progress.accept("Processing index (4/4)");
66 processIndex(this);
64 } 67 }
65 68
66 @Override 69 @Override
67 public void processIndex(EntryResolver resolver) { 70 public void processIndex(JarIndex index) {
68 indexers.forEach(indexer -> indexer.processIndex(entryResolver)); 71 indexers.forEach(indexer -> indexer.processIndex(index));
69 } 72 }
70 73
71 @Override 74 @Override
diff --git a/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java b/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java
index a087e59..457c223 100644
--- a/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java
+++ b/src/main/java/cuchaz/enigma/analysis/index/JarIndexer.java
@@ -1,6 +1,5 @@
1package cuchaz.enigma.analysis.index; 1package cuchaz.enigma.analysis.index;
2 2
3import cuchaz.enigma.translation.mapping.EntryResolver;
4import cuchaz.enigma.translation.representation.entry.*; 3import cuchaz.enigma.translation.representation.entry.*;
5 4
6public interface JarIndexer { 5public interface JarIndexer {
@@ -19,6 +18,6 @@ public interface JarIndexer {
19 default void indexFieldReference(MethodDefEntry callerEntry, FieldEntry referencedEntry) { 18 default void indexFieldReference(MethodDefEntry callerEntry, FieldEntry referencedEntry) {
20 } 19 }
21 20
22 default void processIndex(EntryResolver resolver) { 21 default void processIndex(JarIndex index) {
23 } 22 }
24} 23}
diff --git a/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java b/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java
index ac11da4..ee28b3e 100644
--- a/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java
+++ b/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java
@@ -3,12 +3,12 @@ package cuchaz.enigma.analysis.index;
3import com.google.common.collect.HashMultimap; 3import com.google.common.collect.HashMultimap;
4import com.google.common.collect.Multimap; 4import com.google.common.collect.Multimap;
5import cuchaz.enigma.analysis.EntryReference; 5import cuchaz.enigma.analysis.EntryReference;
6import cuchaz.enigma.translation.mapping.EntryResolver;
7import cuchaz.enigma.translation.mapping.ResolutionStrategy; 6import cuchaz.enigma.translation.mapping.ResolutionStrategy;
8import cuchaz.enigma.translation.representation.entry.*; 7import cuchaz.enigma.translation.representation.entry.*;
9 8
10import java.util.Collection; 9import java.util.Collection;
11import java.util.Map; 10import java.util.Map;
11import java.util.Optional;
12 12
13public class ReferenceIndex implements JarIndexer { 13public class ReferenceIndex implements JarIndexer {
14 private Multimap<MethodEntry, MethodEntry> methodReferences = HashMultimap.create(); 14 private Multimap<MethodEntry, MethodEntry> methodReferences = HashMultimap.create();
@@ -34,35 +34,54 @@ public class ReferenceIndex implements JarIndexer {
34 } 34 }
35 35
36 @Override 36 @Override
37 public void processIndex(EntryResolver resolver) { 37 public void processIndex(JarIndex index) {
38 methodReferences = resolveReferences(resolver, methodReferences); 38 methodReferences = remapReferences(index, methodReferences);
39 referencesToMethods = resolveReferencesTo(resolver, referencesToMethods); 39 referencesToMethods = remapReferencesTo(index, referencesToMethods);
40 referencesToClasses = resolveReferencesTo(resolver, referencesToClasses); 40 referencesToClasses = remapReferencesTo(index, referencesToClasses);
41 referencesToFields = resolveReferencesTo(resolver, referencesToFields); 41 referencesToFields = remapReferencesTo(index, referencesToFields);
42 } 42 }
43 43
44 private <K extends Entry<?>, V extends Entry<?>> Multimap<K, V> resolveReferences(EntryResolver resolver, Multimap<K, V> multimap) { 44 private <K extends Entry<?>, V extends Entry<?>> Multimap<K, V> remapReferences(JarIndex index, Multimap<K, V> multimap) {
45 Multimap<K, V> resolved = HashMultimap.create(); 45 Multimap<K, V> resolved = HashMultimap.create();
46 for (Map.Entry<K, V> entry : multimap.entries()) { 46 for (Map.Entry<K, V> entry : multimap.entries()) {
47 resolved.put(resolve(resolver, entry.getKey()), resolve(resolver, entry.getValue())); 47 resolved.put(remap(index, entry.getKey()), remap(index, entry.getValue()));
48 } 48 }
49 return resolved; 49 return resolved;
50 } 50 }
51 51
52 private <E extends Entry<?>, C extends Entry<?>> Multimap<E, EntryReference<E, C>> resolveReferencesTo(EntryResolver resolver, Multimap<E, EntryReference<E, C>> multimap) { 52 private <E extends Entry<?>, C extends Entry<?>> Multimap<E, EntryReference<E, C>> remapReferencesTo(JarIndex index, Multimap<E, EntryReference<E, C>> multimap) {
53 Multimap<E, EntryReference<E, C>> resolved = HashMultimap.create(); 53 Multimap<E, EntryReference<E, C>> resolved = HashMultimap.create();
54 for (Map.Entry<E, EntryReference<E, C>> entry : multimap.entries()) { 54 for (Map.Entry<E, EntryReference<E, C>> entry : multimap.entries()) {
55 resolved.put(resolve(resolver, entry.getKey()), resolve(resolver, entry.getValue())); 55 resolved.put(remap(index, entry.getKey()), remap(index, entry.getValue()));
56 } 56 }
57 return resolved; 57 return resolved;
58 } 58 }
59 59
60 private <E extends Entry<?>> E resolve(EntryResolver resolver, E entry) { 60 private <E extends Entry<?>> E remap(JarIndex index, E entry) {
61 return resolver.resolveFirstEntry(entry, ResolutionStrategy.RESOLVE_CLOSEST); 61 E resolvedEntry = index.getEntryResolver().resolveFirstEntry(entry, ResolutionStrategy.RESOLVE_CLOSEST);
62
63 Optional<E> remappedBridge = getRemappedBridge(index, resolvedEntry);
64 return remappedBridge.orElse(resolvedEntry);
65 }
66
67 private <E extends Entry<?>, C extends Entry<?>> EntryReference<E, C> remap(JarIndex index, EntryReference<E, C> reference) {
68 EntryReference<E, C> resolvedReference = index.getEntryResolver().resolveFirstReference(reference, ResolutionStrategy.RESOLVE_CLOSEST);
69
70 getRemappedBridge(index, resolvedReference.entry).ifPresent(e -> resolvedReference.entry = e);
71 getRemappedBridge(index, resolvedReference.context).ifPresent(e -> resolvedReference.context = e);
72
73 return resolvedReference;
62 } 74 }
63 75
64 private <E extends Entry<?>, C extends Entry<?>> EntryReference<E, C> resolve(EntryResolver resolver, EntryReference<E, C> reference) { 76 @SuppressWarnings("unchecked")
65 return resolver.resolveFirstReference(reference, ResolutionStrategy.RESOLVE_CLOSEST); 77 private <E extends Entry<?>> Optional<E> getRemappedBridge(JarIndex index, E entry) {
78 if (entry instanceof MethodEntry) {
79 MethodEntry bridgeEntry = index.getBridgeMethodIndex().getBridgeFromAccessed((MethodEntry) entry);
80 if (bridgeEntry != null) {
81 return Optional.of((E) entry.withName(bridgeEntry.getName()));
82 }
83 }
84 return Optional.empty();
66 } 85 }
67 86
68 public Collection<MethodEntry> getMethodsReferencedBy(MethodEntry entry) { 87 public Collection<MethodEntry> getMethodsReferencedBy(MethodEntry entry) {