summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java
diff options
context:
space:
mode:
authorGravatar gegy10002018-05-19 17:02:46 +0200
committerGravatar gegy10002018-05-19 17:02:46 +0200
commit2b2249e873c4adfd2dd6e8f1f2489ccd9f6aa021 (patch)
tree14c8b1e806449ace1641a1dbafae162855f79670 /src/main/java/cuchaz/enigma/analysis/TranslationIndex.java
parentFix build (diff)
downloadenigma-fork-2b2249e873c4adfd2dd6e8f1f2489ccd9f6aa021.tar.gz
enigma-fork-2b2249e873c4adfd2dd6e8f1f2489ccd9f6aa021.tar.xz
enigma-fork-2b2249e873c4adfd2dd6e8f1f2489ccd9f6aa021.zip
Initial port to ASM
Diffstat (limited to 'src/main/java/cuchaz/enigma/analysis/TranslationIndex.java')
-rw-r--r--src/main/java/cuchaz/enigma/analysis/TranslationIndex.java123
1 files changed, 58 insertions, 65 deletions
diff --git a/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java b/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java
index 26be05b..3cd80ff 100644
--- a/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java
+++ b/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java
@@ -15,11 +15,8 @@ import com.google.common.collect.HashMultimap;
15import com.google.common.collect.Lists; 15import com.google.common.collect.Lists;
16import com.google.common.collect.Maps; 16import com.google.common.collect.Maps;
17import com.google.common.collect.Multimap; 17import com.google.common.collect.Multimap;
18import cuchaz.enigma.bytecode.AccessFlags;
18import cuchaz.enigma.mapping.*; 19import cuchaz.enigma.mapping.*;
19import javassist.CtBehavior;
20import javassist.CtClass;
21import javassist.CtField;
22import javassist.bytecode.Descriptor;
23 20
24import java.util.Collection; 21import java.util.Collection;
25import java.util.List; 22import java.util.List;
@@ -28,96 +25,91 @@ import java.util.Set;
28 25
29public class TranslationIndex { 26public class TranslationIndex {
30 27
28 private final ReferencedEntryPool entryPool;
31 private Map<ClassEntry, ClassEntry> superclasses; 29 private Map<ClassEntry, ClassEntry> superclasses;
32 private Multimap<ClassEntry, FieldEntry> fieldEntries; 30 private Multimap<ClassEntry, FieldDefEntry> fieldEntries;
33 private Multimap<ClassEntry, BehaviorEntry> behaviorEntries; 31 private Multimap<ClassEntry, MethodDefEntry> methodEntries;
34 private Multimap<ClassEntry, ClassEntry> interfaces; 32 private Multimap<ClassEntry, ClassEntry> interfaces;
35 33
36 public TranslationIndex() { 34 public TranslationIndex(ReferencedEntryPool entryPool) {
35 this.entryPool = entryPool;
37 this.superclasses = Maps.newHashMap(); 36 this.superclasses = Maps.newHashMap();
38 this.fieldEntries = HashMultimap.create(); 37 this.fieldEntries = HashMultimap.create();
39 this.behaviorEntries = HashMultimap.create(); 38 this.methodEntries = HashMultimap.create();
40 this.interfaces = HashMultimap.create(); 39 this.interfaces = HashMultimap.create();
41 } 40 }
42 41
43 public TranslationIndex(TranslationIndex other, Translator translator) { 42 public TranslationIndex(TranslationIndex other, Translator translator) {
43 this.entryPool = other.entryPool;
44
44 // translate the superclasses 45 // translate the superclasses
45 this.superclasses = Maps.newHashMap(); 46 this.superclasses = Maps.newHashMap();
46 for (Map.Entry<ClassEntry, ClassEntry> mapEntry : other.superclasses.entrySet()) { 47 for (Map.Entry<ClassEntry, ClassEntry> mapEntry : other.superclasses.entrySet()) {
47 this.superclasses.put(translator.translateEntry(mapEntry.getKey()), translator.translateEntry(mapEntry.getValue())); 48 this.superclasses.put(translator.getTranslatedClass(mapEntry.getKey()), translator.getTranslatedClass(mapEntry.getValue()));
48 } 49 }
49 50
50 // translate the interfaces 51 // translate the interfaces
51 this.interfaces = HashMultimap.create(); 52 this.interfaces = HashMultimap.create();
52 for (Map.Entry<ClassEntry, ClassEntry> mapEntry : other.interfaces.entries()) { 53 for (Map.Entry<ClassEntry, ClassEntry> mapEntry : other.interfaces.entries()) {
53 this.interfaces.put( 54 this.interfaces.put(
54 translator.translateEntry(mapEntry.getKey()), 55 translator.getTranslatedClass(mapEntry.getKey()),
55 translator.translateEntry(mapEntry.getValue()) 56 translator.getTranslatedClass(mapEntry.getValue())
56 ); 57 );
57 } 58 }
58 59
59 // translate the fields 60 // translate the fields
60 this.fieldEntries = HashMultimap.create(); 61 this.fieldEntries = HashMultimap.create();
61 for (Map.Entry<ClassEntry, FieldEntry> mapEntry : other.fieldEntries.entries()) { 62 for (Map.Entry<ClassEntry, FieldDefEntry> mapEntry : other.fieldEntries.entries()) {
62 this.fieldEntries.put( 63 this.fieldEntries.put(
63 translator.translateEntry(mapEntry.getKey()), 64 translator.getTranslatedClass(mapEntry.getKey()),
64 translator.translateEntry(mapEntry.getValue()) 65 translator.getTranslatedFieldDef(mapEntry.getValue())
65 ); 66 );
66 } 67 }
67 68
68 this.behaviorEntries = HashMultimap.create(); 69 this.methodEntries = HashMultimap.create();
69 for (Map.Entry<ClassEntry, BehaviorEntry> mapEntry : other.behaviorEntries.entries()) { 70 for (Map.Entry<ClassEntry, MethodDefEntry> mapEntry : other.methodEntries.entries()) {
70 this.behaviorEntries.put( 71 this.methodEntries.put(
71 translator.translateEntry(mapEntry.getKey()), 72 translator.getTranslatedClass(mapEntry.getKey()),
72 translator.translateEntry(mapEntry.getValue()) 73 translator.getTranslatedMethodDef(mapEntry.getValue())
73 ); 74 );
74 } 75 }
75 } 76 }
76 77
77 public void indexClass(CtClass c) { 78 protected ClassDefEntry indexClass(int access, String name, String superName, String[] interfaces) {
78 indexClass(c, true); 79 ClassDefEntry classEntry = new ClassDefEntry(name, new AccessFlags(access));
79 }
80
81 public void indexClass(CtClass c, boolean indexMembers) {
82 ClassEntry classEntry = EntryFactory.getClassEntry(c);
83 if (isJre(classEntry)) { 80 if (isJre(classEntry)) {
84 return; 81 return null;
85 } 82 }
86 83
87 // add the superclass 84 // add the superclass
88 ClassEntry superclassEntry = EntryFactory.getSuperclassEntry(c); 85 ClassEntry superclassEntry = entryPool.getClass(superName);
89 if (superclassEntry != null) { 86 if (!isJre(superclassEntry)) {
90 this.superclasses.put(classEntry, superclassEntry); 87 this.superclasses.put(classEntry, superclassEntry);
91 } 88 }
92 89
93 // add the interfaces 90 // add the interfaces
94 for (String interfaceClassName : c.getClassFile().getInterfaces()) { 91 for (String interfaceClassName : interfaces) {
95 ClassEntry interfaceClassEntry = new ClassEntry(Descriptor.toJvmName(interfaceClassName)); 92 ClassEntry interfaceClassEntry = entryPool.getClass(interfaceClassName);
96 if (!isJre(interfaceClassEntry)) { 93 if (!isJre(interfaceClassEntry)) {
97
98 this.interfaces.put(classEntry, interfaceClassEntry); 94 this.interfaces.put(classEntry, interfaceClassEntry);
99 } 95 }
100 } 96 }
101 97
102 if (indexMembers) { 98 return classEntry;
103 // add fields 99 }
104 for (CtField field : c.getDeclaredFields()) {
105 FieldEntry fieldEntry = EntryFactory.getFieldEntry(field);
106 this.fieldEntries.put(fieldEntry.getClassEntry(), fieldEntry);
107 }
108 100
109 // add behaviors 101 protected void indexField(FieldDefEntry fieldEntry) {
110 for (CtBehavior behavior : c.getDeclaredBehaviors()) { 102 this.fieldEntries.put(fieldEntry.getOwnerClassEntry(), fieldEntry);
111 BehaviorEntry behaviorEntry = EntryFactory.getBehaviorEntry(behavior); 103 }
112 this.behaviorEntries.put(behaviorEntry.getClassEntry(), behaviorEntry); 104
113 } 105 protected void indexMethod(MethodDefEntry methodEntry) {
114 } 106 this.methodEntries.put(methodEntry.getOwnerClassEntry(), methodEntry);
115 } 107 }
116 108
117 public void renameClasses(Map<String, String> renames) { 109 public void renameClasses(Map<String, String> renames) {
118 EntryRenamer.renameClassesInMap(renames, this.superclasses); 110 EntryRenamer.renameClassesInMap(renames, this.superclasses);
119 EntryRenamer.renameClassesInMultimap(renames, this.fieldEntries); 111 EntryRenamer.renameClassesInMultimap(renames, this.fieldEntries);
120 EntryRenamer.renameClassesInMultimap(renames, this.behaviorEntries); 112 EntryRenamer.renameClassesInMultimap(renames, this.methodEntries);
121 } 113 }
122 114
123 public ClassEntry getSuperclass(ClassEntry classEntry) { 115 public ClassEntry getSuperclass(ClassEntry classEntry) {
@@ -175,31 +167,32 @@ public class TranslationIndex {
175 } 167 }
176 168
177 public boolean entryExists(Entry entry) { 169 public boolean entryExists(Entry entry) {
170 if (entry == null) {
171 return false;
172 }
178 if (entry instanceof FieldEntry) { 173 if (entry instanceof FieldEntry) {
179 return fieldExists((FieldEntry) entry); 174 return fieldExists((FieldEntry) entry);
180 } else if (entry instanceof BehaviorEntry) { 175 } else if (entry instanceof MethodEntry) {
181 return behaviorExists((BehaviorEntry) entry); 176 return methodExists((MethodEntry) entry);
182 } else if (entry instanceof ArgumentEntry) {
183 return behaviorExists(((ArgumentEntry) entry).getBehaviorEntry());
184 } else if (entry instanceof LocalVariableEntry) { 177 } else if (entry instanceof LocalVariableEntry) {
185 return behaviorExists(((LocalVariableEntry) entry).getBehaviorEntry()); 178 return methodExists(((LocalVariableEntry) entry).getOwnerEntry());
186 } 179 }
187 throw new IllegalArgumentException("Cannot check existence for " + entry.getClass()); 180 throw new IllegalArgumentException("Cannot check existence for " + entry.getClass());
188 } 181 }
189 182
190 public boolean fieldExists(FieldEntry fieldEntry) { 183 public boolean fieldExists(FieldEntry fieldEntry) {
191 return this.fieldEntries.containsEntry(fieldEntry.getClassEntry(), fieldEntry); 184 return this.fieldEntries.containsEntry(fieldEntry.getOwnerClassEntry(), fieldEntry);
192 } 185 }
193 186
194 public boolean behaviorExists(BehaviorEntry behaviorEntry) { 187 public boolean methodExists(MethodEntry methodEntry) {
195 return this.behaviorEntries.containsEntry(behaviorEntry.getClassEntry(), behaviorEntry); 188 return this.methodEntries.containsEntry(methodEntry.getOwnerClassEntry(), methodEntry);
196 } 189 }
197 190
198 public ClassEntry resolveEntryClass(Entry entry) { 191 public ClassEntry resolveEntryOwner(Entry entry) {
199 return resolveEntryClass(entry, false); 192 return resolveEntryOwner(entry, false);
200 } 193 }
201 194
202 public ClassEntry resolveEntryClass(Entry entry, boolean checkSuperclassBeforeChild) { 195 public ClassEntry resolveEntryOwner(Entry entry, boolean checkSuperclassBeforeChild) {
203 if (entry instanceof ClassEntry) { 196 if (entry instanceof ClassEntry) {
204 return (ClassEntry) entry; 197 return (ClassEntry) entry;
205 } 198 }
@@ -227,12 +220,12 @@ public class TranslationIndex {
227 Entry originalEntry = entry; 220 Entry originalEntry = entry;
228 221
229 // Get all possible superclasses and reverse the list 222 // Get all possible superclasses and reverse the list
230 List<ClassEntry> superclasses = Lists.reverse(getAncestry(originalEntry.getClassEntry())); 223 List<ClassEntry> superclasses = Lists.reverse(getAncestry(originalEntry.getOwnerClassEntry()));
231 224
232 boolean existInEntry = false; 225 boolean existInEntry = false;
233 226
234 for (ClassEntry classEntry : superclasses) { 227 for (ClassEntry classEntry : superclasses) {
235 entry = entry.cloneToNewClass(classEntry); 228 entry = entry.updateOwnership(classEntry);
236 existInEntry = entryExists(entry); 229 existInEntry = entryExists(entry);
237 230
238 // Check for possible entry in interfaces of superclasses 231 // Check for possible entry in interfaces of superclasses
@@ -245,9 +238,9 @@ public class TranslationIndex {
245 238
246 // Doesn't exists in superclasses? check the child or return null 239 // Doesn't exists in superclasses? check the child or return null
247 if (!existInEntry) 240 if (!existInEntry)
248 return !entryExists(originalEntry) ? null : originalEntry.getClassEntry(); 241 return !entryExists(originalEntry) ? null : originalEntry.getOwnerClassEntry();
249 242
250 return entry.getClassEntry(); 243 return entry.getOwnerClassEntry();
251 } 244 }
252 245
253 public ClassEntry resolveSuperclass(Entry entry) { 246 public ClassEntry resolveSuperclass(Entry entry) {
@@ -256,7 +249,7 @@ public class TranslationIndex {
256 249
257 while (!entryExists(entry)) { 250 while (!entryExists(entry)) {
258 // is there a parent class? 251 // is there a parent class?
259 ClassEntry superclassEntry = getSuperclass(entry.getClassEntry()); 252 ClassEntry superclassEntry = getSuperclass(entry.getOwnerClassEntry());
260 if (superclassEntry == null) { 253 if (superclassEntry == null) {
261 // this is probably a method from a class in a library 254 // this is probably a method from a class in a library
262 // we can't trace the implementation up any higher unless we index the library 255 // we can't trace the implementation up any higher unless we index the library
@@ -264,23 +257,23 @@ public class TranslationIndex {
264 } 257 }
265 258
266 // move up to the parent class 259 // move up to the parent class
267 entry = entry.cloneToNewClass(superclassEntry); 260 entry = entry.updateOwnership(superclassEntry);
268 } 261 }
269 return entry.getClassEntry(); 262 return entry.getOwnerClassEntry();
270 } 263 }
271 264
272 public ClassEntry resolveInterface(Entry entry) { 265 public ClassEntry resolveInterface(Entry entry) {
273 // the interfaces for any class is a forest 266 // the interfaces for any class is a forest
274 // so let's look at all the trees 267 // so let's look at all the trees
275 268
276 for (ClassEntry interfaceEntry : this.interfaces.get(entry.getClassEntry())) { 269 for (ClassEntry interfaceEntry : this.interfaces.get(entry.getOwnerClassEntry())) {
277 Collection<ClassEntry> subInterface = this.interfaces.get(interfaceEntry); 270 Collection<ClassEntry> subInterface = this.interfaces.get(interfaceEntry);
278 if (subInterface != null && !subInterface.isEmpty()) { 271 if (subInterface != null && !subInterface.isEmpty()) {
279 ClassEntry result = resolveInterface(entry.cloneToNewClass(interfaceEntry)); 272 ClassEntry result = resolveInterface(entry.updateOwnership(interfaceEntry));
280 if (result != null) 273 if (result != null)
281 return result; 274 return result;
282 } 275 }
283 ClassEntry resolvedClassEntry = resolveSuperclass(entry.cloneToNewClass(interfaceEntry)); 276 ClassEntry resolvedClassEntry = resolveSuperclass(entry.updateOwnership(interfaceEntry));
284 if (resolvedClassEntry != null) { 277 if (resolvedClassEntry != null) {
285 return resolvedClassEntry; 278 return resolvedClassEntry;
286 } 279 }