Javaparser使用
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 parsingProjectRoot projectRoot = new ParserCollectionStrategy().collect(root);projectRoot.getSourceRoots().forEach(sourceRoot -> {System.out.println(sourceRoot);try {// 解析source rootsourceRoot.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 declarationString 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 examplesString pathToExamplesDir = "." + separator + "src"+ separator + "main" + separator + "resources";String javaName = pathToExamplesDir+ separator + "ASimpleClass.java";// Parse the code of an entire source file, a.k.a. a Compilation UnitCompilationUnit compilationUnitNode = StaticJavaParser.parse(new File(MyJavaParserConstant.JAVA_FILE_PATH));printCompilationUnit("My original class", compilationUnitNode);// Modifying the name of the classString className = "HelloWorld";compilationUnitNode.getClassByName(className).get().setName("MyRenamedClass");printCompilationUnit("Renamed class", compilationUnitNode);// Adding a method: we add a setterMethodDeclaration 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("my.example.javaparser");// Add an asterisk import for java.utilcompilationUnit.addImport("java.util", 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 fieldMethodDeclaration addElement = myClass.addMethod("addElement", Modifier.Keyword.PUBLIC);// our method get a parameter: the value to add to the fieldaddElement.addParameter("String", "newElement");// the body consists in one expression wrapped into a statement// the expression is in invocation of elements.add to which we// pass the parameteraddElement.getBody().get().getStatements().add(new ExpressionStmt(new MethodCallExpr(new NameExpr("elements"), new SimpleName("add"),NodeList.nodeList(new NameExpr("newElement")))));// Method to get elementsMethodDeclaration getElements = myClass.addMethod("getElements", Modifier.Keyword.PUBLIC);// we specify that we are returning a Collection of StringgetElements.setType("Collection<String>");// The body consists of just a return statement. We return the// fieldgetElements.getBody().get().getStatements().add(new ReturnStmt(new NameExpr("elements")));System.out.println(compilationUnit);}
}
参考
Javaparser github
Javaparser homepage
Javaparser使用教程
Javaparser代码生成
https://github.com/ftomassetti/effectivejava.git
https://github.com/javaparser/javasymbolsolver.git
可用的demos
https://github.com/ftomassetti/analyze-java-code-examples.git