一、AST版“Hello World”
- public class HelloWorld {
- public static void main(String[] args) {
- AST ast = AST.newAST(AST.JLS3);
- CompilationUnit compilationUnit = ast.newCompilationUnit();
- TypeDeclaration programClass = ast.newTypeDeclaration();
- programClass.setName(ast.newSimpleName("HelloWorld"));
- programClass.modifiers().add(
- ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD));
- compilationUnit.types().add(programClass);
- PackageDeclaration packageDeclaration = ast.newPackageDeclaration();
- packageDeclaration.setName(ast.newName("com.dream"));
- compilationUnit.setPackage(packageDeclaration);
- MethodDeclaration main = ast.newMethodDeclaration();
- main.setName(ast.newSimpleName("main"));
- main.modifiers().add(
- ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD));
- main.modifiers().add(ast.newModifier(ModifierKeyword.STATIC_KEYWORD));
- main.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID));
- programClass.bodyDeclarations().add(main);
- Block mainBlock = ast.newBlock();
- main.setBody(mainBlock);
- SingleVariableDeclaration mainParameter = ast
- .newSingleVariableDeclaration();
- mainParameter.setName(ast.newSimpleName("arg"));
- mainParameter.setType(ast.newArrayType(ast.newSimpleType(ast
- .newName("String"))));
- main.parameters().add(mainParameter);
- MethodInvocation println=ast.newMethodInvocation();
- println.setName(ast.newSimpleName("prinln"));
- StringLiteral s=ast.newStringLiteral();
- s.setLiteralValue("Hello World");
- println.arguments().add(s);
- println.setExpression(ast.newName("System.out"));
- mainBlock.statements().add(ast.newExpressionStatement(println));
- System.out.println(compilationUnit.toString());
- }
- }
public class HelloWorld {
public static void main(String[] args) {
AST ast = AST.newAST(AST.JLS3);
CompilationUnit compilationUnit = ast.newCompilationUnit();
// 创建类
TypeDeclaration programClass = ast.newTypeDeclaration();
programClass.setName(ast.newSimpleName("HelloWorld"));
programClass.modifiers().add(
ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD));
compilationUnit.types().add(programClass);
// 创建包
PackageDeclaration packageDeclaration = ast.newPackageDeclaration();
packageDeclaration.setName(ast.newName("com.dream"));
compilationUnit.setPackage(packageDeclaration);
MethodDeclaration main = ast.newMethodDeclaration();
main.setName(ast.newSimpleName("main"));
main.modifiers().add(
ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD));
main.modifiers().add(ast.newModifier(ModifierKeyword.STATIC_KEYWORD));
main.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID));
programClass.bodyDeclarations().add(main);
Block mainBlock = ast.newBlock();
main.setBody(mainBlock);
// 给main方法定义String[]参数
SingleVariableDeclaration mainParameter = ast
.newSingleVariableDeclaration();
mainParameter.setName(ast.newSimpleName("arg"));
mainParameter.setType(ast.newArrayType(ast.newSimpleType(ast
.newName("String"))));
main.parameters().add(mainParameter);
MethodInvocation println=ast.newMethodInvocation();
println.setName(ast.newSimpleName("prinln"));
//生成String类型的常量
StringLiteral s=ast.newStringLiteral();
s.setLiteralValue("Hello World");
println.arguments().add(s);
println.setExpression(ast.newName("System.out"));
mainBlock.statements().add(ast.newExpressionStatement(println));
System.out.println(compilationUnit.toString());
}
}
上面的代码只是生成了一个只有一个main方法的类,并且main方法里面只有一行System.out.println("Hello World");
需要注意的几点:
-
AST ast = AST.newAST(AST.JLS3);AST.JLS3为版本,如果生成的代码中用到try的话,要用AST.JLS4这个版本
-
println.setExpression(ast.newName("System.out"));如果只是调用某个变量的方法,参数可以用ast.newSimpleName和ast.newName,如果中间的表达式很复杂,会出现一些java变量定义不允许的字符,就必须用ast.newName。Name和SimpleName都是从Expression中继承而来,所以只要用到Expression的地方,都可以直接用ast.newName。
-
所有的import都要自己手动加入,本例中没有。
二、用AST解析java源代码。
- ASTParser parsert = ASTParser.newParser(AST.JLS4);
- String contents = "public class T{public void t(){Object o;o=System.out;}}";
- parsert.setSource(contents.toCharArray());
- CompilationUnit result = (CompilationUnit) parsert.createAST(null);
- TypeDeclaration type = (TypeDeclaration) result.types().get(0);
- MethodDeclaration method = type.getMethods()[0];
- ExpressionStatement ifs = (ExpressionStatement) method.getBody().statements().get(1);
- Assignment expression=(Assignment)ifs.getExpression();
- Expression exp=expression.getRightHandSide();
ASTParser parsert = ASTParser.newParser(AST.JLS4);
String contents = "public class T{public void t(){Object o;o=System.out;}}";
parsert.setSource(contents.toCharArray());
// 使用解析器进行解析并返回AST上下文结果(CompilationUnit为根节点)
CompilationUnit result = (CompilationUnit) parsert.createAST(null);
TypeDeclaration type = (TypeDeclaration) result.types().get(0);
MethodDeclaration method = type.getMethods()[0];
ExpressionStatement ifs = (ExpressionStatement) method.getBody().statements().get(1);
Assignment expression=(Assignment)ifs.getExpression();
Expression exp=expression.getRightHandSide();
在ast中,所有的节点开成一个树,根节点为ast对象,根节点不同的两个节点不能互相添加。所以如果你想把解析出来的节点加到你自己生成的节点上,那你只有去改源代码了。在CompilationUnitResolver类的convert中的276行AST ast = AST.newAST(apiLevel);它每次都会新建一个AST,修改的办法就是重载一下这个方法,加一个AST参数。