summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar jeff2014-08-20 01:21:52 -0400
committerGravatar jeff2014-08-20 01:21:52 -0400
commita85529d1ce6ec533809575ec84572de855464b36 (patch)
tree8f1894c272edf0e7eb22aec2f3af41f6bd19c092
parentstarted new reference navigation system (diff)
downloadenigma-fork-a85529d1ce6ec533809575ec84572de855464b36.tar.gz
enigma-fork-a85529d1ce6ec533809575ec84572de855464b36.tar.xz
enigma-fork-a85529d1ce6ec533809575ec84572de855464b36.zip
finished reference navigation system. Still need to debug and polish it, but the basic idea seems to work. =)
-rw-r--r--src/cuchaz/enigma/Deobfuscator.java105
-rw-r--r--src/cuchaz/enigma/Main.java1
-rw-r--r--src/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java12
-rw-r--r--src/cuchaz/enigma/analysis/EntryReference.java89
-rw-r--r--src/cuchaz/enigma/analysis/FieldReferenceTreeNode.java14
-rw-r--r--src/cuchaz/enigma/analysis/JarIndex.java43
-rw-r--r--src/cuchaz/enigma/analysis/ReferenceTreeNode.java6
-rw-r--r--src/cuchaz/enigma/analysis/SourceIndex.java51
-rw-r--r--src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java142
-rw-r--r--src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java114
-rw-r--r--src/cuchaz/enigma/analysis/SourceIndexVisitor.java600
-rw-r--r--src/cuchaz/enigma/analysis/Token.java6
-rw-r--r--src/cuchaz/enigma/gui/Gui.java158
-rw-r--r--src/cuchaz/enigma/gui/GuiController.java106
-rw-r--r--src/cuchaz/enigma/mapping/Translator.java28
15 files changed, 633 insertions, 842 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java
index 293e1c2..34e6033 100644
--- a/src/cuchaz/enigma/Deobfuscator.java
+++ b/src/cuchaz/enigma/Deobfuscator.java
@@ -26,6 +26,7 @@ import com.strobel.decompiler.languages.java.ast.AstBuilder;
26import com.strobel.decompiler.languages.java.ast.CompilationUnit; 26import com.strobel.decompiler.languages.java.ast.CompilationUnit;
27import com.strobel.decompiler.languages.java.ast.InsertParenthesesVisitor; 27import com.strobel.decompiler.languages.java.ast.InsertParenthesesVisitor;
28 28
29import cuchaz.enigma.analysis.EntryReference;
29import cuchaz.enigma.analysis.JarIndex; 30import cuchaz.enigma.analysis.JarIndex;
30import cuchaz.enigma.analysis.SourceIndex; 31import cuchaz.enigma.analysis.SourceIndex;
31import cuchaz.enigma.analysis.SourceIndexVisitor; 32import cuchaz.enigma.analysis.SourceIndexVisitor;
@@ -169,98 +170,92 @@ public class Deobfuscator
169 SourceIndex index = new SourceIndex( buf.toString() ); 170 SourceIndex index = new SourceIndex( buf.toString() );
170 root.acceptVisitor( new SourceIndexVisitor(), index ); 171 root.acceptVisitor( new SourceIndexVisitor(), index );
171 172
172 return index; 173 /* DEBUG
173 } 174 for( Token token : index.referenceTokens() )
174
175 // NOTE: these methods are a bit messy... oh well
176
177 public void rename( Entry obfEntry, String newName )
178 {
179 if( obfEntry instanceof ClassEntry )
180 { 175 {
181 m_renamer.setClassName( (ClassEntry)obfEntry, newName ); 176 EntryReference<Entry,Entry> reference = index.getDeobfReference( token );
182 } 177 System.out.println( token + " -> " + reference + " -> " + index.getReferenceToken( reference ) );
183 else if( obfEntry instanceof FieldEntry )
184 {
185 m_renamer.setFieldName( (FieldEntry)obfEntry, newName );
186 }
187 else if( obfEntry instanceof MethodEntry )
188 {
189 m_renamer.setMethodTreeName( (MethodEntry)obfEntry, newName );
190 }
191 else if( obfEntry instanceof ConstructorEntry )
192 {
193 m_renamer.setClassName( obfEntry.getClassEntry(), newName );
194 }
195 else if( obfEntry instanceof ArgumentEntry )
196 {
197 m_renamer.setArgumentName( (ArgumentEntry)obfEntry, newName );
198 }
199 else
200 {
201 throw new Error( "Unknown entry type: " + obfEntry.getClass().getName() );
202 } 178 }
179 */
203 180
204 // clear the type loader cache 181 return index;
205 m_typeLoader.clearCache();
206 } 182 }
207 183
208 public Entry obfuscateEntry( Entry deobfEntry ) 184 public Entry obfuscateEntry( Entry deobfEntry )
209 { 185 {
210 Translator translator = getTranslator( TranslationDirection.Obfuscating ); 186 if( deobfEntry == null )
211 if( deobfEntry instanceof ClassEntry )
212 {
213 return translator.translateEntry( (ClassEntry)deobfEntry );
214 }
215 else if( deobfEntry instanceof FieldEntry )
216 {
217 return translator.translateEntry( (FieldEntry)deobfEntry );
218 }
219 else if( deobfEntry instanceof MethodEntry )
220 { 187 {
221 return translator.translateEntry( (MethodEntry)deobfEntry ); 188 return null;
222 } 189 }
223 else if( deobfEntry instanceof ConstructorEntry ) 190 return getTranslator( TranslationDirection.Obfuscating ).translateEntry( deobfEntry );
191 }
192
193 public Entry deobfuscateEntry( Entry obfEntry )
194 {
195 if( obfEntry == null )
224 { 196 {
225 return translator.translateEntry( (ConstructorEntry)deobfEntry ); 197 return null;
226 } 198 }
227 else if( deobfEntry instanceof ArgumentEntry ) 199 return getTranslator( TranslationDirection.Deobfuscating ).translateEntry( obfEntry );
200 }
201
202 public EntryReference<Entry,Entry> obfuscateReference( EntryReference<Entry,Entry> deobfReference )
203 {
204 if( deobfReference == null )
228 { 205 {
229 return translator.translateEntry( (ArgumentEntry)deobfEntry ); 206 return null;
230 } 207 }
231 else 208 return new EntryReference<Entry,Entry>(
209 obfuscateEntry( deobfReference.entry ),
210 obfuscateEntry( deobfReference.context ),
211 deobfReference.pos
212 );
213 }
214
215 public EntryReference<Entry,Entry> deobfuscateReference( EntryReference<Entry,Entry> obfReference )
216 {
217 if( obfReference == null )
232 { 218 {
233 throw new Error( "Unknown entry type: " + deobfEntry.getClass().getName() ); 219 return null;
234 } 220 }
221 return new EntryReference<Entry,Entry>(
222 deobfuscateEntry( obfReference.entry ),
223 deobfuscateEntry( obfReference.context ),
224 obfReference.pos
225 );
235 } 226 }
236 227
237 public Entry deobfuscateEntry( Entry obfEntry ) 228 // NOTE: these methods are a bit messy... oh well
229
230 public void rename( Entry obfEntry, String newName )
238 { 231 {
239 Translator translator = getTranslator( TranslationDirection.Deobfuscating );
240 if( obfEntry instanceof ClassEntry ) 232 if( obfEntry instanceof ClassEntry )
241 { 233 {
242 return translator.translateEntry( (ClassEntry)obfEntry ); 234 m_renamer.setClassName( (ClassEntry)obfEntry, newName );
243 } 235 }
244 else if( obfEntry instanceof FieldEntry ) 236 else if( obfEntry instanceof FieldEntry )
245 { 237 {
246 return translator.translateEntry( (FieldEntry)obfEntry ); 238 m_renamer.setFieldName( (FieldEntry)obfEntry, newName );
247 } 239 }
248 else if( obfEntry instanceof MethodEntry ) 240 else if( obfEntry instanceof MethodEntry )
249 { 241 {
250 return translator.translateEntry( (MethodEntry)obfEntry ); 242 m_renamer.setMethodTreeName( (MethodEntry)obfEntry, newName );
251 } 243 }
252 else if( obfEntry instanceof ConstructorEntry ) 244 else if( obfEntry instanceof ConstructorEntry )
253 { 245 {
254 return translator.translateEntry( (ConstructorEntry)obfEntry ); 246 m_renamer.setClassName( obfEntry.getClassEntry(), newName );
255 } 247 }
256 else if( obfEntry instanceof ArgumentEntry ) 248 else if( obfEntry instanceof ArgumentEntry )
257 { 249 {
258 return translator.translateEntry( (ArgumentEntry)obfEntry ); 250 m_renamer.setArgumentName( (ArgumentEntry)obfEntry, newName );
259 } 251 }
260 else 252 else
261 { 253 {
262 throw new Error( "Unknown entry type: " + obfEntry.getClass().getName() ); 254 throw new Error( "Unknown entry type: " + obfEntry.getClass().getName() );
263 } 255 }
256
257 // clear the type loader cache
258 m_typeLoader.clearCache();
264 } 259 }
265 260
266 public boolean hasMapping( Entry obfEntry ) 261 public boolean hasMapping( Entry obfEntry )
diff --git a/src/cuchaz/enigma/Main.java b/src/cuchaz/enigma/Main.java
index 20d73c2..7d38bd6 100644
--- a/src/cuchaz/enigma/Main.java
+++ b/src/cuchaz/enigma/Main.java
@@ -13,7 +13,6 @@ package cuchaz.enigma;
13import java.io.File; 13import java.io.File;
14 14
15import cuchaz.enigma.gui.Gui; 15import cuchaz.enigma.gui.Gui;
16import cuchaz.enigma.mapping.ClassEntry;
17 16
18public class Main 17public class Main
19{ 18{
diff --git a/src/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java b/src/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java
index 158aad7..0f7e7f7 100644
--- a/src/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java
+++ b/src/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java
@@ -21,13 +21,13 @@ import cuchaz.enigma.mapping.BehaviorEntry;
21import cuchaz.enigma.mapping.Entry; 21import cuchaz.enigma.mapping.Entry;
22import cuchaz.enigma.mapping.Translator; 22import cuchaz.enigma.mapping.Translator;
23 23
24public class BehaviorReferenceTreeNode extends DefaultMutableTreeNode implements ReferenceTreeNode<BehaviorEntry> 24public class BehaviorReferenceTreeNode extends DefaultMutableTreeNode implements ReferenceTreeNode<BehaviorEntry,BehaviorEntry>
25{ 25{
26 private static final long serialVersionUID = -3658163700783307520L; 26 private static final long serialVersionUID = -3658163700783307520L;
27 27
28 private Translator m_deobfuscatingTranslator; 28 private Translator m_deobfuscatingTranslator;
29 private BehaviorEntry m_entry; 29 private BehaviorEntry m_entry;
30 private EntryReference<BehaviorEntry> m_reference; 30 private EntryReference<BehaviorEntry,BehaviorEntry> m_reference;
31 31
32 public BehaviorReferenceTreeNode( Translator deobfuscatingTranslator, BehaviorEntry entry ) 32 public BehaviorReferenceTreeNode( Translator deobfuscatingTranslator, BehaviorEntry entry )
33 { 33 {
@@ -36,7 +36,7 @@ public class BehaviorReferenceTreeNode extends DefaultMutableTreeNode implements
36 m_reference = null; 36 m_reference = null;
37 } 37 }
38 38
39 public BehaviorReferenceTreeNode( Translator deobfuscatingTranslator, EntryReference<BehaviorEntry> reference ) 39 public BehaviorReferenceTreeNode( Translator deobfuscatingTranslator, EntryReference<BehaviorEntry,BehaviorEntry> reference )
40 { 40 {
41 m_deobfuscatingTranslator = deobfuscatingTranslator; 41 m_deobfuscatingTranslator = deobfuscatingTranslator;
42 m_entry = reference.entry; 42 m_entry = reference.entry;
@@ -50,7 +50,7 @@ public class BehaviorReferenceTreeNode extends DefaultMutableTreeNode implements
50 } 50 }
51 51
52 @Override 52 @Override
53 public EntryReference<BehaviorEntry> getReference( ) 53 public EntryReference<BehaviorEntry,BehaviorEntry> getReference( )
54 { 54 {
55 return m_reference; 55 return m_reference;
56 } 56 }
@@ -60,7 +60,7 @@ public class BehaviorReferenceTreeNode extends DefaultMutableTreeNode implements
60 { 60 {
61 if( m_reference != null ) 61 if( m_reference != null )
62 { 62 {
63 return m_deobfuscatingTranslator.translateEntry( m_reference.caller ).toString(); 63 return m_deobfuscatingTranslator.translateEntry( m_reference.context ).toString();
64 } 64 }
65 return m_deobfuscatingTranslator.translateEntry( m_entry ).toString(); 65 return m_deobfuscatingTranslator.translateEntry( m_entry ).toString();
66 } 66 }
@@ -68,7 +68,7 @@ public class BehaviorReferenceTreeNode extends DefaultMutableTreeNode implements
68 public void load( JarIndex index, boolean recurse ) 68 public void load( JarIndex index, boolean recurse )
69 { 69 {
70 // get all the child nodes 70 // get all the child nodes
71 for( EntryReference<BehaviorEntry> reference : index.getBehaviorReferences( m_entry ) ) 71 for( EntryReference<BehaviorEntry,BehaviorEntry> reference : index.getBehaviorReferences( m_entry ) )
72 { 72 {
73 add( new BehaviorReferenceTreeNode( m_deobfuscatingTranslator, reference ) ); 73 add( new BehaviorReferenceTreeNode( m_deobfuscatingTranslator, reference ) );
74 } 74 }
diff --git a/src/cuchaz/enigma/analysis/EntryReference.java b/src/cuchaz/enigma/analysis/EntryReference.java
index f462210..869e08c 100644
--- a/src/cuchaz/enigma/analysis/EntryReference.java
+++ b/src/cuchaz/enigma/analysis/EntryReference.java
@@ -10,19 +10,96 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma.analysis; 11package cuchaz.enigma.analysis;
12 12
13import cuchaz.enigma.mapping.BehaviorEntry; 13import cuchaz.enigma.Util;
14import cuchaz.enigma.mapping.ClassEntry;
14import cuchaz.enigma.mapping.Entry; 15import cuchaz.enigma.mapping.Entry;
15 16
16public class EntryReference<T extends Entry> 17public class EntryReference<E extends Entry, C extends Entry>
17{ 18{
18 public T entry; 19 public E entry;
19 public BehaviorEntry caller; 20 public C context;
20 public int pos; 21 public int pos;
21 22
22 public EntryReference( T entry, BehaviorEntry caller, int pos ) 23 public EntryReference( E entry )
23 { 24 {
25 this( entry, null, -1 );
26 }
27
28 public EntryReference( E entry, C context, int pos )
29 {
30 if( entry == null )
31 {
32 throw new IllegalArgumentException( "Entry cannot be null!" );
33 }
34
24 this.entry = entry; 35 this.entry = entry;
25 this.caller = caller; 36 this.context = context;
26 this.pos = pos; 37 this.pos = pos;
27 } 38 }
39
40 public ClassEntry getClassEntry( )
41 {
42 if( context != null )
43 {
44 return context.getClassEntry();
45 }
46 return entry.getClassEntry();
47 }
48
49 @Override
50 public int hashCode( )
51 {
52 if( context != null )
53 {
54 return Util.combineHashesOrdered( entry.hashCode(), context.hashCode(), Integer.valueOf( pos ).hashCode() );
55 }
56 return entry.hashCode();
57 }
58
59 @Override
60 public boolean equals( Object other )
61 {
62 if( other instanceof EntryReference )
63 {
64 return equals( (EntryReference<?,?>)other );
65 }
66 return false;
67 }
68
69 public boolean equals( EntryReference<?,?> other )
70 {
71 // check entry first
72 boolean isEntrySame = entry.equals( other.entry );
73 if( !isEntrySame )
74 {
75 return false;
76 }
77
78 // check caller
79 if( context == null && other.context == null )
80 {
81 return true;
82 }
83 else if( context != null && other.context != null )
84 {
85 return context.equals( other.context ) && pos == other.pos;
86 }
87 return false;
88 }
89
90 @Override
91 public String toString( )
92 {
93 StringBuilder buf = new StringBuilder();
94 buf.append( entry );
95 if( context != null )
96 {
97 buf.append( " called from " );
98 buf.append( context );
99 buf.append( " (" );
100 buf.append( pos );
101 buf.append( ")" );
102 }
103 return buf.toString();
104 }
28} 105}
diff --git a/src/cuchaz/enigma/analysis/FieldReferenceTreeNode.java b/src/cuchaz/enigma/analysis/FieldReferenceTreeNode.java
index dd552d6..645e682 100644
--- a/src/cuchaz/enigma/analysis/FieldReferenceTreeNode.java
+++ b/src/cuchaz/enigma/analysis/FieldReferenceTreeNode.java
@@ -16,13 +16,13 @@ import cuchaz.enigma.mapping.BehaviorEntry;
16import cuchaz.enigma.mapping.FieldEntry; 16import cuchaz.enigma.mapping.FieldEntry;
17import cuchaz.enigma.mapping.Translator; 17import cuchaz.enigma.mapping.Translator;
18 18
19public class FieldReferenceTreeNode extends DefaultMutableTreeNode implements ReferenceTreeNode<FieldEntry> 19public class FieldReferenceTreeNode extends DefaultMutableTreeNode implements ReferenceTreeNode<FieldEntry,BehaviorEntry>
20{ 20{
21 private static final long serialVersionUID = -7934108091928699835L; 21 private static final long serialVersionUID = -7934108091928699835L;
22 22
23 private Translator m_deobfuscatingTranslator; 23 private Translator m_deobfuscatingTranslator;
24 private FieldEntry m_entry; 24 private FieldEntry m_entry;
25 private EntryReference<FieldEntry> m_reference; 25 private EntryReference<FieldEntry,BehaviorEntry> m_reference;
26 26
27 public FieldReferenceTreeNode( Translator deobfuscatingTranslator, FieldEntry entry ) 27 public FieldReferenceTreeNode( Translator deobfuscatingTranslator, FieldEntry entry )
28 { 28 {
@@ -31,7 +31,7 @@ public class FieldReferenceTreeNode extends DefaultMutableTreeNode implements Re
31 m_reference = null; 31 m_reference = null;
32 } 32 }
33 33
34 private FieldReferenceTreeNode( Translator deobfuscatingTranslator, EntryReference<FieldEntry> reference ) 34 private FieldReferenceTreeNode( Translator deobfuscatingTranslator, EntryReference<FieldEntry,BehaviorEntry> reference )
35 { 35 {
36 m_deobfuscatingTranslator = deobfuscatingTranslator; 36 m_deobfuscatingTranslator = deobfuscatingTranslator;
37 m_entry = reference.entry; 37 m_entry = reference.entry;
@@ -45,7 +45,7 @@ public class FieldReferenceTreeNode extends DefaultMutableTreeNode implements Re
45 } 45 }
46 46
47 @Override 47 @Override
48 public EntryReference<FieldEntry> getReference( ) 48 public EntryReference<FieldEntry,BehaviorEntry> getReference( )
49 { 49 {
50 return m_reference; 50 return m_reference;
51 } 51 }
@@ -55,7 +55,7 @@ public class FieldReferenceTreeNode extends DefaultMutableTreeNode implements Re
55 { 55 {
56 if( m_reference != null ) 56 if( m_reference != null )
57 { 57 {
58 return m_deobfuscatingTranslator.translateEntry( m_reference.caller ).toString(); 58 return m_deobfuscatingTranslator.translateEntry( m_reference.context ).toString();
59 } 59 }
60 return m_deobfuscatingTranslator.translateEntry( m_entry ).toString(); 60 return m_deobfuscatingTranslator.translateEntry( m_entry ).toString();
61 } 61 }
@@ -65,14 +65,14 @@ public class FieldReferenceTreeNode extends DefaultMutableTreeNode implements Re
65 // get all the child nodes 65 // get all the child nodes
66 if( m_reference == null ) 66 if( m_reference == null )
67 { 67 {
68 for( EntryReference<FieldEntry> reference : index.getFieldReferences( m_entry ) ) 68 for( EntryReference<FieldEntry,BehaviorEntry> reference : index.getFieldReferences( m_entry ) )
69 { 69 {
70 add( new FieldReferenceTreeNode( m_deobfuscatingTranslator, reference ) ); 70 add( new FieldReferenceTreeNode( m_deobfuscatingTranslator, reference ) );
71 } 71 }
72 } 72 }
73 else 73 else
74 { 74 {
75 for( EntryReference<BehaviorEntry> reference : index.getBehaviorReferences( m_reference.caller ) ) 75 for( EntryReference<BehaviorEntry,BehaviorEntry> reference : index.getBehaviorReferences( m_reference.context ) )
76 { 76 {
77 add( new BehaviorReferenceTreeNode( m_deobfuscatingTranslator, reference ) ); 77 add( new BehaviorReferenceTreeNode( m_deobfuscatingTranslator, reference ) );
78 } 78 }
diff --git a/src/cuchaz/enigma/analysis/JarIndex.java b/src/cuchaz/enigma/analysis/JarIndex.java
index f1c29c5..f408d93 100644
--- a/src/cuchaz/enigma/analysis/JarIndex.java
+++ b/src/cuchaz/enigma/analysis/JarIndex.java
@@ -56,8 +56,8 @@ public class JarIndex
56 private Set<String> m_obfClassNames; 56 private Set<String> m_obfClassNames;
57 private Ancestries m_ancestries; 57 private Ancestries m_ancestries;
58 private Multimap<String,MethodEntry> m_methodImplementations; 58 private Multimap<String,MethodEntry> m_methodImplementations;
59 private Multimap<BehaviorEntry,EntryReference<? extends Entry>> m_behaviorReferences; 59 private Multimap<BehaviorEntry,EntryReference<BehaviorEntry,BehaviorEntry>> m_behaviorReferences;
60 private Multimap<FieldEntry,EntryReference<? extends Entry>> m_fieldReferences; 60 private Multimap<FieldEntry,EntryReference<FieldEntry,BehaviorEntry>> m_fieldReferences;
61 private Multimap<String,String> m_innerClasses; 61 private Multimap<String,String> m_innerClasses;
62 private Map<String,String> m_outerClasses; 62 private Map<String,String> m_outerClasses;
63 private Set<String> m_anonymousClasses; 63 private Set<String> m_anonymousClasses;
@@ -108,12 +108,12 @@ public class JarIndex
108 m_anonymousClasses.add( innerClassName ); 108 m_anonymousClasses.add( innerClassName );
109 109
110 // DEBUG 110 // DEBUG
111 System.out.println( "ANONYMOUS: " + outerClassName + "$" + innerClassName ); 111 //System.out.println( "ANONYMOUS: " + outerClassName + "$" + innerClassName );
112 } 112 }
113 else 113 else
114 { 114 {
115 // DEBUG 115 // DEBUG
116 System.out.println( "INNER: " + outerClassName + "$" + innerClassName ); 116 //System.out.println( "INNER: " + outerClassName + "$" + innerClassName );
117 } 117 }
118 } 118 }
119 } 119 }
@@ -172,7 +172,7 @@ public class JarIndex
172 call.getSignature() 172 call.getSignature()
173 ); 173 );
174 callNumbers.add( calledMethodEntry ); 174 callNumbers.add( calledMethodEntry );
175 EntryReference<MethodEntry> reference = new EntryReference<MethodEntry>( 175 EntryReference<BehaviorEntry,BehaviorEntry> reference = new EntryReference<BehaviorEntry,BehaviorEntry>(
176 calledMethodEntry, 176 calledMethodEntry,
177 thisEntry, 177 thisEntry,
178 callNumbers.count( calledMethodEntry ) - 1 178 callNumbers.count( calledMethodEntry ) - 1
@@ -189,7 +189,7 @@ public class JarIndex
189 call.getFieldName() 189 call.getFieldName()
190 ); 190 );
191 callNumbers.add( calledFieldEntry ); 191 callNumbers.add( calledFieldEntry );
192 EntryReference<FieldEntry> reference = new EntryReference<FieldEntry>( 192 EntryReference<FieldEntry,BehaviorEntry> reference = new EntryReference<FieldEntry,BehaviorEntry>(
193 calledFieldEntry, 193 calledFieldEntry,
194 thisEntry, 194 thisEntry,
195 callNumbers.count( calledFieldEntry ) - 1 195 callNumbers.count( calledFieldEntry ) - 1
@@ -209,7 +209,7 @@ public class JarIndex
209 call.getSignature() 209 call.getSignature()
210 ); 210 );
211 callNumbers.add( calledConstructorEntry ); 211 callNumbers.add( calledConstructorEntry );
212 EntryReference<ConstructorEntry> reference = new EntryReference<ConstructorEntry>( 212 EntryReference<BehaviorEntry,BehaviorEntry> reference = new EntryReference<BehaviorEntry,BehaviorEntry>(
213 calledConstructorEntry, 213 calledConstructorEntry,
214 thisEntry, 214 thisEntry,
215 callNumbers.count( calledConstructorEntry ) - 1 215 callNumbers.count( calledConstructorEntry ) - 1
@@ -226,7 +226,7 @@ public class JarIndex
226 call.getSignature() 226 call.getSignature()
227 ); 227 );
228 callNumbers.add( calledConstructorEntry ); 228 callNumbers.add( calledConstructorEntry );
229 EntryReference<ConstructorEntry> reference = new EntryReference<ConstructorEntry>( 229 EntryReference<BehaviorEntry,BehaviorEntry> reference = new EntryReference<BehaviorEntry,BehaviorEntry>(
230 calledConstructorEntry, 230 calledConstructorEntry,
231 thisEntry, 231 thisEntry,
232 callNumbers.count( calledConstructorEntry ) - 1 232 callNumbers.count( calledConstructorEntry ) - 1
@@ -261,9 +261,9 @@ public class JarIndex
261 new ClassEntry( Descriptor.toJvmName( c.getName() ) ), 261 new ClassEntry( Descriptor.toJvmName( c.getName() ) ),
262 constructor.getMethodInfo().getDescriptor() 262 constructor.getMethodInfo().getDescriptor()
263 ); 263 );
264 for( EntryReference<BehaviorEntry> reference : getBehaviorReferences( constructorEntry ) ) 264 for( EntryReference<BehaviorEntry,BehaviorEntry> reference : getBehaviorReferences( constructorEntry ) )
265 { 265 {
266 callerClasses.add( reference.caller.getClassEntry() ); 266 callerClasses.add( reference.context.getClassEntry() );
267 } 267 }
268 268
269 // is this called by exactly one class? 269 // is this called by exactly one class?
@@ -496,26 +496,14 @@ public class JarIndex
496 return rootNode; 496 return rootNode;
497 } 497 }
498 498
499 @SuppressWarnings( "unchecked" ) 499 public Collection<EntryReference<FieldEntry,BehaviorEntry>> getFieldReferences( FieldEntry fieldEntry )
500 public Collection<EntryReference<FieldEntry>> getFieldReferences( FieldEntry fieldEntry )
501 { 500 {
502 List<EntryReference<FieldEntry>> references = Lists.newArrayList(); 501 return m_fieldReferences.get( fieldEntry );
503 for( EntryReference<? extends Entry> reference : m_fieldReferences.get( fieldEntry ) )
504 {
505 references.add( (EntryReference<FieldEntry>)reference );
506 }
507 return references;
508 } 502 }
509 503
510 @SuppressWarnings( "unchecked" ) 504 public Collection<EntryReference<BehaviorEntry,BehaviorEntry>> getBehaviorReferences( BehaviorEntry behaviorEntry )
511 public Collection<EntryReference<BehaviorEntry>> getBehaviorReferences( BehaviorEntry behaviorEntry )
512 { 505 {
513 List<EntryReference<BehaviorEntry>> references = Lists.newArrayList(); 506 return m_behaviorReferences.get( behaviorEntry );
514 for( EntryReference<? extends Entry> reference : m_behaviorReferences.get( behaviorEntry ) )
515 {
516 references.add( (EntryReference<BehaviorEntry>)reference );
517 }
518 return references;
519 } 507 }
520 508
521 public Collection<String> getInnerClasses( String obfOuterClassName ) 509 public Collection<String> getInnerClasses( String obfOuterClassName )
@@ -613,8 +601,9 @@ public class JarIndex
613 } 601 }
614 else if( thing instanceof EntryReference ) 602 else if( thing instanceof EntryReference )
615 { 603 {
616 EntryReference<Entry> reference = (EntryReference<Entry>)thing; 604 EntryReference<Entry,Entry> reference = (EntryReference<Entry,Entry>)thing;
617 reference.entry = renameThing( renames, reference.entry ); 605 reference.entry = renameThing( renames, reference.entry );
606 reference.context = renameThing( renames, reference.context );
618 return thing; 607 return thing;
619 } 608 }
620 else 609 else
diff --git a/src/cuchaz/enigma/analysis/ReferenceTreeNode.java b/src/cuchaz/enigma/analysis/ReferenceTreeNode.java
index 08ae39d..e0a0a74 100644
--- a/src/cuchaz/enigma/analysis/ReferenceTreeNode.java
+++ b/src/cuchaz/enigma/analysis/ReferenceTreeNode.java
@@ -12,8 +12,8 @@ package cuchaz.enigma.analysis;
12 12
13import cuchaz.enigma.mapping.Entry; 13import cuchaz.enigma.mapping.Entry;
14 14
15public interface ReferenceTreeNode<T extends Entry> 15public interface ReferenceTreeNode<E extends Entry, C extends Entry>
16{ 16{
17 T getEntry(); 17 E getEntry();
18 EntryReference<T> getReference(); 18 EntryReference<E,C> getReference();
19} 19}
diff --git a/src/cuchaz/enigma/analysis/SourceIndex.java b/src/cuchaz/enigma/analysis/SourceIndex.java
index 645a71d..bf890e3 100644
--- a/src/cuchaz/enigma/analysis/SourceIndex.java
+++ b/src/cuchaz/enigma/analysis/SourceIndex.java
@@ -10,6 +10,7 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma.analysis; 11package cuchaz.enigma.analysis;
12 12
13import java.util.HashMap;
13import java.util.List; 14import java.util.List;
14import java.util.Map; 15import java.util.Map;
15import java.util.TreeMap; 16import java.util.TreeMap;
@@ -24,15 +25,17 @@ import cuchaz.enigma.mapping.Entry;
24public class SourceIndex 25public class SourceIndex
25{ 26{
26 private String m_source; 27 private String m_source;
27 private TreeMap<Token,Entry> m_tokens; 28 private TreeMap<Token,EntryReference<Entry,Entry>> m_tokenToReference;
28 private Map<Entry,Token> m_declarations; 29 private HashMap<EntryReference<Entry,Entry>,Token> m_referenceToToken;
30 private Map<Entry,Token> m_declarationToToken;
29 private List<Integer> m_lineOffsets; 31 private List<Integer> m_lineOffsets;
30 32
31 public SourceIndex( String source ) 33 public SourceIndex( String source )
32 { 34 {
33 m_source = source; 35 m_source = source;
34 m_tokens = Maps.newTreeMap(); 36 m_tokenToReference = Maps.newTreeMap();
35 m_declarations = Maps.newHashMap(); 37 m_referenceToToken = Maps.newHashMap();
38 m_declarationToToken = Maps.newHashMap();
36 m_lineOffsets = Lists.newArrayList(); 39 m_lineOffsets = Lists.newArrayList();
37 40
38 // count the lines 41 // count the lines
@@ -87,12 +90,13 @@ public class SourceIndex
87 return token; 90 return token;
88 } 91 }
89 92
90 public void add( Identifier node, Entry deobfEntry ) 93 public void addReference( Identifier node, EntryReference<Entry,Entry> deobfReference )
91 { 94 {
92 Token token = getToken( node ); 95 Token token = getToken( node );
93 if( token != null ) 96 if( token != null )
94 { 97 {
95 m_tokens.put( token, deobfEntry ); 98 m_tokenToReference.put( token, deobfReference );
99 m_referenceToToken.put( deobfReference, token );
96 } 100 }
97 } 101 }
98 102
@@ -101,19 +105,16 @@ public class SourceIndex
101 Token token = getToken( node ); 105 Token token = getToken( node );
102 if( token != null ) 106 if( token != null )
103 { 107 {
104 m_tokens.put( token, deobfEntry ); 108 EntryReference<Entry,Entry> reference = new EntryReference<Entry,Entry>( deobfEntry );
105 m_declarations.put( deobfEntry, token ); 109 m_tokenToReference.put( token, reference );
110 m_referenceToToken.put( reference, token );
111 m_declarationToToken.put( deobfEntry, token );
106 } 112 }
107 } 113 }
108 114
109 public Token getToken( int pos ) 115 public Token getReferenceToken( int pos )
110 { 116 {
111 Map.Entry<Token,Entry> mapEntry = m_tokens.floorEntry( new Token( pos, pos ) ); 117 Token token = m_tokenToReference.floorKey( new Token( pos, pos ) );
112 if( mapEntry == null )
113 {
114 return null;
115 }
116 Token token = mapEntry.getKey();
117 if( token.contains( pos ) ) 118 if( token.contains( pos ) )
118 { 119 {
119 return token; 120 return token;
@@ -121,23 +122,33 @@ public class SourceIndex
121 return null; 122 return null;
122 } 123 }
123 124
124 public Entry getEntry( Token token ) 125 public Token getReferenceToken( EntryReference<Entry,Entry> deobfReference )
126 {
127 return m_referenceToToken.get( deobfReference );
128 }
129
130 public EntryReference<Entry,Entry> getDeobfReference( Token token )
125 { 131 {
126 if( token == null ) 132 if( token == null )
127 { 133 {
128 return null; 134 return null;
129 } 135 }
130 return m_tokens.get( token ); 136 return m_tokenToReference.get( token );
137 }
138
139 public Iterable<Token> referenceTokens( )
140 {
141 return m_tokenToReference.keySet();
131 } 142 }
132 143
133 public Iterable<Token> tokens( ) 144 public Iterable<Token> declarationTokens( )
134 { 145 {
135 return m_tokens.keySet(); 146 return m_declarationToToken.values();
136 } 147 }
137 148
138 public Token getDeclarationToken( Entry deobfEntry ) 149 public Token getDeclarationToken( Entry deobfEntry )
139 { 150 {
140 return m_declarations.get( deobfEntry ); 151 return m_declarationToToken.get( deobfEntry );
141 } 152 }
142 153
143 private int toPos( int line, int col ) 154 private int toPos( int line, int col )
diff --git a/src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java b/src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java
new file mode 100644
index 0000000..d3386c5
--- /dev/null
+++ b/src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java
@@ -0,0 +1,142 @@
1/*******************************************************************************
2 * Copyright (c) 2014 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Public License v3.0
5 * which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/gpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.analysis;
12
13import com.google.common.collect.HashMultiset;
14import com.google.common.collect.Multiset;
15import com.strobel.assembler.metadata.MemberReference;
16import com.strobel.assembler.metadata.MethodDefinition;
17import com.strobel.assembler.metadata.ParameterDefinition;
18import com.strobel.assembler.metadata.TypeReference;
19import com.strobel.decompiler.languages.TextLocation;
20import com.strobel.decompiler.languages.java.ast.ConstructorDeclaration;
21import com.strobel.decompiler.languages.java.ast.IdentifierExpression;
22import com.strobel.decompiler.languages.java.ast.InvocationExpression;
23import com.strobel.decompiler.languages.java.ast.Keys;
24import com.strobel.decompiler.languages.java.ast.MemberReferenceExpression;
25import com.strobel.decompiler.languages.java.ast.MethodDeclaration;
26import com.strobel.decompiler.languages.java.ast.ParameterDeclaration;
27import com.strobel.decompiler.languages.java.ast.SimpleType;
28
29import cuchaz.enigma.mapping.ArgumentEntry;
30import cuchaz.enigma.mapping.BehaviorEntry;
31import cuchaz.enigma.mapping.ClassEntry;
32import cuchaz.enigma.mapping.Entry;
33import cuchaz.enigma.mapping.FieldEntry;
34import cuchaz.enigma.mapping.MethodEntry;
35
36public class SourceIndexBehaviorVisitor extends SourceIndexVisitor
37{
38 private BehaviorEntry m_behaviorEntry;
39 private Multiset<Entry> m_indices;
40
41 public SourceIndexBehaviorVisitor( BehaviorEntry behaviorEntry )
42 {
43 m_behaviorEntry = behaviorEntry;
44 m_indices = HashMultiset.create();
45 }
46
47 @Override
48 public Void visitMethodDeclaration( MethodDeclaration node, SourceIndex index )
49 {
50 return recurse( node, index );
51 }
52
53 @Override
54 public Void visitConstructorDeclaration( ConstructorDeclaration node, SourceIndex index )
55 {
56 return recurse( node, index );
57 }
58
59 @Override
60 public Void visitInvocationExpression( InvocationExpression node, SourceIndex index )
61 {
62 MemberReference ref = node.getUserData( Keys.MEMBER_REFERENCE );
63 ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() );
64 MethodEntry methodEntry = new MethodEntry( classEntry, ref.getName(), ref.getSignature() );
65 if( node.getTarget() instanceof MemberReferenceExpression )
66 {
67 m_indices.add( methodEntry );
68 index.addReference(
69 ((MemberReferenceExpression)node.getTarget()).getMemberNameToken(),
70 new EntryReference<Entry,Entry>( methodEntry, m_behaviorEntry, m_indices.count( methodEntry ) )
71 );
72 }
73
74 return recurse( node, index );
75 }
76
77 @Override
78 public Void visitMemberReferenceExpression( MemberReferenceExpression node, SourceIndex index )
79 {
80 MemberReference ref = node.getUserData( Keys.MEMBER_REFERENCE );
81 if( ref != null )
82 {
83 ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() );
84 FieldEntry fieldEntry = new FieldEntry( classEntry, ref.getName() );
85 m_indices.add( fieldEntry );
86 index.addReference(
87 node.getMemberNameToken(),
88 new EntryReference<Entry,Entry>( fieldEntry, m_behaviorEntry, m_indices.count( fieldEntry ) )
89 );
90 }
91
92 return recurse( node, index );
93 }
94
95 @Override
96 public Void visitSimpleType( SimpleType node, SourceIndex index )
97 {
98 TypeReference ref = node.getUserData( Keys.TYPE_REFERENCE );
99 if( node.getIdentifierToken().getStartLocation() != TextLocation.EMPTY )
100 {
101 ClassEntry classEntry = new ClassEntry( ref.getInternalName() );
102 m_indices.add( classEntry );
103 index.addReference(
104 node.getIdentifierToken(),
105 new EntryReference<Entry,Entry>( classEntry, m_behaviorEntry, m_indices.count( classEntry ) )
106 );
107 }
108
109 return recurse( node, index );
110 }
111
112 @Override
113 public Void visitParameterDeclaration( ParameterDeclaration node, SourceIndex index )
114 {
115 ParameterDefinition def = node.getUserData( Keys.PARAMETER_DEFINITION );
116 ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() );
117 MethodDefinition methodDef = (MethodDefinition)def.getMethod();
118 MethodEntry methodEntry = new MethodEntry( classEntry, methodDef.getName(), methodDef.getSignature() );
119 ArgumentEntry argumentEntry = new ArgumentEntry( methodEntry, def.getPosition(), def.getName() );
120 index.addDeclaration( node.getNameToken(), argumentEntry );
121
122 return recurse( node, index );
123 }
124
125 @Override
126 public Void visitIdentifierExpression( IdentifierExpression node, SourceIndex index )
127 {
128 MemberReference ref = node.getUserData( Keys.MEMBER_REFERENCE );
129 if( ref != null )
130 {
131 ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() );
132 FieldEntry fieldEntry = new FieldEntry( classEntry, ref.getName() );
133 m_indices.add( fieldEntry );
134 index.addReference(
135 node.getIdentifierToken(),
136 new EntryReference<Entry,Entry>( fieldEntry, m_behaviorEntry, m_indices.count( fieldEntry ) )
137 );
138 }
139
140 return recurse( node, index );
141 }
142}
diff --git a/src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java b/src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java
new file mode 100644
index 0000000..2d4c0f5
--- /dev/null
+++ b/src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java
@@ -0,0 +1,114 @@
1/*******************************************************************************
2 * Copyright (c) 2014 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Public License v3.0
5 * which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/gpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.analysis;
12
13import com.google.common.collect.HashMultiset;
14import com.google.common.collect.Multiset;
15import com.strobel.assembler.metadata.FieldDefinition;
16import com.strobel.assembler.metadata.MethodDefinition;
17import com.strobel.assembler.metadata.TypeReference;
18import com.strobel.decompiler.languages.TextLocation;
19import com.strobel.decompiler.languages.java.ast.ConstructorDeclaration;
20import com.strobel.decompiler.languages.java.ast.EnumValueDeclaration;
21import com.strobel.decompiler.languages.java.ast.FieldDeclaration;
22import com.strobel.decompiler.languages.java.ast.Keys;
23import com.strobel.decompiler.languages.java.ast.MethodDeclaration;
24import com.strobel.decompiler.languages.java.ast.SimpleType;
25import com.strobel.decompiler.languages.java.ast.TypeDeclaration;
26import com.strobel.decompiler.languages.java.ast.VariableInitializer;
27
28import cuchaz.enigma.mapping.ClassEntry;
29import cuchaz.enigma.mapping.ConstructorEntry;
30import cuchaz.enigma.mapping.Entry;
31import cuchaz.enigma.mapping.FieldEntry;
32import cuchaz.enigma.mapping.MethodEntry;
33
34public class SourceIndexClassVisitor extends SourceIndexVisitor
35{
36 private ClassEntry m_classEntry;
37 private Multiset<Entry> m_indices;
38
39 public SourceIndexClassVisitor( ClassEntry classEntry )
40 {
41 m_classEntry = classEntry;
42 m_indices = HashMultiset.create();
43 }
44
45 @Override
46 public Void visitTypeDeclaration( TypeDeclaration node, SourceIndex index )
47 {
48 return recurse( node, index );
49 }
50
51 @Override
52 public Void visitSimpleType( SimpleType node, SourceIndex index )
53 {
54 TypeReference ref = node.getUserData( Keys.TYPE_REFERENCE );
55 if( node.getIdentifierToken().getStartLocation() != TextLocation.EMPTY )
56 {
57 ClassEntry classEntry = new ClassEntry( ref.getInternalName() );
58 index.addReference(
59 node.getIdentifierToken(),
60 new EntryReference<Entry,Entry>( classEntry, m_classEntry, m_indices.count( classEntry ) )
61 );
62 }
63
64 return recurse( node, index );
65 }
66
67 @Override
68 public Void visitMethodDeclaration( MethodDeclaration node, SourceIndex index )
69 {
70 MethodDefinition def = node.getUserData( Keys.METHOD_DEFINITION );
71 ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() );
72 MethodEntry methodEntry = new MethodEntry( classEntry, def.getName(), def.getSignature() );
73 index.addDeclaration( node.getNameToken(), methodEntry );
74 //if( !def.getName().equals( "<clinit>" ) )
75
76 return node.acceptVisitor( new SourceIndexBehaviorVisitor( methodEntry ), index );
77 }
78
79 @Override
80 public Void visitConstructorDeclaration( ConstructorDeclaration node, SourceIndex index )
81 {
82 MethodDefinition def = node.getUserData( Keys.METHOD_DEFINITION );
83 ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() );
84 ConstructorEntry constructorEntry = new ConstructorEntry( classEntry, def.getSignature() );
85 index.addDeclaration( node.getNameToken(), constructorEntry );
86
87 return recurse( node, index );
88 }
89
90 @Override
91 public Void visitFieldDeclaration( FieldDeclaration node, SourceIndex index )
92 {
93 FieldDefinition def = node.getUserData( Keys.FIELD_DEFINITION );
94 ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() );
95 FieldEntry fieldEntry = new FieldEntry( classEntry, def.getName() );
96 assert( node.getVariables().size() == 1 );
97 VariableInitializer variable = node.getVariables().firstOrNullObject();
98 index.addDeclaration( variable.getNameToken(), fieldEntry );
99
100 return recurse( node, index );
101 }
102
103 @Override
104 public Void visitEnumValueDeclaration( EnumValueDeclaration node, SourceIndex index )
105 {
106 // treat enum declarations as field declarations
107 FieldDefinition def = node.getUserData( Keys.FIELD_DEFINITION );
108 ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() );
109 FieldEntry fieldEntry = new FieldEntry( classEntry, def.getName() );
110 index.addDeclaration( node.getNameToken(), fieldEntry );
111
112 return recurse( node, index );
113 }
114}
diff --git a/src/cuchaz/enigma/analysis/SourceIndexVisitor.java b/src/cuchaz/enigma/analysis/SourceIndexVisitor.java
deleted file mode 100644
index 841d176..0000000
--- a/src/cuchaz/enigma/analysis/SourceIndexVisitor.java
+++ /dev/null
@@ -1,600 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2014 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Public License v3.0
5 * which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/gpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.analysis;
12
13import com.strobel.assembler.metadata.FieldDefinition;
14import com.strobel.assembler.metadata.MemberReference;
15import com.strobel.assembler.metadata.MethodDefinition;
16import com.strobel.assembler.metadata.ParameterDefinition;
17import com.strobel.assembler.metadata.TypeDefinition;
18import com.strobel.assembler.metadata.TypeReference;
19import com.strobel.decompiler.languages.TextLocation;
20import com.strobel.decompiler.languages.java.ast.Annotation;
21import com.strobel.decompiler.languages.java.ast.AnonymousObjectCreationExpression;
22import com.strobel.decompiler.languages.java.ast.ArrayCreationExpression;
23import com.strobel.decompiler.languages.java.ast.ArrayInitializerExpression;
24import com.strobel.decompiler.languages.java.ast.ArraySpecifier;
25import com.strobel.decompiler.languages.java.ast.AssertStatement;
26import com.strobel.decompiler.languages.java.ast.AssignmentExpression;
27import com.strobel.decompiler.languages.java.ast.AstNode;
28import com.strobel.decompiler.languages.java.ast.BinaryOperatorExpression;
29import com.strobel.decompiler.languages.java.ast.BlockStatement;
30import com.strobel.decompiler.languages.java.ast.BreakStatement;
31import com.strobel.decompiler.languages.java.ast.CaseLabel;
32import com.strobel.decompiler.languages.java.ast.CastExpression;
33import com.strobel.decompiler.languages.java.ast.CatchClause;
34import com.strobel.decompiler.languages.java.ast.ClassOfExpression;
35import com.strobel.decompiler.languages.java.ast.Comment;
36import com.strobel.decompiler.languages.java.ast.CompilationUnit;
37import com.strobel.decompiler.languages.java.ast.ComposedType;
38import com.strobel.decompiler.languages.java.ast.ConditionalExpression;
39import com.strobel.decompiler.languages.java.ast.ConstructorDeclaration;
40import com.strobel.decompiler.languages.java.ast.ContinueStatement;
41import com.strobel.decompiler.languages.java.ast.DoWhileStatement;
42import com.strobel.decompiler.languages.java.ast.EmptyStatement;
43import com.strobel.decompiler.languages.java.ast.EnumValueDeclaration;
44import com.strobel.decompiler.languages.java.ast.ExpressionStatement;
45import com.strobel.decompiler.languages.java.ast.FieldDeclaration;
46import com.strobel.decompiler.languages.java.ast.ForEachStatement;
47import com.strobel.decompiler.languages.java.ast.ForStatement;
48import com.strobel.decompiler.languages.java.ast.GotoStatement;
49import com.strobel.decompiler.languages.java.ast.IAstVisitor;
50import com.strobel.decompiler.languages.java.ast.Identifier;
51import com.strobel.decompiler.languages.java.ast.IdentifierExpression;
52import com.strobel.decompiler.languages.java.ast.IfElseStatement;
53import com.strobel.decompiler.languages.java.ast.ImportDeclaration;
54import com.strobel.decompiler.languages.java.ast.IndexerExpression;
55import com.strobel.decompiler.languages.java.ast.InstanceInitializer;
56import com.strobel.decompiler.languages.java.ast.InstanceOfExpression;
57import com.strobel.decompiler.languages.java.ast.InvocationExpression;
58import com.strobel.decompiler.languages.java.ast.JavaTokenNode;
59import com.strobel.decompiler.languages.java.ast.Keys;
60import com.strobel.decompiler.languages.java.ast.LabelStatement;
61import com.strobel.decompiler.languages.java.ast.LabeledStatement;
62import com.strobel.decompiler.languages.java.ast.LambdaExpression;
63import com.strobel.decompiler.languages.java.ast.LocalTypeDeclarationStatement;
64import com.strobel.decompiler.languages.java.ast.MemberReferenceExpression;
65import com.strobel.decompiler.languages.java.ast.MethodDeclaration;
66import com.strobel.decompiler.languages.java.ast.MethodGroupExpression;
67import com.strobel.decompiler.languages.java.ast.NewLineNode;
68import com.strobel.decompiler.languages.java.ast.NullReferenceExpression;
69import com.strobel.decompiler.languages.java.ast.ObjectCreationExpression;
70import com.strobel.decompiler.languages.java.ast.PackageDeclaration;
71import com.strobel.decompiler.languages.java.ast.ParameterDeclaration;
72import com.strobel.decompiler.languages.java.ast.ParenthesizedExpression;
73import com.strobel.decompiler.languages.java.ast.PrimitiveExpression;
74import com.strobel.decompiler.languages.java.ast.ReturnStatement;
75import com.strobel.decompiler.languages.java.ast.SimpleType;
76import com.strobel.decompiler.languages.java.ast.SuperReferenceExpression;
77import com.strobel.decompiler.languages.java.ast.SwitchSection;
78import com.strobel.decompiler.languages.java.ast.SwitchStatement;
79import com.strobel.decompiler.languages.java.ast.SynchronizedStatement;
80import com.strobel.decompiler.languages.java.ast.TextNode;
81import com.strobel.decompiler.languages.java.ast.ThisReferenceExpression;
82import com.strobel.decompiler.languages.java.ast.ThrowStatement;
83import com.strobel.decompiler.languages.java.ast.TryCatchStatement;
84import com.strobel.decompiler.languages.java.ast.TypeDeclaration;
85import com.strobel.decompiler.languages.java.ast.TypeParameterDeclaration;
86import com.strobel.decompiler.languages.java.ast.TypeReferenceExpression;
87import com.strobel.decompiler.languages.java.ast.UnaryOperatorExpression;
88import com.strobel.decompiler.languages.java.ast.VariableDeclarationStatement;
89import com.strobel.decompiler.languages.java.ast.VariableInitializer;
90import com.strobel.decompiler.languages.java.ast.WhileStatement;
91import com.strobel.decompiler.languages.java.ast.WildcardType;
92import com.strobel.decompiler.patterns.Pattern;
93
94import cuchaz.enigma.mapping.ArgumentEntry;
95import cuchaz.enigma.mapping.ClassEntry;
96import cuchaz.enigma.mapping.ConstructorEntry;
97import cuchaz.enigma.mapping.FieldEntry;
98import cuchaz.enigma.mapping.MethodEntry;
99
100public class SourceIndexVisitor implements IAstVisitor<SourceIndex, Void>
101{
102 @Override
103 public Void visitInvocationExpression( InvocationExpression node, SourceIndex index )
104 {
105 MemberReference ref = node.getUserData( Keys.MEMBER_REFERENCE );
106 ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() );
107 MethodEntry methodEntry = new MethodEntry( classEntry, ref.getName(), ref.getSignature() );
108 if( node.getTarget() instanceof MemberReferenceExpression )
109 {
110 index.add( ((MemberReferenceExpression)node.getTarget()).getMemberNameToken(), methodEntry );
111 }
112
113 return recurse( node, index );
114 }
115
116 @Override
117 public Void visitMemberReferenceExpression( MemberReferenceExpression node, SourceIndex index )
118 {
119 MemberReference ref = node.getUserData( Keys.MEMBER_REFERENCE );
120 if( ref != null )
121 {
122 ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() );
123 FieldEntry fieldEntry = new FieldEntry( classEntry, ref.getName() );
124 index.add( node.getMemberNameToken(), fieldEntry );
125 }
126
127 return recurse( node, index );
128 }
129
130 @Override
131 public Void visitSimpleType( SimpleType node, SourceIndex index )
132 {
133 TypeReference ref = node.getUserData( Keys.TYPE_REFERENCE );
134 if( node.getIdentifierToken().getStartLocation() != TextLocation.EMPTY )
135 {
136 index.add( node.getIdentifierToken(), new ClassEntry( ref.getInternalName() ) );
137 }
138
139 return recurse( node, index );
140 }
141
142 @Override
143 public Void visitMethodDeclaration( MethodDeclaration node, SourceIndex index )
144 {
145 MethodDefinition def = node.getUserData( Keys.METHOD_DEFINITION );
146
147 // static initializers don't have identifier tokens
148 if( !def.getName().equals( "<clinit>" ) )
149 {
150 ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() );
151 MethodEntry methodEntry = new MethodEntry( classEntry, def.getName(), def.getSignature() );
152 index.addDeclaration( node.getNameToken(), methodEntry );
153 }
154
155 return recurse( node, index );
156 }
157
158 @Override
159 public Void visitConstructorDeclaration( ConstructorDeclaration node, SourceIndex index )
160 {
161 MethodDefinition def = node.getUserData( Keys.METHOD_DEFINITION );
162 ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() );
163 ConstructorEntry constructorEntry = new ConstructorEntry( classEntry, def.getSignature() );
164 index.addDeclaration( node.getNameToken(), constructorEntry );
165
166 return recurse( node, index );
167 }
168
169 @Override
170 public Void visitParameterDeclaration( ParameterDeclaration node, SourceIndex index )
171 {
172 ParameterDefinition def = node.getUserData( Keys.PARAMETER_DEFINITION );
173 ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() );
174 MethodDefinition methodDef = (MethodDefinition)def.getMethod();
175 MethodEntry methodEntry = new MethodEntry( classEntry, methodDef.getName(), methodDef.getSignature() );
176 ArgumentEntry argumentEntry = new ArgumentEntry( methodEntry, def.getPosition(), def.getName() );
177 index.addDeclaration( node.getNameToken(), argumentEntry );
178
179 return recurse( node, index );
180 }
181
182 @Override
183 public Void visitFieldDeclaration( FieldDeclaration node, SourceIndex index )
184 {
185 FieldDefinition def = node.getUserData( Keys.FIELD_DEFINITION );
186 ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() );
187 FieldEntry fieldEntry = new FieldEntry( classEntry, def.getName() );
188 assert( node.getVariables().size() == 1 );
189 VariableInitializer variable = node.getVariables().firstOrNullObject();
190 index.addDeclaration( variable.getNameToken(), fieldEntry );
191
192 return recurse( node, index );
193 }
194
195 @Override
196 public Void visitTypeDeclaration( TypeDeclaration node, SourceIndex index )
197 {
198 TypeDefinition def = node.getUserData( Keys.TYPE_DEFINITION );
199 index.addDeclaration( node.getNameToken(), new ClassEntry( def.getInternalName() ) );
200
201 return recurse( node, index );
202 }
203
204 @Override
205 public Void visitEnumValueDeclaration( EnumValueDeclaration node, SourceIndex index )
206 {
207 // treat enum declarations as field declarations
208 FieldDefinition def = node.getUserData( Keys.FIELD_DEFINITION );
209 ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() );
210 FieldEntry fieldEntry = new FieldEntry( classEntry, def.getName() );
211 index.addDeclaration( node.getNameToken(), fieldEntry );
212
213 return recurse( node, index );
214 }
215
216 @Override
217 public Void visitIdentifierExpression( IdentifierExpression node, SourceIndex index )
218 {
219 MemberReference ref = node.getUserData( Keys.MEMBER_REFERENCE );
220 if( ref != null )
221 {
222 ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() );
223 FieldEntry fieldEntry = new FieldEntry( classEntry, ref.getName() );
224 index.add( node.getIdentifierToken(), fieldEntry );
225 }
226
227 return recurse( node, index );
228 }
229
230 private Void recurse( AstNode node, SourceIndex index )
231 {
232 for( final AstNode child : node.getChildren() )
233 {
234 child.acceptVisitor( this, index );
235 }
236 return null;
237 }
238
239 // OVERRIDES WE DON'T CARE ABOUT
240
241 @Override
242 public Void visitComment( Comment node, SourceIndex index )
243 {
244 return recurse( node, index );
245 }
246
247 @Override
248 public Void visitPatternPlaceholder( AstNode node, Pattern pattern, SourceIndex index )
249 {
250 return recurse( node, index );
251 }
252
253 @Override
254 public Void visitTypeReference( TypeReferenceExpression node, SourceIndex index )
255 {
256 return recurse( node, index );
257 }
258
259 @Override
260 public Void visitJavaTokenNode( JavaTokenNode node, SourceIndex index )
261 {
262 return recurse( node, index );
263 }
264
265 @Override
266 public Void visitIdentifier( Identifier node, SourceIndex index )
267 {
268 return recurse( node, index );
269 }
270
271 @Override
272 public Void visitNullReferenceExpression( NullReferenceExpression node, SourceIndex index )
273 {
274 return recurse( node, index );
275 }
276
277 @Override
278 public Void visitThisReferenceExpression( ThisReferenceExpression node, SourceIndex index )
279 {
280 return recurse( node, index );
281 }
282
283 @Override
284 public Void visitSuperReferenceExpression( SuperReferenceExpression node, SourceIndex index )
285 {
286 return recurse( node, index );
287 }
288
289 @Override
290 public Void visitClassOfExpression( ClassOfExpression node, SourceIndex index )
291 {
292 return recurse( node, index );
293 }
294
295 @Override
296 public Void visitBlockStatement( BlockStatement node, SourceIndex index )
297 {
298 return recurse( node, index );
299 }
300
301 @Override
302 public Void visitExpressionStatement( ExpressionStatement node, SourceIndex index )
303 {
304 return recurse( node, index );
305 }
306
307 @Override
308 public Void visitBreakStatement( BreakStatement node, SourceIndex index )
309 {
310 return recurse( node, index );
311 }
312
313 @Override
314 public Void visitContinueStatement( ContinueStatement node, SourceIndex index )
315 {
316 return recurse( node, index );
317 }
318
319 @Override
320 public Void visitDoWhileStatement( DoWhileStatement node, SourceIndex index )
321 {
322 return recurse( node, index );
323 }
324
325 @Override
326 public Void visitEmptyStatement( EmptyStatement node, SourceIndex index )
327 {
328 return recurse( node, index );
329 }
330
331 @Override
332 public Void visitIfElseStatement( IfElseStatement node, SourceIndex index )
333 {
334 return recurse( node, index );
335 }
336
337 @Override
338 public Void visitLabelStatement( LabelStatement node, SourceIndex index )
339 {
340 return recurse( node, index );
341 }
342
343 @Override
344 public Void visitLabeledStatement( LabeledStatement node, SourceIndex index )
345 {
346 return recurse( node, index );
347 }
348
349 @Override
350 public Void visitReturnStatement( ReturnStatement node, SourceIndex index )
351 {
352 return recurse( node, index );
353 }
354
355 @Override
356 public Void visitSwitchStatement( SwitchStatement node, SourceIndex index )
357 {
358 return recurse( node, index );
359 }
360
361 @Override
362 public Void visitSwitchSection( SwitchSection node, SourceIndex index )
363 {
364 return recurse( node, index );
365 }
366
367 @Override
368 public Void visitCaseLabel( CaseLabel node, SourceIndex index )
369 {
370 return recurse( node, index );
371 }
372
373 @Override
374 public Void visitThrowStatement( ThrowStatement node, SourceIndex index )
375 {
376 return recurse( node, index );
377 }
378
379 @Override
380 public Void visitCatchClause( CatchClause node, SourceIndex index )
381 {
382 return recurse( node, index );
383 }
384
385 @Override
386 public Void visitAnnotation( Annotation node, SourceIndex index )
387 {
388 return recurse( node, index );
389 }
390
391 @Override
392 public Void visitNewLine( NewLineNode node, SourceIndex index )
393 {
394 return recurse( node, index );
395 }
396
397 @Override
398 public Void visitVariableDeclaration( VariableDeclarationStatement node, SourceIndex index )
399 {
400 return recurse( node, index );
401 }
402
403 @Override
404 public Void visitVariableInitializer( VariableInitializer node, SourceIndex index )
405 {
406 return recurse( node, index );
407 }
408
409 @Override
410 public Void visitText( TextNode node, SourceIndex index )
411 {
412 return recurse( node, index );
413 }
414
415 @Override
416 public Void visitImportDeclaration( ImportDeclaration node, SourceIndex index )
417 {
418 return recurse( node, index );
419 }
420
421 @Override
422 public Void visitInitializerBlock( InstanceInitializer node, SourceIndex index )
423 {
424 return recurse( node, index );
425 }
426
427 @Override
428 public Void visitTypeParameterDeclaration( TypeParameterDeclaration node, SourceIndex index )
429 {
430 return recurse( node, index );
431 }
432
433 @Override
434 public Void visitCompilationUnit( CompilationUnit node, SourceIndex index )
435 {
436 return recurse( node, index );
437 }
438
439 @Override
440 public Void visitPackageDeclaration( PackageDeclaration node, SourceIndex index )
441 {
442 return recurse( node, index );
443 }
444
445 @Override
446 public Void visitArraySpecifier( ArraySpecifier node, SourceIndex index )
447 {
448 return recurse( node, index );
449 }
450
451 @Override
452 public Void visitComposedType( ComposedType node, SourceIndex index )
453 {
454 return recurse( node, index );
455 }
456
457 @Override
458 public Void visitWhileStatement( WhileStatement node, SourceIndex index )
459 {
460 return recurse( node, index );
461 }
462
463 @Override
464 public Void visitPrimitiveExpression( PrimitiveExpression node, SourceIndex index )
465 {
466 return recurse( node, index );
467 }
468
469 @Override
470 public Void visitCastExpression( CastExpression node, SourceIndex index )
471 {
472 return recurse( node, index );
473 }
474
475 @Override
476 public Void visitBinaryOperatorExpression( BinaryOperatorExpression node, SourceIndex index )
477 {
478 return recurse( node, index );
479 }
480
481 @Override
482 public Void visitInstanceOfExpression( InstanceOfExpression node, SourceIndex index )
483 {
484 return recurse( node, index );
485 }
486
487 @Override
488 public Void visitIndexerExpression( IndexerExpression node, SourceIndex index )
489 {
490 return recurse( node, index );
491 }
492
493 @Override
494 public Void visitUnaryOperatorExpression( UnaryOperatorExpression node, SourceIndex index )
495 {
496 return recurse( node, index );
497 }
498
499 @Override
500 public Void visitConditionalExpression( ConditionalExpression node, SourceIndex index )
501 {
502 return recurse( node, index );
503 }
504
505 @Override
506 public Void visitArrayInitializerExpression( ArrayInitializerExpression node, SourceIndex index )
507 {
508 return recurse( node, index );
509 }
510
511 @Override
512 public Void visitObjectCreationExpression( ObjectCreationExpression node, SourceIndex index )
513 {
514 return recurse( node, index );
515 }
516
517 @Override
518 public Void visitArrayCreationExpression( ArrayCreationExpression node, SourceIndex index )
519 {
520 return recurse( node, index );
521 }
522
523 @Override
524 public Void visitAssignmentExpression( AssignmentExpression node, SourceIndex index )
525 {
526 return recurse( node, index );
527 }
528
529 @Override
530 public Void visitForStatement( ForStatement node, SourceIndex index )
531 {
532 return recurse( node, index );
533 }
534
535 @Override
536 public Void visitForEachStatement( ForEachStatement node, SourceIndex index )
537 {
538 return recurse( node, index );
539 }
540
541 @Override
542 public Void visitTryCatchStatement( TryCatchStatement node, SourceIndex index )
543 {
544 return recurse( node, index );
545 }
546
547 @Override
548 public Void visitGotoStatement( GotoStatement node, SourceIndex index )
549 {
550 return recurse( node, index );
551 }
552
553 @Override
554 public Void visitParenthesizedExpression( ParenthesizedExpression node, SourceIndex index )
555 {
556 return recurse( node, index );
557 }
558
559 @Override
560 public Void visitSynchronizedStatement( SynchronizedStatement node, SourceIndex index )
561 {
562 return recurse( node, index );
563 }
564
565 @Override
566 public Void visitAnonymousObjectCreationExpression( AnonymousObjectCreationExpression node, SourceIndex index )
567 {
568 return recurse( node, index );
569 }
570
571 @Override
572 public Void visitWildcardType( WildcardType node, SourceIndex index )
573 {
574 return recurse( node, index );
575 }
576
577 @Override
578 public Void visitMethodGroupExpression( MethodGroupExpression node, SourceIndex index )
579 {
580 return recurse( node, index );
581 }
582
583 @Override
584 public Void visitAssertStatement( AssertStatement node, SourceIndex index )
585 {
586 return recurse( node, index );
587 }
588
589 @Override
590 public Void visitLambdaExpression( LambdaExpression node, SourceIndex index )
591 {
592 return recurse( node, index );
593 }
594
595 @Override
596 public Void visitLocalTypeDeclarationStatement( LocalTypeDeclarationStatement node, SourceIndex index )
597 {
598 return recurse( node, index );
599 }
600}
diff --git a/src/cuchaz/enigma/analysis/Token.java b/src/cuchaz/enigma/analysis/Token.java
index 74023e3..d0f2b70 100644
--- a/src/cuchaz/enigma/analysis/Token.java
+++ b/src/cuchaz/enigma/analysis/Token.java
@@ -46,4 +46,10 @@ public class Token implements Comparable<Token>
46 { 46 {
47 return start == other.start && end == other.end; 47 return start == other.start && end == other.end;
48 } 48 }
49
50 @Override
51 public String toString( )
52 {
53 return String.format( "[%d,%d]", start, end );
54 }
49} 55}
diff --git a/src/cuchaz/enigma/gui/Gui.java b/src/cuchaz/enigma/gui/Gui.java
index 43a0cda..341c149 100644
--- a/src/cuchaz/enigma/gui/Gui.java
+++ b/src/cuchaz/enigma/gui/Gui.java
@@ -68,6 +68,7 @@ import com.google.common.collect.Lists;
68import cuchaz.enigma.Constants; 68import cuchaz.enigma.Constants;
69import cuchaz.enigma.analysis.BehaviorReferenceTreeNode; 69import cuchaz.enigma.analysis.BehaviorReferenceTreeNode;
70import cuchaz.enigma.analysis.ClassInheritanceTreeNode; 70import cuchaz.enigma.analysis.ClassInheritanceTreeNode;
71import cuchaz.enigma.analysis.EntryReference;
71import cuchaz.enigma.analysis.FieldReferenceTreeNode; 72import cuchaz.enigma.analysis.FieldReferenceTreeNode;
72import cuchaz.enigma.analysis.MethodInheritanceTreeNode; 73import cuchaz.enigma.analysis.MethodInheritanceTreeNode;
73import cuchaz.enigma.analysis.ReferenceTreeNode; 74import cuchaz.enigma.analysis.ReferenceTreeNode;
@@ -76,7 +77,6 @@ import cuchaz.enigma.mapping.ArgumentEntry;
76import cuchaz.enigma.mapping.ClassEntry; 77import cuchaz.enigma.mapping.ClassEntry;
77import cuchaz.enigma.mapping.ConstructorEntry; 78import cuchaz.enigma.mapping.ConstructorEntry;
78import cuchaz.enigma.mapping.Entry; 79import cuchaz.enigma.mapping.Entry;
79import cuchaz.enigma.mapping.EntryPair;
80import cuchaz.enigma.mapping.FieldEntry; 80import cuchaz.enigma.mapping.FieldEntry;
81import cuchaz.enigma.mapping.IllegalNameException; 81import cuchaz.enigma.mapping.IllegalNameException;
82import cuchaz.enigma.mapping.MappingParseException; 82import cuchaz.enigma.mapping.MappingParseException;
@@ -160,7 +160,7 @@ public class Gui
160 private JMenuItem m_showCallsMenu; 160 private JMenuItem m_showCallsMenu;
161 161
162 // state 162 // state
163 private EntryPair<? extends Entry> m_selectedEntryPair; 163 private EntryReference<Entry,Entry> m_reference;
164 private JFileChooser m_jarFileChooser; 164 private JFileChooser m_jarFileChooser;
165 private JFileChooser m_mappingsFileChooser; 165 private JFileChooser m_mappingsFileChooser;
166 166
@@ -192,6 +192,10 @@ public class Gui
192 String selected = m_obfClasses.getSelectedValue(); 192 String selected = m_obfClasses.getSelectedValue();
193 if( selected != null ) 193 if( selected != null )
194 { 194 {
195 if( m_reference != null )
196 {
197 m_controller.savePreviousReference( m_reference );
198 }
195 m_controller.openDeclaration( new ClassEntry( selected ) ); 199 m_controller.openDeclaration( new ClassEntry( selected ) );
196 } 200 }
197 } 201 }
@@ -218,6 +222,10 @@ public class Gui
218 String selected = m_deobfClasses.getSelectedValue(); 222 String selected = m_deobfClasses.getSelectedValue();
219 if( selected != null ) 223 if( selected != null )
220 { 224 {
225 if( m_reference != null )
226 {
227 m_controller.savePreviousReference( m_reference );
228 }
221 m_controller.openDeclaration( new ClassEntry( selected ) ); 229 m_controller.openDeclaration( new ClassEntry( selected ) );
222 } 230 }
223 } 231 }
@@ -234,7 +242,7 @@ public class Gui
234 m_infoPanel.setLayout( new GridLayout( 4, 1, 0, 0 ) ); 242 m_infoPanel.setLayout( new GridLayout( 4, 1, 0, 0 ) );
235 m_infoPanel.setPreferredSize( new Dimension( 0, 100 ) ); 243 m_infoPanel.setPreferredSize( new Dimension( 0, 100 ) );
236 m_infoPanel.setBorder( BorderFactory.createTitledBorder( "Identifier Info" ) ); 244 m_infoPanel.setBorder( BorderFactory.createTitledBorder( "Identifier Info" ) );
237 clearEntryPair(); 245 clearReference();
238 246
239 // init editor 247 // init editor
240 DefaultSyntaxKit.initKit(); 248 DefaultSyntaxKit.initKit();
@@ -273,7 +281,7 @@ public class Gui
273 break; 281 break;
274 282
275 case KeyEvent.VK_P: 283 case KeyEvent.VK_P:
276 m_controller.openPreviousLocation(); 284 m_controller.openPreviousReference();
277 break; 285 break;
278 286
279 case KeyEvent.VK_C: 287 case KeyEvent.VK_C:
@@ -357,7 +365,7 @@ public class Gui
357 @Override 365 @Override
358 public void actionPerformed( ActionEvent event ) 366 public void actionPerformed( ActionEvent event )
359 { 367 {
360 m_controller.openPreviousLocation(); 368 m_controller.openPreviousReference();
361 } 369 }
362 } ); 370 } );
363 menu.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_P, 0 ) ); 371 menu.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_P, 0 ) );
@@ -386,6 +394,10 @@ public class Gui
386 Object node = path.getLastPathComponent(); 394 Object node = path.getLastPathComponent();
387 if( node instanceof ClassInheritanceTreeNode ) 395 if( node instanceof ClassInheritanceTreeNode )
388 { 396 {
397 if( m_reference != null )
398 {
399 m_controller.savePreviousReference( m_reference );
400 }
389 m_controller.openDeclaration( new ClassEntry( ((ClassInheritanceTreeNode)node).getObfClassName() ) ); 401 m_controller.openDeclaration( new ClassEntry( ((ClassInheritanceTreeNode)node).getObfClassName() ) );
390 } 402 }
391 else if( node instanceof MethodInheritanceTreeNode ) 403 else if( node instanceof MethodInheritanceTreeNode )
@@ -393,6 +405,10 @@ public class Gui
393 MethodInheritanceTreeNode methodNode = (MethodInheritanceTreeNode)node; 405 MethodInheritanceTreeNode methodNode = (MethodInheritanceTreeNode)node;
394 if( methodNode.isImplemented() ) 406 if( methodNode.isImplemented() )
395 { 407 {
408 if( m_reference != null )
409 {
410 m_controller.savePreviousReference( m_reference );
411 }
396 m_controller.openDeclaration( methodNode.getMethodEntry() ); 412 m_controller.openDeclaration( methodNode.getMethodEntry() );
397 } 413 }
398 } 414 }
@@ -424,7 +440,11 @@ public class Gui
424 Object node = path.getLastPathComponent(); 440 Object node = path.getLastPathComponent();
425 if( node instanceof ReferenceTreeNode ) 441 if( node instanceof ReferenceTreeNode )
426 { 442 {
427 ReferenceTreeNode<Entry> referenceNode = ((ReferenceTreeNode<Entry>)node); 443 if( m_reference != null )
444 {
445 m_controller.savePreviousReference( m_reference );
446 }
447 ReferenceTreeNode<Entry,Entry> referenceNode = ((ReferenceTreeNode<Entry,Entry>)node);
428 if( referenceNode.getReference() != null ) 448 if( referenceNode.getReference() != null )
429 { 449 {
430 m_controller.openReference( referenceNode.getReference() ); 450 m_controller.openReference( referenceNode.getReference() );
@@ -715,6 +735,10 @@ public class Gui
715 735
716 public void showToken( Token token ) 736 public void showToken( Token token )
717 { 737 {
738 if( token == null )
739 {
740 throw new IllegalArgumentException( "Token cannot be null!" );
741 }
718 m_editor.setCaretPosition( token.start ); 742 m_editor.setCaretPosition( token.start );
719 m_editor.grabFocus(); 743 m_editor.grabFocus();
720 } 744 }
@@ -752,7 +776,7 @@ public class Gui
752 } 776 }
753 } 777 }
754 778
755 private void clearEntryPair( ) 779 private void clearReference( )
756 { 780 {
757 m_infoPanel.removeAll(); 781 m_infoPanel.removeAll();
758 JLabel label = new JLabel( "No identifier selected" ); 782 JLabel label = new JLabel( "No identifier selected" );
@@ -763,76 +787,75 @@ public class Gui
763 redraw(); 787 redraw();
764 } 788 }
765 789
766 @SuppressWarnings( "unchecked" ) 790 private void showReference( EntryReference<Entry,Entry> reference )
767 private void showEntryPair( EntryPair<? extends Entry> pair )
768 { 791 {
769 if( pair == null ) 792 if( reference == null )
770 { 793 {
771 clearEntryPair(); 794 clearReference();
772 return; 795 return;
773 } 796 }
774 797
775 m_selectedEntryPair = pair; 798 m_reference = reference;
776 799
777 m_infoPanel.removeAll(); 800 m_infoPanel.removeAll();
778 if( pair.deobf instanceof ClassEntry ) 801 if( reference.entry instanceof ClassEntry )
779 { 802 {
780 showClassEntryPair( (EntryPair<ClassEntry>)pair ); 803 showClassEntry( (ClassEntry)m_reference.entry );
781 } 804 }
782 else if( pair.deobf instanceof FieldEntry ) 805 else if( m_reference.entry instanceof FieldEntry )
783 { 806 {
784 showFieldEntryPair( (EntryPair<FieldEntry>)pair ); 807 showFieldEntry( (FieldEntry)m_reference.entry );
785 } 808 }
786 else if( pair.deobf instanceof MethodEntry ) 809 else if( m_reference.entry instanceof MethodEntry )
787 { 810 {
788 showMethodEntryPair( (EntryPair<MethodEntry>)pair ); 811 showMethodEntry( (MethodEntry)m_reference.entry );
789 } 812 }
790 else if( pair.deobf instanceof ConstructorEntry ) 813 else if( m_reference.entry instanceof ConstructorEntry )
791 { 814 {
792 showConstructorEntryPair( (EntryPair<ConstructorEntry>)pair ); 815 showConstructorEntry( (ConstructorEntry)m_reference.entry );
793 } 816 }
794 else if( pair.deobf instanceof ArgumentEntry ) 817 else if( m_reference.entry instanceof ArgumentEntry )
795 { 818 {
796 showArgumentEntryPair( (EntryPair<ArgumentEntry>)pair ); 819 showArgumentEntry( (ArgumentEntry)m_reference.entry );
797 } 820 }
798 else 821 else
799 { 822 {
800 throw new Error( "Unknown entry type: " + pair.deobf.getClass().getName() ); 823 throw new Error( "Unknown entry type: " + m_reference.entry.getClass().getName() );
801 } 824 }
802 825
803 redraw(); 826 redraw();
804 } 827 }
805 828
806 private void showClassEntryPair( EntryPair<ClassEntry> pair ) 829 private void showClassEntry( ClassEntry entry )
807 { 830 {
808 addNameValue( m_infoPanel, "Class", pair.deobf.getName() ); 831 addNameValue( m_infoPanel, "Class", entry.getName() );
809 } 832 }
810 833
811 private void showFieldEntryPair( EntryPair<FieldEntry> pair ) 834 private void showFieldEntry( FieldEntry entry )
812 { 835 {
813 addNameValue( m_infoPanel, "Field", pair.deobf.getName() ); 836 addNameValue( m_infoPanel, "Field", entry.getName() );
814 addNameValue( m_infoPanel, "Class", pair.deobf.getClassEntry().getName() ); 837 addNameValue( m_infoPanel, "Class", entry.getClassEntry().getName() );
815 } 838 }
816 839
817 private void showMethodEntryPair( EntryPair<MethodEntry> pair ) 840 private void showMethodEntry( MethodEntry entry )
818 { 841 {
819 addNameValue( m_infoPanel, "Method", pair.deobf.getName() ); 842 addNameValue( m_infoPanel, "Method", entry.getName() );
820 addNameValue( m_infoPanel, "Class", pair.deobf.getClassEntry().getName() ); 843 addNameValue( m_infoPanel, "Class", entry.getClassEntry().getName() );
821 addNameValue( m_infoPanel, "Signature", pair.deobf.getSignature() ); 844 addNameValue( m_infoPanel, "Signature", entry.getSignature() );
822 } 845 }
823 846
824 private void showConstructorEntryPair( EntryPair<ConstructorEntry> pair ) 847 private void showConstructorEntry( ConstructorEntry entry )
825 { 848 {
826 addNameValue( m_infoPanel, "Constructor", pair.deobf.getClassEntry().getName() ); 849 addNameValue( m_infoPanel, "Constructor", entry.getClassEntry().getName() );
827 addNameValue( m_infoPanel, "Signature", pair.deobf.getSignature() ); 850 addNameValue( m_infoPanel, "Signature", entry.getSignature() );
828 } 851 }
829 852
830 private void showArgumentEntryPair( EntryPair<ArgumentEntry> pair ) 853 private void showArgumentEntry( ArgumentEntry entry )
831 { 854 {
832 addNameValue( m_infoPanel, "Argument", pair.deobf.getName() ); 855 addNameValue( m_infoPanel, "Argument", entry.getName() );
833 addNameValue( m_infoPanel, "Class", pair.deobf.getClassEntry().getName() ); 856 addNameValue( m_infoPanel, "Class", entry.getClassEntry().getName() );
834 addNameValue( m_infoPanel, "Method", pair.deobf.getMethodEntry().getName() ); 857 addNameValue( m_infoPanel, "Method", entry.getMethodEntry().getName() );
835 addNameValue( m_infoPanel, "Index", Integer.toString( pair.deobf.getIndex() ) ); 858 addNameValue( m_infoPanel, "Index", Integer.toString( entry.getIndex() ) );
836 } 859 }
837 860
838 private void addNameValue( JPanel container, String name, String value ) 861 private void addNameValue( JPanel container, String name, String value )
@@ -853,19 +876,19 @@ public class Gui
853 Token token = m_controller.getToken( pos ); 876 Token token = m_controller.getToken( pos );
854 boolean isToken = token != null; 877 boolean isToken = token != null;
855 878
856 m_selectedEntryPair = m_controller.getEntryPair( token ); 879 m_reference = m_controller.getDeobfReference( token );
857 boolean isClassEntry = isToken && m_selectedEntryPair.obf instanceof ClassEntry; 880 boolean isClassEntry = isToken && m_reference.entry instanceof ClassEntry;
858 boolean isFieldEntry = isToken && m_selectedEntryPair.obf instanceof FieldEntry; 881 boolean isFieldEntry = isToken && m_reference.entry instanceof FieldEntry;
859 boolean isMethodEntry = isToken && m_selectedEntryPair.obf instanceof MethodEntry; 882 boolean isMethodEntry = isToken && m_reference.entry instanceof MethodEntry;
860 boolean isConstructorEntry = isToken && m_selectedEntryPair.obf instanceof ConstructorEntry; 883 boolean isConstructorEntry = isToken && m_reference.entry instanceof ConstructorEntry;
861 884
862 if( isToken ) 885 if( isToken )
863 { 886 {
864 showEntryPair( m_selectedEntryPair ); 887 showReference( m_reference );
865 } 888 }
866 else 889 else
867 { 890 {
868 clearEntryPair(); 891 clearReference();
869 } 892 }
870 893
871 m_renameMenu.setEnabled( isToken ); 894 m_renameMenu.setEnabled( isToken );
@@ -878,11 +901,11 @@ public class Gui
878 private void startRename( ) 901 private void startRename( )
879 { 902 {
880 // get the class name 903 // get the class name
881 String className = m_selectedEntryPair.deobf.getName(); 904 ClassEntry classEntry = m_reference.entry.getClassEntry();
882 int pos = className.lastIndexOf( '$' ); 905 String className = classEntry.getName();
883 if( pos >= 0 ) 906 if( classEntry.isInnerClass() )
884 { 907 {
885 className = className.substring( pos + 1 ); 908 className = classEntry.getInnerClassName();
886 } 909 }
887 910
888 // init the text box 911 // init the text box
@@ -924,7 +947,7 @@ public class Gui
924 { 947 {
925 try 948 try
926 { 949 {
927 m_controller.rename( m_selectedEntryPair.obf, newName ); 950 m_controller.rename( m_reference, newName );
928 } 951 }
929 catch( IllegalNameException ex ) 952 catch( IllegalNameException ex )
930 { 953 {
@@ -937,7 +960,7 @@ public class Gui
937 // abort the rename 960 // abort the rename
938 JPanel panel = (JPanel)m_infoPanel.getComponent( 0 ); 961 JPanel panel = (JPanel)m_infoPanel.getComponent( 0 );
939 panel.remove( panel.getComponentCount() - 1 ); 962 panel.remove( panel.getComponentCount() - 1 );
940 panel.add( unboldLabel( new JLabel( m_selectedEntryPair.deobf.getName(), JLabel.LEFT ) ) ); 963 panel.add( unboldLabel( new JLabel( m_reference.entry.getName(), JLabel.LEFT ) ) );
941 964
942 m_editor.grabFocus(); 965 m_editor.grabFocus();
943 966
@@ -946,15 +969,15 @@ public class Gui
946 969
947 private void showInheritance( ) 970 private void showInheritance( )
948 { 971 {
949 if( m_selectedEntryPair == null ) 972 if( m_reference == null )
950 { 973 {
951 return; 974 return;
952 } 975 }
953 976
954 if( m_selectedEntryPair.obf instanceof ClassEntry ) 977 if( m_reference.entry instanceof ClassEntry )
955 { 978 {
956 // get the class inheritance 979 // get the class inheritance
957 ClassInheritanceTreeNode classNode = m_controller.getClassInheritance( (ClassEntry)m_selectedEntryPair.obf ); 980 ClassInheritanceTreeNode classNode = m_controller.getClassInheritance( (ClassEntry)m_reference.entry );
958 981
959 // show the tree at the root 982 // show the tree at the root
960 TreePath path = getPathToRoot( classNode ); 983 TreePath path = getPathToRoot( classNode );
@@ -962,10 +985,10 @@ public class Gui
962 m_inheritanceTree.expandPath( path ); 985 m_inheritanceTree.expandPath( path );
963 m_inheritanceTree.setSelectionRow( m_inheritanceTree.getRowForPath( path ) ); 986 m_inheritanceTree.setSelectionRow( m_inheritanceTree.getRowForPath( path ) );
964 } 987 }
965 else if( m_selectedEntryPair.obf instanceof MethodEntry ) 988 else if( m_reference.entry instanceof MethodEntry )
966 { 989 {
967 // get the method inheritance 990 // get the method inheritance
968 MethodInheritanceTreeNode classNode = m_controller.getMethodInheritance( (MethodEntry)m_selectedEntryPair.obf ); 991 MethodInheritanceTreeNode classNode = m_controller.getMethodInheritance( (MethodEntry)m_reference.entry );
969 992
970 // show the tree at the root 993 // show the tree at the root
971 TreePath path = getPathToRoot( classNode ); 994 TreePath path = getPathToRoot( classNode );
@@ -980,24 +1003,24 @@ public class Gui
980 1003
981 private void showCalls( ) 1004 private void showCalls( )
982 { 1005 {
983 if( m_selectedEntryPair == null ) 1006 if( m_reference == null )
984 { 1007 {
985 return; 1008 return;
986 } 1009 }
987 1010
988 if( m_selectedEntryPair.obf instanceof FieldEntry ) 1011 if( m_reference.entry instanceof FieldEntry )
989 { 1012 {
990 FieldReferenceTreeNode node = m_controller.getFieldReferences( (FieldEntry)m_selectedEntryPair.obf ); 1013 FieldReferenceTreeNode node = m_controller.getFieldReferences( (FieldEntry)m_reference.entry );
991 m_callsTree.setModel( new DefaultTreeModel( node ) ); 1014 m_callsTree.setModel( new DefaultTreeModel( node ) );
992 } 1015 }
993 else if( m_selectedEntryPair.obf instanceof MethodEntry ) 1016 else if( m_reference.entry instanceof MethodEntry )
994 { 1017 {
995 BehaviorReferenceTreeNode node = m_controller.getMethodReferences( (MethodEntry)m_selectedEntryPair.obf ); 1018 BehaviorReferenceTreeNode node = m_controller.getMethodReferences( (MethodEntry)m_reference.entry );
996 m_callsTree.setModel( new DefaultTreeModel( node ) ); 1019 m_callsTree.setModel( new DefaultTreeModel( node ) );
997 } 1020 }
998 else if( m_selectedEntryPair.obf instanceof ConstructorEntry ) 1021 else if( m_reference.entry instanceof ConstructorEntry )
999 { 1022 {
1000 BehaviorReferenceTreeNode node = m_controller.getMethodReferences( (ConstructorEntry)m_selectedEntryPair.obf ); 1023 BehaviorReferenceTreeNode node = m_controller.getMethodReferences( (ConstructorEntry)m_reference.entry );
1001 m_callsTree.setModel( new DefaultTreeModel( node ) ); 1024 m_callsTree.setModel( new DefaultTreeModel( node ) );
1002 } 1025 }
1003 1026
@@ -1021,11 +1044,12 @@ public class Gui
1021 1044
1022 private void openDeclaration( ) 1045 private void openDeclaration( )
1023 { 1046 {
1024 if( m_selectedEntryPair == null ) 1047 if( m_reference == null )
1025 { 1048 {
1026 return; 1049 return;
1027 } 1050 }
1028 m_controller.openDeclaration( m_selectedEntryPair.obf ); 1051 m_controller.savePreviousReference( m_reference );
1052 m_controller.openDeclaration( m_reference.entry );
1029 } 1053 }
1030 1054
1031 private void close( ) 1055 private void close( )
diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java
index f80bec7..dfa2557 100644
--- a/src/cuchaz/enigma/gui/GuiController.java
+++ b/src/cuchaz/enigma/gui/GuiController.java
@@ -14,10 +14,11 @@ import java.io.File;
14import java.io.FileReader; 14import java.io.FileReader;
15import java.io.FileWriter; 15import java.io.FileWriter;
16import java.io.IOException; 16import java.io.IOException;
17import java.util.Deque;
17import java.util.List; 18import java.util.List;
18import java.util.Stack;
19 19
20import com.google.common.collect.Lists; 20import com.google.common.collect.Lists;
21import com.google.common.collect.Queues;
21 22
22import cuchaz.enigma.Deobfuscator; 23import cuchaz.enigma.Deobfuscator;
23import cuchaz.enigma.analysis.BehaviorReferenceTreeNode; 24import cuchaz.enigma.analysis.BehaviorReferenceTreeNode;
@@ -30,7 +31,6 @@ import cuchaz.enigma.analysis.Token;
30import cuchaz.enigma.mapping.BehaviorEntry; 31import cuchaz.enigma.mapping.BehaviorEntry;
31import cuchaz.enigma.mapping.ClassEntry; 32import cuchaz.enigma.mapping.ClassEntry;
32import cuchaz.enigma.mapping.Entry; 33import cuchaz.enigma.mapping.Entry;
33import cuchaz.enigma.mapping.EntryPair;
34import cuchaz.enigma.mapping.FieldEntry; 34import cuchaz.enigma.mapping.FieldEntry;
35import cuchaz.enigma.mapping.MappingParseException; 35import cuchaz.enigma.mapping.MappingParseException;
36import cuchaz.enigma.mapping.MappingsReader; 36import cuchaz.enigma.mapping.MappingsReader;
@@ -43,18 +43,18 @@ public class GuiController
43 private Deobfuscator m_deobfuscator; 43 private Deobfuscator m_deobfuscator;
44 private Gui m_gui; 44 private Gui m_gui;
45 private SourceIndex m_index; 45 private SourceIndex m_index;
46 private ClassEntry m_currentClass; 46 private ClassEntry m_currentObfClass;
47 private boolean m_isDirty; 47 private boolean m_isDirty;
48 private Stack<Entry> m_locationStack; // TODO: make a location class, can be either Entry or EntryReference 48 private Deque<EntryReference<Entry,Entry>> m_referenceStack; // TODO: make a location class, can be either Entry or EntryReference
49 49
50 public GuiController( Gui gui ) 50 public GuiController( Gui gui )
51 { 51 {
52 m_gui = gui; 52 m_gui = gui;
53 m_deobfuscator = null; 53 m_deobfuscator = null;
54 m_index = null; 54 m_index = null;
55 m_currentClass = null; 55 m_currentObfClass = null;
56 m_isDirty = false; 56 m_isDirty = false;
57 m_locationStack = new Stack<Entry>(); 57 m_referenceStack = Queues.newArrayDeque();
58 } 58 }
59 59
60 public boolean isDirty( ) 60 public boolean isDirty( )
@@ -112,22 +112,16 @@ public class GuiController
112 return null; 112 return null;
113 } 113 }
114 114
115 return m_index.getToken( pos ); 115 return m_index.getReferenceToken( pos );
116 } 116 }
117 117
118 public EntryPair<Entry> getEntryPair( Token token ) 118 public EntryReference<Entry,Entry> getDeobfReference( Token token )
119 { 119 {
120 if( m_index == null ) 120 if( m_index == null )
121 { 121 {
122 return null; 122 return null;
123 } 123 }
124 124 return m_index.getDeobfReference( token );
125 Entry deobfEntry = m_index.getEntry( token );
126 if( deobfEntry == null )
127 {
128 return null;
129 }
130 return new EntryPair<Entry>( m_deobfuscator.obfuscateEntry( deobfEntry ), deobfEntry );
131 } 125 }
132 126
133 public boolean entryHasMapping( Entry deobfEntry ) 127 public boolean entryHasMapping( Entry deobfEntry )
@@ -178,54 +172,63 @@ public class GuiController
178 return rootNode; 172 return rootNode;
179 } 173 }
180 174
181 public void rename( Entry obfEntry, String newName ) 175 public void rename( EntryReference<Entry,Entry> deobfReference, String newName )
182 { 176 {
183 m_deobfuscator.rename( obfEntry, newName ); 177 EntryReference<Entry,Entry> obfReference = m_deobfuscator.obfuscateReference( deobfReference );
178 m_deobfuscator.rename( obfReference.entry, newName );
184 m_isDirty = true; 179 m_isDirty = true;
185 refreshClasses(); 180 refreshClasses();
186 refreshCurrentClass( obfEntry ); 181 refreshCurrentClass( obfReference );
187 } 182 }
188 183
189 public void openDeclaration( Entry entry ) 184 public void openDeclaration( Entry entry )
190 { 185 {
191 // go to the entry 186 if( entry == null )
192 Entry obfEntry = m_deobfuscator.obfuscateEntry( entry );
193 if( m_currentClass == null || !m_currentClass.equals( obfEntry.getClassEntry() ) )
194 { 187 {
195 m_currentClass = new ClassEntry( obfEntry.getClassEntry() ); 188 throw new IllegalArgumentException( "Entry cannot be null!" );
196 deobfuscate( m_currentClass, obfEntry );
197 } 189 }
198 else 190 openReference( new EntryReference<Entry,Entry>( entry ) );
191 }
192
193 public void openReference( EntryReference<Entry,Entry> deobfReference )
194 {
195 if( deobfReference == null )
199 { 196 {
200 m_gui.showToken( m_index.getDeclarationToken( m_deobfuscator.deobfuscateEntry( obfEntry ) ) ); 197 throw new IllegalArgumentException( "Reference cannot be null!" );
201 } 198 }
202 199
203 if( m_locationStack.isEmpty() || !m_locationStack.peek().equals( obfEntry ) ) 200 // get the reference target class
201 EntryReference<Entry,Entry> obfReference = m_deobfuscator.obfuscateReference( deobfReference );
202 ClassEntry obfClassEntry = obfReference.getClassEntry().getOuterClassEntry();
203 if( m_currentObfClass == null || !m_currentObfClass.equals( obfClassEntry ) )
204 {
205 // deobfuscate the class, then navigate to the reference
206 m_currentObfClass = obfClassEntry;
207 deobfuscate( m_currentObfClass, obfReference );
208 }
209 else
204 { 210 {
205 // update the stack 211 // the class file is already open, just navigate to the reference
206 m_locationStack.push( obfEntry ); 212 m_gui.showToken( m_index.getReferenceToken( deobfReference ) );
207 } 213 }
208 } 214 }
209 215
210 public void openReference( EntryReference<Entry> reference ) 216 public void savePreviousReference( EntryReference<Entry,Entry> deobfReference )
211 { 217 {
212 // TODO: find out how to load the n-th reference in a caller 218 m_referenceStack.push( m_deobfuscator.obfuscateReference( deobfReference ) );
213 // TEMP: just go to the caller for now
214 openDeclaration( reference.caller );
215 } 219 }
216 220
217 public void openPreviousLocation( ) 221 public void openPreviousReference( )
218 { 222 {
219 if( hasPreviousLocation() ) 223 if( hasPreviousLocation() )
220 { 224 {
221 m_locationStack.pop(); 225 openReference( m_deobfuscator.deobfuscateReference( m_referenceStack.pop() ) );
222 openDeclaration( m_locationStack.peek() );
223 } 226 }
224 } 227 }
225 228
226 public boolean hasPreviousLocation( ) 229 public boolean hasPreviousLocation( )
227 { 230 {
228 return m_locationStack.size() > 1; 231 return !m_referenceStack.isEmpty();
229 } 232 }
230 233
231 private void refreshClasses( ) 234 private void refreshClasses( )
@@ -242,15 +245,15 @@ public class GuiController
242 refreshCurrentClass( null ); 245 refreshCurrentClass( null );
243 } 246 }
244 247
245 private void refreshCurrentClass( Entry obfEntryToShow ) 248 private void refreshCurrentClass( EntryReference<Entry,Entry> obfReferenceToShow )
246 { 249 {
247 if( m_currentClass != null ) 250 if( m_currentObfClass != null )
248 { 251 {
249 deobfuscate( m_currentClass, obfEntryToShow ); 252 deobfuscate( m_currentObfClass, obfReferenceToShow );
250 } 253 }
251 } 254 }
252 255
253 private void deobfuscate( final ClassEntry classEntry, final Entry obfEntryToShow ) 256 private void deobfuscate( final ClassEntry classEntry, final EntryReference<Entry,Entry> obfReferenceToShow )
254 { 257 {
255 m_gui.setSource( "(deobfuscating...)" ); 258 m_gui.setSource( "(deobfuscating...)" );
256 259
@@ -263,29 +266,32 @@ public class GuiController
263 // decompile,deobfuscate the bytecode 266 // decompile,deobfuscate the bytecode
264 m_index = m_deobfuscator.getSource( classEntry.getClassName() ); 267 m_index = m_deobfuscator.getSource( classEntry.getClassName() );
265 m_gui.setSource( m_index.getSource() ); 268 m_gui.setSource( m_index.getSource() );
266 if( obfEntryToShow != null ) 269 if( obfReferenceToShow != null )
267 { 270 {
268 Entry deobfEntryToShow = m_deobfuscator.deobfuscateEntry( obfEntryToShow ); 271 EntryReference<Entry,Entry> deobfReferenceToShow = m_deobfuscator.deobfuscateReference( obfReferenceToShow );
269 Token token = m_index.getDeclarationToken( deobfEntryToShow ); 272 Token token = m_index.getReferenceToken( deobfReferenceToShow );
270 if( token == null ) 273 if( token == null )
271 { 274 {
272 // TEMP 275 // DEBUG
273 System.out.println( "WARNING: can't find token for " + obfEntryToShow + " -> " + deobfEntryToShow ); 276 System.out.println( "WARNING: can't find token for " + obfReferenceToShow + " -> " + deobfReferenceToShow );
277 }
278 else
279 {
280 m_gui.showToken( token );
274 } 281 }
275 m_gui.showToken( token );
276 } 282 }
277 283
278 // set the highlighted tokens 284 // set the highlighted tokens
279 List<Token> obfuscatedTokens = Lists.newArrayList(); 285 List<Token> obfuscatedTokens = Lists.newArrayList();
280 List<Token> deobfuscatedTokens = Lists.newArrayList(); 286 List<Token> deobfuscatedTokens = Lists.newArrayList();
281 for( Token token : m_index.tokens() ) 287 for( Token token : m_index.referenceTokens() )
282 { 288 {
283 Entry entry = m_index.getEntry( token ); 289 EntryReference<Entry,Entry> reference = m_index.getDeobfReference( token );
284 if( entryHasMapping( entry ) ) 290 if( entryHasMapping( reference.entry ) )
285 { 291 {
286 deobfuscatedTokens.add( token ); 292 deobfuscatedTokens.add( token );
287 } 293 }
288 else if( entryIsObfuscatedIdenfitier( entry ) ) 294 else if( entryIsObfuscatedIdenfitier( reference.entry ) )
289 { 295 {
290 obfuscatedTokens.add( token ); 296 obfuscatedTokens.add( token );
291 } 297 }
diff --git a/src/cuchaz/enigma/mapping/Translator.java b/src/cuchaz/enigma/mapping/Translator.java
index a1230db..e34c31b 100644
--- a/src/cuchaz/enigma/mapping/Translator.java
+++ b/src/cuchaz/enigma/mapping/Translator.java
@@ -30,6 +30,34 @@ public class Translator
30 m_ancestries = ancestries; 30 m_ancestries = ancestries;
31 } 31 }
32 32
33 public Entry translateEntry( Entry entry )
34 {
35 if( entry instanceof ClassEntry )
36 {
37 return translateEntry( (ClassEntry)entry );
38 }
39 else if( entry instanceof FieldEntry )
40 {
41 return translateEntry( (FieldEntry)entry );
42 }
43 else if( entry instanceof MethodEntry )
44 {
45 return translateEntry( (MethodEntry)entry );
46 }
47 else if( entry instanceof ConstructorEntry )
48 {
49 return translateEntry( (ConstructorEntry)entry );
50 }
51 else if( entry instanceof ArgumentEntry )
52 {
53 return translateEntry( (ArgumentEntry)entry );
54 }
55 else
56 {
57 throw new Error( "Unknown entry type: " + entry.getClass().getName() );
58 }
59 }
60
33 public String translateClass( String className ) 61 public String translateClass( String className )
34 { 62 {
35 return translate( new ClassEntry( className ) ); 63 return translate( new ClassEntry( className ) );