使⽤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小时内删除。
发表评论