javaparser
包含一组实现具有高级分析功能的 Java 1.0 - Java 15 Parser 的库。 这包括 Java 13 的预览功能,Java 14 预览功能正在进行中。
使用 demo工程: 从官方demo fork的工程里可以看到大部分使用示例(对应于官方指导文档里使用说明)。
示例代码:
public static void main(String[] args) throws Exception {
CompilationUnit cu = StaticJavaParser.parse(new FileInputStream(FILE_PATH));
VoidVisitor<Void> methodCallVisitor = new MethodCallPrinter();
methodCallVisitor.visit(cu, null);
}
private static class MethodCallPrinter extends VoidVisitorAdapter<Void> {
@Override
public void visit(MethodCallExpr mc, Void arg) {
super.visit(mc, arg);
Range range = mc.getRange().orElse(Range.range(-1, -1, -1, -1));
int startLine = range.begin.line;
int endLine = range.end.line;
MethodDeclaration methodDeclaration = funcCalledByMethod(mc);
ClassOrInterfaceDeclaration classDeclaration = funcCalledByClass(methodDeclaration);
System.out.printf("Method call Printed -> method %s called in %s.%s() line [%d, %d]\n",
mc.getName().getIdentifier(), classDeclaration == null ? "" : classDeclaration.getName().getIdentifier(),
methodDeclaration == null ? "" : methodDeclaration.getName().getIdentifier(), startLine, endLine);
}
执行结果:
Method call Printed -> method split called in ReversePolishNotation.calc() line [25, 25]
Method call Printed -> method pop called in ReversePolishNotation.calc() line [33, 33]
Method call Printed -> method pop called in ReversePolishNotation.calc() line [34, 34]
Method call Printed -> method push called in ReversePolishNotation.calc() line [35, 35]
Method call Printed -> method pop called in ReversePolishNotation.calc() line [38, 38]
Method call Printed -> method pop called in ReversePolishNotation.calc() line [39, 39]
Method call Printed -> method push called in ReversePolishNotation.calc() line [40, 40]
Method call Printed -> method pop called in ReversePolishNotation.calc() line [43, 43]
Method call Printed -> method pop called in ReversePolishNotation.calc() line [44, 44]
Method call Printed -> method push called in ReversePolishNotation.calc() line [45, 45]
Method call Printed -> method pop called in ReversePolishNotation.calc() line [48, 48]
Method call Printed -> method pop called in ReversePolishNotation.calc() line [49, 49]
Method call Printed -> method push called in ReversePolishNotation.calc() line [50, 50]
Method call Printed -> method valueOf called in ReversePolishNotation.calc() line [53, 53]
Method call Printed -> method push called in ReversePolishNotation.calc() line [53, 53]
Method call Printed -> method of called in ReversePolishNotation.calc() line [28, 28]
Method call Printed -> method forEach called in ReversePolishNotation.calc() line [28, 55]
Method call Printed -> method pop called in ReversePolishNotation.calc() line [56, 56]
/**
* 查找节点在哪个函数里调用
*
* @param node 节点
* @return 函数声明
*/
private MethodDeclaration funcCalledByMethod(@Nullable Node node) {
if (node == null) {
return null;
}
Node parentNode = node.getParentNode().get();
if (parentNode instanceof MethodDeclaration) {
return (MethodDeclaration) parentNode;
} else {
return funcCalledByMethod(parentNode);
}
}
/**
* 查找节点在哪个类或接口里
*
* @param node 节点
* @return 类或接口声明
*/
private ClassOrInterfaceDeclaration funcCalledByClass(@Nullable Node node) {
if (node == null) {
return null;
}
Node parentNode = node.getParentNode().get();
if (parentNode instanceof ClassOrInterfaceDeclaration) {
return (ClassOrInterfaceDeclaration) parentNode;
} else {
return funcCalledByClass(parentNode);
}
}
https://github.com/javaparser/javaparser