使用JavaParser进行java源码解析

  JavaParser下载地址:http://code.google.com/p/javaparser/downloads/list

  刚开始接触的时候觉得和JDT里的Parser类不太一样。查了一下WiKi,发现它访问编译单元成员,需要调用相应子元素对应的Visitor类的visit()方法。此方法可以通过复写来实现自己需要的功能。我需要的功能是将编译单元里的所有MethodDeclaration取出,因此利用传递句柄的方式,实现代码如下:

  

 1 public static List<MethodDeclaration> getMethodList(CompilationUnit cu) {
 2         List<MethodDeclaration> methodList = new ArrayList<MethodDeclaration>();
 3         new MethodGetterVisitor().visit(cu, methodList);
 4         
 5         return methodList;
 6     }
 7     
 8     private static class MethodGetterVisitor extends VoidVisitorAdapter<Object> {
 9 
10         @SuppressWarnings("unchecked")
11         @Override
12         public void visit(MethodDeclaration n, Object arg) {
13             List<MethodDeclaration> methodList = new ArrayList<MethodDeclaration>();
14             methodList =  (List<MethodDeclaration>) arg;
15             methodList.add(n);
16         }
17     }

   

  官方还提供了不通过Visitor改变一个类成员方法的示例(相对Visitor更复杂):

 1 public class MethodChanger {
 2 
 3     public static void main(String[] args) throws Exception {
 4         // creates an input stream for the file to be parsed
 5         FileInputStream in = new FileInputStream("test.java");
 6 
 7         CompilationUnit cu;
 8         try {
 9             // parse the file
10             cu = JavaParser.parse(in);
11         } finally {
12             in.close();
13         }
14 
15         // change the methods names and parameters
16         changeMethods(cu);
17 
18         // prints the changed compilation unit
19         System.out.println(cu.toString());
20     }
21 
22     private static void changeMethods(CompilationUnit cu) {
23         List<TypeDeclaration> types = cu.getTypes();
24         for (TypeDeclaration type : types) {
25             List<BodyDeclaration> members = type.getMembers();
26             for (BodyDeclaration member : members) {
27                 if (member instanceof MethodDeclaration) {
28                     MethodDeclaration method = (MethodDeclaration) member;
29                     changeMethod(method);
30                 }
31             }
32         }
33     }
34 
35     private static void changeMethod(MethodDeclaration n) {
36         // change the name of the method to upper case
37         n.setName(n.getName().toUpperCase());
38 
39         // create the new parameter
40         Parameter newArg = ASTHelper.createParameter(ASTHelper.INT_TYPE, "value");
41 
42         // add the parameter to the method
43         ASTHelper.addParameter(n, newArg);
44     }
45 }

 

 最后附上WiKi里给出的编译单元创建示例:

 1 public class ClassCreator {
 2 
 3     public static void main(String[] args) throws Exception {
 4         // creates the compilation unit
 5         CompilationUnit cu = createCU();
 6 
 7         // prints the created compilation unit
 8         System.out.println(cu.toString());
 9     }
10 
11     /**
12      * creates the compilation unit
13      */
14     private static CompilationUnit createCU() {
15         CompilationUnit cu = new CompilationUnit();
16         // set the package
17         cu.setPakage(new PackageDeclaration(ASTHelper.createNameExpr("java.parser.test")));
18 
19         // create the type declaration 
20         ClassOrInterfaceDeclaration type = new ClassOrInterfaceDeclaration(ModifierSet.PUBLIC, false, "GeneratedClass");
21         ASTHelper.addTypeDeclaration(cu, type);
22 
23         // create a method
24         MethodDeclaration method = new MethodDeclaration(ModifierSet.PUBLIC, ASTHelper.VOID_TYPE, "main");
25         method.setModifiers(ModifierSet.addModifier(method.getModifiers(), ModifierSet.STATIC));
26         ASTHelper.addMember(type, method);
27 
28         // add a parameter to the method
29         Parameter param = ASTHelper.createParameter(ASTHelper.createReferenceType("String", 0), "args");
30         param.setVarArgs(true);
31         ASTHelper.addParameter(method, param);
32 
33         // add a body to the method
34         BlockStmt block = new BlockStmt();
35         method.setBody(block);
36 
37         // add a statement do the method body
38         NameExpr clazz = new NameExpr("System");
39         FieldAccessExpr field = new FieldAccessExpr(clazz, "out");
40         MethodCallExpr call = new MethodCallExpr(field, "println");
41         ASTHelper.addArgument(call, new StringLiteralExpr("Hello World!"));
42         ASTHelper.addStmt(block, call);
43 
44         return cu;
45     }
46 }

 

posted @ 2014-02-11 09:25  viruseeee  阅读(12773)  评论(0编辑  收藏  举报