From d24d2b9ad9b5c895020b56f700a72906346482e5 Mon Sep 17 00:00:00 2001 From: jeff Date: Sun, 10 Aug 2014 01:03:40 -0400 Subject: completely re-wrote token recognizer to bootstrap from Procyon's AST changed imports to guava instead of whatever collections library happened to be on my classpath --- src/cuchaz/enigma/analysis/SourceIndexVisitor.java | 618 +++++++++++++++++++++ 1 file changed, 618 insertions(+) create mode 100644 src/cuchaz/enigma/analysis/SourceIndexVisitor.java (limited to 'src/cuchaz/enigma/analysis/SourceIndexVisitor.java') diff --git a/src/cuchaz/enigma/analysis/SourceIndexVisitor.java b/src/cuchaz/enigma/analysis/SourceIndexVisitor.java new file mode 100644 index 0000000..2a26c85 --- /dev/null +++ b/src/cuchaz/enigma/analysis/SourceIndexVisitor.java @@ -0,0 +1,618 @@ +/******************************************************************************* + * 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.componentmodel.Key; +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.Expression; +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.FieldEntry; +import cuchaz.enigma.mapping.MethodEntry; + +public class SourceIndexVisitor implements IAstVisitor +{ + @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 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 visitTypeReference( TypeReferenceExpression node, SourceIndex index ) + { + return recurse( node, index ); + } + + @Override + public Void visitJavaTokenNode( JavaTokenNode node, SourceIndex index ) + { + 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 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 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 ); + ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() ); + MethodEntry methodEntry = new MethodEntry( classEntry, def.getName(), def.getSignature() ); + index.add( node.getNameToken(), methodEntry ); + + return recurse( node, index ); + } + + @Override + public Void visitInitializerBlock( InstanceInitializer node, SourceIndex index ) + { + return recurse( node, index ); + } + + @Override + public Void visitConstructorDeclaration( ConstructorDeclaration node, SourceIndex index ) + { + MethodDefinition def = node.getUserData( Keys.METHOD_DEFINITION ); + index.add( node.getNameToken(), new ClassEntry( def.getDeclaringType().getInternalName() ) ); + + return recurse( node, index ); + } + + @Override + public Void visitTypeParameterDeclaration( TypeParameterDeclaration node, SourceIndex index ) + { + 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.add( 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.add( variable.getNameToken(), fieldEntry ); + + return recurse( node, index ); + } + + @Override + public Void visitTypeDeclaration( TypeDeclaration node, SourceIndex index ) + { + TypeDefinition def = node.getUserData( Keys.TYPE_DEFINITION ); + index.add( node.getNameToken(), new ClassEntry( def.getInternalName() ) ); + + 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 visitIdentifierExpression( IdentifierExpression node, SourceIndex index ) + { + // TODO + 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 visitEnumValueDeclaration( EnumValueDeclaration 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 ); + } + + private Void recurse( AstNode node, SourceIndex index ) + { + // TEMP: show the tree + System.out.println( getIndent( node ) + node.getClass().getSimpleName() + dumpUserData( node ) + " " + node.getRegion() ); + + for( final AstNode child : node.getChildren() ) + { + child.acceptVisitor( this, index ); + } + return null; + } + + private String dumpUserData( AstNode node ) + { + StringBuilder buf = new StringBuilder(); + for( Key key : Keys.ALL_KEYS ) + { + Object val = node.getUserData( key ); + if( val != null ) + { + buf.append( String.format( " [%s=%s]", key, val ) ); + } + } + return buf.toString(); + } + + private String getIndent( AstNode node ) + { + StringBuilder buf = new StringBuilder(); + int depth = getDepth( node ); + for( int i = 0; i < depth; i++ ) + { + buf.append( "\t" ); + } + return buf.toString(); + } + + private int getDepth( AstNode node ) + { + int depth = -1; + while( node != null ) + { + depth++; + node = node.getParent(); + } + return depth; + } +} -- cgit v1.2.3