使⽤JavaParser进⾏java源码解析
刚开始接触的时候觉得和JDT⾥的Parser类不太⼀样。查了⼀下WiKi,发现它访问编译单元成员,需要调⽤相应⼦元素对应的Visitor类的visit()⽅法。此⽅法可以通过复写来实现⾃⼰需要的功能。我需要的功能是将编译单元⾥的所有MethodDeclaration取出,因此利⽤传递句柄的⽅式,实现代码如下:
1public static List<MethodDeclaration> getMethodList(CompilationUnit cu) {
2        List<MethodDeclaration> methodList = new ArrayList<MethodDeclaration>();
3new MethodGetterVisitor().visit(cu, methodList);
4
5return methodList;
6    }
7
8private static class MethodGetterVisitor extends VoidVisitorAdapter<Object> {
9
10        @SuppressWarnings("unchecked")
11        @Override
12public 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更复杂):
1public class MethodChanger {
2
3public 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;
8try {
9// parse the file
10            cu = JavaParser.parse(in);
11        } finally {
java源代码加密
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.String());
20    }
21
22private static void changeMethods(CompilationUnit cu) {
23        List<TypeDeclaration> types = cu.getTypes();
24for (TypeDeclaration type : types) {
25            List<BodyDeclaration> members = Members();
26for (BodyDeclaration member : members) {
27if (member instanceof MethodDeclaration) {
28                    MethodDeclaration method = (MethodDeclaration) member;
29                    changeMethod(method);
30                }
31            }
32        }
33    }
34
35private static void changeMethod(MethodDeclaration n) {
36// change the name of the method to upper case
37        n.Name().toUpperCase());
38
39// create the new parameter
40        Parameter newArg = ateParameter(ASTHelper.INT_TYPE, "value");
41
42// add the parameter to the method
43        ASTHelper.addParameter(n, newArg);
44    }
45 }
最后附上WiKi⾥给出的编译单元创建⽰例:
1public class ClassCreator {
2
3public 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.String());
9    }
10
11/**
12    * creates the compilation unit
13*/
14private static CompilationUnit createCU() {
15        CompilationUnit cu = new CompilationUnit();
16// set the package
17        cu.setPakage(new ateNameExpr("st")));
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.Modifiers(), ModifierSet.STATIC));
26        ASTHelper.addMember(type, method);
27
28// add a parameter to the method
29        Parameter param = ateReferenceType("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
44return cu;
45    }
46 }

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。