summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar jeff2015-03-15 00:44:35 -0400
committerGravatar jeff2015-03-15 00:44:35 -0400
commit294e97d7e4cda6cadb62918fd822e7d0d11f16a9 (patch)
treee90ba16c26d4a98b6d89f4fdc470c1da711683eb
parentcomplete mappings converion code. Still need to debug though (diff)
downloadenigma-294e97d7e4cda6cadb62918fd822e7d0d11f16a9.tar.gz
enigma-294e97d7e4cda6cadb62918fd822e7d0d11f16a9.tar.xz
enigma-294e97d7e4cda6cadb62918fd822e7d0d11f16a9.zip
fix bugs in the mappings converter
-rw-r--r--src/cuchaz/enigma/ConvertMain.java27
-rw-r--r--src/cuchaz/enigma/convert/MappingsConverter.java125
-rw-r--r--src/cuchaz/enigma/convert/MemberMatches.java4
-rw-r--r--src/cuchaz/enigma/mapping/ClassMapping.java10
-rw-r--r--src/cuchaz/enigma/mapping/FieldMapping.java5
-rw-r--r--src/cuchaz/enigma/mapping/MemberMapping.java1
-rw-r--r--src/cuchaz/enigma/mapping/MethodMapping.java5
7 files changed, 121 insertions, 56 deletions
diff --git a/src/cuchaz/enigma/ConvertMain.java b/src/cuchaz/enigma/ConvertMain.java
index c5c92bcb..79caae44 100644
--- a/src/cuchaz/enigma/ConvertMain.java
+++ b/src/cuchaz/enigma/ConvertMain.java
@@ -14,12 +14,16 @@ import cuchaz.enigma.convert.MemberMatches;
14import cuchaz.enigma.gui.ClassMatchingGui; 14import cuchaz.enigma.gui.ClassMatchingGui;
15import cuchaz.enigma.gui.MemberMatchingGui; 15import cuchaz.enigma.gui.MemberMatchingGui;
16import cuchaz.enigma.mapping.BehaviorEntry; 16import cuchaz.enigma.mapping.BehaviorEntry;
17import cuchaz.enigma.mapping.ClassEntry;
18import cuchaz.enigma.mapping.ClassMapping;
17import cuchaz.enigma.mapping.FieldEntry; 19import cuchaz.enigma.mapping.FieldEntry;
20import cuchaz.enigma.mapping.FieldMapping;
18import cuchaz.enigma.mapping.MappingParseException; 21import cuchaz.enigma.mapping.MappingParseException;
19import cuchaz.enigma.mapping.Mappings; 22import cuchaz.enigma.mapping.Mappings;
20import cuchaz.enigma.mapping.MappingsChecker; 23import cuchaz.enigma.mapping.MappingsChecker;
21import cuchaz.enigma.mapping.MappingsReader; 24import cuchaz.enigma.mapping.MappingsReader;
22import cuchaz.enigma.mapping.MappingsWriter; 25import cuchaz.enigma.mapping.MappingsWriter;
26import cuchaz.enigma.mapping.MethodMapping;
23 27
24 28
25public class ConvertMain { 29public class ConvertMain {
@@ -158,7 +162,7 @@ public class ConvertMain {
158 162
159 // apply matches 163 // apply matches
160 Mappings newMappings = MappingsConverter.newMappings(classMatches, mappings, deobfuscators.source, deobfuscators.dest); 164 Mappings newMappings = MappingsConverter.newMappings(classMatches, mappings, deobfuscators.source, deobfuscators.dest);
161 MappingsConverter.applyMemberMatches(newMappings, fieldMatches, MappingsConverter.getFieldDoer()); 165 MappingsConverter.applyMemberMatches(newMappings, classMatches, fieldMatches, MappingsConverter.getFieldDoer());
162 166
163 // write out the converted mappings 167 // write out the converted mappings
164 try (FileWriter out = new FileWriter(outMappingsFile)) { 168 try (FileWriter out = new FileWriter(outMappingsFile)) {
@@ -232,8 +236,25 @@ public class ConvertMain {
232 236
233 // apply matches 237 // apply matches
234 Mappings newMappings = MappingsConverter.newMappings(classMatches, mappings, deobfuscators.source, deobfuscators.dest); 238 Mappings newMappings = MappingsConverter.newMappings(classMatches, mappings, deobfuscators.source, deobfuscators.dest);
235 MappingsConverter.applyMemberMatches(newMappings, fieldMatches, MappingsConverter.getFieldDoer()); 239 MappingsConverter.applyMemberMatches(newMappings, classMatches, fieldMatches, MappingsConverter.getFieldDoer());
236 MappingsConverter.applyMemberMatches(newMappings, methodMatches, MappingsConverter.getMethodDoer()); 240 MappingsConverter.applyMemberMatches(newMappings, classMatches, methodMatches, MappingsConverter.getMethodDoer());
241
242 // check the final mappings
243 MappingsChecker checker = new MappingsChecker(deobfuscators.dest.getJarIndex());
244 checker.dropBrokenMappings(newMappings);
245
246 for (java.util.Map.Entry<ClassEntry,ClassMapping> mapping : checker.getDroppedClassMappings().entrySet()) {
247 System.out.println("WARNING: Broken class entry " + mapping.getKey() + " (" + mapping.getValue().getDeobfName() + ")");
248 }
249 for (java.util.Map.Entry<ClassEntry,ClassMapping> mapping : checker.getDroppedInnerClassMappings().entrySet()) {
250 System.out.println("WARNING: Broken inner class entry " + mapping.getKey() + " (" + mapping.getValue().getDeobfName() + ")");
251 }
252 for (java.util.Map.Entry<FieldEntry,FieldMapping> mapping : checker.getDroppedFieldMappings().entrySet()) {
253 System.out.println("WARNING: Broken field entry " + mapping.getKey() + " (" + mapping.getValue().getDeobfName() + ")");
254 }
255 for (java.util.Map.Entry<BehaviorEntry,MethodMapping> mapping : checker.getDroppedMethodMappings().entrySet()) {
256 System.out.println("WARNING: Broken behavior entry " + mapping.getKey() + " (" + mapping.getValue().getDeobfName() + ")");
257 }
237 258
238 // write out the converted mappings 259 // write out the converted mappings
239 try (FileWriter out = new FileWriter(outMappingsFile)) { 260 try (FileWriter out = new FileWriter(outMappingsFile)) {
diff --git a/src/cuchaz/enigma/convert/MappingsConverter.java b/src/cuchaz/enigma/convert/MappingsConverter.java
index 59f3b5ba..ddd3a53c 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}
diff --git a/src/cuchaz/enigma/convert/MemberMatches.java b/src/cuchaz/enigma/convert/MemberMatches.java
index 1078ab75..1c162eac 100644
--- a/src/cuchaz/enigma/convert/MemberMatches.java
+++ b/src/cuchaz/enigma/convert/MemberMatches.java
@@ -113,6 +113,10 @@ public class MemberMatches<T extends Entry> {
113 public boolean isMatchedDestEntry(T destEntry) { 113 public boolean isMatchedDestEntry(T destEntry) {
114 return m_matches.containsValue(destEntry); 114 return m_matches.containsValue(destEntry);
115 } 115 }
116
117 public boolean isUnmatchableSourceEntry(T sourceEntry) {
118 return m_unmatchableSourceEntries.containsEntry(sourceEntry.getClassEntry(), sourceEntry);
119 }
116 120
117 public void makeMatch(T sourceEntry, T destEntry) { 121 public void makeMatch(T sourceEntry, T destEntry) {
118 boolean wasRemoved = m_unmatchedSourceEntries.remove(sourceEntry.getClassEntry(), sourceEntry); 122 boolean wasRemoved = m_unmatchedSourceEntries.remove(sourceEntry.getClassEntry(), sourceEntry);
diff --git a/src/cuchaz/enigma/mapping/ClassMapping.java b/src/cuchaz/enigma/mapping/ClassMapping.java
index ac70df0d..38cd3d6d 100644
--- a/src/cuchaz/enigma/mapping/ClassMapping.java
+++ b/src/cuchaz/enigma/mapping/ClassMapping.java
@@ -243,12 +243,13 @@ public class ClassMapping implements Serializable, Comparable<ClassMapping> {
243 } 243 }
244 } 244 }
245 245
246 public void setFieldObfName(String oldObfName, Type obfType, String newObfName) { 246 public void setFieldObfNameAndType(String oldObfName, Type obfType, String newObfName, Type newObfType) {
247 assert(newObfName != null); 247 assert(newObfName != null);
248 FieldMapping fieldMapping = m_fieldsByObf.remove(getFieldKey(oldObfName, obfType)); 248 FieldMapping fieldMapping = m_fieldsByObf.remove(getFieldKey(oldObfName, obfType));
249 assert(fieldMapping != null); 249 assert(fieldMapping != null);
250 fieldMapping.setObfName(newObfName); 250 fieldMapping.setObfName(newObfName);
251 boolean obfWasAdded = m_fieldsByObf.put(getFieldKey(newObfName, obfType), fieldMapping) == null; 251 fieldMapping.setObfType(newObfType);
252 boolean obfWasAdded = m_fieldsByObf.put(getFieldKey(newObfName, newObfType), fieldMapping) == null;
252 assert(obfWasAdded); 253 assert(obfWasAdded);
253 } 254 }
254 255
@@ -328,12 +329,13 @@ public class ClassMapping implements Serializable, Comparable<ClassMapping> {
328 } 329 }
329 } 330 }
330 331
331 public void setMethodObfName(String oldObfName, Signature obfSignature, String newObfName) { 332 public void setMethodObfNameAndSignature(String oldObfName, Signature obfSignature, String newObfName, Signature newObfSignature) {
332 assert(newObfName != null); 333 assert(newObfName != null);
333 MethodMapping methodMapping = m_methodsByObf.remove(getMethodKey(oldObfName, obfSignature)); 334 MethodMapping methodMapping = m_methodsByObf.remove(getMethodKey(oldObfName, obfSignature));
334 assert(methodMapping != null); 335 assert(methodMapping != null);
335 methodMapping.setObfName(newObfName); 336 methodMapping.setObfName(newObfName);
336 boolean obfWasAdded = m_methodsByObf.put(getMethodKey(newObfName, obfSignature), methodMapping) == null; 337 methodMapping.setObfSignature(newObfSignature);
338 boolean obfWasAdded = m_methodsByObf.put(getMethodKey(newObfName, newObfSignature), methodMapping) == null;
337 assert(obfWasAdded); 339 assert(obfWasAdded);
338 } 340 }
339 341
diff --git a/src/cuchaz/enigma/mapping/FieldMapping.java b/src/cuchaz/enigma/mapping/FieldMapping.java
index 3aa9e698..463d901c 100644
--- a/src/cuchaz/enigma/mapping/FieldMapping.java
+++ b/src/cuchaz/enigma/mapping/FieldMapping.java
@@ -32,6 +32,7 @@ public class FieldMapping implements Serializable, Comparable<FieldMapping>, Mem
32 m_obfType = new Type(other.m_obfType, obfClassNameReplacer); 32 m_obfType = new Type(other.m_obfType, obfClassNameReplacer);
33 } 33 }
34 34
35 @Override
35 public String getObfName() { 36 public String getObfName() {
36 return m_obfName; 37 return m_obfName;
37 } 38 }
@@ -52,6 +53,10 @@ public class FieldMapping implements Serializable, Comparable<FieldMapping>, Mem
52 return m_obfType; 53 return m_obfType;
53 } 54 }
54 55
56 public void setObfType(Type val) {
57 m_obfType = val;
58 }
59
55 @Override 60 @Override
56 public int compareTo(FieldMapping other) { 61 public int compareTo(FieldMapping other) {
57 return (m_obfName + m_obfType).compareTo(other.m_obfName + other.m_obfType); 62 return (m_obfName + m_obfType).compareTo(other.m_obfName + other.m_obfType);
diff --git a/src/cuchaz/enigma/mapping/MemberMapping.java b/src/cuchaz/enigma/mapping/MemberMapping.java
index d62a7c10..d8e2ee3a 100644
--- a/src/cuchaz/enigma/mapping/MemberMapping.java
+++ b/src/cuchaz/enigma/mapping/MemberMapping.java
@@ -3,4 +3,5 @@ package cuchaz.enigma.mapping;
3 3
4public interface MemberMapping<T extends Entry> { 4public interface MemberMapping<T extends Entry> {
5 T getObfEntry(ClassEntry classEntry); 5 T getObfEntry(ClassEntry classEntry);
6 String getObfName();
6} 7}
diff --git a/src/cuchaz/enigma/mapping/MethodMapping.java b/src/cuchaz/enigma/mapping/MethodMapping.java
index a67e352f..bef232e3 100644
--- a/src/cuchaz/enigma/mapping/MethodMapping.java
+++ b/src/cuchaz/enigma/mapping/MethodMapping.java
@@ -52,6 +52,7 @@ public class MethodMapping implements Serializable, Comparable<MethodMapping>, M
52 } 52 }
53 } 53 }
54 54
55 @Override
55 public String getObfName() { 56 public String getObfName() {
56 return m_obfName; 57 return m_obfName;
57 } 58 }
@@ -72,6 +73,10 @@ public class MethodMapping implements Serializable, Comparable<MethodMapping>, M
72 return m_obfSignature; 73 return m_obfSignature;
73 } 74 }
74 75
76 public void setObfSignature(Signature val) {
77 m_obfSignature = val;
78 }
79
75 public Iterable<ArgumentMapping> arguments() { 80 public Iterable<ArgumentMapping> arguments() {
76 return m_arguments.values(); 81 return m_arguments.values();
77 } 82 }