diff options
| author | 2014-08-19 00:25:32 -0400 | |
|---|---|---|
| committer | 2014-08-19 00:25:32 -0400 | |
| commit | c4e35f2d516ade27e8e1a863b4bc356f182f43c2 (patch) | |
| tree | 6711cde39dcfaea30520b8ccabb6236872e0d756 /src | |
| parent | fixed type caching after rename (diff) | |
| download | enigma-fork-c4e35f2d516ade27e8e1a863b4bc356f182f43c2.tar.gz enigma-fork-c4e35f2d516ade27e8e1a863b4bc356f182f43c2.tar.xz enigma-fork-c4e35f2d516ade27e8e1a863b4bc356f182f43c2.zip | |
started new reference navigation system
Diffstat (limited to 'src')
| -rw-r--r-- | src/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java | 105 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/EntryReference.java | 28 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/FieldCallsTreeNode.java | 82 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/FieldReferenceTreeNode.java | 92 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/JarIndex.java | 141 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/MethodCallsTreeNode.java | 144 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/ReferenceTreeNode.java | 19 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/SourceIndexVisitor.java | 20 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/TreeDumpVisitor.java | 11 | ||||
| -rw-r--r-- | src/cuchaz/enigma/gui/Gui.java | 46 | ||||
| -rw-r--r-- | src/cuchaz/enigma/gui/GuiController.java | 65 | ||||
| -rw-r--r-- | src/cuchaz/enigma/mapping/BehaviorEntry.java | 6 | ||||
| -rw-r--r-- | src/cuchaz/enigma/mapping/ConstructorEntry.java | 3 | ||||
| -rw-r--r-- | src/cuchaz/enigma/mapping/MethodEntry.java | 3 | ||||
| -rw-r--r-- | src/cuchaz/enigma/mapping/Translator.java | 13 |
15 files changed, 441 insertions, 337 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 | ******************************************************************************/ | ||
| 11 | package cuchaz.enigma.analysis; | ||
| 12 | |||
| 13 | import java.util.Set; | ||
| 14 | |||
| 15 | import javax.swing.tree.DefaultMutableTreeNode; | ||
| 16 | import javax.swing.tree.TreeNode; | ||
| 17 | |||
| 18 | import com.google.common.collect.Sets; | ||
| 19 | |||
| 20 | import cuchaz.enigma.mapping.BehaviorEntry; | ||
| 21 | import cuchaz.enigma.mapping.Entry; | ||
| 22 | import cuchaz.enigma.mapping.Translator; | ||
| 23 | |||
| 24 | public 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 | ******************************************************************************/ | ||
| 11 | package cuchaz.enigma.analysis; | ||
| 12 | |||
| 13 | import cuchaz.enigma.mapping.BehaviorEntry; | ||
| 14 | import cuchaz.enigma.mapping.Entry; | ||
| 15 | |||
| 16 | public 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 | ******************************************************************************/ | ||
| 11 | package cuchaz.enigma.analysis; | ||
| 12 | |||
| 13 | import javax.swing.tree.DefaultMutableTreeNode; | ||
| 14 | |||
| 15 | import cuchaz.enigma.mapping.ConstructorEntry; | ||
| 16 | import cuchaz.enigma.mapping.Entry; | ||
| 17 | import cuchaz.enigma.mapping.FieldEntry; | ||
| 18 | import cuchaz.enigma.mapping.MethodEntry; | ||
| 19 | import cuchaz.enigma.mapping.Translator; | ||
| 20 | |||
| 21 | public 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 | ******************************************************************************/ | ||
| 11 | package cuchaz.enigma.analysis; | ||
| 12 | |||
| 13 | import javax.swing.tree.DefaultMutableTreeNode; | ||
| 14 | |||
| 15 | import cuchaz.enigma.mapping.BehaviorEntry; | ||
| 16 | import cuchaz.enigma.mapping.FieldEntry; | ||
| 17 | import cuchaz.enigma.mapping.Translator; | ||
| 18 | |||
| 19 | public 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; | |||
| 35 | import javassist.expr.NewExpr; | 35 | import javassist.expr.NewExpr; |
| 36 | 36 | ||
| 37 | import com.google.common.collect.HashMultimap; | 37 | import com.google.common.collect.HashMultimap; |
| 38 | import com.google.common.collect.HashMultiset; | ||
| 38 | import com.google.common.collect.Lists; | 39 | import com.google.common.collect.Lists; |
| 39 | import com.google.common.collect.Maps; | 40 | import com.google.common.collect.Maps; |
| 40 | import com.google.common.collect.Multimap; | 41 | import com.google.common.collect.Multimap; |
| 42 | import com.google.common.collect.Multiset; | ||
| 41 | import com.google.common.collect.Sets; | 43 | import com.google.common.collect.Sets; |
| 42 | 44 | ||
| 43 | import cuchaz.enigma.mapping.ArgumentEntry; | 45 | import cuchaz.enigma.mapping.ArgumentEntry; |
| 46 | import cuchaz.enigma.mapping.BehaviorEntry; | ||
| 44 | import cuchaz.enigma.mapping.ClassEntry; | 47 | import cuchaz.enigma.mapping.ClassEntry; |
| 45 | import cuchaz.enigma.mapping.ConstructorEntry; | 48 | import cuchaz.enigma.mapping.ConstructorEntry; |
| 46 | import cuchaz.enigma.mapping.Entry; | 49 | import 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 | ******************************************************************************/ | ||
| 11 | package cuchaz.enigma.analysis; | ||
| 12 | |||
| 13 | import java.util.Set; | ||
| 14 | |||
| 15 | import javax.swing.tree.DefaultMutableTreeNode; | ||
| 16 | import javax.swing.tree.TreeNode; | ||
| 17 | |||
| 18 | import com.google.common.collect.Sets; | ||
| 19 | |||
| 20 | import cuchaz.enigma.mapping.ConstructorEntry; | ||
| 21 | import cuchaz.enigma.mapping.Entry; | ||
| 22 | import cuchaz.enigma.mapping.MethodEntry; | ||
| 23 | import cuchaz.enigma.mapping.Translator; | ||
| 24 | |||
| 25 | public 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 | ******************************************************************************/ | ||
| 11 | package cuchaz.enigma.analysis; | ||
| 12 | |||
| 13 | import cuchaz.enigma.mapping.Entry; | ||
| 14 | |||
| 15 | public 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(); |
diff --git a/src/cuchaz/enigma/gui/Gui.java b/src/cuchaz/enigma/gui/Gui.java index 9ed6dd8..43a0cda 100644 --- a/src/cuchaz/enigma/gui/Gui.java +++ b/src/cuchaz/enigma/gui/Gui.java | |||
| @@ -66,10 +66,11 @@ import jsyntaxpane.DefaultSyntaxKit; | |||
| 66 | import com.google.common.collect.Lists; | 66 | import com.google.common.collect.Lists; |
| 67 | 67 | ||
| 68 | import cuchaz.enigma.Constants; | 68 | import cuchaz.enigma.Constants; |
| 69 | import cuchaz.enigma.analysis.BehaviorReferenceTreeNode; | ||
| 69 | import cuchaz.enigma.analysis.ClassInheritanceTreeNode; | 70 | import cuchaz.enigma.analysis.ClassInheritanceTreeNode; |
| 70 | import cuchaz.enigma.analysis.FieldCallsTreeNode; | 71 | import cuchaz.enigma.analysis.FieldReferenceTreeNode; |
| 71 | import cuchaz.enigma.analysis.MethodCallsTreeNode; | ||
| 72 | import cuchaz.enigma.analysis.MethodInheritanceTreeNode; | 72 | import cuchaz.enigma.analysis.MethodInheritanceTreeNode; |
| 73 | import cuchaz.enigma.analysis.ReferenceTreeNode; | ||
| 73 | import cuchaz.enigma.analysis.Token; | 74 | import cuchaz.enigma.analysis.Token; |
| 74 | import cuchaz.enigma.mapping.ArgumentEntry; | 75 | import cuchaz.enigma.mapping.ArgumentEntry; |
| 75 | import cuchaz.enigma.mapping.ClassEntry; | 76 | import cuchaz.enigma.mapping.ClassEntry; |
| @@ -191,7 +192,7 @@ public class Gui | |||
| 191 | String selected = m_obfClasses.getSelectedValue(); | 192 | String selected = m_obfClasses.getSelectedValue(); |
| 192 | if( selected != null ) | 193 | if( selected != null ) |
| 193 | { | 194 | { |
| 194 | m_controller.openEntry( new ClassEntry( selected ) ); | 195 | m_controller.openDeclaration( new ClassEntry( selected ) ); |
| 195 | } | 196 | } |
| 196 | } | 197 | } |
| 197 | } | 198 | } |
| @@ -217,7 +218,7 @@ public class Gui | |||
| 217 | String selected = m_deobfClasses.getSelectedValue(); | 218 | String selected = m_deobfClasses.getSelectedValue(); |
| 218 | if( selected != null ) | 219 | if( selected != null ) |
| 219 | { | 220 | { |
| 220 | m_controller.openEntry( new ClassEntry( selected ) ); | 221 | m_controller.openDeclaration( new ClassEntry( selected ) ); |
| 221 | } | 222 | } |
| 222 | } | 223 | } |
| 223 | } | 224 | } |
| @@ -268,11 +269,11 @@ public class Gui | |||
| 268 | break; | 269 | break; |
| 269 | 270 | ||
| 270 | case KeyEvent.VK_N: | 271 | case KeyEvent.VK_N: |
| 271 | openEntry(); | 272 | openDeclaration(); |
| 272 | break; | 273 | break; |
| 273 | 274 | ||
| 274 | case KeyEvent.VK_P: | 275 | case KeyEvent.VK_P: |
| 275 | m_controller.openPreviousEntry(); | 276 | m_controller.openPreviousLocation(); |
| 276 | break; | 277 | break; |
| 277 | 278 | ||
| 278 | case KeyEvent.VK_C: | 279 | case KeyEvent.VK_C: |
| @@ -341,7 +342,7 @@ public class Gui | |||
| 341 | @Override | 342 | @Override |
| 342 | public void actionPerformed( ActionEvent event ) | 343 | public void actionPerformed( ActionEvent event ) |
| 343 | { | 344 | { |
| 344 | openEntry(); | 345 | openDeclaration(); |
| 345 | } | 346 | } |
| 346 | } ); | 347 | } ); |
| 347 | menu.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_N, 0 ) ); | 348 | menu.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_N, 0 ) ); |
| @@ -356,7 +357,7 @@ public class Gui | |||
| 356 | @Override | 357 | @Override |
| 357 | public void actionPerformed( ActionEvent event ) | 358 | public void actionPerformed( ActionEvent event ) |
| 358 | { | 359 | { |
| 359 | m_controller.openPreviousEntry(); | 360 | m_controller.openPreviousLocation(); |
| 360 | } | 361 | } |
| 361 | } ); | 362 | } ); |
| 362 | menu.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_P, 0 ) ); | 363 | menu.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_P, 0 ) ); |
| @@ -385,14 +386,14 @@ public class Gui | |||
| 385 | Object node = path.getLastPathComponent(); | 386 | Object node = path.getLastPathComponent(); |
| 386 | if( node instanceof ClassInheritanceTreeNode ) | 387 | if( node instanceof ClassInheritanceTreeNode ) |
| 387 | { | 388 | { |
| 388 | m_controller.openEntry( new ClassEntry( ((ClassInheritanceTreeNode)node).getObfClassName() ) ); | 389 | m_controller.openDeclaration( new ClassEntry( ((ClassInheritanceTreeNode)node).getObfClassName() ) ); |
| 389 | } | 390 | } |
| 390 | else if( node instanceof MethodInheritanceTreeNode ) | 391 | else if( node instanceof MethodInheritanceTreeNode ) |
| 391 | { | 392 | { |
| 392 | MethodInheritanceTreeNode methodNode = (MethodInheritanceTreeNode)node; | 393 | MethodInheritanceTreeNode methodNode = (MethodInheritanceTreeNode)node; |
| 393 | if( methodNode.isImplemented() ) | 394 | if( methodNode.isImplemented() ) |
| 394 | { | 395 | { |
| 395 | m_controller.openEntry( methodNode.getMethodEntry() ); | 396 | m_controller.openDeclaration( methodNode.getMethodEntry() ); |
| 396 | } | 397 | } |
| 397 | } | 398 | } |
| 398 | } | 399 | } |
| @@ -407,6 +408,7 @@ public class Gui | |||
| 407 | m_callsTree.setModel( null ); | 408 | m_callsTree.setModel( null ); |
| 408 | m_callsTree.addMouseListener( new MouseAdapter( ) | 409 | m_callsTree.addMouseListener( new MouseAdapter( ) |
| 409 | { | 410 | { |
| 411 | @SuppressWarnings( "unchecked" ) | ||
| 410 | @Override | 412 | @Override |
| 411 | public void mouseClicked( MouseEvent event ) | 413 | public void mouseClicked( MouseEvent event ) |
| 412 | { | 414 | { |
| @@ -420,9 +422,17 @@ public class Gui | |||
| 420 | } | 422 | } |
| 421 | 423 | ||
| 422 | Object node = path.getLastPathComponent(); | 424 | Object node = path.getLastPathComponent(); |
| 423 | if( node instanceof MethodCallsTreeNode ) | 425 | if( node instanceof ReferenceTreeNode ) |
| 424 | { | 426 | { |
| 425 | m_controller.openEntry( ((MethodCallsTreeNode)node).getEntry() ); | 427 | ReferenceTreeNode<Entry> referenceNode = ((ReferenceTreeNode<Entry>)node); |
| 428 | if( referenceNode.getReference() != null ) | ||
| 429 | { | ||
| 430 | m_controller.openReference( referenceNode.getReference() ); | ||
| 431 | } | ||
| 432 | else | ||
| 433 | { | ||
| 434 | m_controller.openDeclaration( referenceNode.getEntry() ); | ||
| 435 | } | ||
| 426 | } | 436 | } |
| 427 | } | 437 | } |
| 428 | } | 438 | } |
| @@ -862,7 +872,7 @@ public class Gui | |||
| 862 | m_showInheritanceMenu.setEnabled( isClassEntry || isMethodEntry || isConstructorEntry ); | 872 | m_showInheritanceMenu.setEnabled( isClassEntry || isMethodEntry || isConstructorEntry ); |
| 863 | m_showCallsMenu.setEnabled( isFieldEntry || isMethodEntry || isConstructorEntry ); | 873 | m_showCallsMenu.setEnabled( isFieldEntry || isMethodEntry || isConstructorEntry ); |
| 864 | m_openEntryMenu.setEnabled( isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry ); | 874 | m_openEntryMenu.setEnabled( isClassEntry || isFieldEntry || isMethodEntry || isConstructorEntry ); |
| 865 | m_openPreviousMenu.setEnabled( m_controller.hasPreviousEntry() ); | 875 | m_openPreviousMenu.setEnabled( m_controller.hasPreviousLocation() ); |
| 866 | } | 876 | } |
| 867 | 877 | ||
| 868 | private void startRename( ) | 878 | private void startRename( ) |
| @@ -977,17 +987,17 @@ public class Gui | |||
| 977 | 987 | ||
| 978 | if( m_selectedEntryPair.obf instanceof FieldEntry ) | 988 | if( m_selectedEntryPair.obf instanceof FieldEntry ) |
| 979 | { | 989 | { |
| 980 | FieldCallsTreeNode node = m_controller.getFieldCalls( (FieldEntry)m_selectedEntryPair.obf ); | 990 | FieldReferenceTreeNode node = m_controller.getFieldReferences( (FieldEntry)m_selectedEntryPair.obf ); |
| 981 | m_callsTree.setModel( new DefaultTreeModel( node ) ); | 991 | m_callsTree.setModel( new DefaultTreeModel( node ) ); |
| 982 | } | 992 | } |
| 983 | else if( m_selectedEntryPair.obf instanceof MethodEntry ) | 993 | else if( m_selectedEntryPair.obf instanceof MethodEntry ) |
| 984 | { | 994 | { |
| 985 | MethodCallsTreeNode node = m_controller.getMethodCalls( (MethodEntry)m_selectedEntryPair.obf ); | 995 | BehaviorReferenceTreeNode node = m_controller.getMethodReferences( (MethodEntry)m_selectedEntryPair.obf ); |
| 986 | m_callsTree.setModel( new DefaultTreeModel( node ) ); | 996 | m_callsTree.setModel( new DefaultTreeModel( node ) ); |
| 987 | } | 997 | } |
| 988 | else if( m_selectedEntryPair.obf instanceof ConstructorEntry ) | 998 | else if( m_selectedEntryPair.obf instanceof ConstructorEntry ) |
| 989 | { | 999 | { |
| 990 | MethodCallsTreeNode node = m_controller.getMethodCalls( (ConstructorEntry)m_selectedEntryPair.obf ); | 1000 | BehaviorReferenceTreeNode node = m_controller.getMethodReferences( (ConstructorEntry)m_selectedEntryPair.obf ); |
| 991 | m_callsTree.setModel( new DefaultTreeModel( node ) ); | 1001 | m_callsTree.setModel( new DefaultTreeModel( node ) ); |
| 992 | } | 1002 | } |
| 993 | 1003 | ||
| @@ -1009,13 +1019,13 @@ public class Gui | |||
| 1009 | return new TreePath( nodes.toArray() ); | 1019 | return new TreePath( nodes.toArray() ); |
| 1010 | } | 1020 | } |
| 1011 | 1021 | ||
| 1012 | private void openEntry( ) | 1022 | private void openDeclaration( ) |
| 1013 | { | 1023 | { |
| 1014 | if( m_selectedEntryPair == null ) | 1024 | if( m_selectedEntryPair == null ) |
| 1015 | { | 1025 | { |
| 1016 | return; | 1026 | return; |
| 1017 | } | 1027 | } |
| 1018 | m_controller.openEntry( m_selectedEntryPair.obf ); | 1028 | m_controller.openDeclaration( m_selectedEntryPair.obf ); |
| 1019 | } | 1029 | } |
| 1020 | 1030 | ||
| 1021 | private void close( ) | 1031 | private void close( ) |
diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java index f305e34..f80bec7 100644 --- a/src/cuchaz/enigma/gui/GuiController.java +++ b/src/cuchaz/enigma/gui/GuiController.java | |||
| @@ -20,14 +20,15 @@ import java.util.Stack; | |||
| 20 | import com.google.common.collect.Lists; | 20 | import com.google.common.collect.Lists; |
| 21 | 21 | ||
| 22 | import cuchaz.enigma.Deobfuscator; | 22 | import cuchaz.enigma.Deobfuscator; |
| 23 | import cuchaz.enigma.analysis.BehaviorReferenceTreeNode; | ||
| 23 | import cuchaz.enigma.analysis.ClassInheritanceTreeNode; | 24 | import cuchaz.enigma.analysis.ClassInheritanceTreeNode; |
| 24 | import cuchaz.enigma.analysis.FieldCallsTreeNode; | 25 | import cuchaz.enigma.analysis.EntryReference; |
| 25 | import cuchaz.enigma.analysis.MethodCallsTreeNode; | 26 | import cuchaz.enigma.analysis.FieldReferenceTreeNode; |
| 26 | import cuchaz.enigma.analysis.MethodInheritanceTreeNode; | 27 | import cuchaz.enigma.analysis.MethodInheritanceTreeNode; |
| 27 | import cuchaz.enigma.analysis.SourceIndex; | 28 | import cuchaz.enigma.analysis.SourceIndex; |
| 28 | import cuchaz.enigma.analysis.Token; | 29 | import cuchaz.enigma.analysis.Token; |
| 30 | import cuchaz.enigma.mapping.BehaviorEntry; | ||
| 29 | import cuchaz.enigma.mapping.ClassEntry; | 31 | import cuchaz.enigma.mapping.ClassEntry; |
| 30 | import cuchaz.enigma.mapping.ConstructorEntry; | ||
| 31 | import cuchaz.enigma.mapping.Entry; | 32 | import cuchaz.enigma.mapping.Entry; |
| 32 | import cuchaz.enigma.mapping.EntryPair; | 33 | import cuchaz.enigma.mapping.EntryPair; |
| 33 | import cuchaz.enigma.mapping.FieldEntry; | 34 | import cuchaz.enigma.mapping.FieldEntry; |
| @@ -44,7 +45,7 @@ public class GuiController | |||
| 44 | private SourceIndex m_index; | 45 | private SourceIndex m_index; |
| 45 | private ClassEntry m_currentClass; | 46 | private ClassEntry m_currentClass; |
| 46 | private boolean m_isDirty; | 47 | private boolean m_isDirty; |
| 47 | private Stack<Entry> m_entryStack; | 48 | private Stack<Entry> m_locationStack; // TODO: make a location class, can be either Entry or EntryReference |
| 48 | 49 | ||
| 49 | public GuiController( Gui gui ) | 50 | public GuiController( Gui gui ) |
| 50 | { | 51 | { |
| @@ -53,7 +54,7 @@ public class GuiController | |||
| 53 | m_index = null; | 54 | m_index = null; |
| 54 | m_currentClass = null; | 55 | m_currentClass = null; |
| 55 | m_isDirty = false; | 56 | m_isDirty = false; |
| 56 | m_entryStack = new Stack<Entry>(); | 57 | m_locationStack = new Stack<Entry>(); |
| 57 | } | 58 | } |
| 58 | 59 | ||
| 59 | public boolean isDirty( ) | 60 | public boolean isDirty( ) |
| @@ -157,9 +158,9 @@ public class GuiController | |||
| 157 | return MethodInheritanceTreeNode.findNode( rootNode, obfMethodEntry ); | 158 | return MethodInheritanceTreeNode.findNode( rootNode, obfMethodEntry ); |
| 158 | } | 159 | } |
| 159 | 160 | ||
| 160 | public FieldCallsTreeNode getFieldCalls( FieldEntry obfFieldEntry ) | 161 | public FieldReferenceTreeNode getFieldReferences( FieldEntry obfFieldEntry ) |
| 161 | { | 162 | { |
| 162 | FieldCallsTreeNode rootNode = new FieldCallsTreeNode( | 163 | FieldReferenceTreeNode rootNode = new FieldReferenceTreeNode( |
| 163 | m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), | 164 | m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), |
| 164 | obfFieldEntry | 165 | obfFieldEntry |
| 165 | ); | 166 | ); |
| @@ -167,27 +168,12 @@ public class GuiController | |||
| 167 | return rootNode; | 168 | return rootNode; |
| 168 | } | 169 | } |
| 169 | 170 | ||
| 170 | public MethodCallsTreeNode getMethodCalls( Entry obfEntry ) | 171 | public BehaviorReferenceTreeNode getMethodReferences( BehaviorEntry obfEntry ) |
| 171 | { | 172 | { |
| 172 | MethodCallsTreeNode rootNode; | 173 | BehaviorReferenceTreeNode rootNode = new BehaviorReferenceTreeNode( |
| 173 | if( obfEntry instanceof MethodEntry ) | 174 | m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), |
| 174 | { | 175 | obfEntry |
| 175 | rootNode = new MethodCallsTreeNode( | 176 | ); |
| 176 | m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), | ||
| 177 | (MethodEntry)obfEntry | ||
| 178 | ); | ||
| 179 | } | ||
| 180 | else if( obfEntry instanceof ConstructorEntry ) | ||
| 181 | { | ||
| 182 | rootNode = new MethodCallsTreeNode( | ||
| 183 | m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), | ||
| 184 | (ConstructorEntry)obfEntry | ||
| 185 | ); | ||
| 186 | } | ||
| 187 | else | ||
| 188 | { | ||
| 189 | throw new IllegalArgumentException( "entry must be a MethodEntry or a ConstructorEntry!" ); | ||
| 190 | } | ||
| 191 | rootNode.load( m_deobfuscator.getJarIndex(), true ); | 177 | rootNode.load( m_deobfuscator.getJarIndex(), true ); |
| 192 | return rootNode; | 178 | return rootNode; |
| 193 | } | 179 | } |
| @@ -200,7 +186,7 @@ public class GuiController | |||
| 200 | refreshCurrentClass( obfEntry ); | 186 | refreshCurrentClass( obfEntry ); |
| 201 | } | 187 | } |
| 202 | 188 | ||
| 203 | public void openEntry( Entry entry ) | 189 | public void openDeclaration( Entry entry ) |
| 204 | { | 190 | { |
| 205 | // go to the entry | 191 | // go to the entry |
| 206 | Entry obfEntry = m_deobfuscator.obfuscateEntry( entry ); | 192 | Entry obfEntry = m_deobfuscator.obfuscateEntry( entry ); |
| @@ -214,25 +200,32 @@ public class GuiController | |||
| 214 | m_gui.showToken( m_index.getDeclarationToken( m_deobfuscator.deobfuscateEntry( obfEntry ) ) ); | 200 | m_gui.showToken( m_index.getDeclarationToken( m_deobfuscator.deobfuscateEntry( obfEntry ) ) ); |
| 215 | } | 201 | } |
| 216 | 202 | ||
| 217 | if( m_entryStack.isEmpty() || !m_entryStack.peek().equals( obfEntry ) ) | 203 | if( m_locationStack.isEmpty() || !m_locationStack.peek().equals( obfEntry ) ) |
| 218 | { | 204 | { |
| 219 | // update the stack | 205 | // update the stack |
| 220 | m_entryStack.push( obfEntry ); | 206 | m_locationStack.push( obfEntry ); |
| 221 | } | 207 | } |
| 222 | } | 208 | } |
| 223 | 209 | ||
| 224 | public void openPreviousEntry( ) | 210 | public void openReference( EntryReference<Entry> reference ) |
| 211 | { | ||
| 212 | // TODO: find out how to load the n-th reference in a caller | ||
| 213 | // TEMP: just go to the caller for now | ||
| 214 | openDeclaration( reference.caller ); | ||
| 215 | } | ||
| 216 | |||
| 217 | public void openPreviousLocation( ) | ||
| 225 | { | 218 | { |
| 226 | if( hasPreviousEntry() ) | 219 | if( hasPreviousLocation() ) |
| 227 | { | 220 | { |
| 228 | m_entryStack.pop(); | 221 | m_locationStack.pop(); |
| 229 | openEntry( m_entryStack.peek() ); | 222 | openDeclaration( m_locationStack.peek() ); |
| 230 | } | 223 | } |
| 231 | } | 224 | } |
| 232 | 225 | ||
| 233 | public boolean hasPreviousEntry( ) | 226 | public boolean hasPreviousLocation( ) |
| 234 | { | 227 | { |
| 235 | return m_entryStack.size() > 1; | 228 | return m_locationStack.size() > 1; |
| 236 | } | 229 | } |
| 237 | 230 | ||
| 238 | private void refreshClasses( ) | 231 | private void refreshClasses( ) |
diff --git a/src/cuchaz/enigma/mapping/BehaviorEntry.java b/src/cuchaz/enigma/mapping/BehaviorEntry.java new file mode 100644 index 0000000..99fdd28 --- /dev/null +++ b/src/cuchaz/enigma/mapping/BehaviorEntry.java | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | package cuchaz.enigma.mapping; | ||
| 2 | |||
| 3 | public interface BehaviorEntry extends Entry | ||
| 4 | { | ||
| 5 | public String getSignature(); | ||
| 6 | } | ||
diff --git a/src/cuchaz/enigma/mapping/ConstructorEntry.java b/src/cuchaz/enigma/mapping/ConstructorEntry.java index e0fa7cf..0f7dab6 100644 --- a/src/cuchaz/enigma/mapping/ConstructorEntry.java +++ b/src/cuchaz/enigma/mapping/ConstructorEntry.java | |||
| @@ -14,7 +14,7 @@ import java.io.Serializable; | |||
| 14 | 14 | ||
| 15 | import cuchaz.enigma.Util; | 15 | import cuchaz.enigma.Util; |
| 16 | 16 | ||
| 17 | public class ConstructorEntry implements Entry, Serializable | 17 | public class ConstructorEntry implements BehaviorEntry, Serializable |
| 18 | { | 18 | { |
| 19 | private static final long serialVersionUID = -868346075317366758L; | 19 | private static final long serialVersionUID = -868346075317366758L; |
| 20 | 20 | ||
| @@ -54,6 +54,7 @@ public class ConstructorEntry implements Entry, Serializable | |||
| 54 | return m_classEntry.getName(); | 54 | return m_classEntry.getName(); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | @Override | ||
| 57 | public String getSignature( ) | 58 | public String getSignature( ) |
| 58 | { | 59 | { |
| 59 | return m_signature; | 60 | return m_signature; |
diff --git a/src/cuchaz/enigma/mapping/MethodEntry.java b/src/cuchaz/enigma/mapping/MethodEntry.java index b4b9c9b..a311e63 100644 --- a/src/cuchaz/enigma/mapping/MethodEntry.java +++ b/src/cuchaz/enigma/mapping/MethodEntry.java | |||
| @@ -14,7 +14,7 @@ import java.io.Serializable; | |||
| 14 | 14 | ||
| 15 | import cuchaz.enigma.Util; | 15 | import cuchaz.enigma.Util; |
| 16 | 16 | ||
| 17 | public class MethodEntry implements Entry, Serializable | 17 | public class MethodEntry implements BehaviorEntry, Serializable |
| 18 | { | 18 | { |
| 19 | private static final long serialVersionUID = 4770915224467247458L; | 19 | private static final long serialVersionUID = 4770915224467247458L; |
| 20 | 20 | ||
| @@ -68,6 +68,7 @@ public class MethodEntry implements Entry, Serializable | |||
| 68 | return m_name; | 68 | return m_name; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | @Override | ||
| 71 | public String getSignature( ) | 72 | public String getSignature( ) |
| 72 | { | 73 | { |
| 73 | return m_signature; | 74 | return m_signature; |
diff --git a/src/cuchaz/enigma/mapping/Translator.java b/src/cuchaz/enigma/mapping/Translator.java index fc41f94..a1230db 100644 --- a/src/cuchaz/enigma/mapping/Translator.java +++ b/src/cuchaz/enigma/mapping/Translator.java | |||
| @@ -172,6 +172,19 @@ public class Translator | |||
| 172 | ); | 172 | ); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | public BehaviorEntry translateEntry( BehaviorEntry in ) | ||
| 176 | { | ||
| 177 | if( in instanceof MethodEntry ) | ||
| 178 | { | ||
| 179 | return translateEntry( (MethodEntry)in ); | ||
| 180 | } | ||
| 181 | else if( in instanceof ConstructorEntry ) | ||
| 182 | { | ||
| 183 | return translateEntry( (ConstructorEntry)in ); | ||
| 184 | } | ||
| 185 | throw new Error( "Wrong entry type!" ); | ||
| 186 | } | ||
| 187 | |||
| 175 | public String translate( ArgumentEntry in ) | 188 | public String translate( ArgumentEntry in ) |
| 176 | { | 189 | { |
| 177 | for( String className : getSelfAndAncestors( in.getClassName() ) ) | 190 | for( String className : getSelfAndAncestors( in.getClassName() ) ) |