/**
* 设置JavaParser解析配置
*/
private ParserConfiguration buildJavaParserConfig(List<String> sourcePath) {
TypeSolver reflectionTypeSolver = new ReflectionTypeSolver();
CombinedTypeSolver combinedSolver = new CombinedTypeSolver(reflectionTypeSolver);
sourcePath.forEach(path -> {
try {
TypeSolver javaParserTypeSolver = new JavaParserTypeSolver(new File(path));
combinedSolver.add(javaParserTypeSolver);
} catch (Exception e) {
log.error("load source path error, path:{}", path);
}
});
JavaSymbolSolver symbolSolver = new JavaSymbolSolver(combinedSolver);
return new ParserConfiguration().setSymbolResolver(symbolSolver);
}
/**
* 获取解析出的接口或类相关信息
*/
private void parseInterfaceOrClass(AstEntity astEntity, String projectRootPath, String path) throws FileNotFoundException {
CompilationUnit cu = StaticJavaParser.parse(new File(projectRootPath + "/" + path));
// 类型声明解析
List<ClassOrInterfaceDeclaration> classDeclarations = cu.findAll(ClassOrInterfaceDeclaration.class);
if (CollectionUtils.isEmpty(classDeclarations)) {
return;
}
// 类解析(只解析顶层类定义,其他内部类方法会归属到其下)
ClassOrInterfaceDeclaration classOrInterfaceDeclaration = classDeclarations.get(0);
ResolvedReferenceTypeDeclaration resolve = classOrInterfaceDeclaration.resolve();
AstEntity.InterfaceOrClassDeclareInfo interfaceOrClassDeclareInfo = new AstEntity.InterfaceOrClassDeclareInfo();
interfaceOrClassDeclareInfo.setClassFileRelativePath(path);
interfaceOrClassDeclareInfo.setSimpleName(classOrInterfaceDeclaration.getNameAsString());
interfaceOrClassDeclareInfo.setSignature(resolve.getQualifiedName());
interfaceOrClassDeclareInfo.setInterface(classOrInterfaceDeclaration.isInterface());
interfaceOrClassDeclareInfo.setAbstract(classOrInterfaceDeclaration.isAbstract());
NodeList<ClassOrInterfaceType> implementedTypes = classOrInterfaceDeclaration.getImplementedTypes();
// 实现接口信息
if (CollectionUtils.isNotEmpty(implementedTypes)) {
Set<String> signatures = this.getClassSignatures(implementedTypes);
interfaceOrClassDeclareInfo.setImplementInterfaceSignatures(signatures);
}
// 继承类信息
NodeList<ClassOrInterfaceType> extendedTypes = classOrInterfaceDeclaration.getExtendedTypes();
if (CollectionUtils.isNotEmpty(extendedTypes)) {
Set<String> signatures = this.getClassSignatures(extendedTypes);
interfaceOrClassDeclareInfo.setExtendClassSignatures(signatures);
}
// 声明方法解析
List<MethodDeclaration> methodDeclarations = classOrInterfaceDeclaration.findAll(MethodDeclaration.class);
if (CollectionUtils.isNotEmpty(methodDeclarations)) {
Map<String, AstEntity.MethodDeclareInfo> methodDeclareInfoMap = methodDeclarations.stream()
.map(e -> this.parseMethod(e, classOrInterfaceDeclaration.getNameAsString()))
.filter(Objects::nonNull)
.collect(Collectors.toMap(AstEntity.MethodDeclareInfo::getSignature, Function.identity(), (v1, v2) -> v1));
astEntity.getSignature2MethodDeclareMap().putAll(methodDeclareInfoMap);
// 项目入口识别(目前仅通过注解识别spring http入口,可以扩展其他的模式)
NodeList<AnnotationExpr> annotations = classOrInterfaceDeclaration.getAnnotations();
if (CollectionUtils.isNotEmpty(annotations)
&& annotations.stream().map(AnnotationExpr::getNameAsString)
.anyMatch(e -> "Controller".equals(e) || "RestController".equals(e))) {
methodDeclareInfoMap.forEach((signature, methodDeclareInfo) -> {
boolean isEndpoint = methodDeclareInfo.getAnnotationSimpleNames().stream()
.anyMatch(e -> "GetMapping".equals(e) || "PostMapping".equals(e)
|| "PutMapping".equals(e) || "DeleteMapping".equals(e) || "RequestMapping".equals(e));
if (isEndpoint) {
astEntity.getEndPointMethodSignatures().add(signature);
}
});
}
}
astEntity.getSignature2InterfaceOrClassDeclareMap().put(interfaceOrClassDeclareInfo.getSignature(), interfaceOrClassDeclareInfo);
}
/**
* 获取解析出的方法和方法调用相关信息
*/
private AstEntity.MethodDeclareInfo parseMethod(MethodDeclaration methodDeclaration, String classSimpleName) {
try {
ResolvedMethodDeclaration methodResolve = methodDeclaration.resolve();
AstEntity.MethodDeclareInfo methodDeclareInfo = new AstEntity.MethodDeclareInfo();
methodDeclareInfo.setSimpleName(methodDeclaration.getNameAsString());
methodDeclareInfo.setSignature(methodResolve.getQualifiedSignature());
methodDeclareInfo.setClassSimpleName(classSimpleName);
methodDeclareInfo.setPublic(methodDeclaration.isPublic());
// 填充方法参数信息
if (CollectionUtils.isNotEmpty(methodDeclaration.getParameters())) {
List<String> params = this.getParamSignatures(methodDeclaration);
methodDeclareInfo.setParamTypeList(params);
}
// 填充注解信息
NodeList<AnnotationExpr> annotations = methodDeclaration.getAnnotations();
if (CollectionUtils.isNotEmpty(annotations)) {
Set<String> annotationNames = annotations.stream().map(AnnotationExpr::getNameAsString).collect(Collectors.toSet());
methodDeclareInfo.setAnnotationSimpleNames(annotationNames);
}
// 填充方法调用信息
List<MethodCallExpr> methodCallExprs = methodDeclaration.getBody()
.map(e -> e.findAll(MethodCallExpr.class))
.orElse(Collections.emptyList());
if (CollectionUtils.isNotEmpty(methodCallExprs)) {
List<String> callMethodSignatures = methodCallExprs.stream().map(methodCallExpr -> {
try {
ResolvedMethodDeclaration resolve = methodCallExpr.resolve();
return resolve.getQualifiedSignature();
} catch (Throwable throwable) {
log.error("cannot resolve: {}", methodCallExpr.getNameAsString());
return null;
}
}).filter(StringUtils::isNotBlank)
.collect(Collectors.toList());
methodDeclareInfo.setCallMethodSignatures(callMethodSignatures);
}
return methodDeclareInfo;
} catch (Throwable e) {
log.error("parseMethod error! name:{}", methodDeclaration.getNameAsString());
return null;
}
}