利用Java-parser进行Java抽象语法树分析

JavaParser

https://github.com/javaparser/javaparser
JavaPaser是Github上的一个开源项目,提供了简单清晰的API,对Java1.0至Java15进行抽象语法树分析。
在有了AST之后,便可以基于此进行语法检查,代码风格检查,格式化,高亮,自动补全,错误提示,代码混淆,压缩,代码变更等等操作。

JavaParser提供了一系列类、API来表达Java抽象语法树:

  • 类 com.github.javaparser.JavaParser - 提供来一套API从源码生成AST
  • 类 com.github.javaparser.StaticJavaParser - 提供静态方法快速从源码生成AST
  • 类 com.github.javaparser.ast.CompilationUnit - 语法树的节点单元,每个java文件都会产出一个CompilationUnit。CompilationUnit中从一个可选的包声明开始(package),接下来是导入声明(import),然后是类型声明(属性)。

接下来看一个简单代码片段,从一个source jar中生成AST,并找出所有方法抛出的异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public static void main(String[] args) {
String sourceJarPath = "x x x x x";
final ParserConfiguration parserConfiguration = new ParserConfiguration();
parserConfiguration.setDetectOriginalLineSeparator(true);
parserConfiguration.setLexicalPreservationEnabled(true);
parserConfiguration.setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_8);
final JavaParser javaParser = new JavaParser(parserConfiguration);
try {
final ParseResult<CompilationUnit> result = javaParser.parse(Paths.get(sourceJarPath).normalize());
if (result == null ||! result.isSuccessful() ||! result.getResult().isPresent()) {
return;
}
final CompilationUnit compilationUnit = result.getResult().get();
LexicalPreservingPrinter.setup(compilationUnit);

compilationUnit.findAll(ClassOrInterfaceDeclaration.class).parallelStream()
.peek(clz->{System.out.println("类"+clz.getFullyQualifiedName().orElse(null));})
.flatMap(clz->clz.getMethods().stream())
.filter(m->m.getThrownExceptions()!=null&&!m.getThrownExceptions().isEmpty())
.forEach(method->{
System.out.println("方法: "+method.getDeclarationAsString());
System.out.println("抛出异常: "+method.getThrownExceptions().stream().map(ReferenceType::toDescriptor).collect(Collectors.joining(", ")));
});
} catch (Exception e) {
e.printStackTrace();
}
}
Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码

请我喝杯咖啡吧

微信