You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用OpenRewrite在方法后添加单行注释?

需求

为带有Lombok @Generated注解的方法添加Parasoft Jtest抑制检测的单行注释,目标代码如下:

class FooBar {
    // parasoft-begin-suppress ALL
    @Generated
    public String hello() {
        return "Hello from com.yourorg.FooBar!";
    }
    //parasoft-end-suppress ALL
}
已完成的尝试

发现JavaParser会拆分行尾单行注释,因此采用OpenRewrite规则,已成功在注解前添加注释,代码如下:

public class JtestSuppressDelombokVisitor extends JavaIsoVisitor<ExecutionContext> {
    @Override
    public MethodDeclaration visitMethodDeclaration(MethodDeclaration methodDecl, ExecutionContext context) {
        boolean hasGeneratedAnnotation = methodDecl.getLeadingAnnotations().stream()
                .anyMatch(annotation -> annotation.getType().toString().equals("lombok.Generated"));

        Iterator<Comment> it = methodDecl.getPrefix().getComments().iterator();
        boolean alreadyHasSuppressComment = false;
        while (it.hasNext()) {
            Comment comment = it.next();
            PrintOutputCapture<String> p = new PrintOutputCapture<String>("");
            comment.printComment(this.getCursor(), p);
            if (p.out.toString().matches(".*parasoft-begin-suppress\\sALL.*")) {
                alreadyHasSuppressComment = true;
                break;
            }
        }

        if (hasGeneratedAnnotation && !alreadyHasSuppressComment) {
            String methodDeclWhitespace = methodDecl.getPrefix().getWhitespace();
            if (methodDecl.getPrefix().getComments().size() == 0) {
                methodDecl = methodDecl.withComments(Arrays.asList(new TextComment(false, "parasoft-begin-suppress ALL", methodDeclWhitespace, Markers.EMPTY)));
            } else {
                methodDecl.getPrefix().getComments().add(new TextComment(false, "parasoft-begin-suppress ALL", methodDeclWhitespace, Markers.EMPTY));
            }
            return methodDecl;
        }

        return methodDecl;
    }
}
遇到的问题

无法在方法后添加//parasoft-end-suppress ALL注释,尝试三种方式均失败:

  1. 使用JavaTemplate添加注释:代码执行后无任何内容添加
final JavaTemplate endSuppressCommentTemplate =
        JavaTemplate.builder(this::getCursor, "// parasoft-end-suppress ALL").build();
methodDecl = methodDecl.withBody(methodDecl.getBody().withTemplate(
        endSuppressCommentTemplate,
        methodDecl.getBody().getCoordinates().lastStatement()
        ));
  1. 在方法体末尾添加注释:注释被添加到方法最后一行内,且重复出现在多行,还覆盖了注解前的注释
methodDecl.getBody().getEnd().getComments().add(new TextComment(false, "parasoft-end-suppress ALL", "\n", Markers.EMPTY));

生成的错误代码:

class FooBar {
    //parasoft-end-suppress ALL
@Generated
    //parasoft-end-suppress ALL
public String hello() {
        return "Hello from com.yourorg.FooBar!";
    //parasoft-end-suppress ALL
}
  1. 创建Space实例添加注释:结果与方式2完全相同
Space currentSpace = methodDecl.getBody().getEnd();
Space newSpace = Space.build(currentSpace.getWhitespace(), currentSpace.getComments());
newSpace.getComments().add(new TextComment(false, "parasoft-end-suppress ALL", "\n", Markers.EMPTY));
methodDecl = methodDecl.withBody(methodDecl.getBody().withEnd(newSpace));
问题

如何通过OpenRewrite规则在方法后(或方法结尾处)添加单行注释?


解决方法

要在方法后添加注释,需要操作方法声明的**后缀(Suffix)**而非方法体的内容。方法体的getEnd()指向的是方法体内部的结尾,而方法声明本身的后缀才是方法闭合大括号之后的区域。

修改你的visitMethodDeclaration方法,在添加开头注释的逻辑后,加入以下代码来添加结尾注释:

// 检查是否已存在结尾抑制注释
boolean hasEndSuppress = methodDecl.getSuffix().getComments().stream()
    .anyMatch(comment -> {
        PrintOutputCapture<String> p = new PrintOutputCapture<>("");
        comment.printComment(getCursor(), p);
        return p.out.toString().contains("parasoft-end-suppress ALL");
    });

if (hasGeneratedAnnotation && !hasEndSuppress) {
    // 获取方法后缀的现有空白符,保持格式一致
    String suffixWhitespace = methodDecl.getSuffix().getWhitespace();
    // 创建结尾注释
    TextComment endComment = new TextComment(false, "parasoft-end-suppress ALL", suffixWhitespace.isEmpty() ? "\n    " : suffixWhitespace, Markers.EMPTY);
    // 构建新的后缀,添加注释
    Space newSuffix = Space.build(suffixWhitespace, new ArrayList<>(methodDecl.getSuffix().getComments()));
    newSuffix.getComments().add(endComment);
    // 更新方法声明的后缀
    methodDecl = methodDecl.withSuffix(newSuffix);
}

关键说明:

