上一篇文章介绍了一些背景知识以及如何创建一个ASTParser,下面给出一些使用AST的例子。
创建ASTParser并将Java源文件解析成AST:
// Initialize ASTParser ASTParser parser = ASTParser.newParser(AST.JLS3); //initialize parser.setKind(ASTParser.K_COMPILATION_UNIT); //to parse compilation unit parser.setSource(content.toCharArray()); //content is a string which stores the java source parser.setResolveBindings(true); CompilationUnit result = (CompilationUnit) parser.createAST(null);
调用imports()方法得到源文件的一系列import声明:
//show import declarations in order List importList = result.imports(); System.out.println("import:"); for(Object obj : importList) { ImportDeclaration importDec = (ImportDeclaration)obj; System.out.println(importDec.getName()); }
调用types()方法得到类名称:
//show class name List types = result.types(); TypeDeclaration typeDec = (TypeDeclaration) types.get(0); System.out.println("className:"+typeDec.getName());
调用TypeDeclaration的getField方法得到类里定义的field:
//show fields FieldDeclaration fieldDec[]=typeDec.getFields(); System.out.println("Fields:"); for(FieldDeclaration field: fieldDec) { System.out.println("Field fragment:"+field.fragments()); System.out.println("Field type:"+field.getType()); }
调用TypeDeclaration的getMethods方法得到类里定义的list of methods;同理,可以调用MethodDeclaration里的各种方法得到method的方法名,参数,返回类型等等:
//show methods MethodDeclaration methodDec[] = typeDec.getMethods(); System.out.println("Method:"); for (MethodDeclaration method : methodDec) { //get method name SimpleName methodName=method.getName(); System.out.println("method name:"+methodName); //get method parameters List param=method.parameters(); System.out.println("method parameters:"+param); //get method return type Type returnType=method.getReturnType2(); System.out.println("method return type:"+returnType);
一个方法的内容对应一个block,可以用getBody()得到;一个block又可以被分解成一系列statements,可以用statements()方法得到:
//get method body Block body=method.getBody(); List statements=body.statements(); //get the statements of the method body Iterator iter=statements.iterator(); while(iter.hasNext()) { //get each statement Statement stmt=(Statement)iter.next();
接下来需要根据每个statement的类型来对源码进行相应的解析。Statement有很多子类,这里只给出其中的几类介绍(具体可以参考我上一篇文章:ASTParser介绍;最好直接去Eclipse documentation官网查看相关文档)。基本流程就是先判断statement是哪种类型的实例,做出相应的ClassCast,再调用相应的方法。
1. ExpressionStatement (又包括Assignement, MethodInvocation等子类)。
if(stmt instanceof ExpressionStatement) { ExpressionStatement expressStmt=(ExpressionStatement) stmt; Expression express=expressStmt.getExpression(); if(express instanceof Assignment) { Assignment assign=(Assignment)express; System.out.println("LHS:"+assign.getLeftHandSide()+"; "); System.out.println("Op:"+assign.getOperator()+"; "); System.out.println("RHS:"+assign.getRightHandSide()); } else if(express instanceof MethodInvocation) { MethodInvocation mi=(MethodInvocation) express; System.out.println("invocation name:"+mi.getName()); System.out.println("invocation exp:"+mi.getExpression()); System.out.println("invocation arg:"+mi.arguments()); } System.out.println(); }
2. IfStatement
else if(stmt instanceof IfStatement) { IfStatement ifstmt=(IfStatement) stmt; InfixExpression wex=(InfixExpression) ifstmt.getExpression(); System.out.println("if-LHS:"+wex.getLeftOperand()+"; "); System.out.println("if-op:"+wex.getOperator()+"; "); System.out.println("if-RHS:"+wex.getRightOperand()); System.out.println(); }
3. VariableDeclarationStatement
else if(stmt instanceof VariableDeclarationStatement) { VariableDeclarationStatement var=(VariableDeclarationStatement) stmt; System.out.println("Type of variable:"+var.getType()); System.out.println("Name of variable:"+var.fragments()); System.out.println(); }
4. ReturnStatement
else if(stmt instanceof ReturnStatement) { ReturnStatement rtstmt=(ReturnStatement) stmt; System.out.println("return:"+rtstmt.getExpression()); System.out.println(); }
ASTParser 作为programming language编译器的一部分,功能机制可以说是相当强大。以上的例子只是冰山一角。使用ASTParser可以对java的源文件进行各种解析,用户只需要指明源文件,调用一下ASTParser的createAST方法就能得到完整的AST了,剩下的就是用户根据实际需要对AST进行各种manipulate了。
Eclipse documentation详细记录了AST相关的各类描述,继承关系等等。另外,如果对AST机制或者在Eclipse里使用ASTParser有什么疑问的话,可以参考我的另一篇文章:Eclipse JDT--AST入门,里面整理了很多相关资料。
估计接下来一段时间就是继续研究AST了,还请各位高手多多指教~~~
最后一句碎碎念:尽请转载,不过请注明出处哦,必须的~~~:)