summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Thog2017-03-07 21:24:39 +0100
committerGravatar Thog2017-03-07 21:30:02 +0100
commitb4aaff683d78ab92b83f3a7257c33b8e27d1affa (patch)
treef23c9bb0927d83cc7302881266b7df8fd37959c7
parentAvoid crash of the matcher when the obf name is invalid (set a deob it using ... (diff)
downloadenigma-b4aaff683d78ab92b83f3a7257c33b8e27d1affa.tar.gz
enigma-b4aaff683d78ab92b83f3a7257c33b8e27d1affa.tar.xz
enigma-b4aaff683d78ab92b83f3a7257c33b8e27d1affa.zip
Drop unix case style and implement hashCode when equals is overrided
Also update Guava to version 21
-rw-r--r--build.gradle2
-rw-r--r--src/main/java/cuchaz/enigma/ConvertMain.java58
-rw-r--r--src/main/java/cuchaz/enigma/Deobfuscator.java8
-rw-r--r--src/main/java/cuchaz/enigma/Main.java1
-rw-r--r--src/main/java/cuchaz/enigma/analysis/Access.java15
-rw-r--r--src/main/java/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java93
-rw-r--r--src/main/java/cuchaz/enigma/analysis/BridgeMarker.java6
-rw-r--r--src/main/java/cuchaz/enigma/analysis/JarIndex.java2
-rw-r--r--src/main/java/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java1
-rw-r--r--src/main/java/cuchaz/enigma/analysis/Token.java6
-rw-r--r--src/main/java/cuchaz/enigma/analysis/TreeDumpVisitor.java13
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/CheckCastIterator.java119
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/ClassRenamer.java7
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java1
-rw-r--r--src/main/java/cuchaz/enigma/convert/ClassIdentity.java19
-rw-r--r--src/main/java/cuchaz/enigma/convert/ClassMatches.java88
-rw-r--r--src/main/java/cuchaz/enigma/convert/ClassMatching.java36
-rw-r--r--src/main/java/cuchaz/enigma/convert/FieldMatches.java68
-rw-r--r--src/main/java/cuchaz/enigma/convert/MappingsConverter.java53
-rw-r--r--src/main/java/cuchaz/enigma/convert/MatchesReader.java5
-rw-r--r--src/main/java/cuchaz/enigma/convert/MemberMatches.java70
-rw-r--r--src/main/java/cuchaz/enigma/gui/BrowserCaret.java1
-rw-r--r--src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java290
-rw-r--r--src/main/java/cuchaz/enigma/gui/ClassSelector.java29
-rw-r--r--src/main/java/cuchaz/enigma/gui/CodeReader.java89
-rw-r--r--src/main/java/cuchaz/enigma/gui/Gui.java318
-rw-r--r--src/main/java/cuchaz/enigma/gui/GuiController.java64
-rw-r--r--src/main/java/cuchaz/enigma/gui/MemberMatchingGui.java281
-rw-r--r--src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java20
-rw-r--r--src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java32
-rw-r--r--src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java16
-rw-r--r--src/main/java/cuchaz/enigma/gui/elements/MenuBar.java20
-rw-r--r--src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java2
-rw-r--r--src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java5
-rw-r--r--src/main/java/cuchaz/enigma/gui/node/ClassSelectorPackageNode.java5
-rw-r--r--src/main/java/cuchaz/enigma/mapping/ClassMapping.java250
-rw-r--r--src/main/java/cuchaz/enigma/mapping/FieldMapping.java12
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java6
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java54
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsSRGWriter.java2
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MethodMapping.java12
-rw-r--r--src/main/java/cuchaz/enigma/throwables/MappingParseException.java10
-rw-r--r--src/main/java/cuchaz/enigma/utils/Utils.java3
-rw-r--r--src/test/java/cuchaz/enigma/TestDeobfed.java14
-rw-r--r--src/test/java/cuchaz/enigma/TestInnerClasses.java66
-rw-r--r--src/test/java/cuchaz/enigma/TestJarIndexConstructorReferences.java75
-rw-r--r--src/test/java/cuchaz/enigma/TestJarIndexInheritanceTree.java176
-rw-r--r--src/test/java/cuchaz/enigma/TestJarIndexLoneClass.java68
-rw-r--r--src/test/java/cuchaz/enigma/TestTranslator.java26
-rw-r--r--src/test/java/cuchaz/enigma/TokenChecker.java16
-rw-r--r--src/test/java/cuchaz/enigma/inputs/inheritanceTree/BaseClass.java6
-rw-r--r--src/test/java/cuchaz/enigma/inputs/inheritanceTree/SubclassB.java6
-rw-r--r--src/test/java/cuchaz/enigma/inputs/loneClass/LoneClass.java6
-rw-r--r--src/test/java/cuchaz/enigma/inputs/translation/F_ObjectMethods.java1
54 files changed, 1237 insertions, 1415 deletions
diff --git a/build.gradle b/build.gradle
index d42cd61a..d67082c9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -64,7 +64,7 @@ configurations {
64} 64}
65 65
66dependencies { 66dependencies {
67 compile 'com.google.guava:guava:17.+' 67 compile 'com.google.guava:guava:21.+'
68 compile 'org.javassist:javassist:3.+' 68 compile 'org.javassist:javassist:3.+'
69 compile 'org.bitbucket.mstrobel:procyon-compilertools:0.5.33.8-enigma' 69 compile 'org.bitbucket.mstrobel:procyon-compilertools:0.5.33.8-enigma'
70 70
diff --git a/src/main/java/cuchaz/enigma/ConvertMain.java b/src/main/java/cuchaz/enigma/ConvertMain.java
index 1890aef1..48e7f27c 100644
--- a/src/main/java/cuchaz/enigma/ConvertMain.java
+++ b/src/main/java/cuchaz/enigma/ConvertMain.java
@@ -126,14 +126,12 @@ public class ConvertMain {
126 Deobfuscators deobfuscators = new Deobfuscators(sourceJar, destJar); 126 Deobfuscators deobfuscators = new Deobfuscators(sourceJar, destJar);
127 deobfuscators.source.setMappings(mappings); 127 deobfuscators.source.setMappings(mappings);
128 System.out.println("Starting GUI..."); 128 System.out.println("Starting GUI...");
129 new ClassMatchingGui(classMatches, deobfuscators.source, deobfuscators.dest).setSaveListener(new ClassMatchingGui.SaveListener() { 129 new ClassMatchingGui(classMatches, deobfuscators.source, deobfuscators.dest).setSaveListener(matches ->
130 @Override 130 {
131 public void save(ClassMatches matches) { 131 try {
132 try { 132 MatchesWriter.writeClasses(matches, classMatchesFile);
133 MatchesWriter.writeClasses(matches, classMatchesFile); 133 } catch (IOException ex) {
134 } catch (IOException ex) { 134 throw new Error(ex);
135 throw new Error(ex);
136 }
137 } 135 }
138 }); 136 });
139 } 137 }
@@ -190,16 +188,15 @@ public class ConvertMain {
190 checker.dropBrokenMappings(destMappings); 188 checker.dropBrokenMappings(destMappings);
191 deobfuscators.dest.setMappings(destMappings); 189 deobfuscators.dest.setMappings(destMappings);
192 190
193 new MemberMatchingGui<>(classMatches, fieldMatches, deobfuscators.source, deobfuscators.dest).setSaveListener(new MemberMatchingGui.SaveListener<FieldEntry>() { 191 new MemberMatchingGui<>(classMatches, fieldMatches, deobfuscators.source, deobfuscators.dest).setSaveListener(
194 @Override 192 matches ->
195 public void save(MemberMatches<FieldEntry> matches) { 193 {
196 try { 194 try {
197 MatchesWriter.writeMembers(matches, fieldMatchesFile); 195 MatchesWriter.writeMembers(matches, fieldMatchesFile);
198 } catch (IOException ex) { 196 } catch (IOException ex) {
199 throw new Error(ex); 197 throw new Error(ex);
200 } 198 }
201 } 199 });
202 });
203 } 200 }
204 201
205 @SuppressWarnings("unused") 202 @SuppressWarnings("unused")
@@ -267,16 +264,15 @@ public class ConvertMain {
267 checker.dropBrokenMappings(destMappings); 264 checker.dropBrokenMappings(destMappings);
268 deobfuscators.dest.setMappings(destMappings); 265 deobfuscators.dest.setMappings(destMappings);
269 266
270 new MemberMatchingGui<>(classMatches, methodMatches, deobfuscators.source, deobfuscators.dest).setSaveListener(new MemberMatchingGui.SaveListener<BehaviorEntry>() { 267 new MemberMatchingGui<>(classMatches, methodMatches, deobfuscators.source, deobfuscators.dest).setSaveListener(
271 @Override 268 matches ->
272 public void save(MemberMatches<BehaviorEntry> matches) { 269 {
273 try { 270 try {
274 MatchesWriter.writeMembers(matches, methodMatchesFile); 271 MatchesWriter.writeMembers(matches, methodMatchesFile);
275 } catch (IOException ex) { 272 } catch (IOException ex) {
276 throw new Error(ex); 273 throw new Error(ex);
277 } 274 }
278 } 275 });
279 });
280 } 276 }
281 277
282 private static void convertMappings(File outMappingsFile, JarFile sourceJar, JarFile destJar, Mappings mappings, File classMatchesFile, File fieldMatchesFile, File methodMatchesFile) 278 private static void convertMappings(File outMappingsFile, JarFile sourceJar, JarFile destJar, Mappings mappings, File classMatchesFile, File fieldMatchesFile, File methodMatchesFile)
@@ -338,11 +334,11 @@ public class ConvertMain {
338 334
339 private static class IndexerThread extends Thread { 335 private static class IndexerThread extends Thread {
340 336
341 private JarFile m_jarFile; 337 private JarFile jarFile;
342 public Deobfuscator deobfuscator; 338 public Deobfuscator deobfuscator;
343 339
344 public IndexerThread(JarFile jarFile) { 340 public IndexerThread(JarFile jarFile) {
345 m_jarFile = jarFile; 341 this.jarFile = jarFile;
346 deobfuscator = null; 342 deobfuscator = null;
347 } 343 }
348 344
@@ -356,7 +352,7 @@ public class ConvertMain {
356 352
357 @Override 353 @Override
358 public void run() { 354 public void run() {
359 deobfuscator = new Deobfuscator(m_jarFile); 355 deobfuscator = new Deobfuscator(jarFile);
360 } 356 }
361 } 357 }
362} \ No newline at end of file 358} \ No newline at end of file
diff --git a/src/main/java/cuchaz/enigma/Deobfuscator.java b/src/main/java/cuchaz/enigma/Deobfuscator.java
index 2766380b..2602abcc 100644
--- a/src/main/java/cuchaz/enigma/Deobfuscator.java
+++ b/src/main/java/cuchaz/enigma/Deobfuscator.java
@@ -126,12 +126,8 @@ public class Deobfuscator {
126 } 126 }
127 127
128 public Translator getTranslator(TranslationDirection direction) { 128 public Translator getTranslator(TranslationDirection direction) {
129 Translator translator = this.translatorCache.get(direction); 129 return this.translatorCache.computeIfAbsent(direction,
130 if (translator == null) { 130 k -> this.mappings.getTranslator(direction, this.jarIndex.getTranslationIndex()));
131 translator = this.mappings.getTranslator(direction, this.jarIndex.getTranslationIndex());
132 this.translatorCache.put(direction, translator);
133 }
134 return translator;
135 } 131 }
136 132
137 public void getSeparatedClasses(List<ClassEntry> obfClasses, List<ClassEntry> deobfClasses) { 133 public void getSeparatedClasses(List<ClassEntry> obfClasses, List<ClassEntry> deobfClasses) {
diff --git a/src/main/java/cuchaz/enigma/Main.java b/src/main/java/cuchaz/enigma/Main.java
index a89f898b..73709868 100644
--- a/src/main/java/cuchaz/enigma/Main.java
+++ b/src/main/java/cuchaz/enigma/Main.java
@@ -16,7 +16,6 @@ import java.util.jar.JarFile;
16import javax.swing.UIManager; 16import javax.swing.UIManager;
17 17
18import cuchaz.enigma.gui.Gui; 18import cuchaz.enigma.gui.Gui;
19import cuchaz.enigma.mapping.ClassEntry;
20 19
21public class Main { 20public class Main {
22 21
diff --git a/src/main/java/cuchaz/enigma/analysis/Access.java b/src/main/java/cuchaz/enigma/analysis/Access.java
index b8aafaa0..b8a7b2c8 100644
--- a/src/main/java/cuchaz/enigma/analysis/Access.java
+++ b/src/main/java/cuchaz/enigma/analysis/Access.java
@@ -17,10 +17,7 @@ import javassist.CtField;
17 17
18public enum Access { 18public enum Access {
19 19
20 Public, 20 PUBLIC, PROTECTED, PACKAGE, PRIVATE;
21 Protected,
22 Package,
23 Private;
24 21
25 public static Access get(CtBehavior behavior) { 22 public static Access get(CtBehavior behavior) {
26 return get(behavior.getModifiers()); 23 return get(behavior.getModifiers());
@@ -36,15 +33,15 @@ public enum Access {
36 boolean isPrivate = Modifier.isPrivate(modifiers); 33 boolean isPrivate = Modifier.isPrivate(modifiers);
37 34
38 if (isPublic && !isProtected && !isPrivate) { 35 if (isPublic && !isProtected && !isPrivate) {
39 return Public; 36 return PUBLIC;
40 } else if (!isPublic && isProtected && !isPrivate) { 37 } else if (!isPublic && isProtected && !isPrivate) {
41 return Protected; 38 return PROTECTED;
42 } else if (!isPublic && !isProtected && isPrivate) { 39 } else if (!isPublic && !isProtected && isPrivate) {
43 return Private; 40 return PRIVATE;
44 } else if (!isPublic && !isProtected && !isPrivate) { 41 } else if (!isPublic && !isProtected && !isPrivate) {
45 return Package; 42 return PACKAGE;
46 } 43 }
47 // assume public by default 44 // assume public by default
48 return Public; 45 return PUBLIC;
49 } 46 }
50} 47}
diff --git a/src/main/java/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java b/src/main/java/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java
index 98aa12e5..52d5b311 100644
--- a/src/main/java/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java
+++ b/src/main/java/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java
@@ -11,75 +11,88 @@
11package cuchaz.enigma.analysis; 11package cuchaz.enigma.analysis;
12 12
13import com.google.common.collect.Sets; 13import com.google.common.collect.Sets;
14
15import java.util.Set;
16
17import javax.swing.tree.DefaultMutableTreeNode;
18import javax.swing.tree.TreeNode;
19
20import cuchaz.enigma.mapping.BehaviorEntry; 14import cuchaz.enigma.mapping.BehaviorEntry;
21import cuchaz.enigma.mapping.Entry; 15import cuchaz.enigma.mapping.Entry;
22import cuchaz.enigma.mapping.Translator; 16import cuchaz.enigma.mapping.Translator;
23 17
24public class BehaviorReferenceTreeNode extends DefaultMutableTreeNode implements ReferenceTreeNode<BehaviorEntry, BehaviorEntry> { 18import javax.swing.tree.DefaultMutableTreeNode;
19import javax.swing.tree.TreeNode;
20import java.util.Set;
21
22public class BehaviorReferenceTreeNode extends DefaultMutableTreeNode
23 implements ReferenceTreeNode<BehaviorEntry, BehaviorEntry>
24{
25 25
26 private Translator m_deobfuscatingTranslator; 26 private Translator deobfuscatingTranslator;
27 private BehaviorEntry m_entry; 27 private BehaviorEntry entry;
28 private EntryReference<BehaviorEntry, BehaviorEntry> m_reference; 28 private EntryReference<BehaviorEntry, BehaviorEntry> reference;
29 private Access m_access; 29 private Access access;
30 30
31 public BehaviorReferenceTreeNode(Translator deobfuscatingTranslator, BehaviorEntry entry) { 31 public BehaviorReferenceTreeNode(Translator deobfuscatingTranslator, BehaviorEntry entry)
32 this.m_deobfuscatingTranslator = deobfuscatingTranslator; 32 {
33 this.m_entry = entry; 33 this.deobfuscatingTranslator = deobfuscatingTranslator;
34 this.m_reference = null; 34 this.entry = entry;
35 this.reference = null;
35 } 36 }
36 37
37 public BehaviorReferenceTreeNode(Translator deobfuscatingTranslator, EntryReference<BehaviorEntry, BehaviorEntry> reference, Access access) { 38 public BehaviorReferenceTreeNode(Translator deobfuscatingTranslator,
38 this.m_deobfuscatingTranslator = deobfuscatingTranslator; 39 EntryReference<BehaviorEntry, BehaviorEntry> reference, Access access)
39 this.m_entry = reference.entry; 40 {
40 this.m_reference = reference; 41 this.deobfuscatingTranslator = deobfuscatingTranslator;
41 this.m_access = access; 42 this.entry = reference.entry;
43 this.reference = reference;
44 this.access = access;
42 } 45 }
43 46
44 @Override 47 @Override public BehaviorEntry getEntry()
45 public BehaviorEntry getEntry() { 48 {
46 return this.m_entry; 49 return this.entry;
47 } 50 }
48 51
49 @Override 52 @Override public EntryReference<BehaviorEntry, BehaviorEntry> getReference()
50 public EntryReference<BehaviorEntry, BehaviorEntry> getReference() { 53 {
51 return this.m_reference; 54 return this.reference;
52 } 55 }
53 56
54 @Override 57 @Override public String toString()
55 public String toString() { 58 {
56 if (this.m_reference != null) { 59 if (this.reference != null)
57 return String.format("%s (%s)", this.m_deobfuscatingTranslator.translateEntry(this.m_reference.context), this.m_access); 60 {
61 return String.format("%s (%s)", this.deobfuscatingTranslator.translateEntry(this.reference.context),
62 this.access);
58 } 63 }
59 return this.m_deobfuscatingTranslator.translateEntry(this.m_entry).toString(); 64 return this.deobfuscatingTranslator.translateEntry(this.entry).toString();
60 } 65 }
61 66
62 public void load(JarIndex index, boolean recurse) { 67 public void load(JarIndex index, boolean recurse)
68 {
63 // get all the child nodes 69 // get all the child nodes
64 for (EntryReference<BehaviorEntry, BehaviorEntry> reference : index.getBehaviorReferences(this.m_entry)) { 70 for (EntryReference<BehaviorEntry, BehaviorEntry> reference : index.getBehaviorReferences(this.entry))
65 add(new BehaviorReferenceTreeNode(this.m_deobfuscatingTranslator, reference, index.getAccess(this.m_entry))); 71 {
72 add(new BehaviorReferenceTreeNode(this.deobfuscatingTranslator, reference, index.getAccess(this.entry)));
66 } 73 }
67 74
68 if (recurse && this.children != null) { 75 if (recurse && this.children != null)
69 for (Object child : this.children) { 76 {
70 if (child instanceof BehaviorReferenceTreeNode) { 77 for (Object child : this.children)
78 {
79 if (child instanceof BehaviorReferenceTreeNode)
80 {
71 BehaviorReferenceTreeNode node = (BehaviorReferenceTreeNode) child; 81 BehaviorReferenceTreeNode node = (BehaviorReferenceTreeNode) child;
72 82
73 // don't recurse into ancestor 83 // don't recurse into ancestor
74 Set<Entry> ancestors = Sets.newHashSet(); 84 Set<Entry> ancestors = Sets.newHashSet();
75 TreeNode n = node; 85 TreeNode n = node;
76 while (n.getParent() != null) { 86 while (n.getParent() != null)
87 {
77 n = n.getParent(); 88 n = n.getParent();
78 if (n instanceof BehaviorReferenceTreeNode) { 89 if (n instanceof BehaviorReferenceTreeNode)
90 {
79 ancestors.add(((BehaviorReferenceTreeNode) n).getEntry()); 91 ancestors.add(((BehaviorReferenceTreeNode) n).getEntry());
80 } 92 }
81 } 93 }
82 if (ancestors.contains(node.getEntry())) { 94 if (ancestors.contains(node.getEntry()))
95 {
83 continue; 96 continue;
84 } 97 }
85 98
diff --git a/src/main/java/cuchaz/enigma/analysis/BridgeMarker.java b/src/main/java/cuchaz/enigma/analysis/BridgeMarker.java
index cd185846..0f4be7d9 100644
--- a/src/main/java/cuchaz/enigma/analysis/BridgeMarker.java
+++ b/src/main/java/cuchaz/enigma/analysis/BridgeMarker.java
@@ -18,10 +18,10 @@ import javassist.bytecode.AccessFlag;
18 18
19public class BridgeMarker { 19public class BridgeMarker {
20 20
21 private JarIndex m_jarIndex; 21 private JarIndex jarIndex;
22 22
23 public BridgeMarker(JarIndex jarIndex) { 23 public BridgeMarker(JarIndex jarIndex) {
24 this.m_jarIndex = jarIndex; 24 this.jarIndex = jarIndex;
25 } 25 }
26 26
27 public void markBridges(CtClass c) { 27 public void markBridges(CtClass c) {
@@ -30,7 +30,7 @@ public class BridgeMarker {
30 MethodEntry methodEntry = EntryFactory.getMethodEntry(method); 30 MethodEntry methodEntry = EntryFactory.getMethodEntry(method);
31 31
32 // is this a bridge method? 32 // is this a bridge method?
33 MethodEntry bridgedMethodEntry = this.m_jarIndex.getBridgedMethod(methodEntry); 33 MethodEntry bridgedMethodEntry = this.jarIndex.getBridgedMethod(methodEntry);
34 if (bridgedMethodEntry != null) { 34 if (bridgedMethodEntry != null) {
35 35
36 // it's a bridge method! add the bridge flag 36 // it's a bridge method! add the bridge flag
diff --git a/src/main/java/cuchaz/enigma/analysis/JarIndex.java b/src/main/java/cuchaz/enigma/analysis/JarIndex.java
index ee1dd544..e8f74cc5 100644
--- a/src/main/java/cuchaz/enigma/analysis/JarIndex.java
+++ b/src/main/java/cuchaz/enigma/analysis/JarIndex.java
@@ -16,8 +16,6 @@ import java.lang.reflect.Modifier;
16import java.util.*; 16import java.util.*;
17import java.util.jar.JarFile; 17import java.util.jar.JarFile;
18 18
19import cuchaz.enigma.Constants;
20import cuchaz.enigma.bytecode.ClassRenamer;
21import cuchaz.enigma.mapping.*; 19import cuchaz.enigma.mapping.*;
22import cuchaz.enigma.mapping.Translator; 20import cuchaz.enigma.mapping.Translator;
23import javassist.*; 21import javassist.*;
diff --git a/src/main/java/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java b/src/main/java/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java
index e690abdf..bfd5a562 100644
--- a/src/main/java/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java
+++ b/src/main/java/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java
@@ -12,7 +12,6 @@ package cuchaz.enigma.analysis;
12 12
13import com.google.common.collect.HashMultimap; 13import com.google.common.collect.HashMultimap;
14import com.google.common.collect.Multimap; 14import com.google.common.collect.Multimap;
15import com.google.common.collect.Multimaps;
16import com.strobel.assembler.metadata.MemberReference; 15import com.strobel.assembler.metadata.MemberReference;
17import com.strobel.assembler.metadata.MethodReference; 16import com.strobel.assembler.metadata.MethodReference;
18import com.strobel.assembler.metadata.ParameterDefinition; 17import com.strobel.assembler.metadata.ParameterDefinition;
diff --git a/src/main/java/cuchaz/enigma/analysis/Token.java b/src/main/java/cuchaz/enigma/analysis/Token.java
index 419842af..42f4660a 100644
--- a/src/main/java/cuchaz/enigma/analysis/Token.java
+++ b/src/main/java/cuchaz/enigma/analysis/Token.java
@@ -38,6 +38,12 @@ public class Token implements Comparable<Token> {
38 return other instanceof Token && equals((Token) other); 38 return other instanceof Token && equals((Token) other);
39 } 39 }
40 40
41 @Override
42 public int hashCode()
43 {
44 return Integer.hashCode(start) + Integer.hashCode(end) + (text != null ? text.hashCode() : 0);
45 }
46
41 public boolean equals(Token other) { 47 public boolean equals(Token other) {
42 return start == other.start && end == other.end; 48 return start == other.start && end == other.end;
43 } 49 }
diff --git a/src/main/java/cuchaz/enigma/analysis/TreeDumpVisitor.java b/src/main/java/cuchaz/enigma/analysis/TreeDumpVisitor.java
index de39d36b..cc025da7 100644
--- a/src/main/java/cuchaz/enigma/analysis/TreeDumpVisitor.java
+++ b/src/main/java/cuchaz/enigma/analysis/TreeDumpVisitor.java
@@ -19,20 +19,19 @@ import java.nio.charset.Charset;
19 19
20public class TreeDumpVisitor implements IAstVisitor<Void, Void> { 20public class TreeDumpVisitor implements IAstVisitor<Void, Void> {
21 21
22 private File m_file; 22 private File file;
23 private Writer m_out; 23 private Writer out;
24 24
25 public TreeDumpVisitor(File file) { 25 public TreeDumpVisitor(File file) {
26 m_file = file; 26 this.file = file;
27 m_out = null;
28 } 27 }
29 28
30 @Override 29 @Override
31 public Void visitCompilationUnit(CompilationUnit node, Void ignored) { 30 public Void visitCompilationUnit(CompilationUnit node, Void ignored) {
32 try { 31 try {
33 m_out = new OutputStreamWriter(new FileOutputStream(m_file), Charset.forName("UTF-8")); 32 out = new OutputStreamWriter(new FileOutputStream(file), Charset.forName("UTF-8"));
34 recurse(node, ignored); 33 recurse(node, ignored);
35 m_out.close(); 34 out.close();
36 return null; 35 return null;
37 } catch (IOException ex) { 36 } catch (IOException ex) {
38 throw new Error(ex); 37 throw new Error(ex);
@@ -42,7 +41,7 @@ public class TreeDumpVisitor implements IAstVisitor<Void, Void> {
42 private Void recurse(AstNode node, Void ignored) { 41 private Void recurse(AstNode node, Void ignored) {
43 // show the tree 42 // show the tree
44 try { 43 try {
45 m_out.write(getIndent(node) + node.getClass().getSimpleName() + " " + getText(node) + " " + dumpUserData(node) + " " + node.getRegion() + "\n"); 44 out.write(getIndent(node) + node.getClass().getSimpleName() + " " + getText(node) + " " + dumpUserData(node) + " " + node.getRegion() + "\n");
46 } catch (IOException ex) { 45 } catch (IOException ex) {
47 throw new Error(ex); 46 throw new Error(ex);
48 } 47 }
diff --git a/src/main/java/cuchaz/enigma/bytecode/CheckCastIterator.java b/src/main/java/cuchaz/enigma/bytecode/CheckCastIterator.java
deleted file mode 100644
index d15dd87c..00000000
--- a/src/main/java/cuchaz/enigma/bytecode/CheckCastIterator.java
+++ /dev/null
@@ -1,119 +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.bytecode;
12
13import java.util.Iterator;
14
15import cuchaz.enigma.bytecode.CheckCastIterator.CheckCast;
16import cuchaz.enigma.mapping.ClassEntry;
17import cuchaz.enigma.mapping.MethodEntry;
18import cuchaz.enigma.mapping.Signature;
19import javassist.bytecode.*;
20
21@Deprecated
22// TODO: Find if this class can have any usage.
23public class CheckCastIterator implements Iterator<CheckCast> {
24
25 public static class CheckCast {
26
27 public String className;
28 public MethodEntry prevMethodEntry;
29
30 public CheckCast(String className, MethodEntry prevMethodEntry) {
31 this.className = className;
32 this.prevMethodEntry = prevMethodEntry;
33 }
34 }
35
36 private ConstPool constants;
37 private CodeAttribute attribute;
38 private CodeIterator iter;
39 private CheckCast next;
40
41 public CheckCastIterator(CodeAttribute codeAttribute) throws BadBytecode {
42 this.constants = codeAttribute.getConstPool();
43 this.attribute = codeAttribute;
44 this.iter = this.attribute.iterator();
45
46 this.next = getNext();
47 }
48
49 @Override
50 public boolean hasNext() {
51 return this.next != null;
52 }
53
54 @Override
55 public CheckCast next() {
56 CheckCast out = this.next;
57 try {
58 this.next = getNext();
59 } catch (BadBytecode ex) {
60 throw new Error(ex);
61 }
62 return out;
63 }
64
65 @Override
66 public void remove() {
67 throw new UnsupportedOperationException();
68 }
69
70 private CheckCast getNext() throws BadBytecode {
71 int prevPos = 0;
72 while (this.iter.hasNext()) {
73 int pos = this.iter.next();
74 int opcode = this.iter.byteAt(pos);
75 switch (opcode) {
76 case Opcode.CHECKCAST:
77
78 // get the type of this op code (next two bytes are a classinfo index)
79 MethodEntry prevMethodEntry = getMethodEntry(prevPos);
80 if (prevMethodEntry != null) {
81 return new CheckCast(this.constants.getClassInfo(this.iter.s16bitAt(pos + 1)), prevMethodEntry);
82 }
83 break;
84 }
85 prevPos = pos;
86 }
87 return null;
88 }
89
90 private MethodEntry getMethodEntry(int pos) {
91 switch (this.iter.byteAt(pos)) {
92 case Opcode.INVOKEVIRTUAL:
93 case Opcode.INVOKESTATIC:
94 case Opcode.INVOKEDYNAMIC:
95 case Opcode.INVOKESPECIAL: {
96 int index = this.iter.s16bitAt(pos + 1);
97 return new MethodEntry(
98 new ClassEntry(Descriptor.toJvmName(this.constants.getMethodrefClassName(index))),
99 this.constants.getMethodrefName(index),
100 new Signature(this.constants.getMethodrefType(index))
101 );
102 }
103
104 case Opcode.INVOKEINTERFACE: {
105 int index = this.iter.s16bitAt(pos + 1);
106 return new MethodEntry(
107 new ClassEntry(Descriptor.toJvmName(this.constants.getInterfaceMethodrefClassName(index))),
108 this.constants.getInterfaceMethodrefName(index),
109 new Signature(this.constants.getInterfaceMethodrefType(index))
110 );
111 }
112 }
113 return null;
114 }
115
116 public Iterable<CheckCast> casts() {
117 return () -> CheckCastIterator.this;
118 }
119}
diff --git a/src/main/java/cuchaz/enigma/bytecode/ClassRenamer.java b/src/main/java/cuchaz/enigma/bytecode/ClassRenamer.java
index d49f13ab..d874633d 100644
--- a/src/main/java/cuchaz/enigma/bytecode/ClassRenamer.java
+++ b/src/main/java/cuchaz/enigma/bytecode/ClassRenamer.java
@@ -52,10 +52,10 @@ public class ClassRenamer {
52 52
53 private static class ReplacerClassMap extends HashMap<String, String> { 53 private static class ReplacerClassMap extends HashMap<String, String> {
54 54
55 private ClassNameReplacer m_replacer; 55 private ClassNameReplacer replacer;
56 56
57 public ReplacerClassMap(ClassNameReplacer replacer) { 57 public ReplacerClassMap(ClassNameReplacer replacer) {
58 m_replacer = replacer; 58 this.replacer = replacer;
59 } 59 }
60 60
61 @Override 61 @Override
@@ -67,7 +67,7 @@ public class ClassRenamer {
67 } 67 }
68 68
69 public String get(String className) { 69 public String get(String className) {
70 return m_replacer.replace(className); 70 return replacer.replace(className);
71 } 71 }
72 } 72 }
73 73
@@ -146,7 +146,6 @@ public class ClassRenamer {
146 146
147 // rename the constant pool (covers ClassInfo, MethodTypeInfo, and NameAndTypeInfo) 147 // rename the constant pool (covers ClassInfo, MethodTypeInfo, and NameAndTypeInfo)
148 ConstPool constPool = c.getClassFile().getConstPool(); 148 ConstPool constPool = c.getClassFile().getConstPool();
149 String className = constPool.getClassName();
150 constPool.renameClass(map); 149 constPool.renameClass(map);
151 150
152 // rename class attributes 151 // rename class attributes
diff --git a/src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java b/src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java
index 6e2a29d5..eb70c23d 100644
--- a/src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java
+++ b/src/main/java/cuchaz/enigma/bytecode/InnerClassWriter.java
@@ -15,7 +15,6 @@ import com.google.common.collect.Lists;
15import java.util.Collection; 15import java.util.Collection;
16import java.util.List; 16import java.util.List;
17 17
18import cuchaz.enigma.Deobfuscator;
19import cuchaz.enigma.analysis.JarIndex; 18import cuchaz.enigma.analysis.JarIndex;
20import cuchaz.enigma.mapping.*; 19import cuchaz.enigma.mapping.*;
21import javassist.ClassPool; 20import javassist.ClassPool;
diff --git a/src/main/java/cuchaz/enigma/convert/ClassIdentity.java b/src/main/java/cuchaz/enigma/convert/ClassIdentity.java
index 73600114..f72bf703 100644
--- a/src/main/java/cuchaz/enigma/convert/ClassIdentity.java
+++ b/src/main/java/cuchaz/enigma/convert/ClassIdentity.java
@@ -20,7 +20,6 @@ import java.util.List;
20import java.util.Map; 20import java.util.Map;
21import java.util.Set; 21import java.util.Set;
22 22
23import cuchaz.enigma.Constants;
24import cuchaz.enigma.analysis.ClassImplementationsTreeNode; 23import cuchaz.enigma.analysis.ClassImplementationsTreeNode;
25import cuchaz.enigma.analysis.EntryReference; 24import cuchaz.enigma.analysis.EntryReference;
26import cuchaz.enigma.analysis.JarIndex; 25import cuchaz.enigma.analysis.JarIndex;
@@ -49,9 +48,9 @@ public class ClassIdentity {
49 private Multiset<String> references; 48 private Multiset<String> references;
50 private String outer; 49 private String outer;
51 50
52 private final ClassNameReplacer m_classNameReplacer = new ClassNameReplacer() { 51 private final ClassNameReplacer classNameReplacer = new ClassNameReplacer() {
53 52
54 private Map<String, String> m_classNames = Maps.newHashMap(); 53 private Map<String, String> classNames = Maps.newHashMap();
55 54
56 @Override 55 @Override
57 public String replace(String className) { 56 public String replace(String className) {
@@ -76,14 +75,14 @@ public class ClassIdentity {
76 } 75 }
77 76
78 // otherwise, use local naming 77 // otherwise, use local naming
79 if (!m_classNames.containsKey(className)) { 78 if (!classNames.containsKey(className)) {
80 m_classNames.put(className, getNewClassName()); 79 classNames.put(className, getNewClassName());
81 } 80 }
82 return m_classNames.get(className); 81 return classNames.get(className);
83 } 82 }
84 83
85 private String getNewClassName() { 84 private String getNewClassName() {
86 return String.format("C%03d", m_classNames.size()); 85 return String.format("C%03d", classNames.size());
87 } 86 }
88 }; 87 };
89 88
@@ -229,7 +228,7 @@ public class ClassIdentity {
229 } 228 }
230 229
231 private String scrubClassName(String className) { 230 private String scrubClassName(String className) {
232 return m_classNameReplacer.replace(className); 231 return classNameReplacer.replace(className);
233 } 232 }
234 233
235 private String scrubType(String typeName) { 234 private String scrubType(String typeName) {
@@ -238,7 +237,7 @@ public class ClassIdentity {
238 237
239 private Type scrubType(Type type) { 238 private Type scrubType(Type type) {
240 if (type.hasClass()) { 239 if (type.hasClass()) {
241 return new Type(type, m_classNameReplacer); 240 return new Type(type, classNameReplacer);
242 } else { 241 } else {
243 return type; 242 return type;
244 } 243 }
@@ -249,7 +248,7 @@ public class ClassIdentity {
249 } 248 }
250 249
251 private Signature scrubSignature(Signature signature) { 250 private Signature scrubSignature(Signature signature) {
252 return new Signature(signature, m_classNameReplacer); 251 return new Signature(signature, classNameReplacer);
253 } 252 }
254 253
255 private boolean isClassMatchedUniquely(String className) { 254 private boolean isClassMatchedUniquely(String className) {
diff --git a/src/main/java/cuchaz/enigma/convert/ClassMatches.java b/src/main/java/cuchaz/enigma/convert/ClassMatches.java
index 3a254357..431c4f24 100644
--- a/src/main/java/cuchaz/enigma/convert/ClassMatches.java
+++ b/src/main/java/cuchaz/enigma/convert/ClassMatches.java
@@ -22,28 +22,28 @@ import cuchaz.enigma.mapping.ClassEntry;
22 22
23public class ClassMatches implements Iterable<ClassMatch> { 23public class ClassMatches implements Iterable<ClassMatch> {
24 24
25 Collection<ClassMatch> m_matches; 25 private Collection<ClassMatch> matches;
26 Map<ClassEntry, ClassMatch> m_matchesBySource; 26 private Map<ClassEntry, ClassMatch> matchesBySource;
27 Map<ClassEntry, ClassMatch> m_matchesByDest; 27 private Map<ClassEntry, ClassMatch> matchesByDest;
28 BiMap<ClassEntry, ClassEntry> m_uniqueMatches; 28 private BiMap<ClassEntry, ClassEntry> uniqueMatches;
29 Map<ClassEntry, ClassMatch> m_ambiguousMatchesBySource; 29 private Map<ClassEntry, ClassMatch> ambiguousMatchesBySource;
30 Map<ClassEntry, ClassMatch> m_ambiguousMatchesByDest; 30 private Map<ClassEntry, ClassMatch> ambiguousMatchesByDest;
31 Set<ClassEntry> m_unmatchedSourceClasses; 31 private Set<ClassEntry> unmatchedSourceClasses;
32 Set<ClassEntry> m_unmatchedDestClasses; 32 private Set<ClassEntry> unmatchedDestClasses;
33 33
34 public ClassMatches() { 34 public ClassMatches() {
35 this(new ArrayList<>()); 35 this(new ArrayList<>());
36 } 36 }
37 37
38 public ClassMatches(Collection<ClassMatch> matches) { 38 public ClassMatches(Collection<ClassMatch> matches) {
39 m_matches = matches; 39 this.matches = matches;
40 m_matchesBySource = Maps.newHashMap(); 40 matchesBySource = Maps.newHashMap();
41 m_matchesByDest = Maps.newHashMap(); 41 matchesByDest = Maps.newHashMap();
42 m_uniqueMatches = HashBiMap.create(); 42 uniqueMatches = HashBiMap.create();
43 m_ambiguousMatchesBySource = Maps.newHashMap(); 43 ambiguousMatchesBySource = Maps.newHashMap();
44 m_ambiguousMatchesByDest = Maps.newHashMap(); 44 ambiguousMatchesByDest = Maps.newHashMap();
45 m_unmatchedSourceClasses = Sets.newHashSet(); 45 unmatchedSourceClasses = Sets.newHashSet();
46 m_unmatchedDestClasses = Sets.newHashSet(); 46 unmatchedDestClasses = Sets.newHashSet();
47 47
48 for (ClassMatch match : matches) { 48 for (ClassMatch match : matches) {
49 indexMatch(match); 49 indexMatch(match);
@@ -51,92 +51,92 @@ public class ClassMatches implements Iterable<ClassMatch> {
51 } 51 }
52 52
53 public void add(ClassMatch match) { 53 public void add(ClassMatch match) {
54 m_matches.add(match); 54 matches.add(match);
55 indexMatch(match); 55 indexMatch(match);
56 } 56 }
57 57
58 public void remove(ClassMatch match) { 58 public void remove(ClassMatch match) {
59 for (ClassEntry sourceClass : match.sourceClasses) { 59 for (ClassEntry sourceClass : match.sourceClasses) {
60 m_matchesBySource.remove(sourceClass); 60 matchesBySource.remove(sourceClass);
61 m_uniqueMatches.remove(sourceClass); 61 uniqueMatches.remove(sourceClass);
62 m_ambiguousMatchesBySource.remove(sourceClass); 62 ambiguousMatchesBySource.remove(sourceClass);
63 m_unmatchedSourceClasses.remove(sourceClass); 63 unmatchedSourceClasses.remove(sourceClass);
64 } 64 }
65 for (ClassEntry destClass : match.destClasses) { 65 for (ClassEntry destClass : match.destClasses) {
66 m_matchesByDest.remove(destClass); 66 matchesByDest.remove(destClass);
67 m_uniqueMatches.inverse().remove(destClass); 67 uniqueMatches.inverse().remove(destClass);
68 m_ambiguousMatchesByDest.remove(destClass); 68 ambiguousMatchesByDest.remove(destClass);
69 m_unmatchedDestClasses.remove(destClass); 69 unmatchedDestClasses.remove(destClass);
70 } 70 }
71 m_matches.remove(match); 71 matches.remove(match);
72 } 72 }
73 73
74 public int size() { 74 public int size() {
75 return m_matches.size(); 75 return matches.size();
76 } 76 }
77 77
78 @Override 78 @Override
79 public Iterator<ClassMatch> iterator() { 79 public Iterator<ClassMatch> iterator() {
80 return m_matches.iterator(); 80 return matches.iterator();
81 } 81 }
82 82
83 private void indexMatch(ClassMatch match) { 83 private void indexMatch(ClassMatch match) {
84 if (!match.isMatched()) { 84 if (!match.isMatched()) {
85 // unmatched 85 // unmatched
86 m_unmatchedSourceClasses.addAll(match.sourceClasses); 86 unmatchedSourceClasses.addAll(match.sourceClasses);
87 m_unmatchedDestClasses.addAll(match.destClasses); 87 unmatchedDestClasses.addAll(match.destClasses);
88 } else { 88 } else {
89 if (match.isAmbiguous()) { 89 if (match.isAmbiguous()) {
90 // ambiguously matched 90 // ambiguously matched
91 for (ClassEntry entry : match.sourceClasses) { 91 for (ClassEntry entry : match.sourceClasses) {
92 m_ambiguousMatchesBySource.put(entry, match); 92 ambiguousMatchesBySource.put(entry, match);
93 } 93 }
94 for (ClassEntry entry : match.destClasses) { 94 for (ClassEntry entry : match.destClasses) {
95 m_ambiguousMatchesByDest.put(entry, match); 95 ambiguousMatchesByDest.put(entry, match);
96 } 96 }
97 } else { 97 } else {
98 // uniquely matched 98 // uniquely matched
99 m_uniqueMatches.put(match.getUniqueSource(), match.getUniqueDest()); 99 uniqueMatches.put(match.getUniqueSource(), match.getUniqueDest());
100 } 100 }
101 } 101 }
102 for (ClassEntry entry : match.sourceClasses) { 102 for (ClassEntry entry : match.sourceClasses) {
103 m_matchesBySource.put(entry, match); 103 matchesBySource.put(entry, match);
104 } 104 }
105 for (ClassEntry entry : match.destClasses) { 105 for (ClassEntry entry : match.destClasses) {
106 m_matchesByDest.put(entry, match); 106 matchesByDest.put(entry, match);
107 } 107 }
108 } 108 }
109 109
110 public BiMap<ClassEntry, ClassEntry> getUniqueMatches() { 110 public BiMap<ClassEntry, ClassEntry> getUniqueMatches() {
111 return m_uniqueMatches; 111 return uniqueMatches;
112 } 112 }
113 113
114 public Set<ClassEntry> getUnmatchedSourceClasses() { 114 public Set<ClassEntry> getUnmatchedSourceClasses() {
115 return m_unmatchedSourceClasses; 115 return unmatchedSourceClasses;
116 } 116 }
117 117
118 public Set<ClassEntry> getUnmatchedDestClasses() { 118 public Set<ClassEntry> getUnmatchedDestClasses() {
119 return m_unmatchedDestClasses; 119 return unmatchedDestClasses;
120 } 120 }
121 121
122 public Set<ClassEntry> getAmbiguouslyMatchedSourceClasses() { 122 public Set<ClassEntry> getAmbiguouslyMatchedSourceClasses() {
123 return m_ambiguousMatchesBySource.keySet(); 123 return ambiguousMatchesBySource.keySet();
124 } 124 }
125 125
126 public ClassMatch getAmbiguousMatchBySource(ClassEntry sourceClass) { 126 public ClassMatch getAmbiguousMatchBySource(ClassEntry sourceClass) {
127 return m_ambiguousMatchesBySource.get(sourceClass); 127 return ambiguousMatchesBySource.get(sourceClass);
128 } 128 }
129 129
130 public ClassMatch getMatchBySource(ClassEntry sourceClass) { 130 public ClassMatch getMatchBySource(ClassEntry sourceClass) {
131 return m_matchesBySource.get(sourceClass); 131 return matchesBySource.get(sourceClass);
132 } 132 }
133 133
134 public ClassMatch getMatchByDest(ClassEntry destClass) { 134 public ClassMatch getMatchByDest(ClassEntry destClass) {
135 return m_matchesByDest.get(destClass); 135 return matchesByDest.get(destClass);
136 } 136 }
137 137
138 public void removeSource(ClassEntry sourceClass) { 138 public void removeSource(ClassEntry sourceClass) {
139 ClassMatch match = m_matchesBySource.get(sourceClass); 139 ClassMatch match = matchesBySource.get(sourceClass);
140 if (match != null) { 140 if (match != null) {
141 remove(match); 141 remove(match);
142 match.sourceClasses.remove(sourceClass); 142 match.sourceClasses.remove(sourceClass);
@@ -147,7 +147,7 @@ public class ClassMatches implements Iterable<ClassMatch> {
147 } 147 }
148 148
149 public void removeDest(ClassEntry destClass) { 149 public void removeDest(ClassEntry destClass) {
150 ClassMatch match = m_matchesByDest.get(destClass); 150 ClassMatch match = matchesByDest.get(destClass);
151 if (match != null) { 151 if (match != null) {
152 remove(match); 152 remove(match);
153 match.destClasses.remove(destClass); 153 match.destClasses.remove(destClass);
diff --git a/src/main/java/cuchaz/enigma/convert/ClassMatching.java b/src/main/java/cuchaz/enigma/convert/ClassMatching.java
index af9ae015..b05df871 100644
--- a/src/main/java/cuchaz/enigma/convert/ClassMatching.java
+++ b/src/main/java/cuchaz/enigma/convert/ClassMatching.java
@@ -25,52 +25,52 @@ import cuchaz.enigma.mapping.ClassEntry;
25 25
26public class ClassMatching { 26public class ClassMatching {
27 27
28 private ClassForest m_sourceClasses; 28 private ClassForest sourceClasses;
29 private ClassForest m_destClasses; 29 private ClassForest destClasses;
30 private BiMap<ClassEntry, ClassEntry> m_knownMatches; 30 private BiMap<ClassEntry, ClassEntry> knownMatches;
31 31
32 public ClassMatching(ClassIdentifier sourceIdentifier, ClassIdentifier destIdentifier) { 32 public ClassMatching(ClassIdentifier sourceIdentifier, ClassIdentifier destIdentifier) {
33 m_sourceClasses = new ClassForest(sourceIdentifier); 33 sourceClasses = new ClassForest(sourceIdentifier);
34 m_destClasses = new ClassForest(destIdentifier); 34 destClasses = new ClassForest(destIdentifier);
35 m_knownMatches = HashBiMap.create(); 35 knownMatches = HashBiMap.create();
36 } 36 }
37 37
38 public void addKnownMatches(BiMap<ClassEntry, ClassEntry> knownMatches) { 38 public void addKnownMatches(BiMap<ClassEntry, ClassEntry> knownMatches) {
39 m_knownMatches.putAll(knownMatches); 39 this.knownMatches.putAll(knownMatches);
40 } 40 }
41 41
42 public void match(Iterable<ClassEntry> sourceClasses, Iterable<ClassEntry> destClasses) { 42 public void match(Iterable<ClassEntry> sourceClasses, Iterable<ClassEntry> destClasses) {
43 for (ClassEntry sourceClass : sourceClasses) { 43 for (ClassEntry sourceClass : sourceClasses) {
44 if (!m_knownMatches.containsKey(sourceClass)) { 44 if (!knownMatches.containsKey(sourceClass)) {
45 m_sourceClasses.add(sourceClass); 45 this.sourceClasses.add(sourceClass);
46 } 46 }
47 } 47 }
48 for (ClassEntry destClass : destClasses) { 48 for (ClassEntry destClass : destClasses) {
49 if (!m_knownMatches.containsValue(destClass)) { 49 if (!knownMatches.containsValue(destClass)) {
50 m_destClasses.add(destClass); 50 this.destClasses.add(destClass);
51 } 51 }
52 } 52 }
53 } 53 }
54 54
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 : knownMatches.entrySet()) {
58 matches.add(new ClassMatch( 58 matches.add(new ClassMatch(
59 entry.getKey(), 59 entry.getKey(),
60 entry.getValue() 60 entry.getValue()
61 )); 61 ));
62 } 62 }
63 for (ClassIdentity identity : m_sourceClasses.identities()) { 63 for (ClassIdentity identity : sourceClasses.identities()) {
64 matches.add(new ClassMatch( 64 matches.add(new ClassMatch(
65 m_sourceClasses.getClasses(identity), 65 sourceClasses.getClasses(identity),
66 m_destClasses.getClasses(identity) 66 destClasses.getClasses(identity)
67 )); 67 ));
68 } 68 }
69 for (ClassIdentity identity : m_destClasses.identities()) { 69 for (ClassIdentity identity : destClasses.identities()) {
70 if (!m_sourceClasses.containsIdentity(identity)) { 70 if (!sourceClasses.containsIdentity(identity)) {
71 matches.add(new ClassMatch( 71 matches.add(new ClassMatch(
72 new ArrayList<>(), 72 new ArrayList<>(),
73 m_destClasses.getClasses(identity) 73 destClasses.getClasses(identity)
74 )); 74 ));
75 } 75 }
76 } 76 }
diff --git a/src/main/java/cuchaz/enigma/convert/FieldMatches.java b/src/main/java/cuchaz/enigma/convert/FieldMatches.java
index 0899cd2e..236cd4d1 100644
--- a/src/main/java/cuchaz/enigma/convert/FieldMatches.java
+++ b/src/main/java/cuchaz/enigma/convert/FieldMatches.java
@@ -21,29 +21,29 @@ import cuchaz.enigma.mapping.FieldEntry;
21 21
22public class FieldMatches { 22public class FieldMatches {
23 23
24 private BiMap<FieldEntry, FieldEntry> m_matches; 24 private BiMap<FieldEntry, FieldEntry> matches;
25 private Multimap<ClassEntry, FieldEntry> m_matchedSourceFields; 25 private Multimap<ClassEntry, FieldEntry> matchedSourceFields;
26 private Multimap<ClassEntry, FieldEntry> m_unmatchedSourceFields; 26 private Multimap<ClassEntry, FieldEntry> unmatchedSourceFields;
27 private Multimap<ClassEntry, FieldEntry> m_unmatchedDestFields; 27 private Multimap<ClassEntry, FieldEntry> unmatchedDestFields;
28 private Multimap<ClassEntry, FieldEntry> m_unmatchableSourceFields; 28 private Multimap<ClassEntry, FieldEntry> unmatchableSourceFields;
29 29
30 public FieldMatches() { 30 public FieldMatches() {
31 m_matches = HashBiMap.create(); 31 matches = HashBiMap.create();
32 m_matchedSourceFields = HashMultimap.create(); 32 matchedSourceFields = HashMultimap.create();
33 m_unmatchedSourceFields = HashMultimap.create(); 33 unmatchedSourceFields = HashMultimap.create();
34 m_unmatchedDestFields = HashMultimap.create(); 34 unmatchedDestFields = HashMultimap.create();
35 m_unmatchableSourceFields = HashMultimap.create(); 35 unmatchableSourceFields = HashMultimap.create();
36 } 36 }
37 37
38 public void addMatch(FieldEntry srcField, FieldEntry destField) { 38 public void addMatch(FieldEntry srcField, FieldEntry destField) {
39 boolean wasAdded = m_matches.put(srcField, destField) == null; 39 boolean wasAdded = matches.put(srcField, destField) == null;
40 assert (wasAdded); 40 assert (wasAdded);
41 wasAdded = m_matchedSourceFields.put(srcField.getClassEntry(), srcField); 41 wasAdded = matchedSourceFields.put(srcField.getClassEntry(), srcField);
42 assert (wasAdded); 42 assert (wasAdded);
43 } 43 }
44 44
45 public void addUnmatchedSourceField(FieldEntry fieldEntry) { 45 public void addUnmatchedSourceField(FieldEntry fieldEntry) {
46 boolean wasAdded = m_unmatchedSourceFields.put(fieldEntry.getClassEntry(), fieldEntry); 46 boolean wasAdded = unmatchedSourceFields.put(fieldEntry.getClassEntry(), fieldEntry);
47 assert (wasAdded); 47 assert (wasAdded);
48 } 48 }
49 49
@@ -54,7 +54,7 @@ public class FieldMatches {
54 } 54 }
55 55
56 public void addUnmatchedDestField(FieldEntry fieldEntry) { 56 public void addUnmatchedDestField(FieldEntry fieldEntry) {
57 boolean wasAdded = m_unmatchedDestFields.put(fieldEntry.getClassEntry(), fieldEntry); 57 boolean wasAdded = unmatchedDestFields.put(fieldEntry.getClassEntry(), fieldEntry);
58 assert (wasAdded); 58 assert (wasAdded);
59 } 59 }
60 60
@@ -65,78 +65,78 @@ public class FieldMatches {
65 } 65 }
66 66
67 public void addUnmatchableSourceField(FieldEntry sourceField) { 67 public void addUnmatchableSourceField(FieldEntry sourceField) {
68 boolean wasAdded = m_unmatchableSourceFields.put(sourceField.getClassEntry(), sourceField); 68 boolean wasAdded = unmatchableSourceFields.put(sourceField.getClassEntry(), sourceField);
69 assert (wasAdded); 69 assert (wasAdded);
70 } 70 }
71 71
72 public Set<ClassEntry> getSourceClassesWithUnmatchedFields() { 72 public Set<ClassEntry> getSourceClassesWithUnmatchedFields() {
73 return m_unmatchedSourceFields.keySet(); 73 return unmatchedSourceFields.keySet();
74 } 74 }
75 75
76 public Collection<ClassEntry> getSourceClassesWithoutUnmatchedFields() { 76 public Collection<ClassEntry> getSourceClassesWithoutUnmatchedFields() {
77 Set<ClassEntry> out = Sets.newHashSet(); 77 Set<ClassEntry> out = Sets.newHashSet();
78 out.addAll(m_matchedSourceFields.keySet()); 78 out.addAll(matchedSourceFields.keySet());
79 out.removeAll(m_unmatchedSourceFields.keySet()); 79 out.removeAll(unmatchedSourceFields.keySet());
80 return out; 80 return out;
81 } 81 }
82 82
83 public Collection<FieldEntry> getUnmatchedSourceFields() { 83 public Collection<FieldEntry> getUnmatchedSourceFields() {
84 return m_unmatchedSourceFields.values(); 84 return unmatchedSourceFields.values();
85 } 85 }
86 86
87 public Collection<FieldEntry> getUnmatchedSourceFields(ClassEntry sourceClass) { 87 public Collection<FieldEntry> getUnmatchedSourceFields(ClassEntry sourceClass) {
88 return m_unmatchedSourceFields.get(sourceClass); 88 return unmatchedSourceFields.get(sourceClass);
89 } 89 }
90 90
91 public Collection<FieldEntry> getUnmatchedDestFields() { 91 public Collection<FieldEntry> getUnmatchedDestFields() {
92 return m_unmatchedDestFields.values(); 92 return unmatchedDestFields.values();
93 } 93 }
94 94
95 public Collection<FieldEntry> getUnmatchedDestFields(ClassEntry destClass) { 95 public Collection<FieldEntry> getUnmatchedDestFields(ClassEntry destClass) {
96 return m_unmatchedDestFields.get(destClass); 96 return unmatchedDestFields.get(destClass);
97 } 97 }
98 98
99 public Collection<FieldEntry> getUnmatchableSourceFields() { 99 public Collection<FieldEntry> getUnmatchableSourceFields() {
100 return m_unmatchableSourceFields.values(); 100 return unmatchableSourceFields.values();
101 } 101 }
102 102
103 public boolean hasSource(FieldEntry fieldEntry) { 103 public boolean hasSource(FieldEntry fieldEntry) {
104 return m_matches.containsKey(fieldEntry) || m_unmatchedSourceFields.containsValue(fieldEntry); 104 return matches.containsKey(fieldEntry) || unmatchedSourceFields.containsValue(fieldEntry);
105 } 105 }
106 106
107 public boolean hasDest(FieldEntry fieldEntry) { 107 public boolean hasDest(FieldEntry fieldEntry) {
108 return m_matches.containsValue(fieldEntry) || m_unmatchedDestFields.containsValue(fieldEntry); 108 return matches.containsValue(fieldEntry) || unmatchedDestFields.containsValue(fieldEntry);
109 } 109 }
110 110
111 public BiMap<FieldEntry, FieldEntry> matches() { 111 public BiMap<FieldEntry, FieldEntry> matches() {
112 return m_matches; 112 return matches;
113 } 113 }
114 114
115 public boolean isMatchedSourceField(FieldEntry sourceField) { 115 public boolean isMatchedSourceField(FieldEntry sourceField) {
116 return m_matches.containsKey(sourceField); 116 return matches.containsKey(sourceField);
117 } 117 }
118 118
119 public boolean isMatchedDestField(FieldEntry destField) { 119 public boolean isMatchedDestField(FieldEntry destField) {
120 return m_matches.containsValue(destField); 120 return matches.containsValue(destField);
121 } 121 }
122 122
123 public void makeMatch(FieldEntry sourceField, FieldEntry destField) { 123 public void makeMatch(FieldEntry sourceField, FieldEntry destField) {
124 boolean wasRemoved = m_unmatchedSourceFields.remove(sourceField.getClassEntry(), sourceField); 124 boolean wasRemoved = unmatchedSourceFields.remove(sourceField.getClassEntry(), sourceField);
125 assert (wasRemoved); 125 assert (wasRemoved);
126 wasRemoved = m_unmatchedDestFields.remove(destField.getClassEntry(), destField); 126 wasRemoved = unmatchedDestFields.remove(destField.getClassEntry(), destField);
127 assert (wasRemoved); 127 assert (wasRemoved);
128 addMatch(sourceField, destField); 128 addMatch(sourceField, destField);
129 } 129 }
130 130
131 public boolean isMatched(FieldEntry sourceField, FieldEntry destField) { 131 public boolean isMatched(FieldEntry sourceField, FieldEntry destField) {
132 FieldEntry match = m_matches.get(sourceField); 132 FieldEntry match = matches.get(sourceField);
133 return match != null && match.equals(destField); 133 return match != null && match.equals(destField);
134 } 134 }
135 135
136 public void unmakeMatch(FieldEntry sourceField, FieldEntry destField) { 136 public void unmakeMatch(FieldEntry sourceField, FieldEntry destField) {
137 boolean wasRemoved = m_matches.remove(sourceField) != null; 137 boolean wasRemoved = matches.remove(sourceField) != null;
138 assert (wasRemoved); 138 assert (wasRemoved);
139 wasRemoved = m_matchedSourceFields.remove(sourceField.getClassEntry(), sourceField); 139 wasRemoved = matchedSourceFields.remove(sourceField.getClassEntry(), sourceField);
140 assert (wasRemoved); 140 assert (wasRemoved);
141 addUnmatchedSourceField(sourceField); 141 addUnmatchedSourceField(sourceField);
142 addUnmatchedDestField(destField); 142 addUnmatchedDestField(destField);
@@ -144,7 +144,7 @@ public class FieldMatches {
144 144
145 public void makeSourceUnmatchable(FieldEntry sourceField) { 145 public void makeSourceUnmatchable(FieldEntry sourceField) {
146 assert (!isMatchedSourceField(sourceField)); 146 assert (!isMatchedSourceField(sourceField));
147 boolean wasRemoved = m_unmatchedSourceFields.remove(sourceField.getClassEntry(), sourceField); 147 boolean wasRemoved = unmatchedSourceFields.remove(sourceField.getClassEntry(), sourceField);
148 assert (wasRemoved); 148 assert (wasRemoved);
149 addUnmatchableSourceField(sourceField); 149 addUnmatchableSourceField(sourceField);
150 } 150 }
diff --git a/src/main/java/cuchaz/enigma/convert/MappingsConverter.java b/src/main/java/cuchaz/enigma/convert/MappingsConverter.java
index 929c89f2..a5ded677 100644
--- a/src/main/java/cuchaz/enigma/convert/MappingsConverter.java
+++ b/src/main/java/cuchaz/enigma/convert/MappingsConverter.java
@@ -11,7 +11,6 @@
11package cuchaz.enigma.convert; 11package cuchaz.enigma.convert;
12 12
13import com.google.common.collect.*; 13import com.google.common.collect.*;
14import cuchaz.enigma.Constants;
15import cuchaz.enigma.Deobfuscator; 14import cuchaz.enigma.Deobfuscator;
16import cuchaz.enigma.TranslatingTypeLoader; 15import cuchaz.enigma.TranslatingTypeLoader;
17import cuchaz.enigma.analysis.JarIndex; 16import cuchaz.enigma.analysis.JarIndex;
@@ -24,7 +23,6 @@ import javassist.NotFoundException;
24import javassist.bytecode.BadBytecode; 23import javassist.bytecode.BadBytecode;
25import javassist.bytecode.CodeAttribute; 24import javassist.bytecode.CodeAttribute;
26import javassist.bytecode.CodeIterator; 25import javassist.bytecode.CodeIterator;
27import javassist.bytecode.MethodInfo;
28 26
29import java.util.*; 27import java.util.*;
30import java.util.jar.JarFile; 28import java.util.jar.JarFile;
@@ -174,15 +172,13 @@ public class MappingsConverter {
174 172
175 private static ClassMapping migrateClassMapping(ClassEntry newObfClass, ClassMapping oldClassMapping, final ClassMatches matches, boolean useSimpleName) { 173 private static ClassMapping migrateClassMapping(ClassEntry newObfClass, ClassMapping oldClassMapping, final ClassMatches matches, boolean useSimpleName) {
176 174
177 ClassNameReplacer replacer = new ClassNameReplacer() { 175 ClassNameReplacer replacer = className ->
178 @Override 176 {
179 public String replace(String className) { 177 ClassEntry newClassEntry = matches.getUniqueMatches().get(new ClassEntry(className));
180 ClassEntry newClassEntry = matches.getUniqueMatches().get(new ClassEntry(className)); 178 if (newClassEntry != null) {
181 if (newClassEntry != null) { 179 return newClassEntry.getName();
182 return newClassEntry.getName();
183 }
184 return null;
185 } 180 }
181 return null;
186 }; 182 };
187 183
188 ClassMapping newClassMapping; 184 ClassMapping newClassMapping;
@@ -434,13 +430,12 @@ public class MappingsConverter {
434 // Empty method body, ignore! 430 // Empty method body, ignore!
435 if (sourceAttribute == null) 431 if (sourceAttribute == null)
436 return null; 432 return null;
437 Iterator<BehaviorEntry> it = obfDestEntries.iterator(); 433 for (BehaviorEntry desEntry : obfDestEntries)
438 while (it.hasNext())
439 { 434 {
440 BehaviorEntry desEntry = it.next();
441 try 435 try
442 { 436 {
443 CtMethod destCtClassMethod = destCtClass.getMethod(desEntry.getName(), desEntry.getSignature().toString()); 437 CtMethod destCtClassMethod = destCtClass
438 .getMethod(desEntry.getName(), desEntry.getSignature().toString());
444 CodeAttribute destAttribute = destCtClassMethod.getMethodInfo().getCodeAttribute(); 439 CodeAttribute destAttribute = destCtClassMethod.getMethodInfo().getCodeAttribute();
445 440
446 // Ignore empty body methods 441 // Ignore empty body methods
@@ -533,7 +528,7 @@ public class MappingsConverter {
533 528
534 public static <T extends Entry> MemberMatches<T> computeMemberMatches(Deobfuscator destDeobfuscator, Mappings destMappings, ClassMatches classMatches, Doer<T> doer) { 529 public static <T extends Entry> MemberMatches<T> computeMemberMatches(Deobfuscator destDeobfuscator, Mappings destMappings, ClassMatches classMatches, Doer<T> doer) {
535 530
536 MemberMatches<T> memberMatches = new MemberMatches<T>(); 531 MemberMatches<T> memberMatches = new MemberMatches<>();
537 532
538 // unmatched source fields are easy 533 // unmatched source fields are easy
539 MappingsChecker checker = new MappingsChecker(destDeobfuscator.getJarIndex()); 534 MappingsChecker checker = new MappingsChecker(destDeobfuscator.getJarIndex());
@@ -624,15 +619,13 @@ public class MappingsConverter {
624 } 619 }
625 620
626 private static Type translate(Type type, final BiMap<ClassEntry, ClassEntry> map) { 621 private static Type translate(Type type, final BiMap<ClassEntry, ClassEntry> map) {
627 return new Type(type, new ClassNameReplacer() { 622 return new Type(type, inClassName ->
628 @Override 623 {
629 public String replace(String inClassName) { 624 ClassEntry outClassEntry = map.get(new ClassEntry(inClassName));
630 ClassEntry outClassEntry = map.get(new ClassEntry(inClassName)); 625 if (outClassEntry == null) {
631 if (outClassEntry == null) { 626 return null;
632 return null;
633 }
634 return outClassEntry.getName();
635 } 627 }
628 return outClassEntry.getName();
636 }); 629 });
637 } 630 }
638 631
@@ -640,15 +633,13 @@ public class MappingsConverter {
640 if (signature == null) { 633 if (signature == null) {
641 return null; 634 return null;
642 } 635 }
643 return new Signature(signature, new ClassNameReplacer() { 636 return new Signature(signature, inClassName ->
644 @Override 637 {
645 public String replace(String inClassName) { 638 ClassEntry outClassEntry = map.get(new ClassEntry(inClassName));
646 ClassEntry outClassEntry = map.get(new ClassEntry(inClassName)); 639 if (outClassEntry == null) {
647 if (outClassEntry == null) { 640 return null;
648 return null;
649 }
650 return outClassEntry.getName();
651 } 641 }
642 return outClassEntry.getName();
652 }); 643 });
653 } 644 }
654 645
diff --git a/src/main/java/cuchaz/enigma/convert/MatchesReader.java b/src/main/java/cuchaz/enigma/convert/MatchesReader.java
index 550da497..d86d6c2a 100644
--- a/src/main/java/cuchaz/enigma/convert/MatchesReader.java
+++ b/src/main/java/cuchaz/enigma/convert/MatchesReader.java
@@ -34,8 +34,7 @@ public class MatchesReader {
34 } 34 }
35 } 35 }
36 36
37 private static ClassMatch readClassMatch(String line) 37 private static ClassMatch readClassMatch(String line) {
38 throws IOException {
39 String[] sides = line.split(":", 2); 38 String[] sides = line.split(":", 2);
40 return new ClassMatch(readClasses(sides[0]), readClasses(sides[1])); 39 return new ClassMatch(readClasses(sides[0]), readClasses(sides[1]));
41 } 40 }
@@ -54,7 +53,7 @@ public class MatchesReader {
54 public static <T extends Entry> MemberMatches<T> readMembers(File file) 53 public static <T extends Entry> MemberMatches<T> readMembers(File file)
55 throws IOException { 54 throws IOException {
56 try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")))) { 55 try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")))) {
57 MemberMatches<T> matches = new MemberMatches<T>(); 56 MemberMatches<T> matches = new MemberMatches<>();
58 String line; 57 String line;
59 while ((line = in.readLine()) != null) { 58 while ((line = in.readLine()) != null) {
60 readMemberMatch(matches, line); 59 readMemberMatch(matches, line);
diff --git a/src/main/java/cuchaz/enigma/convert/MemberMatches.java b/src/main/java/cuchaz/enigma/convert/MemberMatches.java
index 25af2f8e..51cee859 100644
--- a/src/main/java/cuchaz/enigma/convert/MemberMatches.java
+++ b/src/main/java/cuchaz/enigma/convert/MemberMatches.java
@@ -21,29 +21,29 @@ import java.util.Set;
21 21
22public class MemberMatches<T extends Entry> { 22public class MemberMatches<T extends Entry> {
23 23
24 private BiMap<T, T> m_matches; 24 private BiMap<T, T> matches;
25 private Multimap<ClassEntry, T> m_matchedSourceEntries; 25 private Multimap<ClassEntry, T> matchedSourceEntries;
26 private Multimap<ClassEntry, T> m_unmatchedSourceEntries; 26 private Multimap<ClassEntry, T> unmatchedSourceEntries;
27 private Multimap<ClassEntry, T> m_unmatchedDestEntries; 27 private Multimap<ClassEntry, T> unmatchedDestEntries;
28 private Multimap<ClassEntry, T> m_unmatchableSourceEntries; 28 private Multimap<ClassEntry, T> unmatchableSourceEntries;
29 29
30 public MemberMatches() { 30 public MemberMatches() {
31 m_matches = HashBiMap.create(); 31 matches = HashBiMap.create();
32 m_matchedSourceEntries = HashMultimap.create(); 32 matchedSourceEntries = HashMultimap.create();
33 m_unmatchedSourceEntries = HashMultimap.create(); 33 unmatchedSourceEntries = HashMultimap.create();
34 m_unmatchedDestEntries = HashMultimap.create(); 34 unmatchedDestEntries = HashMultimap.create();
35 m_unmatchableSourceEntries = HashMultimap.create(); 35 unmatchableSourceEntries = HashMultimap.create();
36 } 36 }
37 37
38 public void addMatch(T srcEntry, T destEntry) { 38 public void addMatch(T srcEntry, T destEntry) {
39 boolean wasAdded = m_matches.put(srcEntry, destEntry) == null; 39 boolean wasAdded = matches.put(srcEntry, destEntry) == null;
40 assert (wasAdded); 40 assert (wasAdded);
41 wasAdded = m_matchedSourceEntries.put(srcEntry.getClassEntry(), srcEntry); 41 wasAdded = matchedSourceEntries.put(srcEntry.getClassEntry(), srcEntry);
42 assert (wasAdded); 42 assert (wasAdded);
43 } 43 }
44 44
45 public void addUnmatchedSourceEntry(T sourceEntry) { 45 public void addUnmatchedSourceEntry(T sourceEntry) {
46 boolean wasAdded = m_unmatchedSourceEntries.put(sourceEntry.getClassEntry(), sourceEntry); 46 boolean wasAdded = unmatchedSourceEntries.put(sourceEntry.getClassEntry(), sourceEntry);
47 assert (wasAdded); 47 assert (wasAdded);
48 } 48 }
49 49
@@ -56,7 +56,7 @@ public class MemberMatches<T extends Entry> {
56 public void addUnmatchedDestEntry(T destEntry) { 56 public void addUnmatchedDestEntry(T destEntry) {
57 if (destEntry.getName().equals("<clinit>") || destEntry.getName().equals("<init>")) 57 if (destEntry.getName().equals("<clinit>") || destEntry.getName().equals("<init>"))
58 return; 58 return;
59 boolean wasAdded = m_unmatchedDestEntries.put(destEntry.getClassEntry(), destEntry); 59 boolean wasAdded = unmatchedDestEntries.put(destEntry.getClassEntry(), destEntry);
60 assert (wasAdded); 60 assert (wasAdded);
61 } 61 }
62 62
@@ -67,63 +67,63 @@ public class MemberMatches<T extends Entry> {
67 } 67 }
68 68
69 public void addUnmatchableSourceEntry(T sourceEntry) { 69 public void addUnmatchableSourceEntry(T sourceEntry) {
70 boolean wasAdded = m_unmatchableSourceEntries.put(sourceEntry.getClassEntry(), sourceEntry); 70 boolean wasAdded = unmatchableSourceEntries.put(sourceEntry.getClassEntry(), sourceEntry);
71 assert (wasAdded); 71 assert (wasAdded);
72 } 72 }
73 73
74 public Set<ClassEntry> getSourceClassesWithUnmatchedEntries() { 74 public Set<ClassEntry> getSourceClassesWithUnmatchedEntries() {
75 return m_unmatchedSourceEntries.keySet(); 75 return unmatchedSourceEntries.keySet();
76 } 76 }
77 77
78 public Collection<ClassEntry> getSourceClassesWithoutUnmatchedEntries() { 78 public Collection<ClassEntry> getSourceClassesWithoutUnmatchedEntries() {
79 Set<ClassEntry> out = Sets.newHashSet(); 79 Set<ClassEntry> out = Sets.newHashSet();
80 out.addAll(m_matchedSourceEntries.keySet()); 80 out.addAll(matchedSourceEntries.keySet());
81 out.removeAll(m_unmatchedSourceEntries.keySet()); 81 out.removeAll(unmatchedSourceEntries.keySet());
82 return out; 82 return out;
83 } 83 }
84 84
85 public Collection<T> getUnmatchedSourceEntries() { 85 public Collection<T> getUnmatchedSourceEntries() {
86 return m_unmatchedSourceEntries.values(); 86 return unmatchedSourceEntries.values();
87 } 87 }
88 88
89 public Collection<T> getUnmatchedSourceEntries(ClassEntry sourceClass) { 89 public Collection<T> getUnmatchedSourceEntries(ClassEntry sourceClass) {
90 return m_unmatchedSourceEntries.get(sourceClass); 90 return unmatchedSourceEntries.get(sourceClass);
91 } 91 }
92 92
93 public Collection<T> getUnmatchedDestEntries() { 93 public Collection<T> getUnmatchedDestEntries() {
94 return m_unmatchedDestEntries.values(); 94 return unmatchedDestEntries.values();
95 } 95 }
96 96
97 public Collection<T> getUnmatchedDestEntries(ClassEntry destClass) { 97 public Collection<T> getUnmatchedDestEntries(ClassEntry destClass) {
98 return m_unmatchedDestEntries.get(destClass); 98 return unmatchedDestEntries.get(destClass);
99 } 99 }
100 100
101 public Collection<T> getUnmatchableSourceEntries() { 101 public Collection<T> getUnmatchableSourceEntries() {
102 return m_unmatchableSourceEntries.values(); 102 return unmatchableSourceEntries.values();
103 } 103 }
104 104
105 public boolean hasSource(T sourceEntry) { 105 public boolean hasSource(T sourceEntry) {
106 return m_matches.containsKey(sourceEntry) || m_unmatchedSourceEntries.containsValue(sourceEntry); 106 return matches.containsKey(sourceEntry) || unmatchedSourceEntries.containsValue(sourceEntry);
107 } 107 }
108 108
109 public boolean hasDest(T destEntry) { 109 public boolean hasDest(T destEntry) {
110 return m_matches.containsValue(destEntry) || m_unmatchedDestEntries.containsValue(destEntry); 110 return matches.containsValue(destEntry) || unmatchedDestEntries.containsValue(destEntry);
111 } 111 }
112 112
113 public BiMap<T, T> matches() { 113 public BiMap<T, T> matches() {
114 return m_matches; 114 return matches;
115 } 115 }
116 116
117 public boolean isMatchedSourceEntry(T sourceEntry) { 117 public boolean isMatchedSourceEntry(T sourceEntry) {
118 return m_matches.containsKey(sourceEntry); 118 return matches.containsKey(sourceEntry);
119 } 119 }
120 120
121 public boolean isMatchedDestEntry(T destEntry) { 121 public boolean isMatchedDestEntry(T destEntry) {
122 return m_matches.containsValue(destEntry); 122 return matches.containsValue(destEntry);
123 } 123 }
124 124
125 public boolean isUnmatchableSourceEntry(T sourceEntry) { 125 public boolean isUnmatchableSourceEntry(T sourceEntry) {
126 return m_unmatchableSourceEntries.containsEntry(sourceEntry.getClassEntry(), sourceEntry); 126 return unmatchableSourceEntries.containsEntry(sourceEntry.getClassEntry(), sourceEntry);
127 } 127 }
128 public void makeMatch(T sourceEntry, T destEntry) { 128 public void makeMatch(T sourceEntry, T destEntry) {
129 makeMatch(sourceEntry, destEntry, null, null); 129 makeMatch(sourceEntry, destEntry, null, null);
@@ -136,15 +136,15 @@ public class MemberMatches<T extends Entry> {
136 sourceEntry = (T) sourceEntry.cloneToNewClass(sourceDeobfuscator.getJarIndex().getTranslationIndex().resolveEntryClass(sourceEntry, true)); 136 sourceEntry = (T) sourceEntry.cloneToNewClass(sourceDeobfuscator.getJarIndex().getTranslationIndex().resolveEntryClass(sourceEntry, true));
137 destEntry = (T) destEntry.cloneToNewClass(destDeobfuscator.getJarIndex().getTranslationIndex().resolveEntryClass(destEntry, true)); 137 destEntry = (T) destEntry.cloneToNewClass(destDeobfuscator.getJarIndex().getTranslationIndex().resolveEntryClass(destEntry, true));
138 } 138 }
139 boolean wasRemoved = m_unmatchedSourceEntries.remove(sourceEntry.getClassEntry(), sourceEntry); 139 boolean wasRemoved = unmatchedSourceEntries.remove(sourceEntry.getClassEntry(), sourceEntry);
140 assert (wasRemoved); 140 assert (wasRemoved);
141 wasRemoved = m_unmatchedDestEntries.remove(destEntry.getClassEntry(), destEntry); 141 wasRemoved = unmatchedDestEntries.remove(destEntry.getClassEntry(), destEntry);
142 assert (wasRemoved); 142 assert (wasRemoved);
143 addMatch(sourceEntry, destEntry); 143 addMatch(sourceEntry, destEntry);
144 } 144 }
145 145
146 public boolean isMatched(T sourceEntry, T destEntry) { 146 public boolean isMatched(T sourceEntry, T destEntry) {
147 T match = m_matches.get(sourceEntry); 147 T match = matches.get(sourceEntry);
148 return match != null && match.equals(destEntry); 148 return match != null && match.equals(destEntry);
149 } 149 }
150 150
@@ -159,9 +159,9 @@ public class MemberMatches<T extends Entry> {
159 destDeobfuscator.getJarIndex().getTranslationIndex().resolveEntryClass(destEntry, true)); 159 destDeobfuscator.getJarIndex().getTranslationIndex().resolveEntryClass(destEntry, true));
160 } 160 }
161 161
162 boolean wasRemoved = m_matches.remove(sourceEntry) != null; 162 boolean wasRemoved = matches.remove(sourceEntry) != null;
163 assert (wasRemoved); 163 assert (wasRemoved);
164 wasRemoved = m_matchedSourceEntries.remove(sourceEntry.getClassEntry(), sourceEntry); 164 wasRemoved = matchedSourceEntries.remove(sourceEntry.getClassEntry(), sourceEntry);
165 assert (wasRemoved); 165 assert (wasRemoved);
166 addUnmatchedSourceEntry(sourceEntry); 166 addUnmatchedSourceEntry(sourceEntry);
167 addUnmatchedDestEntry(destEntry); 167 addUnmatchedDestEntry(destEntry);
@@ -175,7 +175,7 @@ public class MemberMatches<T extends Entry> {
175 sourceDeobfuscator.getJarIndex().getTranslationIndex().resolveEntryClass(sourceEntry, true)); 175 sourceDeobfuscator.getJarIndex().getTranslationIndex().resolveEntryClass(sourceEntry, true));
176 } 176 }
177 assert (!isMatchedSourceEntry(sourceEntry)); 177 assert (!isMatchedSourceEntry(sourceEntry));
178 boolean wasRemoved = m_unmatchedSourceEntries.remove(sourceEntry.getClassEntry(), sourceEntry); 178 boolean wasRemoved = unmatchedSourceEntries.remove(sourceEntry.getClassEntry(), sourceEntry);
179 assert (wasRemoved); 179 assert (wasRemoved);
180 addUnmatchableSourceEntry(sourceEntry); 180 addUnmatchableSourceEntry(sourceEntry);
181 } 181 }
diff --git a/src/main/java/cuchaz/enigma/gui/BrowserCaret.java b/src/main/java/cuchaz/enigma/gui/BrowserCaret.java
index 013778a2..bcdff51e 100644
--- a/src/main/java/cuchaz/enigma/gui/BrowserCaret.java
+++ b/src/main/java/cuchaz/enigma/gui/BrowserCaret.java
@@ -11,7 +11,6 @@
11package cuchaz.enigma.gui; 11package cuchaz.enigma.gui;
12 12
13import javax.swing.text.DefaultCaret; 13import javax.swing.text.DefaultCaret;
14import javax.swing.text.Highlighter;
15 14
16public class BrowserCaret extends DefaultCaret { 15public class BrowserCaret extends DefaultCaret {
17 16
diff --git a/src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java b/src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java
index edf1e30b..dcbe1c5b 100644
--- a/src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java
+++ b/src/main/java/cuchaz/enigma/gui/ClassMatchingGui.java
@@ -13,19 +13,6 @@ package cuchaz.enigma.gui;
13import com.google.common.collect.BiMap; 13import com.google.common.collect.BiMap;
14import com.google.common.collect.Lists; 14import com.google.common.collect.Lists;
15import com.google.common.collect.Maps; 15import com.google.common.collect.Maps;
16
17import java.awt.BorderLayout;
18import java.awt.Container;
19import java.awt.Dimension;
20import java.awt.FlowLayout;
21import java.awt.event.ActionListener;
22import java.util.Collection;
23import java.util.Collections;
24import java.util.List;
25import java.util.Map;
26
27import javax.swing.*;
28
29import cuchaz.enigma.Constants; 16import cuchaz.enigma.Constants;
30import cuchaz.enigma.Deobfuscator; 17import cuchaz.enigma.Deobfuscator;
31import cuchaz.enigma.convert.*; 18import cuchaz.enigma.convert.*;
@@ -37,6 +24,13 @@ import cuchaz.enigma.mapping.MappingsChecker;
37import cuchaz.enigma.throwables.MappingConflict; 24import cuchaz.enigma.throwables.MappingConflict;
38import de.sciss.syntaxpane.DefaultSyntaxKit; 25import de.sciss.syntaxpane.DefaultSyntaxKit;
39 26
27import javax.swing.*;
28import java.awt.*;
29import java.awt.event.ActionListener;
30import java.util.Collection;
31import java.util.List;
32import java.util.Map;
33
40 34
41public class ClassMatchingGui { 35public class ClassMatchingGui {
42 36
@@ -80,35 +74,35 @@ public class ClassMatchingGui {
80 } 74 }
81 75
82 // controls 76 // controls
83 private JFrame m_frame; 77 private JFrame frame;
84 private ClassSelector m_sourceClasses; 78 private ClassSelector sourceClasses;
85 private ClassSelector m_destClasses; 79 private ClassSelector destClasses;
86 private CodeReader m_sourceReader; 80 private CodeReader sourceReader;
87 private CodeReader m_destReader; 81 private CodeReader destReader;
88 private JLabel m_sourceClassLabel; 82 private JLabel sourceClassLabel;
89 private JLabel m_destClassLabel; 83 private JLabel destClassLabel;
90 private JButton m_matchButton; 84 private JButton matchButton;
91 private Map<SourceType, JRadioButton> m_sourceTypeButtons; 85 private Map<SourceType, JRadioButton> sourceTypeButtons;
92 private JCheckBox m_advanceCheck; 86 private JCheckBox advanceCheck;
93 private JCheckBox m_top10Matches; 87 private JCheckBox top10Matches;
94 88
95 private ClassMatches m_classMatches; 89 private ClassMatches classMatches;
96 private Deobfuscator m_sourceDeobfuscator; 90 private Deobfuscator sourceDeobfuscator;
97 private Deobfuscator m_destDeobfuscator; 91 private Deobfuscator destDeobfuscator;
98 private ClassEntry m_sourceClass; 92 private ClassEntry sourceClass;
99 private ClassEntry m_destClass; 93 private ClassEntry destClass;
100 private SourceType m_sourceType; 94 private SourceType sourceType;
101 private SaveListener m_saveListener; 95 private SaveListener saveListener;
102 96
103 public ClassMatchingGui(ClassMatches matches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) { 97 public ClassMatchingGui(ClassMatches matches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) {
104 98
105 m_classMatches = matches; 99 classMatches = matches;
106 m_sourceDeobfuscator = sourceDeobfuscator; 100 this.sourceDeobfuscator = sourceDeobfuscator;
107 m_destDeobfuscator = destDeobfuscator; 101 this.destDeobfuscator = destDeobfuscator;
108 102
109 // init frame 103 // init frame
110 m_frame = new JFrame(Constants.NAME + " - Class Matcher"); 104 frame = new JFrame(Constants.NAME + " - Class Matcher");
111 final Container pane = m_frame.getContentPane(); 105 final Container pane = frame.getContentPane();
112 pane.setLayout(new BorderLayout()); 106 pane.setLayout(new BorderLayout());
113 107
114 // init source side 108 // init source side
@@ -124,16 +118,16 @@ public class ClassMatchingGui {
124 sourceTypePanel.setLayout(new BoxLayout(sourceTypePanel, BoxLayout.PAGE_AXIS)); 118 sourceTypePanel.setLayout(new BoxLayout(sourceTypePanel, BoxLayout.PAGE_AXIS));
125 ActionListener sourceTypeListener = event -> setSourceType(SourceType.valueOf(event.getActionCommand())); 119 ActionListener sourceTypeListener = event -> setSourceType(SourceType.valueOf(event.getActionCommand()));
126 ButtonGroup sourceTypeButtons = new ButtonGroup(); 120 ButtonGroup sourceTypeButtons = new ButtonGroup();
127 m_sourceTypeButtons = Maps.newHashMap(); 121 this.sourceTypeButtons = Maps.newHashMap();
128 for (SourceType sourceType : SourceType.values()) { 122 for (SourceType sourceType : SourceType.values()) {
129 JRadioButton button = sourceType.newRadio(sourceTypeListener, sourceTypeButtons); 123 JRadioButton button = sourceType.newRadio(sourceTypeListener, sourceTypeButtons);
130 m_sourceTypeButtons.put(sourceType, button); 124 this.sourceTypeButtons.put(sourceType, button);
131 sourceTypePanel.add(button); 125 sourceTypePanel.add(button);
132 } 126 }
133 127
134 m_sourceClasses = new ClassSelector(null, ClassSelector.DEOBF_CLASS_COMPARATOR, false); 128 sourceClasses = new ClassSelector(null, ClassSelector.DEOBF_CLASS_COMPARATOR, false);
135 m_sourceClasses.setSelectionListener(this::setSourceClass); 129 sourceClasses.setSelectionListener(this::setSourceClass);
136 JScrollPane sourceScroller = new JScrollPane(m_sourceClasses); 130 JScrollPane sourceScroller = new JScrollPane(sourceClasses);
137 sourcePanel.add(sourceScroller); 131 sourcePanel.add(sourceScroller);
138 132
139 // init dest side 133 // init dest side
@@ -143,13 +137,13 @@ public class ClassMatchingGui {
143 pane.add(destPanel, BorderLayout.WEST); 137 pane.add(destPanel, BorderLayout.WEST);
144 destPanel.add(new JLabel("Destination Classes")); 138 destPanel.add(new JLabel("Destination Classes"));
145 139
146 m_top10Matches = new JCheckBox("Show only top 10 matches"); 140 top10Matches = new JCheckBox("Show only top 10 matches");
147 destPanel.add(m_top10Matches); 141 destPanel.add(top10Matches);
148 m_top10Matches.addActionListener(event -> toggleTop10Matches()); 142 top10Matches.addActionListener(event -> toggleTop10Matches());
149 143
150 m_destClasses = new ClassSelector(null, ClassSelector.DEOBF_CLASS_COMPARATOR, false); 144 destClasses = new ClassSelector(null, ClassSelector.DEOBF_CLASS_COMPARATOR, false);
151 m_destClasses.setSelectionListener(this::setDestClass); 145 destClasses.setSelectionListener(this::setDestClass);
152 JScrollPane destScroller = new JScrollPane(m_destClasses); 146 JScrollPane destScroller = new JScrollPane(destClasses);
153 destPanel.add(destScroller); 147 destPanel.add(destScroller);
154 148
155 JButton autoMatchButton = new JButton("AutoMatch"); 149 JButton autoMatchButton = new JButton("AutoMatch");
@@ -158,13 +152,14 @@ public class ClassMatchingGui {
158 152
159 // init source panels 153 // init source panels
160 DefaultSyntaxKit.initKit(); 154 DefaultSyntaxKit.initKit();
161 m_sourceReader = new CodeReader(); 155 sourceReader = new CodeReader();
162 m_destReader = new CodeReader(); 156 destReader = new CodeReader();
163 157
164 // init all the splits 158 // init all the splits
165 JSplitPane splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, sourcePanel, new JScrollPane(m_sourceReader)); 159 JSplitPane splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, sourcePanel, new JScrollPane(
160 sourceReader));
166 splitLeft.setResizeWeight(0); // let the right side take all the slack 161 splitLeft.setResizeWeight(0); // let the right side take all the slack
167 JSplitPane splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JScrollPane(m_destReader), destPanel); 162 JSplitPane splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JScrollPane(destReader), destPanel);
168 splitRight.setResizeWeight(1); // let the left side take all the slack 163 splitRight.setResizeWeight(1); // let the left side take all the slack
169 JSplitPane splitCenter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, splitLeft, splitRight); 164 JSplitPane splitCenter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, splitLeft, splitRight);
170 splitCenter.setResizeWeight(0.5); // resize 50:50 165 splitCenter.setResizeWeight(0.5); // resize 50:50
@@ -175,55 +170,52 @@ public class ClassMatchingGui {
175 JPanel bottomPanel = new JPanel(); 170 JPanel bottomPanel = new JPanel();
176 bottomPanel.setLayout(new FlowLayout()); 171 bottomPanel.setLayout(new FlowLayout());
177 172
178 m_sourceClassLabel = new JLabel(); 173 sourceClassLabel = new JLabel();
179 m_sourceClassLabel.setHorizontalAlignment(SwingConstants.RIGHT); 174 sourceClassLabel.setHorizontalAlignment(SwingConstants.RIGHT);
180 m_destClassLabel = new JLabel(); 175 destClassLabel = new JLabel();
181 m_destClassLabel.setHorizontalAlignment(SwingConstants.LEFT); 176 destClassLabel.setHorizontalAlignment(SwingConstants.LEFT);
182 177
183 m_matchButton = new JButton(); 178 matchButton = new JButton();
184 179
185 m_advanceCheck = new JCheckBox("Advance to next likely match"); 180 advanceCheck = new JCheckBox("Advance to next likely match");
186 m_advanceCheck.addActionListener(event -> { 181 advanceCheck.addActionListener(event -> {
187 if (m_advanceCheck.isSelected()) { 182 if (advanceCheck.isSelected()) {
188 advance(); 183 advance();
189 } 184 }
190 }); 185 });
191 186
192 bottomPanel.add(m_sourceClassLabel); 187 bottomPanel.add(sourceClassLabel);
193 bottomPanel.add(m_matchButton); 188 bottomPanel.add(matchButton);
194 bottomPanel.add(m_destClassLabel); 189 bottomPanel.add(destClassLabel);
195 bottomPanel.add(m_advanceCheck); 190 bottomPanel.add(advanceCheck);
196 pane.add(bottomPanel, BorderLayout.SOUTH); 191 pane.add(bottomPanel, BorderLayout.SOUTH);
197 192
198 // show the frame 193 // show the frame
199 pane.doLayout(); 194 pane.doLayout();
200 m_frame.setSize(1024, 576); 195 frame.setSize(1024, 576);
201 m_frame.setMinimumSize(new Dimension(640, 480)); 196 frame.setMinimumSize(new Dimension(640, 480));
202 m_frame.setVisible(true); 197 frame.setVisible(true);
203 m_frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 198 frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
204 199
205 // init state 200 // init state
206 updateDestMappings(); 201 updateDestMappings();
207 setSourceType(SourceType.getDefault()); 202 setSourceType(SourceType.getDefault());
208 updateMatchButton(); 203 updateMatchButton();
209 m_saveListener = null; 204 saveListener = null;
210 } 205 }
211 206
212 public void setSaveListener(SaveListener val) { 207 public void setSaveListener(SaveListener val) {
213 m_saveListener = val; 208 saveListener = val;
214 } 209 }
215 210
216 private void updateDestMappings() { 211 private void updateDestMappings() {
217 try { 212 try {
218 Mappings newMappings = MappingsConverter.newMappings( 213 Mappings newMappings = MappingsConverter.newMappings(classMatches,
219 m_classMatches, 214 sourceDeobfuscator.getMappings(), sourceDeobfuscator, destDeobfuscator
220 m_sourceDeobfuscator.getMappings(),
221 m_sourceDeobfuscator,
222 m_destDeobfuscator
223 ); 215 );
224 216
225 // look for dropped mappings 217 // look for dropped mappings
226 MappingsChecker checker = new MappingsChecker(m_destDeobfuscator.getJarIndex()); 218 MappingsChecker checker = new MappingsChecker(destDeobfuscator.getJarIndex());
227 checker.dropBrokenMappings(newMappings); 219 checker.dropBrokenMappings(newMappings);
228 220
229 // count them 221 // count them
@@ -236,7 +228,7 @@ public class ClassMatchingGui {
236 numDroppedMethods 228 numDroppedMethods
237 )); 229 ));
238 230
239 m_destDeobfuscator.setMappings(newMappings); 231 destDeobfuscator.setMappings(newMappings);
240 } catch (MappingConflict ex) { 232 } catch (MappingConflict ex) {
241 System.out.println(ex.getMessage()); 233 System.out.println(ex.getMessage());
242 ex.printStackTrace(); 234 ex.printStackTrace();
@@ -247,14 +239,14 @@ public class ClassMatchingGui {
247 protected void setSourceType(SourceType val) { 239 protected void setSourceType(SourceType val) {
248 240
249 // show the source classes 241 // show the source classes
250 m_sourceType = val; 242 sourceType = val;
251 m_sourceClasses.setClasses(deobfuscateClasses(m_sourceType.getSourceClasses(m_classMatches), m_sourceDeobfuscator)); 243 sourceClasses.setClasses(deobfuscateClasses(sourceType.getSourceClasses(classMatches), sourceDeobfuscator));
252 244
253 // update counts 245 // update counts
254 for (SourceType sourceType : SourceType.values()) { 246 for (SourceType sourceType : SourceType.values()) {
255 m_sourceTypeButtons.get(sourceType).setText(String.format("%s (%d)", 247 sourceTypeButtons.get(sourceType).setText(String.format("%s (%d)",
256 sourceType.name(), 248 sourceType.name(),
257 sourceType.getSourceClasses(m_classMatches).size() 249 sourceType.getSourceClasses(classMatches).size()
258 )); 250 ));
259 } 251 }
260 } 252 }
@@ -278,7 +270,7 @@ public class ClassMatchingGui {
278 protected void setSourceClass(ClassEntry classEntry) { 270 protected void setSourceClass(ClassEntry classEntry) {
279 271
280 Runnable onGetDestClasses = null; 272 Runnable onGetDestClasses = null;
281 if (m_advanceCheck.isSelected()) { 273 if (advanceCheck.isSelected()) {
282 onGetDestClasses = this::pickBestDestClass; 274 onGetDestClasses = this::pickBestDestClass;
283 } 275 }
284 276
@@ -288,35 +280,33 @@ public class ClassMatchingGui {
288 protected void setSourceClass(ClassEntry classEntry, final Runnable onGetDestClasses) { 280 protected void setSourceClass(ClassEntry classEntry, final Runnable onGetDestClasses) {
289 281
290 // update the current source class 282 // update the current source class
291 m_sourceClass = classEntry; 283 sourceClass = classEntry;
292 m_sourceClassLabel.setText(m_sourceClass != null ? m_sourceClass.getName() : ""); 284 sourceClassLabel.setText(sourceClass != null ? sourceClass.getName() : "");
293 285
294 if (m_sourceClass != null) { 286 if (sourceClass != null) {
295 287
296 // show the dest class(es) 288 // show the dest class(es)
297 ClassMatch match = m_classMatches.getMatchBySource(m_sourceDeobfuscator.obfuscateEntry(m_sourceClass)); 289 ClassMatch match = classMatches.getMatchBySource(sourceDeobfuscator.obfuscateEntry(sourceClass));
298 assert (match != null); 290 assert (match != null);
299 if (match.destClasses.isEmpty()) { 291 if (match.destClasses.isEmpty()) {
300 292
301 m_destClasses.setClasses(null); 293 destClasses.setClasses(null);
302 294
303 // run in a separate thread to keep ui responsive 295 // run in a separate thread to keep ui responsive
304 new Thread() { 296 new Thread(() ->
305 @Override 297 {
306 public void run() { 298 destClasses.setClasses(deobfuscateClasses(getLikelyMatches(sourceClass), destDeobfuscator));
307 m_destClasses.setClasses(deobfuscateClasses(getLikelyMatches(m_sourceClass), m_destDeobfuscator)); 299 destClasses.expandAll();
308 m_destClasses.expandAll(); 300
309 301 if (onGetDestClasses != null) {
310 if (onGetDestClasses != null) { 302 onGetDestClasses.run();
311 onGetDestClasses.run();
312 }
313 } 303 }
314 }.start(); 304 }).start();
315 305
316 } else { 306 } else {
317 307
318 m_destClasses.setClasses(deobfuscateClasses(match.destClasses, m_destDeobfuscator)); 308 destClasses.setClasses(deobfuscateClasses(match.destClasses, destDeobfuscator));
319 m_destClasses.expandAll(); 309 destClasses.expandAll();
320 310
321 if (onGetDestClasses != null) { 311 if (onGetDestClasses != null) {
322 onGetDestClasses.run(); 312 onGetDestClasses.run();
@@ -325,23 +315,24 @@ public class ClassMatchingGui {
325 } 315 }
326 316
327 setDestClass(null); 317 setDestClass(null);
328 m_sourceReader.decompileClass(m_sourceClass, m_sourceDeobfuscator, () -> m_sourceReader.navigateToClassDeclaration(m_sourceClass)); 318 sourceReader.decompileClass(
319 sourceClass, sourceDeobfuscator, () -> sourceReader.navigateToClassDeclaration(sourceClass));
329 320
330 updateMatchButton(); 321 updateMatchButton();
331 } 322 }
332 323
333 private Collection<ClassEntry> getLikelyMatches(ClassEntry sourceClass) { 324 private Collection<ClassEntry> getLikelyMatches(ClassEntry sourceClass) {
334 325
335 ClassEntry obfSourceClass = m_sourceDeobfuscator.obfuscateEntry(sourceClass); 326 ClassEntry obfSourceClass = sourceDeobfuscator.obfuscateEntry(sourceClass);
336 327
337 // set up identifiers 328 // set up identifiers
338 ClassNamer namer = new ClassNamer(m_classMatches.getUniqueMatches()); 329 ClassNamer namer = new ClassNamer(classMatches.getUniqueMatches());
339 ClassIdentifier sourceIdentifier = new ClassIdentifier( 330 ClassIdentifier sourceIdentifier = new ClassIdentifier(
340 m_sourceDeobfuscator.getJar(), m_sourceDeobfuscator.getJarIndex(), 331 sourceDeobfuscator.getJar(), sourceDeobfuscator.getJarIndex(),
341 namer.getSourceNamer(), true 332 namer.getSourceNamer(), true
342 ); 333 );
343 ClassIdentifier destIdentifier = new ClassIdentifier( 334 ClassIdentifier destIdentifier = new ClassIdentifier(
344 m_destDeobfuscator.getJar(), m_destDeobfuscator.getJarIndex(), 335 destDeobfuscator.getJar(), destDeobfuscator.getJarIndex(),
345 namer.getDestNamer(), true 336 namer.getDestNamer(), true
346 ); 337 );
347 338
@@ -350,15 +341,16 @@ public class ClassMatchingGui {
350 // rank all the unmatched dest classes against the source class 341 // rank all the unmatched dest classes against the source class
351 ClassIdentity sourceIdentity = sourceIdentifier.identify(obfSourceClass); 342 ClassIdentity sourceIdentity = sourceIdentifier.identify(obfSourceClass);
352 List<ClassEntry> scoredDestClasses = Lists.newArrayList(); 343 List<ClassEntry> scoredDestClasses = Lists.newArrayList();
353 for (ClassEntry unmatchedDestClass : m_classMatches.getUnmatchedDestClasses()) { 344 for (ClassEntry unmatchedDestClass : classMatches.getUnmatchedDestClasses()) {
354 ClassIdentity destIdentity = destIdentifier.identify(unmatchedDestClass); 345 ClassIdentity destIdentity = destIdentifier.identify(unmatchedDestClass);
355 float score = 100.0f * (sourceIdentity.getMatchScore(destIdentity) + destIdentity.getMatchScore(sourceIdentity)) 346 float score = 100.0f * (sourceIdentity.getMatchScore(destIdentity) + destIdentity.getMatchScore(sourceIdentity))
356 / (sourceIdentity.getMaxMatchScore() + destIdentity.getMaxMatchScore()); 347 / (sourceIdentity.getMaxMatchScore() + destIdentity.getMaxMatchScore());
357 scoredDestClasses.add(new ScoredClassEntry(unmatchedDestClass, score)); 348 scoredDestClasses.add(new ScoredClassEntry(unmatchedDestClass, score));
358 } 349 }
359 350
360 if (m_top10Matches.isSelected() && scoredDestClasses.size() > 10) { 351 if (top10Matches.isSelected() && scoredDestClasses.size() > 10) {
361 Collections.sort(scoredDestClasses, (a, b) -> { 352 scoredDestClasses.sort((a, b) ->
353 {
362 ScoredClassEntry sa = (ScoredClassEntry) a; 354 ScoredClassEntry sa = (ScoredClassEntry) a;
363 ScoredClassEntry sb = (ScoredClassEntry) b; 355 ScoredClassEntry sb = (ScoredClassEntry) b;
364 return -Float.compare(sa.getScore(), sb.getScore()); 356 return -Float.compare(sa.getScore(), sb.getScore());
@@ -376,30 +368,30 @@ public class ClassMatchingGui {
376 protected void setDestClass(ClassEntry classEntry) { 368 protected void setDestClass(ClassEntry classEntry) {
377 369
378 // update the current source class 370 // update the current source class
379 m_destClass = classEntry; 371 destClass = classEntry;
380 m_destClassLabel.setText(m_destClass != null ? m_destClass.getName() : ""); 372 destClassLabel.setText(destClass != null ? destClass.getName() : "");
381 373
382 m_destReader.decompileClass(m_destClass, m_destDeobfuscator, () -> m_destReader.navigateToClassDeclaration(m_destClass)); 374 destReader.decompileClass(destClass, destDeobfuscator, () -> destReader.navigateToClassDeclaration(destClass));
383 375
384 updateMatchButton(); 376 updateMatchButton();
385 } 377 }
386 378
387 private void updateMatchButton() { 379 private void updateMatchButton() {
388 380
389 ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass); 381 ClassEntry obfSource = sourceDeobfuscator.obfuscateEntry(sourceClass);
390 ClassEntry obfDest = m_destDeobfuscator.obfuscateEntry(m_destClass); 382 ClassEntry obfDest = destDeobfuscator.obfuscateEntry(destClass);
391 383
392 BiMap<ClassEntry, ClassEntry> uniqueMatches = m_classMatches.getUniqueMatches(); 384 BiMap<ClassEntry, ClassEntry> uniqueMatches = classMatches.getUniqueMatches();
393 boolean twoSelected = m_sourceClass != null && m_destClass != null; 385 boolean twoSelected = sourceClass != null && destClass != null;
394 boolean isMatched = uniqueMatches.containsKey(obfSource) && uniqueMatches.containsValue(obfDest); 386 boolean isMatched = uniqueMatches.containsKey(obfSource) && uniqueMatches.containsValue(obfDest);
395 boolean canMatch = !uniqueMatches.containsKey(obfSource) && !uniqueMatches.containsValue(obfDest); 387 boolean canMatch = !uniqueMatches.containsKey(obfSource) && !uniqueMatches.containsValue(obfDest);
396 388
397 GuiTricks.deactivateButton(m_matchButton); 389 GuiTricks.deactivateButton(matchButton);
398 if (twoSelected) { 390 if (twoSelected) {
399 if (isMatched) { 391 if (isMatched) {
400 GuiTricks.activateButton(m_matchButton, "Unmatch", event -> onUnmatchClick()); 392 GuiTricks.activateButton(matchButton, "Unmatch", event -> onUnmatchClick());
401 } else if (canMatch) { 393 } else if (canMatch) {
402 GuiTricks.activateButton(m_matchButton, "Match", event -> onMatchClick()); 394 GuiTricks.activateButton(matchButton, "Match", event -> onMatchClick());
403 } 395 }
404 } 396 }
405 } 397 }
@@ -407,19 +399,19 @@ public class ClassMatchingGui {
407 private void onMatchClick() { 399 private void onMatchClick() {
408 // precondition: source and dest classes are set correctly 400 // precondition: source and dest classes are set correctly
409 401
410 ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass); 402 ClassEntry obfSource = sourceDeobfuscator.obfuscateEntry(sourceClass);
411 ClassEntry obfDest = m_destDeobfuscator.obfuscateEntry(m_destClass); 403 ClassEntry obfDest = destDeobfuscator.obfuscateEntry(destClass);
412 404
413 // remove the classes from their match 405 // remove the classes from their match
414 m_classMatches.removeSource(obfSource); 406 classMatches.removeSource(obfSource);
415 m_classMatches.removeDest(obfDest); 407 classMatches.removeDest(obfDest);
416 408
417 // add them as matched classes 409 // add them as matched classes
418 m_classMatches.add(new ClassMatch(obfSource, obfDest)); 410 classMatches.add(new ClassMatch(obfSource, obfDest));
419 411
420 ClassEntry nextClass = null; 412 ClassEntry nextClass = null;
421 if (m_advanceCheck.isSelected()) { 413 if (advanceCheck.isSelected()) {
422 nextClass = m_sourceClasses.getNextClass(m_sourceClass); 414 nextClass = sourceClasses.getNextClass(sourceClass);
423 } 415 }
424 416
425 save(); 417 save();
@@ -433,11 +425,11 @@ public class ClassMatchingGui {
433 private void onUnmatchClick() { 425 private void onUnmatchClick() {
434 // precondition: source and dest classes are set to a unique match 426 // precondition: source and dest classes are set to a unique match
435 427
436 ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass); 428 ClassEntry obfSource = sourceDeobfuscator.obfuscateEntry(sourceClass);
437 429
438 // remove the source to break the match, then add the source back as unmatched 430 // remove the source to break the match, then add the source back as unmatched
439 m_classMatches.removeSource(obfSource); 431 classMatches.removeSource(obfSource);
440 m_classMatches.add(new ClassMatch(obfSource, null)); 432 classMatches.add(new ClassMatch(obfSource, null));
441 433
442 save(); 434 save();
443 updateMatches(); 435 updateMatches();
@@ -446,20 +438,20 @@ public class ClassMatchingGui {
446 private void updateMatches() { 438 private void updateMatches() {
447 updateDestMappings(); 439 updateDestMappings();
448 setDestClass(null); 440 setDestClass(null);
449 m_destClasses.setClasses(null); 441 destClasses.setClasses(null);
450 updateMatchButton(); 442 updateMatchButton();
451 443
452 // remember where we were in the source tree 444 // remember where we were in the source tree
453 String packageName = m_sourceClasses.getSelectedPackage(); 445 String packageName = sourceClasses.getSelectedPackage();
454 446
455 setSourceType(m_sourceType); 447 setSourceType(sourceType);
456 448
457 m_sourceClasses.expandPackage(packageName); 449 sourceClasses.expandPackage(packageName);
458 } 450 }
459 451
460 private void save() { 452 private void save() {
461 if (m_saveListener != null) { 453 if (saveListener != null) {
462 m_saveListener.save(m_classMatches); 454 saveListener.save(classMatches);
463 } 455 }
464 } 456 }
465 457
@@ -469,17 +461,17 @@ public class ClassMatchingGui {
469 461
470 // compute a new matching 462 // compute a new matching
471 ClassMatching matching = MappingsConverter.computeMatching( 463 ClassMatching matching = MappingsConverter.computeMatching(
472 m_sourceDeobfuscator.getJar(), m_sourceDeobfuscator.getJarIndex(), 464 sourceDeobfuscator.getJar(), sourceDeobfuscator.getJarIndex(),
473 m_destDeobfuscator.getJar(), m_destDeobfuscator.getJarIndex(), 465 destDeobfuscator.getJar(), destDeobfuscator.getJarIndex(),
474 m_classMatches.getUniqueMatches() 466 classMatches.getUniqueMatches()
475 ); 467 );
476 ClassMatches newMatches = new ClassMatches(matching.matches()); 468 ClassMatches newMatches = new ClassMatches(matching.matches());
477 System.out.println(String.format("Automatch found %d new matches", 469 System.out.println(String.format("Automatch found %d new matches",
478 newMatches.getUniqueMatches().size() - m_classMatches.getUniqueMatches().size() 470 newMatches.getUniqueMatches().size() - classMatches.getUniqueMatches().size()
479 )); 471 ));
480 472
481 // update the current matches 473 // update the current matches
482 m_classMatches = newMatches; 474 classMatches = newMatches;
483 save(); 475 save();
484 updateMatches(); 476 updateMatches();
485 } 477 }
@@ -492,17 +484,17 @@ public class ClassMatchingGui {
492 484
493 // make sure we have a source class 485 // make sure we have a source class
494 if (sourceClass == null) { 486 if (sourceClass == null) {
495 sourceClass = m_sourceClasses.getSelectedClass(); 487 sourceClass = sourceClasses.getSelectedClass();
496 if (sourceClass != null) { 488 if (sourceClass != null) {
497 sourceClass = m_sourceClasses.getNextClass(sourceClass); 489 sourceClass = sourceClasses.getNextClass(sourceClass);
498 } else { 490 } else {
499 sourceClass = m_sourceClasses.getFirstClass(); 491 sourceClass = sourceClasses.getFirstClass();
500 } 492 }
501 } 493 }
502 494
503 // set the source class 495 // set the source class
504 setSourceClass(sourceClass, this::pickBestDestClass); 496 setSourceClass(sourceClass, this::pickBestDestClass);
505 m_sourceClasses.setSelectionClass(sourceClass); 497 sourceClasses.setSelectionClass(sourceClass);
506 } 498 }
507 499
508 private void pickBestDestClass() { 500 private void pickBestDestClass() {
@@ -510,8 +502,8 @@ public class ClassMatchingGui {
510 // then, pick the best dest class 502 // then, pick the best dest class
511 ClassEntry firstClass = null; 503 ClassEntry firstClass = null;
512 ScoredClassEntry bestDestClass = null; 504 ScoredClassEntry bestDestClass = null;
513 for (ClassSelectorPackageNode packageNode : m_destClasses.packageNodes()) { 505 for (ClassSelectorPackageNode packageNode : destClasses.packageNodes()) {
514 for (ClassSelectorClassNode classNode : m_destClasses.classNodes(packageNode)) { 506 for (ClassSelectorClassNode classNode : destClasses.classNodes(packageNode)) {
515 if (firstClass == null) { 507 if (firstClass == null) {
516 firstClass = classNode.getClassEntry(); 508 firstClass = classNode.getClassEntry();
517 } 509 }
@@ -533,14 +525,14 @@ public class ClassMatchingGui {
533 } 525 }
534 526
535 setDestClass(destClass); 527 setDestClass(destClass);
536 m_destClasses.setSelectionClass(destClass); 528 destClasses.setSelectionClass(destClass);
537 } 529 }
538 530
539 private void toggleTop10Matches() { 531 private void toggleTop10Matches() {
540 if (m_sourceClass != null) { 532 if (sourceClass != null) {
541 m_destClasses.clearSelection(); 533 destClasses.clearSelection();
542 m_destClasses.setClasses(deobfuscateClasses(getLikelyMatches(m_sourceClass), m_destDeobfuscator)); 534 destClasses.setClasses(deobfuscateClasses(getLikelyMatches(sourceClass), destDeobfuscator));
543 m_destClasses.expandAll(); 535 destClasses.expandAll();
544 } 536 }
545 } 537 }
546} 538}
diff --git a/src/main/java/cuchaz/enigma/gui/ClassSelector.java b/src/main/java/cuchaz/enigma/gui/ClassSelector.java
index 435509e5..8ece0a0a 100644
--- a/src/main/java/cuchaz/enigma/gui/ClassSelector.java
+++ b/src/main/java/cuchaz/enigma/gui/ClassSelector.java
@@ -29,7 +29,7 @@ import java.util.*;
29 29
30public class ClassSelector extends JTree { 30public class ClassSelector extends JTree {
31 31
32 public static final Comparator<ClassEntry> DEOBF_CLASS_COMPARATOR = (a, b) -> a.getName().compareTo(b.getName()); 32 public static final Comparator<ClassEntry> DEOBF_CLASS_COMPARATOR = Comparator.comparing(ClassEntry::getName);
33 private DefaultMutableTreeNode rootNodes; 33 private DefaultMutableTreeNode rootNodes;
34 34
35 public interface ClassSelectionListener { 35 public interface ClassSelectionListener {
@@ -177,25 +177,32 @@ public class ClassSelector extends JTree {
177 177
178 // sort the packages 178 // sort the packages
179 List<String> sortedPackageNames = Lists.newArrayList(packages.keySet()); 179 List<String> sortedPackageNames = Lists.newArrayList(packages.keySet());
180 Collections.sort(sortedPackageNames, (a, b) -> { 180 sortedPackageNames.sort((a, b) ->
181 {
181 // I can never keep this rule straight when writing these damn things... 182 // I can never keep this rule straight when writing these damn things...
182 // a < b => -1, a == b => 0, a > b => +1 183 // a < b => -1, a == b => 0, a > b => +1
183 184
184 if(b == null || a == null){ 185 if (b == null || a == null)
186 {
185 return 0; 187 return 0;
186 } 188 }
187 189
188 String[] aparts = a.split("/"); 190 String[] aparts = a.split("/");
189 String[] bparts = b.split("/"); 191 String[] bparts = b.split("/");
190 for (int i = 0; true; i++) { 192 for (int i = 0; true; i++)
191 if (i >= aparts.length) { 193 {
194 if (i >= aparts.length)
195 {
192 return -1; 196 return -1;
193 } else if (i >= bparts.length) { 197 }
198 else if (i >= bparts.length)
199 {
194 return 1; 200 return 1;
195 } 201 }
196 202
197 int result = aparts[i].compareTo(bparts[i]); 203 int result = aparts[i].compareTo(bparts[i]);
198 if (result != 0) { 204 if (result != 0)
205 {
199 return result; 206 return result;
200 } 207 }
201 } 208 }
@@ -219,7 +226,7 @@ public class ClassSelector extends JTree {
219 for (String packageName : packagedClassEntries.keySet()) { 226 for (String packageName : packagedClassEntries.keySet()) {
220 // sort the class entries 227 // sort the class entries
221 List<ClassEntry> classEntriesInPackage = Lists.newArrayList(packagedClassEntries.get(packageName)); 228 List<ClassEntry> classEntriesInPackage = Lists.newArrayList(packagedClassEntries.get(packageName));
222 Collections.sort(classEntriesInPackage, this.comparator); 229 classEntriesInPackage.sort(this.comparator);
223 230
224 // create the nodes in order 231 // create the nodes in order
225 for (ClassEntry classEntry : classEntriesInPackage) { 232 for (ClassEntry classEntry : classEntriesInPackage) {
@@ -274,7 +281,7 @@ public class ClassSelector extends JTree {
274 281
275 public String getExpansionState(JTree tree, int row) { 282 public String getExpansionState(JTree tree, int row) {
276 TreePath rowPath = tree.getPathForRow(row); 283 TreePath rowPath = tree.getPathForRow(row);
277 StringBuffer buf = new StringBuffer(); 284 StringBuilder buf = new StringBuilder();
278 int rowCount = tree.getRowCount(); 285 int rowCount = tree.getRowCount();
279 for (int i = row; i < rowCount; i++) { 286 for (int i = row; i < rowCount; i++) {
280 TreePath path = tree.getPathForRow(i); 287 TreePath path = tree.getPathForRow(i);
@@ -500,7 +507,7 @@ public class ClassSelector extends JTree {
500 { 507 {
501 List<ClassSelectorClassNode> classNodes = classNodes(newPackageNode); 508 List<ClassSelectorClassNode> classNodes = classNodes(newPackageNode);
502 classNodes.add(classNode); 509 classNodes.add(classNode);
503 Collections.sort(classNodes, (a, b) -> a.toString().compareTo(b.toString())); 510 classNodes.sort(Comparator.comparing(ClassSelectorClassNode::toString));
504 for (int i = 0; i < classNodes.size(); i++) 511 for (int i = 0; i < classNodes.size(); i++)
505 if (classNodes.get(i) == classNode) 512 if (classNodes.get(i) == classNode)
506 return i; 513 return i;
@@ -514,7 +521,7 @@ public class ClassSelector extends JTree {
514 if (!packageNodes.contains(newPackageNode)) 521 if (!packageNodes.contains(newPackageNode))
515 { 522 {
516 packageNodes.add(newPackageNode); 523 packageNodes.add(newPackageNode);
517 Collections.sort(packageNodes, (a, b) -> a.toString().compareTo(b.toString())); 524 packageNodes.sort(Comparator.comparing(ClassSelectorPackageNode::toString));
518 } 525 }
519 526
520 for (int i = 0; i < packageNodes.size(); i++) 527 for (int i = 0; i < packageNodes.size(); i++)
diff --git a/src/main/java/cuchaz/enigma/gui/CodeReader.java b/src/main/java/cuchaz/enigma/gui/CodeReader.java
index 601e5b95..8225d8f4 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
@@ -38,15 +36,15 @@ public class CodeReader extends JEditorPane {
38 36
39 private static final long serialVersionUID = 3673180950485748810L; 37 private static final long serialVersionUID = 3673180950485748810L;
40 38
41 private static final Object m_lock = new Object(); 39 private static final Object lock = new Object();
42 40
43 public interface SelectionListener { 41 public interface SelectionListener {
44 void onSelect(EntryReference<Entry, Entry> reference); 42 void onSelect(EntryReference<Entry, Entry> reference);
45 } 43 }
46 44
47 private SelectionHighlightPainter m_selectionHighlightPainter; 45 private SelectionHighlightPainter selectionHighlightPainter;
48 private SourceIndex m_sourceIndex; 46 private SourceIndex sourceIndex;
49 private SelectionListener m_selectionListener; 47 private SelectionListener selectionListener;
50 48
51 public CodeReader() { 49 public CodeReader() {
52 50
@@ -58,38 +56,34 @@ public class CodeReader extends JEditorPane {
58 kit.toggleComponent(this, "de.sciss.syntaxpane.components.TokenMarker"); 56 kit.toggleComponent(this, "de.sciss.syntaxpane.components.TokenMarker");
59 57
60 // hook events 58 // hook events
61 addCaretListener(new CaretListener() { 59 addCaretListener(event ->
62 @Override 60 {
63 public void caretUpdate(CaretEvent event) { 61 if (selectionListener != null && sourceIndex != null) {
64 if (m_selectionListener != null && m_sourceIndex != null) { 62 Token token = sourceIndex.getReferenceToken(event.getDot());
65 Token token = m_sourceIndex.getReferenceToken(event.getDot()); 63 if (token != null) {
66 if (token != null) { 64 selectionListener.onSelect(sourceIndex.getDeobfReference(token));
67 m_selectionListener.onSelect(m_sourceIndex.getDeobfReference(token)); 65 } else {
68 } else { 66 selectionListener.onSelect(null);
69 m_selectionListener.onSelect(null);
70 }
71 } 67 }
72 } 68 }
73 }); 69 });
74 70
75 m_selectionHighlightPainter = new SelectionHighlightPainter(); 71 selectionHighlightPainter = new SelectionHighlightPainter();
76 m_sourceIndex = null;
77 m_selectionListener = null;
78 } 72 }
79 73
80 public void setSelectionListener(SelectionListener val) { 74 public void setSelectionListener(SelectionListener val) {
81 m_selectionListener = val; 75 selectionListener = val;
82 } 76 }
83 77
84 public void setCode(String code) { 78 public void setCode(String code) {
85 // 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
86 synchronized (m_lock) { 80 synchronized (lock) {
87 setText(code); 81 setText(code);
88 } 82 }
89 } 83 }
90 84
91 public SourceIndex getSourceIndex() { 85 public SourceIndex getSourceIndex() {
92 return m_sourceIndex; 86 return sourceIndex;
93 } 87 }
94 88
95 public void decompileClass(ClassEntry classEntry, Deobfuscator deobfuscator) { 89 public void decompileClass(ClassEntry classEntry, Deobfuscator deobfuscator) {
@@ -110,33 +104,31 @@ public class CodeReader extends JEditorPane {
110 setCode("(decompiling...)"); 104 setCode("(decompiling...)");
111 105
112 // run decompilation in a separate thread to keep ui responsive 106 // run decompilation in a separate thread to keep ui responsive
113 new Thread() { 107 new Thread(() ->
114 @Override 108 {
115 public void run() {
116 109
117 // decompile it 110 // decompile it
118 CompilationUnit sourceTree = deobfuscator.getSourceTree(classEntry.getOutermostClassName()); 111 CompilationUnit sourceTree = deobfuscator.getSourceTree(classEntry.getOutermostClassName());
119 String source = deobfuscator.getSource(sourceTree); 112 String source = deobfuscator.getSource(sourceTree);
120 setCode(source); 113 setCode(source);
121 m_sourceIndex = deobfuscator.getSourceIndex(sourceTree, source, ignoreBadTokens); 114 sourceIndex = deobfuscator.getSourceIndex(sourceTree, source, ignoreBadTokens);
122 115
123 if (callback != null) { 116 if (callback != null) {
124 callback.run(); 117 callback.run();
125 }
126 } 118 }
127 }.start(); 119 }).start();
128 } 120 }
129 121
130 public void navigateToClassDeclaration(ClassEntry classEntry) { 122 public void navigateToClassDeclaration(ClassEntry classEntry) {
131 123
132 // navigate to the class declaration 124 // navigate to the class declaration
133 Token token = m_sourceIndex.getDeclarationToken(classEntry); 125 Token token = sourceIndex.getDeclarationToken(classEntry);
134 if (token == null) { 126 if (token == null) {
135 // couldn't find the class declaration token, might be an anonymous class 127 // couldn't find the class declaration token, might be an anonymous class
136 // look for any declaration in that class instead 128 // look for any declaration in that class instead
137 for (Entry entry : m_sourceIndex.declarations()) { 129 for (Entry entry : sourceIndex.declarations()) {
138 if (entry.getClassEntry().equals(classEntry)) { 130 if (entry.getClassEntry().equals(classEntry)) {
139 token = m_sourceIndex.getDeclarationToken(entry); 131 token = sourceIndex.getDeclarationToken(entry);
140 break; 132 break;
141 } 133 }
142 } 134 }
@@ -151,7 +143,7 @@ public class CodeReader extends JEditorPane {
151 } 143 }
152 144
153 public void navigateToToken(final Token token) { 145 public void navigateToToken(final Token token) {
154 navigateToToken(this, token, m_selectionHighlightPainter); 146 navigateToToken(this, token, selectionHighlightPainter);
155 } 147 }
156 148
157 // HACKHACK: someday we can update the main GUI to use this code reader 149 // HACKHACK: someday we can update the main GUI to use this code reader
@@ -167,34 +159,29 @@ public class CodeReader extends JEditorPane {
167 Rectangle end = editor.modelToView(token.end); 159 Rectangle end = editor.modelToView(token.end);
168 final Rectangle show = start.union(end); 160 final Rectangle show = start.union(end);
169 show.grow(start.width * 10, start.height * 6); 161 show.grow(start.width * 10, start.height * 6);
170 SwingUtilities.invokeLater(new Runnable() { 162 SwingUtilities.invokeLater(() -> editor.scrollRectToVisible(show));
171 @Override
172 public void run() {
173 editor.scrollRectToVisible(show);
174 }
175 });
176 } catch (BadLocationException ex) { 163 } catch (BadLocationException ex) {
177 throw new Error(ex); 164 throw new Error(ex);
178 } 165 }
179 166
180 // highlight the token momentarily 167 // highlight the token momentarily
181 final Timer timer = new Timer(200, new ActionListener() { 168 final Timer timer = new Timer(200, new ActionListener() {
182 private int m_counter = 0; 169 private int counter = 0;
183 private Object m_highlight = null; 170 private Object highlight = null;
184 171
185 @Override 172 @Override
186 public void actionPerformed(ActionEvent event) { 173 public void actionPerformed(ActionEvent event) {
187 if (m_counter % 2 == 0) { 174 if (counter % 2 == 0) {
188 try { 175 try {
189 m_highlight = editor.getHighlighter().addHighlight(token.start, token.end, highlightPainter); 176 highlight = editor.getHighlighter().addHighlight(token.start, token.end, highlightPainter);
190 } catch (BadLocationException ex) { 177 } catch (BadLocationException ex) {
191 // don't care 178 // don't care
192 } 179 }
193 } else if (m_highlight != null) { 180 } else if (highlight != null) {
194 editor.getHighlighter().removeHighlight(m_highlight); 181 editor.getHighlighter().removeHighlight(highlight);
195 } 182 }
196 183
197 if (m_counter++ > 6) { 184 if (counter++ > 6) {
198 Timer timer = (Timer) event.getSource(); 185 Timer timer = (Timer) event.getSource();
199 timer.stop(); 186 timer.stop();
200 } 187 }
diff --git a/src/main/java/cuchaz/enigma/gui/Gui.java b/src/main/java/cuchaz/enigma/gui/Gui.java
index ed18777a..7cb494fa 100644
--- a/src/main/java/cuchaz/enigma/gui/Gui.java
+++ b/src/main/java/cuchaz/enigma/gui/Gui.java
@@ -62,23 +62,23 @@ public class Gui {
62 private final MenuBar menuBar; 62 private final MenuBar menuBar;
63 public final PopupMenuBar popupMenu; 63 public final PopupMenuBar popupMenu;
64 64
65 private JFrame frame; 65 private JFrame frame;
66 private PanelEditor editor; 66 private PanelEditor editor;
67 private JPanel classesPanel; 67 private JPanel classesPanel;
68 private JSplitPane m_splitClasses; 68 private JSplitPane splitClasses;
69 private PanelIdentifier m_infoPanel; 69 private PanelIdentifier infoPanel;
70 private ObfuscatedHighlightPainter m_obfuscatedHighlightPainter; 70 private ObfuscatedHighlightPainter obfuscatedHighlightPainter;
71 private DeobfuscatedHighlightPainter m_deobfuscatedHighlightPainter; 71 private DeobfuscatedHighlightPainter deobfuscatedHighlightPainter;
72 private OtherHighlightPainter m_otherHighlightPainter; 72 private OtherHighlightPainter otherHighlightPainter;
73 private SelectionHighlightPainter m_selectionHighlightPainter; 73 private SelectionHighlightPainter selectionHighlightPainter;
74 private JTree m_inheritanceTree; 74 private JTree inheritanceTree;
75 private JTree m_implementationsTree; 75 private JTree implementationsTree;
76 private JTree m_callsTree; 76 private JTree callsTree;
77 private JList<Token> m_tokens; 77 private JList<Token> tokens;
78 private JTabbedPane m_tabs; 78 private JTabbedPane tabs;
79 79
80 // state 80 // state
81 public EntryReference<Entry, Entry> m_reference; 81 public EntryReference<Entry, Entry> reference;
82 82
83 public JFileChooser jarFileChooser; 83 public JFileChooser jarFileChooser;
84 public JFileChooser enigmaMappingsFileChooser; 84 public JFileChooser enigmaMappingsFileChooser;
@@ -118,22 +118,22 @@ public class Gui {
118 this.deobfPanel = new PanelDeobf(this); 118 this.deobfPanel = new PanelDeobf(this);
119 119
120 // set up classes panel (don't add the splitter yet) 120 // set up classes panel (don't add the splitter yet)
121 m_splitClasses = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, this.obfPanel, this.deobfPanel); 121 splitClasses = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, this.obfPanel, this.deobfPanel);
122 m_splitClasses.setResizeWeight(0.3); 122 splitClasses.setResizeWeight(0.3);
123 this.classesPanel = new JPanel(); 123 this.classesPanel = new JPanel();
124 this.classesPanel.setLayout(new BorderLayout()); 124 this.classesPanel.setLayout(new BorderLayout());
125 this.classesPanel.setPreferredSize(new Dimension(250, 0)); 125 this.classesPanel.setPreferredSize(new Dimension(250, 0));
126 126
127 // init info panel 127 // init info panel
128 m_infoPanel = new PanelIdentifier(this); 128 infoPanel = new PanelIdentifier(this);
129 m_infoPanel.clearReference(); 129 infoPanel.clearReference();
130 130
131 // init editor 131 // init editor
132 DefaultSyntaxKit.initKit(); 132 DefaultSyntaxKit.initKit();
133 m_obfuscatedHighlightPainter = new ObfuscatedHighlightPainter(); 133 obfuscatedHighlightPainter = new ObfuscatedHighlightPainter();
134 m_deobfuscatedHighlightPainter = new DeobfuscatedHighlightPainter(); 134 deobfuscatedHighlightPainter = new DeobfuscatedHighlightPainter();
135 m_otherHighlightPainter = new OtherHighlightPainter(); 135 otherHighlightPainter = new OtherHighlightPainter();
136 m_selectionHighlightPainter = new SelectionHighlightPainter(); 136 selectionHighlightPainter = new SelectionHighlightPainter();
137 this.editor = new PanelEditor(this); 137 this.editor = new PanelEditor(this);
138 JScrollPane sourceScroller = new JScrollPane(this.editor); 138 JScrollPane sourceScroller = new JScrollPane(this.editor);
139 this.editor.setContentType("text/java"); 139 this.editor.setContentType("text/java");
@@ -145,14 +145,14 @@ public class Gui {
145 this.editor.setComponentPopupMenu(this.popupMenu); 145 this.editor.setComponentPopupMenu(this.popupMenu);
146 146
147 // init inheritance panel 147 // init inheritance panel
148 m_inheritanceTree = new JTree(); 148 inheritanceTree = new JTree();
149 m_inheritanceTree.setModel(null); 149 inheritanceTree.setModel(null);
150 m_inheritanceTree.addMouseListener(new MouseAdapter() { 150 inheritanceTree.addMouseListener(new MouseAdapter() {
151 @Override 151 @Override
152 public void mouseClicked(MouseEvent event) { 152 public void mouseClicked(MouseEvent event) {
153 if (event.getClickCount() == 2) { 153 if (event.getClickCount() == 2) {
154 // get the selected node 154 // get the selected node
155 TreePath path = m_inheritanceTree.getSelectionPath(); 155 TreePath path = inheritanceTree.getSelectionPath();
156 if (path == null) { 156 if (path == null) {
157 return; 157 return;
158 } 158 }
@@ -172,17 +172,17 @@ public class Gui {
172 }); 172 });
173 JPanel inheritancePanel = new JPanel(); 173 JPanel inheritancePanel = new JPanel();
174 inheritancePanel.setLayout(new BorderLayout()); 174 inheritancePanel.setLayout(new BorderLayout());
175 inheritancePanel.add(new JScrollPane(m_inheritanceTree)); 175 inheritancePanel.add(new JScrollPane(inheritanceTree));
176 176
177 // init implementations panel 177 // init implementations panel
178 m_implementationsTree = new JTree(); 178 implementationsTree = new JTree();
179 m_implementationsTree.setModel(null); 179 implementationsTree.setModel(null);
180 m_implementationsTree.addMouseListener(new MouseAdapter() { 180 implementationsTree.addMouseListener(new MouseAdapter() {
181 @Override 181 @Override
182 public void mouseClicked(MouseEvent event) { 182 public void mouseClicked(MouseEvent event) {
183 if (event.getClickCount() == 2) { 183 if (event.getClickCount() == 2) {
184 // get the selected node 184 // get the selected node
185 TreePath path = m_implementationsTree.getSelectionPath(); 185 TreePath path = implementationsTree.getSelectionPath();
186 if (path == null) { 186 if (path == null) {
187 return; 187 return;
188 } 188 }
@@ -200,18 +200,18 @@ public class Gui {
200 }); 200 });
201 JPanel implementationsPanel = new JPanel(); 201 JPanel implementationsPanel = new JPanel();
202 implementationsPanel.setLayout(new BorderLayout()); 202 implementationsPanel.setLayout(new BorderLayout());
203 implementationsPanel.add(new JScrollPane(m_implementationsTree)); 203 implementationsPanel.add(new JScrollPane(implementationsTree));
204 204
205 // init call panel 205 // init call panel
206 m_callsTree = new JTree(); 206 callsTree = new JTree();
207 m_callsTree.setModel(null); 207 callsTree.setModel(null);
208 m_callsTree.addMouseListener(new MouseAdapter() { 208 callsTree.addMouseListener(new MouseAdapter() {
209 @SuppressWarnings("unchecked") 209 @SuppressWarnings("unchecked")
210 @Override 210 @Override
211 public void mouseClicked(MouseEvent event) { 211 public void mouseClicked(MouseEvent event) {
212 if (event.getClickCount() == 2) { 212 if (event.getClickCount() == 2) {
213 // get the selected node 213 // get the selected node
214 TreePath path = m_callsTree.getSelectionPath(); 214 TreePath path = callsTree.getSelectionPath();
215 if (path == null) { 215 if (path == null) {
216 return; 216 return;
217 } 217 }
@@ -228,28 +228,28 @@ public class Gui {
228 } 228 }
229 } 229 }
230 }); 230 });
231 m_tokens = new JList<>(); 231 tokens = new JList<>();
232 m_tokens.setCellRenderer(new TokenListCellRenderer(this.controller)); 232 tokens.setCellRenderer(new TokenListCellRenderer(this.controller));
233 m_tokens.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 233 tokens.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
234 m_tokens.setLayoutOrientation(JList.VERTICAL); 234 tokens.setLayoutOrientation(JList.VERTICAL);
235 m_tokens.addMouseListener(new MouseAdapter() { 235 tokens.addMouseListener(new MouseAdapter() {
236 @Override 236 @Override
237 public void mouseClicked(MouseEvent event) { 237 public void mouseClicked(MouseEvent event) {
238 if (event.getClickCount() == 2) { 238 if (event.getClickCount() == 2) {
239 Token selected = m_tokens.getSelectedValue(); 239 Token selected = tokens.getSelectedValue();
240 if (selected != null) { 240 if (selected != null) {
241 showToken(selected); 241 showToken(selected);
242 } 242 }
243 } 243 }
244 } 244 }
245 }); 245 });
246 m_tokens.setPreferredSize(new Dimension(0, 200)); 246 tokens.setPreferredSize(new Dimension(0, 200));
247 m_tokens.setMinimumSize(new Dimension(0, 200)); 247 tokens.setMinimumSize(new Dimension(0, 200));
248 JSplitPane callPanel = new JSplitPane( 248 JSplitPane callPanel = new JSplitPane(
249 JSplitPane.VERTICAL_SPLIT, 249 JSplitPane.VERTICAL_SPLIT,
250 true, 250 true,
251 new JScrollPane(m_callsTree), 251 new JScrollPane(callsTree),
252 new JScrollPane(m_tokens) 252 new JScrollPane(tokens)
253 ); 253 );
254 callPanel.setResizeWeight(1); // let the top side take all the slack 254 callPanel.setResizeWeight(1); // let the top side take all the slack
255 callPanel.resetToPreferredSizes(); 255 callPanel.resetToPreferredSizes();
@@ -257,14 +257,14 @@ public class Gui {
257 // layout controls 257 // layout controls
258 JPanel centerPanel = new JPanel(); 258 JPanel centerPanel = new JPanel();
259 centerPanel.setLayout(new BorderLayout()); 259 centerPanel.setLayout(new BorderLayout());
260 centerPanel.add(m_infoPanel, BorderLayout.NORTH); 260 centerPanel.add(infoPanel, BorderLayout.NORTH);
261 centerPanel.add(sourceScroller, BorderLayout.CENTER); 261 centerPanel.add(sourceScroller, BorderLayout.CENTER);
262 m_tabs = new JTabbedPane(); 262 tabs = new JTabbedPane();
263 m_tabs.setPreferredSize(new Dimension(250, 0)); 263 tabs.setPreferredSize(new Dimension(250, 0));
264 m_tabs.addTab("Inheritance", inheritancePanel); 264 tabs.addTab("Inheritance", inheritancePanel);
265 m_tabs.addTab("Implementations", implementationsPanel); 265 tabs.addTab("Implementations", implementationsPanel);
266 m_tabs.addTab("Call Graph", callPanel); 266 tabs.addTab("Call Graph", callPanel);
267 JSplitPane splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, centerPanel, m_tabs); 267 JSplitPane splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, centerPanel, tabs);
268 splitRight.setResizeWeight(1); // let the left side take all the slack 268 splitRight.setResizeWeight(1); // let the left side take all the slack
269 splitRight.resetToPreferredSizes(); 269 splitRight.resetToPreferredSizes();
270 JSplitPane splitCenter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, this.classesPanel, splitRight); 270 JSplitPane splitCenter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, this.classesPanel, splitRight);
@@ -314,7 +314,7 @@ public class Gui {
314 // update gui 314 // update gui
315 this.frame.setTitle(Constants.NAME + " - " + jarName); 315 this.frame.setTitle(Constants.NAME + " - " + jarName);
316 this.classesPanel.removeAll(); 316 this.classesPanel.removeAll();
317 this.classesPanel.add(m_splitClasses); 317 this.classesPanel.add(splitClasses);
318 setSource(null); 318 setSource(null);
319 319
320 // update menu 320 // update menu
@@ -375,7 +375,7 @@ public class Gui {
375 if (token == null) { 375 if (token == null) {
376 throw new IllegalArgumentException("Token cannot be null!"); 376 throw new IllegalArgumentException("Token cannot be null!");
377 } 377 }
378 CodeReader.navigateToToken(this.editor, token, m_selectionHighlightPainter); 378 CodeReader.navigateToToken(this.editor, token, selectionHighlightPainter);
379 redraw(); 379 redraw();
380 } 380 }
381 381
@@ -384,10 +384,10 @@ public class Gui {
384 Collections.sort(sortedTokens); 384 Collections.sort(sortedTokens);
385 if (sortedTokens.size() > 1) { 385 if (sortedTokens.size() > 1) {
386 // sort the tokens and update the tokens panel 386 // sort the tokens and update the tokens panel
387 m_tokens.setListData(sortedTokens); 387 this.tokens.setListData(sortedTokens);
388 m_tokens.setSelectedIndex(0); 388 this.tokens.setSelectedIndex(0);
389 } else { 389 } else {
390 m_tokens.setListData(new Vector<>()); 390 this.tokens.setListData(new Vector<>());
391 } 391 }
392 392
393 // show the first token 393 // show the first token
@@ -401,13 +401,13 @@ public class Gui {
401 401
402 // color things based on the index 402 // color things based on the index
403 if (obfuscatedTokens != null) { 403 if (obfuscatedTokens != null) {
404 setHighlightedTokens(obfuscatedTokens, m_obfuscatedHighlightPainter); 404 setHighlightedTokens(obfuscatedTokens, obfuscatedHighlightPainter);
405 } 405 }
406 if (deobfuscatedTokens != null) { 406 if (deobfuscatedTokens != null) {
407 setHighlightedTokens(deobfuscatedTokens, m_deobfuscatedHighlightPainter); 407 setHighlightedTokens(deobfuscatedTokens, deobfuscatedHighlightPainter);
408 } 408 }
409 if (otherTokens != null) { 409 if (otherTokens != null) {
410 setHighlightedTokens(otherTokens, m_otherHighlightPainter); 410 setHighlightedTokens(otherTokens, otherHighlightPainter);
411 } 411 }
412 412
413 redraw(); 413 redraw();
@@ -425,73 +425,73 @@ public class Gui {
425 425
426 private void showReference(EntryReference<Entry, Entry> reference) { 426 private void showReference(EntryReference<Entry, Entry> reference) {
427 if (reference == null) { 427 if (reference == null) {
428 m_infoPanel.clearReference(); 428 infoPanel.clearReference();
429 return; 429 return;
430 } 430 }
431 431
432 m_reference = reference; 432 this.reference = reference;
433 433
434 m_infoPanel.removeAll(); 434 infoPanel.removeAll();
435 if (reference.entry instanceof ClassEntry) { 435 if (reference.entry instanceof ClassEntry) {
436 showClassEntry((ClassEntry) m_reference.entry); 436 showClassEntry((ClassEntry) this.reference.entry);
437 } else if (m_reference.entry instanceof FieldEntry) { 437 } else if (this.reference.entry instanceof FieldEntry) {
438 showFieldEntry((FieldEntry) m_reference.entry); 438 showFieldEntry((FieldEntry) this.reference.entry);
439 } else if (m_reference.entry instanceof MethodEntry) { 439 } else if (this.reference.entry instanceof MethodEntry) {
440 showMethodEntry((MethodEntry) m_reference.entry); 440 showMethodEntry((MethodEntry) this.reference.entry);
441 } else if (m_reference.entry instanceof ConstructorEntry) { 441 } else if (this.reference.entry instanceof ConstructorEntry) {
442 showConstructorEntry((ConstructorEntry) m_reference.entry); 442 showConstructorEntry((ConstructorEntry) this.reference.entry);
443 } else if (m_reference.entry instanceof ArgumentEntry) { 443 } else if (this.reference.entry instanceof ArgumentEntry) {
444 showArgumentEntry((ArgumentEntry) m_reference.entry); 444 showArgumentEntry((ArgumentEntry) this.reference.entry);
445 } else if (m_reference.entry instanceof LocalVariableEntry) { 445 } else if (this.reference.entry instanceof LocalVariableEntry) {
446 showLocalVariableEntry((LocalVariableEntry) m_reference.entry); 446 showLocalVariableEntry((LocalVariableEntry) this.reference.entry);
447 } else { 447 } else {
448 throw new Error("Unknown entry type: " + m_reference.entry.getClass().getName()); 448 throw new Error("Unknown entry type: " + this.reference.entry.getClass().getName());
449 } 449 }
450 450
451 redraw(); 451 redraw();
452 } 452 }
453 453
454 private void showLocalVariableEntry(LocalVariableEntry entry) { 454 private void showLocalVariableEntry(LocalVariableEntry entry) {
455 addNameValue(m_infoPanel, "Variable", entry.getName()); 455 addNameValue(infoPanel, "Variable", entry.getName());
456 addNameValue(m_infoPanel, "Class", entry.getClassEntry().getName()); 456 addNameValue(infoPanel, "Class", entry.getClassEntry().getName());
457 addNameValue(m_infoPanel, "Method", entry.getBehaviorEntry().getName()); 457 addNameValue(infoPanel, "Method", entry.getBehaviorEntry().getName());
458 addNameValue(m_infoPanel, "Index", Integer.toString(entry.getIndex())); 458 addNameValue(infoPanel, "Index", Integer.toString(entry.getIndex()));
459 addNameValue(m_infoPanel, "Type", entry.getType().toString()); 459 addNameValue(infoPanel, "Type", entry.getType().toString());
460 } 460 }
461 461
462 private void showClassEntry(ClassEntry entry) { 462 private void showClassEntry(ClassEntry entry) {
463 addNameValue(m_infoPanel, "Class", entry.getName()); 463 addNameValue(infoPanel, "Class", entry.getName());
464 addModifierComboBox(m_infoPanel, "Modifier", entry); 464 addModifierComboBox(infoPanel, "Modifier", entry);
465 } 465 }
466 466
467 private void showFieldEntry(FieldEntry entry) { 467 private void showFieldEntry(FieldEntry entry) {
468 addNameValue(m_infoPanel, "Field", entry.getName()); 468 addNameValue(infoPanel, "Field", entry.getName());
469 addNameValue(m_infoPanel, "Class", entry.getClassEntry().getName()); 469 addNameValue(infoPanel, "Class", entry.getClassEntry().getName());
470 addNameValue(m_infoPanel, "Type", entry.getType().toString()); 470 addNameValue(infoPanel, "Type", entry.getType().toString());
471 addModifierComboBox(m_infoPanel, "Modifier", entry); 471 addModifierComboBox(infoPanel, "Modifier", entry);
472 } 472 }
473 473
474 private void showMethodEntry(MethodEntry entry) { 474 private void showMethodEntry(MethodEntry entry) {
475 addNameValue(m_infoPanel, "Method", entry.getName()); 475 addNameValue(infoPanel, "Method", entry.getName());
476 addNameValue(m_infoPanel, "Class", entry.getClassEntry().getName()); 476 addNameValue(infoPanel, "Class", entry.getClassEntry().getName());
477 addNameValue(m_infoPanel, "Signature", entry.getSignature().toString()); 477 addNameValue(infoPanel, "Signature", entry.getSignature().toString());
478 addModifierComboBox(m_infoPanel, "Modifier", entry); 478 addModifierComboBox(infoPanel, "Modifier", entry);
479 479
480 } 480 }
481 481
482 private void showConstructorEntry(ConstructorEntry entry) { 482 private void showConstructorEntry(ConstructorEntry entry) {
483 addNameValue(m_infoPanel, "Constructor", entry.getClassEntry().getName()); 483 addNameValue(infoPanel, "Constructor", entry.getClassEntry().getName());
484 if (!entry.isStatic()) { 484 if (!entry.isStatic()) {
485 addNameValue(m_infoPanel, "Signature", entry.getSignature().toString()); 485 addNameValue(infoPanel, "Signature", entry.getSignature().toString());
486 addModifierComboBox(m_infoPanel, "Modifier", entry); 486 addModifierComboBox(infoPanel, "Modifier", entry);
487 } 487 }
488 } 488 }
489 489
490 private void showArgumentEntry(ArgumentEntry entry) { 490 private void showArgumentEntry(ArgumentEntry entry) {
491 addNameValue(m_infoPanel, "Argument", entry.getName()); 491 addNameValue(infoPanel, "Argument", entry.getName());
492 addNameValue(m_infoPanel, "Class", entry.getClassEntry().getName()); 492 addNameValue(infoPanel, "Class", entry.getClassEntry().getName());
493 addNameValue(m_infoPanel, "Method", entry.getBehaviorEntry().getName()); 493 addNameValue(infoPanel, "Method", entry.getBehaviorEntry().getName());
494 addNameValue(m_infoPanel, "Index", Integer.toString(entry.getIndex())); 494 addNameValue(infoPanel, "Index", Integer.toString(entry.getIndex()));
495 } 495 }
496 496
497 private void addNameValue(JPanel container, String name, String value) { 497 private void addNameValue(JPanel container, String name, String value) {
@@ -530,18 +530,18 @@ public class Gui {
530 Token token = this.controller.getToken(pos); 530 Token token = this.controller.getToken(pos);
531 boolean isToken = token != null; 531 boolean isToken = token != null;
532 532
533 m_reference = this.controller.getDeobfReference(token); 533 reference = this.controller.getDeobfReference(token);
534 boolean isClassEntry = isToken && m_reference.entry instanceof ClassEntry; 534 boolean isClassEntry = isToken && reference.entry instanceof ClassEntry;
535 boolean isFieldEntry = isToken && m_reference.entry instanceof FieldEntry; 535 boolean isFieldEntry = isToken && reference.entry instanceof FieldEntry;
536 boolean isMethodEntry = isToken && m_reference.entry instanceof MethodEntry; 536 boolean isMethodEntry = isToken && reference.entry instanceof MethodEntry;
537 boolean isConstructorEntry = isToken && m_reference.entry instanceof ConstructorEntry; 537 boolean isConstructorEntry = isToken && reference.entry instanceof ConstructorEntry;
538 boolean isInJar = isToken && this.controller.entryIsInJar(m_reference.entry); 538 boolean isInJar = isToken && this.controller.entryIsInJar(reference.entry);
539 boolean isRenameable = isToken && this.controller.referenceIsRenameable(m_reference); 539 boolean isRenameable = isToken && this.controller.referenceIsRenameable(reference);
540 540
541 if (isToken) { 541 if (isToken) {
542 showReference(m_reference); 542 showReference(reference);
543 } else { 543 } else {
544 m_infoPanel.clearReference(); 544 infoPanel.clearReference();
545 } 545 }
546 546
547 this.popupMenu.renameMenu.setEnabled(isRenameable); 547 this.popupMenu.renameMenu.setEnabled(isRenameable);
@@ -552,7 +552,7 @@ public class Gui {
552 this.popupMenu.openPreviousMenu.setEnabled(this.controller.hasPreviousLocation()); 552 this.popupMenu.openPreviousMenu.setEnabled(this.controller.hasPreviousLocation());
553 this.popupMenu.toggleMappingMenu.setEnabled(isRenameable); 553 this.popupMenu.toggleMappingMenu.setEnabled(isRenameable);
554 554
555 if (isToken && this.controller.entryHasDeobfuscatedName(m_reference.entry)) { 555 if (isToken && this.controller.entryHasDeobfuscatedName(reference.entry)) {
556 this.popupMenu.toggleMappingMenu.setText("Reset to obfuscated"); 556 this.popupMenu.toggleMappingMenu.setText("Reset to obfuscated");
557 } else { 557 } else {
558 this.popupMenu.toggleMappingMenu.setText("Mark as deobfuscated"); 558 this.popupMenu.toggleMappingMenu.setText("Mark as deobfuscated");
@@ -564,8 +564,8 @@ public class Gui {
564 // entry is not in the jar. Ignore it 564 // entry is not in the jar. Ignore it
565 return; 565 return;
566 } 566 }
567 if (m_reference != null) { 567 if (reference != null) {
568 this.controller.savePreviousReference(m_reference); 568 this.controller.savePreviousReference(reference);
569 } 569 }
570 this.controller.openDeclaration(entry); 570 this.controller.openDeclaration(entry);
571 } 571 }
@@ -574,8 +574,8 @@ public class Gui {
574 if (!this.controller.entryIsInJar(reference.getLocationClassEntry())) { 574 if (!this.controller.entryIsInJar(reference.getLocationClassEntry())) {
575 return; 575 return;
576 } 576 }
577 if (m_reference != null) { 577 if (this.reference != null) {
578 this.controller.savePreviousReference(m_reference); 578 this.controller.savePreviousReference(this.reference);
579 } 579 }
580 this.controller.openReference(reference); 580 this.controller.openReference(reference);
581 } 581 }
@@ -584,7 +584,7 @@ public class Gui {
584 584
585 // init the text box 585 // init the text box
586 final JTextField text = new JTextField(); 586 final JTextField text = new JTextField();
587 text.setText(m_reference.getNamableName()); 587 text.setText(reference.getNamableName());
588 text.setPreferredSize(new Dimension(360, text.getPreferredSize().height)); 588 text.setPreferredSize(new Dimension(360, text.getPreferredSize().height));
589 text.addKeyListener(new KeyAdapter() { 589 text.addKeyListener(new KeyAdapter() {
590 @Override 590 @Override
@@ -604,14 +604,14 @@ public class Gui {
604 }); 604 });
605 605
606 // find the label with the name and replace it with the text box 606 // find the label with the name and replace it with the text box
607 JPanel panel = (JPanel) m_infoPanel.getComponent(0); 607 JPanel panel = (JPanel) infoPanel.getComponent(0);
608 panel.remove(panel.getComponentCount() - 1); 608 panel.remove(panel.getComponentCount() - 1);
609 panel.add(text); 609 panel.add(text);
610 text.grabFocus(); 610 text.grabFocus();
611 611
612 int offset = text.getText().lastIndexOf('/') + 1; 612 int offset = text.getText().lastIndexOf('/') + 1;
613 // If it's a class and isn't in the default package, assume that it's deobfuscated. 613 // If it's a class and isn't in the default package, assume that it's deobfuscated.
614 if (m_reference.getNameableEntry() instanceof ClassEntry && text.getText().contains("/") && offset != 0) 614 if (reference.getNameableEntry() instanceof ClassEntry && text.getText().contains("/") && offset != 0)
615 text.select(offset, text.getText().length()); 615 text.select(offset, text.getText().length());
616 else 616 else
617 text.selectAll(); 617 text.selectAll();
@@ -623,7 +623,7 @@ public class Gui {
623 String newName = text.getText(); 623 String newName = text.getText();
624 if (saveName && newName != null && newName.length() > 0) { 624 if (saveName && newName != null && newName.length() > 0) {
625 try { 625 try {
626 this.controller.rename(m_reference, newName); 626 this.controller.rename(reference, newName);
627 } catch (IllegalNameException ex) { 627 } catch (IllegalNameException ex) {
628 text.setBorder(BorderFactory.createLineBorder(Color.red, 1)); 628 text.setBorder(BorderFactory.createLineBorder(Color.red, 1));
629 text.setToolTipText(ex.getReason()); 629 text.setToolTipText(ex.getReason());
@@ -633,9 +633,9 @@ public class Gui {
633 } 633 }
634 634
635 // abort the rename 635 // abort the rename
636 JPanel panel = (JPanel) m_infoPanel.getComponent(0); 636 JPanel panel = (JPanel) infoPanel.getComponent(0);
637 panel.remove(panel.getComponentCount() - 1); 637 panel.remove(panel.getComponentCount() - 1);
638 panel.add(Utils.unboldLabel(new JLabel(m_reference.getNamableName(), JLabel.LEFT))); 638 panel.add(Utils.unboldLabel(new JLabel(reference.getNamableName(), JLabel.LEFT)));
639 639
640 this.editor.grabFocus(); 640 this.editor.grabFocus();
641 641
@@ -644,95 +644,95 @@ public class Gui {
644 644
645 public void showInheritance() { 645 public void showInheritance() {
646 646
647 if (m_reference == null) { 647 if (reference == null) {
648 return; 648 return;
649 } 649 }
650 650
651 m_inheritanceTree.setModel(null); 651 inheritanceTree.setModel(null);
652 652
653 if (m_reference.entry instanceof ClassEntry) { 653 if (reference.entry instanceof ClassEntry) {
654 // get the class inheritance 654 // get the class inheritance
655 ClassInheritanceTreeNode classNode = this.controller.getClassInheritance((ClassEntry) m_reference.entry); 655 ClassInheritanceTreeNode classNode = this.controller.getClassInheritance((ClassEntry) reference.entry);
656 656
657 // show the tree at the root 657 // show the tree at the root
658 TreePath path = getPathToRoot(classNode); 658 TreePath path = getPathToRoot(classNode);
659 m_inheritanceTree.setModel(new DefaultTreeModel((TreeNode) path.getPathComponent(0))); 659 inheritanceTree.setModel(new DefaultTreeModel((TreeNode) path.getPathComponent(0)));
660 m_inheritanceTree.expandPath(path); 660 inheritanceTree.expandPath(path);
661 m_inheritanceTree.setSelectionRow(m_inheritanceTree.getRowForPath(path)); 661 inheritanceTree.setSelectionRow(inheritanceTree.getRowForPath(path));
662 } else if (m_reference.entry instanceof MethodEntry) { 662 } else if (reference.entry instanceof MethodEntry) {
663 // get the method inheritance 663 // get the method inheritance
664 MethodInheritanceTreeNode classNode = this.controller.getMethodInheritance((MethodEntry) m_reference.entry); 664 MethodInheritanceTreeNode classNode = this.controller.getMethodInheritance((MethodEntry) reference.entry);
665 665
666 // show the tree at the root 666 // show the tree at the root
667 TreePath path = getPathToRoot(classNode); 667 TreePath path = getPathToRoot(classNode);
668 m_inheritanceTree.setModel(new DefaultTreeModel((TreeNode) path.getPathComponent(0))); 668 inheritanceTree.setModel(new DefaultTreeModel((TreeNode) path.getPathComponent(0)));
669 m_inheritanceTree.expandPath(path); 669 inheritanceTree.expandPath(path);
670 m_inheritanceTree.setSelectionRow(m_inheritanceTree.getRowForPath(path)); 670 inheritanceTree.setSelectionRow(inheritanceTree.getRowForPath(path));
671 } 671 }
672 672
673 m_tabs.setSelectedIndex(0); 673 tabs.setSelectedIndex(0);
674 redraw(); 674 redraw();
675 } 675 }
676 676
677 public void showImplementations() { 677 public void showImplementations() {
678 678
679 if (m_reference == null) { 679 if (reference == null) {
680 return; 680 return;
681 } 681 }
682 682
683 m_implementationsTree.setModel(null); 683 implementationsTree.setModel(null);
684 684
685 DefaultMutableTreeNode node = null; 685 DefaultMutableTreeNode node = null;
686 686
687 // get the class implementations 687 // get the class implementations
688 if (m_reference.entry instanceof ClassEntry) 688 if (reference.entry instanceof ClassEntry)
689 node = this.controller.getClassImplementations((ClassEntry) m_reference.entry); 689 node = this.controller.getClassImplementations((ClassEntry) reference.entry);
690 else // get the method implementations 690 else // get the method implementations
691 if (m_reference.entry instanceof MethodEntry) 691 if (reference.entry instanceof MethodEntry)
692 node = this.controller.getMethodImplementations((MethodEntry) m_reference.entry); 692 node = this.controller.getMethodImplementations((MethodEntry) reference.entry);
693 693
694 if (node != null) { 694 if (node != null) {
695 // show the tree at the root 695 // show the tree at the root
696 TreePath path = getPathToRoot(node); 696 TreePath path = getPathToRoot(node);
697 m_implementationsTree.setModel(new DefaultTreeModel((TreeNode) path.getPathComponent(0))); 697 implementationsTree.setModel(new DefaultTreeModel((TreeNode) path.getPathComponent(0)));
698 m_implementationsTree.expandPath(path); 698 implementationsTree.expandPath(path);
699 m_implementationsTree.setSelectionRow(m_implementationsTree.getRowForPath(path)); 699 implementationsTree.setSelectionRow(implementationsTree.getRowForPath(path));
700 } 700 }
701 701
702 m_tabs.setSelectedIndex(1); 702 tabs.setSelectedIndex(1);
703 redraw(); 703 redraw();
704 } 704 }
705 705
706 public void showCalls() { 706 public void showCalls() {
707 if (m_reference == null) { 707 if (reference == null) {
708 return; 708 return;
709 } 709 }
710 710
711 if (m_reference.entry instanceof ClassEntry) { 711 if (reference.entry instanceof ClassEntry) {
712 // look for calls to the default constructor 712 // look for calls to the default constructor
713 // TODO: get a list of all the constructors and find calls to all of them 713 // TODO: get a list of all the constructors and find calls to all of them
714 BehaviorReferenceTreeNode node = this.controller.getMethodReferences(new ConstructorEntry((ClassEntry) m_reference.entry, new Signature("()V"))); 714 BehaviorReferenceTreeNode node = this.controller.getMethodReferences(new ConstructorEntry((ClassEntry) reference.entry, new Signature("()V")));
715 m_callsTree.setModel(new DefaultTreeModel(node)); 715 callsTree.setModel(new DefaultTreeModel(node));
716 } else if (m_reference.entry instanceof FieldEntry) { 716 } else if (reference.entry instanceof FieldEntry) {
717 FieldReferenceTreeNode node = this.controller.getFieldReferences((FieldEntry) m_reference.entry); 717 FieldReferenceTreeNode node = this.controller.getFieldReferences((FieldEntry) reference.entry);
718 m_callsTree.setModel(new DefaultTreeModel(node)); 718 callsTree.setModel(new DefaultTreeModel(node));
719 } else if (m_reference.entry instanceof MethodEntry) { 719 } else if (reference.entry instanceof MethodEntry) {
720 BehaviorReferenceTreeNode node = this.controller.getMethodReferences((MethodEntry) m_reference.entry); 720 BehaviorReferenceTreeNode node = this.controller.getMethodReferences((MethodEntry) reference.entry);
721 m_callsTree.setModel(new DefaultTreeModel(node)); 721 callsTree.setModel(new DefaultTreeModel(node));
722 } else if (m_reference.entry instanceof ConstructorEntry) { 722 } else if (reference.entry instanceof ConstructorEntry) {
723 BehaviorReferenceTreeNode node = this.controller.getMethodReferences((ConstructorEntry) m_reference.entry); 723 BehaviorReferenceTreeNode node = this.controller.getMethodReferences((ConstructorEntry) reference.entry);
724 m_callsTree.setModel(new DefaultTreeModel(node)); 724 callsTree.setModel(new DefaultTreeModel(node));
725 } 725 }
726 726
727 m_tabs.setSelectedIndex(2); 727 tabs.setSelectedIndex(2);
728 redraw(); 728 redraw();
729 } 729 }
730 730
731 public void toggleMapping() { 731 public void toggleMapping() {
732 if (this.controller.entryHasDeobfuscatedName(m_reference.entry)) { 732 if (this.controller.entryHasDeobfuscatedName(reference.entry)) {
733 this.controller.removeMapping(m_reference); 733 this.controller.removeMapping(reference);
734 } else { 734 } else {
735 this.controller.markAsDeobfuscated(m_reference); 735 this.controller.markAsDeobfuscated(reference);
736 } 736 }
737 } 737 }
738 738
diff --git a/src/main/java/cuchaz/enigma/gui/GuiController.java b/src/main/java/cuchaz/enigma/gui/GuiController.java
index c2e202e2..68fd4843 100644
--- a/src/main/java/cuchaz/enigma/gui/GuiController.java
+++ b/src/main/java/cuchaz/enigma/gui/GuiController.java
@@ -50,7 +50,7 @@ public class GuiController {
50 return this.isDirty; 50 return this.isDirty;
51 } 51 }
52 52
53 public void openJar(final JarFile jar) throws IOException { 53 public void openJar(final JarFile jar) {
54 this.gui.onStartOpenJar(); 54 this.gui.onStartOpenJar();
55 this.deobfuscator = new Deobfuscator(jar); 55 this.deobfuscator = new Deobfuscator(jar);
56 this.gui.onFinishOpenJar(this.deobfuscator.getJarName()); 56 this.gui.onFinishOpenJar(this.deobfuscator.getJarName());
@@ -302,42 +302,40 @@ public class GuiController {
302 this.gui.setSource("(deobfuscating...)"); 302 this.gui.setSource("(deobfuscating...)");
303 303
304 // run the deobfuscator in a separate thread so we don't block the GUI event queue 304 // run the deobfuscator in a separate thread so we don't block the GUI event queue
305 new Thread() { 305 new Thread(() ->
306 @Override 306 {
307 public void run() { 307 // decompile,deobfuscate the bytecode
308 // decompile,deobfuscate the bytecode 308 CompilationUnit sourceTree = deobfuscator.getSourceTree(classEntry.getClassName());
309 CompilationUnit sourceTree = deobfuscator.getSourceTree(classEntry.getClassName()); 309 if (sourceTree == null) {
310 if (sourceTree == null) { 310 // decompilation of this class is not supported
311 // decompilation of this class is not supported 311 gui.setSource("Unable to find class: " + classEntry);
312 gui.setSource("Unable to find class: " + classEntry); 312 return;
313 return; 313 }
314 } 314 String source = deobfuscator.getSource(sourceTree);
315 String source = deobfuscator.getSource(sourceTree); 315 index = deobfuscator.getSourceIndex(sourceTree, source);
316 index = deobfuscator.getSourceIndex(sourceTree, source); 316 gui.setSource(index.getSource());
317 gui.setSource(index.getSource()); 317 if (obfReference != null) {
318 if (obfReference != null) { 318 showReference(obfReference);
319 showReference(obfReference); 319 }
320 }
321 320
322 // set the highlighted tokens 321 // set the highlighted tokens
323 List<Token> obfuscatedTokens = Lists.newArrayList(); 322 List<Token> obfuscatedTokens = Lists.newArrayList();
324 List<Token> deobfuscatedTokens = Lists.newArrayList(); 323 List<Token> deobfuscatedTokens = Lists.newArrayList();
325 List<Token> otherTokens = Lists.newArrayList(); 324 List<Token> otherTokens = Lists.newArrayList();
326 for (Token token : index.referenceTokens()) { 325 for (Token token : index.referenceTokens()) {
327 EntryReference<Entry, Entry> reference = index.getDeobfReference(token); 326 EntryReference<Entry, Entry> reference = index.getDeobfReference(token);
328 if (referenceIsRenameable(reference)) { 327 if (referenceIsRenameable(reference)) {
329 if (entryHasDeobfuscatedName(reference.getNameableEntry())) { 328 if (entryHasDeobfuscatedName(reference.getNameableEntry())) {
330 deobfuscatedTokens.add(token); 329 deobfuscatedTokens.add(token);
331 } else {
332 obfuscatedTokens.add(token);
333 }
334 } else { 330 } else {
335 otherTokens.add(token); 331 obfuscatedTokens.add(token);
336 } 332 }
333 } else {
334 otherTokens.add(token);
337 } 335 }
338 gui.setHighlightedTokens(obfuscatedTokens, deobfuscatedTokens, otherTokens);
339 } 336 }
340 }.start(); 337 gui.setHighlightedTokens(obfuscatedTokens, deobfuscatedTokens, otherTokens);
338 }).start();
341 } 339 }
342 340
343 public Deobfuscator getDeobfuscator() 341 public Deobfuscator getDeobfuscator()
@@ -349,7 +347,7 @@ public class GuiController {
349 { 347 {
350 if (event.getStateChange() == ItemEvent.SELECTED) 348 if (event.getStateChange() == ItemEvent.SELECTED)
351 { 349 {
352 deobfuscator.changeModifier(gui.m_reference.entry, (Mappings.EntryModifier) event.getItem()); 350 deobfuscator.changeModifier(gui.reference.entry, (Mappings.EntryModifier) event.getItem());
353 this.isDirty = true; 351 this.isDirty = true;
354 refreshCurrentClass(); 352 refreshCurrentClass();
355 } 353 }
diff --git a/src/main/java/cuchaz/enigma/gui/MemberMatchingGui.java b/src/main/java/cuchaz/enigma/gui/MemberMatchingGui.java
index ecc280d5..671f85fe 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,7 +29,6 @@ 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;
@@ -78,39 +76,38 @@ public class MemberMatchingGui<T extends Entry> {
78 } 76 }
79 77
80 // controls 78 // controls
81 private JFrame m_frame; 79 private JFrame frame;
82 private Map<SourceType, JRadioButton> m_sourceTypeButtons; 80 private Map<SourceType, JRadioButton> sourceTypeButtons;
83 private ClassSelector m_sourceClasses; 81 private ClassSelector sourceClasses;
84 private CodeReader m_sourceReader; 82 private CodeReader sourceReader;
85 private CodeReader m_destReader; 83 private CodeReader destReader;
86 private JButton m_matchButton; 84 private JButton matchButton;
87 private JButton m_unmatchableButton; 85 private JButton unmatchableButton;
88 private JLabel m_sourceLabel; 86 private JLabel sourceLabel;
89 private JLabel m_destLabel; 87 private JLabel destLabel;
90 private HighlightPainter m_unmatchedHighlightPainter; 88 private HighlightPainter unmatchedHighlightPainter;
91 private HighlightPainter m_matchedHighlightPainter; 89 private HighlightPainter matchedHighlightPainter;
92 90 private ClassMatches classMatches;
93 private ClassMatches m_classMatches; 91 private MemberMatches<T> memberMatches;
94 private MemberMatches<T> m_memberMatches; 92 private Deobfuscator sourceDeobfuscator;
95 private Deobfuscator m_sourceDeobfuscator; 93 private Deobfuscator destDeobfuscator;
96 private Deobfuscator m_destDeobfuscator; 94 private SaveListener<T> saveListener;
97 private SaveListener<T> m_saveListener; 95 private SourceType sourceType;
98 private SourceType m_sourceType; 96 private ClassEntry obfSourceClass;
99 private ClassEntry m_obfSourceClass; 97 private ClassEntry obfDestClass;
100 private ClassEntry m_obfDestClass; 98 private T obfSourceEntry;
101 private T m_obfSourceEntry; 99 private T obfDestEntry;
102 private T m_obfDestEntry;
103 100
104 public MemberMatchingGui(ClassMatches classMatches, MemberMatches<T> fieldMatches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) { 101 public MemberMatchingGui(ClassMatches classMatches, MemberMatches<T> fieldMatches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) {
105 102
106 m_classMatches = classMatches; 103 this.classMatches = classMatches;
107 m_memberMatches = fieldMatches; 104 memberMatches = fieldMatches;
108 m_sourceDeobfuscator = sourceDeobfuscator; 105 this.sourceDeobfuscator = sourceDeobfuscator;
109 m_destDeobfuscator = destDeobfuscator; 106 this.destDeobfuscator = destDeobfuscator;
110 107
111 // init frame 108 // init frame
112 m_frame = new JFrame(Constants.NAME + " - Member Matcher"); 109 frame = new JFrame(Constants.NAME + " - Member Matcher");
113 final Container pane = m_frame.getContentPane(); 110 final Container pane = frame.getContentPane();
114 pane.setLayout(new BorderLayout()); 111 pane.setLayout(new BorderLayout());
115 112
116 // init classes side 113 // init classes side
@@ -124,47 +121,38 @@ public class MemberMatchingGui<T extends Entry> {
124 JPanel sourceTypePanel = new JPanel(); 121 JPanel sourceTypePanel = new JPanel();
125 classesPanel.add(sourceTypePanel); 122 classesPanel.add(sourceTypePanel);
126 sourceTypePanel.setLayout(new BoxLayout(sourceTypePanel, BoxLayout.PAGE_AXIS)); 123 sourceTypePanel.setLayout(new BoxLayout(sourceTypePanel, BoxLayout.PAGE_AXIS));
127 ActionListener sourceTypeListener = new ActionListener() { 124 ActionListener sourceTypeListener = event -> setSourceType(SourceType.valueOf(event.getActionCommand()));
128 @Override
129 public void actionPerformed(ActionEvent event) {
130 setSourceType(SourceType.valueOf(event.getActionCommand()));
131 }
132 };
133 ButtonGroup sourceTypeButtons = new ButtonGroup(); 125 ButtonGroup sourceTypeButtons = new ButtonGroup();
134 m_sourceTypeButtons = Maps.newHashMap(); 126 this.sourceTypeButtons = Maps.newHashMap();
135 for (SourceType sourceType : SourceType.values()) { 127 for (SourceType sourceType : SourceType.values()) {
136 JRadioButton button = sourceType.newRadio(sourceTypeListener, sourceTypeButtons); 128 JRadioButton button = sourceType.newRadio(sourceTypeListener, sourceTypeButtons);
137 m_sourceTypeButtons.put(sourceType, button); 129 this.sourceTypeButtons.put(sourceType, button);
138 sourceTypePanel.add(button); 130 sourceTypePanel.add(button);
139 } 131 }
140 132
141 m_sourceClasses = new ClassSelector(null, ClassSelector.DEOBF_CLASS_COMPARATOR, false); 133 sourceClasses = new ClassSelector(null, ClassSelector.DEOBF_CLASS_COMPARATOR, false);
142 m_sourceClasses.setSelectionListener(this::setSourceClass); 134 sourceClasses.setSelectionListener(this::setSourceClass);
143 JScrollPane sourceScroller = new JScrollPane(m_sourceClasses); 135 JScrollPane sourceScroller = new JScrollPane(sourceClasses);
144 classesPanel.add(sourceScroller); 136 classesPanel.add(sourceScroller);
145 137
146 // init readers 138 // init readers
147 DefaultSyntaxKit.initKit(); 139 DefaultSyntaxKit.initKit();
148 m_sourceReader = new CodeReader(); 140 sourceReader = new CodeReader();
149 m_sourceReader.setSelectionListener(new CodeReader.SelectionListener() { 141 sourceReader.setSelectionListener(reference ->
150 @Override 142 {
151 public void onSelect(EntryReference<Entry, Entry> reference) { 143 if (reference != null) {
152 if (reference != null) { 144 onSelectSource(reference.entry);
153 onSelectSource(reference.entry); 145 } else {
154 } else { 146 onSelectSource(null);
155 onSelectSource(null);
156 }
157 } 147 }
158 }); 148 });
159 m_destReader = new CodeReader(); 149 destReader = new CodeReader();
160 m_destReader.setSelectionListener(new CodeReader.SelectionListener() { 150 destReader.setSelectionListener(reference ->
161 @Override 151 {
162 public void onSelect(EntryReference<Entry, Entry> reference) { 152 if (reference != null) {
163 if (reference != null) { 153 onSelectDest(reference.entry);
164 onSelectDest(reference.entry); 154 } else {
165 } else { 155 onSelectDest(null);
166 onSelectDest(null);
167 }
168 } 156 }
169 }); 157 });
170 158
@@ -173,14 +161,15 @@ public class MemberMatchingGui<T extends Entry> {
173 @Override 161 @Override
174 public void keyPressed(KeyEvent event) { 162 public void keyPressed(KeyEvent event) {
175 if (event.getKeyCode() == KeyEvent.VK_M) 163 if (event.getKeyCode() == KeyEvent.VK_M)
176 m_matchButton.doClick(); 164 matchButton.doClick();
177 } 165 }
178 }; 166 };
179 m_sourceReader.addKeyListener(keyListener); 167 sourceReader.addKeyListener(keyListener);
180 m_destReader.addKeyListener(keyListener); 168 destReader.addKeyListener(keyListener);
181 169
182 // init all the splits 170 // init all the splits
183 JSplitPane splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JScrollPane(m_sourceReader), new JScrollPane(m_destReader)); 171 JSplitPane splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JScrollPane(sourceReader), new JScrollPane(
172 destReader));
184 splitRight.setResizeWeight(0.5); // resize 50:50 173 splitRight.setResizeWeight(0.5); // resize 50:50
185 JSplitPane splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, classesPanel, splitRight); 174 JSplitPane splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, classesPanel, splitRight);
186 splitLeft.setResizeWeight(0); // let the right side take all the slack 175 splitLeft.setResizeWeight(0); // let the right side take all the slack
@@ -192,102 +181,92 @@ public class MemberMatchingGui<T extends Entry> {
192 bottomPanel.setLayout(new FlowLayout()); 181 bottomPanel.setLayout(new FlowLayout());
193 pane.add(bottomPanel, BorderLayout.SOUTH); 182 pane.add(bottomPanel, BorderLayout.SOUTH);
194 183
195 m_matchButton = new JButton(); 184 matchButton = new JButton();
196 m_unmatchableButton = new JButton(); 185 unmatchableButton = new JButton();
197 186
198 m_sourceLabel = new JLabel(); 187 sourceLabel = new JLabel();
199 bottomPanel.add(m_sourceLabel); 188 bottomPanel.add(sourceLabel);
200 bottomPanel.add(m_matchButton); 189 bottomPanel.add(matchButton);
201 bottomPanel.add(m_unmatchableButton); 190 bottomPanel.add(unmatchableButton);
202 m_destLabel = new JLabel(); 191 destLabel = new JLabel();
203 bottomPanel.add(m_destLabel); 192 bottomPanel.add(destLabel);
204 193
205 // show the frame 194 // show the frame
206 pane.doLayout(); 195 pane.doLayout();
207 m_frame.setSize(1024, 576); 196 frame.setSize(1024, 576);
208 m_frame.setMinimumSize(new Dimension(640, 480)); 197 frame.setMinimumSize(new Dimension(640, 480));
209 m_frame.setVisible(true); 198 frame.setVisible(true);
210 m_frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 199 frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
211 200
212 m_unmatchedHighlightPainter = new ObfuscatedHighlightPainter(); 201 unmatchedHighlightPainter = new ObfuscatedHighlightPainter();
213 m_matchedHighlightPainter = new DeobfuscatedHighlightPainter(); 202 matchedHighlightPainter = new DeobfuscatedHighlightPainter();
214 203
215 // init state 204 // init state
216 m_saveListener = null; 205 saveListener = null;
217 m_obfSourceClass = null; 206 obfSourceClass = null;
218 m_obfDestClass = null; 207 obfDestClass = null;
219 m_obfSourceEntry = null; 208 obfSourceEntry = null;
220 m_obfDestEntry = null; 209 obfDestEntry = null;
221 setSourceType(SourceType.getDefault()); 210 setSourceType(SourceType.getDefault());
222 updateButtons(); 211 updateButtons();
223 } 212 }
224 213
225 protected void setSourceType(SourceType val) { 214 protected void setSourceType(SourceType val) {
226 m_sourceType = val; 215 sourceType = val;
227 updateSourceClasses(); 216 updateSourceClasses();
228 } 217 }
229 218
230 public void setSaveListener(SaveListener<T> val) { 219 public void setSaveListener(SaveListener<T> val) {
231 m_saveListener = val; 220 saveListener = val;
232 } 221 }
233 222
234 private void updateSourceClasses() { 223 private void updateSourceClasses() {
235 224
236 String selectedPackage = m_sourceClasses.getSelectedPackage(); 225 String selectedPackage = sourceClasses.getSelectedPackage();
237 226
238 List<ClassEntry> deobfClassEntries = Lists.newArrayList(); 227 List<ClassEntry> deobfClassEntries = Lists.newArrayList();
239 for (ClassEntry entry : m_sourceType.getObfSourceClasses(m_memberMatches)) { 228 for (ClassEntry entry : sourceType.getObfSourceClasses(memberMatches)) {
240 deobfClassEntries.add(m_sourceDeobfuscator.deobfuscateEntry(entry)); 229 deobfClassEntries.add(sourceDeobfuscator.deobfuscateEntry(entry));
241 } 230 }
242 m_sourceClasses.setClasses(deobfClassEntries); 231 sourceClasses.setClasses(deobfClassEntries);
243 232
244 if (selectedPackage != null) { 233 if (selectedPackage != null) {
245 m_sourceClasses.expandPackage(selectedPackage); 234 sourceClasses.expandPackage(selectedPackage);
246 } 235 }
247 236
248 for (SourceType sourceType : SourceType.values()) { 237 for (SourceType sourceType : SourceType.values()) {
249 m_sourceTypeButtons.get(sourceType).setText(String.format("%s (%d)", 238 sourceTypeButtons.get(sourceType).setText(String.format("%s (%d)",
250 sourceType.name(), sourceType.getObfSourceClasses(m_memberMatches).size() 239 sourceType.name(), sourceType.getObfSourceClasses(memberMatches).size()
251 )); 240 ));
252 } 241 }
253 } 242 }
254 243
255 protected void setSourceClass(ClassEntry sourceClass) { 244 protected void setSourceClass(ClassEntry sourceClass) {
256 245
257 m_obfSourceClass = m_sourceDeobfuscator.obfuscateEntry(sourceClass); 246 obfSourceClass = sourceDeobfuscator.obfuscateEntry(sourceClass);
258 m_obfDestClass = m_classMatches.getUniqueMatches().get(m_obfSourceClass); 247 obfDestClass = classMatches.getUniqueMatches().get(obfSourceClass);
259 if (m_obfDestClass == null) { 248 if (obfDestClass == null) {
260 throw new Error("No matching dest class for source class: " + m_obfSourceClass); 249 throw new Error("No matching dest class for source class: " + obfSourceClass);
261 } 250 }
262 251
263 m_sourceReader.decompileClass(m_obfSourceClass, m_sourceDeobfuscator, false, new Runnable() { 252 sourceReader.decompileClass(obfSourceClass, sourceDeobfuscator, false, this::updateSourceHighlights);
264 @Override 253 destReader.decompileClass(obfDestClass, destDeobfuscator, false, this::updateDestHighlights);
265 public void run() {
266 updateSourceHighlights();
267 }
268 });
269 m_destReader.decompileClass(m_obfDestClass, m_destDeobfuscator, false, new Runnable() {
270 @Override
271 public void run() {
272 updateDestHighlights();
273 }
274 });
275 } 254 }
276 255
277 protected void updateSourceHighlights() { 256 protected void updateSourceHighlights() {
278 highlightEntries(m_sourceReader, m_sourceDeobfuscator, m_memberMatches.matches().keySet(), m_memberMatches.getUnmatchedSourceEntries()); 257 highlightEntries(sourceReader, sourceDeobfuscator, memberMatches.matches().keySet(), memberMatches.getUnmatchedSourceEntries());
279 } 258 }
280 259
281 protected void updateDestHighlights() { 260 protected void updateDestHighlights() {
282 highlightEntries(m_destReader, m_destDeobfuscator, m_memberMatches.matches().values(), m_memberMatches.getUnmatchedDestEntries()); 261 highlightEntries(destReader, destDeobfuscator, memberMatches.matches().values(), memberMatches.getUnmatchedDestEntries());
283 } 262 }
284 263
285 private void highlightEntries(CodeReader reader, Deobfuscator deobfuscator, Collection<T> obfMatchedEntries, Collection<T> obfUnmatchedEntries) { 264 private void highlightEntries(CodeReader reader, Deobfuscator deobfuscator, Collection<T> obfMatchedEntries, Collection<T> obfUnmatchedEntries) {
286 reader.clearHighlights(); 265 reader.clearHighlights();
287 // matched fields 266 // matched fields
288 updateHighlighted(obfMatchedEntries, deobfuscator, reader, m_matchedHighlightPainter); 267 updateHighlighted(obfMatchedEntries, deobfuscator, reader, matchedHighlightPainter);
289 // unmatched fields 268 // unmatched fields
290 updateHighlighted(obfUnmatchedEntries, deobfuscator, reader, m_unmatchedHighlightPainter); 269 updateHighlighted(obfUnmatchedEntries, deobfuscator, reader, unmatchedHighlightPainter);
291 } 270 }
292 271
293 private void updateHighlighted(Collection<T> entries, Deobfuscator deobfuscator, CodeReader reader, HighlightPainter painter) 272 private void updateHighlighted(Collection<T> entries, Deobfuscator deobfuscator, CodeReader reader, HighlightPainter painter)
@@ -303,8 +282,8 @@ public class MemberMatchingGui<T extends Entry> {
303 } 282 }
304 283
305 private boolean isSelectionMatched() { 284 private boolean isSelectionMatched() {
306 return m_obfSourceEntry != null && m_obfDestEntry != null 285 return obfSourceEntry != null && obfDestEntry != null
307 && m_memberMatches.isMatched(m_obfSourceEntry, m_obfDestEntry); 286 && memberMatches.isMatched(obfSourceEntry, obfDestEntry);
308 } 287 }
309 288
310 protected void onSelectSource(Entry source) { 289 protected void onSelectSource(Entry source) {
@@ -324,12 +303,12 @@ public class MemberMatchingGui<T extends Entry> {
324 @SuppressWarnings("unchecked") 303 @SuppressWarnings("unchecked")
325 T sourceEntry = (T) source; 304 T sourceEntry = (T) source;
326 305
327 T obfSourceEntry = m_sourceDeobfuscator.obfuscateEntry(sourceEntry); 306 T obfSourceEntry = sourceDeobfuscator.obfuscateEntry(sourceEntry);
328 if (m_memberMatches.hasSource(obfSourceEntry)) { 307 if (memberMatches.hasSource(obfSourceEntry)) {
329 setSource(obfSourceEntry); 308 setSource(obfSourceEntry);
330 309
331 // look for a matched dest too 310 // look for a matched dest too
332 T obfDestEntry = m_memberMatches.matches().get(obfSourceEntry); 311 T obfDestEntry = memberMatches.matches().get(obfSourceEntry);
333 if (obfDestEntry != null) { 312 if (obfDestEntry != null) {
334 setDest(obfDestEntry); 313 setDest(obfDestEntry);
335 } 314 }
@@ -356,12 +335,12 @@ public class MemberMatchingGui<T extends Entry> {
356 @SuppressWarnings("unchecked") 335 @SuppressWarnings("unchecked")
357 T destEntry = (T) dest; 336 T destEntry = (T) dest;
358 337
359 T obfDestEntry = m_destDeobfuscator.obfuscateEntry(destEntry); 338 T obfDestEntry = destDeobfuscator.obfuscateEntry(destEntry);
360 if (m_memberMatches.hasDest(obfDestEntry)) { 339 if (memberMatches.hasDest(obfDestEntry)) {
361 setDest(obfDestEntry); 340 setDest(obfDestEntry);
362 341
363 // look for a matched source too 342 // look for a matched source too
364 T obfSourceEntry = m_memberMatches.matches().inverse().get(obfDestEntry); 343 T obfSourceEntry = memberMatches.matches().inverse().get(obfDestEntry);
365 if (obfSourceEntry != null) { 344 if (obfSourceEntry != null) {
366 setSource(obfSourceEntry); 345 setSource(obfSourceEntry);
367 } 346 }
@@ -373,21 +352,21 @@ public class MemberMatchingGui<T extends Entry> {
373 352
374 private void setSource(T obfEntry) { 353 private void setSource(T obfEntry) {
375 if (obfEntry == null) { 354 if (obfEntry == null) {
376 m_obfSourceEntry = null; 355 obfSourceEntry = null;
377 m_sourceLabel.setText(""); 356 sourceLabel.setText("");
378 } else { 357 } else {
379 m_obfSourceEntry = obfEntry; 358 obfSourceEntry = obfEntry;
380 m_sourceLabel.setText(getEntryLabel(obfEntry, m_sourceDeobfuscator)); 359 sourceLabel.setText(getEntryLabel(obfEntry, sourceDeobfuscator));
381 } 360 }
382 } 361 }
383 362
384 private void setDest(T obfEntry) { 363 private void setDest(T obfEntry) {
385 if (obfEntry == null) { 364 if (obfEntry == null) {
386 m_obfDestEntry = null; 365 obfDestEntry = null;
387 m_destLabel.setText(""); 366 destLabel.setText("");
388 } else { 367 } else {
389 m_obfDestEntry = obfEntry; 368 obfDestEntry = obfEntry;
390 m_destLabel.setText(getEntryLabel(obfEntry, m_destDeobfuscator)); 369 destLabel.setText(getEntryLabel(obfEntry, destDeobfuscator));
391 } 370 }
392 } 371 }
393 372
@@ -399,39 +378,23 @@ public class MemberMatchingGui<T extends Entry> {
399 378
400 private void updateButtons() { 379 private void updateButtons() {
401 380
402 GuiTricks.deactivateButton(m_matchButton); 381 GuiTricks.deactivateButton(matchButton);
403 GuiTricks.deactivateButton(m_unmatchableButton); 382 GuiTricks.deactivateButton(unmatchableButton);
404 383
405 if (m_obfSourceEntry != null && m_obfDestEntry != null) { 384 if (obfSourceEntry != null && obfDestEntry != null) {
406 if (m_memberMatches.isMatched(m_obfSourceEntry, m_obfDestEntry)) { 385 if (memberMatches.isMatched(obfSourceEntry, obfDestEntry))
407 GuiTricks.activateButton(m_matchButton, "Unmatch", new ActionListener() { 386 GuiTricks.activateButton(matchButton, "Unmatch", event -> unmatch());
408 @Override 387 else if (!memberMatches.isMatchedSourceEntry(obfSourceEntry) && !memberMatches.isMatchedDestEntry(
409 public void actionPerformed(ActionEvent event) { 388 obfDestEntry))
410 unmatch(); 389 GuiTricks.activateButton(matchButton, "Match", event -> match());
411 } 390 } else if (obfSourceEntry != null)
412 }); 391 GuiTricks.activateButton(unmatchableButton, "Set Unmatchable", event -> unmatchable());
413 } else if (!m_memberMatches.isMatchedSourceEntry(m_obfSourceEntry) && !m_memberMatches.isMatchedDestEntry(m_obfDestEntry)) {
414 GuiTricks.activateButton(m_matchButton, "Match", new ActionListener() {
415 @Override
416 public void actionPerformed(ActionEvent event) {
417 match();
418 }
419 });
420 }
421 } else if (m_obfSourceEntry != null) {
422 GuiTricks.activateButton(m_unmatchableButton, "Set Unmatchable", new ActionListener() {
423 @Override
424 public void actionPerformed(ActionEvent event) {
425 unmatchable();
426 }
427 });
428 }
429 } 392 }
430 393
431 protected void match() { 394 protected void match() {
432 395
433 // update the field matches 396 // update the field matches
434 m_memberMatches.makeMatch(m_obfSourceEntry, m_obfDestEntry, m_sourceDeobfuscator, m_destDeobfuscator); 397 memberMatches.makeMatch(obfSourceEntry, obfDestEntry, sourceDeobfuscator, destDeobfuscator);
435 save(); 398 save();
436 399
437 // update the ui 400 // update the ui
@@ -445,7 +408,7 @@ public class MemberMatchingGui<T extends Entry> {
445 protected void unmatch() { 408 protected void unmatch() {
446 409
447 // update the field matches 410 // update the field matches
448 m_memberMatches.unmakeMatch(m_obfSourceEntry, m_obfDestEntry, m_sourceDeobfuscator, m_destDeobfuscator); 411 memberMatches.unmakeMatch(obfSourceEntry, obfDestEntry, sourceDeobfuscator, destDeobfuscator);
449 save(); 412 save();
450 413
451 // update the ui 414 // update the ui
@@ -459,7 +422,7 @@ public class MemberMatchingGui<T extends Entry> {
459 protected void unmatchable() { 422 protected void unmatchable() {
460 423
461 // update the field matches 424 // update the field matches
462 m_memberMatches.makeSourceUnmatchable(m_obfSourceEntry, m_sourceDeobfuscator); 425 memberMatches.makeSourceUnmatchable(obfSourceEntry, sourceDeobfuscator);
463 save(); 426 save();
464 427
465 // update the ui 428 // update the ui
@@ -471,8 +434,8 @@ public class MemberMatchingGui<T extends Entry> {
471 } 434 }
472 435
473 private void save() { 436 private void save() {
474 if (m_saveListener != null) { 437 if (saveListener != null) {
475 m_saveListener.save(m_memberMatches); 438 saveListener.save(memberMatches);
476 } 439 }
477 } 440 }
478} 441}
diff --git a/src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java b/src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java
index d1e2de0e..bd9fe3d4 100644
--- a/src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java
+++ b/src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java
@@ -17,14 +17,28 @@ public class ScoredClassEntry extends ClassEntry {
17 17
18 private static final long serialVersionUID = -8798725308554217105L; 18 private static final long serialVersionUID = -8798725308554217105L;
19 19
20 private float m_score; 20 private float score;
21 21
22 public ScoredClassEntry(ClassEntry other, float score) { 22 public ScoredClassEntry(ClassEntry other, float score) {
23 super(other); 23 super(other);
24 m_score = score; 24 this.score = score;
25 } 25 }
26 26
27 public float getScore() { 27 public float getScore() {
28 return m_score; 28 return score;
29 }
30
31 @Override
32 public int hashCode() {
33 return Float.hashCode(score) + super.hashCode();
34 }
35
36 @Override
37 public boolean equals(Object other) {
38 return super.equals(other) && other instanceof ScoredClassEntry && equals((ScoredClassEntry) other);
39 }
40
41 public boolean equals(ScoredClassEntry other) {
42 return other != null && score == other.score;
29 } 43 }
30} 44}
diff --git a/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java
index 8d3df47b..5c1d9ff8 100644
--- a/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java
+++ b/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java
@@ -23,15 +23,15 @@ import cuchaz.enigma.utils.Utils;
23 23
24public class CrashDialog { 24public class CrashDialog {
25 25
26 private static CrashDialog m_instance = null; 26 private static CrashDialog instance = null;
27 27
28 private JFrame m_frame; 28 private JFrame frame;
29 private JTextArea m_text; 29 private JTextArea text;
30 30
31 private CrashDialog(JFrame parent) { 31 private CrashDialog(JFrame parent) {
32 // init frame 32 // init frame
33 m_frame = new JFrame(Constants.NAME + " - Crash Report"); 33 frame = new JFrame(Constants.NAME + " - Crash Report");
34 final Container pane = m_frame.getContentPane(); 34 final Container pane = frame.getContentPane();
35 pane.setLayout(new BorderLayout()); 35 pane.setLayout(new BorderLayout());
36 36
37 JLabel label = new JLabel(Constants.NAME + " has crashed! =("); 37 JLabel label = new JLabel(Constants.NAME + " has crashed! =(");
@@ -39,9 +39,9 @@ public class CrashDialog {
39 pane.add(label, BorderLayout.NORTH); 39 pane.add(label, BorderLayout.NORTH);
40 40
41 // report panel 41 // report panel
42 m_text = new JTextArea(); 42 text = new JTextArea();
43 m_text.setTabSize(2); 43 text.setTabSize(2);
44 pane.add(new JScrollPane(m_text), BorderLayout.CENTER); 44 pane.add(new JScrollPane(text), BorderLayout.CENTER);
45 45
46 // buttons panel 46 // buttons panel
47 JPanel buttonsPanel = new JPanel(); 47 JPanel buttonsPanel = new JPanel();
@@ -52,7 +52,7 @@ public class CrashDialog {
52 JButton ignoreButton = new JButton("Ignore"); 52 JButton ignoreButton = new JButton("Ignore");
53 ignoreButton.addActionListener(event -> { 53 ignoreButton.addActionListener(event -> {
54 // close (hide) the dialog 54 // close (hide) the dialog
55 m_frame.setVisible(false); 55 frame.setVisible(false);
56 }); 56 });
57 buttonsPanel.add(ignoreButton); 57 buttonsPanel.add(ignoreButton);
58 JButton exitButton = new JButton("Exit"); 58 JButton exitButton = new JButton("Exit");
@@ -64,13 +64,13 @@ public class CrashDialog {
64 pane.add(buttonsPanel, BorderLayout.SOUTH); 64 pane.add(buttonsPanel, BorderLayout.SOUTH);
65 65
66 // show the frame 66 // show the frame
67 m_frame.setSize(600, 400); 67 frame.setSize(600, 400);
68 m_frame.setLocationRelativeTo(parent); 68 frame.setLocationRelativeTo(parent);
69 m_frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 69 frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
70 } 70 }
71 71
72 public static void init(JFrame parent) { 72 public static void init(JFrame parent) {
73 m_instance = new CrashDialog(parent); 73 instance = new CrashDialog(parent);
74 } 74 }
75 75
76 public static void show(Throwable ex) { 76 public static void show(Throwable ex) {
@@ -80,8 +80,8 @@ public class CrashDialog {
80 String report = buf.toString(); 80 String report = buf.toString();
81 81
82 // show it! 82 // show it!
83 m_instance.m_text.setText(report); 83 instance.text.setText(report);
84 m_instance.m_frame.doLayout(); 84 instance.frame.doLayout();
85 m_instance.m_frame.setVisible(true); 85 instance.frame.setVisible(true);
86 } 86 }
87} 87}
diff --git a/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java
index c752c868..8df22a7f 100644
--- a/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java
+++ b/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java
@@ -87,15 +87,13 @@ public class ProgressDialog implements ProgressListener, AutoCloseable {
87 } 87 }
88 88
89 public static void runInThread(final JFrame parent, final ProgressRunnable runnable) { 89 public static void runInThread(final JFrame parent, final ProgressRunnable runnable) {
90 new Thread() { 90 new Thread(() ->
91 @Override 91 {
92 public void run() { 92 try (ProgressDialog progress = new ProgressDialog(parent)) {
93 try (ProgressDialog progress = new ProgressDialog(parent)) { 93 runnable.run(progress);
94 runnable.run(progress); 94 } catch (Exception ex) {
95 } catch (Exception ex) { 95 throw new Error(ex);
96 throw new Error(ex);
97 }
98 } 96 }
99 }.start(); 97 }).start();
100 } 98 }
101} 99}
diff --git a/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java b/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
index dcd7c93a..0ccd5372 100644
--- a/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
+++ b/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
@@ -42,16 +42,14 @@ public class MenuBar extends JMenuBar {
42 item.addActionListener(event -> { 42 item.addActionListener(event -> {
43 if (this.gui.jarFileChooser.showOpenDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { 43 if (this.gui.jarFileChooser.showOpenDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
44 // load the jar in a separate thread 44 // load the jar in a separate thread
45 new Thread() { 45 new Thread(() ->
46 @Override 46 {
47 public void run() { 47 try {
48 try { 48 gui.getController().openJar(new JarFile(gui.jarFileChooser.getSelectedFile()));
49 gui.getController().openJar(new JarFile(gui.jarFileChooser.getSelectedFile())); 49 } catch (IOException ex) {
50 } catch (IOException ex) { 50 throw new Error(ex);
51 throw new Error(ex);
52 }
53 } 51 }
54 }.start(); 52 }).start();
55 } 53 }
56 }); 54 });
57 } 55 }
@@ -177,9 +175,7 @@ public class MenuBar extends JMenuBar {
177 { 175 {
178 JMenuItem item = new JMenuItem("Rebuild Method Names"); 176 JMenuItem item = new JMenuItem("Rebuild Method Names");
179 menu.add(item); 177 menu.add(item);
180 item.addActionListener(event -> { 178 item.addActionListener(event -> this.gui.getController().rebuildMethodNames());
181 this.gui.getController().rebuildMethodNames();
182 });
183 this.rebuildMethodNamesMenu = item; 179 this.rebuildMethodNamesMenu = item;
184 } 180 }
185 menu.addSeparator(); 181 menu.addSeparator();
diff --git a/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java b/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java
index 2b06342b..e387ed31 100644
--- a/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java
+++ b/src/main/java/cuchaz/enigma/gui/elements/PopupMenuBar.java
@@ -53,7 +53,7 @@ public class PopupMenuBar extends JPopupMenu {
53 } 53 }
54 { 54 {
55 JMenuItem menu = new JMenuItem("Go to Declaration"); 55 JMenuItem menu = new JMenuItem("Go to Declaration");
56 menu.addActionListener(event -> gui.navigateTo(gui.m_reference.entry)); 56 menu.addActionListener(event -> gui.navigateTo(gui.reference.entry));
57 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, 0)); 57 menu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, 0));
58 menu.setEnabled(false); 58 menu.setEnabled(false);
59 this.add(menu); 59 this.add(menu);
diff --git a/src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java b/src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java
index 83418267..9f391f2e 100644
--- a/src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java
+++ b/src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java
@@ -37,6 +37,11 @@ public class ClassSelectorClassNode extends DefaultMutableTreeNode {
37 return other instanceof ClassSelectorClassNode && equals((ClassSelectorClassNode) other); 37 return other instanceof ClassSelectorClassNode && equals((ClassSelectorClassNode) other);
38 } 38 }
39 39
40 @Override public int hashCode()
41 {
42 return 17 + (classEntry != null ? classEntry.hashCode() : 0);
43 }
44
40 @Override public void setUserObject(Object userObject) 45 @Override public void setUserObject(Object userObject)
41 { 46 {
42 String packageName = ""; 47 String packageName = "";
diff --git a/src/main/java/cuchaz/enigma/gui/node/ClassSelectorPackageNode.java b/src/main/java/cuchaz/enigma/gui/node/ClassSelectorPackageNode.java
index 31b4ebfa..b3eb90ef 100644
--- a/src/main/java/cuchaz/enigma/gui/node/ClassSelectorPackageNode.java
+++ b/src/main/java/cuchaz/enigma/gui/node/ClassSelectorPackageNode.java
@@ -48,6 +48,11 @@ public class ClassSelectorPackageNode extends DefaultMutableTreeNode {
48 return other instanceof ClassSelectorPackageNode && equals((ClassSelectorPackageNode) other); 48 return other instanceof ClassSelectorPackageNode && equals((ClassSelectorPackageNode) other);
49 } 49 }
50 50
51 @Override public int hashCode()
52 {
53 return packageName.hashCode();
54 }
55
51 public boolean equals(ClassSelectorPackageNode other) { 56 public boolean equals(ClassSelectorPackageNode other) {
52 return other != null && this.packageName.equals(other.packageName); 57 return other != null && this.packageName.equals(other.packageName);
53 } 58 }
diff --git a/src/main/java/cuchaz/enigma/mapping/ClassMapping.java b/src/main/java/cuchaz/enigma/mapping/ClassMapping.java
index 8f893889..a261c912 100644
--- a/src/main/java/cuchaz/enigma/mapping/ClassMapping.java
+++ b/src/main/java/cuchaz/enigma/mapping/ClassMapping.java
@@ -20,19 +20,19 @@ import cuchaz.enigma.throwables.MappingConflict;
20// FIXME: Enigma doesn't support inner classes of inner class????! 20// FIXME: Enigma doesn't support inner classes of inner class????!
21public class ClassMapping implements Comparable<ClassMapping> { 21public class ClassMapping implements Comparable<ClassMapping> {
22 22
23 private String m_obfFullName; 23 private String obfFullName;
24 private String m_obfSimpleName; 24 private String obfSimpleName;
25 private String m_deobfName; 25 private String deobfName;
26 private String m_previousDeobfName; 26 private String previousDeobfName;
27 private Map<String, ClassMapping> m_innerClassesByObfSimple; 27 private Map<String, ClassMapping> innerClassesByObfSimple;
28 private Map<String, ClassMapping> m_innerClassesByObfFull; 28 private Map<String, ClassMapping> innerClassesByObfFull;
29 private Map<String, ClassMapping> m_innerClassesByDeobf; 29 private Map<String, ClassMapping> innerClassesByDeobf;
30 private Map<String, FieldMapping> m_fieldsByObf; 30 private Map<String, FieldMapping> fieldsByObf;
31 private Map<String, FieldMapping> m_fieldsByDeobf; 31 private Map<String, FieldMapping> fieldsByDeobf;
32 private Map<String, MethodMapping> m_methodsByObf; 32 private Map<String, MethodMapping> methodsByObf;
33 private Map<String, MethodMapping> m_methodsByDeobf; 33 private Map<String, MethodMapping> methodsByDeobf;
34 private boolean isDirty; 34 private boolean isDirty;
35 private Mappings.EntryModifier modifier; 35 private Mappings.EntryModifier modifier;
36 36
37 public ClassMapping(String obfFullName) 37 public ClassMapping(String obfFullName)
38 { 38 {
@@ -46,85 +46,85 @@ public class ClassMapping implements Comparable<ClassMapping> {
46 46
47 public ClassMapping(String obfFullName, String deobfName, Mappings.EntryModifier modifier) 47 public ClassMapping(String obfFullName, String deobfName, Mappings.EntryModifier modifier)
48 { 48 {
49 m_obfFullName = obfFullName; 49 this.obfFullName = obfFullName;
50 ClassEntry classEntry = new ClassEntry(obfFullName); 50 ClassEntry classEntry = new ClassEntry(obfFullName);
51 m_obfSimpleName = classEntry.isInnerClass() ? classEntry.getInnermostClassName() : classEntry.getSimpleName(); 51 obfSimpleName = classEntry.isInnerClass() ? classEntry.getInnermostClassName() : classEntry.getSimpleName();
52 m_previousDeobfName = null; 52 previousDeobfName = null;
53 m_deobfName = NameValidator.validateClassName(deobfName, false); 53 this.deobfName = NameValidator.validateClassName(deobfName, false);
54 m_innerClassesByObfSimple = Maps.newHashMap(); 54 innerClassesByObfSimple = Maps.newHashMap();
55 m_innerClassesByObfFull = Maps.newHashMap(); 55 innerClassesByObfFull = Maps.newHashMap();
56 m_innerClassesByDeobf = Maps.newHashMap(); 56 innerClassesByDeobf = Maps.newHashMap();
57 m_fieldsByObf = Maps.newHashMap(); 57 fieldsByObf = Maps.newHashMap();
58 m_fieldsByDeobf = Maps.newHashMap(); 58 fieldsByDeobf = Maps.newHashMap();
59 m_methodsByObf = Maps.newHashMap(); 59 methodsByObf = Maps.newHashMap();
60 m_methodsByDeobf = Maps.newHashMap(); 60 methodsByDeobf = Maps.newHashMap();
61 isDirty = true; 61 isDirty = true;
62 this.modifier = modifier; 62 this.modifier = modifier;
63 } 63 }
64 64
65 public String getObfFullName() { 65 public String getObfFullName() {
66 return m_obfFullName; 66 return obfFullName;
67 } 67 }
68 68
69 public String getObfSimpleName() { 69 public String getObfSimpleName() {
70 return m_obfSimpleName; 70 return obfSimpleName;
71 } 71 }
72 72
73 public String getPreviousDeobfName() { 73 public String getPreviousDeobfName() {
74 return m_previousDeobfName; 74 return previousDeobfName;
75 } 75 }
76 76
77 public String getDeobfName() { 77 public String getDeobfName() {
78 return m_deobfName; 78 return deobfName;
79 } 79 }
80 80
81 public void setDeobfName(String val) { 81 public void setDeobfName(String val) {
82 m_previousDeobfName = m_deobfName; 82 previousDeobfName = deobfName;
83 m_deobfName = NameValidator.validateClassName(val, false); 83 deobfName = NameValidator.validateClassName(val, false);
84 this.isDirty = true; 84 this.isDirty = true;
85 } 85 }
86 86
87 //// INNER CLASSES //////// 87 //// INNER CLASSES ////////
88 88
89 public Iterable<ClassMapping> innerClasses() { 89 public Iterable<ClassMapping> innerClasses() {
90 assert (m_innerClassesByObfSimple.size() >= m_innerClassesByDeobf.size()); 90 assert (innerClassesByObfSimple.size() >= innerClassesByDeobf.size());
91 return m_innerClassesByObfSimple.values(); 91 return innerClassesByObfSimple.values();
92 } 92 }
93 93
94 public void addInnerClassMapping(ClassMapping classMapping) throws MappingConflict { 94 public void addInnerClassMapping(ClassMapping classMapping) throws MappingConflict {
95 // FIXME: dirty hack, that can get into issues, but it's a temp fix! 95 // FIXME: dirty hack, that can get into issues, but it's a temp fix!
96 if (this.m_innerClassesByObfFull.containsKey(classMapping.getObfSimpleName())) { 96 if (this.innerClassesByObfFull.containsKey(classMapping.getObfSimpleName())) {
97 throw new MappingConflict("classes", classMapping.getObfSimpleName(), this.m_innerClassesByObfSimple.get(classMapping.getObfSimpleName()).getObfSimpleName()); 97 throw new MappingConflict("classes", classMapping.getObfSimpleName(), this.innerClassesByObfSimple.get(classMapping.getObfSimpleName()).getObfSimpleName());
98 } 98 }
99 m_innerClassesByObfFull.put(classMapping.getObfFullName(), classMapping); 99 innerClassesByObfFull.put(classMapping.getObfFullName(), classMapping);
100 m_innerClassesByObfSimple.put(classMapping.getObfSimpleName(), classMapping); 100 innerClassesByObfSimple.put(classMapping.getObfSimpleName(), classMapping);
101 101
102 if (classMapping.getDeobfName() != null) { 102 if (classMapping.getDeobfName() != null) {
103 if (this.m_innerClassesByDeobf.containsKey(classMapping.getDeobfName())) { 103 if (this.innerClassesByDeobf.containsKey(classMapping.getDeobfName())) {
104 throw new MappingConflict("classes", classMapping.getDeobfName(), this.m_innerClassesByDeobf.get(classMapping.getDeobfName()).getDeobfName()); 104 throw new MappingConflict("classes", classMapping.getDeobfName(), this.innerClassesByDeobf.get(classMapping.getDeobfName()).getDeobfName());
105 } 105 }
106 m_innerClassesByDeobf.put(classMapping.getDeobfName(), classMapping); 106 innerClassesByDeobf.put(classMapping.getDeobfName(), classMapping);
107 } 107 }
108 this.isDirty = true; 108 this.isDirty = true;
109 } 109 }
110 110
111 public void removeInnerClassMapping(ClassMapping classMapping) { 111 public void removeInnerClassMapping(ClassMapping classMapping) {
112 m_innerClassesByObfFull.remove(classMapping.getObfFullName()); 112 innerClassesByObfFull.remove(classMapping.getObfFullName());
113 boolean obfWasRemoved = m_innerClassesByObfSimple.remove(classMapping.getObfSimpleName()) != null; 113 boolean obfWasRemoved = innerClassesByObfSimple.remove(classMapping.getObfSimpleName()) != null;
114 assert (obfWasRemoved); 114 assert (obfWasRemoved);
115 if (classMapping.getDeobfName() != null) { 115 if (classMapping.getDeobfName() != null) {
116 boolean deobfWasRemoved = m_innerClassesByDeobf.remove(classMapping.getDeobfName()) != null; 116 boolean deobfWasRemoved = innerClassesByDeobf.remove(classMapping.getDeobfName()) != null;
117 assert (deobfWasRemoved); 117 assert (deobfWasRemoved);
118 } 118 }
119 this.isDirty = true; 119 this.isDirty = true;
120 } 120 }
121 121
122 public ClassMapping getOrCreateInnerClass(ClassEntry obfInnerClass) { 122 public ClassMapping getOrCreateInnerClass(ClassEntry obfInnerClass) {
123 ClassMapping classMapping = m_innerClassesByObfSimple.get(obfInnerClass.getInnermostClassName()); 123 ClassMapping classMapping = innerClassesByObfSimple.get(obfInnerClass.getInnermostClassName());
124 if (classMapping == null) { 124 if (classMapping == null) {
125 classMapping = new ClassMapping(obfInnerClass.getName()); 125 classMapping = new ClassMapping(obfInnerClass.getName());
126 m_innerClassesByObfFull.put(classMapping.getObfFullName(), classMapping); 126 innerClassesByObfFull.put(classMapping.getObfFullName(), classMapping);
127 boolean wasAdded = m_innerClassesByObfSimple.put(classMapping.getObfSimpleName(), classMapping) == null; 127 boolean wasAdded = innerClassesByObfSimple.put(classMapping.getObfSimpleName(), classMapping) == null;
128 assert (wasAdded); 128 assert (wasAdded);
129 this.isDirty = true; 129 this.isDirty = true;
130 } 130 }
@@ -133,12 +133,12 @@ public class ClassMapping implements Comparable<ClassMapping> {
133 133
134 public ClassMapping getInnerClassByObfSimple(String obfSimpleName) { 134 public ClassMapping getInnerClassByObfSimple(String obfSimpleName) {
135 assert (isSimpleClassName(obfSimpleName)); 135 assert (isSimpleClassName(obfSimpleName));
136 return m_innerClassesByObfSimple.get(obfSimpleName); 136 return innerClassesByObfSimple.get(obfSimpleName);
137 } 137 }
138 138
139 public ClassMapping getInnerClassByDeobf(String deobfName) { 139 public ClassMapping getInnerClassByDeobf(String deobfName) {
140 assert (isSimpleClassName(deobfName)); 140 assert (isSimpleClassName(deobfName));
141 return m_innerClassesByDeobf.get(deobfName); 141 return innerClassesByDeobf.get(deobfName);
142 } 142 }
143 143
144 public ClassMapping getInnerClassByDeobfThenObfSimple(String name) { 144 public ClassMapping getInnerClassByDeobfThenObfSimple(String name) {
@@ -151,7 +151,7 @@ public class ClassMapping implements Comparable<ClassMapping> {
151 151
152 public String getDeobfInnerClassName(String obfSimpleName) { 152 public String getDeobfInnerClassName(String obfSimpleName) {
153 assert (isSimpleClassName(obfSimpleName)); 153 assert (isSimpleClassName(obfSimpleName));
154 ClassMapping classMapping = m_innerClassesByObfSimple.get(obfSimpleName); 154 ClassMapping classMapping = innerClassesByObfSimple.get(obfSimpleName);
155 if (classMapping != null) { 155 if (classMapping != null) {
156 return classMapping.getDeobfName(); 156 return classMapping.getDeobfName();
157 } 157 }
@@ -161,80 +161,80 @@ public class ClassMapping implements Comparable<ClassMapping> {
161 public void setInnerClassName(ClassEntry obfInnerClass, String deobfName) { 161 public void setInnerClassName(ClassEntry obfInnerClass, String deobfName) {
162 ClassMapping classMapping = getOrCreateInnerClass(obfInnerClass); 162 ClassMapping classMapping = getOrCreateInnerClass(obfInnerClass);
163 if (classMapping.getDeobfName() != null) { 163 if (classMapping.getDeobfName() != null) {
164 boolean wasRemoved = m_innerClassesByDeobf.remove(classMapping.getDeobfName()) != null; 164 boolean wasRemoved = innerClassesByDeobf.remove(classMapping.getDeobfName()) != null;
165 assert (wasRemoved); 165 assert (wasRemoved);
166 } 166 }
167 classMapping.setDeobfName(deobfName); 167 classMapping.setDeobfName(deobfName);
168 if (deobfName != null) { 168 if (deobfName != null) {
169 assert (isSimpleClassName(deobfName)); 169 assert (isSimpleClassName(deobfName));
170 boolean wasAdded = m_innerClassesByDeobf.put(deobfName, classMapping) == null; 170 boolean wasAdded = innerClassesByDeobf.put(deobfName, classMapping) == null;
171 assert (wasAdded); 171 assert (wasAdded);
172 } 172 }
173 this.isDirty = true; 173 this.isDirty = true;
174 } 174 }
175 175
176 public boolean hasInnerClassByObfSimple(String obfSimpleName) { 176 public boolean hasInnerClassByObfSimple(String obfSimpleName) {
177 return m_innerClassesByObfSimple.containsKey(obfSimpleName); 177 return innerClassesByObfSimple.containsKey(obfSimpleName);
178 } 178 }
179 179
180 public boolean hasInnerClassByDeobf(String deobfName) { 180 public boolean hasInnerClassByDeobf(String deobfName) {
181 return m_innerClassesByDeobf.containsKey(deobfName); 181 return innerClassesByDeobf.containsKey(deobfName);
182 } 182 }
183 183
184 184
185 //// FIELDS //////// 185 //// FIELDS ////////
186 186
187 public Iterable<FieldMapping> fields() { 187 public Iterable<FieldMapping> fields() {
188 assert (m_fieldsByObf.size() == m_fieldsByDeobf.size()); 188 assert (fieldsByObf.size() == fieldsByDeobf.size());
189 return m_fieldsByObf.values(); 189 return fieldsByObf.values();
190 } 190 }
191 191
192 public boolean containsObfField(String obfName, Type obfType) { 192 public boolean containsObfField(String obfName, Type obfType) {
193 return m_fieldsByObf.containsKey(getFieldKey(obfName, obfType)); 193 return fieldsByObf.containsKey(getFieldKey(obfName, obfType));
194 } 194 }
195 195
196 public boolean containsDeobfField(String deobfName, Type deobfType) { 196 public boolean containsDeobfField(String deobfName, Type deobfType) {
197 return m_fieldsByDeobf.containsKey(getFieldKey(deobfName, deobfType)); 197 return fieldsByDeobf.containsKey(getFieldKey(deobfName, deobfType));
198 } 198 }
199 199
200 public void addFieldMapping(FieldMapping fieldMapping) { 200 public void addFieldMapping(FieldMapping fieldMapping) {
201 String obfKey = getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfType()); 201 String obfKey = getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfType());
202 if (m_fieldsByObf.containsKey(obfKey)) { 202 if (fieldsByObf.containsKey(obfKey)) {
203 throw new Error("Already have mapping for " + m_obfFullName + "." + obfKey); 203 throw new Error("Already have mapping for " + obfFullName + "." + obfKey);
204 } 204 }
205 if (fieldMapping.getDeobfName() != null) { 205 if (fieldMapping.getDeobfName() != null) {
206 String deobfKey = getFieldKey(fieldMapping.getDeobfName(), fieldMapping.getObfType()); 206 String deobfKey = getFieldKey(fieldMapping.getDeobfName(), fieldMapping.getObfType());
207 if (m_fieldsByDeobf.containsKey(deobfKey)) { 207 if (fieldsByDeobf.containsKey(deobfKey)) {
208 throw new Error("Already have mapping for " + m_deobfName + "." + deobfKey); 208 throw new Error("Already have mapping for " + deobfName + "." + deobfKey);
209 } 209 }
210 boolean deobfWasAdded = m_fieldsByDeobf.put(deobfKey, fieldMapping) == null; 210 boolean deobfWasAdded = fieldsByDeobf.put(deobfKey, fieldMapping) == null;
211 assert (deobfWasAdded); 211 assert (deobfWasAdded);
212 } 212 }
213 boolean obfWasAdded = m_fieldsByObf.put(obfKey, fieldMapping) == null; 213 boolean obfWasAdded = fieldsByObf.put(obfKey, fieldMapping) == null;
214 assert (obfWasAdded); 214 assert (obfWasAdded);
215 this.isDirty = true; 215 this.isDirty = true;
216 } 216 }
217 217
218 public void removeFieldMapping(FieldMapping fieldMapping) { 218 public void removeFieldMapping(FieldMapping fieldMapping) {
219 boolean obfWasRemoved = m_fieldsByObf.remove(getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfType())) != null; 219 boolean obfWasRemoved = fieldsByObf.remove(getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfType())) != null;
220 assert (obfWasRemoved); 220 assert (obfWasRemoved);
221 if (fieldMapping.getDeobfName() != null) { 221 if (fieldMapping.getDeobfName() != null) {
222 boolean deobfWasRemoved = m_fieldsByDeobf.remove(getFieldKey(fieldMapping.getDeobfName(), fieldMapping.getObfType())) != null; 222 boolean deobfWasRemoved = fieldsByDeobf.remove(getFieldKey(fieldMapping.getDeobfName(), fieldMapping.getObfType())) != null;
223 assert (deobfWasRemoved); 223 assert (deobfWasRemoved);
224 } 224 }
225 this.isDirty = true; 225 this.isDirty = true;
226 } 226 }
227 227
228 public FieldMapping getFieldByObf(String obfName, Type obfType) { 228 public FieldMapping getFieldByObf(String obfName, Type obfType) {
229 return m_fieldsByObf.get(getFieldKey(obfName, obfType)); 229 return fieldsByObf.get(getFieldKey(obfName, obfType));
230 } 230 }
231 231
232 public FieldMapping getFieldByDeobf(String deobfName, Type obfType) { 232 public FieldMapping getFieldByDeobf(String deobfName, Type obfType) {
233 return m_fieldsByDeobf.get(getFieldKey(deobfName, obfType)); 233 return fieldsByDeobf.get(getFieldKey(deobfName, obfType));
234 } 234 }
235 235
236 public String getObfFieldName(String deobfName, Type obfType) { 236 public String getObfFieldName(String deobfName, Type obfType) {
237 FieldMapping fieldMapping = m_fieldsByDeobf.get(getFieldKey(deobfName, obfType)); 237 FieldMapping fieldMapping = fieldsByDeobf.get(getFieldKey(deobfName, obfType));
238 if (fieldMapping != null) { 238 if (fieldMapping != null) {
239 return fieldMapping.getObfName(); 239 return fieldMapping.getObfName();
240 } 240 }
@@ -242,7 +242,7 @@ public class ClassMapping implements Comparable<ClassMapping> {
242 } 242 }
243 243
244 public String getDeobfFieldName(String obfName, Type obfType) { 244 public String getDeobfFieldName(String obfName, Type obfType) {
245 FieldMapping fieldMapping = m_fieldsByObf.get(getFieldKey(obfName, obfType)); 245 FieldMapping fieldMapping = fieldsByObf.get(getFieldKey(obfName, obfType));
246 if (fieldMapping != null) { 246 if (fieldMapping != null) {
247 return fieldMapping.getDeobfName(); 247 return fieldMapping.getDeobfName();
248 } 248 }
@@ -261,18 +261,18 @@ public class ClassMapping implements Comparable<ClassMapping> {
261 261
262 public void setFieldName(String obfName, Type obfType, String deobfName) { 262 public void setFieldName(String obfName, Type obfType, String deobfName) {
263 assert (deobfName != null); 263 assert (deobfName != null);
264 FieldMapping fieldMapping = m_fieldsByObf.get(getFieldKey(obfName, obfType)); 264 FieldMapping fieldMapping = fieldsByObf.get(getFieldKey(obfName, obfType));
265 if (fieldMapping == null) { 265 if (fieldMapping == null) {
266 fieldMapping = new FieldMapping(obfName, obfType, deobfName, Mappings.EntryModifier.UNCHANGED); 266 fieldMapping = new FieldMapping(obfName, obfType, deobfName, Mappings.EntryModifier.UNCHANGED);
267 boolean obfWasAdded = m_fieldsByObf.put(getFieldKey(obfName, obfType), fieldMapping) == null; 267 boolean obfWasAdded = fieldsByObf.put(getFieldKey(obfName, obfType), fieldMapping) == null;
268 assert (obfWasAdded); 268 assert (obfWasAdded);
269 } else { 269 } else {
270 boolean wasRemoved = m_fieldsByDeobf.remove(getFieldKey(fieldMapping.getDeobfName(), obfType)) != null; 270 boolean wasRemoved = fieldsByDeobf.remove(getFieldKey(fieldMapping.getDeobfName(), obfType)) != null;
271 assert (wasRemoved); 271 assert (wasRemoved);
272 } 272 }
273 fieldMapping.setDeobfName(deobfName); 273 fieldMapping.setDeobfName(deobfName);
274 if (deobfName != null) { 274 if (deobfName != null) {
275 boolean wasAdded = m_fieldsByDeobf.put(getFieldKey(deobfName, obfType), fieldMapping) == null; 275 boolean wasAdded = fieldsByDeobf.put(getFieldKey(deobfName, obfType), fieldMapping) == null;
276 assert (wasAdded); 276 assert (wasAdded);
277 } 277 }
278 this.isDirty = true; 278 this.isDirty = true;
@@ -280,11 +280,11 @@ public class ClassMapping implements Comparable<ClassMapping> {
280 280
281 public void setFieldObfNameAndType(String oldObfName, Type obfType, String newObfName, Type newObfType) { 281 public void setFieldObfNameAndType(String oldObfName, Type obfType, String newObfName, Type newObfType) {
282 assert(newObfName != null); 282 assert(newObfName != null);
283 FieldMapping fieldMapping = m_fieldsByObf.remove(getFieldKey(oldObfName, obfType)); 283 FieldMapping fieldMapping = fieldsByObf.remove(getFieldKey(oldObfName, obfType));
284 assert(fieldMapping != null); 284 assert(fieldMapping != null);
285 fieldMapping.setObfName(newObfName); 285 fieldMapping.setObfName(newObfName);
286 fieldMapping.setObfType(newObfType); 286 fieldMapping.setObfType(newObfType);
287 boolean obfWasAdded = m_fieldsByObf.put(getFieldKey(newObfName, newObfType), fieldMapping) == null; 287 boolean obfWasAdded = fieldsByObf.put(getFieldKey(newObfName, newObfType), fieldMapping) == null;
288 assert(obfWasAdded); 288 assert(obfWasAdded);
289 this.isDirty = true; 289 this.isDirty = true;
290 } 290 }
@@ -292,53 +292,53 @@ public class ClassMapping implements Comparable<ClassMapping> {
292 //// METHODS //////// 292 //// METHODS ////////
293 293
294 public Iterable<MethodMapping> methods() { 294 public Iterable<MethodMapping> methods() {
295 assert (m_methodsByObf.size() >= m_methodsByDeobf.size()); 295 assert (methodsByObf.size() >= methodsByDeobf.size());
296 return m_methodsByObf.values(); 296 return methodsByObf.values();
297 } 297 }
298 298
299 public boolean containsObfMethod(String obfName, Signature obfSignature) { 299 public boolean containsObfMethod(String obfName, Signature obfSignature) {
300 return m_methodsByObf.containsKey(getMethodKey(obfName, obfSignature)); 300 return methodsByObf.containsKey(getMethodKey(obfName, obfSignature));
301 } 301 }
302 302
303 public boolean containsDeobfMethod(String deobfName, Signature obfSignature) { 303 public boolean containsDeobfMethod(String deobfName, Signature obfSignature) {
304 return m_methodsByDeobf.containsKey(getMethodKey(deobfName, obfSignature)); 304 return methodsByDeobf.containsKey(getMethodKey(deobfName, obfSignature));
305 } 305 }
306 306
307 public void addMethodMapping(MethodMapping methodMapping) { 307 public void addMethodMapping(MethodMapping methodMapping) {
308 String obfKey = getMethodKey(methodMapping.getObfName(), methodMapping.getObfSignature()); 308 String obfKey = getMethodKey(methodMapping.getObfName(), methodMapping.getObfSignature());
309 if (m_methodsByObf.containsKey(obfKey)) { 309 if (methodsByObf.containsKey(obfKey)) {
310 throw new Error("Already have mapping for " + m_obfFullName + "." + obfKey); 310 throw new Error("Already have mapping for " + obfFullName + "." + obfKey);
311 } 311 }
312 boolean wasAdded = m_methodsByObf.put(obfKey, methodMapping) == null; 312 boolean wasAdded = methodsByObf.put(obfKey, methodMapping) == null;
313 assert (wasAdded); 313 assert (wasAdded);
314 if (methodMapping.getDeobfName() != null) { 314 if (methodMapping.getDeobfName() != null) {
315 String deobfKey = getMethodKey(methodMapping.getDeobfName(), methodMapping.getObfSignature()); 315 String deobfKey = getMethodKey(methodMapping.getDeobfName(), methodMapping.getObfSignature());
316 if (m_methodsByDeobf.containsKey(deobfKey)) { 316 if (methodsByDeobf.containsKey(deobfKey)) {
317 throw new Error("Already have mapping for " + m_deobfName + "." + deobfKey); 317 throw new Error("Already have mapping for " + deobfName + "." + deobfKey);
318 } 318 }
319 boolean deobfWasAdded = m_methodsByDeobf.put(deobfKey, methodMapping) == null; 319 boolean deobfWasAdded = methodsByDeobf.put(deobfKey, methodMapping) == null;
320 assert (deobfWasAdded); 320 assert (deobfWasAdded);
321 } 321 }
322 this.isDirty = true; 322 this.isDirty = true;
323 assert (m_methodsByObf.size() >= m_methodsByDeobf.size()); 323 assert (methodsByObf.size() >= methodsByDeobf.size());
324 } 324 }
325 325
326 public void removeMethodMapping(MethodMapping methodMapping) { 326 public void removeMethodMapping(MethodMapping methodMapping) {
327 boolean obfWasRemoved = m_methodsByObf.remove(getMethodKey(methodMapping.getObfName(), methodMapping.getObfSignature())) != null; 327 boolean obfWasRemoved = methodsByObf.remove(getMethodKey(methodMapping.getObfName(), methodMapping.getObfSignature())) != null;
328 assert (obfWasRemoved); 328 assert (obfWasRemoved);
329 if (methodMapping.getDeobfName() != null) { 329 if (methodMapping.getDeobfName() != null) {
330 boolean deobfWasRemoved = m_methodsByDeobf.remove(getMethodKey(methodMapping.getDeobfName(), methodMapping.getObfSignature())) != null; 330 boolean deobfWasRemoved = methodsByDeobf.remove(getMethodKey(methodMapping.getDeobfName(), methodMapping.getObfSignature())) != null;
331 assert (deobfWasRemoved); 331 assert (deobfWasRemoved);
332 } 332 }
333 this.isDirty = true; 333 this.isDirty = true;
334 } 334 }
335 335
336 public MethodMapping getMethodByObf(String obfName, Signature obfSignature) { 336 public MethodMapping getMethodByObf(String obfName, Signature obfSignature) {
337 return m_methodsByObf.get(getMethodKey(obfName, obfSignature)); 337 return methodsByObf.get(getMethodKey(obfName, obfSignature));
338 } 338 }
339 339
340 public MethodMapping getMethodByDeobf(String deobfName, Signature obfSignature) { 340 public MethodMapping getMethodByDeobf(String deobfName, Signature obfSignature) {
341 return m_methodsByDeobf.get(getMethodKey(deobfName, obfSignature)); 341 return methodsByDeobf.get(getMethodKey(deobfName, obfSignature));
342 } 342 }
343 343
344 private String getMethodKey(String name, Signature signature) { 344 private String getMethodKey(String name, Signature signature) {
@@ -352,16 +352,16 @@ public class ClassMapping implements Comparable<ClassMapping> {
352 } 352 }
353 353
354 public void setMethodName(String obfName, Signature obfSignature, String deobfName) { 354 public void setMethodName(String obfName, Signature obfSignature, String deobfName) {
355 MethodMapping methodMapping = m_methodsByObf.get(getMethodKey(obfName, obfSignature)); 355 MethodMapping methodMapping = methodsByObf.get(getMethodKey(obfName, obfSignature));
356 if (methodMapping == null) { 356 if (methodMapping == null) {
357 methodMapping = createMethodMapping(obfName, obfSignature); 357 methodMapping = createMethodMapping(obfName, obfSignature);
358 } else if (methodMapping.getDeobfName() != null) { 358 } else if (methodMapping.getDeobfName() != null) {
359 boolean wasRemoved = m_methodsByDeobf.remove(getMethodKey(methodMapping.getDeobfName(), methodMapping.getObfSignature())) != null; 359 boolean wasRemoved = methodsByDeobf.remove(getMethodKey(methodMapping.getDeobfName(), methodMapping.getObfSignature())) != null;
360 assert (wasRemoved); 360 assert (wasRemoved);
361 } 361 }
362 methodMapping.setDeobfName(deobfName); 362 methodMapping.setDeobfName(deobfName);
363 if (deobfName != null) { 363 if (deobfName != null) {
364 boolean wasAdded = m_methodsByDeobf.put(getMethodKey(deobfName, obfSignature), methodMapping) == null; 364 boolean wasAdded = methodsByDeobf.put(getMethodKey(deobfName, obfSignature), methodMapping) == null;
365 assert (wasAdded); 365 assert (wasAdded);
366 } 366 }
367 this.isDirty = true; 367 this.isDirty = true;
@@ -369,11 +369,11 @@ public class ClassMapping implements Comparable<ClassMapping> {
369 369
370 public void setMethodObfNameAndSignature(String oldObfName, Signature obfSignature, String newObfName, Signature newObfSignature) { 370 public void setMethodObfNameAndSignature(String oldObfName, Signature obfSignature, String newObfName, Signature newObfSignature) {
371 assert(newObfName != null); 371 assert(newObfName != null);
372 MethodMapping methodMapping = m_methodsByObf.remove(getMethodKey(oldObfName, obfSignature)); 372 MethodMapping methodMapping = methodsByObf.remove(getMethodKey(oldObfName, obfSignature));
373 assert(methodMapping != null); 373 assert(methodMapping != null);
374 methodMapping.setObfName(newObfName); 374 methodMapping.setObfName(newObfName);
375 methodMapping.setObfSignature(newObfSignature); 375 methodMapping.setObfSignature(newObfSignature);
376 boolean obfWasAdded = m_methodsByObf.put(getMethodKey(newObfName, newObfSignature), methodMapping) == null; 376 boolean obfWasAdded = methodsByObf.put(getMethodKey(newObfName, newObfSignature), methodMapping) == null;
377 assert(obfWasAdded); 377 assert(obfWasAdded);
378 this.isDirty = true; 378 this.isDirty = true;
379 } 379 }
@@ -382,7 +382,7 @@ public class ClassMapping implements Comparable<ClassMapping> {
382 382
383 public void setArgumentName(String obfMethodName, Signature obfMethodSignature, int argumentIndex, String argumentName) { 383 public void setArgumentName(String obfMethodName, Signature obfMethodSignature, int argumentIndex, String argumentName) {
384 assert (argumentName != null); 384 assert (argumentName != null);
385 MethodMapping methodMapping = m_methodsByObf.get(getMethodKey(obfMethodName, obfMethodSignature)); 385 MethodMapping methodMapping = methodsByObf.get(getMethodKey(obfMethodName, obfMethodSignature));
386 if (methodMapping == null) { 386 if (methodMapping == null) {
387 methodMapping = createMethodMapping(obfMethodName, obfMethodSignature); 387 methodMapping = createMethodMapping(obfMethodName, obfMethodSignature);
388 } 388 }
@@ -391,13 +391,13 @@ public class ClassMapping implements Comparable<ClassMapping> {
391 } 391 }
392 392
393 public void removeArgumentName(String obfMethodName, Signature obfMethodSignature, int argumentIndex) { 393 public void removeArgumentName(String obfMethodName, Signature obfMethodSignature, int argumentIndex) {
394 m_methodsByObf.get(getMethodKey(obfMethodName, obfMethodSignature)).removeArgumentName(argumentIndex); 394 methodsByObf.get(getMethodKey(obfMethodName, obfMethodSignature)).removeArgumentName(argumentIndex);
395 this.isDirty = true; 395 this.isDirty = true;
396 } 396 }
397 397
398 private MethodMapping createMethodMapping(String obfName, Signature obfSignature) { 398 private MethodMapping createMethodMapping(String obfName, Signature obfSignature) {
399 MethodMapping methodMapping = new MethodMapping(obfName, obfSignature); 399 MethodMapping methodMapping = new MethodMapping(obfName, obfSignature);
400 boolean wasAdded = m_methodsByObf.put(getMethodKey(obfName, obfSignature), methodMapping) == null; 400 boolean wasAdded = methodsByObf.put(getMethodKey(obfName, obfSignature), methodMapping) == null;
401 assert (wasAdded); 401 assert (wasAdded);
402 this.isDirty = true; 402 this.isDirty = true;
403 return methodMapping; 403 return methodMapping;
@@ -406,9 +406,9 @@ public class ClassMapping implements Comparable<ClassMapping> {
406 @Override 406 @Override
407 public String toString() { 407 public String toString() {
408 StringBuilder buf = new StringBuilder(); 408 StringBuilder buf = new StringBuilder();
409 buf.append(m_obfFullName); 409 buf.append(obfFullName);
410 buf.append(" <-> "); 410 buf.append(" <-> ");
411 buf.append(m_deobfName); 411 buf.append(deobfName);
412 buf.append("\n"); 412 buf.append("\n");
413 buf.append("Fields:\n"); 413 buf.append("Fields:\n");
414 for (FieldMapping fieldMapping : fields()) { 414 for (FieldMapping fieldMapping : fields()) {
@@ -419,12 +419,12 @@ public class ClassMapping implements Comparable<ClassMapping> {
419 buf.append("\n"); 419 buf.append("\n");
420 } 420 }
421 buf.append("Methods:\n"); 421 buf.append("Methods:\n");
422 for (MethodMapping methodMapping : m_methodsByObf.values()) { 422 for (MethodMapping methodMapping : methodsByObf.values()) {
423 buf.append(methodMapping.toString()); 423 buf.append(methodMapping.toString());
424 buf.append("\n"); 424 buf.append("\n");
425 } 425 }
426 buf.append("Inner Classes:\n"); 426 buf.append("Inner Classes:\n");
427 for (ClassMapping classMapping : m_innerClassesByObfSimple.values()) { 427 for (ClassMapping classMapping : innerClassesByObfSimple.values()) {
428 buf.append("\t"); 428 buf.append("\t");
429 buf.append(classMapping.getObfSimpleName()); 429 buf.append(classMapping.getObfSimpleName());
430 buf.append(" <-> "); 430 buf.append(" <-> ");
@@ -437,49 +437,51 @@ public class ClassMapping implements Comparable<ClassMapping> {
437 @Override 437 @Override
438 public int compareTo(ClassMapping other) { 438 public int compareTo(ClassMapping other) {
439 // sort by a, b, c, ... aa, ab, etc 439 // sort by a, b, c, ... aa, ab, etc
440 if (m_obfFullName.length() != other.m_obfFullName.length()) { 440 if (obfFullName.length() != other.obfFullName.length()) {
441 return m_obfFullName.length() - other.m_obfFullName.length(); 441 return obfFullName.length() - other.obfFullName.length();
442 } 442 }
443 return m_obfFullName.compareTo(other.m_obfFullName); 443 return obfFullName.compareTo(other.obfFullName);
444 } 444 }
445 445
446 public boolean renameObfClass(String oldObfClassName, String newObfClassName) { 446 public boolean renameObfClass(String oldObfClassName, String newObfClassName) {
447 447
448 // rename inner classes 448 // rename inner classes
449 for (ClassMapping innerClassMapping : new ArrayList<>(m_innerClassesByObfSimple.values())) { 449 for (ClassMapping innerClassMapping : new ArrayList<>(innerClassesByObfSimple.values())) {
450 if (innerClassMapping.renameObfClass(oldObfClassName, newObfClassName)) { 450 if (innerClassMapping.renameObfClass(oldObfClassName, newObfClassName)) {
451 boolean wasRemoved = m_innerClassesByObfSimple.remove(oldObfClassName) != null; 451 boolean wasRemoved = innerClassesByObfSimple.remove(oldObfClassName) != null;
452 assert (wasRemoved); 452 assert (wasRemoved);
453 boolean wasAdded = m_innerClassesByObfSimple.put(newObfClassName, innerClassMapping) == null; 453 boolean wasAdded = innerClassesByObfSimple.put(newObfClassName, innerClassMapping) == null;
454 assert (wasAdded); 454 assert (wasAdded);
455 } 455 }
456 } 456 }
457 457
458 // rename field types 458 // rename field types
459 for (FieldMapping fieldMapping : new ArrayList<>(m_fieldsByObf.values())) { 459 for (FieldMapping fieldMapping : new ArrayList<>(fieldsByObf.values())) {
460 String oldFieldKey = getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfType()); 460 String oldFieldKey = getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfType());
461 if (fieldMapping.renameObfClass(oldObfClassName, newObfClassName)) { 461 if (fieldMapping.renameObfClass(oldObfClassName, newObfClassName)) {
462 boolean wasRemoved = m_fieldsByObf.remove(oldFieldKey) != null; 462 boolean wasRemoved = fieldsByObf.remove(oldFieldKey) != null;
463 assert (wasRemoved); 463 assert (wasRemoved);
464 boolean wasAdded = m_fieldsByObf.put(getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfType()), fieldMapping) == null; 464 boolean wasAdded = fieldsByObf
465 .put(getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfType()), fieldMapping) == null;
465 assert (wasAdded); 466 assert (wasAdded);
466 } 467 }
467 } 468 }
468 469
469 // rename method signatures 470 // rename method signatures
470 for (MethodMapping methodMapping : new ArrayList<>(m_methodsByObf.values())) { 471 for (MethodMapping methodMapping : new ArrayList<>(methodsByObf.values())) {
471 String oldMethodKey = getMethodKey(methodMapping.getObfName(), methodMapping.getObfSignature()); 472 String oldMethodKey = getMethodKey(methodMapping.getObfName(), methodMapping.getObfSignature());
472 if (methodMapping.renameObfClass(oldObfClassName, newObfClassName)) { 473 if (methodMapping.renameObfClass(oldObfClassName, newObfClassName)) {
473 boolean wasRemoved = m_methodsByObf.remove(oldMethodKey) != null; 474 boolean wasRemoved = methodsByObf.remove(oldMethodKey) != null;
474 assert (wasRemoved); 475 assert (wasRemoved);
475 boolean wasAdded = m_methodsByObf.put(getMethodKey(methodMapping.getObfName(), methodMapping.getObfSignature()), methodMapping) == null; 476 boolean wasAdded = methodsByObf
477 .put(getMethodKey(methodMapping.getObfName(), methodMapping.getObfSignature()), methodMapping) == null;
476 assert (wasAdded); 478 assert (wasAdded);
477 } 479 }
478 } 480 }
479 481
480 if (m_obfFullName.equals(oldObfClassName)) { 482 if (obfFullName.equals(oldObfClassName)) {
481 // rename this class 483 // rename this class
482 m_obfFullName = newObfClassName; 484 obfFullName = newObfClassName;
483 return true; 485 return true;
484 } 486 }
485 this.isDirty = true; 487 this.isDirty = true;
@@ -487,7 +489,7 @@ public class ClassMapping implements Comparable<ClassMapping> {
487 } 489 }
488 490
489 public boolean containsArgument(BehaviorEntry obfBehaviorEntry, String name) { 491 public boolean containsArgument(BehaviorEntry obfBehaviorEntry, String name) {
490 MethodMapping methodMapping = m_methodsByObf.get(getMethodKey(obfBehaviorEntry.getName(), obfBehaviorEntry.getSignature())); 492 MethodMapping methodMapping = methodsByObf.get(getMethodKey(obfBehaviorEntry.getName(), obfBehaviorEntry.getSignature()));
491 return methodMapping != null && methodMapping.containsArgument(name); 493 return methodMapping != null && methodMapping.containsArgument(name);
492 } 494 }
493 495
@@ -496,7 +498,7 @@ public class ClassMapping implements Comparable<ClassMapping> {
496 } 498 }
497 499
498 public ClassEntry getObfEntry() { 500 public ClassEntry getObfEntry() {
499 return new ClassEntry(m_obfFullName); 501 return new ClassEntry(obfFullName);
500 } 502 }
501 503
502 public boolean isDirty() 504 public boolean isDirty()
@@ -522,11 +524,8 @@ public class ClassMapping implements Comparable<ClassMapping> {
522 } 524 }
523 525
524 public void setFieldModifier(String obfName, Type obfType, Mappings.EntryModifier modifier) { 526 public void setFieldModifier(String obfName, Type obfType, Mappings.EntryModifier modifier) {
525 FieldMapping fieldMapping = m_fieldsByObf.get(getFieldKey(obfName, obfType)); 527 FieldMapping fieldMapping = fieldsByObf.computeIfAbsent(getFieldKey(obfName, obfType),
526 if (fieldMapping == null) { 528 k -> new FieldMapping(obfName, obfType, null, Mappings.EntryModifier.UNCHANGED));
527 fieldMapping = new FieldMapping(obfName, obfType, null, Mappings.EntryModifier.UNCHANGED);
528 m_fieldsByObf.put(getFieldKey(obfName, obfType), fieldMapping);
529 }
530 529
531 if (fieldMapping.getModifier() != modifier) 530 if (fieldMapping.getModifier() != modifier)
532 { 531 {
@@ -536,11 +535,8 @@ public class ClassMapping implements Comparable<ClassMapping> {
536 } 535 }
537 536
538 public void setMethodModifier(String obfName, Signature sig, Mappings.EntryModifier modifier) { 537 public void setMethodModifier(String obfName, Signature sig, Mappings.EntryModifier modifier) {
539 MethodMapping methodMapping = m_methodsByObf.get(getMethodKey(obfName, sig)); 538 MethodMapping methodMapping = methodsByObf.computeIfAbsent(getMethodKey(obfName, sig),
540 if (methodMapping == null) { 539 k -> new MethodMapping(obfName, sig, null, Mappings.EntryModifier.UNCHANGED));
541 methodMapping = new MethodMapping(obfName, sig, null, Mappings.EntryModifier.UNCHANGED);
542 m_methodsByObf.put(getMethodKey(obfName, sig), methodMapping);
543 }
544 540
545 if (methodMapping.getModifier() != modifier) 541 if (methodMapping.getModifier() != modifier)
546 { 542 {
diff --git a/src/main/java/cuchaz/enigma/mapping/FieldMapping.java b/src/main/java/cuchaz/enigma/mapping/FieldMapping.java
index 83e22779..22ba307e 100644
--- a/src/main/java/cuchaz/enigma/mapping/FieldMapping.java
+++ b/src/main/java/cuchaz/enigma/mapping/FieldMapping.java
@@ -92,14 +92,12 @@ public class FieldMapping implements Comparable<FieldMapping>, MemberMapping<Fie
92 92
93 public boolean renameObfClass(final String oldObfClassName, final String newObfClassName) { 93 public boolean renameObfClass(final String oldObfClassName, final String newObfClassName) {
94 // rename obf classes in the type 94 // rename obf classes in the type
95 Type newType = new Type(this.obfType, new ClassNameReplacer() { 95 Type newType = new Type(this.obfType, className ->
96 @Override 96 {
97 public String replace(String className) { 97 if (className.equals(oldObfClassName)) {
98 if (className.equals(oldObfClassName)) { 98 return newObfClassName;
99 return newObfClassName;
100 }
101 return null;
102 } 99 }
100 return null;
103 }); 101 });
104 102
105 if (!newType.equals(this.obfType)) { 103 if (!newType.equals(this.obfType)) {
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java
index c09f4a67..6c57200f 100644
--- a/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java
+++ b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java
@@ -131,7 +131,7 @@ public class MappingsEnigmaWriter {
131 } 131 }
132 } 132 }
133 133
134 private void write(PrintWriter out, FieldMapping fieldMapping, int depth) throws IOException { 134 private void write(PrintWriter out, FieldMapping fieldMapping, int depth) {
135 if (fieldMapping.getDeobfName() == null) 135 if (fieldMapping.getDeobfName() == null)
136 out.format("%sFIELD %s %s%s\n", getIndent(depth), fieldMapping.getObfName(), fieldMapping.getObfType().toString(), fieldMapping.getModifier() == Mappings.EntryModifier.UNCHANGED ? "" : fieldMapping.getModifier().getFormattedName()); 136 out.format("%sFIELD %s %s%s\n", getIndent(depth), fieldMapping.getObfName(), fieldMapping.getObfType().toString(), fieldMapping.getModifier() == Mappings.EntryModifier.UNCHANGED ? "" : fieldMapping.getModifier().getFormattedName());
137 else 137 else
@@ -150,12 +150,12 @@ public class MappingsEnigmaWriter {
150 } 150 }
151 } 151 }
152 152
153 private void write(PrintWriter out, ArgumentMapping argumentMapping, int depth) throws IOException { 153 private void write(PrintWriter out, ArgumentMapping argumentMapping, int depth) {
154 out.format("%sARG %d %s\n", getIndent(depth), argumentMapping.getIndex(), argumentMapping.getName()); 154 out.format("%sARG %d %s\n", getIndent(depth), argumentMapping.getIndex(), argumentMapping.getName());
155 } 155 }
156 156
157 private <T extends Comparable<T>> List<T> sorted(Iterable<T> classes) { 157 private <T extends Comparable<T>> List<T> sorted(Iterable<T> classes) {
158 List<T> out = new ArrayList<T>(); 158 List<T> out = new ArrayList<>();
159 for (T t : classes) { 159 for (T t : classes) {
160 out.add(t); 160 out.add(t);
161 } 161 }
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java b/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java
index bac62503..e1428ea0 100644
--- a/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java
+++ b/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java
@@ -13,30 +13,28 @@ package cuchaz.enigma.mapping;
13import java.io.IOException; 13import java.io.IOException;
14import java.io.ObjectOutputStream; 14import java.io.ObjectOutputStream;
15import java.io.OutputStream; 15import java.io.OutputStream;
16import java.io.Serializable;
17import java.util.List; 16import java.util.List;
18import java.util.Set; 17import java.util.Set;
19import java.util.zip.GZIPOutputStream; 18import java.util.zip.GZIPOutputStream;
20 19
21import com.google.common.collect.Lists; 20import com.google.common.collect.Lists;
22import cuchaz.enigma.analysis.JarIndex; 21import cuchaz.enigma.analysis.JarIndex;
23import cuchaz.enigma.analysis.MethodImplementationsTreeNode;
24import cuchaz.enigma.throwables.IllegalNameException; 22import cuchaz.enigma.throwables.IllegalNameException;
25import cuchaz.enigma.throwables.MappingConflict; 23import cuchaz.enigma.throwables.MappingConflict;
26 24
27public class MappingsRenamer { 25public class MappingsRenamer {
28 26
29 private JarIndex m_index; 27 private JarIndex index;
30 private Mappings m_mappings; 28 private Mappings mappings;
31 29
32 public MappingsRenamer(JarIndex index, Mappings mappings) { 30 public MappingsRenamer(JarIndex index, Mappings mappings) {
33 m_index = index; 31 this.index = index;
34 m_mappings = mappings; 32 this.mappings = mappings;
35 } 33 }
36 34
37 public void setMappings(Mappings mappings) 35 public void setMappings(Mappings mappings)
38 { 36 {
39 this.m_mappings = mappings; 37 this.mappings = mappings;
40 } 38 }
41 39
42 public void setClassName(ClassEntry obf, String deobfName) { 40 public void setClassName(ClassEntry obf, String deobfName) {
@@ -48,13 +46,13 @@ public class MappingsRenamer {
48 46
49 if (deobfName != null) { 47 if (deobfName != null) {
50 // make sure we don't rename to an existing obf or deobf class 48 // make sure we don't rename to an existing obf or deobf class
51 if (m_mappings.containsDeobfClass(deobfName) || m_index.containsObfClass(new ClassEntry(deobfName))) { 49 if (mappings.containsDeobfClass(deobfName) || index.containsObfClass(new ClassEntry(deobfName))) {
52 throw new IllegalNameException(deobfName, "There is already a class with that name"); 50 throw new IllegalNameException(deobfName, "There is already a class with that name");
53 } 51 }
54 } 52 }
55 53
56 ClassMapping classMapping = mappingChain.get(0); 54 ClassMapping classMapping = mappingChain.get(0);
57 m_mappings.setClassDeobfName(classMapping, deobfName); 55 mappings.setClassDeobfName(classMapping, deobfName);
58 56
59 } else { 57 } else {
60 58
@@ -80,7 +78,7 @@ public class MappingsRenamer {
80 List<ClassMapping> mappingChain = getOrCreateClassMappingChain(obf); 78 List<ClassMapping> mappingChain = getOrCreateClassMappingChain(obf);
81 if (mappingChain.size() == 1) { 79 if (mappingChain.size() == 1) {
82 ClassMapping classMapping = mappingChain.get(0); 80 ClassMapping classMapping = mappingChain.get(0);
83 m_mappings.setClassDeobfName(classMapping, deobfName); 81 mappings.setClassDeobfName(classMapping, deobfName);
84 } else { 82 } else {
85 ClassMapping outerClassMapping = mappingChain.get(mappingChain.size() - 2); 83 ClassMapping outerClassMapping = mappingChain.get(mappingChain.size() - 2);
86 outerClassMapping.setInnerClassName(obf, deobfName); 84 outerClassMapping.setInnerClassName(obf, deobfName);
@@ -91,11 +89,11 @@ public class MappingsRenamer {
91 deobfName = NameValidator.validateFieldName(deobfName); 89 deobfName = NameValidator.validateFieldName(deobfName);
92 FieldEntry targetEntry = new FieldEntry(obf.getClassEntry(), deobfName, obf.getType()); 90 FieldEntry targetEntry = new FieldEntry(obf.getClassEntry(), deobfName, obf.getType());
93 ClassEntry definedClass = null; 91 ClassEntry definedClass = null;
94 if (m_mappings.containsDeobfField(obf.getClassEntry(), deobfName) || m_index.containsEntryWithSameName(targetEntry)) 92 if (mappings.containsDeobfField(obf.getClassEntry(), deobfName) || index.containsEntryWithSameName(targetEntry))
95 definedClass = obf.getClassEntry(); 93 definedClass = obf.getClassEntry();
96 else { 94 else {
97 for (ClassEntry ancestorEntry : this.m_index.getTranslationIndex().getAncestry(obf.getClassEntry())) { 95 for (ClassEntry ancestorEntry : this.index.getTranslationIndex().getAncestry(obf.getClassEntry())) {
98 if (m_mappings.containsDeobfField(ancestorEntry, deobfName) || m_index.containsEntryWithSameName(targetEntry.cloneToNewClass(ancestorEntry))) { 96 if (mappings.containsDeobfField(ancestorEntry, deobfName) || index.containsEntryWithSameName(targetEntry.cloneToNewClass(ancestorEntry))) {
99 definedClass = ancestorEntry; 97 definedClass = ancestorEntry;
100 break; 98 break;
101 } 99 }
@@ -103,7 +101,7 @@ public class MappingsRenamer {
103 } 101 }
104 102
105 if (definedClass != null) { 103 if (definedClass != null) {
106 String className = m_mappings.getTranslator(TranslationDirection.Deobfuscating, m_index.getTranslationIndex()).translateClass(definedClass.getClassName()); 104 String className = mappings.getTranslator(TranslationDirection.Deobfuscating, index.getTranslationIndex()).translateClass(definedClass.getClassName());
107 if (className == null) 105 if (className == null)
108 className = definedClass.getClassName(); 106 className = definedClass.getClassName();
109 throw new IllegalNameException(deobfName, "There is already a field with that name in " + className); 107 throw new IllegalNameException(deobfName, "There is already a field with that name in " + className);
@@ -127,23 +125,23 @@ public class MappingsRenamer {
127 MethodEntry targetEntry = new MethodEntry(entry.getClassEntry(), deobfName, entry.getSignature()); 125 MethodEntry targetEntry = new MethodEntry(entry.getClassEntry(), deobfName, entry.getSignature());
128 126
129 // TODO: Verify if I don't break things 127 // TODO: Verify if I don't break things
130 ClassMapping classMapping = m_mappings.getClassByObf(entry.getClassEntry()); 128 ClassMapping classMapping = mappings.getClassByObf(entry.getClassEntry());
131 if ((classMapping != null && classMapping.containsDeobfMethod(deobfName, entry.getSignature()) && classMapping.getMethodByObf(entry.getName(), entry.getSignature()) != classMapping.getMethodByDeobf(deobfName, entry.getSignature())) 129 if ((classMapping != null && classMapping.containsDeobfMethod(deobfName, entry.getSignature()) && classMapping.getMethodByObf(entry.getName(), entry.getSignature()) != classMapping.getMethodByDeobf(deobfName, entry.getSignature()))
132 || m_index.containsObfBehavior(targetEntry)) { 130 || index.containsObfBehavior(targetEntry)) {
133 String deobfClassName = m_mappings.getTranslator(TranslationDirection.Deobfuscating, m_index.getTranslationIndex()).translateClass(entry.getClassName()); 131 String deobfClassName = mappings.getTranslator(TranslationDirection.Deobfuscating, index.getTranslationIndex()).translateClass(entry.getClassName());
134 if (deobfClassName == null) { 132 if (deobfClassName == null) {
135 deobfClassName = entry.getClassName(); 133 deobfClassName = entry.getClassName();
136 } 134 }
137 throw new IllegalNameException(deobfName, "There is already a method with that name and signature in class " + deobfClassName); 135 throw new IllegalNameException(deobfName, "There is already a method with that name and signature in class " + deobfClassName);
138 } 136 }
139 137
140 for (ClassEntry child : m_index.getTranslationIndex().getSubclass(entry.getClassEntry())) { 138 for (ClassEntry child : index.getTranslationIndex().getSubclass(entry.getClassEntry())) {
141 validateMethodTreeName(entry.cloneToNewClass(child), deobfName); 139 validateMethodTreeName(entry.cloneToNewClass(child), deobfName);
142 } 140 }
143 } 141 }
144 142
145 public void setMethodTreeName(MethodEntry obf, String deobfName) { 143 public void setMethodTreeName(MethodEntry obf, String deobfName) {
146 Set<MethodEntry> implementations = m_index.getRelatedMethodImplementations(obf); 144 Set<MethodEntry> implementations = index.getRelatedMethodImplementations(obf);
147 145
148 deobfName = NameValidator.validateMethodName(deobfName); 146 deobfName = NameValidator.validateMethodName(deobfName);
149 for (MethodEntry entry : implementations) { 147 for (MethodEntry entry : implementations) {
@@ -161,9 +159,9 @@ public class MappingsRenamer {
161 ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); 159 ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry());
162 160
163 // TODO: Verify if I don't break things 161 // TODO: Verify if I don't break things
164 if ((m_mappings.containsDeobfMethod(obf.getClassEntry(), deobfName, obf.getSignature()) && classMapping.getMethodByObf(obf.getName(), obf.getSignature()) != classMapping.getMethodByDeobf(deobfName, obf.getSignature())) 162 if ((mappings.containsDeobfMethod(obf.getClassEntry(), deobfName, obf.getSignature()) && classMapping.getMethodByObf(obf.getName(), obf.getSignature()) != classMapping.getMethodByDeobf(deobfName, obf.getSignature()))
165 || m_index.containsObfBehavior(targetEntry)) { 163 || index.containsObfBehavior(targetEntry)) {
166 String deobfClassName = m_mappings.getTranslator(TranslationDirection.Deobfuscating, m_index.getTranslationIndex()).translateClass(obf.getClassName()); 164 String deobfClassName = mappings.getTranslator(TranslationDirection.Deobfuscating, index.getTranslationIndex()).translateClass(obf.getClassName());
167 if (deobfClassName == null) { 165 if (deobfClassName == null) {
168 deobfClassName = obf.getClassName(); 166 deobfClassName = obf.getClassName();
169 } 167 }
@@ -174,7 +172,7 @@ public class MappingsRenamer {
174 } 172 }
175 173
176 public void removeMethodTreeMapping(MethodEntry obf) { 174 public void removeMethodTreeMapping(MethodEntry obf) {
177 m_index.getRelatedMethodImplementations(obf).forEach(this::removeMethodMapping); 175 index.getRelatedMethodImplementations(obf).forEach(this::removeMethodMapping);
178 } 176 }
179 177
180 public void removeMethodMapping(MethodEntry obf) { 178 public void removeMethodMapping(MethodEntry obf) {
@@ -183,7 +181,7 @@ public class MappingsRenamer {
183 } 181 }
184 182
185 public void markMethodTreeAsDeobfuscated(MethodEntry obf) { 183 public void markMethodTreeAsDeobfuscated(MethodEntry obf) {
186 m_index.getRelatedMethodImplementations(obf).forEach(this::markMethodAsDeobfuscated); 184 index.getRelatedMethodImplementations(obf).forEach(this::markMethodAsDeobfuscated);
187 } 185 }
188 186
189 public void markMethodAsDeobfuscated(MethodEntry obf) { 187 public void markMethodAsDeobfuscated(MethodEntry obf) {
@@ -199,9 +197,9 @@ public class MappingsRenamer {
199 197
200 MethodEntry obfMethod = (MethodEntry) obf.getBehaviorEntry(); 198 MethodEntry obfMethod = (MethodEntry) obf.getBehaviorEntry();
201 199
202 Set<MethodEntry> implementations = m_index.getRelatedMethodImplementations(obfMethod); 200 Set<MethodEntry> implementations = index.getRelatedMethodImplementations(obfMethod);
203 for (MethodEntry entry : implementations) { 201 for (MethodEntry entry : implementations) {
204 ClassMapping classMapping = m_mappings.getClassByObf(entry.getClassEntry()); 202 ClassMapping classMapping = mappings.getClassByObf(entry.getClassEntry());
205 if (classMapping != null) { 203 if (classMapping != null) {
206 MethodMapping mapping = classMapping.getMethodByObf(entry.getName(), entry.getSignature()); 204 MethodMapping mapping = classMapping.getMethodByObf(entry.getName(), entry.getSignature());
207 // NOTE: don't need to check arguments for name collisions with names determined by Procyon 205 // NOTE: don't need to check arguments for name collisions with names determined by Procyon
@@ -297,7 +295,7 @@ public class MappingsRenamer {
297 295
298 private List<ClassMapping> getOrCreateClassMappingChain(ClassEntry obfClassEntry) { 296 private List<ClassMapping> getOrCreateClassMappingChain(ClassEntry obfClassEntry) {
299 List<ClassEntry> classChain = obfClassEntry.getClassChain(); 297 List<ClassEntry> classChain = obfClassEntry.getClassChain();
300 List<ClassMapping> mappingChain = m_mappings.getClassMappingChain(obfClassEntry); 298 List<ClassMapping> mappingChain = mappings.getClassMappingChain(obfClassEntry);
301 for (int i = 0; i < classChain.size(); i++) { 299 for (int i = 0; i < classChain.size(); i++) {
302 ClassEntry classEntry = classChain.get(i); 300 ClassEntry classEntry = classChain.get(i);
303 ClassMapping classMapping = mappingChain.get(i); 301 ClassMapping classMapping = mappingChain.get(i);
@@ -310,7 +308,7 @@ public class MappingsRenamer {
310 // add it to the right parent 308 // add it to the right parent
311 try { 309 try {
312 if (i == 0) { 310 if (i == 0) {
313 m_mappings.addClassMapping(classMapping); 311 mappings.addClassMapping(classMapping);
314 } else { 312 } else {
315 mappingChain.get(i - 1).addInnerClassMapping(classMapping); 313 mappingChain.get(i - 1).addInnerClassMapping(classMapping);
316 } 314 }
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsSRGWriter.java b/src/main/java/cuchaz/enigma/mapping/MappingsSRGWriter.java
index 4d0c2610..a3f0cc87 100644
--- a/src/main/java/cuchaz/enigma/mapping/MappingsSRGWriter.java
+++ b/src/main/java/cuchaz/enigma/mapping/MappingsSRGWriter.java
@@ -71,7 +71,7 @@ public class MappingsSRGWriter {
71 71
72 72
73 private <T extends Comparable<T>> List<T> sorted(Iterable<T> classes) { 73 private <T extends Comparable<T>> List<T> sorted(Iterable<T> classes) {
74 List<T> out = new ArrayList<T>(); 74 List<T> out = new ArrayList<>();
75 for (T t : classes) { 75 for (T t : classes) {
76 out.add(t); 76 out.add(t);
77 } 77 }
diff --git a/src/main/java/cuchaz/enigma/mapping/MethodMapping.java b/src/main/java/cuchaz/enigma/mapping/MethodMapping.java
index f973d6b7..e0aeea2d 100644
--- a/src/main/java/cuchaz/enigma/mapping/MethodMapping.java
+++ b/src/main/java/cuchaz/enigma/mapping/MethodMapping.java
@@ -178,14 +178,12 @@ public class MethodMapping implements Comparable<MethodMapping>, MemberMapping<B
178 178
179 public boolean renameObfClass(final String oldObfClassName, final String newObfClassName) { 179 public boolean renameObfClass(final String oldObfClassName, final String newObfClassName) {
180 // rename obf classes in the signature 180 // rename obf classes in the signature
181 Signature newSignature = new Signature(this.obfSignature, new ClassNameReplacer() { 181 Signature newSignature = new Signature(this.obfSignature, className ->
182 @Override 182 {
183 public String replace(String className) { 183 if (className.equals(oldObfClassName)) {
184 if (className.equals(oldObfClassName)) { 184 return newObfClassName;
185 return newObfClassName;
186 }
187 return null;
188 } 185 }
186 return null;
189 }); 187 });
190 188
191 if (!newSignature.equals(this.obfSignature)) { 189 if (!newSignature.equals(this.obfSignature)) {
diff --git a/src/main/java/cuchaz/enigma/throwables/MappingParseException.java b/src/main/java/cuchaz/enigma/throwables/MappingParseException.java
index 18dff277..d4c66734 100644
--- a/src/main/java/cuchaz/enigma/throwables/MappingParseException.java
+++ b/src/main/java/cuchaz/enigma/throwables/MappingParseException.java
@@ -14,18 +14,18 @@ import java.io.File;
14 14
15public class MappingParseException extends Exception { 15public class MappingParseException extends Exception {
16 16
17 private int m_line; 17 private int line;
18 private String m_message; 18 private String message;
19 private String filePath; 19 private String filePath;
20 20
21 public MappingParseException(File file, int line, String message) { 21 public MappingParseException(File file, int line, String message) {
22 m_line = line; 22 this.line = line;
23 m_message = message; 23 this.message = message;
24 filePath = file.getAbsolutePath(); 24 filePath = file.getAbsolutePath();
25 } 25 }
26 26
27 @Override 27 @Override
28 public String getMessage() { 28 public String getMessage() {
29 return "Line " + m_line + ": " + m_message + " in file " + filePath; 29 return "Line " + line + ": " + message + " in file " + filePath;
30 } 30 }
31} 31}
diff --git a/src/main/java/cuchaz/enigma/utils/Utils.java b/src/main/java/cuchaz/enigma/utils/Utils.java
index ebc110aa..474f7edf 100644
--- a/src/main/java/cuchaz/enigma/utils/Utils.java
+++ b/src/main/java/cuchaz/enigma/utils/Utils.java
@@ -21,6 +21,7 @@ import java.io.InputStreamReader;
21import java.net.URI; 21import java.net.URI;
22import java.net.URISyntaxException; 22import java.net.URISyntaxException;
23import java.util.Arrays; 23import java.util.Arrays;
24import java.util.List;
24 25
25import javax.swing.*; 26import javax.swing.*;
26 27
@@ -30,7 +31,7 @@ public class Utils {
30 return combineHashesOrdered(Arrays.asList(objs)); 31 return combineHashesOrdered(Arrays.asList(objs));
31 } 32 }
32 33
33 public static int combineHashesOrdered(Iterable<Object> objs) { 34 public static int combineHashesOrdered(List<Object> objs) {
34 final int prime = 67; 35 final int prime = 67;
35 int result = 1; 36 int result = 1;
36 for (Object obj : objs) { 37 for (Object obj : objs) {
diff --git a/src/test/java/cuchaz/enigma/TestDeobfed.java b/src/test/java/cuchaz/enigma/TestDeobfed.java
index 2f318c80..76a3d3b5 100644
--- a/src/test/java/cuchaz/enigma/TestDeobfed.java
+++ b/src/test/java/cuchaz/enigma/TestDeobfed.java
@@ -25,20 +25,20 @@ import cuchaz.enigma.analysis.JarIndex;
25 25
26public class TestDeobfed { 26public class TestDeobfed {
27 27
28 private static JarFile m_jar; 28 private static JarFile jar;
29 private static JarIndex m_index; 29 private static JarIndex index;
30 30
31 @BeforeClass 31 @BeforeClass
32 public static void beforeClass() 32 public static void beforeClass()
33 throws Exception { 33 throws Exception {
34 m_jar = new JarFile("build/test-deobf/translation.jar"); 34 jar = new JarFile("build/test-deobf/translation.jar");
35 m_index = new JarIndex(); 35 index = new JarIndex();
36 m_index.indexJar(m_jar, true); 36 index.indexJar(jar, true);
37 } 37 }
38 38
39 @Test 39 @Test
40 public void obfEntries() { 40 public void obfEntries() {
41 assertThat(m_index.getObfClassEntries(), containsInAnyOrder( 41 assertThat(index.getObfClassEntries(), containsInAnyOrder(
42 newClass("cuchaz/enigma/inputs/Keep"), 42 newClass("cuchaz/enigma/inputs/Keep"),
43 newClass("a"), 43 newClass("a"),
44 newClass("b"), 44 newClass("b"),
@@ -68,7 +68,7 @@ public class TestDeobfed {
68 @Test 68 @Test
69 public void decompile() 69 public void decompile()
70 throws Exception { 70 throws Exception {
71 Deobfuscator deobfuscator = new Deobfuscator(m_jar); 71 Deobfuscator deobfuscator = new Deobfuscator(jar);
72 deobfuscator.getSourceTree("a"); 72 deobfuscator.getSourceTree("a");
73 deobfuscator.getSourceTree("b"); 73 deobfuscator.getSourceTree("b");
74 deobfuscator.getSourceTree("c"); 74 deobfuscator.getSourceTree("c");
diff --git a/src/test/java/cuchaz/enigma/TestInnerClasses.java b/src/test/java/cuchaz/enigma/TestInnerClasses.java
index 70765e32..64a695a9 100644
--- a/src/test/java/cuchaz/enigma/TestInnerClasses.java
+++ b/src/test/java/cuchaz/enigma/TestInnerClasses.java
@@ -24,8 +24,8 @@ import cuchaz.enigma.mapping.ClassEntry;
24 24
25public class TestInnerClasses { 25public class TestInnerClasses {
26 26
27 private JarIndex m_index; 27 private JarIndex index;
28 private Deobfuscator m_deobfuscator; 28 private Deobfuscator deobfuscator;
29 29
30 private static final ClassEntry AnonymousOuter = newClass("a"); 30 private static final ClassEntry AnonymousOuter = newClass("a");
31 private static final ClassEntry AnonymousInner = newClass("a$1"); 31 private static final ClassEntry AnonymousInner = newClass("a$1");
@@ -44,49 +44,49 @@ public class TestInnerClasses {
44 44
45 public TestInnerClasses() 45 public TestInnerClasses()
46 throws Exception { 46 throws Exception {
47 m_index = new JarIndex(); 47 index = new JarIndex();
48 JarFile jar = new JarFile("build/test-obf/innerClasses.jar"); 48 JarFile jar = new JarFile("build/test-obf/innerClasses.jar");
49 m_index.indexJar(jar, true); 49 index.indexJar(jar, true);
50 m_deobfuscator = new Deobfuscator(jar); 50 deobfuscator = new Deobfuscator(jar);
51 } 51 }
52 52
53 @Test 53 @Test
54 public void simple() { 54 public void simple() {
55 assertThat(m_index.getOuterClass(SimpleInner), is(SimpleOuter)); 55 assertThat(index.getOuterClass(SimpleInner), is(SimpleOuter));
56 assertThat(m_index.getInnerClasses(SimpleOuter), containsInAnyOrder(SimpleInner)); 56 assertThat(index.getInnerClasses(SimpleOuter), containsInAnyOrder(SimpleInner));
57 assertThat(m_index.isAnonymousClass(SimpleInner), is(false)); 57 assertThat(index.isAnonymousClass(SimpleInner), is(false));
58 decompile(SimpleOuter); 58 decompile(SimpleOuter);
59 } 59 }
60 60
61 @Test 61 @Test
62 public void anonymous() { 62 public void anonymous() {
63 assertThat(m_index.getOuterClass(AnonymousInner), is(AnonymousOuter)); 63 assertThat(index.getOuterClass(AnonymousInner), is(AnonymousOuter));
64 assertThat(m_index.getInnerClasses(AnonymousOuter), containsInAnyOrder(AnonymousInner)); 64 assertThat(index.getInnerClasses(AnonymousOuter), containsInAnyOrder(AnonymousInner));
65 assertThat(m_index.isAnonymousClass(AnonymousInner), is(true)); 65 assertThat(index.isAnonymousClass(AnonymousInner), is(true));
66 decompile(AnonymousOuter); 66 decompile(AnonymousOuter);
67 } 67 }
68 68
69 @Test 69 @Test
70 public void constructorArgs() { 70 public void constructorArgs() {
71 assertThat(m_index.getOuterClass(ConstructorArgsInner), is(ConstructorArgsOuter)); 71 assertThat(index.getOuterClass(ConstructorArgsInner), is(ConstructorArgsOuter));
72 assertThat(m_index.getInnerClasses(ConstructorArgsOuter), containsInAnyOrder(ConstructorArgsInner)); 72 assertThat(index.getInnerClasses(ConstructorArgsOuter), containsInAnyOrder(ConstructorArgsInner));
73 assertThat(m_index.isAnonymousClass(ConstructorArgsInner), is(false)); 73 assertThat(index.isAnonymousClass(ConstructorArgsInner), is(false));
74 decompile(ConstructorArgsOuter); 74 decompile(ConstructorArgsOuter);
75 } 75 }
76 76
77 @Test 77 @Test
78 public void anonymousWithScopeArgs() { 78 public void anonymousWithScopeArgs() {
79 assertThat(m_index.getOuterClass(AnonymousWithScopeArgsInner), is(AnonymousWithScopeArgsOuter)); 79 assertThat(index.getOuterClass(AnonymousWithScopeArgsInner), is(AnonymousWithScopeArgsOuter));
80 assertThat(m_index.getInnerClasses(AnonymousWithScopeArgsOuter), containsInAnyOrder(AnonymousWithScopeArgsInner)); 80 assertThat(index.getInnerClasses(AnonymousWithScopeArgsOuter), containsInAnyOrder(AnonymousWithScopeArgsInner));
81 assertThat(m_index.isAnonymousClass(AnonymousWithScopeArgsInner), is(true)); 81 assertThat(index.isAnonymousClass(AnonymousWithScopeArgsInner), is(true));
82 decompile(AnonymousWithScopeArgsOuter); 82 decompile(AnonymousWithScopeArgsOuter);
83 } 83 }
84 84
85 @Test 85 @Test
86 public void anonymousWithOuterAccess() { 86 public void anonymousWithOuterAccess() {
87 assertThat(m_index.getOuterClass(AnonymousWithOuterAccessInner), is(AnonymousWithOuterAccessOuter)); 87 assertThat(index.getOuterClass(AnonymousWithOuterAccessInner), is(AnonymousWithOuterAccessOuter));
88 assertThat(m_index.getInnerClasses(AnonymousWithOuterAccessOuter), containsInAnyOrder(AnonymousWithOuterAccessInner)); 88 assertThat(index.getInnerClasses(AnonymousWithOuterAccessOuter), containsInAnyOrder(AnonymousWithOuterAccessInner));
89 assertThat(m_index.isAnonymousClass(AnonymousWithOuterAccessInner), is(true)); 89 assertThat(index.isAnonymousClass(AnonymousWithOuterAccessInner), is(true));
90 decompile(AnonymousWithOuterAccessOuter); 90 decompile(AnonymousWithOuterAccessOuter);
91 } 91 }
92 92
@@ -94,26 +94,26 @@ public class TestInnerClasses {
94 public void classTree() { 94 public void classTree() {
95 95
96 // root level 96 // root level
97 assertThat(m_index.containsObfClass(ClassTreeRoot), is(true)); 97 assertThat(index.containsObfClass(ClassTreeRoot), is(true));
98 assertThat(m_index.getOuterClass(ClassTreeRoot), is(nullValue())); 98 assertThat(index.getOuterClass(ClassTreeRoot), is(nullValue()));
99 assertThat(m_index.getInnerClasses(ClassTreeRoot), containsInAnyOrder(ClassTreeLevel1)); 99 assertThat(index.getInnerClasses(ClassTreeRoot), containsInAnyOrder(ClassTreeLevel1));
100 100
101 // level 1 101 // level 1
102 ClassEntry fullClassEntry = new ClassEntry(ClassTreeRoot.getName() 102 ClassEntry fullClassEntry = new ClassEntry(ClassTreeRoot.getName()
103 + "$" + ClassTreeLevel1.getInnermostClassName() 103 + "$" + ClassTreeLevel1.getInnermostClassName()
104 ); 104 );
105 assertThat(m_index.containsObfClass(fullClassEntry), is(true)); 105 assertThat(index.containsObfClass(fullClassEntry), is(true));
106 assertThat(m_index.getOuterClass(ClassTreeLevel1), is(ClassTreeRoot)); 106 assertThat(index.getOuterClass(ClassTreeLevel1), is(ClassTreeRoot));
107 assertThat(m_index.getInnerClasses(ClassTreeLevel1), containsInAnyOrder(ClassTreeLevel2)); 107 assertThat(index.getInnerClasses(ClassTreeLevel1), containsInAnyOrder(ClassTreeLevel2));
108 108
109 // level 2 109 // level 2
110 fullClassEntry = new ClassEntry(ClassTreeRoot.getName() 110 fullClassEntry = new ClassEntry(ClassTreeRoot.getName()
111 + "$" + ClassTreeLevel1.getInnermostClassName() 111 + "$" + ClassTreeLevel1.getInnermostClassName()
112 + "$" + ClassTreeLevel2.getInnermostClassName() 112 + "$" + ClassTreeLevel2.getInnermostClassName()
113 ); 113 );
114 assertThat(m_index.containsObfClass(fullClassEntry), is(true)); 114 assertThat(index.containsObfClass(fullClassEntry), is(true));
115 assertThat(m_index.getOuterClass(ClassTreeLevel2), is(ClassTreeLevel1)); 115 assertThat(index.getOuterClass(ClassTreeLevel2), is(ClassTreeLevel1));
116 assertThat(m_index.getInnerClasses(ClassTreeLevel2), containsInAnyOrder(ClassTreeLevel3)); 116 assertThat(index.getInnerClasses(ClassTreeLevel2), containsInAnyOrder(ClassTreeLevel3));
117 117
118 // level 3 118 // level 3
119 fullClassEntry = new ClassEntry(ClassTreeRoot.getName() 119 fullClassEntry = new ClassEntry(ClassTreeRoot.getName()
@@ -121,12 +121,12 @@ public class TestInnerClasses {
121 + "$" + ClassTreeLevel2.getInnermostClassName() 121 + "$" + ClassTreeLevel2.getInnermostClassName()
122 + "$" + ClassTreeLevel3.getInnermostClassName() 122 + "$" + ClassTreeLevel3.getInnermostClassName()
123 ); 123 );
124 assertThat(m_index.containsObfClass(fullClassEntry), is(true)); 124 assertThat(index.containsObfClass(fullClassEntry), is(true));
125 assertThat(m_index.getOuterClass(ClassTreeLevel3), is(ClassTreeLevel2)); 125 assertThat(index.getOuterClass(ClassTreeLevel3), is(ClassTreeLevel2));
126 assertThat(m_index.getInnerClasses(ClassTreeLevel3), is(empty())); 126 assertThat(index.getInnerClasses(ClassTreeLevel3), is(empty()));
127 } 127 }
128 128
129 private void decompile(ClassEntry classEntry) { 129 private void decompile(ClassEntry classEntry) {
130 m_deobfuscator.getSourceTree(classEntry.getName()); 130 deobfuscator.getSourceTree(classEntry.getName());
131 } 131 }
132} 132}
diff --git a/src/test/java/cuchaz/enigma/TestJarIndexConstructorReferences.java b/src/test/java/cuchaz/enigma/TestJarIndexConstructorReferences.java
index cb65cd07..01d4bab6 100644
--- a/src/test/java/cuchaz/enigma/TestJarIndexConstructorReferences.java
+++ b/src/test/java/cuchaz/enigma/TestJarIndexConstructorReferences.java
@@ -27,98 +27,99 @@ import cuchaz.enigma.mapping.ClassEntry;
27 27
28public class TestJarIndexConstructorReferences { 28public class TestJarIndexConstructorReferences {
29 29
30 private JarIndex m_index; 30 private JarIndex index;
31 31
32 private ClassEntry m_baseClass = newClass("a"); 32 private ClassEntry baseClass = newClass("a");
33 private ClassEntry m_subClass = newClass("d"); 33 private ClassEntry subClass = newClass("d");
34 private ClassEntry m_subsubClass = newClass("e"); 34 private ClassEntry subsubClass = newClass("e");
35 private ClassEntry m_defaultClass = newClass("c"); 35 private ClassEntry defaultClass = newClass("c");
36 private ClassEntry m_callerClass = newClass("b"); 36 private ClassEntry callerClass = newClass("b");
37 37
38 public TestJarIndexConstructorReferences() 38 public TestJarIndexConstructorReferences()
39 throws Exception { 39 throws Exception {
40 File jarFile = new File("build/test-obf/constructors.jar"); 40 File jarFile = new File("build/test-obf/constructors.jar");
41 m_index = new JarIndex(); 41 index = new JarIndex();
42 m_index.indexJar(new JarFile(jarFile), false); 42 index.indexJar(new JarFile(jarFile), false);
43 } 43 }
44 44
45 @Test 45 @Test
46 public void obfEntries() { 46 public void obfEntries() {
47 assertThat(m_index.getObfClassEntries(), containsInAnyOrder(newClass("cuchaz/enigma/inputs/Keep"), m_baseClass, m_subClass, m_subsubClass, m_defaultClass, m_callerClass)); 47 assertThat(index.getObfClassEntries(), containsInAnyOrder(newClass("cuchaz/enigma/inputs/Keep"), baseClass,
48 subClass, subsubClass, defaultClass, callerClass));
48 } 49 }
49 50
50 @Test 51 @Test
51 @SuppressWarnings("unchecked") 52 @SuppressWarnings("unchecked")
52 public void baseDefault() { 53 public void baseDefault() {
53 BehaviorEntry source = newConstructor(m_baseClass, "()V"); 54 BehaviorEntry source = newConstructor(baseClass, "()V");
54 Collection<EntryReference<BehaviorEntry,BehaviorEntry>> references = m_index.getBehaviorReferences(source); 55 Collection<EntryReference<BehaviorEntry,BehaviorEntry>> references = index.getBehaviorReferences(source);
55 assertThat(references, containsInAnyOrder( 56 assertThat(references, containsInAnyOrder(
56 newBehaviorReferenceByMethod(source, m_callerClass.getName(), "a", "()V"), 57 newBehaviorReferenceByMethod(source, callerClass.getName(), "a", "()V"),
57 newBehaviorReferenceByConstructor(source, m_subClass.getName(), "()V"), 58 newBehaviorReferenceByConstructor(source, subClass.getName(), "()V"),
58 newBehaviorReferenceByConstructor(source, m_subClass.getName(), "(III)V") 59 newBehaviorReferenceByConstructor(source, subClass.getName(), "(III)V")
59 )); 60 ));
60 } 61 }
61 62
62 @Test 63 @Test
63 @SuppressWarnings("unchecked") 64 @SuppressWarnings("unchecked")
64 public void baseInt() { 65 public void baseInt() {
65 BehaviorEntry source = newConstructor(m_baseClass, "(I)V"); 66 BehaviorEntry source = newConstructor(baseClass, "(I)V");
66 assertThat(m_index.getBehaviorReferences(source), containsInAnyOrder( 67 assertThat(index.getBehaviorReferences(source), containsInAnyOrder(
67 newBehaviorReferenceByMethod(source, m_callerClass.getName(), "b", "()V") 68 newBehaviorReferenceByMethod(source, callerClass.getName(), "b", "()V")
68 )); 69 ));
69 } 70 }
70 71
71 @Test 72 @Test
72 @SuppressWarnings("unchecked") 73 @SuppressWarnings("unchecked")
73 public void subDefault() { 74 public void subDefault() {
74 BehaviorEntry source = newConstructor(m_subClass, "()V"); 75 BehaviorEntry source = newConstructor(subClass, "()V");
75 assertThat(m_index.getBehaviorReferences(source), containsInAnyOrder( 76 assertThat(index.getBehaviorReferences(source), containsInAnyOrder(
76 newBehaviorReferenceByMethod(source, m_callerClass.getName(), "c", "()V"), 77 newBehaviorReferenceByMethod(source, callerClass.getName(), "c", "()V"),
77 newBehaviorReferenceByConstructor(source, m_subClass.getName(), "(I)V") 78 newBehaviorReferenceByConstructor(source, subClass.getName(), "(I)V")
78 )); 79 ));
79 } 80 }
80 81
81 @Test 82 @Test
82 @SuppressWarnings("unchecked") 83 @SuppressWarnings("unchecked")
83 public void subInt() { 84 public void subInt() {
84 BehaviorEntry source = newConstructor(m_subClass, "(I)V"); 85 BehaviorEntry source = newConstructor(subClass, "(I)V");
85 assertThat(m_index.getBehaviorReferences(source), containsInAnyOrder( 86 assertThat(index.getBehaviorReferences(source), containsInAnyOrder(
86 newBehaviorReferenceByMethod(source, m_callerClass.getName(), "d", "()V"), 87 newBehaviorReferenceByMethod(source, callerClass.getName(), "d", "()V"),
87 newBehaviorReferenceByConstructor(source, m_subClass.getName(), "(II)V"), 88 newBehaviorReferenceByConstructor(source, subClass.getName(), "(II)V"),
88 newBehaviorReferenceByConstructor(source, m_subsubClass.getName(), "(I)V") 89 newBehaviorReferenceByConstructor(source, subsubClass.getName(), "(I)V")
89 )); 90 ));
90 } 91 }
91 92
92 @Test 93 @Test
93 @SuppressWarnings("unchecked") 94 @SuppressWarnings("unchecked")
94 public void subIntInt() { 95 public void subIntInt() {
95 BehaviorEntry source = newConstructor(m_subClass, "(II)V"); 96 BehaviorEntry source = newConstructor(subClass, "(II)V");
96 assertThat(m_index.getBehaviorReferences(source), containsInAnyOrder( 97 assertThat(index.getBehaviorReferences(source), containsInAnyOrder(
97 newBehaviorReferenceByMethod(source, m_callerClass.getName(), "e", "()V") 98 newBehaviorReferenceByMethod(source, callerClass.getName(), "e", "()V")
98 )); 99 ));
99 } 100 }
100 101
101 @Test 102 @Test
102 public void subIntIntInt() { 103 public void subIntIntInt() {
103 BehaviorEntry source = newConstructor(m_subClass, "(III)V"); 104 BehaviorEntry source = newConstructor(subClass, "(III)V");
104 assertThat(m_index.getBehaviorReferences(source), is(empty())); 105 assertThat(index.getBehaviorReferences(source), is(empty()));
105 } 106 }
106 107
107 @Test 108 @Test
108 @SuppressWarnings("unchecked") 109 @SuppressWarnings("unchecked")
109 public void subsubInt() { 110 public void subsubInt() {
110 BehaviorEntry source = newConstructor(m_subsubClass, "(I)V"); 111 BehaviorEntry source = newConstructor(subsubClass, "(I)V");
111 assertThat(m_index.getBehaviorReferences(source), containsInAnyOrder( 112 assertThat(index.getBehaviorReferences(source), containsInAnyOrder(
112 newBehaviorReferenceByMethod(source, m_callerClass.getName(), "f", "()V") 113 newBehaviorReferenceByMethod(source, callerClass.getName(), "f", "()V")
113 )); 114 ));
114 } 115 }
115 116
116 @Test 117 @Test
117 @SuppressWarnings("unchecked") 118 @SuppressWarnings("unchecked")
118 public void defaultConstructable() { 119 public void defaultConstructable() {
119 BehaviorEntry source = newConstructor(m_defaultClass, "()V"); 120 BehaviorEntry source = newConstructor(defaultClass, "()V");
120 assertThat(m_index.getBehaviorReferences(source), containsInAnyOrder( 121 assertThat(index.getBehaviorReferences(source), containsInAnyOrder(
121 newBehaviorReferenceByMethod(source, m_callerClass.getName(), "g", "()V") 122 newBehaviorReferenceByMethod(source, callerClass.getName(), "g", "()V")
122 )); 123 ));
123 } 124 }
124} 125}
diff --git a/src/test/java/cuchaz/enigma/TestJarIndexInheritanceTree.java b/src/test/java/cuchaz/enigma/TestJarIndexInheritanceTree.java
index 28408f2a..4d9c8dc1 100644
--- a/src/test/java/cuchaz/enigma/TestJarIndexInheritanceTree.java
+++ b/src/test/java/cuchaz/enigma/TestJarIndexInheritanceTree.java
@@ -41,66 +41,60 @@ import cuchaz.enigma.mapping.MethodEntry;
41 41
42public class TestJarIndexInheritanceTree { 42public class TestJarIndexInheritanceTree {
43 43
44 private JarIndex m_index; 44 private JarIndex index;
45 45
46 private ClassEntry m_objectClass = newClass("java/lang/Object"); 46 private ClassEntry objectClass = newClass("java/lang/Object");
47 private ClassEntry m_baseClass = newClass("a"); 47 private ClassEntry baseClass = newClass("a");
48 private ClassEntry m_subClassA = newClass("b"); 48 private ClassEntry subClassA = newClass("b");
49 private ClassEntry m_subClassAA = newClass("d"); 49 private ClassEntry subClassAA = newClass("d");
50 private ClassEntry m_subClassB = newClass("c"); 50 private ClassEntry subClassB = newClass("c");
51 private FieldEntry m_nameField = newField(m_baseClass, "a", "Ljava/lang/String;"); 51 private FieldEntry nameField = newField(baseClass, "a", "Ljava/lang/String;");
52 private FieldEntry m_numThingsField = newField(m_subClassB, "a", "I"); 52 private FieldEntry numThingsField = newField(subClassB, "a", "I");
53 53
54 public TestJarIndexInheritanceTree() 54 public TestJarIndexInheritanceTree()
55 throws Exception { 55 throws Exception {
56 m_index = new JarIndex(); 56 index = new JarIndex();
57 m_index.indexJar(new JarFile("build/test-obf/inheritanceTree.jar"), false); 57 index.indexJar(new JarFile("build/test-obf/inheritanceTree.jar"), false);
58 } 58 }
59 59
60 @Test 60 @Test
61 public void obfEntries() { 61 public void obfEntries() {
62 assertThat(m_index.getObfClassEntries(), containsInAnyOrder( 62 assertThat(index.getObfClassEntries(), containsInAnyOrder(
63 newClass("cuchaz/enigma/inputs/Keep"), 63 newClass("cuchaz/enigma/inputs/Keep"), baseClass, subClassA, subClassAA, subClassB
64 m_baseClass,
65 m_subClassA,
66 m_subClassAA,
67 m_subClassB
68 )); 64 ));
69 } 65 }
70 66
71 @Test 67 @Test
72 public void translationIndex() { 68 public void translationIndex() {
73 69
74 TranslationIndex index = m_index.getTranslationIndex(); 70 TranslationIndex index = this.index.getTranslationIndex();
75 71
76 // base class 72 // base class
77 assertThat(index.getSuperclass(m_baseClass), is(m_objectClass)); 73 assertThat(index.getSuperclass(baseClass), is(objectClass));
78 assertThat(index.getAncestry(m_baseClass), contains(m_objectClass)); 74 assertThat(index.getAncestry(baseClass), contains(objectClass));
79 assertThat(index.getSubclass(m_baseClass), containsInAnyOrder( 75 assertThat(index.getSubclass(baseClass), containsInAnyOrder(subClassA, subClassB
80 m_subClassA,
81 m_subClassB
82 )); 76 ));
83 77
84 // subclass a 78 // subclass a
85 assertThat(index.getSuperclass(m_subClassA), is(m_baseClass)); 79 assertThat(index.getSuperclass(subClassA), is(baseClass));
86 assertThat(index.getAncestry(m_subClassA), contains(m_baseClass, m_objectClass)); 80 assertThat(index.getAncestry(subClassA), contains(baseClass, objectClass));
87 assertThat(index.getSubclass(m_subClassA), contains(m_subClassAA)); 81 assertThat(index.getSubclass(subClassA), contains(subClassAA));
88 82
89 // subclass aa 83 // subclass aa
90 assertThat(index.getSuperclass(m_subClassAA), is(m_subClassA)); 84 assertThat(index.getSuperclass(subClassAA), is(subClassA));
91 assertThat(index.getAncestry(m_subClassAA), contains(m_subClassA, m_baseClass, m_objectClass)); 85 assertThat(index.getAncestry(subClassAA), contains(subClassA, baseClass, objectClass));
92 assertThat(index.getSubclass(m_subClassAA), is(empty())); 86 assertThat(index.getSubclass(subClassAA), is(empty()));
93 87
94 // subclass b 88 // subclass b
95 assertThat(index.getSuperclass(m_subClassB), is(m_baseClass)); 89 assertThat(index.getSuperclass(subClassB), is(baseClass));
96 assertThat(index.getAncestry(m_subClassB), contains(m_baseClass, m_objectClass)); 90 assertThat(index.getAncestry(subClassB), contains(baseClass, objectClass));
97 assertThat(index.getSubclass(m_subClassB), is(empty())); 91 assertThat(index.getSubclass(subClassB), is(empty()));
98 } 92 }
99 93
100 @Test 94 @Test
101 public void access() { 95 public void access() {
102 assertThat(m_index.getAccess(m_nameField), is(Access.Private)); 96 assertThat(index.getAccess(nameField), is(Access.PRIVATE));
103 assertThat(m_index.getAccess(m_numThingsField), is(Access.Private)); 97 assertThat(index.getAccess(numThingsField), is(Access.PRIVATE));
104 } 98 }
105 99
106 @Test 100 @Test
@@ -109,40 +103,40 @@ public class TestJarIndexInheritanceTree {
109 Set<MethodEntry> entries; 103 Set<MethodEntry> entries;
110 104
111 // getName() 105 // getName()
112 entries = m_index.getRelatedMethodImplementations(newMethod(m_baseClass, "a", "()Ljava/lang/String;")); 106 entries = index.getRelatedMethodImplementations(newMethod(baseClass, "a", "()Ljava/lang/String;"));
113 assertThat(entries, containsInAnyOrder( 107 assertThat(entries, containsInAnyOrder(
114 newMethod(m_baseClass, "a", "()Ljava/lang/String;"), 108 newMethod(baseClass, "a", "()Ljava/lang/String;"),
115 newMethod(m_subClassAA, "a", "()Ljava/lang/String;") 109 newMethod(subClassAA, "a", "()Ljava/lang/String;")
116 )); 110 ));
117 entries = m_index.getRelatedMethodImplementations(newMethod(m_subClassAA, "a", "()Ljava/lang/String;")); 111 entries = index.getRelatedMethodImplementations(newMethod(subClassAA, "a", "()Ljava/lang/String;"));
118 assertThat(entries, containsInAnyOrder( 112 assertThat(entries, containsInAnyOrder(
119 newMethod(m_baseClass, "a", "()Ljava/lang/String;"), 113 newMethod(baseClass, "a", "()Ljava/lang/String;"),
120 newMethod(m_subClassAA, "a", "()Ljava/lang/String;") 114 newMethod(subClassAA, "a", "()Ljava/lang/String;")
121 )); 115 ));
122 116
123 // doBaseThings() 117 // doBaseThings()
124 entries = m_index.getRelatedMethodImplementations(newMethod(m_baseClass, "a", "()V")); 118 entries = index.getRelatedMethodImplementations(newMethod(baseClass, "a", "()V"));
125 assertThat(entries, containsInAnyOrder( 119 assertThat(entries, containsInAnyOrder(
126 newMethod(m_baseClass, "a", "()V"), 120 newMethod(baseClass, "a", "()V"),
127 newMethod(m_subClassAA, "a", "()V"), 121 newMethod(subClassAA, "a", "()V"),
128 newMethod(m_subClassB, "a", "()V") 122 newMethod(subClassB, "a", "()V")
129 )); 123 ));
130 entries = m_index.getRelatedMethodImplementations(newMethod(m_subClassAA, "a", "()V")); 124 entries = index.getRelatedMethodImplementations(newMethod(subClassAA, "a", "()V"));
131 assertThat(entries, containsInAnyOrder( 125 assertThat(entries, containsInAnyOrder(
132 newMethod(m_baseClass, "a", "()V"), 126 newMethod(baseClass, "a", "()V"),
133 newMethod(m_subClassAA, "a", "()V"), 127 newMethod(subClassAA, "a", "()V"),
134 newMethod(m_subClassB, "a", "()V") 128 newMethod(subClassB, "a", "()V")
135 )); 129 ));
136 entries = m_index.getRelatedMethodImplementations(newMethod(m_subClassB, "a", "()V")); 130 entries = index.getRelatedMethodImplementations(newMethod(subClassB, "a", "()V"));
137 assertThat(entries, containsInAnyOrder( 131 assertThat(entries, containsInAnyOrder(
138 newMethod(m_baseClass, "a", "()V"), 132 newMethod(baseClass, "a", "()V"),
139 newMethod(m_subClassAA, "a", "()V"), 133 newMethod(subClassAA, "a", "()V"),
140 newMethod(m_subClassB, "a", "()V") 134 newMethod(subClassB, "a", "()V")
141 )); 135 ));
142 136
143 // doBThings 137 // doBThings
144 entries = m_index.getRelatedMethodImplementations(newMethod(m_subClassB, "b", "()V")); 138 entries = index.getRelatedMethodImplementations(newMethod(subClassB, "b", "()V"));
145 assertThat(entries, containsInAnyOrder(newMethod(m_subClassB, "b", "()V"))); 139 assertThat(entries, containsInAnyOrder(newMethod(subClassB, "b", "()V")));
146 } 140 }
147 141
148 @Test 142 @Test
@@ -151,17 +145,17 @@ public class TestJarIndexInheritanceTree {
151 Collection<EntryReference<FieldEntry,BehaviorEntry>> references; 145 Collection<EntryReference<FieldEntry,BehaviorEntry>> references;
152 146
153 // name 147 // name
154 references = m_index.getFieldReferences(m_nameField); 148 references = index.getFieldReferences(nameField);
155 assertThat(references, containsInAnyOrder( 149 assertThat(references, containsInAnyOrder(
156 newFieldReferenceByConstructor(m_nameField, m_baseClass.getName(), "(Ljava/lang/String;)V"), 150 newFieldReferenceByConstructor(nameField, baseClass.getName(), "(Ljava/lang/String;)V"),
157 newFieldReferenceByMethod(m_nameField, m_baseClass.getName(), "a", "()Ljava/lang/String;") 151 newFieldReferenceByMethod(nameField, baseClass.getName(), "a", "()Ljava/lang/String;")
158 )); 152 ));
159 153
160 // numThings 154 // numThings
161 references = m_index.getFieldReferences(m_numThingsField); 155 references = index.getFieldReferences(numThingsField);
162 assertThat(references, containsInAnyOrder( 156 assertThat(references, containsInAnyOrder(
163 newFieldReferenceByConstructor(m_numThingsField, m_subClassB.getName(), "()V"), 157 newFieldReferenceByConstructor(numThingsField, subClassB.getName(), "()V"),
164 newFieldReferenceByMethod(m_numThingsField, m_subClassB.getName(), "b", "()V") 158 newFieldReferenceByMethod(numThingsField, subClassB.getName(), "b", "()V")
165 )); 159 ));
166 } 160 }
167 161
@@ -173,33 +167,33 @@ public class TestJarIndexInheritanceTree {
173 Collection<EntryReference<BehaviorEntry,BehaviorEntry>> references; 167 Collection<EntryReference<BehaviorEntry,BehaviorEntry>> references;
174 168
175 // baseClass constructor 169 // baseClass constructor
176 source = newConstructor(m_baseClass, "(Ljava/lang/String;)V"); 170 source = newConstructor(baseClass, "(Ljava/lang/String;)V");
177 references = m_index.getBehaviorReferences(source); 171 references = index.getBehaviorReferences(source);
178 assertThat(references, containsInAnyOrder( 172 assertThat(references, containsInAnyOrder(
179 newBehaviorReferenceByConstructor(source, m_subClassA.getName(), "(Ljava/lang/String;)V"), 173 newBehaviorReferenceByConstructor(source, subClassA.getName(), "(Ljava/lang/String;)V"),
180 newBehaviorReferenceByConstructor(source, m_subClassB.getName(), "()V") 174 newBehaviorReferenceByConstructor(source, subClassB.getName(), "()V")
181 )); 175 ));
182 176
183 // subClassA constructor 177 // subClassA constructor
184 source = newConstructor(m_subClassA, "(Ljava/lang/String;)V"); 178 source = newConstructor(subClassA, "(Ljava/lang/String;)V");
185 references = m_index.getBehaviorReferences(source); 179 references = index.getBehaviorReferences(source);
186 assertThat(references, containsInAnyOrder( 180 assertThat(references, containsInAnyOrder(
187 newBehaviorReferenceByConstructor(source, m_subClassAA.getName(), "()V") 181 newBehaviorReferenceByConstructor(source, subClassAA.getName(), "()V")
188 )); 182 ));
189 183
190 // baseClass.getName() 184 // baseClass.getName()
191 source = newMethod(m_baseClass, "a", "()Ljava/lang/String;"); 185 source = newMethod(baseClass, "a", "()Ljava/lang/String;");
192 references = m_index.getBehaviorReferences(source); 186 references = index.getBehaviorReferences(source);
193 assertThat(references, containsInAnyOrder( 187 assertThat(references, containsInAnyOrder(
194 newBehaviorReferenceByMethod(source, m_subClassAA.getName(), "a", "()Ljava/lang/String;"), 188 newBehaviorReferenceByMethod(source, subClassAA.getName(), "a", "()Ljava/lang/String;"),
195 newBehaviorReferenceByMethod(source, m_subClassB.getName(), "a", "()V") 189 newBehaviorReferenceByMethod(source, subClassB.getName(), "a", "()V")
196 )); 190 ));
197 191
198 // subclassAA.getName() 192 // subclassAA.getName()
199 source = newMethod(m_subClassAA, "a", "()Ljava/lang/String;"); 193 source = newMethod(subClassAA, "a", "()Ljava/lang/String;");
200 references = m_index.getBehaviorReferences(source); 194 references = index.getBehaviorReferences(source);
201 assertThat(references, containsInAnyOrder( 195 assertThat(references, containsInAnyOrder(
202 newBehaviorReferenceByMethod(source, m_subClassAA.getName(), "a", "()V") 196 newBehaviorReferenceByMethod(source, subClassAA.getName(), "a", "()V")
203 )); 197 ));
204 } 198 }
205 199
@@ -207,33 +201,33 @@ public class TestJarIndexInheritanceTree {
207 public void containsEntries() { 201 public void containsEntries() {
208 202
209 // classes 203 // classes
210 assertThat(m_index.containsObfClass(m_baseClass), is(true)); 204 assertThat(index.containsObfClass(baseClass), is(true));
211 assertThat(m_index.containsObfClass(m_subClassA), is(true)); 205 assertThat(index.containsObfClass(subClassA), is(true));
212 assertThat(m_index.containsObfClass(m_subClassAA), is(true)); 206 assertThat(index.containsObfClass(subClassAA), is(true));
213 assertThat(m_index.containsObfClass(m_subClassB), is(true)); 207 assertThat(index.containsObfClass(subClassB), is(true));
214 208
215 // fields 209 // fields
216 assertThat(m_index.containsObfField(m_nameField), is(true)); 210 assertThat(index.containsObfField(nameField), is(true));
217 assertThat(m_index.containsObfField(m_numThingsField), is(true)); 211 assertThat(index.containsObfField(numThingsField), is(true));
218 212
219 // methods 213 // methods
220 // getName() 214 // getName()
221 assertThat(m_index.containsObfBehavior(newMethod(m_baseClass, "a", "()Ljava/lang/String;")), is(true)); 215 assertThat(index.containsObfBehavior(newMethod(baseClass, "a", "()Ljava/lang/String;")), is(true));
222 assertThat(m_index.containsObfBehavior(newMethod(m_subClassA, "a", "()Ljava/lang/String;")), is(false)); 216 assertThat(index.containsObfBehavior(newMethod(subClassA, "a", "()Ljava/lang/String;")), is(false));
223 assertThat(m_index.containsObfBehavior(newMethod(m_subClassAA, "a", "()Ljava/lang/String;")), is(true)); 217 assertThat(index.containsObfBehavior(newMethod(subClassAA, "a", "()Ljava/lang/String;")), is(true));
224 assertThat(m_index.containsObfBehavior(newMethod(m_subClassB, "a", "()Ljava/lang/String;")), is(false)); 218 assertThat(index.containsObfBehavior(newMethod(subClassB, "a", "()Ljava/lang/String;")), is(false));
225 219
226 // doBaseThings() 220 // doBaseThings()
227 assertThat(m_index.containsObfBehavior(newMethod(m_baseClass, "a", "()V")), is(true)); 221 assertThat(index.containsObfBehavior(newMethod(baseClass, "a", "()V")), is(true));
228 assertThat(m_index.containsObfBehavior(newMethod(m_subClassA, "a", "()V")), is(false)); 222 assertThat(index.containsObfBehavior(newMethod(subClassA, "a", "()V")), is(false));
229 assertThat(m_index.containsObfBehavior(newMethod(m_subClassAA, "a", "()V")), is(true)); 223 assertThat(index.containsObfBehavior(newMethod(subClassAA, "a", "()V")), is(true));
230 assertThat(m_index.containsObfBehavior(newMethod(m_subClassB, "a", "()V")), is(true)); 224 assertThat(index.containsObfBehavior(newMethod(subClassB, "a", "()V")), is(true));
231 225
232 // doBThings() 226 // doBThings()
233 assertThat(m_index.containsObfBehavior(newMethod(m_baseClass, "b", "()V")), is(false)); 227 assertThat(index.containsObfBehavior(newMethod(baseClass, "b", "()V")), is(false));
234 assertThat(m_index.containsObfBehavior(newMethod(m_subClassA, "b", "()V")), is(false)); 228 assertThat(index.containsObfBehavior(newMethod(subClassA, "b", "()V")), is(false));
235 assertThat(m_index.containsObfBehavior(newMethod(m_subClassAA, "b", "()V")), is(false)); 229 assertThat(index.containsObfBehavior(newMethod(subClassAA, "b", "()V")), is(false));
236 assertThat(m_index.containsObfBehavior(newMethod(m_subClassB, "b", "()V")), is(true)); 230 assertThat(index.containsObfBehavior(newMethod(subClassB, "b", "()V")), is(true));
237 231
238 } 232 }
239} 233}
diff --git a/src/test/java/cuchaz/enigma/TestJarIndexLoneClass.java b/src/test/java/cuchaz/enigma/TestJarIndexLoneClass.java
index 65af6d83..8efa57c6 100644
--- a/src/test/java/cuchaz/enigma/TestJarIndexLoneClass.java
+++ b/src/test/java/cuchaz/enigma/TestJarIndexLoneClass.java
@@ -34,17 +34,17 @@ import cuchaz.enigma.mapping.Translator;
34 34
35public class TestJarIndexLoneClass { 35public class TestJarIndexLoneClass {
36 36
37 private JarIndex m_index; 37 private JarIndex index;
38 38
39 public TestJarIndexLoneClass() 39 public TestJarIndexLoneClass()
40 throws Exception { 40 throws Exception {
41 m_index = new JarIndex(); 41 index = new JarIndex();
42 m_index.indexJar(new JarFile("build/test-obf/loneClass.jar"), false); 42 index.indexJar(new JarFile("build/test-obf/loneClass.jar"), false);
43 } 43 }
44 44
45 @Test 45 @Test
46 public void obfEntries() { 46 public void obfEntries() {
47 assertThat(m_index.getObfClassEntries(), containsInAnyOrder( 47 assertThat(index.getObfClassEntries(), containsInAnyOrder(
48 newClass("cuchaz/enigma/inputs/Keep"), 48 newClass("cuchaz/enigma/inputs/Keep"),
49 newClass("a") 49 newClass("a")
50 )); 50 ));
@@ -52,25 +52,25 @@ public class TestJarIndexLoneClass {
52 52
53 @Test 53 @Test
54 public void translationIndex() { 54 public void translationIndex() {
55 assertThat(m_index.getTranslationIndex().getSuperclass(new ClassEntry("a")), is(new ClassEntry("java/lang/Object"))); 55 assertThat(index.getTranslationIndex().getSuperclass(new ClassEntry("a")), is(new ClassEntry("java/lang/Object")));
56 assertThat(m_index.getTranslationIndex().getSuperclass(new ClassEntry("cuchaz/enigma/inputs/Keep")), is(new ClassEntry("java/lang/Object"))); 56 assertThat(index.getTranslationIndex().getSuperclass(new ClassEntry("cuchaz/enigma/inputs/Keep")), is(new ClassEntry("java/lang/Object")));
57 assertThat(m_index.getTranslationIndex().getAncestry(new ClassEntry("a")), contains(new ClassEntry("java/lang/Object"))); 57 assertThat(index.getTranslationIndex().getAncestry(new ClassEntry("a")), contains(new ClassEntry("java/lang/Object")));
58 assertThat(m_index.getTranslationIndex().getAncestry(new ClassEntry("cuchaz/enigma/inputs/Keep")), contains(new ClassEntry("java/lang/Object"))); 58 assertThat(index.getTranslationIndex().getAncestry(new ClassEntry("cuchaz/enigma/inputs/Keep")), contains(new ClassEntry("java/lang/Object")));
59 assertThat(m_index.getTranslationIndex().getSubclass(new ClassEntry("a")), is(empty())); 59 assertThat(index.getTranslationIndex().getSubclass(new ClassEntry("a")), is(empty()));
60 assertThat(m_index.getTranslationIndex().getSubclass(new ClassEntry("cuchaz/enigma/inputs/Keep")), is(empty())); 60 assertThat(index.getTranslationIndex().getSubclass(new ClassEntry("cuchaz/enigma/inputs/Keep")), is(empty()));
61 } 61 }
62 62
63 @Test 63 @Test
64 public void access() { 64 public void access() {
65 assertThat(m_index.getAccess(newField("a", "a", "Ljava/lang/String;")), is(Access.Private)); 65 assertThat(index.getAccess(newField("a", "a", "Ljava/lang/String;")), is(Access.PRIVATE));
66 assertThat(m_index.getAccess(newMethod("a", "a", "()Ljava/lang/String;")), is(Access.Public)); 66 assertThat(index.getAccess(newMethod("a", "a", "()Ljava/lang/String;")), is(Access.PUBLIC));
67 assertThat(m_index.getAccess(newField("a", "b", "Ljava/lang/String;")), is(nullValue())); 67 assertThat(index.getAccess(newField("a", "b", "Ljava/lang/String;")), is(nullValue()));
68 assertThat(m_index.getAccess(newField("a", "a", "LFoo;")), is(nullValue())); 68 assertThat(index.getAccess(newField("a", "a", "LFoo;")), is(nullValue()));
69 } 69 }
70 70
71 @Test 71 @Test
72 public void classInheritance() { 72 public void classInheritance() {
73 ClassInheritanceTreeNode node = m_index.getClassInheritance(new Translator(), newClass("a")); 73 ClassInheritanceTreeNode node = index.getClassInheritance(new Translator(), newClass("a"));
74 assertThat(node, is(not(nullValue()))); 74 assertThat(node, is(not(nullValue())));
75 assertThat(node.getObfClassName(), is("a")); 75 assertThat(node.getObfClassName(), is("a"));
76 assertThat(node.getChildCount(), is(0)); 76 assertThat(node.getChildCount(), is(0));
@@ -79,7 +79,7 @@ public class TestJarIndexLoneClass {
79 @Test 79 @Test
80 public void methodInheritance() { 80 public void methodInheritance() {
81 MethodEntry source = newMethod("a", "a", "()Ljava/lang/String;"); 81 MethodEntry source = newMethod("a", "a", "()Ljava/lang/String;");
82 MethodInheritanceTreeNode node = m_index.getMethodInheritance(new Translator(), source); 82 MethodInheritanceTreeNode node = index.getMethodInheritance(new Translator(), source);
83 assertThat(node, is(not(nullValue()))); 83 assertThat(node, is(not(nullValue())));
84 assertThat(node.getMethodEntry(), is(source)); 84 assertThat(node.getMethodEntry(), is(source));
85 assertThat(node.getChildCount(), is(0)); 85 assertThat(node.getChildCount(), is(0));
@@ -87,19 +87,19 @@ public class TestJarIndexLoneClass {
87 87
88 @Test 88 @Test
89 public void classImplementations() { 89 public void classImplementations() {
90 ClassImplementationsTreeNode node = m_index.getClassImplementations(new Translator(), newClass("a")); 90 ClassImplementationsTreeNode node = index.getClassImplementations(new Translator(), newClass("a"));
91 assertThat(node, is(nullValue())); 91 assertThat(node, is(nullValue()));
92 } 92 }
93 93
94 @Test 94 @Test
95 public void methodImplementations() { 95 public void methodImplementations() {
96 MethodEntry source = newMethod("a", "a", "()Ljava/lang/String;"); 96 MethodEntry source = newMethod("a", "a", "()Ljava/lang/String;");
97 assertThat(m_index.getMethodImplementations(new Translator(), source), is(empty())); 97 assertThat(index.getMethodImplementations(new Translator(), source), is(empty()));
98 } 98 }
99 99
100 @Test 100 @Test
101 public void relatedMethodImplementations() { 101 public void relatedMethodImplementations() {
102 Set<MethodEntry> entries = m_index.getRelatedMethodImplementations(newMethod("a", "a", "()Ljava/lang/String;")); 102 Set<MethodEntry> entries = index.getRelatedMethodImplementations(newMethod("a", "a", "()Ljava/lang/String;"));
103 assertThat(entries, containsInAnyOrder( 103 assertThat(entries, containsInAnyOrder(
104 newMethod("a", "a", "()Ljava/lang/String;") 104 newMethod("a", "a", "()Ljava/lang/String;")
105 )); 105 ));
@@ -109,7 +109,7 @@ public class TestJarIndexLoneClass {
109 @SuppressWarnings("unchecked") 109 @SuppressWarnings("unchecked")
110 public void fieldReferences() { 110 public void fieldReferences() {
111 FieldEntry source = newField("a", "a", "Ljava/lang/String;"); 111 FieldEntry source = newField("a", "a", "Ljava/lang/String;");
112 Collection<EntryReference<FieldEntry,BehaviorEntry>> references = m_index.getFieldReferences(source); 112 Collection<EntryReference<FieldEntry,BehaviorEntry>> references = index.getFieldReferences(source);
113 assertThat(references, containsInAnyOrder( 113 assertThat(references, containsInAnyOrder(
114 newFieldReferenceByConstructor(source, "a", "(Ljava/lang/String;)V"), 114 newFieldReferenceByConstructor(source, "a", "(Ljava/lang/String;)V"),
115 newFieldReferenceByMethod(source, "a", "a", "()Ljava/lang/String;") 115 newFieldReferenceByMethod(source, "a", "a", "()Ljava/lang/String;")
@@ -118,47 +118,47 @@ public class TestJarIndexLoneClass {
118 118
119 @Test 119 @Test
120 public void behaviorReferences() { 120 public void behaviorReferences() {
121 assertThat(m_index.getBehaviorReferences(newMethod("a", "a", "()Ljava/lang/String;")), is(empty())); 121 assertThat(index.getBehaviorReferences(newMethod("a", "a", "()Ljava/lang/String;")), is(empty()));
122 } 122 }
123 123
124 @Test 124 @Test
125 public void innerClasses() { 125 public void innerClasses() {
126 assertThat(m_index.getInnerClasses(newClass("a")), is(empty())); 126 assertThat(index.getInnerClasses(newClass("a")), is(empty()));
127 } 127 }
128 128
129 @Test 129 @Test
130 public void outerClass() { 130 public void outerClass() {
131 assertThat(m_index.getOuterClass(newClass("a")), is(nullValue())); 131 assertThat(index.getOuterClass(newClass("a")), is(nullValue()));
132 } 132 }
133 133
134 @Test 134 @Test
135 public void isAnonymousClass() { 135 public void isAnonymousClass() {
136 assertThat(m_index.isAnonymousClass(newClass("a")), is(false)); 136 assertThat(index.isAnonymousClass(newClass("a")), is(false));
137 } 137 }
138 138
139 @Test 139 @Test
140 public void interfaces() { 140 public void interfaces() {
141 assertThat(m_index.getInterfaces("a"), is(empty())); 141 assertThat(index.getInterfaces("a"), is(empty()));
142 } 142 }
143 143
144 @Test 144 @Test
145 public void implementingClasses() { 145 public void implementingClasses() {
146 assertThat(m_index.getImplementingClasses("a"), is(empty())); 146 assertThat(index.getImplementingClasses("a"), is(empty()));
147 } 147 }
148 148
149 @Test 149 @Test
150 public void isInterface() { 150 public void isInterface() {
151 assertThat(m_index.isInterface("a"), is(false)); 151 assertThat(index.isInterface("a"), is(false));
152 } 152 }
153 153
154 @Test 154 @Test
155 public void testContains() { 155 public void testContains() {
156 assertThat(m_index.containsObfClass(newClass("a")), is(true)); 156 assertThat(index.containsObfClass(newClass("a")), is(true));
157 assertThat(m_index.containsObfClass(newClass("b")), is(false)); 157 assertThat(index.containsObfClass(newClass("b")), is(false));
158 assertThat(m_index.containsObfField(newField("a", "a", "Ljava/lang/String;")), is(true)); 158 assertThat(index.containsObfField(newField("a", "a", "Ljava/lang/String;")), is(true));
159 assertThat(m_index.containsObfField(newField("a", "b", "Ljava/lang/String;")), is(false)); 159 assertThat(index.containsObfField(newField("a", "b", "Ljava/lang/String;")), is(false));
160 assertThat(m_index.containsObfField(newField("a", "a", "LFoo;")), is(false)); 160 assertThat(index.containsObfField(newField("a", "a", "LFoo;")), is(false));
161 assertThat(m_index.containsObfBehavior(newMethod("a", "a", "()Ljava/lang/String;")), is(true)); 161 assertThat(index.containsObfBehavior(newMethod("a", "a", "()Ljava/lang/String;")), is(true));
162 assertThat(m_index.containsObfBehavior(newMethod("a", "b", "()Ljava/lang/String;")), is(false)); 162 assertThat(index.containsObfBehavior(newMethod("a", "b", "()Ljava/lang/String;")), is(false));
163 } 163 }
164} 164}
diff --git a/src/test/java/cuchaz/enigma/TestTranslator.java b/src/test/java/cuchaz/enigma/TestTranslator.java
index c8af307b..2c54603b 100644
--- a/src/test/java/cuchaz/enigma/TestTranslator.java
+++ b/src/test/java/cuchaz/enigma/TestTranslator.java
@@ -22,21 +22,21 @@ import cuchaz.enigma.mapping.Translator;
22 22
23public class TestTranslator { 23public class TestTranslator {
24 24
25 private static Deobfuscator m_deobfuscator; 25 private static Deobfuscator deobfuscator;
26 private static Mappings m_mappings; 26 private static Mappings mappings;
27 private static Translator m_deobfTranslator; 27 private static Translator deobfTranslator;
28 private static Translator m_obfTranslator; 28 private static Translator obfTranslator;
29 29
30 @BeforeClass 30 @BeforeClass
31 public static void beforeClass() 31 public static void beforeClass()
32 throws Exception { 32 throws Exception {
33 //TODO FIx 33 //TODO FIx
34 //m_deobfuscator = new Deobfuscator(new JarFile("build/test-obf/translation.jar")); 34 //deobfuscator = new Deobfuscator(new JarFile("build/test-obf/translation.jar"));
35 //try (InputStream in = TestTranslator.class.getResourceAsStream("/cuchaz/enigma/resources/translation.mappings")) { 35 //try (InputStream in = TestTranslator.class.getResourceAsStream("/cuchaz/enigma/resources/translation.mappings")) {
36 // m_mappings = new MappingsJsonReader().read(new InputStreamReader(in)); 36 // mappings = new MappingsJsonReader().read(new InputStreamReader(in));
37 // m_deobfuscator.setMappings(m_mappings); 37 // deobfuscator.setMappings(mappings);
38 // m_deobfTranslator = m_deobfuscator.getTranslator(TranslationDirection.Deobfuscating); 38 // deobfTranslator = deobfuscator.getTranslator(TranslationDirection.Deobfuscating);
39 // m_obfTranslator = m_deobfuscator.getTranslator(TranslationDirection.Obfuscating); 39 // obfTranslator = deobfuscator.getTranslator(TranslationDirection.Obfuscating);
40 //} 40 //}
41 } 41 }
42 42
@@ -147,15 +147,15 @@ public class TestTranslator {
147 } 147 }
148 148
149 private void assertMapping(Entry obf, Entry deobf) { 149 private void assertMapping(Entry obf, Entry deobf) {
150 //assertThat(m_deobfTranslator.translateEntry(obf), is(deobf)); 150 //assertThat(deobfTranslator.translateEntry(obf), is(deobf));
151 //assertThat(m_obfTranslator.translateEntry(deobf), is(obf)); 151 //assertThat(obfTranslator.translateEntry(deobf), is(obf));
152 152
153 //String deobfName = m_deobfTranslator.translate(obf); 153 //String deobfName = deobfTranslator.translate(obf);
154 //if (deobfName != null) { 154 //if (deobfName != null) {
155 // assertThat(deobfName, is(deobf.getName())); 155 // assertThat(deobfName, is(deobf.getName()));
156 //} 156 //}
157 157
158 //String obfName = m_obfTranslator.translate(deobf); 158 //String obfName = obfTranslator.translate(deobf);
159 //if (obfName != null) { 159 //if (obfName != null) {
160 // assertThat(obfName, is(obf.getName())); 160 // assertThat(obfName, is(obf.getName()));
161 //} 161 //}
diff --git a/src/test/java/cuchaz/enigma/TokenChecker.java b/src/test/java/cuchaz/enigma/TokenChecker.java
index 7afb4cfe..07463206 100644
--- a/src/test/java/cuchaz/enigma/TokenChecker.java
+++ b/src/test/java/cuchaz/enigma/TokenChecker.java
@@ -25,20 +25,20 @@ import cuchaz.enigma.mapping.Entry;
25 25
26public class TokenChecker { 26public class TokenChecker {
27 27
28 private Deobfuscator m_deobfuscator; 28 private Deobfuscator deobfuscator;
29 29
30 protected TokenChecker(JarFile jarFile) 30 protected TokenChecker(JarFile jarFile)
31 throws IOException { 31 throws IOException {
32 m_deobfuscator = new Deobfuscator(jarFile); 32 deobfuscator = new Deobfuscator(jarFile);
33 } 33 }
34 34
35 protected String getDeclarationToken(Entry entry) { 35 protected String getDeclarationToken(Entry entry) {
36 // decompile the class 36 // decompile the class
37 CompilationUnit tree = m_deobfuscator.getSourceTree(entry.getClassName()); 37 CompilationUnit tree = deobfuscator.getSourceTree(entry.getClassName());
38 // DEBUG 38 // DEBUG
39 // tree.acceptVisitor( new TreeDumpVisitor( new File( "tree." + entry.getClassName().replace( '/', '.' ) + ".txt" ) ), null ); 39 // tree.acceptVisitor( new TreeDumpVisitor( new File( "tree." + entry.getClassName().replace( '/', '.' ) + ".txt" ) ), null );
40 String source = m_deobfuscator.getSource(tree); 40 String source = deobfuscator.getSource(tree);
41 SourceIndex index = m_deobfuscator.getSourceIndex(tree, source); 41 SourceIndex index = deobfuscator.getSourceIndex(tree, source);
42 42
43 // get the token value 43 // get the token value
44 Token token = index.getDeclarationToken(entry); 44 Token token = index.getDeclarationToken(entry);
@@ -51,9 +51,9 @@ public class TokenChecker {
51 @SuppressWarnings("unchecked") 51 @SuppressWarnings("unchecked")
52 protected Collection<String> getReferenceTokens(EntryReference<? extends Entry,? extends Entry> reference) { 52 protected Collection<String> getReferenceTokens(EntryReference<? extends Entry,? extends Entry> reference) {
53 // decompile the class 53 // decompile the class
54 CompilationUnit tree = m_deobfuscator.getSourceTree(reference.context.getClassName()); 54 CompilationUnit tree = deobfuscator.getSourceTree(reference.context.getClassName());
55 String source = m_deobfuscator.getSource(tree); 55 String source = deobfuscator.getSource(tree);
56 SourceIndex index = m_deobfuscator.getSourceIndex(tree, source); 56 SourceIndex index = deobfuscator.getSourceIndex(tree, source);
57 57
58 // get the token values 58 // get the token values
59 List<String> values = Lists.newArrayList(); 59 List<String> values = Lists.newArrayList();
diff --git a/src/test/java/cuchaz/enigma/inputs/inheritanceTree/BaseClass.java b/src/test/java/cuchaz/enigma/inputs/inheritanceTree/BaseClass.java
index d676ba24..1b1f3694 100644
--- a/src/test/java/cuchaz/enigma/inputs/inheritanceTree/BaseClass.java
+++ b/src/test/java/cuchaz/enigma/inputs/inheritanceTree/BaseClass.java
@@ -14,16 +14,16 @@ package cuchaz.enigma.inputs.inheritanceTree;
14public abstract class BaseClass { 14public abstract class BaseClass {
15 15
16 // a 16 // a
17 private String m_name; 17 private String name;
18 18
19 // <init>(Ljava/lang/String;)V 19 // <init>(Ljava/lang/String;)V
20 protected BaseClass(String name) { 20 protected BaseClass(String name) {
21 m_name = name; 21 this.name = name;
22 } 22 }
23 23
24 // a()Ljava/lang/String; 24 // a()Ljava/lang/String;
25 public String getName() { 25 public String getName() {
26 return m_name; 26 return name;
27 } 27 }
28 28
29 // a()V 29 // a()V
diff --git a/src/test/java/cuchaz/enigma/inputs/inheritanceTree/SubclassB.java b/src/test/java/cuchaz/enigma/inputs/inheritanceTree/SubclassB.java
index 751fdd16..6d3b0d0f 100644
--- a/src/test/java/cuchaz/enigma/inputs/inheritanceTree/SubclassB.java
+++ b/src/test/java/cuchaz/enigma/inputs/inheritanceTree/SubclassB.java
@@ -14,7 +14,7 @@ package cuchaz.enigma.inputs.inheritanceTree;
14public class SubclassB extends BaseClass { 14public class SubclassB extends BaseClass {
15 15
16 // a 16 // a
17 private int m_numThings; 17 private int numThings;
18 18
19 // <init>()V 19 // <init>()V
20 protected SubclassB() { 20 protected SubclassB() {
@@ -22,7 +22,7 @@ public class SubclassB extends BaseClass {
22 super("B"); 22 super("B");
23 23
24 // access to a 24 // access to a
25 m_numThings = 4; 25 numThings = 4;
26 } 26 }
27 27
28 @Override 28 @Override
@@ -35,6 +35,6 @@ public class SubclassB extends BaseClass {
35 // b()V 35 // b()V
36 public void doBThings() { 36 public void doBThings() {
37 // access to a 37 // access to a
38 System.out.println("" + m_numThings + " B things!"); 38 System.out.println("" + numThings + " B things!");
39 } 39 }
40} 40}
diff --git a/src/test/java/cuchaz/enigma/inputs/loneClass/LoneClass.java b/src/test/java/cuchaz/enigma/inputs/loneClass/LoneClass.java
index bf264fa5..d28ae97c 100644
--- a/src/test/java/cuchaz/enigma/inputs/loneClass/LoneClass.java
+++ b/src/test/java/cuchaz/enigma/inputs/loneClass/LoneClass.java
@@ -12,13 +12,13 @@ package cuchaz.enigma.inputs.loneClass;
12 12
13public class LoneClass { 13public class LoneClass {
14 14
15 private String m_name; 15 private String name;
16 16
17 public LoneClass(String name) { 17 public LoneClass(String name) {
18 m_name = name; 18 this.name = name;
19 } 19 }
20 20
21 public String getName() { 21 public String getName() {
22 return m_name; 22 return name;
23 } 23 }
24} 24}
diff --git a/src/test/java/cuchaz/enigma/inputs/translation/F_ObjectMethods.java b/src/test/java/cuchaz/enigma/inputs/translation/F_ObjectMethods.java
index 32c246cb..845d62b0 100644
--- a/src/test/java/cuchaz/enigma/inputs/translation/F_ObjectMethods.java
+++ b/src/test/java/cuchaz/enigma/inputs/translation/F_ObjectMethods.java
@@ -10,6 +10,7 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma.inputs.translation; 11package cuchaz.enigma.inputs.translation;
12 12
13@SuppressWarnings("FinalizeCalledExplicitly")
13public class F_ObjectMethods { 14public class F_ObjectMethods {
14 15
15 public void callEmAll() 16 public void callEmAll()