  • 方法的Suffix:methodDecl.getSuffix()对应方法闭合大括号之后的空白和注释区域,这才是我们需要添加结尾注释的位置。
  • 避免重复添加:先检查后缀中是否已存在目标注释,防止重复操作。
  • 格式对齐:根据现有空白符调整注释的缩进,保持代码格式一致。

完整的修改后代码:

public class JtestSuppressDelombokVisitor extends JavaIsoVisitor<ExecutionContext> {
    @Override
    public MethodDeclaration visitMethodDeclaration(MethodDeclaration methodDecl, ExecutionContext context) {
        boolean hasGeneratedAnnotation = methodDecl.getLeadingAnnotations().stream()
                .anyMatch(annotation -> annotation.getType().toString().equals("lombok.Generated"));

        // 检查是否已存在开头抑制注释
        boolean alreadyHasSuppressComment = methodDecl.getPrefix().getComments().stream()
                .anyMatch(comment -> {
                    PrintOutputCapture<String> p = new PrintOutputCapture<>("");
                    comment.printComment(getCursor(), p);
                    return p.out.toString().matches(".*parasoft-begin-suppress\\sALL.*");
                });

        // 添加开头注释
        if (hasGeneratedAnnotation && !alreadyHasSuppressComment) {
            String methodDeclWhitespace = methodDecl.getPrefix().getWhitespace();
            TextComment beginComment = new TextComment(false, "parasoft-begin-suppress ALL", 
                    methodDeclWhitespace.isEmpty() ? "\n    " : methodDeclWhitespace, Markers.EMPTY);
            if (methodDecl.getPrefix().getComments().isEmpty()) {
                methodDecl = methodDecl.withComments(Collections.singletonList(beginComment));
            } else {
                methodDecl.getPrefix().getComments().add(beginComment);
            }
        }

        // 检查是否已存在结尾抑制注释
        boolean hasEndSuppress = methodDecl.getSuffix().getComments().stream()
                .anyMatch(comment -> {
                    PrintOutputCapture<String> p = new PrintOutputCapture<>("");
                    comment.printComment(getCursor(), p);
                    return p.out.toString().contains("parasoft-end-suppress ALL");
                });

        // 添加结尾注释
        if (hasGeneratedAnnotation && !hasEndSuppress) {
            String suffixWhitespace = methodDecl.getSuffix().getWhitespace();
            TextComment endComment = new TextComment(false, "parasoft-end-suppress ALL", 
                    suffixWhitespace.isEmpty() ? "\n    " : suffixWhitespace, Markers.EMPTY);
            List<Comment> suffixComments = new ArrayList<>(methodDecl.getSuffix().getComments());
            suffixComments.add(endComment);
            Space newSuffix = Space.build(suffixWhitespace, suffixComments);
            methodDecl = methodDecl.withSuffix(newSuffix);
        }

        return methodDecl;
    }
}

这段代码会正确生成你需要的目标格式:在@Generated注解上方添加开头抑制注释,在方法闭合大括号下方添加结尾抑制注释,同时避免重复添加和格式混乱。


内容的提问来源于stack exchange,提问作者SATO Yusuke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 19:40:57