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