如何使用JavaParser在@lombok.Generated注解方法后添加单行注释?
如何用JavaParser为带@lombok.Generated注解的方法添加后行注释?
问题场景
需要为带有@lombok.Generated注解的方法添加Parasoft Jtest抑制检测的单行注释,预期效果如下:
// parasoft-begin-suppress ALL @lombok.Generated void generatedMethod() { } // parasoft-end-suppress ALL
已通过JavaParser成功在注解前添加起始注释,但尝试通过childNodeList.add(new LineComment("// parasoft-end-suppress ALL"));在方法后添加结束注释时,抛出UnsupportedOperationException异常,尽管Node#getChildNodes的Javadoc说明该列表支持添加节点。
现有实现代码
public static void main(String[] args) throws IOException { Log.setAdapter(new Log.StandardOutStandardErrorAdapter()); Path inPath = Paths.get("/path/to/input/source"); SourceRoot sourceRoot = new SourceRoot(inPath); List<ParseResult<CompilationUnit>> p = sourceRoot.tryToParseParallelized(); Iterator<ParseResult<CompilationUnit>> it = p.iterator(); while (it.hasNext()) { ParseResult<CompilationUnit> pr = it.next(); pr.getResult().ifPresent(cu -> { cu.accept(new ModifierVisitor<Void>() { @Override public Visitable visit(MethodDeclaration n, Void arg) { List<MarkerAnnotationExpr> list = n.findAll(MarkerAnnotationExpr.class); Iterator<MarkerAnnotationExpr> it = list.iterator(); while (it.hasNext()) { MarkerAnnotationExpr ann = it.next(); if (ann.getNameAsString().equals("lombok.Generated")) { ann.setLineComment("// parasoft-begin-suppress ALL"); List<Node> childNodeList = n.getChildNodes(); // childNodeList.add(new LineComment("// parasoft-end-suppress ALL")); } } return super.visit(n, arg); } }, null); }); } Path outPath = Paths.get("/path/to/output/source"); sourceRoot.saveAll(outPath); }
问题原因
Node#getChildNodes()返回的列表虽然文档标注支持添加节点,但对于MethodDeclaration这类结构固定的节点,其直接子节点仅包含修饰符、注解、方法签名、方法体等核心元素,不能直接插入注释节点。注释在JavaParser中属于节点的附属元素,而非直接子节点,需要通过专门的API操作。
解决方案
使用MethodDeclaration提供的setTrailingComment()方法,直接设置方法的尾随注释,该方法会自动处理注释的位置和格式,避免操作子节点的异常。修正后的代码如下:
public static void main(String[] args) throws IOException { Log.setAdapter(new Log.StandardOutStandardErrorAdapter()); Path inPath = Paths.get("/path/to/input/source"); SourceRoot sourceRoot = new SourceRoot(inPath); List<ParseResult<CompilationUnit>> p = sourceRoot.tryToParseParallelized(); Iterator<ParseResult<CompilationUnit>> it = p.iterator(); while (it.hasNext()) { ParseResult<CompilationUnit> pr = it.next(); pr.getResult().ifPresent(cu -> { cu.accept(new ModifierVisitor<Void>() { @Override public Visitable visit(MethodDeclaration n, Void arg) { List<MarkerAnnotationExpr> list = n.findAll(MarkerAnnotationExpr.class); for (MarkerAnnotationExpr ann : list) { if (ann.getNameAsString().equals("lombok.Generated")) { // 添加注解前的起始注释 ann.setLineComment("// parasoft-begin-suppress ALL"); // 添加方法后的结束注释 LineComment endComment = new LineComment("// parasoft-end-suppress ALL"); n.setTrailingComment(endComment); } } return super.visit(n, arg); } }, null); }); } Path outPath = Paths.get("/path/to/output/source"); sourceRoot.saveAll(outPath); }
补充说明
setTrailingComment()是JavaParser为节点设计的专用方法,会自动将注释放置在节点结束位置,无需手动处理行号或位置。- 如果需要更精细的格式控制(比如注释与方法体之间留空行),可以通过
endComment.setPosition()手动指定位置,但默认逻辑已能满足大部分场景需求。 - 改用增强for循环遍历注解,代码更简洁;同时保留
super.visit(n, arg)确保后续节点的遍历逻辑正常执行。
内容的提问来源于stack exchange,提问作者SATO Yusuke
相关产品推荐
相关产品推荐

