Search code examples
javajavaparser

How to add a line comment just after a method with JavaParser


What I want to do

I am trying to add a single-line comments around a method annotated with @lombok.Generated to tell Parasoft Jtest to suppress the reporting of findings in the method like this:

// parasoft-begin-suppress ALL
@lombok.Generated
void generatedMethod() {
}
// parasoft-end-suppress ALL

What I tried

To add these comments, I wrote a Java program that adds comments to Java sources with JavaParser. I have successfully added the comment before the annotation with this code based on the JavaParser sample project :

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);
}

Problem

I couldn't add the comment after the method with childNodeList.add(new LineComment("// parasoft-end-suppress ALL"));. The Javadoc of Node#getChildNodes says You can add and remove nodes from this list by adding or removing nodes from the fields of this node., but I got UnsupportedOperationException when I call childNodeList.add().

Question

How can I add a line comment just after a method with JavaParser?


Solution

  • Instead of adding a single-line comment just after a method, I added a comment at the last line of the method with this code:

    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.getNameAsString().equals("Generated")) {
                                ann.setLineComment("parasoft-begin-suppress ALL");
                                List<Node> childNodeList = n.getChildNodes();
                                // The last child node will be "{ ~ }"
                                Node lastChildNode = childNodeList.get(childNodeList.size() - 1);
                                // This line comment will be inserted at the last line of the method
                                lastChildNode.addOrphanComment(new LineComment("parasoft-end-suppress ALL"));
                            }
                        }
                        return super.visit(n, arg);
                    }
                }, null);
            });
        }
    
        Path outPath = Paths.get("/path/to/output/source");
        sourceRoot.saveAll(outPath);
    }
    

    With this code and the following source,

    @lombok.Generated
    void generatedMethod() {
        System.out.println("DUMMY");
    }
    

    I got the following result (Parasoft Jtest will ignore all statements in this method):

    // parasoft-begin-suppress ALL
    @lombok.Generated
    void generatedMethod() {
        System.out.println("DUMMY");
        // parasoft-end-suppress ALL
    }