类中文说明补充优化
All checks were successful
类变更检测 / class-change-check (push) Successful in 14s

This commit is contained in:
2026-06-08 16:31:53 +08:00
parent 90afda6c3c
commit b9242a9f2b
9 changed files with 136 additions and 12 deletions

View File

@@ -4,9 +4,16 @@ import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.TypeDeclaration;
import com.github.javaparser.ast.comments.JavadocComment;
import com.github.javaparser.ast.expr.AnnotationExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.NormalAnnotationExpr;
import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr;
import java.util.Optional;
/**
* 从 Java 源文件路径或 AST 解析类名(简单名 / 全限定名)。
* 从 Java 源文件路径或 AST 解析类名(简单名 / 全限定名)及类级中文说明
*/
public class ClassDeclParser {
@@ -60,6 +67,100 @@ public class ClassDeclParser {
return inferQualifiedFromPath(relativePath, simpleName);
}
/**
* 提取类级中文说明:@Schema(description/title) > 类 Javadoc 首段。
*/
public String extractClassDescription(String source, String expectedClassName) {
if (source == null || source.isBlank()) {
return "";
}
try {
CompilationUnit cu = StaticJavaParser.parse(source);
ClassOrInterfaceDeclaration classDecl = findClass(cu, expectedClassName);
if (classDecl == null) {
return "";
}
String fromSchema = readSchemaDescription(classDecl);
if (!fromSchema.isEmpty()) {
return fromSchema;
}
return extractClassJavadoc(classDecl);
} catch (Exception ignored) {
return "";
}
}
private ClassOrInterfaceDeclaration findClass(CompilationUnit cu, String expectedClassName) {
if (expectedClassName != null && !expectedClassName.isBlank()) {
for (TypeDeclaration<?> type : cu.getTypes()) {
if (type instanceof ClassOrInterfaceDeclaration) {
ClassOrInterfaceDeclaration classDecl = (ClassOrInterfaceDeclaration) type;
if (classDecl.getNameAsString().equals(expectedClassName)) {
return classDecl;
}
}
}
}
for (TypeDeclaration<?> type : cu.getTypes()) {
if (type instanceof ClassOrInterfaceDeclaration) {
return (ClassOrInterfaceDeclaration) type;
}
}
return null;
}
private String readSchemaDescription(ClassOrInterfaceDeclaration classDecl) {
for (AnnotationExpr annotation : classDecl.getAnnotations()) {
if (!"Schema".equals(annotation.getNameAsString())) {
continue;
}
String description = readAnnotationStringValue(annotation, "description");
if (!description.isEmpty()) {
return description;
}
String title = readAnnotationStringValue(annotation, "title");
if (!title.isEmpty()) {
return title;
}
}
return "";
}
private String readAnnotationStringValue(AnnotationExpr annotation, String attributeName) {
if (annotation.isNormalAnnotationExpr()) {
NormalAnnotationExpr normal = annotation.asNormalAnnotationExpr();
for (var pair : normal.getPairs()) {
if (pair.getNameAsString().equals(attributeName)) {
return literalString(pair.getValue());
}
}
return "";
}
if (annotation.isSingleMemberAnnotationExpr()) {
SingleMemberAnnotationExpr single = annotation.asSingleMemberAnnotationExpr();
if ("value".equals(attributeName) || "description".equals(attributeName)) {
return literalString(single.getMemberValue());
}
}
return "";
}
private String literalString(Expression expression) {
if (expression.isStringLiteralExpr()) {
return expression.asStringLiteralExpr().getValue().trim();
}
return "";
}
private String extractClassJavadoc(ClassOrInterfaceDeclaration classDecl) {
Optional<JavadocComment> javadoc = classDecl.getJavadocComment();
if (javadoc.isEmpty()) {
return "";
}
String text = javadoc.get().parse().getDescription().toText();
return text == null ? "" : text.trim().replaceAll("\\s+", " ");
}
/** 从 src/main/java/ 后的路径推断 package.className */
public static String inferQualifiedFromPath(String relativePath, String className) {
if (relativePath == null || relativePath.isBlank()) {