Javaparser使用
什么是Javaparser
分析,转换,生成Java代码.
Javaparser库为你提供了一个 Java 代码的抽象语法树(Abstract Syntax Tree)。
AST 结构允许您以一种简单的编程方式使用 Java 代码。
为什么需要Javaparser
相对于antlr4,Javaparser提供了更多的API,专门操作Java文件,使用起来更简单.
使用
1.解析多个Java文件
/**
* 解析工程下的所有Java文件
*
* @param path 工程根目录
*/
public static void parseProject(String path) {
Path root = Paths.get(path);
// only parsing
ProjectRoot projectRoot = new ParserCollectionStrategy().collect(root);
projectRoot.getSourceRoots().forEach(sourceRoot -> {
System.out.println(sourceRoot);
try {
// 解析source root
sourceRoot.tryToParse();
} catch (IOException e) {
e.printStackTrace();
}
// 获取解析后的编译单元列表
List<CompilationUnit> cuList = sourceRoot.getCompilationUnits();
cuList.forEach(JavaParserUtil::parseOneFile);
});
}
/**
* 解析单个Java文件
*
* @param cu 编译单元
*/
public static void parseOneFile(CompilationUnit cu) {
// 类型声明
NodeList<TypeDeclaration<?>> types = cu.getTypes();
for (TypeDeclaration<?> type : types) {
System.out.println("## " + type.getName());
// 成员
NodeList<BodyDeclaration<?>> members = type.getMembers();
members.forEach(JavaParserUtil::processNode);
}
}
/**
* 处理类型,方法,成员
*
* @param node
*/
public static void processNode(Node node) {
if (node instanceof TypeDeclaration) {
// 类型声明
// do something with this type declaration
} else if (node instanceof MethodDeclaration) {
// 方法声明
// do something with this method declaration
String methodName = ((MethodDeclaration) node).getName().getIdentifier();
System.out.println("方法: " + methodName);
} else if (node instanceof FieldDeclaration) {
// 成员变量声明
// do something with this field declaration
// 注释
Comment comment = node.getComment().orElse(null);
// 变量
NodeList<VariableDeclarator> variables = ((FieldDeclaration) node).getVariables();
SimpleName fieldName = variables.get(0).getName();
if (comment != null) {
System.out.print(handleComment(comment.getContent()));
}
System.out.print("\t");
System.out.print(fieldName);
System.out.println();
}
for (Node child : node.getChildNodes()) {
processNode(child);
}
}
2.修改Java文件
public static void main(String[] args) throws FileNotFoundException {
// The directory where we store the examples
String pathToExamplesDir = "." + separator + "src"
+ separator + "main" + separator + "resources";
String javaName = pathToExamplesDir
+ separator + "";
// Parse the code of an entire source file, . a Compilation Unit
CompilationUnit compilationUnitNode = StaticJavaParser.parse(new File(MyJavaParserConstant.JAVA_FILE_PATH));
printCompilationUnit("My original class", compilationUnitNode);
// Modifying the name of the class
String className = "HelloWorld";
compilationUnitNode.getClassByName(className).get()
.setName("MyRenamedClass");
printCompilationUnit("Renamed class", compilationUnitNode);
// Adding a method: we add a setter
MethodDeclaration setter = compilationUnitNode
.getClassByName("MyRenamedClass").get()
.addMethod("setAField", Modifier.Keyword.PUBLIC);
setter.addParameter("boolean", "aField");
setter.getBody().get().getStatements().add(new ExpressionStmt(
new AssignExpr(
new FieldAccessExpr(new ThisExpr(),"aField"),
new NameExpr("aField"),
AssignExpr.Operator.ASSIGN
)));
printCompilationUnit("With a setter", compilationUnitNode);
}
3.生成Java代码
/**
* 代码生成
*
* @author zhangcheng
* @date 2021/12/4
*/
public class CodeGenerationExample {
public static void main(String[] args) {
CompilationUnit compilationUnit = new CompilationUnit();
compilationUnit.setPackageDeclaration("");
// Add an asterisk import for
compilationUnit.addImport("", false, true);
// Create a class (not an interface, so the 2nd parameter is false)
ClassOrInterfaceDeclaration myClass = compilationUnit.addClass("MyClass", Modifier.Keyword.PUBLIC);
myClass.addField("List<String>", "elements", Modifier.Keyword.PRIVATE);
// Method to add an element to the field
MethodDeclaration addElement = myClass.addMethod("addElement", Modifier.Keyword.PUBLIC);
// our method get a parameter: the value to add to the field
addElement.addParameter("String", "newElement");
// the body consists in one expression wrapped into a statement
// the expression is in invocation of to which we
// pass the parameter
addElement.getBody().get().getStatements().add(new ExpressionStmt(
new MethodCallExpr(new NameExpr("elements"), new SimpleName("add"),
NodeList.nodeList(new NameExpr("newElement")))
));
// Method to get elements
MethodDeclaration getElements = myClass.addMethod("getElements", Modifier.Keyword.PUBLIC);
// we specify that we are returning a Collection of String
getElements.setType("Collection<String>");
// The body consists of just a return statement. We return the
// field
getElements.getBody().get().getStatements().add(new ReturnStmt(
new NameExpr("elements")));
System.out.println(compilationUnit);
}
}
参考
Javaparser github
Javaparser homepage
Javaparser使用教程
Javaparser代码生成
/ftomassetti/
/javaparser/
可用的demos
/ftomassetti/