summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/convert/MappingsConverter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cuchaz/enigma/convert/MappingsConverter.java')
-rw-r--r--src/cuchaz/enigma/convert/MappingsConverter.java125
1 files changed, 76 insertions, 49 deletions
diff --git a/src/cuchaz/enigma/convert/MappingsConverter.java b/src/cuchaz/enigma/convert/MappingsConverter.java
index 59f3b5b..ddd3a53 100644
--- a/src/cuchaz/enigma/convert/MappingsConverter.java
+++ b/src/cuchaz/enigma/convert/MappingsConverter.java
@@ -183,7 +183,7 @@ public class MappingsConverter {
183 return newMappings; 183 return newMappings;
184 } 184 }
185 185
186 private static ClassMapping migrateClassMapping(ClassEntry newObfClass, ClassMapping mapping, final ClassMatches matches, boolean useSimpleName) { 186 private static ClassMapping migrateClassMapping(ClassEntry newObfClass, ClassMapping oldClassMapping, final ClassMatches matches, boolean useSimpleName) {
187 187
188 ClassNameReplacer replacer = new ClassNameReplacer() { 188 ClassNameReplacer replacer = new ClassNameReplacer() {
189 @Override 189 @Override
@@ -196,30 +196,28 @@ public class MappingsConverter {
196 } 196 }
197 }; 197 };
198 198
199 ClassMapping newMapping; 199 ClassMapping newClassMapping;
200 String deobfName = mapping.getDeobfName(); 200 String deobfName = oldClassMapping.getDeobfName();
201 if (deobfName != null) { 201 if (deobfName != null) {
202 if (useSimpleName) { 202 if (useSimpleName) {
203 deobfName = new ClassEntry(deobfName).getSimpleName(); 203 deobfName = new ClassEntry(deobfName).getSimpleName();
204 } 204 }
205 newMapping = new ClassMapping(newObfClass.getName(), deobfName); 205 newClassMapping = new ClassMapping(newObfClass.getName(), deobfName);
206 } else { 206 } else {
207 newMapping = new ClassMapping(newObfClass.getName()); 207 newClassMapping = new ClassMapping(newObfClass.getName());
208 } 208 }
209 209
210 // copy fields 210 // copy fields
211 for (FieldMapping fieldMapping : mapping.fields()) { 211 for (FieldMapping fieldMapping : oldClassMapping.fields()) {
212 // TODO: map field obf names too... 212 newClassMapping.addFieldMapping(new FieldMapping(fieldMapping, replacer));
213 newMapping.addFieldMapping(new FieldMapping(fieldMapping, replacer));
214 } 213 }
215 214
216 // copy methods 215 // copy methods
217 for (MethodMapping methodMapping : mapping.methods()) { 216 for (MethodMapping methodMapping : oldClassMapping.methods()) {
218 // TODO: map method obf names too... 217 newClassMapping.addMethodMapping(new MethodMapping(methodMapping, replacer));
219 newMapping.addMethodMapping(new MethodMapping(methodMapping, replacer));
220 } 218 }
221 219
222 return newMapping; 220 return newClassMapping;
223 } 221 }
224 222
225 public static void convertMappings(Mappings mappings, BiMap<ClassEntry,ClassEntry> changes) { 223 public static void convertMappings(Mappings mappings, BiMap<ClassEntry,ClassEntry> changes) {
@@ -262,8 +260,9 @@ public class MappingsConverter {
262 Collection<T> getObfEntries(JarIndex jarIndex); 260 Collection<T> getObfEntries(JarIndex jarIndex);
263 Collection<? extends MemberMapping<T>> getMappings(ClassMapping destClassMapping); 261 Collection<? extends MemberMapping<T>> getMappings(ClassMapping destClassMapping);
264 Set<T> filterEntries(Collection<T> obfEntries, T obfSourceEntry, ClassMatches classMatches); 262 Set<T> filterEntries(Collection<T> obfEntries, T obfSourceEntry, ClassMatches classMatches);
265 void setMemberObfName(ClassMapping classMapping, MemberMapping<T> memberMapping, String newObfName); 263 void setUpdateObfMember(ClassMapping classMapping, MemberMapping<T> memberMapping, T newEntry);
266 boolean hasObfMember(ClassMapping classMapping, T obfEntry); 264 boolean hasObfMember(ClassMapping classMapping, T obfEntry);
265 void removeMemberByObf(ClassMapping classMapping, T obfEntry);
267 } 266 }
268 267
269 public static Doer<FieldEntry> getFieldDoer() { 268 public static Doer<FieldEntry> getFieldDoer() {
@@ -297,15 +296,20 @@ public class MappingsConverter {
297 } 296 }
298 297
299 @Override 298 @Override
300 public void setMemberObfName(ClassMapping classMapping, MemberMapping<FieldEntry> memberMapping, String newObfName) { 299 public void setUpdateObfMember(ClassMapping classMapping, MemberMapping<FieldEntry> memberMapping, FieldEntry newField) {
301 FieldMapping fieldMapping = (FieldMapping)memberMapping; 300 FieldMapping fieldMapping = (FieldMapping)memberMapping;
302 classMapping.setFieldObfName(fieldMapping.getObfName(), fieldMapping.getObfType(), newObfName); 301 classMapping.setFieldObfNameAndType(fieldMapping.getObfName(), fieldMapping.getObfType(), newField.getName(), newField.getType());
303 } 302 }
304 303
305 @Override 304 @Override
306 public boolean hasObfMember(ClassMapping classMapping, FieldEntry obfField) { 305 public boolean hasObfMember(ClassMapping classMapping, FieldEntry obfField) {
307 return classMapping.getFieldByObf(obfField.getName(), obfField.getType()) != null; 306 return classMapping.getFieldByObf(obfField.getName(), obfField.getType()) != null;
308 } 307 }
308
309 @Override
310 public void removeMemberByObf(ClassMapping classMapping, FieldEntry obfField) {
311 classMapping.removeFieldMapping(classMapping.getFieldByObf(obfField.getName(), obfField.getType()));
312 }
309 }; 313 };
310 } 314 }
311 315
@@ -344,15 +348,20 @@ public class MappingsConverter {
344 } 348 }
345 349
346 @Override 350 @Override
347 public void setMemberObfName(ClassMapping classMapping, MemberMapping<BehaviorEntry> memberMapping, String newObfName) { 351 public void setUpdateObfMember(ClassMapping classMapping, MemberMapping<BehaviorEntry> memberMapping, BehaviorEntry newBehavior) {
348 MethodMapping methodMapping = (MethodMapping)memberMapping; 352 MethodMapping methodMapping = (MethodMapping)memberMapping;
349 classMapping.setMethodObfName(methodMapping.getObfName(), methodMapping.getObfSignature(), newObfName); 353 classMapping.setMethodObfNameAndSignature(methodMapping.getObfName(), methodMapping.getObfSignature(), newBehavior.getName(), newBehavior.getSignature());
350 } 354 }
351 355
352 @Override 356 @Override
353 public boolean hasObfMember(ClassMapping classMapping, BehaviorEntry obfBehavior) { 357 public boolean hasObfMember(ClassMapping classMapping, BehaviorEntry obfBehavior) {
354 return classMapping.getMethodByObf(obfBehavior.getName(), obfBehavior.getSignature()) != null; 358 return classMapping.getMethodByObf(obfBehavior.getName(), obfBehavior.getSignature()) != null;
355 } 359 }
360
361 @Override
362 public void removeMemberByObf(ClassMapping classMapping, BehaviorEntry obfBehavior) {
363 classMapping.removeMethodMapping(classMapping.getMethodByObf(obfBehavior.getName(), obfBehavior.getSignature()));
364 }
356 }; 365 };
357 } 366 }
358 367
@@ -477,56 +486,74 @@ public class MappingsConverter {
477 }); 486 });
478 } 487 }
479 488
480 public static <T extends Entry> void applyMemberMatches(Mappings mappings, MemberMatches<T> memberMatches, Doer<T> doer) { 489 public static <T extends Entry> void applyMemberMatches(Mappings mappings, ClassMatches classMatches, MemberMatches<T> memberMatches, Doer<T> doer) {
481 for (ClassMapping classMapping : mappings.classes()) { 490 for (ClassMapping classMapping : mappings.classes()) {
482 applyMemberMatches(classMapping, memberMatches, doer); 491 applyMemberMatches(classMapping, classMatches, memberMatches, doer);
483 } 492 }
484 } 493 }
485 494
486 private static <T extends Entry> void applyMemberMatches(ClassMapping classMapping, MemberMatches<T> memberMatches, Doer<T> doer) { 495 private static <T extends Entry> void applyMemberMatches(ClassMapping classMapping, ClassMatches classMatches, MemberMatches<T> memberMatches, Doer<T> doer) {
487 ClassEntry classEntry = classMapping.getObfEntry(); 496
497 // get the classes
498 ClassEntry obfDestClass = classMapping.getObfEntry();
488 499
489 // make a map of all the renames we need to make 500 // make a map of all the renames we need to make
490 Map<T,T> renames = Maps.newHashMap(); 501 Map<T,T> renames = Maps.newHashMap();
491 for (MemberMapping<T> memberMapping : Lists.newArrayList(doer.getMappings(classMapping))) { 502 for (MemberMapping<T> memberMapping : Lists.newArrayList(doer.getMappings(classMapping))) {
492 T obfSourceEntry = memberMapping.getObfEntry(classEntry); 503 T obfOldDestEntry = memberMapping.getObfEntry(obfDestClass);
493 T obfDestEntry = memberMatches.matches().get(obfSourceEntry); 504 T obfSourceEntry = getSourceEntryFromDestMapping(memberMapping, obfDestClass, classMatches);
494 if (obfDestEntry != null) { 505
495 if (obfDestEntry.getName().equals(obfSourceEntry.getName())) { 506 // but drop the unmatchable things
496 // same name, don't need to change anything 507 if (memberMatches.isUnmatchableSourceEntry(obfSourceEntry)) {
497 continue; 508 doer.removeMemberByObf(classMapping, obfOldDestEntry);
498 } 509 continue;
499 renames.put(obfSourceEntry, obfDestEntry); 510 }
511
512 T obfNewDestEntry = memberMatches.matches().get(obfSourceEntry);
513 if (obfNewDestEntry != null && !obfOldDestEntry.getName().equals(obfNewDestEntry.getName())) {
514 renames.put(obfOldDestEntry, obfNewDestEntry);
500 } 515 }
501 } 516 }
502 517
503 // apply to this class (should never need more than n passes) 518 if (!renames.isEmpty()) {
504 int numRenames = renames.size(); 519
505 for (int i=0; i<numRenames && !renames.isEmpty(); i++) { 520 // apply to this class (should never need more than n passes)
506 for (MemberMapping<T> memberMapping : Lists.newArrayList(doer.getMappings(classMapping))) { 521 int numRenamesAppliedThisRound;
507 T obfSourceEntry = memberMapping.getObfEntry(classEntry); 522 do {
508 T obfDestEntry = renames.get(obfSourceEntry); 523 numRenamesAppliedThisRound = 0;
509 if (obfDestEntry != null) { 524
510 // make sure this rename won't cause a collision 525 for (MemberMapping<T> memberMapping : Lists.newArrayList(doer.getMappings(classMapping))) {
511 if (!doer.hasObfMember(classMapping, obfDestEntry)) { 526 T obfOldDestEntry = memberMapping.getObfEntry(obfDestClass);
512 doer.setMemberObfName(classMapping, memberMapping, obfDestEntry.getName()); 527 T obfNewDestEntry = renames.get(obfOldDestEntry);
513 renames.remove(obfSourceEntry); 528 if (obfNewDestEntry != null) {
529 // make sure this rename won't cause a collision
530 // otherwise, save it for the next round and try again next time
531 if (!doer.hasObfMember(classMapping, obfNewDestEntry)) {
532 doer.setUpdateObfMember(classMapping, memberMapping, obfNewDestEntry);
533 renames.remove(obfOldDestEntry);
534 numRenamesAppliedThisRound++;
535 }
514 } 536 }
515 } 537 }
516 } 538 } while(numRenamesAppliedThisRound > 0);
517 } 539
518 if (!renames.isEmpty()) { 540 if (!renames.isEmpty()) {
519 System.err.println(String.format("WARNING: Couldn't apply all the renames for class %s. %d/%d renames left.", 541 System.err.println(String.format("WARNING: Couldn't apply all the renames for class %s. %d renames left.",
520 classMapping.getObfFullName(), renames.size(), numRenames 542 classMapping.getObfFullName(), renames.size()
521 )); 543 ));
522 for (Map.Entry<T,T> entry : renames.entrySet()) { 544 for (Map.Entry<T,T> entry : renames.entrySet()) {
523 System.err.println(String.format("\t%s -> %s", entry.getKey(), entry.getValue())); 545 System.err.println(String.format("\t%s -> %s", entry.getKey().getName(), entry.getValue().getName()));
546 }
524 } 547 }
525 } 548 }
526 549
527 // recurse 550 // recurse
528 for (ClassMapping innerClassMapping : classMapping.innerClasses()) { 551 for (ClassMapping innerClassMapping : classMapping.innerClasses()) {
529 applyMemberMatches(innerClassMapping, memberMatches, doer); 552 applyMemberMatches(innerClassMapping, classMatches, memberMatches, doer);
530 } 553 }
531 } 554 }
555
556 private static <T extends Entry> T getSourceEntryFromDestMapping(MemberMapping<T> destMemberMapping, ClassEntry obfDestClass, ClassMatches classMatches) {
557 return translate(destMemberMapping.getObfEntry(obfDestClass), classMatches.getUniqueMatches().inverse());
558 }
532} 559}