Search code examples
javaeclipse-jdtabstract-syntax-tree

JDT: Missing semicolon when replacing a MethodInvocation with another


I'm trying to use Eclipse JDT's AST model to replace one MethodInvocation with another. To take a trivial example - I'm trying to replace all calls to Log.(i/e/d/w) with calls to System.out.println(). I'm using an ASTVisitor to locate the interesting ASTNode and replace it with the new MethodInvocation node. Here's an outline of the code:

class StatementVisitor extends ASTVisitor {

    @Override
    public boolean visit(ExpressionStatement node) {

        // If node is a MethodInvocation statement and method
        // name is i/e/d/w while class name is Log

        // Code omitted for brevity

        AST ast = node.getAST();
        MethodInvocation newMethodInvocation = ast.newMethodInvocation();
        if (newMethodInvocation != null) {
            newMethodInvocation.setExpression(
                ast.newQualifiedName(
                    ast.newSimpleName("System"), 
                    ast.newSimpleName("out")));
            newMethodInvocation.setName(ast.newSimpleName("println"));

            // Copy the params over to the new MethodInvocation object
            mASTRewrite.replace(node, newMethodInvocation, null);
        }
    }
}

This rewrite is then saved back to the original document. This whole thing is working fine, but for one small problem - the original statement:

Log.i("Hello There");

changes to:

System.out.println("Hello There")

NOTE: Semicolon at the end of the statement is missing

QUESTION: How do I insert the semicolon at the end of the new statement?


Solution

  • Found the answer. The trick is to wrap the newMethodInvocation object in an object of type ExpressionStatement like so:

    ExpressionStatement statement = ast.newExpressionStatement(newMethodInvocation);
    mASTRewrite.replace(node, statement, null);
    

    Essentially, replace the last line in my code sample with the above two lines.