From a85529d1ce6ec533809575ec84572de855464b36 Mon Sep 17 00:00:00 2001 From: jeff Date: Wed, 20 Aug 2014 01:21:52 -0400 Subject: finished reference navigation system. Still need to debug and polish it, but the basic idea seems to work. =) --- src/cuchaz/enigma/Deobfuscator.java | 105 ++-- src/cuchaz/enigma/Main.java | 1 - .../enigma/analysis/BehaviorReferenceTreeNode.java | 12 +- src/cuchaz/enigma/analysis/EntryReference.java | 89 ++- .../enigma/analysis/FieldReferenceTreeNode.java | 14 +- src/cuchaz/enigma/analysis/JarIndex.java | 43 +- src/cuchaz/enigma/analysis/ReferenceTreeNode.java | 6 +- src/cuchaz/enigma/analysis/SourceIndex.java | 51 +- .../analysis/SourceIndexBehaviorVisitor.java | 142 +++++ .../enigma/analysis/SourceIndexClassVisitor.java | 114 ++++ src/cuchaz/enigma/analysis/SourceIndexVisitor.java | 600 --------------------- src/cuchaz/enigma/analysis/Token.java | 6 + src/cuchaz/enigma/gui/Gui.java | 158 +++--- src/cuchaz/enigma/gui/GuiController.java | 106 ++-- src/cuchaz/enigma/mapping/Translator.java | 28 + 15 files changed, 633 insertions(+), 842 deletions(-) create mode 100644 src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java create mode 100644 src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java delete mode 100644 src/cuchaz/enigma/analysis/SourceIndexVisitor.java diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java index 293e1c2f..34e6033b 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; import com.strobel.decompiler.languages.java.ast.CompilationUnit; import com.strobel.decompiler.languages.java.ast.InsertParenthesesVisitor; +import cuchaz.enigma.analysis.EntryReference; import cuchaz.enigma.analysis.JarIndex; import cuchaz.enigma.analysis.SourceIndex; import cuchaz.enigma.analysis.SourceIndexVisitor; @@ -169,98 +170,92 @@ public class Deobfuscator SourceIndex index = new SourceIndex( buf.toString() ); root.acceptVisitor( new SourceIndexVisitor(), index ); - return index; - } - - // NOTE: these methods are a bit messy... oh well - - public void rename( Entry obfEntry, String newName ) - { - if( obfEntry instanceof ClassEntry ) + /* DEBUG + for( Token token : index.referenceTokens() ) { - m_renamer.setClassName( (ClassEntry)obfEntry, newName ); - } - else if( obfEntry instanceof FieldEntry ) - { - m_renamer.setFieldName( (FieldEntry)obfEntry, newName ); - } - else if( obfEntry instanceof MethodEntry ) - { - m_renamer.setMethodTreeName( (MethodEntry)obfEntry, newName ); - } - else if( obfEntry instanceof ConstructorEntry ) - { - m_renamer.setClassName( obfEntry.getClassEntry(), newName ); - } - else if( obfEntry instanceof ArgumentEntry ) - { - m_renamer.setArgumentName( (ArgumentEntry)obfEntry, newName ); - } - else - { - throw new Error( "Unknown entry type: " + obfEntry.getClass().getName() ); + EntryReference reference = index.getDeobfReference( token ); + System.out.println( token + " -> " + reference + " -> " + index.getReferenceToken( reference ) ); } + */ - // clear the type loader cache - m_typeLoader.clearCache(); + return index; } public Entry obfuscateEntry( Entry deobfEntry ) { - Translator translator = getTranslator( TranslationDirection.Obfuscating ); - if( deobfEntry instanceof ClassEntry ) - { - return translator.translateEntry( (ClassEntry)deobfEntry ); - } - else if( deobfEntry instanceof FieldEntry ) - { - return translator.translateEntry( (FieldEntry)deobfEntry ); - } - else if( deobfEntry instanceof MethodEntry ) + if( deobfEntry == null ) { - return translator.translateEntry( (MethodEntry)deobfEntry ); + return null; } - else if( deobfEntry instanceof ConstructorEntry ) + return getTranslator( TranslationDirection.Obfuscating ).translateEntry( deobfEntry ); + } + + public Entry deobfuscateEntry( Entry obfEntry ) + { + if( obfEntry == null ) { - return translator.translateEntry( (ConstructorEntry)deobfEntry ); + return null; } - else if( deobfEntry instanceof ArgumentEntry ) + return getTranslator( TranslationDirection.Deobfuscating ).translateEntry( obfEntry ); + } + + public EntryReference obfuscateReference( EntryReference deobfReference ) + { + if( deobfReference == null ) { - return translator.translateEntry( (ArgumentEntry)deobfEntry ); + return null; } - else + return new EntryReference( + obfuscateEntry( deobfReference.entry ), + obfuscateEntry( deobfReference.context ), + deobfReference.pos + ); + } + + public EntryReference deobfuscateReference( EntryReference obfReference ) + { + if( obfReference == null ) { - throw new Error( "Unknown entry type: " + deobfEntry.getClass().getName() ); + return null; } + return new EntryReference( + deobfuscateEntry( obfReference.entry ), + deobfuscateEntry( obfReference.context ), + obfReference.pos + ); } - public Entry deobfuscateEntry( Entry obfEntry ) + // NOTE: these methods are a bit messy... oh well + + public void rename( Entry obfEntry, String newName ) { - Translator translator = getTranslator( TranslationDirection.Deobfuscating ); if( obfEntry instanceof ClassEntry ) { - return translator.translateEntry( (ClassEntry)obfEntry ); + m_renamer.setClassName( (ClassEntry)obfEntry, newName ); } else if( obfEntry instanceof FieldEntry ) { - return translator.translateEntry( (FieldEntry)obfEntry ); + m_renamer.setFieldName( (FieldEntry)obfEntry, newName ); } else if( obfEntry instanceof MethodEntry ) { - return translator.translateEntry( (MethodEntry)obfEntry ); + m_renamer.setMethodTreeName( (MethodEntry)obfEntry, newName ); } else if( obfEntry instanceof ConstructorEntry ) { - return translator.translateEntry( (ConstructorEntry)obfEntry ); + m_renamer.setClassName( obfEntry.getClassEntry(), newName ); } else if( obfEntry instanceof ArgumentEntry ) { - return translator.translateEntry( (ArgumentEntry)obfEntry ); + m_renamer.setArgumentName( (ArgumentEntry)obfEntry, newName ); } else { throw new Error( "Unknown entry type: " + obfEntry.getClass().getName() ); } + + // clear the type loader cache + m_typeLoader.clearCache(); } public boolean hasMapping( Entry obfEntry ) diff --git a/src/cuchaz/enigma/Main.java b/src/cuchaz/enigma/Main.java index 20d73c29..7d38bd62 100644 --- a/src/cuchaz/enigma/Main.java +++ b/src/cuchaz/enigma/Main.java @@ -13,7 +13,6 @@ package cuchaz.enigma; import java.io.File; import cuchaz.enigma.gui.Gui; -import cuchaz.enigma.mapping.ClassEntry; public class Main { diff --git a/src/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java b/src/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java index 158aad71..0f7e7f71 100644 --- a/src/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java +++ b/src/cuchaz/enigma/analysis/BehaviorReferenceTreeNode.java @@ -21,13 +21,13 @@ import cuchaz.enigma.mapping.BehaviorEntry; import cuchaz.enigma.mapping.Entry; import cuchaz.enigma.mapping.Translator; -public class BehaviorReferenceTreeNode extends DefaultMutableTreeNode implements ReferenceTreeNode +public class BehaviorReferenceTreeNode extends DefaultMutableTreeNode implements ReferenceTreeNode { private static final long serialVersionUID = -3658163700783307520L; private Translator m_deobfuscatingTranslator; private BehaviorEntry m_entry; - private EntryReference m_reference; + private EntryReference m_reference; public BehaviorReferenceTreeNode( Translator deobfuscatingTranslator, BehaviorEntry entry ) { @@ -36,7 +36,7 @@ public class BehaviorReferenceTreeNode extends DefaultMutableTreeNode implements m_reference = null; } - public BehaviorReferenceTreeNode( Translator deobfuscatingTranslator, EntryReference reference ) + public BehaviorReferenceTreeNode( Translator deobfuscatingTranslator, EntryReference reference ) { m_deobfuscatingTranslator = deobfuscatingTranslator; m_entry = reference.entry; @@ -50,7 +50,7 @@ public class BehaviorReferenceTreeNode extends DefaultMutableTreeNode implements } @Override - public EntryReference getReference( ) + public EntryReference getReference( ) { return m_reference; } @@ -60,7 +60,7 @@ public class BehaviorReferenceTreeNode extends DefaultMutableTreeNode implements { if( m_reference != null ) { - return m_deobfuscatingTranslator.translateEntry( m_reference.caller ).toString(); + return m_deobfuscatingTranslator.translateEntry( m_reference.context ).toString(); } return m_deobfuscatingTranslator.translateEntry( m_entry ).toString(); } @@ -68,7 +68,7 @@ public class BehaviorReferenceTreeNode extends DefaultMutableTreeNode implements public void load( JarIndex index, boolean recurse ) { // get all the child nodes - for( EntryReference reference : index.getBehaviorReferences( m_entry ) ) + for( EntryReference reference : index.getBehaviorReferences( m_entry ) ) { add( new BehaviorReferenceTreeNode( m_deobfuscatingTranslator, reference ) ); } diff --git a/src/cuchaz/enigma/analysis/EntryReference.java b/src/cuchaz/enigma/analysis/EntryReference.java index f462210a..869e08c1 100644 --- a/src/cuchaz/enigma/analysis/EntryReference.java +++ b/src/cuchaz/enigma/analysis/EntryReference.java @@ -10,19 +10,96 @@ ******************************************************************************/ package cuchaz.enigma.analysis; -import cuchaz.enigma.mapping.BehaviorEntry; +import cuchaz.enigma.Util; +import cuchaz.enigma.mapping.ClassEntry; import cuchaz.enigma.mapping.Entry; -public class EntryReference +public class EntryReference { - public T entry; - public BehaviorEntry caller; + public E entry; + public C context; public int pos; - public EntryReference( T entry, BehaviorEntry caller, int pos ) + public EntryReference( E entry ) { + this( entry, null, -1 ); + } + + public EntryReference( E entry, C context, int pos ) + { + if( entry == null ) + { + throw new IllegalArgumentException( "Entry cannot be null!" ); + } + this.entry = entry; - this.caller = caller; + this.context = context; this.pos = pos; } + + public ClassEntry getClassEntry( ) + { + if( context != null ) + { + return context.getClassEntry(); + } + return entry.getClassEntry(); + } + + @Override + public int hashCode( ) + { + if( context != null ) + { + return Util.combineHashesOrdered( entry.hashCode(), context.hashCode(), Integer.valueOf( pos ).hashCode() ); + } + return entry.hashCode(); + } + + @Override + public boolean equals( Object other ) + { + if( other instanceof EntryReference ) + { + return equals( (EntryReference)other ); + } + return false; + } + + public boolean equals( EntryReference other ) + { + // check entry first + boolean isEntrySame = entry.equals( other.entry ); + if( !isEntrySame ) + { + return false; + } + + // check caller + if( context == null && other.context == null ) + { + return true; + } + else if( context != null && other.context != null ) + { + return context.equals( other.context ) && pos == other.pos; + } + return false; + } + + @Override + public String toString( ) + { + StringBuilder buf = new StringBuilder(); + buf.append( entry ); + if( context != null ) + { + buf.append( " called from " ); + buf.append( context ); + buf.append( " (" ); + buf.append( pos ); + buf.append( ")" ); + } + return buf.toString(); + } } diff --git a/src/cuchaz/enigma/analysis/FieldReferenceTreeNode.java b/src/cuchaz/enigma/analysis/FieldReferenceTreeNode.java index dd552d68..645e6821 100644 --- a/src/cuchaz/enigma/analysis/FieldReferenceTreeNode.java +++ b/src/cuchaz/enigma/analysis/FieldReferenceTreeNode.java @@ -16,13 +16,13 @@ import cuchaz.enigma.mapping.BehaviorEntry; import cuchaz.enigma.mapping.FieldEntry; import cuchaz.enigma.mapping.Translator; -public class FieldReferenceTreeNode extends DefaultMutableTreeNode implements ReferenceTreeNode +public class FieldReferenceTreeNode extends DefaultMutableTreeNode implements ReferenceTreeNode { private static final long serialVersionUID = -7934108091928699835L; private Translator m_deobfuscatingTranslator; private FieldEntry m_entry; - private EntryReference m_reference; + private EntryReference m_reference; public FieldReferenceTreeNode( Translator deobfuscatingTranslator, FieldEntry entry ) { @@ -31,7 +31,7 @@ public class FieldReferenceTreeNode extends DefaultMutableTreeNode implements Re m_reference = null; } - private FieldReferenceTreeNode( Translator deobfuscatingTranslator, EntryReference reference ) + private FieldReferenceTreeNode( Translator deobfuscatingTranslator, EntryReference reference ) { m_deobfuscatingTranslator = deobfuscatingTranslator; m_entry = reference.entry; @@ -45,7 +45,7 @@ public class FieldReferenceTreeNode extends DefaultMutableTreeNode implements Re } @Override - public EntryReference getReference( ) + public EntryReference getReference( ) { return m_reference; } @@ -55,7 +55,7 @@ public class FieldReferenceTreeNode extends DefaultMutableTreeNode implements Re { if( m_reference != null ) { - return m_deobfuscatingTranslator.translateEntry( m_reference.caller ).toString(); + return m_deobfuscatingTranslator.translateEntry( m_reference.context ).toString(); } return m_deobfuscatingTranslator.translateEntry( m_entry ).toString(); } @@ -65,14 +65,14 @@ public class FieldReferenceTreeNode extends DefaultMutableTreeNode implements Re // get all the child nodes if( m_reference == null ) { - for( EntryReference reference : index.getFieldReferences( m_entry ) ) + for( EntryReference reference : index.getFieldReferences( m_entry ) ) { add( new FieldReferenceTreeNode( m_deobfuscatingTranslator, reference ) ); } } else { - for( EntryReference reference : index.getBehaviorReferences( m_reference.caller ) ) + for( EntryReference reference : index.getBehaviorReferences( m_reference.context ) ) { add( new BehaviorReferenceTreeNode( m_deobfuscatingTranslator, reference ) ); } diff --git a/src/cuchaz/enigma/analysis/JarIndex.java b/src/cuchaz/enigma/analysis/JarIndex.java index f1c29c5b..f408d930 100644 --- a/src/cuchaz/enigma/analysis/JarIndex.java +++ b/src/cuchaz/enigma/analysis/JarIndex.java @@ -56,8 +56,8 @@ public class JarIndex private Set m_obfClassNames; private Ancestries m_ancestries; private Multimap m_methodImplementations; - private Multimap> m_behaviorReferences; - private Multimap> m_fieldReferences; + private Multimap> m_behaviorReferences; + private Multimap> m_fieldReferences; private Multimap m_innerClasses; private Map m_outerClasses; private Set m_anonymousClasses; @@ -108,12 +108,12 @@ public class JarIndex m_anonymousClasses.add( innerClassName ); // DEBUG - System.out.println( "ANONYMOUS: " + outerClassName + "$" + innerClassName ); + //System.out.println( "ANONYMOUS: " + outerClassName + "$" + innerClassName ); } else { // DEBUG - System.out.println( "INNER: " + outerClassName + "$" + innerClassName ); + //System.out.println( "INNER: " + outerClassName + "$" + innerClassName ); } } } @@ -172,7 +172,7 @@ public class JarIndex call.getSignature() ); callNumbers.add( calledMethodEntry ); - EntryReference reference = new EntryReference( + EntryReference reference = new EntryReference( calledMethodEntry, thisEntry, callNumbers.count( calledMethodEntry ) - 1 @@ -189,7 +189,7 @@ public class JarIndex call.getFieldName() ); callNumbers.add( calledFieldEntry ); - EntryReference reference = new EntryReference( + EntryReference reference = new EntryReference( calledFieldEntry, thisEntry, callNumbers.count( calledFieldEntry ) - 1 @@ -209,7 +209,7 @@ public class JarIndex call.getSignature() ); callNumbers.add( calledConstructorEntry ); - EntryReference reference = new EntryReference( + EntryReference reference = new EntryReference( calledConstructorEntry, thisEntry, callNumbers.count( calledConstructorEntry ) - 1 @@ -226,7 +226,7 @@ public class JarIndex call.getSignature() ); callNumbers.add( calledConstructorEntry ); - EntryReference reference = new EntryReference( + EntryReference reference = new EntryReference( calledConstructorEntry, thisEntry, callNumbers.count( calledConstructorEntry ) - 1 @@ -261,9 +261,9 @@ public class JarIndex new ClassEntry( Descriptor.toJvmName( c.getName() ) ), constructor.getMethodInfo().getDescriptor() ); - for( EntryReference reference : getBehaviorReferences( constructorEntry ) ) + for( EntryReference reference : getBehaviorReferences( constructorEntry ) ) { - callerClasses.add( reference.caller.getClassEntry() ); + callerClasses.add( reference.context.getClassEntry() ); } // is this called by exactly one class? @@ -496,26 +496,14 @@ public class JarIndex return rootNode; } - @SuppressWarnings( "unchecked" ) - public Collection> getFieldReferences( FieldEntry fieldEntry ) + public Collection> getFieldReferences( FieldEntry fieldEntry ) { - List> references = Lists.newArrayList(); - for( EntryReference reference : m_fieldReferences.get( fieldEntry ) ) - { - references.add( (EntryReference)reference ); - } - return references; + return m_fieldReferences.get( fieldEntry ); } - @SuppressWarnings( "unchecked" ) - public Collection> getBehaviorReferences( BehaviorEntry behaviorEntry ) + public Collection> getBehaviorReferences( BehaviorEntry behaviorEntry ) { - List> references = Lists.newArrayList(); - for( EntryReference reference : m_behaviorReferences.get( behaviorEntry ) ) - { - references.add( (EntryReference)reference ); - } - return references; + return m_behaviorReferences.get( behaviorEntry ); } public Collection getInnerClasses( String obfOuterClassName ) @@ -613,8 +601,9 @@ public class JarIndex } else if( thing instanceof EntryReference ) { - EntryReference reference = (EntryReference)thing; + EntryReference reference = (EntryReference)thing; reference.entry = renameThing( renames, reference.entry ); + reference.context = renameThing( renames, reference.context ); return thing; } else diff --git a/src/cuchaz/enigma/analysis/ReferenceTreeNode.java b/src/cuchaz/enigma/analysis/ReferenceTreeNode.java index 08ae39d9..e0a0a747 100644 --- a/src/cuchaz/enigma/analysis/ReferenceTreeNode.java +++ b/src/cuchaz/enigma/analysis/ReferenceTreeNode.java @@ -12,8 +12,8 @@ package cuchaz.enigma.analysis; import cuchaz.enigma.mapping.Entry; -public interface ReferenceTreeNode +public interface ReferenceTreeNode { - T getEntry(); - EntryReference getReference(); + E getEntry(); + EntryReference getReference(); } diff --git a/src/cuchaz/enigma/analysis/SourceIndex.java b/src/cuchaz/enigma/analysis/SourceIndex.java index 645a71da..bf890e30 100644 --- a/src/cuchaz/enigma/analysis/SourceIndex.java +++ b/src/cuchaz/enigma/analysis/SourceIndex.java @@ -10,6 +10,7 @@ ******************************************************************************/ package cuchaz.enigma.analysis; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -24,15 +25,17 @@ import cuchaz.enigma.mapping.Entry; public class SourceIndex { private String m_source; - private TreeMap m_tokens; - private Map m_declarations; + private TreeMap> m_tokenToReference; + private HashMap,Token> m_referenceToToken; + private Map m_declarationToToken; private List m_lineOffsets; public SourceIndex( String source ) { m_source = source; - m_tokens = Maps.newTreeMap(); - m_declarations = Maps.newHashMap(); + m_tokenToReference = Maps.newTreeMap(); + m_referenceToToken = Maps.newHashMap(); + m_declarationToToken = Maps.newHashMap(); m_lineOffsets = Lists.newArrayList(); // count the lines @@ -87,12 +90,13 @@ public class SourceIndex return token; } - public void add( Identifier node, Entry deobfEntry ) + public void addReference( Identifier node, EntryReference deobfReference ) { Token token = getToken( node ); if( token != null ) { - m_tokens.put( token, deobfEntry ); + m_tokenToReference.put( token, deobfReference ); + m_referenceToToken.put( deobfReference, token ); } } @@ -101,19 +105,16 @@ public class SourceIndex Token token = getToken( node ); if( token != null ) { - m_tokens.put( token, deobfEntry ); - m_declarations.put( deobfEntry, token ); + EntryReference reference = new EntryReference( deobfEntry ); + m_tokenToReference.put( token, reference ); + m_referenceToToken.put( reference, token ); + m_declarationToToken.put( deobfEntry, token ); } } - public Token getToken( int pos ) + public Token getReferenceToken( int pos ) { - Map.Entry mapEntry = m_tokens.floorEntry( new Token( pos, pos ) ); - if( mapEntry == null ) - { - return null; - } - Token token = mapEntry.getKey(); + Token token = m_tokenToReference.floorKey( new Token( pos, pos ) ); if( token.contains( pos ) ) { return token; @@ -121,23 +122,33 @@ public class SourceIndex return null; } - public Entry getEntry( Token token ) + public Token getReferenceToken( EntryReference deobfReference ) + { + return m_referenceToToken.get( deobfReference ); + } + + public EntryReference getDeobfReference( Token token ) { if( token == null ) { return null; } - return m_tokens.get( token ); + return m_tokenToReference.get( token ); + } + + public Iterable referenceTokens( ) + { + return m_tokenToReference.keySet(); } - public Iterable tokens( ) + public Iterable declarationTokens( ) { - return m_tokens.keySet(); + return m_declarationToToken.values(); } public Token getDeclarationToken( Entry deobfEntry ) { - return m_declarations.get( deobfEntry ); + return m_declarationToToken.get( deobfEntry ); } 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 00000000..d3386c51 --- /dev/null +++ b/src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2014 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/gpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.analysis; + +import com.google.common.collect.HashMultiset; +import com.google.common.collect.Multiset; +import com.strobel.assembler.metadata.MemberReference; +import com.strobel.assembler.metadata.MethodDefinition; +import com.strobel.assembler.metadata.ParameterDefinition; +import com.strobel.assembler.metadata.TypeReference; +import com.strobel.decompiler.languages.TextLocation; +import com.strobel.decompiler.languages.java.ast.ConstructorDeclaration; +import com.strobel.decompiler.languages.java.ast.IdentifierExpression; +import com.strobel.decompiler.languages.java.ast.InvocationExpression; +import com.strobel.decompiler.languages.java.ast.Keys; +import com.strobel.decompiler.languages.java.ast.MemberReferenceExpression; +import com.strobel.decompiler.languages.java.ast.MethodDeclaration; +import com.strobel.decompiler.languages.java.ast.ParameterDeclaration; +import com.strobel.decompiler.languages.java.ast.SimpleType; + +import cuchaz.enigma.mapping.ArgumentEntry; +import cuchaz.enigma.mapping.BehaviorEntry; +import cuchaz.enigma.mapping.ClassEntry; +import cuchaz.enigma.mapping.Entry; +import cuchaz.enigma.mapping.FieldEntry; +import cuchaz.enigma.mapping.MethodEntry; + +public class SourceIndexBehaviorVisitor extends SourceIndexVisitor +{ + private BehaviorEntry m_behaviorEntry; + private Multiset m_indices; + + public SourceIndexBehaviorVisitor( BehaviorEntry behaviorEntry ) + { + m_behaviorEntry = behaviorEntry; + m_indices = HashMultiset.create(); + } + + @Override + public Void visitMethodDeclaration( MethodDeclaration node, SourceIndex index ) + { + return recurse( node, index ); + } + + @Override + public Void visitConstructorDeclaration( ConstructorDeclaration node, SourceIndex index ) + { + return recurse( node, index ); + } + + @Override + public Void visitInvocationExpression( InvocationExpression node, SourceIndex index ) + { + MemberReference ref = node.getUserData( Keys.MEMBER_REFERENCE ); + ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() ); + MethodEntry methodEntry = new MethodEntry( classEntry, ref.getName(), ref.getSignature() ); + if( node.getTarget() instanceof MemberReferenceExpression ) + { + m_indices.add( methodEntry ); + index.addReference( + ((MemberReferenceExpression)node.getTarget()).getMemberNameToken(), + new EntryReference( methodEntry, m_behaviorEntry, m_indices.count( methodEntry ) ) + ); + } + + return recurse( node, index ); + } + + @Override + public Void visitMemberReferenceExpression( MemberReferenceExpression node, SourceIndex index ) + { + MemberReference ref = node.getUserData( Keys.MEMBER_REFERENCE ); + if( ref != null ) + { + ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() ); + FieldEntry fieldEntry = new FieldEntry( classEntry, ref.getName() ); + m_indices.add( fieldEntry ); + index.addReference( + node.getMemberNameToken(), + new EntryReference( fieldEntry, m_behaviorEntry, m_indices.count( fieldEntry ) ) + ); + } + + return recurse( node, index ); + } + + @Override + public Void visitSimpleType( SimpleType node, SourceIndex index ) + { + TypeReference ref = node.getUserData( Keys.TYPE_REFERENCE ); + if( node.getIdentifierToken().getStartLocation() != TextLocation.EMPTY ) + { + ClassEntry classEntry = new ClassEntry( ref.getInternalName() ); + m_indices.add( classEntry ); + index.addReference( + node.getIdentifierToken(), + new EntryReference( classEntry, m_behaviorEntry, m_indices.count( classEntry ) ) + ); + } + + return recurse( node, index ); + } + + @Override + public Void visitParameterDeclaration( ParameterDeclaration node, SourceIndex index ) + { + ParameterDefinition def = node.getUserData( Keys.PARAMETER_DEFINITION ); + ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() ); + MethodDefinition methodDef = (MethodDefinition)def.getMethod(); + MethodEntry methodEntry = new MethodEntry( classEntry, methodDef.getName(), methodDef.getSignature() ); + ArgumentEntry argumentEntry = new ArgumentEntry( methodEntry, def.getPosition(), def.getName() ); + index.addDeclaration( node.getNameToken(), argumentEntry ); + + return recurse( node, index ); + } + + @Override + public Void visitIdentifierExpression( IdentifierExpression node, SourceIndex index ) + { + MemberReference ref = node.getUserData( Keys.MEMBER_REFERENCE ); + if( ref != null ) + { + ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() ); + FieldEntry fieldEntry = new FieldEntry( classEntry, ref.getName() ); + m_indices.add( fieldEntry ); + index.addReference( + node.getIdentifierToken(), + new EntryReference( fieldEntry, m_behaviorEntry, m_indices.count( fieldEntry ) ) + ); + } + + return recurse( node, index ); + } +} diff --git a/src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java b/src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java new file mode 100644 index 00000000..2d4c0f57 --- /dev/null +++ b/src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2014 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/gpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.analysis; + +import com.google.common.collect.HashMultiset; +import com.google.common.collect.Multiset; +import com.strobel.assembler.metadata.FieldDefinition; +import com.strobel.assembler.metadata.MethodDefinition; +import com.strobel.assembler.metadata.TypeReference; +import com.strobel.decompiler.languages.TextLocation; +import com.strobel.decompiler.languages.java.ast.ConstructorDeclaration; +import com.strobel.decompiler.languages.java.ast.EnumValueDeclaration; +import com.strobel.decompiler.languages.java.ast.FieldDeclaration; +import com.strobel.decompiler.languages.java.ast.Keys; +import com.strobel.decompiler.languages.java.ast.MethodDeclaration; +import com.strobel.decompiler.languages.java.ast.SimpleType; +import com.strobel.decompiler.languages.java.ast.TypeDeclaration; +import com.strobel.decompiler.languages.java.ast.VariableInitializer; + +import cuchaz.enigma.mapping.ClassEntry; +import cuchaz.enigma.mapping.ConstructorEntry; +import cuchaz.enigma.mapping.Entry; +import cuchaz.enigma.mapping.FieldEntry; +import cuchaz.enigma.mapping.MethodEntry; + +public class SourceIndexClassVisitor extends SourceIndexVisitor +{ + private ClassEntry m_classEntry; + private Multiset m_indices; + + public SourceIndexClassVisitor( ClassEntry classEntry ) + { + m_classEntry = classEntry; + m_indices = HashMultiset.create(); + } + + @Override + public Void visitTypeDeclaration( TypeDeclaration node, SourceIndex index ) + { + return recurse( node, index ); + } + + @Override + public Void visitSimpleType( SimpleType node, SourceIndex index ) + { + TypeReference ref = node.getUserData( Keys.TYPE_REFERENCE ); + if( node.getIdentifierToken().getStartLocation() != TextLocation.EMPTY ) + { + ClassEntry classEntry = new ClassEntry( ref.getInternalName() ); + index.addReference( + node.getIdentifierToken(), + new EntryReference( classEntry, m_classEntry, m_indices.count( classEntry ) ) + ); + } + + return recurse( node, index ); + } + + @Override + public Void visitMethodDeclaration( MethodDeclaration node, SourceIndex index ) + { + MethodDefinition def = node.getUserData( Keys.METHOD_DEFINITION ); + ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() ); + MethodEntry methodEntry = new MethodEntry( classEntry, def.getName(), def.getSignature() ); + index.addDeclaration( node.getNameToken(), methodEntry ); + //if( !def.getName().equals( "" ) ) + + return node.acceptVisitor( new SourceIndexBehaviorVisitor( methodEntry ), index ); + } + + @Override + public Void visitConstructorDeclaration( ConstructorDeclaration node, SourceIndex index ) + { + MethodDefinition def = node.getUserData( Keys.METHOD_DEFINITION ); + ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() ); + ConstructorEntry constructorEntry = new ConstructorEntry( classEntry, def.getSignature() ); + index.addDeclaration( node.getNameToken(), constructorEntry ); + + return recurse( node, index ); + } + + @Override + public Void visitFieldDeclaration( FieldDeclaration node, SourceIndex index ) + { + FieldDefinition def = node.getUserData( Keys.FIELD_DEFINITION ); + ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() ); + FieldEntry fieldEntry = new FieldEntry( classEntry, def.getName() ); + assert( node.getVariables().size() == 1 ); + VariableInitializer variable = node.getVariables().firstOrNullObject(); + index.addDeclaration( variable.getNameToken(), fieldEntry ); + + return recurse( node, index ); + } + + @Override + public Void visitEnumValueDeclaration( EnumValueDeclaration node, SourceIndex index ) + { + // treat enum declarations as field declarations + FieldDefinition def = node.getUserData( Keys.FIELD_DEFINITION ); + ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() ); + FieldEntry fieldEntry = new FieldEntry( classEntry, def.getName() ); + index.addDeclaration( node.getNameToken(), fieldEntry ); + + return recurse( node, index ); + } +} diff --git a/src/cuchaz/enigma/analysis/SourceIndexVisitor.java b/src/cuchaz/enigma/analysis/SourceIndexVisitor.java deleted file mode 100644 index 841d1767..00000000 --- a/src/cuchaz/enigma/analysis/SourceIndexVisitor.java +++ /dev/null @@ -1,600 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Public License v3.0 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/gpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.analysis; - -import com.strobel.assembler.metadata.FieldDefinition; -import com.strobel.assembler.metadata.MemberReference; -import com.strobel.assembler.metadata.MethodDefinition; -import com.strobel.assembler.metadata.ParameterDefinition; -import com.strobel.assembler.metadata.TypeDefinition; -import com.strobel.assembler.metadata.TypeReference; -import com.strobel.decompiler.languages.TextLocation; -import com.strobel.decompiler.languages.java.ast.Annotation; -import com.strobel.decompiler.languages.java.ast.AnonymousObjectCreationExpression; -import com.strobel.decompiler.languages.java.ast.ArrayCreationExpression; -import com.strobel.decompiler.languages.java.ast.ArrayInitializerExpression; -import com.strobel.decompiler.languages.java.ast.ArraySpecifier; -import com.strobel.decompiler.languages.java.ast.AssertStatement; -import com.strobel.decompiler.languages.java.ast.AssignmentExpression; -import com.strobel.decompiler.languages.java.ast.AstNode; -import com.strobel.decompiler.languages.java.ast.BinaryOperatorExpression; -import com.strobel.decompiler.languages.java.ast.BlockStatement; -import com.strobel.decompiler.languages.java.ast.BreakStatement; -import com.strobel.decompiler.languages.java.ast.CaseLabel; -import com.strobel.decompiler.languages.java.ast.CastExpression; -import com.strobel.decompiler.languages.java.ast.CatchClause; -import com.strobel.decompiler.languages.java.ast.ClassOfExpression; -import com.strobel.decompiler.languages.java.ast.Comment; -import com.strobel.decompiler.languages.java.ast.CompilationUnit; -import com.strobel.decompiler.languages.java.ast.ComposedType; -import com.strobel.decompiler.languages.java.ast.ConditionalExpression; -import com.strobel.decompiler.languages.java.ast.ConstructorDeclaration; -import com.strobel.decompiler.languages.java.ast.ContinueStatement; -import com.strobel.decompiler.languages.java.ast.DoWhileStatement; -import com.strobel.decompiler.languages.java.ast.EmptyStatement; -import com.strobel.decompiler.languages.java.ast.EnumValueDeclaration; -import com.strobel.decompiler.languages.java.ast.ExpressionStatement; -import com.strobel.decompiler.languages.java.ast.FieldDeclaration; -import com.strobel.decompiler.languages.java.ast.ForEachStatement; -import com.strobel.decompiler.languages.java.ast.ForStatement; -import com.strobel.decompiler.languages.java.ast.GotoStatement; -import com.strobel.decompiler.languages.java.ast.IAstVisitor; -import com.strobel.decompiler.languages.java.ast.Identifier; -import com.strobel.decompiler.languages.java.ast.IdentifierExpression; -import com.strobel.decompiler.languages.java.ast.IfElseStatement; -import com.strobel.decompiler.languages.java.ast.ImportDeclaration; -import com.strobel.decompiler.languages.java.ast.IndexerExpression; -import com.strobel.decompiler.languages.java.ast.InstanceInitializer; -import com.strobel.decompiler.languages.java.ast.InstanceOfExpression; -import com.strobel.decompiler.languages.java.ast.InvocationExpression; -import com.strobel.decompiler.languages.java.ast.JavaTokenNode; -import com.strobel.decompiler.languages.java.ast.Keys; -import com.strobel.decompiler.languages.java.ast.LabelStatement; -import com.strobel.decompiler.languages.java.ast.LabeledStatement; -import com.strobel.decompiler.languages.java.ast.LambdaExpression; -import com.strobel.decompiler.languages.java.ast.LocalTypeDeclarationStatement; -import com.strobel.decompiler.languages.java.ast.MemberReferenceExpression; -import com.strobel.decompiler.languages.java.ast.MethodDeclaration; -import com.strobel.decompiler.languages.java.ast.MethodGroupExpression; -import com.strobel.decompiler.languages.java.ast.NewLineNode; -import com.strobel.decompiler.languages.java.ast.NullReferenceExpression; -import com.strobel.decompiler.languages.java.ast.ObjectCreationExpression; -import com.strobel.decompiler.languages.java.ast.PackageDeclaration; -import com.strobel.decompiler.languages.java.ast.ParameterDeclaration; -import com.strobel.decompiler.languages.java.ast.ParenthesizedExpression; -import com.strobel.decompiler.languages.java.ast.PrimitiveExpression; -import com.strobel.decompiler.languages.java.ast.ReturnStatement; -import com.strobel.decompiler.languages.java.ast.SimpleType; -import com.strobel.decompiler.languages.java.ast.SuperReferenceExpression; -import com.strobel.decompiler.languages.java.ast.SwitchSection; -import com.strobel.decompiler.languages.java.ast.SwitchStatement; -import com.strobel.decompiler.languages.java.ast.SynchronizedStatement; -import com.strobel.decompiler.languages.java.ast.TextNode; -import com.strobel.decompiler.languages.java.ast.ThisReferenceExpression; -import com.strobel.decompiler.languages.java.ast.ThrowStatement; -import com.strobel.decompiler.languages.java.ast.TryCatchStatement; -import com.strobel.decompiler.languages.java.ast.TypeDeclaration; -import com.strobel.decompiler.languages.java.ast.TypeParameterDeclaration; -import com.strobel.decompiler.languages.java.ast.TypeReferenceExpression; -import com.strobel.decompiler.languages.java.ast.UnaryOperatorExpression; -import com.strobel.decompiler.languages.java.ast.VariableDeclarationStatement; -import com.strobel.decompiler.languages.java.ast.VariableInitializer; -import com.strobel.decompiler.languages.java.ast.WhileStatement; -import com.strobel.decompiler.languages.java.ast.WildcardType; -import com.strobel.decompiler.patterns.Pattern; - -import cuchaz.enigma.mapping.ArgumentEntry; -import cuchaz.enigma.mapping.ClassEntry; -import cuchaz.enigma.mapping.ConstructorEntry; -import cuchaz.enigma.mapping.FieldEntry; -import cuchaz.enigma.mapping.MethodEntry; - -public class SourceIndexVisitor implements IAstVisitor -{ - @Override - public Void visitInvocationExpression( InvocationExpression node, SourceIndex index ) - { - MemberReference ref = node.getUserData( Keys.MEMBER_REFERENCE ); - ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() ); - MethodEntry methodEntry = new MethodEntry( classEntry, ref.getName(), ref.getSignature() ); - if( node.getTarget() instanceof MemberReferenceExpression ) - { - index.add( ((MemberReferenceExpression)node.getTarget()).getMemberNameToken(), methodEntry ); - } - - return recurse( node, index ); - } - - @Override - public Void visitMemberReferenceExpression( MemberReferenceExpression node, SourceIndex index ) - { - MemberReference ref = node.getUserData( Keys.MEMBER_REFERENCE ); - if( ref != null ) - { - ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() ); - FieldEntry fieldEntry = new FieldEntry( classEntry, ref.getName() ); - index.add( node.getMemberNameToken(), fieldEntry ); - } - - return recurse( node, index ); - } - - @Override - public Void visitSimpleType( SimpleType node, SourceIndex index ) - { - TypeReference ref = node.getUserData( Keys.TYPE_REFERENCE ); - if( node.getIdentifierToken().getStartLocation() != TextLocation.EMPTY ) - { - index.add( node.getIdentifierToken(), new ClassEntry( ref.getInternalName() ) ); - } - - return recurse( node, index ); - } - - @Override - public Void visitMethodDeclaration( MethodDeclaration node, SourceIndex index ) - { - MethodDefinition def = node.getUserData( Keys.METHOD_DEFINITION ); - - // static initializers don't have identifier tokens - if( !def.getName().equals( "" ) ) - { - ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() ); - MethodEntry methodEntry = new MethodEntry( classEntry, def.getName(), def.getSignature() ); - index.addDeclaration( node.getNameToken(), methodEntry ); - } - - return recurse( node, index ); - } - - @Override - public Void visitConstructorDeclaration( ConstructorDeclaration node, SourceIndex index ) - { - MethodDefinition def = node.getUserData( Keys.METHOD_DEFINITION ); - ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() ); - ConstructorEntry constructorEntry = new ConstructorEntry( classEntry, def.getSignature() ); - index.addDeclaration( node.getNameToken(), constructorEntry ); - - return recurse( node, index ); - } - - @Override - public Void visitParameterDeclaration( ParameterDeclaration node, SourceIndex index ) - { - ParameterDefinition def = node.getUserData( Keys.PARAMETER_DEFINITION ); - ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() ); - MethodDefinition methodDef = (MethodDefinition)def.getMethod(); - MethodEntry methodEntry = new MethodEntry( classEntry, methodDef.getName(), methodDef.getSignature() ); - ArgumentEntry argumentEntry = new ArgumentEntry( methodEntry, def.getPosition(), def.getName() ); - index.addDeclaration( node.getNameToken(), argumentEntry ); - - return recurse( node, index ); - } - - @Override - public Void visitFieldDeclaration( FieldDeclaration node, SourceIndex index ) - { - FieldDefinition def = node.getUserData( Keys.FIELD_DEFINITION ); - ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() ); - FieldEntry fieldEntry = new FieldEntry( classEntry, def.getName() ); - assert( node.getVariables().size() == 1 ); - VariableInitializer variable = node.getVariables().firstOrNullObject(); - index.addDeclaration( variable.getNameToken(), fieldEntry ); - - return recurse( node, index ); - } - - @Override - public Void visitTypeDeclaration( TypeDeclaration node, SourceIndex index ) - { - TypeDefinition def = node.getUserData( Keys.TYPE_DEFINITION ); - index.addDeclaration( node.getNameToken(), new ClassEntry( def.getInternalName() ) ); - - return recurse( node, index ); - } - - @Override - public Void visitEnumValueDeclaration( EnumValueDeclaration node, SourceIndex index ) - { - // treat enum declarations as field declarations - FieldDefinition def = node.getUserData( Keys.FIELD_DEFINITION ); - ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() ); - FieldEntry fieldEntry = new FieldEntry( classEntry, def.getName() ); - index.addDeclaration( node.getNameToken(), fieldEntry ); - - return recurse( node, index ); - } - - @Override - public Void visitIdentifierExpression( IdentifierExpression node, SourceIndex index ) - { - MemberReference ref = node.getUserData( Keys.MEMBER_REFERENCE ); - if( ref != null ) - { - ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() ); - FieldEntry fieldEntry = new FieldEntry( classEntry, ref.getName() ); - index.add( node.getIdentifierToken(), fieldEntry ); - } - - return recurse( node, index ); - } - - private Void recurse( AstNode node, SourceIndex index ) - { - for( final AstNode child : node.getChildren() ) - { - child.acceptVisitor( this, index ); - } - return null; - } - - // OVERRIDES WE DON'T CARE ABOUT - - @Override - public Void visitComment( Comment node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitPatternPlaceholder( AstNode node, Pattern pattern, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitTypeReference( TypeReferenceExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitJavaTokenNode( JavaTokenNode node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitIdentifier( Identifier node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitNullReferenceExpression( NullReferenceExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitThisReferenceExpression( ThisReferenceExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitSuperReferenceExpression( SuperReferenceExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitClassOfExpression( ClassOfExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitBlockStatement( BlockStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitExpressionStatement( ExpressionStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitBreakStatement( BreakStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitContinueStatement( ContinueStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitDoWhileStatement( DoWhileStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitEmptyStatement( EmptyStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitIfElseStatement( IfElseStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitLabelStatement( LabelStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitLabeledStatement( LabeledStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitReturnStatement( ReturnStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitSwitchStatement( SwitchStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitSwitchSection( SwitchSection node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitCaseLabel( CaseLabel node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitThrowStatement( ThrowStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitCatchClause( CatchClause node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitAnnotation( Annotation node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitNewLine( NewLineNode node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitVariableDeclaration( VariableDeclarationStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitVariableInitializer( VariableInitializer node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitText( TextNode node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitImportDeclaration( ImportDeclaration node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitInitializerBlock( InstanceInitializer node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitTypeParameterDeclaration( TypeParameterDeclaration node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitCompilationUnit( CompilationUnit node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitPackageDeclaration( PackageDeclaration node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitArraySpecifier( ArraySpecifier node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitComposedType( ComposedType node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitWhileStatement( WhileStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitPrimitiveExpression( PrimitiveExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitCastExpression( CastExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitBinaryOperatorExpression( BinaryOperatorExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitInstanceOfExpression( InstanceOfExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitIndexerExpression( IndexerExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitUnaryOperatorExpression( UnaryOperatorExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitConditionalExpression( ConditionalExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitArrayInitializerExpression( ArrayInitializerExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitObjectCreationExpression( ObjectCreationExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitArrayCreationExpression( ArrayCreationExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitAssignmentExpression( AssignmentExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitForStatement( ForStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitForEachStatement( ForEachStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitTryCatchStatement( TryCatchStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitGotoStatement( GotoStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitParenthesizedExpression( ParenthesizedExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitSynchronizedStatement( SynchronizedStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitAnonymousObjectCreationExpression( AnonymousObjectCreationExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitWildcardType( WildcardType node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitMethodGroupExpression( MethodGroupExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitAssertStatement( AssertStatement node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitLambdaExpression( LambdaExpression node, SourceIndex index ) - { - return recurse( node, index ); - } - - @Override - public Void visitLocalTypeDeclarationStatement( LocalTypeDeclarationStatement node, SourceIndex index ) - { - return recurse( node, index ); - } -} diff --git a/src/cuchaz/enigma/analysis/Token.java b/src/cuchaz/enigma/analysis/Token.java index 74023e32..d0f2b70b 100644 --- a/src/cuchaz/enigma/analysis/Token.java +++ b/src/cuchaz/enigma/analysis/Token.java @@ -46,4 +46,10 @@ public class Token implements Comparable { return start == other.start && end == other.end; } + + @Override + public String toString( ) + { + return String.format( "[%d,%d]", start, end ); + } } diff --git a/src/cuchaz/enigma/gui/Gui.java b/src/cuchaz/enigma/gui/Gui.java index 43a0cdad..341c1493 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; import cuchaz.enigma.Constants; import cuchaz.enigma.analysis.BehaviorReferenceTreeNode; import cuchaz.enigma.analysis.ClassInheritanceTreeNode; +import cuchaz.enigma.analysis.EntryReference; import cuchaz.enigma.analysis.FieldReferenceTreeNode; import cuchaz.enigma.analysis.MethodInheritanceTreeNode; import cuchaz.enigma.analysis.ReferenceTreeNode; @@ -76,7 +77,6 @@ import cuchaz.enigma.mapping.ArgumentEntry; import cuchaz.enigma.mapping.ClassEntry; import cuchaz.enigma.mapping.ConstructorEntry; import cuchaz.enigma.mapping.Entry; -import cuchaz.enigma.mapping.EntryPair; import cuchaz.enigma.mapping.FieldEntry; import cuchaz.enigma.mapping.IllegalNameException; import cuchaz.enigma.mapping.MappingParseException; @@ -160,7 +160,7 @@ public class Gui private JMenuItem m_showCallsMenu; // state - private EntryPair m_selectedEntryPair; + private EntryReference m_reference; private JFileChooser m_jarFileChooser; private JFileChooser m_mappingsFileChooser; @@ -192,6 +192,10 @@ public class Gui String selected = m_obfClasses.getSelectedValue(); if( selected != null ) { + if( m_reference != null ) + { + m_controller.savePreviousReference( m_reference ); + } m_controller.openDeclaration( new ClassEntry( selected ) ); } } @@ -218,6 +222,10 @@ public class Gui String selected = m_deobfClasses.getSelectedValue(); if( selected != null ) { + if( m_reference != null ) + { + m_controller.savePreviousReference( m_reference ); + } m_controller.openDeclaration( new ClassEntry( selected ) ); } } @@ -234,7 +242,7 @@ public class Gui m_infoPanel.setLayout( new GridLayout( 4, 1, 0, 0 ) ); m_infoPanel.setPreferredSize( new Dimension( 0, 100 ) ); m_infoPanel.setBorder( BorderFactory.createTitledBorder( "Identifier Info" ) ); - clearEntryPair(); + clearReference(); // init editor DefaultSyntaxKit.initKit(); @@ -273,7 +281,7 @@ public class Gui break; case KeyEvent.VK_P: - m_controller.openPreviousLocation(); + m_controller.openPreviousReference(); break; case KeyEvent.VK_C: @@ -357,7 +365,7 @@ public class Gui @Override public void actionPerformed( ActionEvent event ) { - m_controller.openPreviousLocation(); + m_controller.openPreviousReference(); } } ); menu.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_P, 0 ) ); @@ -386,6 +394,10 @@ public class Gui Object node = path.getLastPathComponent(); if( node instanceof ClassInheritanceTreeNode ) { + if( m_reference != null ) + { + m_controller.savePreviousReference( m_reference ); + } m_controller.openDeclaration( new ClassEntry( ((ClassInheritanceTreeNode)node).getObfClassName() ) ); } else if( node instanceof MethodInheritanceTreeNode ) @@ -393,6 +405,10 @@ public class Gui MethodInheritanceTreeNode methodNode = (MethodInheritanceTreeNode)node; if( methodNode.isImplemented() ) { + if( m_reference != null ) + { + m_controller.savePreviousReference( m_reference ); + } m_controller.openDeclaration( methodNode.getMethodEntry() ); } } @@ -424,7 +440,11 @@ public class Gui Object node = path.getLastPathComponent(); if( node instanceof ReferenceTreeNode ) { - ReferenceTreeNode referenceNode = ((ReferenceTreeNode)node); + if( m_reference != null ) + { + m_controller.savePreviousReference( m_reference ); + } + ReferenceTreeNode referenceNode = ((ReferenceTreeNode)node); if( referenceNode.getReference() != null ) { m_controller.openReference( referenceNode.getReference() ); @@ -715,6 +735,10 @@ public class Gui public void showToken( Token token ) { + if( token == null ) + { + throw new IllegalArgumentException( "Token cannot be null!" ); + } m_editor.setCaretPosition( token.start ); m_editor.grabFocus(); } @@ -752,7 +776,7 @@ public class Gui } } - private void clearEntryPair( ) + private void clearReference( ) { m_infoPanel.removeAll(); JLabel label = new JLabel( "No identifier selected" ); @@ -763,76 +787,75 @@ public class Gui redraw(); } - @SuppressWarnings( "unchecked" ) - private void showEntryPair( EntryPair pair ) + private void showReference( EntryReference reference ) { - if( pair == null ) + if( reference == null ) { - clearEntryPair(); + clearReference(); return; } - m_selectedEntryPair = pair; + m_reference = reference; m_infoPanel.removeAll(); - if( pair.deobf instanceof ClassEntry ) + if( reference.entry instanceof ClassEntry ) { - showClassEntryPair( (EntryPair)pair ); + showClassEntry( (ClassEntry)m_reference.entry ); } - else if( pair.deobf instanceof FieldEntry ) + else if( m_reference.entry instanceof FieldEntry ) { - showFieldEntryPair( (EntryPair)pair ); + showFieldEntry( (FieldEntry)m_reference.entry ); } - else if( pair.deobf instanceof MethodEntry ) + else if( m_reference.entry instanceof MethodEntry ) { - showMethodEntryPair( (EntryPair)pair ); + showMethodEntry( (MethodEntry)m_reference.entry ); } - else if( pair.deobf instanceof ConstructorEntry ) + else if( m_reference.entry instanceof ConstructorEntry ) { - showConstructorEntryPair( (EntryPair)pair ); + showConstructorEntry( (ConstructorEntry)m_reference.entry ); } - else if( pair.deobf instanceof ArgumentEntry ) + else if( m_reference.entry instanceof ArgumentEntry ) { - showArgumentEntryPair( (EntryPair)pair ); + showArgumentEntry( (ArgumentEntry)m_reference.entry ); } else { - throw new Error( "Unknown entry type: " + pair.deobf.getClass().getName() ); + throw new Error( "Unknown entry type: " + m_reference.entry.getClass().getName() ); } redraw(); } - private void showClassEntryPair( EntryPair pair ) + private void showClassEntry( ClassEntry entry ) { - addNameValue( m_infoPanel, "Class", pair.deobf.getName() ); + addNameValue( m_infoPanel, "Class", entry.getName() ); } - private void showFieldEntryPair( EntryPair pair ) + private void showFieldEntry( FieldEntry entry ) { - addNameValue( m_infoPanel, "Field", pair.deobf.getName() ); - addNameValue( m_infoPanel, "Class", pair.deobf.getClassEntry().getName() ); + addNameValue( m_infoPanel, "Field", entry.getName() ); + addNameValue( m_infoPanel, "Class", entry.getClassEntry().getName() ); } - private void showMethodEntryPair( EntryPair pair ) + private void showMethodEntry( MethodEntry entry ) { - addNameValue( m_infoPanel, "Method", pair.deobf.getName() ); - addNameValue( m_infoPanel, "Class", pair.deobf.getClassEntry().getName() ); - addNameValue( m_infoPanel, "Signature", pair.deobf.getSignature() ); + addNameValue( m_infoPanel, "Method", entry.getName() ); + addNameValue( m_infoPanel, "Class", entry.getClassEntry().getName() ); + addNameValue( m_infoPanel, "Signature", entry.getSignature() ); } - private void showConstructorEntryPair( EntryPair pair ) + private void showConstructorEntry( ConstructorEntry entry ) { - addNameValue( m_infoPanel, "Constructor", pair.deobf.getClassEntry().getName() ); - addNameValue( m_infoPanel, "Signature", pair.deobf.getSignature() ); + addNameValue( m_infoPanel, "Constructor", entry.getClassEntry().getName() ); + addNameValue( m_infoPanel, "Signature", entry.getSignature() ); } - private void showArgumentEntryPair( EntryPair pair ) + private void showArgumentEntry( ArgumentEntry entry ) { - addNameValue( m_infoPanel, "Argument", pair.deobf.getName() ); - addNameValue( m_infoPanel, "Class", pair.deobf.getClassEntry().getName() ); - addNameValue( m_infoPanel, "Method", pair.deobf.getMethodEntry().getName() ); - addNameValue( m_infoPanel, "Index", Integer.toString( pair.deobf.getIndex() ) ); + addNameValue( m_infoPanel, "Argument", entry.getName() ); + addNameValue( m_infoPanel, "Class", entry.getClassEntry().getName() ); + addNameValue( m_infoPanel, "Method", entry.getMethodEntry().getName() ); + addNameValue( m_infoPanel, "Index", Integer.toString( entry.getIndex() ) ); } private void addNameValue( JPanel container, String name, String value ) @@ -853,19 +876,19 @@ public class Gui Token token = m_controller.getToken( pos ); boolean isToken = token != null; - m_selectedEntryPair = m_controller.getEntryPair( token ); - boolean isClassEntry = isToken && m_selectedEntryPair.obf instanceof ClassEntry; - boolean isFieldEntry = isToken && m_selectedEntryPair.obf instanceof FieldEntry; - boolean isMethodEntry = isToken && m_selectedEntryPair.obf instanceof MethodEntry; - boolean isConstructorEntry = isToken && m_selectedEntryPair.obf instanceof ConstructorEntry; + m_reference = m_controller.getDeobfReference( token ); + boolean isClassEntry = isToken && m_reference.entry instanceof ClassEntry; + boolean isFieldEntry = isToken && m_reference.entry instanceof FieldEntry; + boolean isMethodEntry = isToken && m_reference.entry instanceof MethodEntry; + boolean isConstructorEntry = isToken && m_reference.entry instanceof ConstructorEntry; if( isToken ) { - showEntryPair( m_selectedEntryPair ); + showReference( m_reference ); } else { - clearEntryPair(); + clearReference(); } m_renameMenu.setEnabled( isToken ); @@ -878,11 +901,11 @@ public class Gui private void startRename( ) { // get the class name - String className = m_selectedEntryPair.deobf.getName(); - int pos = className.lastIndexOf( '$' ); - if( pos >= 0 ) + ClassEntry classEntry = m_reference.entry.getClassEntry(); + String className = classEntry.getName(); + if( classEntry.isInnerClass() ) { - className = className.substring( pos + 1 ); + className = classEntry.getInnerClassName(); } // init the text box @@ -924,7 +947,7 @@ public class Gui { try { - m_controller.rename( m_selectedEntryPair.obf, newName ); + m_controller.rename( m_reference, newName ); } catch( IllegalNameException ex ) { @@ -937,7 +960,7 @@ public class Gui // abort the rename JPanel panel = (JPanel)m_infoPanel.getComponent( 0 ); panel.remove( panel.getComponentCount() - 1 ); - panel.add( unboldLabel( new JLabel( m_selectedEntryPair.deobf.getName(), JLabel.LEFT ) ) ); + panel.add( unboldLabel( new JLabel( m_reference.entry.getName(), JLabel.LEFT ) ) ); m_editor.grabFocus(); @@ -946,15 +969,15 @@ public class Gui private void showInheritance( ) { - if( m_selectedEntryPair == null ) + if( m_reference == null ) { return; } - if( m_selectedEntryPair.obf instanceof ClassEntry ) + if( m_reference.entry instanceof ClassEntry ) { // get the class inheritance - ClassInheritanceTreeNode classNode = m_controller.getClassInheritance( (ClassEntry)m_selectedEntryPair.obf ); + ClassInheritanceTreeNode classNode = m_controller.getClassInheritance( (ClassEntry)m_reference.entry ); // show the tree at the root TreePath path = getPathToRoot( classNode ); @@ -962,10 +985,10 @@ public class Gui m_inheritanceTree.expandPath( path ); m_inheritanceTree.setSelectionRow( m_inheritanceTree.getRowForPath( path ) ); } - else if( m_selectedEntryPair.obf instanceof MethodEntry ) + else if( m_reference.entry instanceof MethodEntry ) { // get the method inheritance - MethodInheritanceTreeNode classNode = m_controller.getMethodInheritance( (MethodEntry)m_selectedEntryPair.obf ); + MethodInheritanceTreeNode classNode = m_controller.getMethodInheritance( (MethodEntry)m_reference.entry ); // show the tree at the root TreePath path = getPathToRoot( classNode ); @@ -980,24 +1003,24 @@ public class Gui private void showCalls( ) { - if( m_selectedEntryPair == null ) + if( m_reference == null ) { return; } - if( m_selectedEntryPair.obf instanceof FieldEntry ) + if( m_reference.entry instanceof FieldEntry ) { - FieldReferenceTreeNode node = m_controller.getFieldReferences( (FieldEntry)m_selectedEntryPair.obf ); + FieldReferenceTreeNode node = m_controller.getFieldReferences( (FieldEntry)m_reference.entry ); m_callsTree.setModel( new DefaultTreeModel( node ) ); } - else if( m_selectedEntryPair.obf instanceof MethodEntry ) + else if( m_reference.entry instanceof MethodEntry ) { - BehaviorReferenceTreeNode node = m_controller.getMethodReferences( (MethodEntry)m_selectedEntryPair.obf ); + BehaviorReferenceTreeNode node = m_controller.getMethodReferences( (MethodEntry)m_reference.entry ); m_callsTree.setModel( new DefaultTreeModel( node ) ); } - else if( m_selectedEntryPair.obf instanceof ConstructorEntry ) + else if( m_reference.entry instanceof ConstructorEntry ) { - BehaviorReferenceTreeNode node = m_controller.getMethodReferences( (ConstructorEntry)m_selectedEntryPair.obf ); + BehaviorReferenceTreeNode node = m_controller.getMethodReferences( (ConstructorEntry)m_reference.entry ); m_callsTree.setModel( new DefaultTreeModel( node ) ); } @@ -1021,11 +1044,12 @@ public class Gui private void openDeclaration( ) { - if( m_selectedEntryPair == null ) + if( m_reference == null ) { return; } - m_controller.openDeclaration( m_selectedEntryPair.obf ); + m_controller.savePreviousReference( m_reference ); + m_controller.openDeclaration( m_reference.entry ); } private void close( ) diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java index f80bec7e..dfa25576 100644 --- a/src/cuchaz/enigma/gui/GuiController.java +++ b/src/cuchaz/enigma/gui/GuiController.java @@ -14,10 +14,11 @@ import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.util.Deque; import java.util.List; -import java.util.Stack; import com.google.common.collect.Lists; +import com.google.common.collect.Queues; import cuchaz.enigma.Deobfuscator; import cuchaz.enigma.analysis.BehaviorReferenceTreeNode; @@ -30,7 +31,6 @@ import cuchaz.enigma.analysis.Token; import cuchaz.enigma.mapping.BehaviorEntry; import cuchaz.enigma.mapping.ClassEntry; import cuchaz.enigma.mapping.Entry; -import cuchaz.enigma.mapping.EntryPair; import cuchaz.enigma.mapping.FieldEntry; import cuchaz.enigma.mapping.MappingParseException; import cuchaz.enigma.mapping.MappingsReader; @@ -43,18 +43,18 @@ public class GuiController private Deobfuscator m_deobfuscator; private Gui m_gui; private SourceIndex m_index; - private ClassEntry m_currentClass; + private ClassEntry m_currentObfClass; private boolean m_isDirty; - private Stack m_locationStack; // TODO: make a location class, can be either Entry or EntryReference + private Deque> m_referenceStack; // TODO: make a location class, can be either Entry or EntryReference public GuiController( Gui gui ) { m_gui = gui; m_deobfuscator = null; m_index = null; - m_currentClass = null; + m_currentObfClass = null; m_isDirty = false; - m_locationStack = new Stack(); + m_referenceStack = Queues.newArrayDeque(); } public boolean isDirty( ) @@ -112,22 +112,16 @@ public class GuiController return null; } - return m_index.getToken( pos ); + return m_index.getReferenceToken( pos ); } - public EntryPair getEntryPair( Token token ) + public EntryReference getDeobfReference( Token token ) { if( m_index == null ) { return null; } - - Entry deobfEntry = m_index.getEntry( token ); - if( deobfEntry == null ) - { - return null; - } - return new EntryPair( m_deobfuscator.obfuscateEntry( deobfEntry ), deobfEntry ); + return m_index.getDeobfReference( token ); } public boolean entryHasMapping( Entry deobfEntry ) @@ -178,54 +172,63 @@ public class GuiController return rootNode; } - public void rename( Entry obfEntry, String newName ) + public void rename( EntryReference deobfReference, String newName ) { - m_deobfuscator.rename( obfEntry, newName ); + EntryReference obfReference = m_deobfuscator.obfuscateReference( deobfReference ); + m_deobfuscator.rename( obfReference.entry, newName ); m_isDirty = true; refreshClasses(); - refreshCurrentClass( obfEntry ); + refreshCurrentClass( obfReference ); } public void openDeclaration( Entry entry ) { - // go to the entry - Entry obfEntry = m_deobfuscator.obfuscateEntry( entry ); - if( m_currentClass == null || !m_currentClass.equals( obfEntry.getClassEntry() ) ) + if( entry == null ) { - m_currentClass = new ClassEntry( obfEntry.getClassEntry() ); - deobfuscate( m_currentClass, obfEntry ); + throw new IllegalArgumentException( "Entry cannot be null!" ); } - else + openReference( new EntryReference( entry ) ); + } + + public void openReference( EntryReference deobfReference ) + { + if( deobfReference == null ) { - m_gui.showToken( m_index.getDeclarationToken( m_deobfuscator.deobfuscateEntry( obfEntry ) ) ); + throw new IllegalArgumentException( "Reference cannot be null!" ); } - if( m_locationStack.isEmpty() || !m_locationStack.peek().equals( obfEntry ) ) + // get the reference target class + EntryReference obfReference = m_deobfuscator.obfuscateReference( deobfReference ); + ClassEntry obfClassEntry = obfReference.getClassEntry().getOuterClassEntry(); + if( m_currentObfClass == null || !m_currentObfClass.equals( obfClassEntry ) ) + { + // deobfuscate the class, then navigate to the reference + m_currentObfClass = obfClassEntry; + deobfuscate( m_currentObfClass, obfReference ); + } + else { - // update the stack - m_locationStack.push( obfEntry ); + // the class file is already open, just navigate to the reference + m_gui.showToken( m_index.getReferenceToken( deobfReference ) ); } } - public void openReference( EntryReference reference ) + public void savePreviousReference( EntryReference deobfReference ) { - // TODO: find out how to load the n-th reference in a caller - // TEMP: just go to the caller for now - openDeclaration( reference.caller ); + m_referenceStack.push( m_deobfuscator.obfuscateReference( deobfReference ) ); } - public void openPreviousLocation( ) + public void openPreviousReference( ) { if( hasPreviousLocation() ) { - m_locationStack.pop(); - openDeclaration( m_locationStack.peek() ); + openReference( m_deobfuscator.deobfuscateReference( m_referenceStack.pop() ) ); } } public boolean hasPreviousLocation( ) { - return m_locationStack.size() > 1; + return !m_referenceStack.isEmpty(); } private void refreshClasses( ) @@ -242,15 +245,15 @@ public class GuiController refreshCurrentClass( null ); } - private void refreshCurrentClass( Entry obfEntryToShow ) + private void refreshCurrentClass( EntryReference obfReferenceToShow ) { - if( m_currentClass != null ) + if( m_currentObfClass != null ) { - deobfuscate( m_currentClass, obfEntryToShow ); + deobfuscate( m_currentObfClass, obfReferenceToShow ); } } - private void deobfuscate( final ClassEntry classEntry, final Entry obfEntryToShow ) + private void deobfuscate( final ClassEntry classEntry, final EntryReference obfReferenceToShow ) { m_gui.setSource( "(deobfuscating...)" ); @@ -263,29 +266,32 @@ public class GuiController // decompile,deobfuscate the bytecode m_index = m_deobfuscator.getSource( classEntry.getClassName() ); m_gui.setSource( m_index.getSource() ); - if( obfEntryToShow != null ) + if( obfReferenceToShow != null ) { - Entry deobfEntryToShow = m_deobfuscator.deobfuscateEntry( obfEntryToShow ); - Token token = m_index.getDeclarationToken( deobfEntryToShow ); + EntryReference deobfReferenceToShow = m_deobfuscator.deobfuscateReference( obfReferenceToShow ); + Token token = m_index.getReferenceToken( deobfReferenceToShow ); if( token == null ) { - // TEMP - System.out.println( "WARNING: can't find token for " + obfEntryToShow + " -> " + deobfEntryToShow ); + // DEBUG + System.out.println( "WARNING: can't find token for " + obfReferenceToShow + " -> " + deobfReferenceToShow ); + } + else + { + m_gui.showToken( token ); } - m_gui.showToken( token ); } // set the highlighted tokens List obfuscatedTokens = Lists.newArrayList(); List deobfuscatedTokens = Lists.newArrayList(); - for( Token token : m_index.tokens() ) + for( Token token : m_index.referenceTokens() ) { - Entry entry = m_index.getEntry( token ); - if( entryHasMapping( entry ) ) + EntryReference reference = m_index.getDeobfReference( token ); + if( entryHasMapping( reference.entry ) ) { deobfuscatedTokens.add( token ); } - else if( entryIsObfuscatedIdenfitier( entry ) ) + else if( entryIsObfuscatedIdenfitier( reference.entry ) ) { obfuscatedTokens.add( token ); } diff --git a/src/cuchaz/enigma/mapping/Translator.java b/src/cuchaz/enigma/mapping/Translator.java index a1230db3..e34c31bf 100644 --- a/src/cuchaz/enigma/mapping/Translator.java +++ b/src/cuchaz/enigma/mapping/Translator.java @@ -30,6 +30,34 @@ public class Translator m_ancestries = ancestries; } + public Entry translateEntry( Entry entry ) + { + if( entry instanceof ClassEntry ) + { + return translateEntry( (ClassEntry)entry ); + } + else if( entry instanceof FieldEntry ) + { + return translateEntry( (FieldEntry)entry ); + } + else if( entry instanceof MethodEntry ) + { + return translateEntry( (MethodEntry)entry ); + } + else if( entry instanceof ConstructorEntry ) + { + return translateEntry( (ConstructorEntry)entry ); + } + else if( entry instanceof ArgumentEntry ) + { + return translateEntry( (ArgumentEntry)entry ); + } + else + { + throw new Error( "Unknown entry type: " + entry.getClass().getName() ); + } + } + public String translateClass( String className ) { return translate( new ClassEntry( className ) ); -- cgit v1.2.3