summaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/cuchaz/enigma/CommandMain.java2
-rw-r--r--src/main/java/cuchaz/enigma/Constants.java8
-rw-r--r--src/main/java/cuchaz/enigma/ConvertMain.java46
-rw-r--r--src/main/java/cuchaz/enigma/Deobfuscator.java43
-rw-r--r--src/main/java/cuchaz/enigma/MainFormatConverter.java18
-rw-r--r--src/main/java/cuchaz/enigma/TranslatingTypeLoader.java4
-rw-r--r--src/main/java/cuchaz/enigma/analysis/EntryRenamer.java20
-rw-r--r--src/main/java/cuchaz/enigma/analysis/JarIndex.java20
-rw-r--r--src/main/java/cuchaz/enigma/analysis/MethodImplementationsTreeNode.java4
-rw-r--r--src/main/java/cuchaz/enigma/analysis/MethodInheritanceTreeNode.java4
-rw-r--r--src/main/java/cuchaz/enigma/analysis/RelatedMethodChecker.java104
-rw-r--r--src/main/java/cuchaz/enigma/analysis/SourceIndex.java4
-rw-r--r--src/main/java/cuchaz/enigma/analysis/TranslationIndex.java2
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/InfoType.java5
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/MethodParameterWriter.java2
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/MethodParametersAttribute.java2
-rw-r--r--src/main/java/cuchaz/enigma/convert/ClassIdentity.java2
-rw-r--r--src/main/java/cuchaz/enigma/convert/ClassMatches.java4
-rw-r--r--src/main/java/cuchaz/enigma/convert/ClassMatching.java15
-rw-r--r--src/main/java/cuchaz/enigma/convert/FieldMatches.java151
-rw-r--r--src/main/java/cuchaz/enigma/convert/MappingsConverter.java47
-rw-r--r--src/main/java/cuchaz/enigma/convert/MatchesReader.java13
-rw-r--r--src/main/java/cuchaz/enigma/gui/AboutDialog.java8
-rw-r--r--src/main/java/cuchaz/enigma/gui/BoxHighlightPainter.java16
-rw-r--r--src/main/java/cuchaz/enigma/gui/BrowserCaret.java5
-rw-r--r--src/main/java/cuchaz/enigma/gui/ClassListCellRenderer.java36
-rw-r--r--src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java263
-rw-r--r--src/main/java/cuchaz/enigma/gui/ClassSelector.java16
-rw-r--r--src/main/java/cuchaz/enigma/gui/ClassSelectorClassNode.java19
-rw-r--r--src/main/java/cuchaz/enigma/gui/ClassSelectorPackageNode.java15
-rw-r--r--src/main/java/cuchaz/enigma/gui/CodeReader.java66
-rw-r--r--src/main/java/cuchaz/enigma/gui/CrashDialog.java24
-rw-r--r--src/main/java/cuchaz/enigma/gui/DeobfuscatedHighlightPainter.java1
-rw-r--r--src/main/java/cuchaz/enigma/gui/Gui.java221
-rw-r--r--src/main/java/cuchaz/enigma/gui/GuiController.java212
-rw-r--r--src/main/java/cuchaz/enigma/gui/GuiTricks.java8
-rw-r--r--src/main/java/cuchaz/enigma/gui/MemberMatchingGui.java86
-rw-r--r--src/main/java/cuchaz/enigma/gui/ObfuscatedHighlightPainter.java1
-rw-r--r--src/main/java/cuchaz/enigma/gui/OtherHighlightPainter.java1
-rw-r--r--src/main/java/cuchaz/enigma/gui/ProgressDialog.java54
-rw-r--r--src/main/java/cuchaz/enigma/gui/RenameListener.java17
-rw-r--r--src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java7
-rw-r--r--src/main/java/cuchaz/enigma/gui/TokenListCellRenderer.java12
-rw-r--r--src/main/java/cuchaz/enigma/mapping/ArgumentEntry.java5
-rw-r--r--src/main/java/cuchaz/enigma/mapping/ClassMapping.java5
-rw-r--r--src/main/java/cuchaz/enigma/mapping/ConstructorEntry.java5
-rw-r--r--src/main/java/cuchaz/enigma/mapping/FieldMapping.java49
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsChecker.java7
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsReader.java24
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsReaderOld.java2
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java8
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsWriter.java2
-rw-r--r--src/main/java/cuchaz/enigma/mapping/Signature.java5
-rw-r--r--src/main/java/cuchaz/enigma/mapping/SignatureUpdater.java13
-rw-r--r--src/main/java/cuchaz/enigma/mapping/Translator.java9
-rw-r--r--src/main/java/cuchaz/enigma/mapping/Type.java6
56 files changed, 541 insertions, 1207 deletions
diff --git a/src/main/java/cuchaz/enigma/CommandMain.java b/src/main/java/cuchaz/enigma/CommandMain.java
index b715c6e2..8dfbe24d 100644
--- a/src/main/java/cuchaz/enigma/CommandMain.java
+++ b/src/main/java/cuchaz/enigma/CommandMain.java
@@ -79,7 +79,7 @@ public class CommandMain {
79 } 79 }
80 80
81 private static void printHelp() { 81 private static void printHelp() {
82 System.out.println(String.format("%s - %s", Constants.Name, Constants.Version)); 82 System.out.println(String.format("%s - %s", Constants.NAME, Constants.VERSION));
83 System.out.println("Usage:"); 83 System.out.println("Usage:");
84 System.out.println("\tjava -cp enigma.jar cuchaz.enigma.CommandMain <command>"); 84 System.out.println("\tjava -cp enigma.jar cuchaz.enigma.CommandMain <command>");
85 System.out.println("\twhere <command> is one of:"); 85 System.out.println("\twhere <command> is one of:");
diff --git a/src/main/java/cuchaz/enigma/Constants.java b/src/main/java/cuchaz/enigma/Constants.java
index 5d2c84bf..c6a58259 100644
--- a/src/main/java/cuchaz/enigma/Constants.java
+++ b/src/main/java/cuchaz/enigma/Constants.java
@@ -11,10 +11,10 @@
11package cuchaz.enigma; 11package cuchaz.enigma;
12 12
13public class Constants { 13public class Constants {
14 public static final String Name = "Enigma"; 14 public static final String NAME = "Enigma";
15 public static final String Version = "0.2 - Beta"; 15 public static final String VERSION = "0.2 - Beta";
16 public static final String Url = "http://www.cuchazinteractive.com/enigma"; 16 public static final String URL = "http://www.cuchazinteractive.com/enigma";
17 public static final int MiB = 1024 * 1024; // 1 mebibyte 17 public static final int MiB = 1024 * 1024; // 1 mebibyte
18 public static final int KiB = 1024; // 1 kebibyte 18 public static final int KiB = 1024; // 1 kebibyte
19 public static final String NonePackage = "none"; 19 public static final String NONE_PACKAGE = "none";
20} 20}
diff --git a/src/main/java/cuchaz/enigma/ConvertMain.java b/src/main/java/cuchaz/enigma/ConvertMain.java
index a68ab614..caa61545 100644
--- a/src/main/java/cuchaz/enigma/ConvertMain.java
+++ b/src/main/java/cuchaz/enigma/ConvertMain.java
@@ -76,7 +76,7 @@ public class ConvertMain {
76 } 76 }
77 77
78 private static void printHelp() { 78 private static void printHelp() {
79 System.out.println(String.format("%s - %s", Constants.Name, Constants.Version)); 79 System.out.println(String.format("%s - %s", Constants.NAME, Constants.VERSION));
80 System.out.println("Usage:"); 80 System.out.println("Usage:");
81 System.out.println("\tjava -cp enigma.jar cuchaz.enigma.ConvertMain <command> <old-jar> <new-jar> <old-mappings> <new-mappings> <class-matches> <field-matches> <method-matches>"); 81 System.out.println("\tjava -cp enigma.jar cuchaz.enigma.ConvertMain <command> <old-jar> <new-jar> <old-mappings> <new-mappings> <class-matches> <field-matches> <method-matches>");
82 System.out.println("\tWhere <command> is one of:"); 82 System.out.println("\tWhere <command> is one of:");
@@ -121,14 +121,11 @@ public class ConvertMain {
121 Deobfuscators deobfuscators = new Deobfuscators(sourceJar, destJar); 121 Deobfuscators deobfuscators = new Deobfuscators(sourceJar, destJar);
122 deobfuscators.source.setMappings(mappings); 122 deobfuscators.source.setMappings(mappings);
123 System.out.println("Starting GUI..."); 123 System.out.println("Starting GUI...");
124 new ClassMatchingGui(classMatches, deobfuscators.source, deobfuscators.dest).setSaveListener(new ClassMatchingGui.SaveListener() { 124 new ClassMatchingGui(classMatches, deobfuscators.source, deobfuscators.dest).setSaveListener(matches -> {
125 @Override 125 try {
126 public void save(ClassMatches matches) { 126 MatchesWriter.writeClasses(matches, classMatchesFile);
127 try { 127 } catch (IOException ex) {
128 MatchesWriter.writeClasses(matches, classMatchesFile); 128 throw new Error(ex);
129 } catch (IOException ex) {
130 throw new Error(ex);
131 }
132 } 129 }
133 }); 130 });
134 } 131 }
@@ -185,14 +182,11 @@ public class ConvertMain {
185 checker.dropBrokenMappings(destMappings); 182 checker.dropBrokenMappings(destMappings);
186 deobfuscators.dest.setMappings(destMappings); 183 deobfuscators.dest.setMappings(destMappings);
187 184
188 new MemberMatchingGui<>(classMatches, fieldMatches, deobfuscators.source, deobfuscators.dest).setSaveListener(new MemberMatchingGui.SaveListener<FieldEntry>() { 185 new MemberMatchingGui<>(classMatches, fieldMatches, deobfuscators.source, deobfuscators.dest).setSaveListener(matches -> {
189 @Override 186 try {
190 public void save(MemberMatches<FieldEntry> matches) { 187 MatchesWriter.writeMembers(matches, fieldMatchesFile);
191 try { 188 } catch (IOException ex) {
192 MatchesWriter.writeMembers(matches, fieldMatchesFile); 189 throw new Error(ex);
193 } catch (IOException ex) {
194 throw new Error(ex);
195 }
196 } 190 }
197 }); 191 });
198 } 192 }
@@ -258,14 +252,11 @@ public class ConvertMain {
258 checker.dropBrokenMappings(destMappings); 252 checker.dropBrokenMappings(destMappings);
259 deobfuscators.dest.setMappings(destMappings); 253 deobfuscators.dest.setMappings(destMappings);
260 254
261 new MemberMatchingGui<>(classMatches, methodMatches, deobfuscators.source, deobfuscators.dest).setSaveListener(new MemberMatchingGui.SaveListener<BehaviorEntry>() { 255 new MemberMatchingGui<>(classMatches, methodMatches, deobfuscators.source, deobfuscators.dest).setSaveListener(matches -> {
262 @Override 256 try {
263 public void save(MemberMatches<BehaviorEntry> matches) { 257 MatchesWriter.writeMembers(matches, methodMatchesFile);
264 try { 258 } catch (IOException ex) {
265 MatchesWriter.writeMembers(matches, methodMatchesFile); 259 throw new Error(ex);
266 } catch (IOException ex) {
267 throw new Error(ex);
268 }
269 } 260 }
270 }); 261 });
271 } 262 }
@@ -303,11 +294,8 @@ public class ConvertMain {
303 System.out.println("WARNING: Broken behavior entry " + mapping.getKey() + " (" + mapping.getValue().getDeobfName() + ")"); 294 System.out.println("WARNING: Broken behavior entry " + mapping.getKey() + " (" + mapping.getValue().getDeobfName() + ")");
304 } 295 }
305 296
306 //TODO Fix
307 // write out the converted mappings 297 // write out the converted mappings
308// try (FileWriter out = new FileWriter(outMappingsFile)) { 298 new MappingsWriter().write(outMappingsFile, newMappings);
309// new MappingsWriter().write(out, newMappings);
310// }
311 System.out.println("Wrote converted mappings to:\n\t" + outMappingsFile.getAbsolutePath()); 299 System.out.println("Wrote converted mappings to:\n\t" + outMappingsFile.getAbsolutePath());
312 } 300 }
313 301
diff --git a/src/main/java/cuchaz/enigma/Deobfuscator.java b/src/main/java/cuchaz/enigma/Deobfuscator.java
index 2a18e657..f917deb7 100644
--- a/src/main/java/cuchaz/enigma/Deobfuscator.java
+++ b/src/main/java/cuchaz/enigma/Deobfuscator.java
@@ -120,11 +120,6 @@ public class Deobfuscator {
120 } 120 }
121 } 121 }
122 122
123 // check for related method inconsistencies
124 if (checker.getRelatedMethodChecker().hasProblems()) {
125 throw new Error("Related methods are inconsistent! Need to fix the mappings manually.\n" + checker.getRelatedMethodChecker().getReport());
126 }
127
128 m_mappings = val; 123 m_mappings = val;
129 m_renamer = new MappingsRenamer(m_jarIndex, val); 124 m_renamer = new MappingsRenamer(m_jarIndex, val);
130 m_translatorCache.clear(); 125 m_translatorCache.clear();
@@ -151,7 +146,7 @@ public class Deobfuscator {
151 if (!deobfClassEntry.equals(obfClassEntry)) { 146 if (!deobfClassEntry.equals(obfClassEntry)) {
152 // if the class has a mapping, clearly it's deobfuscated 147 // if the class has a mapping, clearly it's deobfuscated
153 deobfClasses.add(deobfClassEntry); 148 deobfClasses.add(deobfClassEntry);
154 } else if (!obfClassEntry.getPackageName().equals(Constants.NonePackage)) { 149 } else if (!obfClassEntry.getPackageName().equals(Constants.NONE_PACKAGE)) {
155 // also call it deobufscated if it's not in the none package 150 // also call it deobufscated if it's not in the none package
156 deobfClasses.add(obfClassEntry); 151 deobfClasses.add(obfClassEntry);
157 } else { 152 } else {
@@ -308,33 +303,15 @@ public class Deobfuscator {
308 getTranslator(TranslationDirection.Obfuscating), 303 getTranslator(TranslationDirection.Obfuscating),
309 getTranslator(TranslationDirection.Deobfuscating) 304 getTranslator(TranslationDirection.Deobfuscating)
310 ); 305 );
311 transformJar(out, progress, new ClassTransformer() { 306 transformJar(out, progress, loader::transformClass);
312
313 @Override
314 public CtClass transform(CtClass c) throws Exception {
315 return loader.transformClass(c);
316 }
317 });
318 } 307 }
319 308
320 public void protectifyJar(File out, ProgressListener progress) { 309 public void protectifyJar(File out, ProgressListener progress) {
321 transformJar(out, progress, new ClassTransformer() { 310 transformJar(out, progress, ClassProtectifier::protectify);
322
323 @Override
324 public CtClass transform(CtClass c) throws Exception {
325 return ClassProtectifier.protectify(c);
326 }
327 });
328 } 311 }
329 312
330 public void publifyJar(File out, ProgressListener progress) { 313 public void publifyJar(File out, ProgressListener progress) {
331 transformJar(out, progress, new ClassTransformer() { 314 transformJar(out, progress, ClassPublifier::publify);
332
333 @Override
334 public CtClass transform(CtClass c) throws Exception {
335 return ClassPublifier.publify(c);
336 }
337 });
338 } 315 }
339 316
340 private interface ClassTransformer { 317 private interface ClassTransformer {
@@ -390,22 +367,14 @@ public class Deobfuscator {
390 if (deobfReference == null) { 367 if (deobfReference == null) {
391 return null; 368 return null;
392 } 369 }
393 return new EntryReference<E, C>( 370 return new EntryReference<>(obfuscateEntry(deobfReference.entry), obfuscateEntry(deobfReference.context), deobfReference);
394 obfuscateEntry(deobfReference.entry),
395 obfuscateEntry(deobfReference.context),
396 deobfReference
397 );
398 } 371 }
399 372
400 public <E extends Entry, C extends Entry> EntryReference<E, C> deobfuscateReference(EntryReference<E, C> obfReference) { 373 public <E extends Entry, C extends Entry> EntryReference<E, C> deobfuscateReference(EntryReference<E, C> obfReference) {
401 if (obfReference == null) { 374 if (obfReference == null) {
402 return null; 375 return null;
403 } 376 }
404 return new EntryReference<E, C>( 377 return new EntryReference<>(deobfuscateEntry(obfReference.entry), deobfuscateEntry(obfReference.context), obfReference);
405 deobfuscateEntry(obfReference.entry),
406 deobfuscateEntry(obfReference.context),
407 obfReference
408 );
409 } 378 }
410 379
411 public boolean isObfuscatedIdentifier(Entry obfEntry) { 380 public boolean isObfuscatedIdentifier(Entry obfEntry) {
diff --git a/src/main/java/cuchaz/enigma/MainFormatConverter.java b/src/main/java/cuchaz/enigma/MainFormatConverter.java
index 712b0f89..4dd19ea8 100644
--- a/src/main/java/cuchaz/enigma/MainFormatConverter.java
+++ b/src/main/java/cuchaz/enigma/MainFormatConverter.java
@@ -59,24 +59,18 @@ public class MainFormatConverter {
59 59
60 System.out.println("Saving mappings..."); 60 System.out.println("Saving mappings...");
61 61
62 //TODO Fix 62 new MappingsWriter().write(fileMappings, mappings);
63// try (FileWriter writer = new FileWriter(fileMappings)) {
64// new MappingsWriter().write(writer, mappings);
65// }
66 63
67 System.out.println("Done!"); 64 System.out.println("Done!");
68 } 65 }
69 66
70 private static Type moveClasssesOutOfDefaultPackage(Type type) { 67 private static Type moveClasssesOutOfDefaultPackage(Type type) {
71 return new Type(type, new ClassNameReplacer() { 68 return new Type(type, className -> {
72 @Override 69 ClassEntry entry = new ClassEntry(className);
73 public String replace(String className) { 70 if (entry.isInDefaultPackage()) {
74 ClassEntry entry = new ClassEntry(className); 71 return Constants.NONE_PACKAGE + "/" + className;
75 if (entry.isInDefaultPackage()) {
76 return Constants.NonePackage + "/" + className;
77 }
78 return null;
79 } 72 }
73 return null;
80 }); 74 });
81 } 75 }
82 76
diff --git a/src/main/java/cuchaz/enigma/TranslatingTypeLoader.java b/src/main/java/cuchaz/enigma/TranslatingTypeLoader.java
index 6c429a6a..a4f53e4b 100644
--- a/src/main/java/cuchaz/enigma/TranslatingTypeLoader.java
+++ b/src/main/java/cuchaz/enigma/TranslatingTypeLoader.java
@@ -191,7 +191,7 @@ public class TranslatingTypeLoader implements ITypeLoader {
191 public List<String> getClassNamesToTry(ClassEntry obfClassEntry) { 191 public List<String> getClassNamesToTry(ClassEntry obfClassEntry) {
192 List<String> classNamesToTry = Lists.newArrayList(); 192 List<String> classNamesToTry = Lists.newArrayList();
193 classNamesToTry.add(obfClassEntry.getName()); 193 classNamesToTry.add(obfClassEntry.getName());
194 if (obfClassEntry.getPackageName().equals(Constants.NonePackage)) { 194 if (obfClassEntry.getPackageName().equals(Constants.NONE_PACKAGE)) {
195 // taking off the none package, if any 195 // taking off the none package, if any
196 classNamesToTry.add(obfClassEntry.getSimpleName()); 196 classNamesToTry.add(obfClassEntry.getSimpleName());
197 } 197 }
@@ -207,7 +207,7 @@ public class TranslatingTypeLoader implements ITypeLoader {
207 207
208 // we moved a lot of classes out of the default package into the none package 208 // we moved a lot of classes out of the default package into the none package
209 // make sure all the class references are consistent 209 // make sure all the class references are consistent
210 ClassRenamer.moveAllClassesOutOfDefaultPackage(c, Constants.NonePackage); 210 ClassRenamer.moveAllClassesOutOfDefaultPackage(c, Constants.NONE_PACKAGE);
211 211
212 // reconstruct inner classes 212 // reconstruct inner classes
213 new InnerClassWriter(m_jarIndex).write(c); 213 new InnerClassWriter(m_jarIndex).write(c);
diff --git a/src/main/java/cuchaz/enigma/analysis/EntryRenamer.java b/src/main/java/cuchaz/enigma/analysis/EntryRenamer.java
index 9c3d051b..a885c6a4 100644
--- a/src/main/java/cuchaz/enigma/analysis/EntryRenamer.java
+++ b/src/main/java/cuchaz/enigma/analysis/EntryRenamer.java
@@ -36,10 +36,7 @@ public class EntryRenamer {
36 // for each key/value pair... 36 // for each key/value pair...
37 Set<Map.Entry<Key, Val>> entriesToAdd = Sets.newHashSet(); 37 Set<Map.Entry<Key, Val>> entriesToAdd = Sets.newHashSet();
38 for (Map.Entry<Key, Val> entry : map.entrySet()) { 38 for (Map.Entry<Key, Val> entry : map.entrySet()) {
39 entriesToAdd.add(new AbstractMap.SimpleEntry<>( 39 entriesToAdd.add(new AbstractMap.SimpleEntry<>(renameClassesInThing(renames, entry.getKey()), renameClassesInThing(renames, entry.getValue())));
40 renameClassesInThing(renames, entry.getKey()),
41 renameClassesInThing(renames, entry.getValue())
42 ));
43 } 40 }
44 map.clear(); 41 map.clear();
45 for (Map.Entry<Key, Val> entry : entriesToAdd) { 42 for (Map.Entry<Key, Val> entry : entriesToAdd) {
@@ -51,10 +48,7 @@ public class EntryRenamer {
51 // for each key/value pair... 48 // for each key/value pair...
52 Set<Map.Entry<Key, Val>> entriesToAdd = Sets.newHashSet(); 49 Set<Map.Entry<Key, Val>> entriesToAdd = Sets.newHashSet();
53 for (Map.Entry<Key, Val> entry : map.entries()) { 50 for (Map.Entry<Key, Val> entry : map.entries()) {
54 entriesToAdd.add(new AbstractMap.SimpleEntry<>( 51 entriesToAdd.add(new AbstractMap.SimpleEntry<>(renameClassesInThing(renames, entry.getKey()), renameClassesInThing(renames, entry.getValue())));
55 renameClassesInThing(renames, entry.getKey()),
56 renameClassesInThing(renames, entry.getValue())
57 ));
58 } 52 }
59 map.clear(); 53 map.clear();
60 for (Map.Entry<Key, Val> entry : entriesToAdd) { 54 for (Map.Entry<Key, Val> entry : entriesToAdd) {
@@ -66,10 +60,7 @@ public class EntryRenamer {
66 // for each key/value pair... 60 // for each key/value pair...
67 Set<Map.Entry<Key, Val>> entriesToAdd = Sets.newHashSet(); 61 Set<Map.Entry<Key, Val>> entriesToAdd = Sets.newHashSet();
68 for (Map.Entry<Key, Val> entry : map.entries()) { 62 for (Map.Entry<Key, Val> entry : map.entries()) {
69 entriesToAdd.add(new AbstractMap.SimpleEntry<>( 63 entriesToAdd.add(new AbstractMap.SimpleEntry<>(renameMethodsInThing(renames, entry.getKey()), renameMethodsInThing(renames, entry.getValue())));
70 renameMethodsInThing(renames, entry.getKey()),
71 renameMethodsInThing(renames, entry.getValue())
72 ));
73 } 64 }
74 map.clear(); 65 map.clear();
75 for (Map.Entry<Key, Val> entry : entriesToAdd) { 66 for (Map.Entry<Key, Val> entry : entriesToAdd) {
@@ -81,10 +72,7 @@ public class EntryRenamer {
81 // for each key/value pair... 72 // for each key/value pair...
82 Set<Map.Entry<Key, Val>> entriesToAdd = Sets.newHashSet(); 73 Set<Map.Entry<Key, Val>> entriesToAdd = Sets.newHashSet();
83 for (Map.Entry<Key, Val> entry : map.entrySet()) { 74 for (Map.Entry<Key, Val> entry : map.entrySet()) {
84 entriesToAdd.add(new AbstractMap.SimpleEntry<>( 75 entriesToAdd.add(new AbstractMap.SimpleEntry<>(renameMethodsInThing(renames, entry.getKey()), renameMethodsInThing(renames, entry.getValue())));
85 renameMethodsInThing(renames, entry.getKey()),
86 renameMethodsInThing(renames, entry.getValue())
87 ));
88 } 76 }
89 map.clear(); 77 map.clear();
90 for (Map.Entry<Key, Val> entry : entriesToAdd) { 78 for (Map.Entry<Key, Val> entry : entriesToAdd) {
diff --git a/src/main/java/cuchaz/enigma/analysis/JarIndex.java b/src/main/java/cuchaz/enigma/analysis/JarIndex.java
index 8b30f9eb..377a8cb2 100644
--- a/src/main/java/cuchaz/enigma/analysis/JarIndex.java
+++ b/src/main/java/cuchaz/enigma/analysis/JarIndex.java
@@ -60,14 +60,14 @@ public class JarIndex {
60 for (ClassEntry classEntry : JarClassIterator.getClassEntries(jar)) { 60 for (ClassEntry classEntry : JarClassIterator.getClassEntries(jar)) {
61 if (classEntry.isInDefaultPackage()) { 61 if (classEntry.isInDefaultPackage()) {
62 // move out of default package 62 // move out of default package
63 classEntry = new ClassEntry(Constants.NonePackage + "/" + classEntry.getName()); 63 classEntry = new ClassEntry(Constants.NONE_PACKAGE + "/" + classEntry.getName());
64 } 64 }
65 this.obfClassEntries.add(classEntry); 65 this.obfClassEntries.add(classEntry);
66 } 66 }
67 67
68 // step 2: index field/method/constructor access 68 // step 2: index field/method/constructor access
69 for (CtClass c : JarClassIterator.classes(jar)) { 69 for (CtClass c : JarClassIterator.classes(jar)) {
70 ClassRenamer.moveAllClassesOutOfDefaultPackage(c, Constants.NonePackage); 70 ClassRenamer.moveAllClassesOutOfDefaultPackage(c, Constants.NONE_PACKAGE);
71 for (CtField field : c.getDeclaredFields()) { 71 for (CtField field : c.getDeclaredFields()) {
72 FieldEntry fieldEntry = EntryFactory.getFieldEntry(field); 72 FieldEntry fieldEntry = EntryFactory.getFieldEntry(field);
73 this.access.put(fieldEntry, Access.get(field)); 73 this.access.put(fieldEntry, Access.get(field));
@@ -82,7 +82,7 @@ public class JarIndex {
82 82
83 // step 3: index extends, implements, fields, and methods 83 // step 3: index extends, implements, fields, and methods
84 for (CtClass c : JarClassIterator.classes(jar)) { 84 for (CtClass c : JarClassIterator.classes(jar)) {
85 ClassRenamer.moveAllClassesOutOfDefaultPackage(c, Constants.NonePackage); 85 ClassRenamer.moveAllClassesOutOfDefaultPackage(c, Constants.NONE_PACKAGE);
86 this.translationIndex.indexClass(c); 86 this.translationIndex.indexClass(c);
87 String className = Descriptor.toJvmName(c.getName()); 87 String className = Descriptor.toJvmName(c.getName());
88 for (String interfaceName : c.getClassFile().getInterfaces()) { 88 for (String interfaceName : c.getClassFile().getInterfaces()) {
@@ -99,7 +99,7 @@ public class JarIndex {
99 99
100 // step 4: index field, method, constructor references 100 // step 4: index field, method, constructor references
101 for (CtClass c : JarClassIterator.classes(jar)) { 101 for (CtClass c : JarClassIterator.classes(jar)) {
102 ClassRenamer.moveAllClassesOutOfDefaultPackage(c, Constants.NonePackage); 102 ClassRenamer.moveAllClassesOutOfDefaultPackage(c, Constants.NONE_PACKAGE);
103 for (CtBehavior behavior : c.getDeclaredBehaviors()) { 103 for (CtBehavior behavior : c.getDeclaredBehaviors()) {
104 indexBehaviorReferences(behavior); 104 indexBehaviorReferences(behavior);
105 } 105 }
@@ -109,7 +109,7 @@ public class JarIndex {
109 109
110 // step 5: index inner classes and anonymous classes 110 // step 5: index inner classes and anonymous classes
111 for (CtClass c : JarClassIterator.classes(jar)) { 111 for (CtClass c : JarClassIterator.classes(jar)) {
112 ClassRenamer.moveAllClassesOutOfDefaultPackage(c, Constants.NonePackage); 112 ClassRenamer.moveAllClassesOutOfDefaultPackage(c, Constants.NONE_PACKAGE);
113 ClassEntry innerClassEntry = EntryFactory.getClassEntry(c); 113 ClassEntry innerClassEntry = EntryFactory.getClassEntry(c);
114 ClassEntry outerClassEntry = findOuterClass(c); 114 ClassEntry outerClassEntry = findOuterClass(c);
115 if (outerClassEntry != null) { 115 if (outerClassEntry != null) {
@@ -183,7 +183,7 @@ public class JarIndex {
183 calledMethodEntry.getSignature() 183 calledMethodEntry.getSignature()
184 ); 184 );
185 } 185 }
186 EntryReference<BehaviorEntry, BehaviorEntry> reference = new EntryReference<BehaviorEntry, BehaviorEntry>( 186 EntryReference<BehaviorEntry, BehaviorEntry> reference = new EntryReference<>(
187 calledMethodEntry, 187 calledMethodEntry,
188 call.getMethodName(), 188 call.getMethodName(),
189 behaviorEntry 189 behaviorEntry
@@ -198,7 +198,7 @@ public class JarIndex {
198 if (resolvedClassEntry != null && !resolvedClassEntry.equals(calledFieldEntry.getClassEntry())) { 198 if (resolvedClassEntry != null && !resolvedClassEntry.equals(calledFieldEntry.getClassEntry())) {
199 calledFieldEntry = new FieldEntry(calledFieldEntry, resolvedClassEntry); 199 calledFieldEntry = new FieldEntry(calledFieldEntry, resolvedClassEntry);
200 } 200 }
201 EntryReference<FieldEntry, BehaviorEntry> reference = new EntryReference<FieldEntry, BehaviorEntry>( 201 EntryReference<FieldEntry, BehaviorEntry> reference = new EntryReference<>(
202 calledFieldEntry, 202 calledFieldEntry,
203 call.getFieldName(), 203 call.getFieldName(),
204 behaviorEntry 204 behaviorEntry
@@ -209,7 +209,7 @@ public class JarIndex {
209 @Override 209 @Override
210 public void edit(ConstructorCall call) { 210 public void edit(ConstructorCall call) {
211 ConstructorEntry calledConstructorEntry = EntryFactory.getConstructorEntry(call); 211 ConstructorEntry calledConstructorEntry = EntryFactory.getConstructorEntry(call);
212 EntryReference<BehaviorEntry, BehaviorEntry> reference = new EntryReference<BehaviorEntry, BehaviorEntry>( 212 EntryReference<BehaviorEntry, BehaviorEntry> reference = new EntryReference<>(
213 calledConstructorEntry, 213 calledConstructorEntry,
214 call.getMethodName(), 214 call.getMethodName(),
215 behaviorEntry 215 behaviorEntry
@@ -220,7 +220,7 @@ public class JarIndex {
220 @Override 220 @Override
221 public void edit(NewExpr call) { 221 public void edit(NewExpr call) {
222 ConstructorEntry calledConstructorEntry = EntryFactory.getConstructorEntry(call); 222 ConstructorEntry calledConstructorEntry = EntryFactory.getConstructorEntry(call);
223 EntryReference<BehaviorEntry, BehaviorEntry> reference = new EntryReference<BehaviorEntry, BehaviorEntry>( 223 EntryReference<BehaviorEntry, BehaviorEntry> reference = new EntryReference<>(
224 calledConstructorEntry, 224 calledConstructorEntry,
225 call.getClassName(), 225 call.getClassName(),
226 behaviorEntry 226 behaviorEntry
@@ -711,7 +711,7 @@ public class JarIndex {
711 711
712 public Set<ClassEntry> getInterfaces(String className) { 712 public Set<ClassEntry> getInterfaces(String className) {
713 ClassEntry classEntry = new ClassEntry(className); 713 ClassEntry classEntry = new ClassEntry(className);
714 Set<ClassEntry> interfaces = new HashSet<ClassEntry>(); 714 Set<ClassEntry> interfaces = new HashSet<>();
715 interfaces.addAll(this.translationIndex.getInterfaces(classEntry)); 715 interfaces.addAll(this.translationIndex.getInterfaces(classEntry));
716 for (ClassEntry ancestor : this.translationIndex.getAncestry(classEntry)) { 716 for (ClassEntry ancestor : this.translationIndex.getAncestry(classEntry)) {
717 interfaces.addAll(this.translationIndex.getInterfaces(ancestor)); 717 interfaces.addAll(this.translationIndex.getInterfaces(ancestor));
diff --git a/src/main/java/cuchaz/enigma/analysis/MethodImplementationsTreeNode.java b/src/main/java/cuchaz/enigma/analysis/MethodImplementationsTreeNode.java
index 1cf80d91..7919b5d5 100644
--- a/src/main/java/cuchaz/enigma/analysis/MethodImplementationsTreeNode.java
+++ b/src/main/java/cuchaz/enigma/analysis/MethodImplementationsTreeNode.java
@@ -75,9 +75,7 @@ public class MethodImplementationsTreeNode extends DefaultMutableTreeNode {
75 } 75 }
76 76
77 // add them to this node 77 // add them to this node
78 for (MethodImplementationsTreeNode node : nodes) { 78 nodes.forEach(this::add);
79 this.add(node);
80 }
81 } 79 }
82 80
83 public static MethodImplementationsTreeNode findNode(MethodImplementationsTreeNode node, MethodEntry entry) { 81 public static MethodImplementationsTreeNode findNode(MethodImplementationsTreeNode node, MethodEntry entry) {
diff --git a/src/main/java/cuchaz/enigma/analysis/MethodInheritanceTreeNode.java b/src/main/java/cuchaz/enigma/analysis/MethodInheritanceTreeNode.java
index a3bed6ed..63837830 100644
--- a/src/main/java/cuchaz/enigma/analysis/MethodInheritanceTreeNode.java
+++ b/src/main/java/cuchaz/enigma/analysis/MethodInheritanceTreeNode.java
@@ -79,9 +79,7 @@ public class MethodInheritanceTreeNode extends DefaultMutableTreeNode {
79 } 79 }
80 80
81 // add them to this node 81 // add them to this node
82 for (MethodInheritanceTreeNode node : nodes) { 82 nodes.forEach(this::add);
83 this.add(node);
84 }
85 83
86 if (recurse) { 84 if (recurse) {
87 for (MethodInheritanceTreeNode node : nodes) { 85 for (MethodInheritanceTreeNode node : nodes) {
diff --git a/src/main/java/cuchaz/enigma/analysis/RelatedMethodChecker.java b/src/main/java/cuchaz/enigma/analysis/RelatedMethodChecker.java
deleted file mode 100644
index 08e2dbf0..00000000
--- a/src/main/java/cuchaz/enigma/analysis/RelatedMethodChecker.java
+++ /dev/null
@@ -1,104 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Lesser General Public
5 * License v3.0 which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/lgpl.html
7 * <p>
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.analysis;
12
13import com.google.common.collect.Maps;
14import com.google.common.collect.Sets;
15
16import java.util.Map;
17import java.util.Set;
18
19import cuchaz.enigma.mapping.*;
20
21public class RelatedMethodChecker {
22
23 private JarIndex m_jarIndex;
24 private Map<Set<MethodEntry>, String> m_deobfNamesByGroup;
25 private Map<MethodEntry, String> m_deobfNamesByObfMethod;
26 private Map<MethodEntry, Set<MethodEntry>> m_groupsByObfMethod;
27 private Set<Set<MethodEntry>> m_inconsistentGroups;
28
29 public RelatedMethodChecker(JarIndex jarIndex) {
30 m_jarIndex = jarIndex;
31 m_deobfNamesByGroup = Maps.newHashMap();
32 m_deobfNamesByObfMethod = Maps.newHashMap();
33 m_groupsByObfMethod = Maps.newHashMap();
34 m_inconsistentGroups = Sets.newHashSet();
35 }
36
37 public void checkMethod(ClassEntry classEntry, MethodMapping methodMapping) {
38
39 // TEMP: disable the expensive check for now, maybe we can optimize it later, or just use it for debugging
40 if (true) {
41 return;
42 }
43
44 BehaviorEntry obfBehaviorEntry = EntryFactory.getObfBehaviorEntry(classEntry, methodMapping);
45 if (!(obfBehaviorEntry instanceof MethodEntry)) {
46 // only methods have related implementations
47 return;
48 }
49 MethodEntry obfMethodEntry = (MethodEntry) obfBehaviorEntry;
50 String deobfName = methodMapping.getDeobfName();
51 m_deobfNamesByObfMethod.put(obfMethodEntry, deobfName);
52
53 // have we seen this method's group before?
54 Set<MethodEntry> group = m_groupsByObfMethod.get(obfMethodEntry);
55 if (group == null) {
56
57 // no, compute the group and save the name
58 group = m_jarIndex.getRelatedMethodImplementations(obfMethodEntry);
59 m_deobfNamesByGroup.put(group, deobfName);
60
61 assert (group.contains(obfMethodEntry));
62 for (MethodEntry relatedMethodEntry : group) {
63 m_groupsByObfMethod.put(relatedMethodEntry, group);
64 }
65 }
66
67 // check the name
68 if (!sameName(m_deobfNamesByGroup.get(group), deobfName)) {
69 m_inconsistentGroups.add(group);
70 }
71 }
72
73 private boolean sameName(String a, String b) {
74 if (a == null && b == null) {
75 return true;
76 } else if (a != null && b != null) {
77 return a.equals(b);
78 }
79 return false;
80 }
81
82 public boolean hasProblems() {
83 return m_inconsistentGroups.size() > 0;
84 }
85
86 public String getReport() {
87 StringBuilder buf = new StringBuilder();
88 buf.append(m_inconsistentGroups.size());
89 buf.append(" groups of methods related by inheritance and/or interfaces have different deobf names!\n");
90 for (Set<MethodEntry> group : m_inconsistentGroups) {
91 buf.append("\tGroup with ");
92 buf.append(group.size());
93 buf.append(" methods:\n");
94 for (MethodEntry methodEntry : group) {
95 buf.append("\t\t");
96 buf.append(methodEntry.toString());
97 buf.append(" => ");
98 buf.append(m_deobfNamesByObfMethod.get(methodEntry));
99 buf.append("\n");
100 }
101 }
102 return buf.toString();
103 }
104}
diff --git a/src/main/java/cuchaz/enigma/analysis/SourceIndex.java b/src/main/java/cuchaz/enigma/analysis/SourceIndex.java
index cbc2945c..719930e9 100644
--- a/src/main/java/cuchaz/enigma/analysis/SourceIndex.java
+++ b/src/main/java/cuchaz/enigma/analysis/SourceIndex.java
@@ -98,7 +98,7 @@ public class SourceIndex {
98 public void addReference(AstNode node, Entry deobfEntry, Entry deobfContext) { 98 public void addReference(AstNode node, Entry deobfEntry, Entry deobfContext) {
99 Token token = getToken(node); 99 Token token = getToken(node);
100 if (token != null) { 100 if (token != null) {
101 EntryReference<Entry, Entry> deobfReference = new EntryReference<Entry, Entry>(deobfEntry, token.text, deobfContext); 101 EntryReference<Entry, Entry> deobfReference = new EntryReference<>(deobfEntry, token.text, deobfContext);
102 this.tokenToReference.put(token, deobfReference); 102 this.tokenToReference.put(token, deobfReference);
103 this.referenceToTokens.put(deobfReference, token); 103 this.referenceToTokens.put(deobfReference, token);
104 } 104 }
@@ -107,7 +107,7 @@ public class SourceIndex {
107 public void addDeclaration(AstNode node, Entry deobfEntry) { 107 public void addDeclaration(AstNode node, Entry deobfEntry) {
108 Token token = getToken(node); 108 Token token = getToken(node);
109 if (token != null) { 109 if (token != null) {
110 EntryReference<Entry, Entry> reference = new EntryReference<Entry, Entry>(deobfEntry, token.text); 110 EntryReference<Entry, Entry> reference = new EntryReference<>(deobfEntry, token.text);
111 this.tokenToReference.put(token, reference); 111 this.tokenToReference.put(token, reference);
112 this.referenceToTokens.put(reference, token); 112 this.referenceToTokens.put(reference, token);
113 this.declarationToToken.put(deobfEntry, token); 113 this.declarationToToken.put(deobfEntry, token);
diff --git a/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java b/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java
index f020ae2c..adb87b6f 100644
--- a/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java
+++ b/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java
@@ -119,7 +119,7 @@ public class TranslationIndex implements Serializable {
119 119
120 public void renameClasses(Map<String, String> renames) { 120 public void renameClasses(Map<String, String> renames) {
121 EntryRenamer.renameClassesInMap(renames, this.superclasses); 121 EntryRenamer.renameClassesInMap(renames, this.superclasses);
122 EntryRenamer.renameClassesInMultimap(renames,this.fieldEntries); 122 EntryRenamer.renameClassesInMultimap(renames, this.fieldEntries);
123 EntryRenamer.renameClassesInMultimap(renames, this.behaviorEntries); 123 EntryRenamer.renameClassesInMultimap(renames, this.behaviorEntries);
124 } 124 }
125 125
diff --git a/src/main/java/cuchaz/enigma/bytecode/InfoType.java b/src/main/java/cuchaz/enigma/bytecode/InfoType.java
index 86e57ab5..bd9e7d1a 100644
--- a/src/main/java/cuchaz/enigma/bytecode/InfoType.java
+++ b/src/main/java/cuchaz/enigma/bytecode/InfoType.java
@@ -253,10 +253,7 @@ public enum InfoType {
253 253
254 public boolean selfIndexIsValid(ConstInfoAccessor entry, ConstPoolEditor pool) { 254 public boolean selfIndexIsValid(ConstInfoAccessor entry, ConstPoolEditor pool) {
255 ConstInfoAccessor entryCheck = pool.getItem(entry.getIndex()); 255 ConstInfoAccessor entryCheck = pool.getItem(entry.getIndex());
256 if (entryCheck == null) { 256 return entryCheck != null && entryCheck.getItem().equals(entry.getItem());
257 return false;
258 }
259 return entryCheck.getItem().equals(entry.getItem());
260 } 257 }
261 258
262 public static InfoType getByTag(int tag) { 259 public static InfoType getByTag(int tag) {
diff --git a/src/main/java/cuchaz/enigma/bytecode/MethodParameterWriter.java b/src/main/java/cuchaz/enigma/bytecode/MethodParameterWriter.java
index 17ecbbe9..28ad04ad 100644
--- a/src/main/java/cuchaz/enigma/bytecode/MethodParameterWriter.java
+++ b/src/main/java/cuchaz/enigma/bytecode/MethodParameterWriter.java
@@ -54,7 +54,7 @@ public class MethodParameterWriter {
54 } 54 }
55 55
56 // get the list of argument names 56 // get the list of argument names
57 List<String> names = new ArrayList<String>(numParams); 57 List<String> names = new ArrayList<>(numParams);
58 for (int i = 0; i < numParams; i++) { 58 for (int i = 0; i < numParams; i++) {
59 names.add(this.translator.translate(new ArgumentEntry(behaviorEntry, i, ""))); 59 names.add(this.translator.translate(new ArgumentEntry(behaviorEntry, i, "")));
60 } 60 }
diff --git a/src/main/java/cuchaz/enigma/bytecode/MethodParametersAttribute.java b/src/main/java/cuchaz/enigma/bytecode/MethodParametersAttribute.java
index ee7ed874..bace3a0d 100644
--- a/src/main/java/cuchaz/enigma/bytecode/MethodParametersAttribute.java
+++ b/src/main/java/cuchaz/enigma/bytecode/MethodParametersAttribute.java
@@ -30,7 +30,7 @@ public class MethodParametersAttribute extends AttributeInfo {
30 30
31 // add the names to the class const pool 31 // add the names to the class const pool
32 ConstPool constPool = info.getConstPool(); 32 ConstPool constPool = info.getConstPool();
33 List<Integer> parameterNameIndices = new ArrayList<Integer>(); 33 List<Integer> parameterNameIndices = new ArrayList<>();
34 for (String name : names) { 34 for (String name : names) {
35 if (name != null) { 35 if (name != null) {
36 parameterNameIndices.add(constPool.addUtf8Info(name)); 36 parameterNameIndices.add(constPool.addUtf8Info(name));
diff --git a/src/main/java/cuchaz/enigma/convert/ClassIdentity.java b/src/main/java/cuchaz/enigma/convert/ClassIdentity.java
index 2317a3d9..606c1df1 100644
--- a/src/main/java/cuchaz/enigma/convert/ClassIdentity.java
+++ b/src/main/java/cuchaz/enigma/convert/ClassIdentity.java
@@ -58,7 +58,7 @@ public class ClassIdentity {
58 58
59 // classes not in the none package can be passed through 59 // classes not in the none package can be passed through
60 ClassEntry classEntry = new ClassEntry(className); 60 ClassEntry classEntry = new ClassEntry(className);
61 if (!classEntry.getPackageName().equals(Constants.NonePackage)) { 61 if (!classEntry.getPackageName().equals(Constants.NONE_PACKAGE)) {
62 return className; 62 return className;
63 } 63 }
64 64
diff --git a/src/main/java/cuchaz/enigma/convert/ClassMatches.java b/src/main/java/cuchaz/enigma/convert/ClassMatches.java
index 3a254357..0b7e8034 100644
--- a/src/main/java/cuchaz/enigma/convert/ClassMatches.java
+++ b/src/main/java/cuchaz/enigma/convert/ClassMatches.java
@@ -45,9 +45,7 @@ public class ClassMatches implements Iterable<ClassMatch> {
45 m_unmatchedSourceClasses = Sets.newHashSet(); 45 m_unmatchedSourceClasses = Sets.newHashSet();
46 m_unmatchedDestClasses = Sets.newHashSet(); 46 m_unmatchedDestClasses = Sets.newHashSet();
47 47
48 for (ClassMatch match : matches) { 48 matches.forEach(this::indexMatch);
49 indexMatch(match);
50 }
51 } 49 }
52 50
53 public void add(ClassMatch match) { 51 public void add(ClassMatch match) {
diff --git a/src/main/java/cuchaz/enigma/convert/ClassMatching.java b/src/main/java/cuchaz/enigma/convert/ClassMatching.java
index 9350ea7f..194b6c4a 100644
--- a/src/main/java/cuchaz/enigma/convert/ClassMatching.java
+++ b/src/main/java/cuchaz/enigma/convert/ClassMatching.java
@@ -55,23 +55,14 @@ public class ClassMatching {
55 public Collection<ClassMatch> matches() { 55 public Collection<ClassMatch> matches() {
56 List<ClassMatch> matches = Lists.newArrayList(); 56 List<ClassMatch> matches = Lists.newArrayList();
57 for (Entry<ClassEntry, ClassEntry> entry : m_knownMatches.entrySet()) { 57 for (Entry<ClassEntry, ClassEntry> entry : m_knownMatches.entrySet()) {
58 matches.add(new ClassMatch( 58 matches.add(new ClassMatch(entry.getKey(), entry.getValue()));
59 entry.getKey(),
60 entry.getValue()
61 ));
62 } 59 }
63 for (ClassIdentity identity : m_sourceClasses.identities()) { 60 for (ClassIdentity identity : m_sourceClasses.identities()) {
64 matches.add(new ClassMatch( 61 matches.add(new ClassMatch(m_sourceClasses.getClasses(identity), m_destClasses.getClasses(identity)));
65 m_sourceClasses.getClasses(identity),
66 m_destClasses.getClasses(identity)
67 ));
68 } 62 }
69 for (ClassIdentity identity : m_destClasses.identities()) { 63 for (ClassIdentity identity : m_destClasses.identities()) {
70 if (!m_sourceClasses.containsIdentity(identity)) { 64 if (!m_sourceClasses.containsIdentity(identity)) {
71 matches.add(new ClassMatch( 65 matches.add(new ClassMatch(new ArrayList<>(), m_destClasses.getClasses(identity)));
72 new ArrayList<>(),
73 m_destClasses.getClasses(identity)
74 ));
75 } 66 }
76 } 67 }
77 return matches; 68 return matches;
diff --git a/src/main/java/cuchaz/enigma/convert/FieldMatches.java b/src/main/java/cuchaz/enigma/convert/FieldMatches.java
deleted file mode 100644
index 0899cd2e..00000000
--- a/src/main/java/cuchaz/enigma/convert/FieldMatches.java
+++ /dev/null
@@ -1,151 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Lesser General Public
5 * License v3.0 which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/lgpl.html
7 * <p>
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.convert;
12
13import com.google.common.collect.*;
14
15import java.util.Collection;
16import java.util.Set;
17
18import cuchaz.enigma.mapping.ClassEntry;
19import cuchaz.enigma.mapping.FieldEntry;
20
21
22public class FieldMatches {
23
24 private BiMap<FieldEntry, FieldEntry> m_matches;
25 private Multimap<ClassEntry, FieldEntry> m_matchedSourceFields;
26 private Multimap<ClassEntry, FieldEntry> m_unmatchedSourceFields;
27 private Multimap<ClassEntry, FieldEntry> m_unmatchedDestFields;
28 private Multimap<ClassEntry, FieldEntry> m_unmatchableSourceFields;
29
30 public FieldMatches() {
31 m_matches = HashBiMap.create();
32 m_matchedSourceFields = HashMultimap.create();
33 m_unmatchedSourceFields = HashMultimap.create();
34 m_unmatchedDestFields = HashMultimap.create();
35 m_unmatchableSourceFields = HashMultimap.create();
36 }
37
38 public void addMatch(FieldEntry srcField, FieldEntry destField) {
39 boolean wasAdded = m_matches.put(srcField, destField) == null;
40 assert (wasAdded);
41 wasAdded = m_matchedSourceFields.put(srcField.getClassEntry(), srcField);
42 assert (wasAdded);
43 }
44
45 public void addUnmatchedSourceField(FieldEntry fieldEntry) {
46 boolean wasAdded = m_unmatchedSourceFields.put(fieldEntry.getClassEntry(), fieldEntry);
47 assert (wasAdded);
48 }
49
50 public void addUnmatchedSourceFields(Iterable<FieldEntry> fieldEntries) {
51 for (FieldEntry fieldEntry : fieldEntries) {
52 addUnmatchedSourceField(fieldEntry);
53 }
54 }
55
56 public void addUnmatchedDestField(FieldEntry fieldEntry) {
57 boolean wasAdded = m_unmatchedDestFields.put(fieldEntry.getClassEntry(), fieldEntry);
58 assert (wasAdded);
59 }
60
61 public void addUnmatchedDestFields(Iterable<FieldEntry> fieldEntries) {
62 for (FieldEntry fieldEntry : fieldEntries) {
63 addUnmatchedDestField(fieldEntry);
64 }
65 }
66
67 public void addUnmatchableSourceField(FieldEntry sourceField) {
68 boolean wasAdded = m_unmatchableSourceFields.put(sourceField.getClassEntry(), sourceField);
69 assert (wasAdded);
70 }
71
72 public Set<ClassEntry> getSourceClassesWithUnmatchedFields() {
73 return m_unmatchedSourceFields.keySet();
74 }
75
76 public Collection<ClassEntry> getSourceClassesWithoutUnmatchedFields() {
77 Set<ClassEntry> out = Sets.newHashSet();
78 out.addAll(m_matchedSourceFields.keySet());
79 out.removeAll(m_unmatchedSourceFields.keySet());
80 return out;
81 }
82
83 public Collection<FieldEntry> getUnmatchedSourceFields() {
84 return m_unmatchedSourceFields.values();
85 }
86
87 public Collection<FieldEntry> getUnmatchedSourceFields(ClassEntry sourceClass) {
88 return m_unmatchedSourceFields.get(sourceClass);
89 }
90
91 public Collection<FieldEntry> getUnmatchedDestFields() {
92 return m_unmatchedDestFields.values();
93 }
94
95 public Collection<FieldEntry> getUnmatchedDestFields(ClassEntry destClass) {
96 return m_unmatchedDestFields.get(destClass);
97 }
98
99 public Collection<FieldEntry> getUnmatchableSourceFields() {
100 return m_unmatchableSourceFields.values();
101 }
102
103 public boolean hasSource(FieldEntry fieldEntry) {
104 return m_matches.containsKey(fieldEntry) || m_unmatchedSourceFields.containsValue(fieldEntry);
105 }
106
107 public boolean hasDest(FieldEntry fieldEntry) {
108 return m_matches.containsValue(fieldEntry) || m_unmatchedDestFields.containsValue(fieldEntry);
109 }
110
111 public BiMap<FieldEntry, FieldEntry> matches() {
112 return m_matches;
113 }
114
115 public boolean isMatchedSourceField(FieldEntry sourceField) {
116 return m_matches.containsKey(sourceField);
117 }
118
119 public boolean isMatchedDestField(FieldEntry destField) {
120 return m_matches.containsValue(destField);
121 }
122
123 public void makeMatch(FieldEntry sourceField, FieldEntry destField) {
124 boolean wasRemoved = m_unmatchedSourceFields.remove(sourceField.getClassEntry(), sourceField);
125 assert (wasRemoved);
126 wasRemoved = m_unmatchedDestFields.remove(destField.getClassEntry(), destField);
127 assert (wasRemoved);
128 addMatch(sourceField, destField);
129 }
130
131 public boolean isMatched(FieldEntry sourceField, FieldEntry destField) {
132 FieldEntry match = m_matches.get(sourceField);
133 return match != null && match.equals(destField);
134 }
135
136 public void unmakeMatch(FieldEntry sourceField, FieldEntry destField) {
137 boolean wasRemoved = m_matches.remove(sourceField) != null;
138 assert (wasRemoved);
139 wasRemoved = m_matchedSourceFields.remove(sourceField.getClassEntry(), sourceField);
140 assert (wasRemoved);
141 addUnmatchedSourceField(sourceField);
142 addUnmatchedDestField(destField);
143 }
144
145 public void makeSourceUnmatchable(FieldEntry sourceField) {
146 assert (!isMatchedSourceField(sourceField));
147 boolean wasRemoved = m_unmatchedSourceFields.remove(sourceField.getClassEntry(), sourceField);
148 assert (wasRemoved);
149 addUnmatchableSourceField(sourceField);
150 }
151}
diff --git a/src/main/java/cuchaz/enigma/convert/MappingsConverter.java b/src/main/java/cuchaz/enigma/convert/MappingsConverter.java
index 394b8c81..d1daadb0 100644
--- a/src/main/java/cuchaz/enigma/convert/MappingsConverter.java
+++ b/src/main/java/cuchaz/enigma/convert/MappingsConverter.java
@@ -151,7 +151,9 @@ public class MappingsConverter {
151 } 151 }
152 } 152 }
153 } 153 }
154 destMapping.addInnerClassMapping(migrateClassMapping(obfDestClassEntry, sourceMapping, matches, true)); 154 if (destMapping != null) {
155 destMapping.addInnerClassMapping(migrateClassMapping(obfDestClassEntry, sourceMapping, matches, true));
156 }
155 } 157 }
156 } 158 }
157 } 159 }
@@ -160,15 +162,12 @@ public class MappingsConverter {
160 162
161 private static ClassMapping migrateClassMapping(ClassEntry newObfClass, ClassMapping oldClassMapping, final ClassMatches matches, boolean useSimpleName) { 163 private static ClassMapping migrateClassMapping(ClassEntry newObfClass, ClassMapping oldClassMapping, final ClassMatches matches, boolean useSimpleName) {
162 164
163 ClassNameReplacer replacer = new ClassNameReplacer() { 165 ClassNameReplacer replacer = className -> {
164 @Override 166 ClassEntry newClassEntry = matches.getUniqueMatches().get(new ClassEntry(className));
165 public String replace(String className) { 167 if (newClassEntry != null) {
166 ClassEntry newClassEntry = matches.getUniqueMatches().get(new ClassEntry(className)); 168 return newClassEntry.getName();
167 if (newClassEntry != null) {
168 return newClassEntry.getName();
169 }
170 return null;
171 } 169 }
170 return null;
172 }; 171 };
173 172
174 ClassMapping newClassMapping; 173 ClassMapping newClassMapping;
@@ -229,7 +228,7 @@ public class MappingsConverter {
229 228
230 // non obfuscated classes can be migrated 229 // non obfuscated classes can be migrated
231 ClassEntry classEntry = oldObfType.getClassEntry(); 230 ClassEntry classEntry = oldObfType.getClassEntry();
232 if (!classEntry.getPackageName().equals(Constants.NonePackage)) { 231 if (!classEntry.getPackageName().equals(Constants.NONE_PACKAGE)) {
233 return true; 232 return true;
234 } 233 }
235 234
@@ -390,7 +389,7 @@ public class MappingsConverter {
390 389
391 public static <T extends Entry> MemberMatches<T> computeMemberMatches(Deobfuscator destDeobfuscator, Mappings destMappings, ClassMatches classMatches, Doer<T> doer) { 390 public static <T extends Entry> MemberMatches<T> computeMemberMatches(Deobfuscator destDeobfuscator, Mappings destMappings, ClassMatches classMatches, Doer<T> doer) {
392 391
393 MemberMatches<T> memberMatches = new MemberMatches<T>(); 392 MemberMatches<T> memberMatches = new MemberMatches<>();
394 393
395 // unmatched source fields are easy 394 // unmatched source fields are easy
396 MappingsChecker checker = new MappingsChecker(destDeobfuscator.getJarIndex()); 395 MappingsChecker checker = new MappingsChecker(destDeobfuscator.getJarIndex());
@@ -481,15 +480,12 @@ public class MappingsConverter {
481 } 480 }
482 481
483 private static Type translate(Type type, final BiMap<ClassEntry, ClassEntry> map) { 482 private static Type translate(Type type, final BiMap<ClassEntry, ClassEntry> map) {
484 return new Type(type, new ClassNameReplacer() { 483 return new Type(type, inClassName -> {
485 @Override 484 ClassEntry outClassEntry = map.get(new ClassEntry(inClassName));
486 public String replace(String inClassName) { 485 if (outClassEntry == null) {
487 ClassEntry outClassEntry = map.get(new ClassEntry(inClassName)); 486 return null;
488 if (outClassEntry == null) {
489 return null;
490 }
491 return outClassEntry.getName();
492 } 487 }
488 return outClassEntry.getName();
493 }); 489 });
494 } 490 }
495 491
@@ -497,15 +493,12 @@ public class MappingsConverter {
497 if (signature == null) { 493 if (signature == null) {
498 return null; 494 return null;
499 } 495 }
500 return new Signature(signature, new ClassNameReplacer() { 496 return new Signature(signature, inClassName -> {
501 @Override 497 ClassEntry outClassEntry = map.get(new ClassEntry(inClassName));
502 public String replace(String inClassName) { 498 if (outClassEntry == null) {
503 ClassEntry outClassEntry = map.get(new ClassEntry(inClassName)); 499 return null;
504 if (outClassEntry == null) {
505 return null;
506 }
507 return outClassEntry.getName();
508 } 500 }
501 return outClassEntry.getName();
509 }); 502 });
510 } 503 }
511 504
diff --git a/src/main/java/cuchaz/enigma/convert/MatchesReader.java b/src/main/java/cuchaz/enigma/convert/MatchesReader.java
index 773566df..f7853acf 100644
--- a/src/main/java/cuchaz/enigma/convert/MatchesReader.java
+++ b/src/main/java/cuchaz/enigma/convert/MatchesReader.java
@@ -28,7 +28,7 @@ public class MatchesReader {
28 throws IOException { 28 throws IOException {
29 try (BufferedReader in = new BufferedReader(new FileReader(file))) { 29 try (BufferedReader in = new BufferedReader(new FileReader(file))) {
30 ClassMatches matches = new ClassMatches(); 30 ClassMatches matches = new ClassMatches();
31 String line = null; 31 String line;
32 while ((line = in.readLine()) != null) { 32 while ((line = in.readLine()) != null) {
33 matches.add(readClassMatch(line)); 33 matches.add(readClassMatch(line));
34 } 34 }
@@ -56,8 +56,8 @@ public class MatchesReader {
56 public static <T extends Entry> MemberMatches<T> readMembers(File file) 56 public static <T extends Entry> MemberMatches<T> readMembers(File file)
57 throws IOException { 57 throws IOException {
58 try (BufferedReader in = new BufferedReader(new FileReader(file))) { 58 try (BufferedReader in = new BufferedReader(new FileReader(file))) {
59 MemberMatches<T> matches = new MemberMatches<T>(); 59 MemberMatches<T> matches = new MemberMatches<>();
60 String line = null; 60 String line;
61 while ((line = in.readLine()) != null) { 61 while ((line = in.readLine()) != null) {
62 readMemberMatch(matches, line); 62 readMemberMatch(matches, line);
63 } 63 }
@@ -90,13 +90,8 @@ public class MatchesReader {
90 } 90 }
91 String[] parts = in.split(" "); 91 String[] parts = in.split(" ");
92 if (parts.length == 3 && parts[2].indexOf('(') < 0) { 92 if (parts.length == 3 && parts[2].indexOf('(') < 0) {
93 return (T) new FieldEntry( 93 return (T) new FieldEntry(new ClassEntry(parts[0]), parts[1], new Type(parts[2]));
94 new ClassEntry(parts[0]),
95 parts[1],
96 new Type(parts[2])
97 );
98 } else { 94 } else {
99 assert (parts.length == 2 || parts.length == 3);
100 if (parts.length == 2) { 95 if (parts.length == 2) {
101 return (T) EntryFactory.getBehaviorEntry(parts[0], parts[1]); 96 return (T) EntryFactory.getBehaviorEntry(parts[0], parts[1]);
102 } else if (parts.length == 3) { 97 } else if (parts.length == 3) {
diff --git a/src/main/java/cuchaz/enigma/gui/AboutDialog.java b/src/main/java/cuchaz/enigma/gui/AboutDialog.java
index a8743998..bb12466f 100644
--- a/src/main/java/cuchaz/enigma/gui/AboutDialog.java
+++ b/src/main/java/cuchaz/enigma/gui/AboutDialog.java
@@ -25,14 +25,14 @@ public class AboutDialog {
25 25
26 public static void show(JFrame parent) { 26 public static void show(JFrame parent) {
27 // init frame 27 // init frame
28 final JFrame frame = new JFrame(Constants.Name + " - About"); 28 final JFrame frame = new JFrame(Constants.NAME + " - About");
29 final Container pane = frame.getContentPane(); 29 final Container pane = frame.getContentPane();
30 pane.setLayout(new FlowLayout()); 30 pane.setLayout(new FlowLayout());
31 31
32 // load the content 32 // load the content
33 try { 33 try {
34 String html = Util.readResourceToString("/about.html"); 34 String html = Util.readResourceToString("/about.html");
35 html = String.format(html, Constants.Name, Constants.Version); 35 html = String.format(html, Constants.NAME, Constants.VERSION);
36 JLabel label = new JLabel(html); 36 JLabel label = new JLabel(html);
37 label.setHorizontalAlignment(JLabel.CENTER); 37 label.setHorizontalAlignment(JLabel.CENTER);
38 pane.add(label); 38 pane.add(label);
@@ -42,9 +42,9 @@ public class AboutDialog {
42 42
43 // show the link 43 // show the link
44 String html = "<html><a href=\"%s\">%s</a></html>"; 44 String html = "<html><a href=\"%s\">%s</a></html>";
45 html = String.format(html, Constants.Url, Constants.Url); 45 html = String.format(html, Constants.URL, Constants.URL);
46 JButton link = new JButton(html); 46 JButton link = new JButton(html);
47 link.addActionListener(event -> Util.openUrl(Constants.Url)); 47 link.addActionListener(event -> Util.openUrl(Constants.URL));
48 link.setBorderPainted(false); 48 link.setBorderPainted(false);
49 link.setOpaque(false); 49 link.setOpaque(false);
50 link.setBackground(Color.WHITE); 50 link.setBackground(Color.WHITE);
diff --git a/src/main/java/cuchaz/enigma/gui/BoxHighlightPainter.java b/src/main/java/cuchaz/enigma/gui/BoxHighlightPainter.java
index efe6b506..b66d13da 100644
--- a/src/main/java/cuchaz/enigma/gui/BoxHighlightPainter.java
+++ b/src/main/java/cuchaz/enigma/gui/BoxHighlightPainter.java
@@ -21,12 +21,12 @@ import javax.swing.text.JTextComponent;
21 21
22public abstract class BoxHighlightPainter implements Highlighter.HighlightPainter { 22public abstract class BoxHighlightPainter implements Highlighter.HighlightPainter {
23 23
24 private Color m_fillColor; 24 private Color fillColor;
25 private Color m_borderColor; 25 private Color borderColor;
26 26
27 protected BoxHighlightPainter(Color fillColor, Color borderColor) { 27 protected BoxHighlightPainter(Color fillColor, Color borderColor) {
28 m_fillColor = fillColor; 28 this.fillColor = fillColor;
29 m_borderColor = borderColor; 29 this.borderColor = borderColor;
30 } 30 }
31 31
32 @Override 32 @Override
@@ -34,17 +34,17 @@ public abstract class BoxHighlightPainter implements Highlighter.HighlightPainte
34 Rectangle bounds = getBounds(text, start, end); 34 Rectangle bounds = getBounds(text, start, end);
35 35
36 // fill the area 36 // fill the area
37 if (m_fillColor != null) { 37 if (this.fillColor != null) {
38 g.setColor(m_fillColor); 38 g.setColor(this.fillColor);
39 g.fillRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 4, 4); 39 g.fillRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 4, 4);
40 } 40 }
41 41
42 // draw a box around the area 42 // draw a box around the area
43 g.setColor(m_borderColor); 43 g.setColor(this.borderColor);
44 g.drawRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 4, 4); 44 g.drawRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 4, 4);
45 } 45 }
46 46
47 protected static Rectangle getBounds(JTextComponent text, int start, int end) { 47 public static Rectangle getBounds(JTextComponent text, int start, int end) {
48 try { 48 try {
49 // determine the bounds of the text 49 // determine the bounds of the text
50 Rectangle bounds = text.modelToView(start).union(text.modelToView(end)); 50 Rectangle bounds = text.modelToView(start).union(text.modelToView(end));
diff --git a/src/main/java/cuchaz/enigma/gui/BrowserCaret.java b/src/main/java/cuchaz/enigma/gui/BrowserCaret.java
index b4acbce9..094b69b2 100644
--- a/src/main/java/cuchaz/enigma/gui/BrowserCaret.java
+++ b/src/main/java/cuchaz/enigma/gui/BrowserCaret.java
@@ -17,8 +17,7 @@ public class BrowserCaret extends DefaultCaret {
17 17
18 private static final long serialVersionUID = 1158977422507969940L; 18 private static final long serialVersionUID = 1158977422507969940L;
19 19
20 private static final Highlighter.HighlightPainter m_selectionPainter = (g, p0, p1, bounds, c) -> { 20 private static final Highlighter.HighlightPainter selectionPainter = (g, p0, p1, bounds, c) -> {
21 // don't paint anything
22 }; 21 };
23 22
24 @Override 23 @Override
@@ -33,6 +32,6 @@ public class BrowserCaret extends DefaultCaret {
33 32
34 @Override 33 @Override
35 public Highlighter.HighlightPainter getSelectionPainter() { 34 public Highlighter.HighlightPainter getSelectionPainter() {
36 return m_selectionPainter; 35 return this.selectionPainter;
37 } 36 }
38} 37}
diff --git a/src/main/java/cuchaz/enigma/gui/ClassListCellRenderer.java b/src/main/java/cuchaz/enigma/gui/ClassListCellRenderer.java
deleted file mode 100644
index 89b9bdd4..00000000
--- a/src/main/java/cuchaz/enigma/gui/ClassListCellRenderer.java
+++ /dev/null
@@ -1,36 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Lesser General Public
5 * License v3.0 which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/lgpl.html
7 * <p>
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.gui;
12
13import java.awt.Component;
14
15import javax.swing.DefaultListCellRenderer;
16import javax.swing.JLabel;
17import javax.swing.JList;
18import javax.swing.ListCellRenderer;
19
20import javassist.bytecode.Descriptor;
21
22public class ClassListCellRenderer implements ListCellRenderer<String> {
23
24 private DefaultListCellRenderer m_defaultRenderer;
25
26 public ClassListCellRenderer() {
27 m_defaultRenderer = new DefaultListCellRenderer();
28 }
29
30 @Override
31 public Component getListCellRendererComponent(JList<? extends String> list, String className, int index, boolean isSelected, boolean hasFocus) {
32 JLabel label = (JLabel) m_defaultRenderer.getListCellRendererComponent(list, className, index, isSelected, hasFocus);
33 label.setText(Descriptor.toJavaName(className));
34 return label;
35 }
36}
diff --git a/src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java b/src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java
index 440565c3..a069bcac 100644
--- a/src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java
+++ b/src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java
@@ -77,35 +77,35 @@ public class ClassMatchingGui {
77 } 77 }
78 78
79 // controls 79 // controls
80 private JFrame m_frame; 80 private JFrame frame;
81 private ClassSelector m_sourceClasses; 81 private ClassSelector sourceClasses;
82 private ClassSelector m_destClasses; 82 private ClassSelector destClasses;
83 private CodeReader m_sourceReader; 83 private CodeReader sourceReader;
84 private CodeReader m_destReader; 84 private CodeReader destReader;
85 private JLabel m_sourceClassLabel; 85 private JLabel sourceClassLabel;
86 private JLabel m_destClassLabel; 86 private JLabel destClassLabel;
87 private JButton m_matchButton; 87 private JButton matchButton;
88 private Map<SourceType, JRadioButton> m_sourceTypeButtons; 88 private Map<SourceType, JRadioButton> sourceTypeButtons;
89 private JCheckBox m_advanceCheck; 89 private JCheckBox advanceCheck;
90 private JCheckBox m_top10Matches; 90 private JCheckBox top10Matches;
91 91
92 private ClassMatches m_classMatches; 92 private ClassMatches classMatches;
93 private Deobfuscator m_sourceDeobfuscator; 93 private Deobfuscator sourceDeobfuscator;
94 private Deobfuscator m_destDeobfuscator; 94 private Deobfuscator destDeobfuscator;
95 private ClassEntry m_sourceClass; 95 private ClassEntry sourceClass;
96 private ClassEntry m_destClass; 96 private ClassEntry destClass;
97 private SourceType m_sourceType; 97 private SourceType sourceType;
98 private SaveListener m_saveListener; 98 private SaveListener saveListener;
99 99
100 public ClassMatchingGui(ClassMatches matches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) { 100 public ClassMatchingGui(ClassMatches matches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) {
101 101
102 m_classMatches = matches; 102 this.classMatches = matches;
103 m_sourceDeobfuscator = sourceDeobfuscator; 103 this.sourceDeobfuscator = sourceDeobfuscator;
104 m_destDeobfuscator = destDeobfuscator; 104 this.destDeobfuscator = destDeobfuscator;
105 105
106 // init frame 106 // init frame
107 m_frame = new JFrame(Constants.Name + " - Class Matcher"); 107 this.frame = new JFrame(Constants.NAME + " - Class Matcher");
108 final Container pane = m_frame.getContentPane(); 108 final Container pane = this.frame.getContentPane();
109 pane.setLayout(new BorderLayout()); 109 pane.setLayout(new BorderLayout());
110 110
111 // init source side 111 // init source side
@@ -121,16 +121,16 @@ public class ClassMatchingGui {
121 sourceTypePanel.setLayout(new BoxLayout(sourceTypePanel, BoxLayout.PAGE_AXIS)); 121 sourceTypePanel.setLayout(new BoxLayout(sourceTypePanel, BoxLayout.PAGE_AXIS));
122 ActionListener sourceTypeListener = event -> setSourceType(SourceType.valueOf(event.getActionCommand())); 122 ActionListener sourceTypeListener = event -> setSourceType(SourceType.valueOf(event.getActionCommand()));
123 ButtonGroup sourceTypeButtons = new ButtonGroup(); 123 ButtonGroup sourceTypeButtons = new ButtonGroup();
124 m_sourceTypeButtons = Maps.newHashMap(); 124 this.sourceTypeButtons = Maps.newHashMap();
125 for (SourceType sourceType : SourceType.values()) { 125 for (SourceType sourceType : SourceType.values()) {
126 JRadioButton button = sourceType.newRadio(sourceTypeListener, sourceTypeButtons); 126 JRadioButton button = sourceType.newRadio(sourceTypeListener, sourceTypeButtons);
127 m_sourceTypeButtons.put(sourceType, button); 127 this.sourceTypeButtons.put(sourceType, button);
128 sourceTypePanel.add(button); 128 sourceTypePanel.add(button);
129 } 129 }
130 130
131 m_sourceClasses = new ClassSelector(ClassSelector.DeobfuscatedClassEntryComparator); 131 this.sourceClasses = new ClassSelector(ClassSelector.DeobfuscatedClassEntryComparator);
132 m_sourceClasses.setListener(classEntry -> setSourceClass(classEntry)); 132 this.sourceClasses.setListener(this::setSourceClass);
133 JScrollPane sourceScroller = new JScrollPane(m_sourceClasses); 133 JScrollPane sourceScroller = new JScrollPane(this.sourceClasses);
134 sourcePanel.add(sourceScroller); 134 sourcePanel.add(sourceScroller);
135 135
136 // init dest side 136 // init dest side
@@ -140,13 +140,13 @@ public class ClassMatchingGui {
140 pane.add(destPanel, BorderLayout.WEST); 140 pane.add(destPanel, BorderLayout.WEST);
141 destPanel.add(new JLabel("Destination Classes")); 141 destPanel.add(new JLabel("Destination Classes"));
142 142
143 m_top10Matches = new JCheckBox("Show only top 10 matches"); 143 this.top10Matches = new JCheckBox("Show only top 10 matches");
144 destPanel.add(m_top10Matches); 144 destPanel.add(this.top10Matches);
145 m_top10Matches.addActionListener(event -> toggleTop10Matches()); 145 this.top10Matches.addActionListener(event -> toggleTop10Matches());
146 146
147 m_destClasses = new ClassSelector(ClassSelector.DeobfuscatedClassEntryComparator); 147 this.destClasses = new ClassSelector(ClassSelector.DeobfuscatedClassEntryComparator);
148 m_destClasses.setListener(this::setDestClass); 148 this.destClasses.setListener(this::setDestClass);
149 JScrollPane destScroller = new JScrollPane(m_destClasses); 149 JScrollPane destScroller = new JScrollPane(this.destClasses);
150 destPanel.add(destScroller); 150 destPanel.add(destScroller);
151 151
152 JButton autoMatchButton = new JButton("AutoMatch"); 152 JButton autoMatchButton = new JButton("AutoMatch");
@@ -155,13 +155,13 @@ public class ClassMatchingGui {
155 155
156 // init source panels 156 // init source panels
157 DefaultSyntaxKit.initKit(); 157 DefaultSyntaxKit.initKit();
158 m_sourceReader = new CodeReader(); 158 this.sourceReader = new CodeReader();
159 m_destReader = new CodeReader(); 159 this.destReader = new CodeReader();
160 160
161 // init all the splits 161 // init all the splits
162 JSplitPane splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, sourcePanel, new JScrollPane(m_sourceReader)); 162 JSplitPane splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, sourcePanel, new JScrollPane(this.sourceReader));
163 splitLeft.setResizeWeight(0); // let the right side take all the slack 163 splitLeft.setResizeWeight(0); // let the right side take all the slack
164 JSplitPane splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JScrollPane(m_destReader), destPanel); 164 JSplitPane splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JScrollPane(this.destReader), destPanel);
165 splitRight.setResizeWeight(1); // let the left side take all the slack 165 splitRight.setResizeWeight(1); // let the left side take all the slack
166 JSplitPane splitCenter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, splitLeft, splitRight); 166 JSplitPane splitCenter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, splitLeft, splitRight);
167 splitCenter.setResizeWeight(0.5); // resize 50:50 167 splitCenter.setResizeWeight(0.5); // resize 50:50
@@ -172,81 +172,75 @@ public class ClassMatchingGui {
172 JPanel bottomPanel = new JPanel(); 172 JPanel bottomPanel = new JPanel();
173 bottomPanel.setLayout(new FlowLayout()); 173 bottomPanel.setLayout(new FlowLayout());
174 174
175 m_sourceClassLabel = new JLabel(); 175 this.sourceClassLabel = new JLabel();
176 m_sourceClassLabel.setHorizontalAlignment(SwingConstants.RIGHT); 176 this.sourceClassLabel.setHorizontalAlignment(SwingConstants.RIGHT);
177 m_destClassLabel = new JLabel(); 177 this.destClassLabel = new JLabel();
178 m_destClassLabel.setHorizontalAlignment(SwingConstants.LEFT); 178 this.destClassLabel.setHorizontalAlignment(SwingConstants.LEFT);
179 179
180 m_matchButton = new JButton(); 180 this.matchButton = new JButton();
181 181
182 m_advanceCheck = new JCheckBox("Advance to next likely match"); 182 this.advanceCheck = new JCheckBox("Advance to next likely match");
183 m_advanceCheck.addActionListener(event -> { 183 this.advanceCheck.addActionListener(event -> {
184 if (m_advanceCheck.isSelected()) { 184 if (this.advanceCheck.isSelected()) {
185 advance(); 185 advance();
186 } 186 }
187 }); 187 });
188 188
189 bottomPanel.add(m_sourceClassLabel); 189 bottomPanel.add(this.sourceClassLabel);
190 bottomPanel.add(m_matchButton); 190 bottomPanel.add(this.matchButton);
191 bottomPanel.add(m_destClassLabel); 191 bottomPanel.add(this.destClassLabel);
192 bottomPanel.add(m_advanceCheck); 192 bottomPanel.add(this.advanceCheck);
193 pane.add(bottomPanel, BorderLayout.SOUTH); 193 pane.add(bottomPanel, BorderLayout.SOUTH);
194 194
195 // show the frame 195 // show the frame
196 pane.doLayout(); 196 pane.doLayout();
197 m_frame.setSize(1024, 576); 197 this.frame.setSize(1024, 576);
198 m_frame.setMinimumSize(new Dimension(640, 480)); 198 this.frame.setMinimumSize(new Dimension(640, 480));
199 m_frame.setVisible(true); 199 this.frame.setVisible(true);
200 m_frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 200 this.frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
201 201
202 // init state 202 // init state
203 updateDestMappings(); 203 updateDestMappings();
204 setSourceType(SourceType.getDefault()); 204 setSourceType(SourceType.getDefault());
205 updateMatchButton(); 205 updateMatchButton();
206 m_saveListener = null; 206 this.saveListener = null;
207 } 207 }
208 208
209 public void setSaveListener(SaveListener val) { 209 public void setSaveListener(SaveListener val) {
210 m_saveListener = val; 210 this.saveListener = val;
211 } 211 }
212 212
213 private void updateDestMappings() { 213 private void updateDestMappings() {
214 214
215 Mappings newMappings = MappingsConverter.newMappings( 215 Mappings newMappings = MappingsConverter.newMappings(this.classMatches, this.sourceDeobfuscator.getMappings(), this.sourceDeobfuscator, this.destDeobfuscator);
216 m_classMatches,
217 m_sourceDeobfuscator.getMappings(),
218 m_sourceDeobfuscator,
219 m_destDeobfuscator
220 );
221 216
222 // look for dropped mappings 217 // look for dropped mappings
223 MappingsChecker checker = new MappingsChecker(m_destDeobfuscator.getJarIndex()); 218 MappingsChecker checker = new MappingsChecker(this.destDeobfuscator.getJarIndex());
224 checker.dropBrokenMappings(newMappings); 219 checker.dropBrokenMappings(newMappings);
225 220
226 // count them 221 // count them
227 int numDroppedFields = checker.getDroppedFieldMappings().size(); 222 int numDroppedFields = checker.getDroppedFieldMappings().size();
228 int numDroppedMethods = checker.getDroppedMethodMappings().size(); 223 int numDroppedMethods = checker.getDroppedMethodMappings().size();
229 System.out.println(String.format( 224 System.out.println(String.format("%d mappings from matched classes don't match the dest jar:\n\t%5d fields\n\t%5d methods",
230 "%d mappings from matched classes don't match the dest jar:\n\t%5d fields\n\t%5d methods",
231 numDroppedFields + numDroppedMethods, 225 numDroppedFields + numDroppedMethods,
232 numDroppedFields, 226 numDroppedFields,
233 numDroppedMethods 227 numDroppedMethods
234 )); 228 ));
235 229
236 m_destDeobfuscator.setMappings(newMappings); 230 this.destDeobfuscator.setMappings(newMappings);
237 } 231 }
238 232
239 protected void setSourceType(SourceType val) { 233 protected void setSourceType(SourceType val) {
240 234
241 // show the source classes 235 // show the source classes
242 m_sourceType = val; 236 this.sourceType = val;
243 m_sourceClasses.setClasses(deobfuscateClasses(m_sourceType.getSourceClasses(m_classMatches), m_sourceDeobfuscator)); 237 this.sourceClasses.setClasses(deobfuscateClasses(this.sourceType.getSourceClasses(this.classMatches), this.sourceDeobfuscator));
244 238
245 // update counts 239 // update counts
246 for (SourceType sourceType : SourceType.values()) { 240 for (SourceType sourceType : SourceType.values()) {
247 m_sourceTypeButtons.get(sourceType).setText(String.format("%s (%d)", 241 this.sourceTypeButtons.get(sourceType).setText(String.format("%s (%d)",
248 sourceType.name(), 242 sourceType.name(),
249 sourceType.getSourceClasses(m_classMatches).size() 243 sourceType.getSourceClasses(this.classMatches).size()
250 )); 244 ));
251 } 245 }
252 } 246 }
@@ -270,7 +264,7 @@ public class ClassMatchingGui {
270 protected void setSourceClass(ClassEntry classEntry) { 264 protected void setSourceClass(ClassEntry classEntry) {
271 265
272 Runnable onGetDestClasses = null; 266 Runnable onGetDestClasses = null;
273 if (m_advanceCheck.isSelected()) { 267 if (this.advanceCheck.isSelected()) {
274 onGetDestClasses = this::pickBestDestClass; 268 onGetDestClasses = this::pickBestDestClass;
275 } 269 }
276 270
@@ -280,24 +274,24 @@ public class ClassMatchingGui {
280 protected void setSourceClass(ClassEntry classEntry, final Runnable onGetDestClasses) { 274 protected void setSourceClass(ClassEntry classEntry, final Runnable onGetDestClasses) {
281 275
282 // update the current source class 276 // update the current source class
283 m_sourceClass = classEntry; 277 this.sourceClass = classEntry;
284 m_sourceClassLabel.setText(m_sourceClass != null ? m_sourceClass.getName() : ""); 278 this.sourceClassLabel.setText(this.sourceClass != null ? this.sourceClass.getName() : "");
285 279
286 if (m_sourceClass != null) { 280 if (this.sourceClass != null) {
287 281
288 // show the dest class(es) 282 // show the dest class(es)
289 ClassMatch match = m_classMatches.getMatchBySource(m_sourceDeobfuscator.obfuscateEntry(m_sourceClass)); 283 ClassMatch match = this.classMatches.getMatchBySource(this.sourceDeobfuscator.obfuscateEntry(this.sourceClass));
290 assert (match != null); 284 assert (match != null);
291 if (match.destClasses.isEmpty()) { 285 if (match.destClasses.isEmpty()) {
292 286
293 m_destClasses.setClasses(null); 287 this.destClasses.setClasses(null);
294 288
295 // run in a separate thread to keep ui responsive 289 // run in a separate thread to keep ui responsive
296 new Thread() { 290 new Thread() {
297 @Override 291 @Override
298 public void run() { 292 public void run() {
299 m_destClasses.setClasses(deobfuscateClasses(getLikelyMatches(m_sourceClass), m_destDeobfuscator)); 293 destClasses.setClasses(deobfuscateClasses(getLikelyMatches(sourceClass), destDeobfuscator));
300 m_destClasses.expandAll(); 294 destClasses.expandAll();
301 295
302 if (onGetDestClasses != null) { 296 if (onGetDestClasses != null) {
303 onGetDestClasses.run(); 297 onGetDestClasses.run();
@@ -307,8 +301,8 @@ public class ClassMatchingGui {
307 301
308 } else { 302 } else {
309 303
310 m_destClasses.setClasses(deobfuscateClasses(match.destClasses, m_destDeobfuscator)); 304 this.destClasses.setClasses(deobfuscateClasses(match.destClasses, this.destDeobfuscator));
311 m_destClasses.expandAll(); 305 this.destClasses.expandAll();
312 306
313 if (onGetDestClasses != null) { 307 if (onGetDestClasses != null) {
314 onGetDestClasses.run(); 308 onGetDestClasses.run();
@@ -317,39 +311,33 @@ public class ClassMatchingGui {
317 } 311 }
318 312
319 setDestClass(null); 313 setDestClass(null);
320 m_sourceReader.decompileClass(m_sourceClass, m_sourceDeobfuscator, () -> m_sourceReader.navigateToClassDeclaration(m_sourceClass)); 314 this.sourceReader.decompileClass(this.sourceClass, this.sourceDeobfuscator, () -> this.sourceReader.navigateToClassDeclaration(this.sourceClass));
321 315
322 updateMatchButton(); 316 updateMatchButton();
323 } 317 }
324 318
325 private Collection<ClassEntry> getLikelyMatches(ClassEntry sourceClass) { 319 private Collection<ClassEntry> getLikelyMatches(ClassEntry sourceClass) {
326 320
327 ClassEntry obfSourceClass = m_sourceDeobfuscator.obfuscateEntry(sourceClass); 321 ClassEntry obfSourceClass = this.sourceDeobfuscator.obfuscateEntry(sourceClass);
328 322
329 // set up identifiers 323 // set up identifiers
330 ClassNamer namer = new ClassNamer(m_classMatches.getUniqueMatches()); 324 ClassNamer namer = new ClassNamer(this.classMatches.getUniqueMatches());
331 ClassIdentifier sourceIdentifier = new ClassIdentifier( 325 ClassIdentifier sourceIdentifier = new ClassIdentifier(this.sourceDeobfuscator.getJar(), this.sourceDeobfuscator.getJarIndex(), namer.getSourceNamer(), true);
332 m_sourceDeobfuscator.getJar(), m_sourceDeobfuscator.getJarIndex(), 326 ClassIdentifier destIdentifier = new ClassIdentifier(this.destDeobfuscator.getJar(), this.destDeobfuscator.getJarIndex(), namer.getDestNamer(), true);
333 namer.getSourceNamer(), true
334 );
335 ClassIdentifier destIdentifier = new ClassIdentifier(
336 m_destDeobfuscator.getJar(), m_destDeobfuscator.getJarIndex(),
337 namer.getDestNamer(), true
338 );
339 327
340 try { 328 try {
341 329
342 // rank all the unmatched dest classes against the source class 330 // rank all the unmatched dest classes against the source class
343 ClassIdentity sourceIdentity = sourceIdentifier.identify(obfSourceClass); 331 ClassIdentity sourceIdentity = sourceIdentifier.identify(obfSourceClass);
344 List<ClassEntry> scoredDestClasses = Lists.newArrayList(); 332 List<ClassEntry> scoredDestClasses = Lists.newArrayList();
345 for (ClassEntry unmatchedDestClass : m_classMatches.getUnmatchedDestClasses()) { 333 for (ClassEntry unmatchedDestClass : this.classMatches.getUnmatchedDestClasses()) {
346 ClassIdentity destIdentity = destIdentifier.identify(unmatchedDestClass); 334 ClassIdentity destIdentity = destIdentifier.identify(unmatchedDestClass);
347 float score = 100.0f * (sourceIdentity.getMatchScore(destIdentity) + destIdentity.getMatchScore(sourceIdentity)) 335 float score = 100.0f * (sourceIdentity.getMatchScore(destIdentity) + destIdentity.getMatchScore(sourceIdentity))
348 / (sourceIdentity.getMaxMatchScore() + destIdentity.getMaxMatchScore()); 336 / (sourceIdentity.getMaxMatchScore() + destIdentity.getMaxMatchScore());
349 scoredDestClasses.add(new ScoredClassEntry(unmatchedDestClass, score)); 337 scoredDestClasses.add(new ScoredClassEntry(unmatchedDestClass, score));
350 } 338 }
351 339
352 if (m_top10Matches.isSelected() && scoredDestClasses.size() > 10) { 340 if (this.top10Matches.isSelected() && scoredDestClasses.size() > 10) {
353 Collections.sort(scoredDestClasses, (a, b) -> { 341 Collections.sort(scoredDestClasses, (a, b) -> {
354 ScoredClassEntry sa = (ScoredClassEntry) a; 342 ScoredClassEntry sa = (ScoredClassEntry) a;
355 ScoredClassEntry sb = (ScoredClassEntry) b; 343 ScoredClassEntry sb = (ScoredClassEntry) b;
@@ -368,30 +356,30 @@ public class ClassMatchingGui {
368 protected void setDestClass(ClassEntry classEntry) { 356 protected void setDestClass(ClassEntry classEntry) {
369 357
370 // update the current source class 358 // update the current source class
371 m_destClass = classEntry; 359 this.destClass = classEntry;
372 m_destClassLabel.setText(m_destClass != null ? m_destClass.getName() : ""); 360 this.destClassLabel.setText(this.destClass != null ? this.destClass.getName() : "");
373 361
374 m_destReader.decompileClass(m_destClass, m_destDeobfuscator, () -> m_destReader.navigateToClassDeclaration(m_destClass)); 362 this.destReader.decompileClass(this.destClass, this.destDeobfuscator, () -> this.destReader.navigateToClassDeclaration(this.destClass));
375 363
376 updateMatchButton(); 364 updateMatchButton();
377 } 365 }
378 366
379 private void updateMatchButton() { 367 private void updateMatchButton() {
380 368
381 ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass); 369 ClassEntry obfSource = this.sourceDeobfuscator.obfuscateEntry(this.sourceClass);
382 ClassEntry obfDest = m_destDeobfuscator.obfuscateEntry(m_destClass); 370 ClassEntry obfDest = this.destDeobfuscator.obfuscateEntry(this.destClass);
383 371
384 BiMap<ClassEntry, ClassEntry> uniqueMatches = m_classMatches.getUniqueMatches(); 372 BiMap<ClassEntry, ClassEntry> uniqueMatches = this.classMatches.getUniqueMatches();
385 boolean twoSelected = m_sourceClass != null && m_destClass != null; 373 boolean twoSelected = this.sourceClass != null && this.destClass != null;
386 boolean isMatched = uniqueMatches.containsKey(obfSource) && uniqueMatches.containsValue(obfDest); 374 boolean isMatched = uniqueMatches.containsKey(obfSource) && uniqueMatches.containsValue(obfDest);
387 boolean canMatch = !uniqueMatches.containsKey(obfSource) && !uniqueMatches.containsValue(obfDest); 375 boolean canMatch = !uniqueMatches.containsKey(obfSource) && !uniqueMatches.containsValue(obfDest);
388 376
389 GuiTricks.deactivateButton(m_matchButton); 377 GuiTricks.deactivateButton(this.matchButton);
390 if (twoSelected) { 378 if (twoSelected) {
391 if (isMatched) { 379 if (isMatched) {
392 GuiTricks.activateButton(m_matchButton, "Unmatch", event -> onUnmatchClick()); 380 GuiTricks.activateButton(this.matchButton, "Unmatch", event -> onUnmatchClick());
393 } else if (canMatch) { 381 } else if (canMatch) {
394 GuiTricks.activateButton(m_matchButton, "Match", event -> onMatchClick()); 382 GuiTricks.activateButton(this.matchButton, "Match", event -> onMatchClick());
395 } 383 }
396 } 384 }
397 } 385 }
@@ -399,19 +387,19 @@ public class ClassMatchingGui {
399 private void onMatchClick() { 387 private void onMatchClick() {
400 // precondition: source and dest classes are set correctly 388 // precondition: source and dest classes are set correctly
401 389
402 ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass); 390 ClassEntry obfSource = this.sourceDeobfuscator.obfuscateEntry(this.sourceClass);
403 ClassEntry obfDest = m_destDeobfuscator.obfuscateEntry(m_destClass); 391 ClassEntry obfDest = this.destDeobfuscator.obfuscateEntry(this.destClass);
404 392
405 // remove the classes from their match 393 // remove the classes from their match
406 m_classMatches.removeSource(obfSource); 394 this.classMatches.removeSource(obfSource);
407 m_classMatches.removeDest(obfDest); 395 this.classMatches.removeDest(obfDest);
408 396
409 // add them as matched classes 397 // add them as matched classes
410 m_classMatches.add(new ClassMatch(obfSource, obfDest)); 398 this.classMatches.add(new ClassMatch(obfSource, obfDest));
411 399
412 ClassEntry nextClass = null; 400 ClassEntry nextClass = null;
413 if (m_advanceCheck.isSelected()) { 401 if (this.advanceCheck.isSelected()) {
414 nextClass = m_sourceClasses.getNextClass(m_sourceClass); 402 nextClass = this.sourceClasses.getNextClass(this.sourceClass);
415 } 403 }
416 404
417 save(); 405 save();
@@ -425,11 +413,11 @@ public class ClassMatchingGui {
425 private void onUnmatchClick() { 413 private void onUnmatchClick() {
426 // precondition: source and dest classes are set to a unique match 414 // precondition: source and dest classes are set to a unique match
427 415
428 ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass); 416 ClassEntry obfSource = this.sourceDeobfuscator.obfuscateEntry(this.sourceClass);
429 417
430 // remove the source to break the match, then add the source back as unmatched 418 // remove the source to break the match, then add the source back as unmatched
431 m_classMatches.removeSource(obfSource); 419 this.classMatches.removeSource(obfSource);
432 m_classMatches.add(new ClassMatch(obfSource, null)); 420 this.classMatches.add(new ClassMatch(obfSource, null));
433 421
434 save(); 422 save();
435 updateMatches(); 423 updateMatches();
@@ -438,20 +426,20 @@ public class ClassMatchingGui {
438 private void updateMatches() { 426 private void updateMatches() {
439 updateDestMappings(); 427 updateDestMappings();
440 setDestClass(null); 428 setDestClass(null);
441 m_destClasses.setClasses(null); 429 this.destClasses.setClasses(null);
442 updateMatchButton(); 430 updateMatchButton();
443 431
444 // remember where we were in the source tree 432 // remember where we were in the source tree
445 String packageName = m_sourceClasses.getSelectedPackage(); 433 String packageName = this.sourceClasses.getSelectedPackage();
446 434
447 setSourceType(m_sourceType); 435 setSourceType(this.sourceType);
448 436
449 m_sourceClasses.expandPackage(packageName); 437 this.sourceClasses.expandPackage(packageName);
450 } 438 }
451 439
452 private void save() { 440 private void save() {
453 if (m_saveListener != null) { 441 if (this.saveListener != null) {
454 m_saveListener.save(m_classMatches); 442 this.saveListener.save(this.classMatches);
455 } 443 }
456 } 444 }
457 445
@@ -460,18 +448,13 @@ public class ClassMatchingGui {
460 System.out.println("Automatching..."); 448 System.out.println("Automatching...");
461 449
462 // compute a new matching 450 // compute a new matching
463 ClassMatching matching = MappingsConverter.computeMatching( 451 ClassMatching matching = MappingsConverter.computeMatching(this.sourceDeobfuscator.getJar(), this.sourceDeobfuscator.getJarIndex(),
464 m_sourceDeobfuscator.getJar(), m_sourceDeobfuscator.getJarIndex(), 452 this.destDeobfuscator.getJar(), this.destDeobfuscator.getJarIndex(), this.classMatches.getUniqueMatches());
465 m_destDeobfuscator.getJar(), m_destDeobfuscator.getJarIndex(),
466 m_classMatches.getUniqueMatches()
467 );
468 ClassMatches newMatches = new ClassMatches(matching.matches()); 453 ClassMatches newMatches = new ClassMatches(matching.matches());
469 System.out.println(String.format("Automatch found %d new matches", 454 System.out.println(String.format("Automatch found %d new matches", newMatches.getUniqueMatches().size() - this.classMatches.getUniqueMatches().size()));
470 newMatches.getUniqueMatches().size() - m_classMatches.getUniqueMatches().size()
471 ));
472 455
473 // update the current matches 456 // update the current matches
474 m_classMatches = newMatches; 457 this.classMatches = newMatches;
475 save(); 458 save();
476 updateMatches(); 459 updateMatches();
477 } 460 }
@@ -484,17 +467,17 @@ public class ClassMatchingGui {
484 467
485 // make sure we have a source class 468 // make sure we have a source class
486 if (sourceClass == null) { 469 if (sourceClass == null) {
487 sourceClass = m_sourceClasses.getSelectedClass(); 470 sourceClass = this.sourceClasses.getSelectedClass();
488 if (sourceClass != null) { 471 if (sourceClass != null) {
489 sourceClass = m_sourceClasses.getNextClass(sourceClass); 472 sourceClass = this.sourceClasses.getNextClass(sourceClass);
490 } else { 473 } else {
491 sourceClass = m_sourceClasses.getFirstClass(); 474 sourceClass = this.sourceClasses.getFirstClass();
492 } 475 }
493 } 476 }
494 477
495 // set the source class 478 // set the source class
496 setSourceClass(sourceClass, this::pickBestDestClass); 479 setSourceClass(sourceClass, this::pickBestDestClass);
497 m_sourceClasses.setSelectionClass(sourceClass); 480 this.sourceClasses.setSelectionClass(sourceClass);
498 } 481 }
499 482
500 private void pickBestDestClass() { 483 private void pickBestDestClass() {
@@ -502,8 +485,8 @@ public class ClassMatchingGui {
502 // then, pick the best dest class 485 // then, pick the best dest class
503 ClassEntry firstClass = null; 486 ClassEntry firstClass = null;
504 ScoredClassEntry bestDestClass = null; 487 ScoredClassEntry bestDestClass = null;
505 for (ClassSelectorPackageNode packageNode : m_destClasses.packageNodes()) { 488 for (ClassSelectorPackageNode packageNode : this.destClasses.packageNodes()) {
506 for (ClassSelectorClassNode classNode : m_destClasses.classNodes(packageNode)) { 489 for (ClassSelectorClassNode classNode : this.destClasses.classNodes(packageNode)) {
507 if (firstClass == null) { 490 if (firstClass == null) {
508 firstClass = classNode.getClassEntry(); 491 firstClass = classNode.getClassEntry();
509 } 492 }
@@ -525,14 +508,14 @@ public class ClassMatchingGui {
525 } 508 }
526 509
527 setDestClass(destClass); 510 setDestClass(destClass);
528 m_destClasses.setSelectionClass(destClass); 511 this.destClasses.setSelectionClass(destClass);
529 } 512 }
530 513
531 private void toggleTop10Matches() { 514 private void toggleTop10Matches() {
532 if (m_sourceClass != null) { 515 if (this.sourceClass != null) {
533 m_destClasses.clearSelection(); 516 this.destClasses.clearSelection();
534 m_destClasses.setClasses(deobfuscateClasses(getLikelyMatches(m_sourceClass), m_destDeobfuscator)); 517 this.destClasses.setClasses(deobfuscateClasses(getLikelyMatches(this.sourceClass), this.destDeobfuscator));
535 m_destClasses.expandAll(); 518 this.destClasses.expandAll();
536 } 519 }
537 } 520 }
538} 521}
diff --git a/src/main/java/cuchaz/enigma/gui/ClassSelector.java b/src/main/java/cuchaz/enigma/gui/ClassSelector.java
index 0c93c439..f6abd51e 100644
--- a/src/main/java/cuchaz/enigma/gui/ClassSelector.java
+++ b/src/main/java/cuchaz/enigma/gui/ClassSelector.java
@@ -58,11 +58,11 @@ public class ClassSelector extends JTree {
58 }; 58 };
59 } 59 }
60 60
61 private ClassSelectionListener m_listener; 61 private ClassSelectionListener listener;
62 private Comparator<ClassEntry> m_comparator; 62 private Comparator<ClassEntry> comparator;
63 63
64 public ClassSelector(Comparator<ClassEntry> comparator) { 64 public ClassSelector(Comparator<ClassEntry> comparator) {
65 m_comparator = comparator; 65 this.comparator = comparator;
66 66
67 // configure the tree control 67 // configure the tree control
68 setRootVisible(false); 68 setRootVisible(false);
@@ -73,23 +73,23 @@ public class ClassSelector extends JTree {
73 addMouseListener(new MouseAdapter() { 73 addMouseListener(new MouseAdapter() {
74 @Override 74 @Override
75 public void mouseClicked(MouseEvent event) { 75 public void mouseClicked(MouseEvent event) {
76 if (m_listener != null && event.getClickCount() == 2) { 76 if (listener != null && event.getClickCount() == 2) {
77 // get the selected node 77 // get the selected node
78 TreePath path = getSelectionPath(); 78 TreePath path = getSelectionPath();
79 if (path != null && path.getLastPathComponent() instanceof ClassSelectorClassNode) { 79 if (path != null && path.getLastPathComponent() instanceof ClassSelectorClassNode) {
80 ClassSelectorClassNode node = (ClassSelectorClassNode) path.getLastPathComponent(); 80 ClassSelectorClassNode node = (ClassSelectorClassNode) path.getLastPathComponent();
81 m_listener.onSelectClass(node.getClassEntry()); 81 listener.onSelectClass(node.getClassEntry());
82 } 82 }
83 } 83 }
84 } 84 }
85 }); 85 });
86 86
87 // init defaults 87 // init defaults
88 m_listener = null; 88 this.listener = null;
89 } 89 }
90 90
91 public void setListener(ClassSelectionListener val) { 91 public void setListener(ClassSelectionListener val) {
92 m_listener = val; 92 this.listener = val;
93 } 93 }
94 94
95 public void setClasses(Collection<ClassEntry> classEntries) { 95 public void setClasses(Collection<ClassEntry> classEntries) {
@@ -144,7 +144,7 @@ public class ClassSelector extends JTree {
144 for (String packageName : packagedClassEntries.keySet()) { 144 for (String packageName : packagedClassEntries.keySet()) {
145 // sort the class entries 145 // sort the class entries
146 List<ClassEntry> classEntriesInPackage = Lists.newArrayList(packagedClassEntries.get(packageName)); 146 List<ClassEntry> classEntriesInPackage = Lists.newArrayList(packagedClassEntries.get(packageName));
147 Collections.sort(classEntriesInPackage, m_comparator); 147 Collections.sort(classEntriesInPackage, this.comparator);
148 148
149 // create the nodes in order 149 // create the nodes in order
150 for (ClassEntry classEntry : classEntriesInPackage) { 150 for (ClassEntry classEntry : classEntriesInPackage) {
diff --git a/src/main/java/cuchaz/enigma/gui/ClassSelectorClassNode.java b/src/main/java/cuchaz/enigma/gui/ClassSelectorClassNode.java
index 6da9782f..e73340a6 100644
--- a/src/main/java/cuchaz/enigma/gui/ClassSelectorClassNode.java
+++ b/src/main/java/cuchaz/enigma/gui/ClassSelectorClassNode.java
@@ -18,33 +18,30 @@ public class ClassSelectorClassNode extends DefaultMutableTreeNode {
18 18
19 private static final long serialVersionUID = -8956754339813257380L; 19 private static final long serialVersionUID = -8956754339813257380L;
20 20
21 private ClassEntry m_classEntry; 21 private ClassEntry classEntry;
22 22
23 public ClassSelectorClassNode(ClassEntry classEntry) { 23 public ClassSelectorClassNode(ClassEntry classEntry) {
24 m_classEntry = classEntry; 24 this.classEntry = classEntry;
25 } 25 }
26 26
27 public ClassEntry getClassEntry() { 27 public ClassEntry getClassEntry() {
28 return m_classEntry; 28 return this.classEntry;
29 } 29 }
30 30
31 @Override 31 @Override
32 public String toString() { 32 public String toString() {
33 if (m_classEntry instanceof ScoredClassEntry) { 33 if (this.classEntry instanceof ScoredClassEntry) {
34 return String.format("%d%% %s", (int) ((ScoredClassEntry) m_classEntry).getScore(), m_classEntry.getSimpleName()); 34 return String.format("%d%% %s", (int) ((ScoredClassEntry) this.classEntry).getScore(), this.classEntry.getSimpleName());
35 } 35 }
36 return m_classEntry.getSimpleName(); 36 return this.classEntry.getSimpleName();
37 } 37 }
38 38
39 @Override 39 @Override
40 public boolean equals(Object other) { 40 public boolean equals(Object other) {
41 if (other instanceof ClassSelectorClassNode) { 41 return other instanceof ClassSelectorClassNode && equals((ClassSelectorClassNode) other);
42 return equals((ClassSelectorClassNode) other);
43 }
44 return false;
45 } 42 }
46 43
47 public boolean equals(ClassSelectorClassNode other) { 44 public boolean equals(ClassSelectorClassNode other) {
48 return m_classEntry.equals(other.m_classEntry); 45 return this.classEntry.equals(other.classEntry);
49 } 46 }
50} 47}
diff --git a/src/main/java/cuchaz/enigma/gui/ClassSelectorPackageNode.java b/src/main/java/cuchaz/enigma/gui/ClassSelectorPackageNode.java
index 36220423..3b5ba8ca 100644
--- a/src/main/java/cuchaz/enigma/gui/ClassSelectorPackageNode.java
+++ b/src/main/java/cuchaz/enigma/gui/ClassSelectorPackageNode.java
@@ -16,30 +16,27 @@ public class ClassSelectorPackageNode extends DefaultMutableTreeNode {
16 16
17 private static final long serialVersionUID = -3730868701219548043L; 17 private static final long serialVersionUID = -3730868701219548043L;
18 18
19 private String m_packageName; 19 private String packageName;
20 20
21 public ClassSelectorPackageNode(String packageName) { 21 public ClassSelectorPackageNode(String packageName) {
22 m_packageName = packageName; 22 this.packageName = packageName;
23 } 23 }
24 24
25 public String getPackageName() { 25 public String getPackageName() {
26 return m_packageName; 26 return this.packageName;
27 } 27 }
28 28
29 @Override 29 @Override
30 public String toString() { 30 public String toString() {
31 return m_packageName; 31 return this.packageName;
32 } 32 }
33 33
34 @Override 34 @Override
35 public boolean equals(Object other) { 35 public boolean equals(Object other) {
36 if (other instanceof ClassSelectorPackageNode) { 36 return other instanceof ClassSelectorPackageNode && equals((ClassSelectorPackageNode) other);
37 return equals((ClassSelectorPackageNode) other);
38 }
39 return false;
40 } 37 }
41 38
42 public boolean equals(ClassSelectorPackageNode other) { 39 public boolean equals(ClassSelectorPackageNode other) {
43 return m_packageName.equals(other.m_packageName); 40 return this.packageName.equals(other.packageName);
44 } 41 }
45} 42}
diff --git a/src/main/java/cuchaz/enigma/gui/CodeReader.java b/src/main/java/cuchaz/enigma/gui/CodeReader.java
index 93f9a75b..a476fa51 100644
--- a/src/main/java/cuchaz/enigma/gui/CodeReader.java
+++ b/src/main/java/cuchaz/enigma/gui/CodeReader.java
@@ -19,8 +19,6 @@ import java.awt.event.ActionListener;
19import javax.swing.JEditorPane; 19import javax.swing.JEditorPane;
20import javax.swing.SwingUtilities; 20import javax.swing.SwingUtilities;
21import javax.swing.Timer; 21import javax.swing.Timer;
22import javax.swing.event.CaretEvent;
23import javax.swing.event.CaretListener;
24import javax.swing.text.BadLocationException; 22import javax.swing.text.BadLocationException;
25import javax.swing.text.Highlighter.HighlightPainter; 23import javax.swing.text.Highlighter.HighlightPainter;
26 24
@@ -37,15 +35,15 @@ public class CodeReader extends JEditorPane {
37 35
38 private static final long serialVersionUID = 3673180950485748810L; 36 private static final long serialVersionUID = 3673180950485748810L;
39 37
40 private static final Object m_lock = new Object(); 38 private static final Object lock = new Object();
41 39
42 public interface SelectionListener { 40 public interface SelectionListener {
43 void onSelect(EntryReference<Entry, Entry> reference); 41 void onSelect(EntryReference<Entry, Entry> reference);
44 } 42 }
45 43
46 private SelectionHighlightPainter m_selectionHighlightPainter; 44 private SelectionHighlightPainter selectionHighlightPainter;
47 private SourceIndex m_sourceIndex; 45 private SourceIndex sourceIndex;
48 private SelectionListener m_selectionListener; 46 private SelectionListener selectionListener;
49 47
50 public CodeReader() { 48 public CodeReader() {
51 49
@@ -57,42 +55,35 @@ public class CodeReader extends JEditorPane {
57 kit.toggleComponent(this, "de.sciss.syntaxpane.components.TokenMarker"); 55 kit.toggleComponent(this, "de.sciss.syntaxpane.components.TokenMarker");
58 56
59 // hook events 57 // hook events
60 addCaretListener(new CaretListener() { 58 addCaretListener(event -> {
61 @Override 59 if (this.selectionListener != null && this.sourceIndex != null) {
62 public void caretUpdate(CaretEvent event) { 60 Token token = this.sourceIndex.getReferenceToken(event.getDot());
63 if (m_selectionListener != null && m_sourceIndex != null) { 61 if (token != null) {
64 Token token = m_sourceIndex.getReferenceToken(event.getDot()); 62 this.selectionListener.onSelect(this.sourceIndex.getDeobfReference(token));
65 if (token != null) { 63 } else {
66 m_selectionListener.onSelect(m_sourceIndex.getDeobfReference(token)); 64 this.selectionListener.onSelect(null);
67 } else {
68 m_selectionListener.onSelect(null);
69 }
70 } 65 }
71 } 66 }
72 }); 67 });
73 68
74 m_selectionHighlightPainter = new SelectionHighlightPainter(); 69 this.selectionHighlightPainter = new SelectionHighlightPainter();
75 m_sourceIndex = null; 70 this.sourceIndex = null;
76 m_selectionListener = null; 71 this.selectionListener = null;
77 } 72 }
78 73
79 public void setSelectionListener(SelectionListener val) { 74 public void setSelectionListener(SelectionListener val) {
80 m_selectionListener = val; 75 this.selectionListener = val;
81 } 76 }
82 77
83 public void setCode(String code) { 78 public void setCode(String code) {
84 // sadly, the java lexer is not thread safe, so we have to serialize all these calls 79 // sadly, the java lexer is not thread safe, so we have to serialize all these calls
85 synchronized (m_lock) { 80 synchronized (lock) {
86 setText(code); 81 setText(code);
87 } 82 }
88 } 83 }
89 84
90 public SourceIndex getSourceIndex() { 85 public SourceIndex getSourceIndex() {
91 return m_sourceIndex; 86 return this.sourceIndex;
92 }
93
94 public void decompileClass(ClassEntry classEntry, Deobfuscator deobfuscator) {
95 decompileClass(classEntry, deobfuscator, null);
96 } 87 }
97 88
98 public void decompileClass(ClassEntry classEntry, Deobfuscator deobfuscator, Runnable callback) { 89 public void decompileClass(ClassEntry classEntry, Deobfuscator deobfuscator, Runnable callback) {
@@ -117,7 +108,7 @@ public class CodeReader extends JEditorPane {
117 CompilationUnit sourceTree = deobfuscator.getSourceTree(classEntry.getOutermostClassName()); 108 CompilationUnit sourceTree = deobfuscator.getSourceTree(classEntry.getOutermostClassName());
118 String source = deobfuscator.getSource(sourceTree); 109 String source = deobfuscator.getSource(sourceTree);
119 setCode(source); 110 setCode(source);
120 m_sourceIndex = deobfuscator.getSourceIndex(sourceTree, source, ignoreBadTokens); 111 sourceIndex = deobfuscator.getSourceIndex(sourceTree, source, ignoreBadTokens);
121 112
122 if (callback != null) { 113 if (callback != null) {
123 callback.run(); 114 callback.run();
@@ -129,13 +120,13 @@ public class CodeReader extends JEditorPane {
129 public void navigateToClassDeclaration(ClassEntry classEntry) { 120 public void navigateToClassDeclaration(ClassEntry classEntry) {
130 121
131 // navigate to the class declaration 122 // navigate to the class declaration
132 Token token = m_sourceIndex.getDeclarationToken(classEntry); 123 Token token = this.sourceIndex.getDeclarationToken(classEntry);
133 if (token == null) { 124 if (token == null) {
134 // couldn't find the class declaration token, might be an anonymous class 125 // couldn't find the class declaration token, might be an anonymous class
135 // look for any declaration in that class instead 126 // look for any declaration in that class instead
136 for (Entry entry : m_sourceIndex.declarations()) { 127 for (Entry entry : this.sourceIndex.declarations()) {
137 if (entry.getClassEntry().equals(classEntry)) { 128 if (entry.getClassEntry().equals(classEntry)) {
138 token = m_sourceIndex.getDeclarationToken(entry); 129 token = this.sourceIndex.getDeclarationToken(entry);
139 break; 130 break;
140 } 131 }
141 } 132 }
@@ -150,7 +141,7 @@ public class CodeReader extends JEditorPane {
150 } 141 }
151 142
152 public void navigateToToken(final Token token) { 143 public void navigateToToken(final Token token) {
153 navigateToToken(this, token, m_selectionHighlightPainter); 144 navigateToToken(this, token, this.selectionHighlightPainter);
154 } 145 }
155 146
156 // HACKHACK: someday we can update the main GUI to use this code reader 147 // HACKHACK: someday we can update the main GUI to use this code reader
@@ -166,12 +157,7 @@ public class CodeReader extends JEditorPane {
166 Rectangle end = editor.modelToView(token.end); 157 Rectangle end = editor.modelToView(token.end);
167 final Rectangle show = start.union(end); 158 final Rectangle show = start.union(end);
168 show.grow(start.width * 10, start.height * 6); 159 show.grow(start.width * 10, start.height * 6);
169 SwingUtilities.invokeLater(new Runnable() { 160 SwingUtilities.invokeLater(() -> editor.scrollRectToVisible(show));
170 @Override
171 public void run() {
172 editor.scrollRectToVisible(show);
173 }
174 });
175 } catch (BadLocationException ex) { 161 } catch (BadLocationException ex) {
176 throw new Error(ex); 162 throw new Error(ex);
177 } 163 }
@@ -202,12 +188,6 @@ public class CodeReader extends JEditorPane {
202 timer.start(); 188 timer.start();
203 } 189 }
204 190
205 public void setHighlightedTokens(Iterable<Token> tokens, HighlightPainter painter) {
206 for (Token token : tokens) {
207 setHighlightedToken(token, painter);
208 }
209 }
210
211 public void setHighlightedToken(Token token, HighlightPainter painter) { 191 public void setHighlightedToken(Token token, HighlightPainter painter) {
212 try { 192 try {
213 getHighlighter().addHighlight(token.start, token.end, painter); 193 getHighlighter().addHighlight(token.start, token.end, painter);
diff --git a/src/main/java/cuchaz/enigma/gui/CrashDialog.java b/src/main/java/cuchaz/enigma/gui/CrashDialog.java
index c0c0869b..3806f54e 100644
--- a/src/main/java/cuchaz/enigma/gui/CrashDialog.java
+++ b/src/main/java/cuchaz/enigma/gui/CrashDialog.java
@@ -13,8 +13,6 @@ package cuchaz.enigma.gui;
13import java.awt.BorderLayout; 13import java.awt.BorderLayout;
14import java.awt.Container; 14import java.awt.Container;
15import java.awt.FlowLayout; 15import java.awt.FlowLayout;
16import java.awt.event.ActionEvent;
17import java.awt.event.ActionListener;
18import java.io.PrintWriter; 16import java.io.PrintWriter;
19import java.io.StringWriter; 17import java.io.StringWriter;
20 18
@@ -31,11 +29,11 @@ public class CrashDialog {
31 29
32 private CrashDialog(JFrame parent) { 30 private CrashDialog(JFrame parent) {
33 // init frame 31 // init frame
34 m_frame = new JFrame(Constants.Name + " - Crash Report"); 32 m_frame = new JFrame(Constants.NAME + " - Crash Report");
35 final Container pane = m_frame.getContentPane(); 33 final Container pane = m_frame.getContentPane();
36 pane.setLayout(new BorderLayout()); 34 pane.setLayout(new BorderLayout());
37 35
38 JLabel label = new JLabel(Constants.Name + " has crashed! =("); 36 JLabel label = new JLabel(Constants.NAME + " has crashed! =(");
39 label.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); 37 label.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
40 pane.add(label, BorderLayout.NORTH); 38 pane.add(label, BorderLayout.NORTH);
41 39
@@ -51,21 +49,15 @@ public class CrashDialog {
51 buttonsPanel.setLayout(buttonsLayout); 49 buttonsPanel.setLayout(buttonsLayout);
52 buttonsPanel.add(GuiTricks.unboldLabel(new JLabel("If you choose exit, you will lose any unsaved work."))); 50 buttonsPanel.add(GuiTricks.unboldLabel(new JLabel("If you choose exit, you will lose any unsaved work.")));
53 JButton ignoreButton = new JButton("Ignore"); 51 JButton ignoreButton = new JButton("Ignore");
54 ignoreButton.addActionListener(new ActionListener() { 52 ignoreButton.addActionListener(event -> {
55 @Override 53 // close (hide) the dialog
56 public void actionPerformed(ActionEvent event) { 54 m_frame.setVisible(false);
57 // close (hide) the dialog
58 m_frame.setVisible(false);
59 }
60 }); 55 });
61 buttonsPanel.add(ignoreButton); 56 buttonsPanel.add(ignoreButton);
62 JButton exitButton = new JButton("Exit"); 57 JButton exitButton = new JButton("Exit");
63 exitButton.addActionListener(new ActionListener() { 58 exitButton.addActionListener(event -> {
64 @Override 59 // exit enigma
65 public void actionPerformed(ActionEvent event) { 60 System.exit(1);
66 // exit enigma
67 System.exit(1);
68 }
69 }); 61 });
70 buttonsPanel.add(exitButton); 62 buttonsPanel.add(exitButton);
71 pane.add(buttonsPanel, BorderLayout.SOUTH); 63 pane.add(buttonsPanel, BorderLayout.SOUTH);
diff --git a/src/main/java/cuchaz/enigma/gui/DeobfuscatedHighlightPainter.java b/src/main/java/cuchaz/enigma/gui/DeobfuscatedHighlightPainter.java
index d92bb0d2..d5ad0c8a 100644
--- a/src/main/java/cuchaz/enigma/gui/DeobfuscatedHighlightPainter.java
+++ b/src/main/java/cuchaz/enigma/gui/DeobfuscatedHighlightPainter.java
@@ -15,7 +15,6 @@ import java.awt.Color;
15public class DeobfuscatedHighlightPainter extends BoxHighlightPainter { 15public class DeobfuscatedHighlightPainter extends BoxHighlightPainter {
16 16
17 public DeobfuscatedHighlightPainter() { 17 public DeobfuscatedHighlightPainter() {
18 // green ish
19 super(new Color(220, 255, 220), new Color(80, 160, 80)); 18 super(new Color(220, 255, 220), new Color(80, 160, 80));
20 } 19 }
21} 20}
diff --git a/src/main/java/cuchaz/enigma/gui/Gui.java b/src/main/java/cuchaz/enigma/gui/Gui.java
index eb26ddd1..fee9c9f6 100644
--- a/src/main/java/cuchaz/enigma/gui/Gui.java
+++ b/src/main/java/cuchaz/enigma/gui/Gui.java
@@ -16,7 +16,6 @@ import java.awt.*;
16import java.awt.event.*; 16import java.awt.event.*;
17import java.io.File; 17import java.io.File;
18import java.io.IOException; 18import java.io.IOException;
19import java.lang.Thread.UncaughtExceptionHandler;
20import java.util.Collection; 19import java.util.Collection;
21import java.util.Collections; 20import java.util.Collections;
22import java.util.List; 21import java.util.List;
@@ -24,8 +23,6 @@ import java.util.Vector;
24import java.util.jar.JarFile; 23import java.util.jar.JarFile;
25 24
26import javax.swing.*; 25import javax.swing.*;
27import javax.swing.event.CaretEvent;
28import javax.swing.event.CaretListener;
29import javax.swing.text.BadLocationException; 26import javax.swing.text.BadLocationException;
30import javax.swing.text.Highlighter; 27import javax.swing.text.Highlighter;
31import javax.swing.tree.DefaultTreeModel; 28import javax.swing.tree.DefaultTreeModel;
@@ -35,7 +32,6 @@ import javax.swing.tree.TreePath;
35import cuchaz.enigma.Constants; 32import cuchaz.enigma.Constants;
36import cuchaz.enigma.ExceptionIgnorer; 33import cuchaz.enigma.ExceptionIgnorer;
37import cuchaz.enigma.analysis.*; 34import cuchaz.enigma.analysis.*;
38import cuchaz.enigma.gui.ClassSelector.ClassSelectionListener;
39import cuchaz.enigma.mapping.*; 35import cuchaz.enigma.mapping.*;
40import de.sciss.syntaxpane.DefaultSyntaxKit; 36import de.sciss.syntaxpane.DefaultSyntaxKit;
41 37
@@ -90,20 +86,17 @@ public class Gui {
90 public Gui() { 86 public Gui() {
91 87
92 // init frame 88 // init frame
93 m_frame = new JFrame(Constants.Name); 89 m_frame = new JFrame(Constants.NAME);
94 final Container pane = m_frame.getContentPane(); 90 final Container pane = m_frame.getContentPane();
95 pane.setLayout(new BorderLayout()); 91 pane.setLayout(new BorderLayout());
96 92
97 if (Boolean.parseBoolean(System.getProperty("enigma.catchExceptions", "true"))) { 93 if (Boolean.parseBoolean(System.getProperty("enigma.catchExceptions", "true"))) {
98 // install a global exception handler to the event thread 94 // install a global exception handler to the event thread
99 CrashDialog.init(m_frame); 95 CrashDialog.init(m_frame);
100 Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { 96 Thread.setDefaultUncaughtExceptionHandler((thread, t) -> {
101 @Override 97 t.printStackTrace(System.err);
102 public void uncaughtException(Thread thread, Throwable t) { 98 if (!ExceptionIgnorer.shouldIgnore(t)) {
103 t.printStackTrace(System.err); 99 CrashDialog.show(t);
104 if (!ExceptionIgnorer.shouldIgnore(t)) {
105 CrashDialog.show(t);
106 }
107 } 100 }
108 }); 101 });
109 } 102 }
@@ -116,19 +109,14 @@ public class Gui {
116 m_mappingsFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 109 m_mappingsFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
117 m_mappingsFileChooser.setAcceptAllFileFilterUsed(false); 110 m_mappingsFileChooser.setAcceptAllFileFilterUsed(false);
118 111
119 m_oldMappingsFileChooser= new JFileChooser(); 112 m_oldMappingsFileChooser = new JFileChooser();
120 m_exportSourceFileChooser = new JFileChooser(); 113 m_exportSourceFileChooser = new JFileChooser();
121 m_exportSourceFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 114 m_exportSourceFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
122 m_exportJarFileChooser = new JFileChooser(); 115 m_exportJarFileChooser = new JFileChooser();
123 116
124 // init obfuscated classes list 117 // init obfuscated classes list
125 m_obfClasses = new ClassSelector(ClassSelector.ObfuscatedClassEntryComparator); 118 m_obfClasses = new ClassSelector(ClassSelector.ObfuscatedClassEntryComparator);
126 m_obfClasses.setListener(new ClassSelectionListener() { 119 m_obfClasses.setListener(this::navigateTo);
127 @Override
128 public void onSelectClass(ClassEntry classEntry) {
129 navigateTo(classEntry);
130 }
131 });
132 JScrollPane obfScroller = new JScrollPane(m_obfClasses); 120 JScrollPane obfScroller = new JScrollPane(m_obfClasses);
133 JPanel obfPanel = new JPanel(); 121 JPanel obfPanel = new JPanel();
134 obfPanel.setLayout(new BorderLayout()); 122 obfPanel.setLayout(new BorderLayout());
@@ -137,12 +125,7 @@ public class Gui {
137 125
138 // init deobfuscated classes list 126 // init deobfuscated classes list
139 m_deobfClasses = new ClassSelector(ClassSelector.DeobfuscatedClassEntryComparator); 127 m_deobfClasses = new ClassSelector(ClassSelector.DeobfuscatedClassEntryComparator);
140 m_deobfClasses.setListener(new ClassSelectionListener() { 128 m_deobfClasses.setListener(this::navigateTo);
141 @Override
142 public void onSelectClass(ClassEntry classEntry) {
143 navigateTo(classEntry);
144 }
145 });
146 JScrollPane deobfScroller = new JScrollPane(m_deobfClasses); 129 JScrollPane deobfScroller = new JScrollPane(m_deobfClasses);
147 JPanel deobfPanel = new JPanel(); 130 JPanel deobfPanel = new JPanel();
148 deobfPanel.setLayout(new BorderLayout()); 131 deobfPanel.setLayout(new BorderLayout());
@@ -174,12 +157,7 @@ public class Gui {
174 m_editor.setCaret(new BrowserCaret()); 157 m_editor.setCaret(new BrowserCaret());
175 JScrollPane sourceScroller = new JScrollPane(m_editor); 158 JScrollPane sourceScroller = new JScrollPane(m_editor);
176 m_editor.setContentType("text/java"); 159 m_editor.setContentType("text/java");
177 m_editor.addCaretListener(new CaretListener() { 160 m_editor.addCaretListener(event -> onCaretMove(event.getDot()));
178 @Override
179 public void caretUpdate(CaretEvent event) {
180 onCaretMove(event.getDot());
181 }
182 });
183 m_editor.addKeyListener(new KeyAdapter() { 161 m_editor.addKeyListener(new KeyAdapter() {
184 @Override 162 @Override
185 public void keyPressed(KeyEvent event) { 163 public void keyPressed(KeyEvent event) {
@@ -224,12 +202,7 @@ public class Gui {
224 m_editor.setComponentPopupMenu(popupMenu); 202 m_editor.setComponentPopupMenu(popupMenu);
225 { 203 {
226 JMenuItem menu = new JMenuItem("Rename"); 204 JMenuItem menu = new JMenuItem("Rename");
227 menu.addActionListener(new ActionListener() { 205 menu.addActionListener(event -> startRename());
228 @Override
229 public void actionPerformed(ActionEvent event) {
230 startRename();
231 }
232 });
233 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, 0)); 206 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, 0));
234 menu.setEnabled(false); 207 menu.setEnabled(false);
235 popupMenu.add(menu); 208 popupMenu.add(menu);
@@ -237,12 +210,7 @@ public class Gui {
237 } 210 }
238 { 211 {
239 JMenuItem menu = new JMenuItem("Show Inheritance"); 212 JMenuItem menu = new JMenuItem("Show Inheritance");
240 menu.addActionListener(new ActionListener() { 213 menu.addActionListener(event -> showInheritance());
241 @Override
242 public void actionPerformed(ActionEvent event) {
243 showInheritance();
244 }
245 });
246 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, 0)); 214 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, 0));
247 menu.setEnabled(false); 215 menu.setEnabled(false);
248 popupMenu.add(menu); 216 popupMenu.add(menu);
@@ -250,12 +218,7 @@ public class Gui {
250 } 218 }
251 { 219 {
252 JMenuItem menu = new JMenuItem("Show Implementations"); 220 JMenuItem menu = new JMenuItem("Show Implementations");
253 menu.addActionListener(new ActionListener() { 221 menu.addActionListener(event -> showImplementations());
254 @Override
255 public void actionPerformed(ActionEvent event) {
256 showImplementations();
257 }
258 });
259 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, 0)); 222 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, 0));
260 menu.setEnabled(false); 223 menu.setEnabled(false);
261 popupMenu.add(menu); 224 popupMenu.add(menu);
@@ -263,12 +226,7 @@ public class Gui {
263 } 226 }
264 { 227 {
265 JMenuItem menu = new JMenuItem("Show Calls"); 228 JMenuItem menu = new JMenuItem("Show Calls");
266 menu.addActionListener(new ActionListener() { 229 menu.addActionListener(event -> showCalls());
267 @Override
268 public void actionPerformed(ActionEvent event) {
269 showCalls();
270 }
271 });
272 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, 0)); 230 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, 0));
273 menu.setEnabled(false); 231 menu.setEnabled(false);
274 popupMenu.add(menu); 232 popupMenu.add(menu);
@@ -276,12 +234,7 @@ public class Gui {
276 } 234 }
277 { 235 {
278 JMenuItem menu = new JMenuItem("Go to Declaration"); 236 JMenuItem menu = new JMenuItem("Go to Declaration");
279 menu.addActionListener(new ActionListener() { 237 menu.addActionListener(event -> navigateTo(m_reference.entry));
280 @Override
281 public void actionPerformed(ActionEvent event) {
282 navigateTo(m_reference.entry);
283 }
284 });
285 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, 0)); 238 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, 0));
286 menu.setEnabled(false); 239 menu.setEnabled(false);
287 popupMenu.add(menu); 240 popupMenu.add(menu);
@@ -289,12 +242,7 @@ public class Gui {
289 } 242 }
290 { 243 {
291 JMenuItem menu = new JMenuItem("Go to previous"); 244 JMenuItem menu = new JMenuItem("Go to previous");
292 menu.addActionListener(new ActionListener() { 245 menu.addActionListener(event -> m_controller.openPreviousReference());
293 @Override
294 public void actionPerformed(ActionEvent event) {
295 m_controller.openPreviousReference();
296 }
297 });
298 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, 0)); 246 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, 0));
299 menu.setEnabled(false); 247 menu.setEnabled(false);
300 popupMenu.add(menu); 248 popupMenu.add(menu);
@@ -302,12 +250,7 @@ public class Gui {
302 } 250 }
303 { 251 {
304 JMenuItem menu = new JMenuItem("Mark as deobfuscated"); 252 JMenuItem menu = new JMenuItem("Mark as deobfuscated");
305 menu.addActionListener(new ActionListener() { 253 menu.addActionListener(event -> toggleMapping());
306 @Override
307 public void actionPerformed(ActionEvent event) {
308 toggleMapping();
309 }
310 });
311 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, 0)); 254 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, 0));
312 menu.setEnabled(false); 255 menu.setEnabled(false);
313 popupMenu.add(menu); 256 popupMenu.add(menu);
@@ -398,7 +341,7 @@ public class Gui {
398 } 341 }
399 } 342 }
400 }); 343 });
401 m_tokens = new JList<Token>(); 344 m_tokens = new JList<>();
402 m_tokens.setCellRenderer(new TokenListCellRenderer(m_controller)); 345 m_tokens.setCellRenderer(new TokenListCellRenderer(m_controller));
403 m_tokens.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 346 m_tokens.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
404 m_tokens.setLayoutOrientation(JList.VERTICAL); 347 m_tokens.setLayoutOrientation(JList.VERTICAL);
@@ -450,51 +393,40 @@ public class Gui {
450 { 393 {
451 JMenuItem item = new JMenuItem("Open Jar..."); 394 JMenuItem item = new JMenuItem("Open Jar...");
452 menu.add(item); 395 menu.add(item);
453 item.addActionListener(new ActionListener() { 396 item.addActionListener(event -> {
454 @Override 397 if (m_jarFileChooser.showOpenDialog(m_frame) == JFileChooser.APPROVE_OPTION) {
455 public void actionPerformed(ActionEvent event) { 398 // load the jar in a separate thread
456 if (m_jarFileChooser.showOpenDialog(m_frame) == JFileChooser.APPROVE_OPTION) { 399 new Thread() {
457 // load the jar in a separate thread 400 @Override
458 new Thread() { 401 public void run() {
459 @Override 402 try {
460 public void run() { 403 m_controller.openJar(new JarFile(m_jarFileChooser.getSelectedFile()));
461 try { 404 } catch (IOException ex) {
462 m_controller.openJar(new JarFile(m_jarFileChooser.getSelectedFile())); 405 throw new Error(ex);
463 } catch (IOException ex) {
464 throw new Error(ex);
465 }
466 } 406 }
467 }.start(); 407 }
468 } 408 }.start();
469 } 409 }
470 }); 410 });
471 } 411 }
472 { 412 {
473 JMenuItem item = new JMenuItem("Close Jar"); 413 JMenuItem item = new JMenuItem("Close Jar");
474 menu.add(item); 414 menu.add(item);
475 item.addActionListener(new ActionListener() { 415 item.addActionListener(event -> m_controller.closeJar());
476 @Override
477 public void actionPerformed(ActionEvent event) {
478 m_controller.closeJar();
479 }
480 });
481 m_closeJarMenu = item; 416 m_closeJarMenu = item;
482 } 417 }
483 menu.addSeparator(); 418 menu.addSeparator();
484 { 419 {
485 JMenuItem item = new JMenuItem("Open Mappings..."); 420 JMenuItem item = new JMenuItem("Open Mappings...");
486 menu.add(item); 421 menu.add(item);
487 item.addActionListener(new ActionListener() { 422 item.addActionListener(event -> {
488 @Override 423 if (m_mappingsFileChooser.showOpenDialog(m_frame) == JFileChooser.APPROVE_OPTION) {
489 public void actionPerformed(ActionEvent event) { 424 try {
490 if (m_mappingsFileChooser.showOpenDialog(m_frame) == JFileChooser.APPROVE_OPTION) { 425 m_controller.openMappings(m_mappingsFileChooser.getSelectedFile());
491 try { 426 } catch (IOException ex) {
492 m_controller.openMappings(m_mappingsFileChooser.getSelectedFile()); 427 throw new Error(ex);
493 } catch (IOException ex) { 428 } catch (MappingParseException ex) {
494 throw new Error(ex); 429 JOptionPane.showMessageDialog(m_frame, ex.getMessage());
495 } catch (MappingParseException ex) {
496 JOptionPane.showMessageDialog(m_frame, ex.getMessage());
497 }
498 } 430 }
499 } 431 }
500 }); 432 });
@@ -520,14 +452,11 @@ public class Gui {
520 { 452 {
521 JMenuItem item = new JMenuItem("Save Mappings"); 453 JMenuItem item = new JMenuItem("Save Mappings");
522 menu.add(item); 454 menu.add(item);
523 item.addActionListener(new ActionListener() { 455 item.addActionListener(event -> {
524 @Override 456 try {
525 public void actionPerformed(ActionEvent event) { 457 m_controller.saveMappings(m_mappingsFileChooser.getSelectedFile());
526 try { 458 } catch (IOException ex) {
527 m_controller.saveMappings(m_mappingsFileChooser.getSelectedFile()); 459 throw new Error(ex);
528 } catch (IOException ex) {
529 throw new Error(ex);
530 }
531 } 460 }
532 }); 461 });
533 item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK)); 462 item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK));
@@ -536,16 +465,13 @@ public class Gui {
536 { 465 {
537 JMenuItem item = new JMenuItem("Save Mappings As..."); 466 JMenuItem item = new JMenuItem("Save Mappings As...");
538 menu.add(item); 467 menu.add(item);
539 item.addActionListener(new ActionListener() { 468 item.addActionListener(event -> {
540 @Override 469 if (m_mappingsFileChooser.showSaveDialog(m_frame) == JFileChooser.APPROVE_OPTION) {
541 public void actionPerformed(ActionEvent event) { 470 try {
542 if (m_mappingsFileChooser.showSaveDialog(m_frame) == JFileChooser.APPROVE_OPTION) { 471 m_controller.saveMappings(m_mappingsFileChooser.getSelectedFile());
543 try { 472 m_saveMappingsMenu.setEnabled(true);
544 m_controller.saveMappings(m_mappingsFileChooser.getSelectedFile()); 473 } catch (IOException ex) {
545 m_saveMappingsMenu.setEnabled(true); 474 throw new Error(ex);
546 } catch (IOException ex) {
547 throw new Error(ex);
548 }
549 } 475 }
550 } 476 }
551 }); 477 });
@@ -555,24 +481,16 @@ public class Gui {
555 { 481 {
556 JMenuItem item = new JMenuItem("Close Mappings"); 482 JMenuItem item = new JMenuItem("Close Mappings");
557 menu.add(item); 483 menu.add(item);
558 item.addActionListener(new ActionListener() { 484 item.addActionListener(event -> m_controller.closeMappings());
559 @Override
560 public void actionPerformed(ActionEvent event) {
561 m_controller.closeMappings();
562 }
563 });
564 m_closeMappingsMenu = item; 485 m_closeMappingsMenu = item;
565 } 486 }
566 menu.addSeparator(); 487 menu.addSeparator();
567 { 488 {
568 JMenuItem item = new JMenuItem("Export Source..."); 489 JMenuItem item = new JMenuItem("Export Source...");
569 menu.add(item); 490 menu.add(item);
570 item.addActionListener(new ActionListener() { 491 item.addActionListener(event -> {
571 @Override 492 if (m_exportSourceFileChooser.showSaveDialog(m_frame) == JFileChooser.APPROVE_OPTION) {
572 public void actionPerformed(ActionEvent event) { 493 m_controller.exportSource(m_exportSourceFileChooser.getSelectedFile());
573 if (m_exportSourceFileChooser.showSaveDialog(m_frame) == JFileChooser.APPROVE_OPTION) {
574 m_controller.exportSource(m_exportSourceFileChooser.getSelectedFile());
575 }
576 } 494 }
577 }); 495 });
578 m_exportSourceMenu = item; 496 m_exportSourceMenu = item;
@@ -580,12 +498,9 @@ public class Gui {
580 { 498 {
581 JMenuItem item = new JMenuItem("Export Jar..."); 499 JMenuItem item = new JMenuItem("Export Jar...");
582 menu.add(item); 500 menu.add(item);
583 item.addActionListener(new ActionListener() { 501 item.addActionListener(event -> {
584 @Override 502 if (m_exportJarFileChooser.showSaveDialog(m_frame) == JFileChooser.APPROVE_OPTION) {
585 public void actionPerformed(ActionEvent event) { 503 m_controller.exportJar(m_exportJarFileChooser.getSelectedFile());
586 if (m_exportJarFileChooser.showSaveDialog(m_frame) == JFileChooser.APPROVE_OPTION) {
587 m_controller.exportJar(m_exportJarFileChooser.getSelectedFile());
588 }
589 } 504 }
590 }); 505 });
591 m_exportJarMenu = item; 506 m_exportJarMenu = item;
@@ -594,12 +509,7 @@ public class Gui {
594 { 509 {
595 JMenuItem item = new JMenuItem("Exit"); 510 JMenuItem item = new JMenuItem("Exit");
596 menu.add(item); 511 menu.add(item);
597 item.addActionListener(new ActionListener() { 512 item.addActionListener(event -> close());
598 @Override
599 public void actionPerformed(ActionEvent event) {
600 close();
601 }
602 });
603 } 513 }
604 } 514 }
605 { 515 {
@@ -608,12 +518,7 @@ public class Gui {
608 { 518 {
609 JMenuItem item = new JMenuItem("About"); 519 JMenuItem item = new JMenuItem("About");
610 menu.add(item); 520 menu.add(item);
611 item.addActionListener(new ActionListener() { 521 item.addActionListener(event -> AboutDialog.show(m_frame));
612 @Override
613 public void actionPerformed(ActionEvent event) {
614 AboutDialog.show(m_frame);
615 }
616 });
617 } 522 }
618 } 523 }
619 524
@@ -654,7 +559,7 @@ public class Gui {
654 559
655 public void onFinishOpenJar(String jarName) { 560 public void onFinishOpenJar(String jarName) {
656 // update gui 561 // update gui
657 m_frame.setTitle(Constants.Name + " - " + jarName); 562 m_frame.setTitle(Constants.NAME + " - " + jarName);
658 m_classesPanel.removeAll(); 563 m_classesPanel.removeAll();
659 m_classesPanel.add(m_splitClasses); 564 m_classesPanel.add(m_splitClasses);
660 setSource(null); 565 setSource(null);
@@ -674,7 +579,7 @@ public class Gui {
674 579
675 public void onCloseJar() { 580 public void onCloseJar() {
676 // update gui 581 // update gui
677 m_frame.setTitle(Constants.Name); 582 m_frame.setTitle(Constants.NAME);
678 setObfClasses(null); 583 setObfClasses(null);
679 setDeobfClasses(null); 584 setDeobfClasses(null);
680 setSource(null); 585 setSource(null);
@@ -720,14 +625,14 @@ public class Gui {
720 } 625 }
721 626
722 public void showTokens(Collection<Token> tokens) { 627 public void showTokens(Collection<Token> tokens) {
723 Vector<Token> sortedTokens = new Vector<Token>(tokens); 628 Vector<Token> sortedTokens = new Vector<>(tokens);
724 Collections.sort(sortedTokens); 629 Collections.sort(sortedTokens);
725 if (sortedTokens.size() > 1) { 630 if (sortedTokens.size() > 1) {
726 // sort the tokens and update the tokens panel 631 // sort the tokens and update the tokens panel
727 m_tokens.setListData(sortedTokens); 632 m_tokens.setListData(sortedTokens);
728 m_tokens.setSelectedIndex(0); 633 m_tokens.setSelectedIndex(0);
729 } else { 634 } else {
730 m_tokens.setListData(new Vector<Token>()); 635 m_tokens.setListData(new Vector<>());
731 } 636 }
732 637
733 // show the first token 638 // show the first token
diff --git a/src/main/java/cuchaz/enigma/gui/GuiController.java b/src/main/java/cuchaz/enigma/gui/GuiController.java
index a6a2ec52..868e0d48 100644
--- a/src/main/java/cuchaz/enigma/gui/GuiController.java
+++ b/src/main/java/cuchaz/enigma/gui/GuiController.java
@@ -24,162 +24,138 @@ import java.util.List;
24import java.util.jar.JarFile; 24import java.util.jar.JarFile;
25 25
26import cuchaz.enigma.Deobfuscator; 26import cuchaz.enigma.Deobfuscator;
27import cuchaz.enigma.Deobfuscator.ProgressListener;
28import cuchaz.enigma.analysis.*; 27import cuchaz.enigma.analysis.*;
29import cuchaz.enigma.gui.ProgressDialog.ProgressRunnable;
30import cuchaz.enigma.mapping.*; 28import cuchaz.enigma.mapping.*;
31 29
32public class GuiController { 30public class GuiController {
33 31
34 private Deobfuscator m_deobfuscator; 32 private Deobfuscator deobfuscator;
35 private Gui m_gui; 33 private Gui gui;
36 private SourceIndex m_index; 34 private SourceIndex index;
37 private ClassEntry m_currentObfClass; 35 private ClassEntry currentObfClass;
38 private boolean m_isDirty; 36 private boolean isDirty;
39 private Deque<EntryReference<Entry, Entry>> m_referenceStack; 37 private Deque<EntryReference<Entry, Entry>> referenceStack;
40 38
41 public GuiController(Gui gui) { 39 public GuiController(Gui gui) {
42 m_gui = gui; 40 this.gui = gui;
43 m_deobfuscator = null; 41 this.deobfuscator = null;
44 m_index = null; 42 this.index = null;
45 m_currentObfClass = null; 43 this.currentObfClass = null;
46 m_isDirty = false; 44 this.isDirty = false;
47 m_referenceStack = Queues.newArrayDeque(); 45 this.referenceStack = Queues.newArrayDeque();
48 } 46 }
49 47
50 public boolean isDirty() { 48 public boolean isDirty() {
51 return m_isDirty; 49 return this.isDirty;
52 } 50 }
53 51
54 public void openJar(final JarFile jar) throws IOException { 52 public void openJar(final JarFile jar) throws IOException {
55 m_gui.onStartOpenJar(); 53 this.gui.onStartOpenJar();
56 m_deobfuscator = new Deobfuscator(jar); 54 this.deobfuscator = new Deobfuscator(jar);
57 m_gui.onFinishOpenJar(m_deobfuscator.getJarName()); 55 this.gui.onFinishOpenJar(this.deobfuscator.getJarName());
58 refreshClasses(); 56 refreshClasses();
59 } 57 }
60 58
61 public void closeJar() { 59 public void closeJar() {
62 m_deobfuscator = null; 60 this.deobfuscator = null;
63 m_gui.onCloseJar(); 61 this.gui.onCloseJar();
64 } 62 }
65 63
66 public void openOldMappings(File file) throws IOException, MappingParseException { 64 public void openOldMappings(File file) throws IOException, MappingParseException {
67 FileReader in = new FileReader(file); 65 FileReader in = new FileReader(file);
68 m_deobfuscator.setMappings(new MappingsReaderOld().read(in)); 66 this.deobfuscator.setMappings(new MappingsReaderOld().read(in));
69 in.close(); 67 in.close();
70 m_isDirty = false; 68 this.isDirty = false;
71 m_gui.setMappingsFile(file); 69 this.gui.setMappingsFile(file);
72 refreshClasses(); 70 refreshClasses();
73 refreshCurrentClass(); 71 refreshCurrentClass();
74 } 72 }
75 73
76 public void openMappings(File file) throws IOException, MappingParseException { 74 public void openMappings(File file) throws IOException, MappingParseException {
77 m_deobfuscator.setMappings(new MappingsReader().read(file)); 75 this.deobfuscator.setMappings(new MappingsReader().read(file));
78 m_isDirty = false; 76 this.isDirty = false;
79 m_gui.setMappingsFile(file); 77 this.gui.setMappingsFile(file);
80 refreshClasses(); 78 refreshClasses();
81 refreshCurrentClass(); 79 refreshCurrentClass();
82 } 80 }
83 81
84 public void saveMappings(File file) throws IOException { 82 public void saveMappings(File file) throws IOException {
85 new MappingsWriter().write(file, m_deobfuscator.getMappings()); 83 new MappingsWriter().write(file, this.deobfuscator.getMappings());
86 m_isDirty = false; 84 this.isDirty = false;
87 } 85 }
88 86
89 public void closeMappings() { 87 public void closeMappings() {
90 m_deobfuscator.setMappings(null); 88 this.deobfuscator.setMappings(null);
91 m_gui.setMappingsFile(null); 89 this.gui.setMappingsFile(null);
92 refreshClasses(); 90 refreshClasses();
93 refreshCurrentClass(); 91 refreshCurrentClass();
94 } 92 }
95 93
96 public void exportSource(final File dirOut) { 94 public void exportSource(final File dirOut) {
97 ProgressDialog.runInThread(m_gui.getFrame(), new ProgressRunnable() { 95 ProgressDialog.runInThread(this.gui.getFrame(), progress -> this.deobfuscator.writeSources(dirOut, progress));
98 @Override
99 public void run(ProgressListener progress) throws Exception {
100 m_deobfuscator.writeSources(dirOut, progress);
101 }
102 });
103 } 96 }
104 97
105 public void exportJar(final File fileOut) { 98 public void exportJar(final File fileOut) {
106 ProgressDialog.runInThread(m_gui.getFrame(), new ProgressRunnable() { 99 ProgressDialog.runInThread(this.gui.getFrame(), progress -> this.deobfuscator.writeJar(fileOut, progress));
107 @Override
108 public void run(ProgressListener progress) {
109 m_deobfuscator.writeJar(fileOut, progress);
110 }
111 });
112 } 100 }
113 101
114 public Token getToken(int pos) { 102 public Token getToken(int pos) {
115 if (m_index == null) { 103 if (this.index == null) {
116 return null; 104 return null;
117 } 105 }
118 return m_index.getReferenceToken(pos); 106 return this.index.getReferenceToken(pos);
119 } 107 }
120 108
121 public EntryReference<Entry, Entry> getDeobfReference(Token token) { 109 public EntryReference<Entry, Entry> getDeobfReference(Token token) {
122 if (m_index == null) { 110 if (this.index == null) {
123 return null; 111 return null;
124 } 112 }
125 return m_index.getDeobfReference(token); 113 return this.index.getDeobfReference(token);
126 } 114 }
127 115
128 public ReadableToken getReadableToken(Token token) { 116 public ReadableToken getReadableToken(Token token) {
129 if (m_index == null) { 117 if (this.index == null) {
130 return null; 118 return null;
131 } 119 }
132 return new ReadableToken( 120 return new ReadableToken(
133 m_index.getLineNumber(token.start), 121 this.index.getLineNumber(token.start),
134 m_index.getColumnNumber(token.start), 122 this.index.getColumnNumber(token.start),
135 m_index.getColumnNumber(token.end) 123 this.index.getColumnNumber(token.end)
136 ); 124 );
137 } 125 }
138 126
139 public boolean entryHasDeobfuscatedName(Entry deobfEntry) { 127 public boolean entryHasDeobfuscatedName(Entry deobfEntry) {
140 return m_deobfuscator.hasDeobfuscatedName(m_deobfuscator.obfuscateEntry(deobfEntry)); 128 return this.deobfuscator.hasDeobfuscatedName(this.deobfuscator.obfuscateEntry(deobfEntry));
141 } 129 }
142 130
143 public boolean entryIsInJar(Entry deobfEntry) { 131 public boolean entryIsInJar(Entry deobfEntry) {
144 return m_deobfuscator.isObfuscatedIdentifier(m_deobfuscator.obfuscateEntry(deobfEntry)); 132 return this.deobfuscator.isObfuscatedIdentifier(this.deobfuscator.obfuscateEntry(deobfEntry));
145 } 133 }
146 134
147 public boolean referenceIsRenameable(EntryReference<Entry, Entry> deobfReference) { 135 public boolean referenceIsRenameable(EntryReference<Entry, Entry> deobfReference) {
148 return m_deobfuscator.isRenameable(m_deobfuscator.obfuscateReference(deobfReference)); 136 return this.deobfuscator.isRenameable(this.deobfuscator.obfuscateReference(deobfReference));
149 } 137 }
150 138
151 public ClassInheritanceTreeNode getClassInheritance(ClassEntry deobfClassEntry) { 139 public ClassInheritanceTreeNode getClassInheritance(ClassEntry deobfClassEntry) {
152 ClassEntry obfClassEntry = m_deobfuscator.obfuscateEntry(deobfClassEntry); 140 ClassEntry obfClassEntry = this.deobfuscator.obfuscateEntry(deobfClassEntry);
153 ClassInheritanceTreeNode rootNode = m_deobfuscator.getJarIndex().getClassInheritance( 141 ClassInheritanceTreeNode rootNode = this.deobfuscator.getJarIndex().getClassInheritance(this.deobfuscator.getTranslator(TranslationDirection.Deobfuscating), obfClassEntry);
154 m_deobfuscator.getTranslator(TranslationDirection.Deobfuscating),
155 obfClassEntry
156 );
157 return ClassInheritanceTreeNode.findNode(rootNode, obfClassEntry); 142 return ClassInheritanceTreeNode.findNode(rootNode, obfClassEntry);
158 } 143 }
159 144
160 public ClassImplementationsTreeNode getClassImplementations(ClassEntry deobfClassEntry) { 145 public ClassImplementationsTreeNode getClassImplementations(ClassEntry deobfClassEntry) {
161 ClassEntry obfClassEntry = m_deobfuscator.obfuscateEntry(deobfClassEntry); 146 ClassEntry obfClassEntry = this.deobfuscator.obfuscateEntry(deobfClassEntry);
162 return m_deobfuscator.getJarIndex().getClassImplementations( 147 return this.deobfuscator.getJarIndex().getClassImplementations(this.deobfuscator.getTranslator(TranslationDirection.Deobfuscating), obfClassEntry);
163 m_deobfuscator.getTranslator(TranslationDirection.Deobfuscating),
164 obfClassEntry
165 );
166 } 148 }
167 149
168 public MethodInheritanceTreeNode getMethodInheritance(MethodEntry deobfMethodEntry) { 150 public MethodInheritanceTreeNode getMethodInheritance(MethodEntry deobfMethodEntry) {
169 MethodEntry obfMethodEntry = m_deobfuscator.obfuscateEntry(deobfMethodEntry); 151 MethodEntry obfMethodEntry = this.deobfuscator.obfuscateEntry(deobfMethodEntry);
170 MethodInheritanceTreeNode rootNode = m_deobfuscator.getJarIndex().getMethodInheritance( 152 MethodInheritanceTreeNode rootNode = this.deobfuscator.getJarIndex().getMethodInheritance(this.deobfuscator.getTranslator(TranslationDirection.Deobfuscating), obfMethodEntry);
171 m_deobfuscator.getTranslator(TranslationDirection.Deobfuscating),
172 obfMethodEntry
173 );
174 return MethodInheritanceTreeNode.findNode(rootNode, obfMethodEntry); 153 return MethodInheritanceTreeNode.findNode(rootNode, obfMethodEntry);
175 } 154 }
176 155
177 public MethodImplementationsTreeNode getMethodImplementations(MethodEntry deobfMethodEntry) { 156 public MethodImplementationsTreeNode getMethodImplementations(MethodEntry deobfMethodEntry) {
178 MethodEntry obfMethodEntry = m_deobfuscator.obfuscateEntry(deobfMethodEntry); 157 MethodEntry obfMethodEntry = this.deobfuscator.obfuscateEntry(deobfMethodEntry);
179 List<MethodImplementationsTreeNode> rootNodes = m_deobfuscator.getJarIndex().getMethodImplementations( 158 List<MethodImplementationsTreeNode> rootNodes = this.deobfuscator.getJarIndex().getMethodImplementations(this.deobfuscator.getTranslator(TranslationDirection.Deobfuscating), obfMethodEntry);
180 m_deobfuscator.getTranslator(TranslationDirection.Deobfuscating),
181 obfMethodEntry
182 );
183 if (rootNodes.isEmpty()) { 159 if (rootNodes.isEmpty()) {
184 return null; 160 return null;
185 } 161 }
@@ -190,45 +166,39 @@ public class GuiController {
190 } 166 }
191 167
192 public FieldReferenceTreeNode getFieldReferences(FieldEntry deobfFieldEntry) { 168 public FieldReferenceTreeNode getFieldReferences(FieldEntry deobfFieldEntry) {
193 FieldEntry obfFieldEntry = m_deobfuscator.obfuscateEntry(deobfFieldEntry); 169 FieldEntry obfFieldEntry = this.deobfuscator.obfuscateEntry(deobfFieldEntry);
194 FieldReferenceTreeNode rootNode = new FieldReferenceTreeNode( 170 FieldReferenceTreeNode rootNode = new FieldReferenceTreeNode(this.deobfuscator.getTranslator(TranslationDirection.Deobfuscating), obfFieldEntry);
195 m_deobfuscator.getTranslator(TranslationDirection.Deobfuscating), 171 rootNode.load(this.deobfuscator.getJarIndex(), true);
196 obfFieldEntry
197 );
198 rootNode.load(m_deobfuscator.getJarIndex(), true);
199 return rootNode; 172 return rootNode;
200 } 173 }
201 174
202 public BehaviorReferenceTreeNode getMethodReferences(BehaviorEntry deobfBehaviorEntry) { 175 public BehaviorReferenceTreeNode getMethodReferences(BehaviorEntry deobfBehaviorEntry) {
203 BehaviorEntry obfBehaviorEntry = m_deobfuscator.obfuscateEntry(deobfBehaviorEntry); 176 BehaviorEntry obfBehaviorEntry = this.deobfuscator.obfuscateEntry(deobfBehaviorEntry);
204 BehaviorReferenceTreeNode rootNode = new BehaviorReferenceTreeNode( 177 BehaviorReferenceTreeNode rootNode = new BehaviorReferenceTreeNode(this.deobfuscator.getTranslator(TranslationDirection.Deobfuscating), obfBehaviorEntry);
205 m_deobfuscator.getTranslator(TranslationDirection.Deobfuscating), 178 rootNode.load(this.deobfuscator.getJarIndex(), true);
206 obfBehaviorEntry
207 );
208 rootNode.load(m_deobfuscator.getJarIndex(), true);
209 return rootNode; 179 return rootNode;
210 } 180 }
211 181
212 public void rename(EntryReference<Entry, Entry> deobfReference, String newName) { 182 public void rename(EntryReference<Entry, Entry> deobfReference, String newName) {
213 EntryReference<Entry, Entry> obfReference = m_deobfuscator.obfuscateReference(deobfReference); 183 EntryReference<Entry, Entry> obfReference = this.deobfuscator.obfuscateReference(deobfReference);
214 m_deobfuscator.rename(obfReference.getNameableEntry(), newName); 184 this.deobfuscator.rename(obfReference.getNameableEntry(), newName);
215 m_isDirty = true; 185 this.isDirty = true;
216 refreshClasses(); 186 refreshClasses();
217 refreshCurrentClass(obfReference); 187 refreshCurrentClass(obfReference);
218 } 188 }
219 189
220 public void removeMapping(EntryReference<Entry, Entry> deobfReference) { 190 public void removeMapping(EntryReference<Entry, Entry> deobfReference) {
221 EntryReference<Entry, Entry> obfReference = m_deobfuscator.obfuscateReference(deobfReference); 191 EntryReference<Entry, Entry> obfReference = this.deobfuscator.obfuscateReference(deobfReference);
222 m_deobfuscator.removeMapping(obfReference.getNameableEntry()); 192 this.deobfuscator.removeMapping(obfReference.getNameableEntry());
223 m_isDirty = true; 193 this.isDirty = true;
224 refreshClasses(); 194 refreshClasses();
225 refreshCurrentClass(obfReference); 195 refreshCurrentClass(obfReference);
226 } 196 }
227 197
228 public void markAsDeobfuscated(EntryReference<Entry, Entry> deobfReference) { 198 public void markAsDeobfuscated(EntryReference<Entry, Entry> deobfReference) {
229 EntryReference<Entry, Entry> obfReference = m_deobfuscator.obfuscateReference(deobfReference); 199 EntryReference<Entry, Entry> obfReference = this.deobfuscator.obfuscateReference(deobfReference);
230 m_deobfuscator.markAsDeobfuscated(obfReference.getNameableEntry()); 200 this.deobfuscator.markAsDeobfuscated(obfReference.getNameableEntry());
231 m_isDirty = true; 201 this.isDirty = true;
232 refreshClasses(); 202 refreshClasses();
233 refreshCurrentClass(obfReference); 203 refreshCurrentClass(obfReference);
234 } 204 }
@@ -237,7 +207,7 @@ public class GuiController {
237 if (deobfEntry == null) { 207 if (deobfEntry == null) {
238 throw new IllegalArgumentException("Entry cannot be null!"); 208 throw new IllegalArgumentException("Entry cannot be null!");
239 } 209 }
240 openReference(new EntryReference<Entry, Entry>(deobfEntry, deobfEntry.getName())); 210 openReference(new EntryReference<>(deobfEntry, deobfEntry.getName()));
241 } 211 }
242 212
243 public void openReference(EntryReference<Entry, Entry> deobfReference) { 213 public void openReference(EntryReference<Entry, Entry> deobfReference) {
@@ -246,51 +216,51 @@ public class GuiController {
246 } 216 }
247 217
248 // get the reference target class 218 // get the reference target class
249 EntryReference<Entry, Entry> obfReference = m_deobfuscator.obfuscateReference(deobfReference); 219 EntryReference<Entry, Entry> obfReference = this.deobfuscator.obfuscateReference(deobfReference);
250 ClassEntry obfClassEntry = obfReference.getLocationClassEntry().getOutermostClassEntry(); 220 ClassEntry obfClassEntry = obfReference.getLocationClassEntry().getOutermostClassEntry();
251 if (!m_deobfuscator.isObfuscatedIdentifier(obfClassEntry)) { 221 if (!this.deobfuscator.isObfuscatedIdentifier(obfClassEntry)) {
252 throw new IllegalArgumentException("Obfuscated class " + obfClassEntry + " was not found in the jar!"); 222 throw new IllegalArgumentException("Obfuscated class " + obfClassEntry + " was not found in the jar!");
253 } 223 }
254 if (m_currentObfClass == null || !m_currentObfClass.equals(obfClassEntry)) { 224 if (this.currentObfClass == null || !this.currentObfClass.equals(obfClassEntry)) {
255 // deobfuscate the class, then navigate to the reference 225 // deobfuscate the class, then navigate to the reference
256 m_currentObfClass = obfClassEntry; 226 this.currentObfClass = obfClassEntry;
257 deobfuscate(m_currentObfClass, obfReference); 227 deobfuscate(this.currentObfClass, obfReference);
258 } else { 228 } else {
259 showReference(obfReference); 229 showReference(obfReference);
260 } 230 }
261 } 231 }
262 232
263 private void showReference(EntryReference<Entry, Entry> obfReference) { 233 private void showReference(EntryReference<Entry, Entry> obfReference) {
264 EntryReference<Entry, Entry> deobfReference = m_deobfuscator.deobfuscateReference(obfReference); 234 EntryReference<Entry, Entry> deobfReference = this.deobfuscator.deobfuscateReference(obfReference);
265 Collection<Token> tokens = m_index.getReferenceTokens(deobfReference); 235 Collection<Token> tokens = this.index.getReferenceTokens(deobfReference);
266 if (tokens.isEmpty()) { 236 if (tokens.isEmpty()) {
267 // DEBUG 237 // DEBUG
268 System.err.println(String.format("WARNING: no tokens found for %s in %s", deobfReference, m_currentObfClass)); 238 System.err.println(String.format("WARNING: no tokens found for %s in %s", deobfReference, this.currentObfClass));
269 } else { 239 } else {
270 m_gui.showTokens(tokens); 240 this.gui.showTokens(tokens);
271 } 241 }
272 } 242 }
273 243
274 public void savePreviousReference(EntryReference<Entry, Entry> deobfReference) { 244 public void savePreviousReference(EntryReference<Entry, Entry> deobfReference) {
275 m_referenceStack.push(m_deobfuscator.obfuscateReference(deobfReference)); 245 this.referenceStack.push(this.deobfuscator.obfuscateReference(deobfReference));
276 } 246 }
277 247
278 public void openPreviousReference() { 248 public void openPreviousReference() {
279 if (hasPreviousLocation()) { 249 if (hasPreviousLocation()) {
280 openReference(m_deobfuscator.deobfuscateReference(m_referenceStack.pop())); 250 openReference(this.deobfuscator.deobfuscateReference(this.referenceStack.pop()));
281 } 251 }
282 } 252 }
283 253
284 public boolean hasPreviousLocation() { 254 public boolean hasPreviousLocation() {
285 return !m_referenceStack.isEmpty(); 255 return !this.referenceStack.isEmpty();
286 } 256 }
287 257
288 private void refreshClasses() { 258 private void refreshClasses() {
289 List<ClassEntry> obfClasses = Lists.newArrayList(); 259 List<ClassEntry> obfClasses = Lists.newArrayList();
290 List<ClassEntry> deobfClasses = Lists.newArrayList(); 260 List<ClassEntry> deobfClasses = Lists.newArrayList();
291 m_deobfuscator.getSeparatedClasses(obfClasses, deobfClasses); 261 this.deobfuscator.getSeparatedClasses(obfClasses, deobfClasses);
292 m_gui.setObfClasses(obfClasses); 262 this.gui.setObfClasses(obfClasses);
293 m_gui.setDeobfClasses(deobfClasses); 263 this.gui.setDeobfClasses(deobfClasses);
294 } 264 }
295 265
296 private void refreshCurrentClass() { 266 private void refreshCurrentClass() {
@@ -298,29 +268,29 @@ public class GuiController {
298 } 268 }
299 269
300 private void refreshCurrentClass(EntryReference<Entry, Entry> obfReference) { 270 private void refreshCurrentClass(EntryReference<Entry, Entry> obfReference) {
301 if (m_currentObfClass != null) { 271 if (this.currentObfClass != null) {
302 deobfuscate(m_currentObfClass, obfReference); 272 deobfuscate(this.currentObfClass, obfReference);
303 } 273 }
304 } 274 }
305 275
306 private void deobfuscate(final ClassEntry classEntry, final EntryReference<Entry, Entry> obfReference) { 276 private void deobfuscate(final ClassEntry classEntry, final EntryReference<Entry, Entry> obfReference) {
307 277
308 m_gui.setSource("(deobfuscating...)"); 278 this.gui.setSource("(deobfuscating...)");
309 279
310 // run the deobfuscator in a separate thread so we don't block the GUI event queue 280 // run the deobfuscator in a separate thread so we don't block the GUI event queue
311 new Thread() { 281 new Thread() {
312 @Override 282 @Override
313 public void run() { 283 public void run() {
314 // decompile,deobfuscate the bytecode 284 // decompile,deobfuscate the bytecode
315 CompilationUnit sourceTree = m_deobfuscator.getSourceTree(classEntry.getClassName()); 285 CompilationUnit sourceTree = deobfuscator.getSourceTree(classEntry.getClassName());
316 if (sourceTree == null) { 286 if (sourceTree == null) {
317 // decompilation of this class is not supported 287 // decompilation of this class is not supported
318 m_gui.setSource("Unable to find class: " + classEntry); 288 gui.setSource("Unable to find class: " + classEntry);
319 return; 289 return;
320 } 290 }
321 String source = m_deobfuscator.getSource(sourceTree); 291 String source = deobfuscator.getSource(sourceTree);
322 m_index = m_deobfuscator.getSourceIndex(sourceTree, source); 292 index = deobfuscator.getSourceIndex(sourceTree, source);
323 m_gui.setSource(m_index.getSource()); 293 gui.setSource(index.getSource());
324 if (obfReference != null) { 294 if (obfReference != null) {
325 showReference(obfReference); 295 showReference(obfReference);
326 } 296 }
@@ -329,8 +299,8 @@ public class GuiController {
329 List<Token> obfuscatedTokens = Lists.newArrayList(); 299 List<Token> obfuscatedTokens = Lists.newArrayList();
330 List<Token> deobfuscatedTokens = Lists.newArrayList(); 300 List<Token> deobfuscatedTokens = Lists.newArrayList();
331 List<Token> otherTokens = Lists.newArrayList(); 301 List<Token> otherTokens = Lists.newArrayList();
332 for (Token token : m_index.referenceTokens()) { 302 for (Token token : index.referenceTokens()) {
333 EntryReference<Entry, Entry> reference = m_index.getDeobfReference(token); 303 EntryReference<Entry, Entry> reference = index.getDeobfReference(token);
334 if (referenceIsRenameable(reference)) { 304 if (referenceIsRenameable(reference)) {
335 if (entryHasDeobfuscatedName(reference.getNameableEntry())) { 305 if (entryHasDeobfuscatedName(reference.getNameableEntry())) {
336 deobfuscatedTokens.add(token); 306 deobfuscatedTokens.add(token);
@@ -341,7 +311,7 @@ public class GuiController {
341 otherTokens.add(token); 311 otherTokens.add(token);
342 } 312 }
343 } 313 }
344 m_gui.setHighlightedTokens(obfuscatedTokens, deobfuscatedTokens, otherTokens); 314 gui.setHighlightedTokens(obfuscatedTokens, deobfuscatedTokens, otherTokens);
345 } 315 }
346 }.start(); 316 }.start();
347 } 317 }
diff --git a/src/main/java/cuchaz/enigma/gui/GuiTricks.java b/src/main/java/cuchaz/enigma/gui/GuiTricks.java
index da2ec74f..ffacfecf 100644
--- a/src/main/java/cuchaz/enigma/gui/GuiTricks.java
+++ b/src/main/java/cuchaz/enigma/gui/GuiTricks.java
@@ -40,17 +40,13 @@ public class GuiTricks {
40 public static void deactivateButton(JButton button) { 40 public static void deactivateButton(JButton button) {
41 button.setEnabled(false); 41 button.setEnabled(false);
42 button.setText(""); 42 button.setText("");
43 for (ActionListener listener : Arrays.asList(button.getActionListeners())) { 43 Arrays.asList(button.getActionListeners()).forEach(button::removeActionListener);
44 button.removeActionListener(listener);
45 }
46 } 44 }
47 45
48 public static void activateButton(JButton button, String text, ActionListener newListener) { 46 public static void activateButton(JButton button, String text, ActionListener newListener) {
49 button.setText(text); 47 button.setText(text);
50 button.setEnabled(true); 48 button.setEnabled(true);
51 for (ActionListener listener : Arrays.asList(button.getActionListeners())) { 49 Arrays.asList(button.getActionListeners()).forEach(button::removeActionListener);
52 button.removeActionListener(listener);
53 }
54 button.addActionListener(newListener); 50 button.addActionListener(newListener);
55 } 51 }
56} 52}
diff --git a/src/main/java/cuchaz/enigma/gui/MemberMatchingGui.java b/src/main/java/cuchaz/enigma/gui/MemberMatchingGui.java
index 4b79b77c..f083e50f 100644
--- a/src/main/java/cuchaz/enigma/gui/MemberMatchingGui.java
+++ b/src/main/java/cuchaz/enigma/gui/MemberMatchingGui.java
@@ -17,7 +17,6 @@ import java.awt.BorderLayout;
17import java.awt.Container; 17import java.awt.Container;
18import java.awt.Dimension; 18import java.awt.Dimension;
19import java.awt.FlowLayout; 19import java.awt.FlowLayout;
20import java.awt.event.ActionEvent;
21import java.awt.event.ActionListener; 20import java.awt.event.ActionListener;
22import java.awt.event.KeyAdapter; 21import java.awt.event.KeyAdapter;
23import java.awt.event.KeyEvent; 22import java.awt.event.KeyEvent;
@@ -30,12 +29,10 @@ import javax.swing.text.Highlighter.HighlightPainter;
30 29
31import cuchaz.enigma.Constants; 30import cuchaz.enigma.Constants;
32import cuchaz.enigma.Deobfuscator; 31import cuchaz.enigma.Deobfuscator;
33import cuchaz.enigma.analysis.EntryReference;
34import cuchaz.enigma.analysis.SourceIndex; 32import cuchaz.enigma.analysis.SourceIndex;
35import cuchaz.enigma.analysis.Token; 33import cuchaz.enigma.analysis.Token;
36import cuchaz.enigma.convert.ClassMatches; 34import cuchaz.enigma.convert.ClassMatches;
37import cuchaz.enigma.convert.MemberMatches; 35import cuchaz.enigma.convert.MemberMatches;
38import cuchaz.enigma.gui.ClassSelector.ClassSelectionListener;
39import cuchaz.enigma.mapping.ClassEntry; 36import cuchaz.enigma.mapping.ClassEntry;
40import cuchaz.enigma.mapping.Entry; 37import cuchaz.enigma.mapping.Entry;
41import de.sciss.syntaxpane.DefaultSyntaxKit; 38import de.sciss.syntaxpane.DefaultSyntaxKit;
@@ -108,7 +105,7 @@ public class MemberMatchingGui<T extends Entry> {
108 m_destDeobfuscator = destDeobfuscator; 105 m_destDeobfuscator = destDeobfuscator;
109 106
110 // init frame 107 // init frame
111 m_frame = new JFrame(Constants.Name + " - Member Matcher"); 108 m_frame = new JFrame(Constants.NAME + " - Member Matcher");
112 final Container pane = m_frame.getContentPane(); 109 final Container pane = m_frame.getContentPane();
113 pane.setLayout(new BorderLayout()); 110 pane.setLayout(new BorderLayout());
114 111
@@ -123,12 +120,7 @@ public class MemberMatchingGui<T extends Entry> {
123 JPanel sourceTypePanel = new JPanel(); 120 JPanel sourceTypePanel = new JPanel();
124 classesPanel.add(sourceTypePanel); 121 classesPanel.add(sourceTypePanel);
125 sourceTypePanel.setLayout(new BoxLayout(sourceTypePanel, BoxLayout.PAGE_AXIS)); 122 sourceTypePanel.setLayout(new BoxLayout(sourceTypePanel, BoxLayout.PAGE_AXIS));
126 ActionListener sourceTypeListener = new ActionListener() { 123 ActionListener sourceTypeListener = event -> setSourceType(SourceType.valueOf(event.getActionCommand()));
127 @Override
128 public void actionPerformed(ActionEvent event) {
129 setSourceType(SourceType.valueOf(event.getActionCommand()));
130 }
131 };
132 ButtonGroup sourceTypeButtons = new ButtonGroup(); 124 ButtonGroup sourceTypeButtons = new ButtonGroup();
133 m_sourceTypeButtons = Maps.newHashMap(); 125 m_sourceTypeButtons = Maps.newHashMap();
134 for (SourceType sourceType : SourceType.values()) { 126 for (SourceType sourceType : SourceType.values()) {
@@ -138,37 +130,26 @@ public class MemberMatchingGui<T extends Entry> {
138 } 130 }
139 131
140 m_sourceClasses = new ClassSelector(ClassSelector.DeobfuscatedClassEntryComparator); 132 m_sourceClasses = new ClassSelector(ClassSelector.DeobfuscatedClassEntryComparator);
141 m_sourceClasses.setListener(new ClassSelectionListener() { 133 m_sourceClasses.setListener(this::setSourceClass);
142 @Override
143 public void onSelectClass(ClassEntry classEntry) {
144 setSourceClass(classEntry);
145 }
146 });
147 JScrollPane sourceScroller = new JScrollPane(m_sourceClasses); 134 JScrollPane sourceScroller = new JScrollPane(m_sourceClasses);
148 classesPanel.add(sourceScroller); 135 classesPanel.add(sourceScroller);
149 136
150 // init readers 137 // init readers
151 DefaultSyntaxKit.initKit(); 138 DefaultSyntaxKit.initKit();
152 m_sourceReader = new CodeReader(); 139 m_sourceReader = new CodeReader();
153 m_sourceReader.setSelectionListener(new CodeReader.SelectionListener() { 140 m_sourceReader.setSelectionListener(reference -> {
154 @Override 141 if (reference != null) {
155 public void onSelect(EntryReference<Entry, Entry> reference) { 142 onSelectSource(reference.entry);
156 if (reference != null) { 143 } else {
157 onSelectSource(reference.entry); 144 onSelectSource(null);
158 } else {
159 onSelectSource(null);
160 }
161 } 145 }
162 }); 146 });
163 m_destReader = new CodeReader(); 147 m_destReader = new CodeReader();
164 m_destReader.setSelectionListener(new CodeReader.SelectionListener() { 148 m_destReader.setSelectionListener(reference -> {
165 @Override 149 if (reference != null) {
166 public void onSelect(EntryReference<Entry, Entry> reference) { 150 onSelectDest(reference.entry);
167 if (reference != null) { 151 } else {
168 onSelectDest(reference.entry); 152 onSelectDest(null);
169 } else {
170 onSelectDest(null);
171 }
172 } 153 }
173 }); 154 });
174 155
@@ -267,18 +248,8 @@ public class MemberMatchingGui<T extends Entry> {
267 throw new Error("No matching dest class for source class: " + m_obfSourceClass); 248 throw new Error("No matching dest class for source class: " + m_obfSourceClass);
268 } 249 }
269 250
270 m_sourceReader.decompileClass(m_obfSourceClass, m_sourceDeobfuscator, false, new Runnable() { 251 m_sourceReader.decompileClass(m_obfSourceClass, m_sourceDeobfuscator, false, this::updateSourceHighlights);
271 @Override 252 m_destReader.decompileClass(m_obfDestClass, m_destDeobfuscator, false, this::updateDestHighlights);
272 public void run() {
273 updateSourceHighlights();
274 }
275 });
276 m_destReader.decompileClass(m_obfDestClass, m_destDeobfuscator, false, new Runnable() {
277 @Override
278 public void run() {
279 updateDestHighlights();
280 }
281 });
282 } 253 }
283 254
284 protected void updateSourceHighlights() { 255 protected void updateSourceHighlights() {
@@ -382,21 +353,19 @@ public class MemberMatchingGui<T extends Entry> {
382 } 353 }
383 354
384 private void setSource(T obfEntry) { 355 private void setSource(T obfEntry) {
356 m_obfSourceEntry = obfEntry;
385 if (obfEntry == null) { 357 if (obfEntry == null) {
386 m_obfSourceEntry = obfEntry;
387 m_sourceLabel.setText(""); 358 m_sourceLabel.setText("");
388 } else { 359 } else {
389 m_obfSourceEntry = obfEntry;
390 m_sourceLabel.setText(getEntryLabel(obfEntry, m_sourceDeobfuscator)); 360 m_sourceLabel.setText(getEntryLabel(obfEntry, m_sourceDeobfuscator));
391 } 361 }
392 } 362 }
393 363
394 private void setDest(T obfEntry) { 364 private void setDest(T obfEntry) {
365 m_obfDestEntry = obfEntry;
395 if (obfEntry == null) { 366 if (obfEntry == null) {
396 m_obfDestEntry = obfEntry;
397 m_destLabel.setText(""); 367 m_destLabel.setText("");
398 } else { 368 } else {
399 m_obfDestEntry = obfEntry;
400 m_destLabel.setText(getEntryLabel(obfEntry, m_destDeobfuscator)); 369 m_destLabel.setText(getEntryLabel(obfEntry, m_destDeobfuscator));
401 } 370 }
402 } 371 }
@@ -414,27 +383,12 @@ public class MemberMatchingGui<T extends Entry> {
414 383
415 if (m_obfSourceEntry != null && m_obfDestEntry != null) { 384 if (m_obfSourceEntry != null && m_obfDestEntry != null) {
416 if (m_memberMatches.isMatched(m_obfSourceEntry, m_obfDestEntry)) { 385 if (m_memberMatches.isMatched(m_obfSourceEntry, m_obfDestEntry)) {
417 GuiTricks.activateButton(m_matchButton, "Unmatch", new ActionListener() { 386 GuiTricks.activateButton(m_matchButton, "Unmatch", event -> unmatch());
418 @Override
419 public void actionPerformed(ActionEvent event) {
420 unmatch();
421 }
422 });
423 } else if (!m_memberMatches.isMatchedSourceEntry(m_obfSourceEntry) && !m_memberMatches.isMatchedDestEntry(m_obfDestEntry)) { 387 } else if (!m_memberMatches.isMatchedSourceEntry(m_obfSourceEntry) && !m_memberMatches.isMatchedDestEntry(m_obfDestEntry)) {
424 GuiTricks.activateButton(m_matchButton, "Match", new ActionListener() { 388 GuiTricks.activateButton(m_matchButton, "Match", event -> match());
425 @Override
426 public void actionPerformed(ActionEvent event) {
427 match();
428 }
429 });
430 } 389 }
431 } else if (m_obfSourceEntry != null) { 390 } else if (m_obfSourceEntry != null) {
432 GuiTricks.activateButton(m_unmatchableButton, "Set Unmatchable", new ActionListener() { 391 GuiTricks.activateButton(m_unmatchableButton, "Set Unmatchable", event -> unmatchable());
433 @Override
434 public void actionPerformed(ActionEvent event) {
435 unmatchable();
436 }
437 });
438 } 392 }
439 } 393 }
440 394
diff --git a/src/main/java/cuchaz/enigma/gui/ObfuscatedHighlightPainter.java b/src/main/java/cuchaz/enigma/gui/ObfuscatedHighlightPainter.java
index caaf99c3..5afc767f 100644
--- a/src/main/java/cuchaz/enigma/gui/ObfuscatedHighlightPainter.java
+++ b/src/main/java/cuchaz/enigma/gui/ObfuscatedHighlightPainter.java
@@ -15,7 +15,6 @@ import java.awt.Color;
15public class ObfuscatedHighlightPainter extends BoxHighlightPainter { 15public class ObfuscatedHighlightPainter extends BoxHighlightPainter {
16 16
17 public ObfuscatedHighlightPainter() { 17 public ObfuscatedHighlightPainter() {
18 // red ish
19 super(new Color(255, 220, 220), new Color(160, 80, 80)); 18 super(new Color(255, 220, 220), new Color(160, 80, 80));
20 } 19 }
21} 20}
diff --git a/src/main/java/cuchaz/enigma/gui/OtherHighlightPainter.java b/src/main/java/cuchaz/enigma/gui/OtherHighlightPainter.java
index d2a2f02f..256f69eb 100644
--- a/src/main/java/cuchaz/enigma/gui/OtherHighlightPainter.java
+++ b/src/main/java/cuchaz/enigma/gui/OtherHighlightPainter.java
@@ -15,7 +15,6 @@ import java.awt.Color;
15public class OtherHighlightPainter extends BoxHighlightPainter { 15public class OtherHighlightPainter extends BoxHighlightPainter {
16 16
17 public OtherHighlightPainter() { 17 public OtherHighlightPainter() {
18 // grey
19 super(null, new Color(180, 180, 180)); 18 super(null, new Color(180, 180, 180));
20 } 19 }
21} 20}
diff --git a/src/main/java/cuchaz/enigma/gui/ProgressDialog.java b/src/main/java/cuchaz/enigma/gui/ProgressDialog.java
index 087d843b..70bca15b 100644
--- a/src/main/java/cuchaz/enigma/gui/ProgressDialog.java
+++ b/src/main/java/cuchaz/enigma/gui/ProgressDialog.java
@@ -22,63 +22,63 @@ import cuchaz.enigma.Deobfuscator.ProgressListener;
22 22
23public class ProgressDialog implements ProgressListener, AutoCloseable { 23public class ProgressDialog implements ProgressListener, AutoCloseable {
24 24
25 private JFrame m_frame; 25 private JFrame frame;
26 private JLabel m_title; 26 private JLabel labelTitle;
27 private JLabel m_text; 27 private JLabel labelText;
28 private JProgressBar m_progress; 28 private JProgressBar progress;
29 29
30 public ProgressDialog(JFrame parent) { 30 public ProgressDialog(JFrame parent) {
31 31
32 // init frame 32 // init frame
33 m_frame = new JFrame(Constants.Name + " - Operation in progress"); 33 this.frame = new JFrame(Constants.NAME + " - Operation in progress");
34 final Container pane = m_frame.getContentPane(); 34 final Container pane = this.frame.getContentPane();
35 FlowLayout layout = new FlowLayout(); 35 FlowLayout layout = new FlowLayout();
36 layout.setAlignment(FlowLayout.LEFT); 36 layout.setAlignment(FlowLayout.LEFT);
37 pane.setLayout(layout); 37 pane.setLayout(layout);
38 38
39 m_title = new JLabel(); 39 this.labelTitle = new JLabel();
40 pane.add(m_title); 40 pane.add(this.labelTitle);
41 41
42 // set up the progress bar 42 // set up the progress bar
43 JPanel panel = new JPanel(); 43 JPanel panel = new JPanel();
44 pane.add(panel); 44 pane.add(panel);
45 panel.setLayout(new BorderLayout()); 45 panel.setLayout(new BorderLayout());
46 m_text = GuiTricks.unboldLabel(new JLabel()); 46 this.labelText = GuiTricks.unboldLabel(new JLabel());
47 m_progress = new JProgressBar(); 47 this.progress = new JProgressBar();
48 m_text.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); 48 this.labelText.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
49 panel.add(m_text, BorderLayout.NORTH); 49 panel.add(this.labelText, BorderLayout.NORTH);
50 panel.add(m_progress, BorderLayout.CENTER); 50 panel.add(this.progress, BorderLayout.CENTER);
51 panel.setPreferredSize(new Dimension(360, 50)); 51 panel.setPreferredSize(new Dimension(360, 50));
52 52
53 // show the frame 53 // show the frame
54 pane.doLayout(); 54 pane.doLayout();
55 m_frame.setSize(400, 120); 55 this.frame.setSize(400, 120);
56 m_frame.setResizable(false); 56 this.frame.setResizable(false);
57 m_frame.setLocationRelativeTo(parent); 57 this.frame.setLocationRelativeTo(parent);
58 m_frame.setVisible(true); 58 this.frame.setVisible(true);
59 m_frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 59 this.frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
60 } 60 }
61 61
62 public void close() { 62 public void close() {
63 m_frame.dispose(); 63 this.frame.dispose();
64 } 64 }
65 65
66 @Override 66 @Override
67 public void init(int totalWork, String title) { 67 public void init(int totalWork, String title) {
68 m_title.setText(title); 68 this.labelTitle.setText(title);
69 m_progress.setMinimum(0); 69 this.progress.setMinimum(0);
70 m_progress.setMaximum(totalWork); 70 this.progress.setMaximum(totalWork);
71 m_progress.setValue(0); 71 this.progress.setValue(0);
72 } 72 }
73 73
74 @Override 74 @Override
75 public void onProgress(int numDone, String message) { 75 public void onProgress(int numDone, String message) {
76 m_text.setText(message); 76 this.labelText.setText(message);
77 m_progress.setValue(numDone); 77 this.progress.setValue(numDone);
78 78
79 // update the frame 79 // update the frame
80 m_frame.validate(); 80 this.frame.validate();
81 m_frame.repaint(); 81 this.frame.repaint();
82 } 82 }
83 83
84 public interface ProgressRunnable { 84 public interface ProgressRunnable {
diff --git a/src/main/java/cuchaz/enigma/gui/RenameListener.java b/src/main/java/cuchaz/enigma/gui/RenameListener.java
deleted file mode 100644
index f0f9dcc4..00000000
--- a/src/main/java/cuchaz/enigma/gui/RenameListener.java
+++ /dev/null
@@ -1,17 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Lesser General Public
5 * License v3.0 which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/lgpl.html
7 * <p>
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.gui;
12
13import cuchaz.enigma.mapping.Entry;
14
15public interface RenameListener {
16 void rename(Entry obfEntry, String newName);
17}
diff --git a/src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java b/src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java
index d1e2de0e..359ec7ae 100644
--- a/src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java
+++ b/src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java
@@ -12,19 +12,18 @@ package cuchaz.enigma.gui;
12 12
13import cuchaz.enigma.mapping.ClassEntry; 13import cuchaz.enigma.mapping.ClassEntry;
14 14
15
16public class ScoredClassEntry extends ClassEntry { 15public class ScoredClassEntry extends ClassEntry {
17 16
18 private static final long serialVersionUID = -8798725308554217105L; 17 private static final long serialVersionUID = -8798725308554217105L;
19 18
20 private float m_score; 19 private float score;
21 20
22 public ScoredClassEntry(ClassEntry other, float score) { 21 public ScoredClassEntry(ClassEntry other, float score) {
23 super(other); 22 super(other);
24 m_score = score; 23 this.score = score;
25 } 24 }
26 25
27 public float getScore() { 26 public float getScore() {
28 return m_score; 27 return this.score;
29 } 28 }
30} 29}
diff --git a/src/main/java/cuchaz/enigma/gui/TokenListCellRenderer.java b/src/main/java/cuchaz/enigma/gui/TokenListCellRenderer.java
index efc8df8b..518055fd 100644
--- a/src/main/java/cuchaz/enigma/gui/TokenListCellRenderer.java
+++ b/src/main/java/cuchaz/enigma/gui/TokenListCellRenderer.java
@@ -21,18 +21,18 @@ import cuchaz.enigma.analysis.Token;
21 21
22public class TokenListCellRenderer implements ListCellRenderer<Token> { 22public class TokenListCellRenderer implements ListCellRenderer<Token> {
23 23
24 private GuiController m_controller; 24 private GuiController controller;
25 private DefaultListCellRenderer m_defaultRenderer; 25 private DefaultListCellRenderer defaultRenderer;
26 26
27 public TokenListCellRenderer(GuiController controller) { 27 public TokenListCellRenderer(GuiController controller) {
28 m_controller = controller; 28 this.controller = controller;
29 m_defaultRenderer = new DefaultListCellRenderer(); 29 this.defaultRenderer = new DefaultListCellRenderer();
30 } 30 }
31 31
32 @Override 32 @Override
33 public Component getListCellRendererComponent(JList<? extends Token> list, Token token, int index, boolean isSelected, boolean hasFocus) { 33 public Component getListCellRendererComponent(JList<? extends Token> list, Token token, int index, boolean isSelected, boolean hasFocus) {
34 JLabel label = (JLabel) m_defaultRenderer.getListCellRendererComponent(list, token, index, isSelected, hasFocus); 34 JLabel label = (JLabel) this.defaultRenderer.getListCellRendererComponent(list, token, index, isSelected, hasFocus);
35 label.setText(m_controller.getReadableToken(token).toString()); 35 label.setText(this.controller.getReadableToken(token).toString());
36 return label; 36 return label;
37 } 37 }
38} 38}
diff --git a/src/main/java/cuchaz/enigma/mapping/ArgumentEntry.java b/src/main/java/cuchaz/enigma/mapping/ArgumentEntry.java
index 886e7be2..c89f7e33 100644
--- a/src/main/java/cuchaz/enigma/mapping/ArgumentEntry.java
+++ b/src/main/java/cuchaz/enigma/mapping/ArgumentEntry.java
@@ -97,10 +97,7 @@ public class ArgumentEntry implements Entry, Serializable {
97 97
98 @Override 98 @Override
99 public boolean equals(Object other) { 99 public boolean equals(Object other) {
100 if (other instanceof ArgumentEntry) { 100 return other instanceof ArgumentEntry && equals((ArgumentEntry) other);
101 return equals((ArgumentEntry) other);
102 }
103 return false;
104 } 101 }
105 102
106 public boolean equals(ArgumentEntry other) { 103 public boolean equals(ArgumentEntry other) {
diff --git a/src/main/java/cuchaz/enigma/mapping/ClassMapping.java b/src/main/java/cuchaz/enigma/mapping/ClassMapping.java
index 84fb6dd8..99e463de 100644
--- a/src/main/java/cuchaz/enigma/mapping/ClassMapping.java
+++ b/src/main/java/cuchaz/enigma/mapping/ClassMapping.java
@@ -444,10 +444,7 @@ public class ClassMapping implements Serializable, Comparable<ClassMapping> {
444 444
445 public boolean containsArgument(BehaviorEntry obfBehaviorEntry, String name) { 445 public boolean containsArgument(BehaviorEntry obfBehaviorEntry, String name) {
446 MethodMapping methodMapping = m_methodsByObf.get(getMethodKey(obfBehaviorEntry.getName(), obfBehaviorEntry.getSignature())); 446 MethodMapping methodMapping = m_methodsByObf.get(getMethodKey(obfBehaviorEntry.getName(), obfBehaviorEntry.getSignature()));
447 if (methodMapping != null) { 447 return methodMapping != null && methodMapping.containsArgument(name);
448 return methodMapping.containsArgument(name);
449 }
450 return false;
451 } 448 }
452 449
453 public static boolean isSimpleClassName(String name) { 450 public static boolean isSimpleClassName(String name) {
diff --git a/src/main/java/cuchaz/enigma/mapping/ConstructorEntry.java b/src/main/java/cuchaz/enigma/mapping/ConstructorEntry.java
index 907bd4ce..ac1a7f2b 100644
--- a/src/main/java/cuchaz/enigma/mapping/ConstructorEntry.java
+++ b/src/main/java/cuchaz/enigma/mapping/ConstructorEntry.java
@@ -87,10 +87,7 @@ public class ConstructorEntry implements BehaviorEntry, Serializable {
87 87
88 @Override 88 @Override
89 public boolean equals(Object other) { 89 public boolean equals(Object other) {
90 if (other instanceof ConstructorEntry) { 90 return other instanceof ConstructorEntry && equals((ConstructorEntry) other);
91 return equals((ConstructorEntry) other);
92 }
93 return false;
94 } 91 }
95 92
96 public boolean equals(ConstructorEntry other) { 93 public boolean equals(ConstructorEntry other) {
diff --git a/src/main/java/cuchaz/enigma/mapping/FieldMapping.java b/src/main/java/cuchaz/enigma/mapping/FieldMapping.java
index 3f5a3822..19d68a97 100644
--- a/src/main/java/cuchaz/enigma/mapping/FieldMapping.java
+++ b/src/main/java/cuchaz/enigma/mapping/FieldMapping.java
@@ -16,67 +16,64 @@ public class FieldMapping implements Serializable, Comparable<FieldMapping>, Mem
16 16
17 private static final long serialVersionUID = 8610742471440861315L; 17 private static final long serialVersionUID = 8610742471440861315L;
18 18
19 private String m_obfName; 19 private String obfName;
20 private String m_deobfName; 20 private String deobfName;
21 private Type m_obfType; 21 private Type obfType;
22 22
23 public FieldMapping(String obfName, Type obfType, String deobfName) { 23 public FieldMapping(String obfName, Type obfType, String deobfName) {
24 m_obfName = obfName; 24 this.obfName = obfName;
25 m_deobfName = NameValidator.validateFieldName(deobfName); 25 this.deobfName = NameValidator.validateFieldName(deobfName);
26 m_obfType = obfType; 26 this.obfType = obfType;
27 } 27 }
28 28
29 public FieldMapping(FieldMapping other, ClassNameReplacer obfClassNameReplacer) { 29 public FieldMapping(FieldMapping other, ClassNameReplacer obfClassNameReplacer) {
30 m_obfName = other.m_obfName; 30 this.obfName = other.obfName;
31 m_deobfName = other.m_deobfName; 31 this.deobfName = other.deobfName;
32 m_obfType = new Type(other.m_obfType, obfClassNameReplacer); 32 this.obfType = new Type(other.obfType, obfClassNameReplacer);
33 } 33 }
34 34
35 @Override 35 @Override
36 public String getObfName() { 36 public String getObfName() {
37 return m_obfName; 37 return this.obfName;
38 } 38 }
39 39
40 public void setObfName(String val) { 40 public void setObfName(String val) {
41 m_obfName = NameValidator.validateFieldName(val); 41 this.obfName = NameValidator.validateFieldName(val);
42 } 42 }
43 43
44 public String getDeobfName() { 44 public String getDeobfName() {
45 return m_deobfName; 45 return this.deobfName;
46 } 46 }
47 47
48 public void setDeobfName(String val) { 48 public void setDeobfName(String val) {
49 m_deobfName = NameValidator.validateFieldName(val); 49 this.deobfName = NameValidator.validateFieldName(val);
50 } 50 }
51 51
52 public Type getObfType() { 52 public Type getObfType() {
53 return m_obfType; 53 return this.obfType;
54 } 54 }
55 55
56 public void setObfType(Type val) { 56 public void setObfType(Type val) {
57 m_obfType = val; 57 this.obfType = val;
58 } 58 }
59 59
60 @Override 60 @Override
61 public int compareTo(FieldMapping other) { 61 public int compareTo(FieldMapping other) {
62 return (m_obfName + m_obfType).compareTo(other.m_obfName + other.m_obfType); 62 return (this.obfName + this.obfType).compareTo(other.obfName + other.obfType);
63 } 63 }
64 64
65 public boolean renameObfClass(final String oldObfClassName, final String newObfClassName) { 65 public boolean renameObfClass(final String oldObfClassName, final String newObfClassName) {
66 66
67 // rename obf classes in the type 67 // rename obf classes in the type
68 Type newType = new Type(m_obfType, new ClassNameReplacer() { 68 Type newType = new Type(this.obfType, className -> {
69 @Override 69 if (className.equals(oldObfClassName)) {
70 public String replace(String className) { 70 return newObfClassName;
71 if (className.equals(oldObfClassName)) {
72 return newObfClassName;
73 }
74 return null;
75 } 71 }
72 return null;
76 }); 73 });
77 74
78 if (!newType.equals(m_obfType)) { 75 if (!newType.equals(this.obfType)) {
79 m_obfType = newType; 76 this.obfType = newType;
80 return true; 77 return true;
81 } 78 }
82 return false; 79 return false;
@@ -84,6 +81,6 @@ public class FieldMapping implements Serializable, Comparable<FieldMapping>, Mem
84 81
85 @Override 82 @Override
86 public FieldEntry getObfEntry(ClassEntry classEntry) { 83 public FieldEntry getObfEntry(ClassEntry classEntry) {
87 return new FieldEntry(classEntry, m_obfName, new Type(m_obfType)); 84 return new FieldEntry(classEntry, this.obfName, new Type(this.obfType));
88 } 85 }
89} 86}
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsChecker.java b/src/main/java/cuchaz/enigma/mapping/MappingsChecker.java
index 5e2b40b2..d8507877 100644
--- a/src/main/java/cuchaz/enigma/mapping/MappingsChecker.java
+++ b/src/main/java/cuchaz/enigma/mapping/MappingsChecker.java
@@ -16,13 +16,11 @@ import com.google.common.collect.Maps;
16import java.util.Map; 16import java.util.Map;
17 17
18import cuchaz.enigma.analysis.JarIndex; 18import cuchaz.enigma.analysis.JarIndex;
19import cuchaz.enigma.analysis.RelatedMethodChecker;
20 19
21 20
22public class MappingsChecker { 21public class MappingsChecker {
23 22
24 private JarIndex m_index; 23 private JarIndex m_index;
25 private RelatedMethodChecker m_relatedMethodChecker;
26 private Map<ClassEntry, ClassMapping> m_droppedClassMappings; 24 private Map<ClassEntry, ClassMapping> m_droppedClassMappings;
27 private Map<ClassEntry, ClassMapping> m_droppedInnerClassMappings; 25 private Map<ClassEntry, ClassMapping> m_droppedInnerClassMappings;
28 private Map<FieldEntry, FieldMapping> m_droppedFieldMappings; 26 private Map<FieldEntry, FieldMapping> m_droppedFieldMappings;
@@ -30,17 +28,12 @@ public class MappingsChecker {
30 28
31 public MappingsChecker(JarIndex index) { 29 public MappingsChecker(JarIndex index) {
32 m_index = index; 30 m_index = index;
33 m_relatedMethodChecker = new RelatedMethodChecker(m_index);
34 m_droppedClassMappings = Maps.newHashMap(); 31 m_droppedClassMappings = Maps.newHashMap();
35 m_droppedInnerClassMappings = Maps.newHashMap(); 32 m_droppedInnerClassMappings = Maps.newHashMap();
36 m_droppedFieldMappings = Maps.newHashMap(); 33 m_droppedFieldMappings = Maps.newHashMap();
37 m_droppedMethodMappings = Maps.newHashMap(); 34 m_droppedMethodMappings = Maps.newHashMap();
38 } 35 }
39 36
40 public RelatedMethodChecker getRelatedMethodChecker() {
41 return m_relatedMethodChecker;
42 }
43
44 public Map<ClassEntry, ClassMapping> getDroppedClassMappings() { 37 public Map<ClassEntry, ClassMapping> getDroppedClassMappings() {
45 return m_droppedClassMappings; 38 return m_droppedClassMappings;
46 } 39 }
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsReader.java b/src/main/java/cuchaz/enigma/mapping/MappingsReader.java
index b2c3a5c0..d1edb9b6 100644
--- a/src/main/java/cuchaz/enigma/mapping/MappingsReader.java
+++ b/src/main/java/cuchaz/enigma/mapping/MappingsReader.java
@@ -31,19 +31,21 @@ public class MappingsReader {
31 public void readDirectory(Mappings mappings, File in) throws IOException, MappingParseException { 31 public void readDirectory(Mappings mappings, File in) throws IOException, MappingParseException {
32 32
33 File[] fList = in.listFiles(); 33 File[] fList = in.listFiles();
34 for (File file : fList) { 34 if (fList != null) {
35 if (file.isFile()) { 35 for (File file : fList) {
36 readFile(mappings, new BufferedReader(new FileReader(file))); 36 if (file.isFile()) {
37 } else if (file.isDirectory()) { 37 readFile(mappings, new BufferedReader(new FileReader(file)));
38 readDirectory(mappings, file.getAbsoluteFile()); 38 } else if (file.isDirectory()) {
39 readDirectory(mappings, file.getAbsoluteFile());
40 }
39 } 41 }
40 } 42 }
41 } 43 }
42 44
43 public void readFile(Mappings mappings, BufferedReader in) throws IOException, MappingParseException { 45 public void readFile(Mappings mappings, BufferedReader in) throws IOException, MappingParseException {
44 46
45 StringBuffer buf = new StringBuffer(); 47 StringBuilder buf = new StringBuilder();
46 String line = null; 48 String line;
47 while ((line = in.readLine()) != null) { 49 while ((line = in.readLine()) != null) {
48 buf.append(line); 50 buf.append(line);
49 } 51 }
@@ -63,10 +65,10 @@ public class MappingsReader {
63 jsonClass.getField().forEach(jsonField -> classMapping.addFieldMapping(readField(jsonField.getObf(), jsonField.getName(), jsonField.getType()))); 65 jsonClass.getField().forEach(jsonField -> classMapping.addFieldMapping(readField(jsonField.getObf(), jsonField.getName(), jsonField.getType())));
64 66
65 jsonClass.getConstructors().forEach(jsonConstructor -> { 67 jsonClass.getConstructors().forEach(jsonConstructor -> {
66 MethodMapping methodMapping = readMethod(jsonConstructor.isStatics() ? "<clinit>" : "<init>", null, jsonConstructor.getSignature()); 68 MethodMapping methodMapping = readMethod(jsonConstructor.isStatics() ? "<clinit>" : "<init>", null, jsonConstructor.getSignature());
67 jsonConstructor.getArgs().forEach(jsonArgument -> methodMapping.addArgumentMapping(readArgument(jsonArgument.getIndex(), jsonArgument.getName()))); 69 jsonConstructor.getArgs().forEach(jsonArgument -> methodMapping.addArgumentMapping(readArgument(jsonArgument.getIndex(), jsonArgument.getName())));
68 classMapping.addMethodMapping(methodMapping); 70 classMapping.addMethodMapping(methodMapping);
69 }); 71 });
70 72
71 jsonClass.getMethod().forEach(jsonMethod -> { 73 jsonClass.getMethod().forEach(jsonMethod -> {
72 MethodMapping methodMapping = readMethod(jsonMethod.getObf(), jsonMethod.getName(), jsonMethod.getSignature()); 74 MethodMapping methodMapping = readMethod(jsonMethod.getObf(), jsonMethod.getName(), jsonMethod.getSignature());
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsReaderOld.java b/src/main/java/cuchaz/enigma/mapping/MappingsReaderOld.java
index 1a93604a..a23a33fa 100644
--- a/src/main/java/cuchaz/enigma/mapping/MappingsReaderOld.java
+++ b/src/main/java/cuchaz/enigma/mapping/MappingsReaderOld.java
@@ -18,7 +18,7 @@ public class MappingsReaderOld {
18 Deque<Object> mappingStack = Queues.newArrayDeque(); 18 Deque<Object> mappingStack = Queues.newArrayDeque();
19 19
20 int lineNumber = 0; 20 int lineNumber = 0;
21 String line = null; 21 String line;
22 while ((line = in.readLine()) != null) { 22 while ((line = in.readLine()) != null) {
23 lineNumber++; 23 lineNumber++;
24 24
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java b/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java
index de1635aa..2b112a24 100644
--- a/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java
+++ b/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java
@@ -129,9 +129,7 @@ public class MappingsRenamer {
129 } 129 }
130 130
131 public void removeMethodTreeMapping(MethodEntry obf) { 131 public void removeMethodTreeMapping(MethodEntry obf) {
132 for (MethodEntry implementation : m_index.getRelatedMethodImplementations(obf)) { 132 m_index.getRelatedMethodImplementations(obf).forEach(this::removeMethodMapping);
133 removeMethodMapping(implementation);
134 }
135 } 133 }
136 134
137 public void removeMethodMapping(MethodEntry obf) { 135 public void removeMethodMapping(MethodEntry obf) {
@@ -140,9 +138,7 @@ public class MappingsRenamer {
140 } 138 }
141 139
142 public void markMethodTreeAsDeobfuscated(MethodEntry obf) { 140 public void markMethodTreeAsDeobfuscated(MethodEntry obf) {
143 for (MethodEntry implementation : m_index.getRelatedMethodImplementations(obf)) { 141 m_index.getRelatedMethodImplementations(obf).forEach(this::markMethodAsDeobfuscated);
144 markMethodAsDeobfuscated(implementation);
145 }
146 } 142 }
147 143
148 public void markMethodAsDeobfuscated(MethodEntry obf) { 144 public void markMethodAsDeobfuscated(MethodEntry obf) {
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsWriter.java b/src/main/java/cuchaz/enigma/mapping/MappingsWriter.java
index aaab22fa..bfd60638 100644
--- a/src/main/java/cuchaz/enigma/mapping/MappingsWriter.java
+++ b/src/main/java/cuchaz/enigma/mapping/MappingsWriter.java
@@ -76,7 +76,7 @@ public class MappingsWriter {
76 } 76 }
77 77
78 private <T extends Comparable<T>> List<T> sorted(Iterable<T> classes) { 78 private <T extends Comparable<T>> List<T> sorted(Iterable<T> classes) {
79 List<T> out = new ArrayList<T>(); 79 List<T> out = new ArrayList<>();
80 for (T t : classes) { 80 for (T t : classes) {
81 out.add(t); 81 out.add(t);
82 } 82 }
diff --git a/src/main/java/cuchaz/enigma/mapping/Signature.java b/src/main/java/cuchaz/enigma/mapping/Signature.java
index 117018ad..e2f9f091 100644
--- a/src/main/java/cuchaz/enigma/mapping/Signature.java
+++ b/src/main/java/cuchaz/enigma/mapping/Signature.java
@@ -91,10 +91,7 @@ public class Signature implements Serializable {
91 91
92 @Override 92 @Override
93 public boolean equals(Object other) { 93 public boolean equals(Object other) {
94 if (other instanceof Signature) { 94 return other instanceof Signature && equals((Signature) other);
95 return equals((Signature) other);
96 }
97 return false;
98 } 95 }
99 96
100 public boolean equals(Signature other) { 97 public boolean equals(Signature other) {
diff --git a/src/main/java/cuchaz/enigma/mapping/SignatureUpdater.java b/src/main/java/cuchaz/enigma/mapping/SignatureUpdater.java
index dac692e4..98643330 100644
--- a/src/main/java/cuchaz/enigma/mapping/SignatureUpdater.java
+++ b/src/main/java/cuchaz/enigma/mapping/SignatureUpdater.java
@@ -28,7 +28,7 @@ public class SignatureUpdater {
28 28
29 // read the signature character-by-character 29 // read the signature character-by-character
30 StringReader reader = new StringReader(signature); 30 StringReader reader = new StringReader(signature);
31 int i = -1; 31 int i;
32 while ((i = reader.read()) != -1) { 32 while ((i = reader.read()) != -1) {
33 char c = (char) i; 33 char c = (char) i;
34 34
@@ -60,7 +60,7 @@ public class SignatureUpdater {
60 // remember to treat generics correctly 60 // remember to treat generics correctly
61 StringBuilder buf = new StringBuilder(); 61 StringBuilder buf = new StringBuilder();
62 int depth = 0; 62 int depth = 0;
63 int i = -1; 63 int i;
64 while ((i = reader.read()) != -1) { 64 while ((i = reader.read()) != -1) {
65 char c = (char) i; 65 char c = (char) i;
66 66
@@ -82,12 +82,9 @@ public class SignatureUpdater {
82 82
83 public static List<String> getClasses(String signature) { 83 public static List<String> getClasses(String signature) {
84 final List<String> classNames = Lists.newArrayList(); 84 final List<String> classNames = Lists.newArrayList();
85 update(signature, new ClassNameUpdater() { 85 update(signature, className -> {
86 @Override 86 classNames.add(className);
87 public String update(String className) { 87 return className;
88 classNames.add(className);
89 return className;
90 }
91 }); 88 });
92 return classNames; 89 return classNames;
93 } 90 }
diff --git a/src/main/java/cuchaz/enigma/mapping/Translator.java b/src/main/java/cuchaz/enigma/mapping/Translator.java
index 2829a75f..1947d1c4 100644
--- a/src/main/java/cuchaz/enigma/mapping/Translator.java
+++ b/src/main/java/cuchaz/enigma/mapping/Translator.java
@@ -24,12 +24,7 @@ public class Translator {
24 private Map<String, ClassMapping> m_classes; 24 private Map<String, ClassMapping> m_classes;
25 private TranslationIndex m_index; 25 private TranslationIndex m_index;
26 26
27 private ClassNameReplacer m_classNameReplacer = new ClassNameReplacer() { 27 private ClassNameReplacer m_classNameReplacer = className -> translateEntry(new ClassEntry(className)).getName();
28 @Override
29 public String replace(String className) {
30 return translateEntry(new ClassEntry(className)).getName();
31 }
32 };
33 28
34 public Translator() { 29 public Translator() {
35 m_direction = null; 30 m_direction = null;
@@ -76,7 +71,7 @@ public class Translator {
76 } else if (entry instanceof MethodEntry) { 71 } else if (entry instanceof MethodEntry) {
77 return translate((MethodEntry) entry); 72 return translate((MethodEntry) entry);
78 } else if (entry instanceof ConstructorEntry) { 73 } else if (entry instanceof ConstructorEntry) {
79 return translate((ConstructorEntry) entry); 74 return translate(entry);
80 } else if (entry instanceof ArgumentEntry) { 75 } else if (entry instanceof ArgumentEntry) {
81 return translate((ArgumentEntry) entry); 76 return translate((ArgumentEntry) entry);
82 } else { 77 } else {
diff --git a/src/main/java/cuchaz/enigma/mapping/Type.java b/src/main/java/cuchaz/enigma/mapping/Type.java
index bfd836c6..f2fd34d9 100644
--- a/src/main/java/cuchaz/enigma/mapping/Type.java
+++ b/src/main/java/cuchaz/enigma/mapping/Type.java
@@ -205,10 +205,7 @@ public class Type implements Serializable {
205 205
206 @Override 206 @Override
207 public boolean equals(Object other) { 207 public boolean equals(Object other) {
208 if (other instanceof Type) { 208 return other instanceof Type && equals((Type) other);
209 return equals((Type) other);
210 }
211 return false;
212 } 209 }
213 210
214 public boolean equals(Type other) { 211 public boolean equals(Type other) {
@@ -222,7 +219,6 @@ public class Type implements Serializable {
222 private static int countArrayDimension(String in) { 219 private static int countArrayDimension(String in) {
223 int i = 0; 220 int i = 0;
224 for (; i < in.length() && in.charAt(i) == '['; i++) { 221 for (; i < in.length() && in.charAt(i) == '['; i++) {
225 ;
226 } 222 }
227 return i; 223 return i;
228 } 224 }