summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/analysis
diff options
context:
space:
mode:
Diffstat (limited to 'src/cuchaz/enigma/analysis')
-rw-r--r--src/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java105
-rw-r--r--src/cuchaz/enigma/analysis/EntryReference.java28
-rw-r--r--src/cuchaz/enigma/analysis/FieldCallsTreeNode.java82
-rw-r--r--src/cuchaz/enigma/analysis/FieldReferenceTreeNode.java92
-rw-r--r--src/cuchaz/enigma/analysis/JarIndex.java141
-rw-r--r--src/cuchaz/enigma/analysis/MethodCallsTreeNode.java144
-rw-r--r--src/cuchaz/enigma/analysis/ReferenceTreeNode.java19
-rw-r--r--src/cuchaz/enigma/analysis/SourceIndexVisitor.java20
-rw-r--r--src/cuchaz/enigma/analysis/TreeDumpVisitor.java11
9 files changed, 361 insertions, 281 deletions
diff --git a/src/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java b/src/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java
new file mode 100644
index 0000000..158aad7
--- /dev/null
+++ b/src/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java
@@ -0,0 +1,105 @@
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 java.util.Set;
14
15import javax.swing.tree.DefaultMutableTreeNode;
16import javax.swing.tree.TreeNode;
17
18import com.google.common.collect.Sets;
19
20import cuchaz.enigma.mapping.BehaviorEntry;
21import cuchaz.enigma.mapping.Entry;
22import cuchaz.enigma.mapping.Translator;
23
24public class BehaviorReferenceTreeNode extends DefaultMutableTreeNode implements ReferenceTreeNode<BehaviorEntry>
25{
26 private static final long serialVersionUID = -3658163700783307520L;
27
28 private Translator m_deobfuscatingTranslator;
29 private BehaviorEntry m_entry;
30 private EntryReference<BehaviorEntry> m_reference;
31
32 public BehaviorReferenceTreeNode( Translator deobfuscatingTranslator, BehaviorEntry entry )
33 {
34 m_deobfuscatingTranslator = deobfuscatingTranslator;
35 m_entry = entry;
36 m_reference = null;
37 }
38
39 public BehaviorReferenceTreeNode( Translator deobfuscatingTranslator, EntryReference<BehaviorEntry> reference )
40 {
41 m_deobfuscatingTranslator = deobfuscatingTranslator;
42 m_entry = reference.entry;
43 m_reference = reference;
44 }
45
46 @Override
47 public BehaviorEntry getEntry( )
48 {
49 return m_entry;
50 }
51
52 @Override
53 public EntryReference<BehaviorEntry> getReference( )
54 {
55 return m_reference;
56 }
57
58 @Override
59 public String toString( )
60 {
61 if( m_reference != null )
62 {
63 return m_deobfuscatingTranslator.translateEntry( m_reference.caller ).toString();
64 }
65 return m_deobfuscatingTranslator.translateEntry( m_entry ).toString();
66 }
67
68 public void load( JarIndex index, boolean recurse )
69 {
70 // get all the child nodes
71 for( EntryReference<BehaviorEntry> reference : index.getBehaviorReferences( m_entry ) )
72 {
73 add( new BehaviorReferenceTreeNode( m_deobfuscatingTranslator, reference ) );
74 }
75
76 if( recurse && children != null )
77 {
78 for( Object child : children )
79 {
80 if( child instanceof BehaviorReferenceTreeNode )
81 {
82 BehaviorReferenceTreeNode node = (BehaviorReferenceTreeNode)child;
83
84 // don't recurse into ancestor
85 Set<Entry> ancestors = Sets.newHashSet();
86 TreeNode n = (TreeNode)node;
87 while( n.getParent() != null )
88 {
89 n = n.getParent();
90 if( n instanceof BehaviorReferenceTreeNode )
91 {
92 ancestors.add( ((BehaviorReferenceTreeNode)n).getEntry() );
93 }
94 }
95 if( ancestors.contains( node.getEntry() ) )
96 {
97 continue;
98 }
99
100 node.load( index, true );
101 }
102 }
103 }
104 }
105}
diff --git a/src/cuchaz/enigma/analysis/EntryReference.java b/src/cuchaz/enigma/analysis/EntryReference.java
new file mode 100644
index 0000000..f462210
--- /dev/null
+++ b/src/cuchaz/enigma/analysis/EntryReference.java
@@ -0,0 +1,28 @@
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 cuchaz.enigma.mapping.BehaviorEntry;
14import cuchaz.enigma.mapping.Entry;
15
16public class EntryReference<T extends Entry>
17{
18 public T entry;
19 public BehaviorEntry caller;
20 public int pos;
21
22 public EntryReference( T entry, BehaviorEntry caller, int pos )
23 {
24 this.entry = entry;
25 this.caller = caller;
26 this.pos = pos;
27 }
28}
diff --git a/src/cuchaz/enigma/analysis/FieldCallsTreeNode.java b/src/cuchaz/enigma/analysis/FieldCallsTreeNode.java
deleted file mode 100644
index 0427b3b..0000000
--- a/src/cuchaz/enigma/analysis/FieldCallsTreeNode.java
+++ /dev/null
@@ -1,82 +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 javax.swing.tree.DefaultMutableTreeNode;
14
15import cuchaz.enigma.mapping.ConstructorEntry;
16import cuchaz.enigma.mapping.Entry;
17import cuchaz.enigma.mapping.FieldEntry;
18import cuchaz.enigma.mapping.MethodEntry;
19import cuchaz.enigma.mapping.Translator;
20
21public class FieldCallsTreeNode extends DefaultMutableTreeNode
22{
23 private static final long serialVersionUID = -7934108091928699835L;
24
25 private Translator m_deobfuscatingTranslator;
26 private FieldEntry m_entry;
27
28 public FieldCallsTreeNode( Translator deobfuscatingTranslator, FieldEntry fieldEntry )
29 {
30 m_deobfuscatingTranslator = deobfuscatingTranslator;
31 m_entry = fieldEntry;
32 }
33
34 public FieldEntry getFieldEntry( )
35 {
36 return m_entry;
37 }
38
39 @Override
40 public String toString( )
41 {
42 String className = m_deobfuscatingTranslator.translateClass( m_entry.getClassName() );
43 if( className == null )
44 {
45 className = m_entry.getClassName();
46 }
47
48 String targetName = m_deobfuscatingTranslator.translate( m_entry );
49 if( targetName == null )
50 {
51 targetName = m_entry.getName();
52 }
53 return className + "." + targetName;
54 }
55
56 public void load( JarIndex index, boolean recurse )
57 {
58 // get all the child nodes
59 for( Entry entry : index.getFieldCallers( m_entry ) )
60 {
61 if( entry instanceof MethodEntry )
62 {
63 add( new MethodCallsTreeNode( m_deobfuscatingTranslator, (MethodEntry)entry ) );
64 }
65 else if( entry instanceof ConstructorEntry )
66 {
67 add( new MethodCallsTreeNode( m_deobfuscatingTranslator, (ConstructorEntry)entry ) );
68 }
69 }
70
71 if( recurse && children != null )
72 {
73 for( Object node : children )
74 {
75 if( node instanceof MethodCallsTreeNode )
76 {
77 ((MethodCallsTreeNode)node).load( index, true );
78 }
79 }
80 }
81 }
82}
diff --git a/src/cuchaz/enigma/analysis/FieldReferenceTreeNode.java b/src/cuchaz/enigma/analysis/FieldReferenceTreeNode.java
new file mode 100644
index 0000000..dd552d6
--- /dev/null
+++ b/src/cuchaz/enigma/analysis/FieldReferenceTreeNode.java
@@ -0,0 +1,92 @@
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 javax.swing.tree.DefaultMutableTreeNode;
14
15import cuchaz.enigma.mapping.BehaviorEntry;
16import cuchaz.enigma.mapping.FieldEntry;
17import cuchaz.enigma.mapping.Translator;
18
19public class FieldReferenceTreeNode extends DefaultMutableTreeNode implements ReferenceTreeNode<FieldEntry>
20{
21 private static final long serialVersionUID = -7934108091928699835L;
22
23 private Translator m_deobfuscatingTranslator;
24 private FieldEntry m_entry;
25 private EntryReference<FieldEntry> m_reference;
26
27 public FieldReferenceTreeNode( Translator deobfuscatingTranslator, FieldEntry entry )
28 {
29 m_deobfuscatingTranslator = deobfuscatingTranslator;
30 m_entry = entry;
31 m_reference = null;
32 }
33
34 private FieldReferenceTreeNode( Translator deobfuscatingTranslator, EntryReference<FieldEntry> reference )
35 {
36 m_deobfuscatingTranslator = deobfuscatingTranslator;
37 m_entry = reference.entry;
38 m_reference = reference;
39 }
40
41 @Override
42 public FieldEntry getEntry( )
43 {
44 return m_entry;
45 }
46
47 @Override
48 public EntryReference<FieldEntry> getReference( )
49 {
50 return m_reference;
51 }
52
53 @Override
54 public String toString( )
55 {
56 if( m_reference != null )
57 {
58 return m_deobfuscatingTranslator.translateEntry( m_reference.caller ).toString();
59 }
60 return m_deobfuscatingTranslator.translateEntry( m_entry ).toString();
61 }
62
63 public void load( JarIndex index, boolean recurse )
64 {
65 // get all the child nodes
66 if( m_reference == null )
67 {
68 for( EntryReference<FieldEntry> reference : index.getFieldReferences( m_entry ) )
69 {
70 add( new FieldReferenceTreeNode( m_deobfuscatingTranslator, reference ) );
71 }
72 }
73 else
74 {
75 for( EntryReference<BehaviorEntry> reference : index.getBehaviorReferences( m_reference.caller ) )
76 {
77 add( new BehaviorReferenceTreeNode( m_deobfuscatingTranslator, reference ) );
78 }
79 }
80
81 if( recurse && children != null )
82 {
83 for( Object node : children )
84 {
85 if( node instanceof BehaviorReferenceTreeNode )
86 {
87 ((BehaviorReferenceTreeNode)node).load( index, true );
88 }
89 }
90 }
91 }
92}
diff --git a/src/cuchaz/enigma/analysis/JarIndex.java b/src/cuchaz/enigma/analysis/JarIndex.java
index 7d68c35..f1c29c5 100644
--- a/src/cuchaz/enigma/analysis/JarIndex.java
+++ b/src/cuchaz/enigma/analysis/JarIndex.java
@@ -35,12 +35,15 @@ import javassist.expr.MethodCall;
35import javassist.expr.NewExpr; 35import javassist.expr.NewExpr;
36 36
37import com.google.common.collect.HashMultimap; 37import com.google.common.collect.HashMultimap;
38import com.google.common.collect.HashMultiset;
38import com.google.common.collect.Lists; 39import com.google.common.collect.Lists;
39import com.google.common.collect.Maps; 40import com.google.common.collect.Maps;
40import com.google.common.collect.Multimap; 41import com.google.common.collect.Multimap;
42import com.google.common.collect.Multiset;
41import com.google.common.collect.Sets; 43import com.google.common.collect.Sets;
42 44
43import cuchaz.enigma.mapping.ArgumentEntry; 45import cuchaz.enigma.mapping.ArgumentEntry;
46import cuchaz.enigma.mapping.BehaviorEntry;
44import cuchaz.enigma.mapping.ClassEntry; 47import cuchaz.enigma.mapping.ClassEntry;
45import cuchaz.enigma.mapping.ConstructorEntry; 48import cuchaz.enigma.mapping.ConstructorEntry;
46import cuchaz.enigma.mapping.Entry; 49import cuchaz.enigma.mapping.Entry;
@@ -53,8 +56,8 @@ public class JarIndex
53 private Set<String> m_obfClassNames; 56 private Set<String> m_obfClassNames;
54 private Ancestries m_ancestries; 57 private Ancestries m_ancestries;
55 private Multimap<String,MethodEntry> m_methodImplementations; 58 private Multimap<String,MethodEntry> m_methodImplementations;
56 private Multimap<Entry,Entry> m_methodCalls; 59 private Multimap<BehaviorEntry,EntryReference<? extends Entry>> m_behaviorReferences;
57 private Multimap<FieldEntry,Entry> m_fieldCalls; 60 private Multimap<FieldEntry,EntryReference<? extends Entry>> m_fieldReferences;
58 private Multimap<String,String> m_innerClasses; 61 private Multimap<String,String> m_innerClasses;
59 private Map<String,String> m_outerClasses; 62 private Map<String,String> m_outerClasses;
60 private Set<String> m_anonymousClasses; 63 private Set<String> m_anonymousClasses;
@@ -64,8 +67,8 @@ public class JarIndex
64 m_obfClassNames = Sets.newHashSet(); 67 m_obfClassNames = Sets.newHashSet();
65 m_ancestries = new Ancestries(); 68 m_ancestries = new Ancestries();
66 m_methodImplementations = HashMultimap.create(); 69 m_methodImplementations = HashMultimap.create();
67 m_methodCalls = HashMultimap.create(); 70 m_behaviorReferences = HashMultimap.create();
68 m_fieldCalls = HashMultimap.create(); 71 m_fieldReferences = HashMultimap.create();
69 m_innerClasses = HashMultimap.create(); 72 m_innerClasses = HashMultimap.create();
70 m_outerClasses = Maps.newHashMap(); 73 m_outerClasses = Maps.newHashMap();
71 m_anonymousClasses = Sets.newHashSet(); 74 m_anonymousClasses = Sets.newHashSet();
@@ -128,7 +131,7 @@ public class JarIndex
128 { 131 {
129 // get the method entry 132 // get the method entry
130 String className = Descriptor.toJvmName( behavior.getDeclaringClass().getName() ); 133 String className = Descriptor.toJvmName( behavior.getDeclaringClass().getName() );
131 final Entry thisEntry; 134 final BehaviorEntry thisEntry;
132 if( behavior instanceof CtMethod ) 135 if( behavior instanceof CtMethod )
133 { 136 {
134 MethodEntry methodEntry = new MethodEntry( 137 MethodEntry methodEntry = new MethodEntry(
@@ -156,6 +159,7 @@ public class JarIndex
156 // index method calls 159 // index method calls
157 try 160 try
158 { 161 {
162 final Multiset<Entry> callNumbers = HashMultiset.create();
159 behavior.instrument( new ExprEditor( ) 163 behavior.instrument( new ExprEditor( )
160 { 164 {
161 @Override 165 @Override
@@ -167,7 +171,13 @@ public class JarIndex
167 call.getMethodName(), 171 call.getMethodName(),
168 call.getSignature() 172 call.getSignature()
169 ); 173 );
170 m_methodCalls.put( calledMethodEntry, thisEntry ); 174 callNumbers.add( calledMethodEntry );
175 EntryReference<MethodEntry> reference = new EntryReference<MethodEntry>(
176 calledMethodEntry,
177 thisEntry,
178 callNumbers.count( calledMethodEntry ) - 1
179 );
180 m_behaviorReferences.put( calledMethodEntry, reference );
171 } 181 }
172 182
173 @Override 183 @Override
@@ -178,22 +188,33 @@ public class JarIndex
178 new ClassEntry( className ), 188 new ClassEntry( className ),
179 call.getFieldName() 189 call.getFieldName()
180 ); 190 );
181 m_fieldCalls.put( calledFieldEntry, thisEntry ); 191 callNumbers.add( calledFieldEntry );
192 EntryReference<FieldEntry> reference = new EntryReference<FieldEntry>(
193 calledFieldEntry,
194 thisEntry,
195 callNumbers.count( calledFieldEntry ) - 1
196 );
197 m_fieldReferences.put( calledFieldEntry, reference );
182 } 198 }
183 199
184 @Override 200 @Override
185 public void edit( ConstructorCall call ) 201 public void edit( ConstructorCall call )
186 { 202 {
203 // TODO: save isSuper in the reference somehow
187 boolean isSuper = call.getMethodName().equals( "super" ); 204 boolean isSuper = call.getMethodName().equals( "super" );
188 // TODO: make method reference class, update method calls tree to use Invocation instances
189 // this might end up being a big refactor... =(
190 205
191 String className = Descriptor.toJvmName( call.getClassName() ); 206 String className = Descriptor.toJvmName( call.getClassName() );
192 ConstructorEntry calledConstructorEntry = new ConstructorEntry( 207 ConstructorEntry calledConstructorEntry = new ConstructorEntry(
193 new ClassEntry( className ), 208 new ClassEntry( className ),
194 call.getSignature() 209 call.getSignature()
195 ); 210 );
196 m_methodCalls.put( calledConstructorEntry, thisEntry ); 211 callNumbers.add( calledConstructorEntry );
212 EntryReference<ConstructorEntry> reference = new EntryReference<ConstructorEntry>(
213 calledConstructorEntry,
214 thisEntry,
215 callNumbers.count( calledConstructorEntry ) - 1
216 );
217 m_behaviorReferences.put( calledConstructorEntry, reference );
197 } 218 }
198 219
199 @Override 220 @Override
@@ -204,7 +225,13 @@ public class JarIndex
204 new ClassEntry( className ), 225 new ClassEntry( className ),
205 call.getSignature() 226 call.getSignature()
206 ); 227 );
207 m_methodCalls.put( calledConstructorEntry, thisEntry ); 228 callNumbers.add( calledConstructorEntry );
229 EntryReference<ConstructorEntry> reference = new EntryReference<ConstructorEntry>(
230 calledConstructorEntry,
231 thisEntry,
232 callNumbers.count( calledConstructorEntry ) - 1
233 );
234 m_behaviorReferences.put( calledConstructorEntry, reference );
208 } 235 }
209 } ); 236 } );
210 } 237 }
@@ -234,9 +261,9 @@ public class JarIndex
234 new ClassEntry( Descriptor.toJvmName( c.getName() ) ), 261 new ClassEntry( Descriptor.toJvmName( c.getName() ) ),
235 constructor.getMethodInfo().getDescriptor() 262 constructor.getMethodInfo().getDescriptor()
236 ); 263 );
237 for( Entry callerEntry : getMethodCallers( constructorEntry ) ) 264 for( EntryReference<BehaviorEntry> reference : getBehaviorReferences( constructorEntry ) )
238 { 265 {
239 callerClasses.add( callerEntry.getClassEntry() ); 266 callerClasses.add( reference.caller.getClassEntry() );
240 } 267 }
241 268
242 // is this called by exactly one class? 269 // is this called by exactly one class?
@@ -388,7 +415,7 @@ public class JarIndex
388 new ClassEntry( innerClassName ), 415 new ClassEntry( innerClassName ),
389 constructor.getMethodInfo().getDescriptor() 416 constructor.getMethodInfo().getDescriptor()
390 ); 417 );
391 if( getMethodCallers( constructorEntry ).size() != 1 ) 418 if( getBehaviorReferences( constructorEntry ).size() != 1 )
392 { 419 {
393 return false; 420 return false;
394 } 421 }
@@ -469,14 +496,26 @@ public class JarIndex
469 return rootNode; 496 return rootNode;
470 } 497 }
471 498
472 public Collection<Entry> getFieldCallers( FieldEntry fieldEntry ) 499 @SuppressWarnings( "unchecked" )
500 public Collection<EntryReference<FieldEntry>> getFieldReferences( FieldEntry fieldEntry )
473 { 501 {
474 return m_fieldCalls.get( fieldEntry ); 502 List<EntryReference<FieldEntry>> references = Lists.newArrayList();
503 for( EntryReference<? extends Entry> reference : m_fieldReferences.get( fieldEntry ) )
504 {
505 references.add( (EntryReference<FieldEntry>)reference );
506 }
507 return references;
475 } 508 }
476 509
477 public Collection<Entry> getMethodCallers( Entry entry ) 510 @SuppressWarnings( "unchecked" )
511 public Collection<EntryReference<BehaviorEntry>> getBehaviorReferences( BehaviorEntry behaviorEntry )
478 { 512 {
479 return m_methodCalls.get( entry ); 513 List<EntryReference<BehaviorEntry>> references = Lists.newArrayList();
514 for( EntryReference<? extends Entry> reference : m_behaviorReferences.get( behaviorEntry ) )
515 {
516 references.add( (EntryReference<BehaviorEntry>)reference );
517 }
518 return references;
480 } 519 }
481 520
482 public Collection<String> getInnerClasses( String obfOuterClassName ) 521 public Collection<String> getInnerClasses( String obfOuterClassName )
@@ -498,85 +537,91 @@ public class JarIndex
498 { 537 {
499 m_ancestries.renameClasses( renames ); 538 m_ancestries.renameClasses( renames );
500 renameMultimap( renames, m_methodImplementations ); 539 renameMultimap( renames, m_methodImplementations );
501 renameMultimap( renames, m_methodCalls ); 540 renameMultimap( renames, m_behaviorReferences );
502 renameMultimap( renames, m_fieldCalls ); 541 renameMultimap( renames, m_fieldReferences );
503 } 542 }
504 543
505 private <T,U> void renameMultimap( Map<String,String> renames, Multimap<T,U> map ) 544 private <Key,Val> void renameMultimap( Map<String,String> renames, Multimap<Key,Val> map )
506 { 545 {
507 // for each key/value pair... 546 // for each key/value pair...
508 Set<Map.Entry<T,U>> entriesToAdd = Sets.newHashSet(); 547 Set<Map.Entry<Key,Val>> entriesToAdd = Sets.newHashSet();
509 Iterator<Map.Entry<T,U>> iter = map.entries().iterator(); 548 Iterator<Map.Entry<Key,Val>> iter = map.entries().iterator();
510 while( iter.hasNext() ) 549 while( iter.hasNext() )
511 { 550 {
512 Map.Entry<T,U> entry = iter.next(); 551 Map.Entry<Key,Val> entry = iter.next();
513 iter.remove(); 552 iter.remove();
514 entriesToAdd.add( new AbstractMap.SimpleEntry<T,U>( 553 entriesToAdd.add( new AbstractMap.SimpleEntry<Key,Val>(
515 renameEntry( renames, entry.getKey() ), 554 renameThing( renames, entry.getKey() ),
516 renameEntry( renames, entry.getValue() ) 555 renameThing( renames, entry.getValue() )
517 ) ); 556 ) );
518 } 557 }
519 for( Map.Entry<T,U> entry : entriesToAdd ) 558 for( Map.Entry<Key,Val> entry : entriesToAdd )
520 { 559 {
521 map.put( entry.getKey(), entry.getValue() ); 560 map.put( entry.getKey(), entry.getValue() );
522 } 561 }
523 } 562 }
524 563
525 @SuppressWarnings( "unchecked" ) 564 @SuppressWarnings( "unchecked" )
526 private <T> T renameEntry( Map<String,String> renames, T entry ) 565 private <T> T renameThing( Map<String,String> renames, T thing )
527 { 566 {
528 if( entry instanceof String ) 567 if( thing instanceof String )
529 { 568 {
530 String stringEntry = (String)entry; 569 String stringEntry = (String)thing;
531 if( renames.containsKey( stringEntry ) ) 570 if( renames.containsKey( stringEntry ) )
532 { 571 {
533 return (T)renames.get( stringEntry ); 572 return (T)renames.get( stringEntry );
534 } 573 }
535 } 574 }
536 else if( entry instanceof ClassEntry ) 575 else if( thing instanceof ClassEntry )
537 { 576 {
538 ClassEntry classEntry = (ClassEntry)entry; 577 ClassEntry classEntry = (ClassEntry)thing;
539 return (T)new ClassEntry( renameEntry( renames, classEntry.getClassName() ) ); 578 return (T)new ClassEntry( renameThing( renames, classEntry.getClassName() ) );
540 } 579 }
541 else if( entry instanceof FieldEntry ) 580 else if( thing instanceof FieldEntry )
542 { 581 {
543 FieldEntry fieldEntry = (FieldEntry)entry; 582 FieldEntry fieldEntry = (FieldEntry)thing;
544 return (T)new FieldEntry( 583 return (T)new FieldEntry(
545 renameEntry( renames, fieldEntry.getClassEntry() ), 584 renameThing( renames, fieldEntry.getClassEntry() ),
546 fieldEntry.getName() 585 fieldEntry.getName()
547 ); 586 );
548 } 587 }
549 else if( entry instanceof ConstructorEntry ) 588 else if( thing instanceof ConstructorEntry )
550 { 589 {
551 ConstructorEntry constructorEntry = (ConstructorEntry)entry; 590 ConstructorEntry constructorEntry = (ConstructorEntry)thing;
552 return (T)new ConstructorEntry( 591 return (T)new ConstructorEntry(
553 renameEntry( renames, constructorEntry.getClassEntry() ), 592 renameThing( renames, constructorEntry.getClassEntry() ),
554 constructorEntry.getSignature() 593 constructorEntry.getSignature()
555 ); 594 );
556 } 595 }
557 else if( entry instanceof MethodEntry ) 596 else if( thing instanceof MethodEntry )
558 { 597 {
559 MethodEntry methodEntry = (MethodEntry)entry; 598 MethodEntry methodEntry = (MethodEntry)thing;
560 return (T)new MethodEntry( 599 return (T)new MethodEntry(
561 renameEntry( renames, methodEntry.getClassEntry() ), 600 renameThing( renames, methodEntry.getClassEntry() ),
562 methodEntry.getName(), 601 methodEntry.getName(),
563 methodEntry.getSignature() 602 methodEntry.getSignature()
564 ); 603 );
565 } 604 }
566 else if( entry instanceof ArgumentEntry ) 605 else if( thing instanceof ArgumentEntry )
567 { 606 {
568 ArgumentEntry argumentEntry = (ArgumentEntry)entry; 607 ArgumentEntry argumentEntry = (ArgumentEntry)thing;
569 return (T)new ArgumentEntry( 608 return (T)new ArgumentEntry(
570 renameEntry( renames, argumentEntry.getMethodEntry() ), 609 renameThing( renames, argumentEntry.getMethodEntry() ),
571 argumentEntry.getIndex(), 610 argumentEntry.getIndex(),
572 argumentEntry.getName() 611 argumentEntry.getName()
573 ); 612 );
574 } 613 }
614 else if( thing instanceof EntryReference )
615 {
616 EntryReference<Entry> reference = (EntryReference<Entry>)thing;
617 reference.entry = renameThing( renames, reference.entry );
618 return thing;
619 }
575 else 620 else
576 { 621 {
577 throw new Error( "Not an entry: " + entry ); 622 throw new Error( "Not an entry: " + thing );
578 } 623 }
579 624
580 return entry; 625 return thing;
581 } 626 }
582} 627}
diff --git a/src/cuchaz/enigma/analysis/MethodCallsTreeNode.java b/src/cuchaz/enigma/analysis/MethodCallsTreeNode.java
deleted file mode 100644
index b5cf4c3..0000000
--- a/src/cuchaz/enigma/analysis/MethodCallsTreeNode.java
+++ /dev/null
@@ -1,144 +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 java.util.Set;
14
15import javax.swing.tree.DefaultMutableTreeNode;
16import javax.swing.tree.TreeNode;
17
18import com.google.common.collect.Sets;
19
20import cuchaz.enigma.mapping.ConstructorEntry;
21import cuchaz.enigma.mapping.Entry;
22import cuchaz.enigma.mapping.MethodEntry;
23import cuchaz.enigma.mapping.Translator;
24
25public class MethodCallsTreeNode extends DefaultMutableTreeNode
26{
27 private static final long serialVersionUID = -3658163700783307520L;
28
29 private Translator m_deobfuscatingTranslator;
30 private MethodEntry m_methodEntry;
31 private ConstructorEntry m_constructorEntry;
32
33 public MethodCallsTreeNode( Translator deobfuscatingTranslator, MethodEntry entry )
34 {
35 m_deobfuscatingTranslator = deobfuscatingTranslator;
36 m_methodEntry = entry;
37 m_constructorEntry = null;
38 }
39
40 public MethodCallsTreeNode( Translator deobfuscatingTranslator, ConstructorEntry entry )
41 {
42 m_deobfuscatingTranslator = deobfuscatingTranslator;
43 m_methodEntry = null;
44 m_constructorEntry = entry;
45 }
46
47 public MethodEntry getMethodEntry( )
48 {
49 return m_methodEntry;
50 }
51
52 public ConstructorEntry getConstructorEntry( )
53 {
54 return m_constructorEntry;
55 }
56
57 public Entry getEntry( )
58 {
59 if( m_methodEntry != null )
60 {
61 return m_methodEntry;
62 }
63 else if( m_constructorEntry != null )
64 {
65 return m_constructorEntry;
66 }
67 throw new Error( "Illegal state!" );
68 }
69
70 @Override
71 public String toString( )
72 {
73 if( m_methodEntry != null )
74 {
75 String className = m_deobfuscatingTranslator.translateClass( m_methodEntry.getClassName() );
76 if( className == null )
77 {
78 className = m_methodEntry.getClassName();
79 }
80
81 String methodName = m_deobfuscatingTranslator.translate( m_methodEntry );
82 if( methodName == null )
83 {
84 methodName = m_methodEntry.getName();
85 }
86 return className + "." + methodName + "()";
87 }
88 else if( m_constructorEntry != null )
89 {
90 String className = m_deobfuscatingTranslator.translateClass( m_constructorEntry.getClassName() );
91 if( className == null )
92 {
93 className = m_constructorEntry.getClassName();
94 }
95 return className + "()";
96 }
97 throw new Error( "Illegal state!" );
98 }
99
100 public void load( JarIndex index, boolean recurse )
101 {
102 // get all the child nodes
103 for( Entry entry : index.getMethodCallers( getEntry() ) )
104 {
105 if( entry instanceof MethodEntry )
106 {
107 add( new MethodCallsTreeNode( m_deobfuscatingTranslator, (MethodEntry)entry ) );
108 }
109 else if( entry instanceof ConstructorEntry )
110 {
111 add( new MethodCallsTreeNode( m_deobfuscatingTranslator, (ConstructorEntry)entry ) );
112 }
113 }
114
115 if( recurse && children != null )
116 {
117 for( Object child : children )
118 {
119 if( child instanceof MethodCallsTreeNode )
120 {
121 MethodCallsTreeNode node = (MethodCallsTreeNode)child;
122
123 // don't recurse into ancestor
124 Set<Entry> ancestors = Sets.newHashSet();
125 TreeNode n = (TreeNode)node;
126 while( n.getParent() != null )
127 {
128 n = n.getParent();
129 if( n instanceof MethodCallsTreeNode )
130 {
131 ancestors.add( ((MethodCallsTreeNode)n).getEntry() );
132 }
133 }
134 if( ancestors.contains( node.getEntry() ) )
135 {
136 continue;
137 }
138
139 node.load( index, true );
140 }
141 }
142 }
143 }
144}
diff --git a/src/cuchaz/enigma/analysis/ReferenceTreeNode.java b/src/cuchaz/enigma/analysis/ReferenceTreeNode.java
new file mode 100644
index 0000000..08ae39d
--- /dev/null
+++ b/src/cuchaz/enigma/analysis/ReferenceTreeNode.java
@@ -0,0 +1,19 @@
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 cuchaz.enigma.mapping.Entry;
14
15public interface ReferenceTreeNode<T extends Entry>
16{
17 T getEntry();
18 EntryReference<T> getReference();
19}
diff --git a/src/cuchaz/enigma/analysis/SourceIndexVisitor.java b/src/cuchaz/enigma/analysis/SourceIndexVisitor.java
index f31eb1a..841d176 100644
--- a/src/cuchaz/enigma/analysis/SourceIndexVisitor.java
+++ b/src/cuchaz/enigma/analysis/SourceIndexVisitor.java
@@ -213,6 +213,20 @@ public class SourceIndexVisitor implements IAstVisitor<SourceIndex, Void>
213 return recurse( node, index ); 213 return recurse( node, index );
214 } 214 }
215 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
216 private Void recurse( AstNode node, SourceIndex index ) 230 private Void recurse( AstNode node, SourceIndex index )
217 { 231 {
218 for( final AstNode child : node.getChildren() ) 232 for( final AstNode child : node.getChildren() )
@@ -477,12 +491,6 @@ public class SourceIndexVisitor implements IAstVisitor<SourceIndex, Void>
477 } 491 }
478 492
479 @Override 493 @Override
480 public Void visitIdentifierExpression( IdentifierExpression node, SourceIndex index )
481 {
482 return recurse( node, index );
483 }
484
485 @Override
486 public Void visitUnaryOperatorExpression( UnaryOperatorExpression node, SourceIndex index ) 494 public Void visitUnaryOperatorExpression( UnaryOperatorExpression node, SourceIndex index )
487 { 495 {
488 return recurse( node, index ); 496 return recurse( node, index );
diff --git a/src/cuchaz/enigma/analysis/TreeDumpVisitor.java b/src/cuchaz/enigma/analysis/TreeDumpVisitor.java
index ac3e92d..12febef 100644
--- a/src/cuchaz/enigma/analysis/TreeDumpVisitor.java
+++ b/src/cuchaz/enigma/analysis/TreeDumpVisitor.java
@@ -122,7 +122,7 @@ public class TreeDumpVisitor implements IAstVisitor<Void, Void>
122 // show the tree 122 // show the tree
123 try 123 try
124 { 124 {
125 m_out.write( getIndent( node ) + node.getClass().getSimpleName() + dumpUserData( node ) + " " + node.getRegion() + "\n" ); 125 m_out.write( getIndent( node ) + node.getClass().getSimpleName() + " " + getText( node ) + " " + dumpUserData( node ) + " " + node.getRegion() + "\n" );
126 } 126 }
127 catch( IOException ex ) 127 catch( IOException ex )
128 { 128 {
@@ -137,6 +137,15 @@ public class TreeDumpVisitor implements IAstVisitor<Void, Void>
137 return null; 137 return null;
138 } 138 }
139 139
140 private String getText( AstNode node )
141 {
142 if( node instanceof Identifier )
143 {
144 return "\"" + node.getText() + "\"";
145 }
146 return "";
147 }
148
140 private String dumpUserData( AstNode node ) 149 private String dumpUserData( AstNode node )
141 { 150 {
142 StringBuilder buf = new StringBuilder(); 151 StringBuilder buf = new StringBuilder();