-->

How to use ASTRewrite to replace a particular Simp

2019-05-30 04:10发布

问题:

I need to preprocess some code before compiling for a java based language - Processing. In this language, all instances of type color, need to be replaced with int. For ex, here's a code snippet:

color red = 0xffaabbcc;
color[][] primary = new color[10][10];

After preprocessing, the above code should look like:

int red = 0xffaabbcc;
int[][] primary = new int[10][10];

I'm working in a non eclipse environment. I'm using Eclipse JDT ASTParser to do this. I've implemented my ASTVisitor which visits all SimpleType nodes. Here's the code snippet from the ASTVisitor implementation:

public boolean visit(SimpleType node) {
    if (node.toString().equals("color")) {
        System.out.println("ST color type detected: "
                + node.getStartPosition());
        // 1
        rewrite.replace(node,
                rewrite.getAST().newPrimitiveType(PrimitiveType.INT), null);
        // 2
        node.setStructuralProperty(SimpleType.NAME_PROPERTY, rewrite
                .getAST().newSimpleName("int")); // 2
    }
    return true;
}

Here rewrite is an instance of ASTRewrite. Line 1 has no effect(with line 2 commented out). And line 2 causes IllegalArgumentException to be thrown because newSimpleName() will not accept any java keywords like int.

Finding and replacing all instances of color with regex doesn't seem like the right way to me since it could cause unnecessary changes. But I may be wrong.

How can I achieve this? Or are there any alternate solutions or approaches I can take?

Thanks

Update Edit: Here's the snippet which performs ASTRewrite:

    CompilationUnit cu = (CompilationUnit) parser.createAST(null);
    cu.recordModifications();
    rewrite = ASTRewrite.create(cu.getAST());
    cu.accept(new XQASTVisitor());

    TextEdit edits = cu.rewrite(doc, null);
    try {
        edits.apply(doc);
    } catch (MalformedTreeException e) {
        e.printStackTrace();
    } catch (BadLocationException e) {
        e.printStackTrace();
    }

XQAstVisitor is the visitor class which contains the above visit method. There are other substitution that I'm performing that execute correctly. Only this one causes problems.

回答1:

I found your errors! This statement:

TextEdit edits = cu.rewrite(doc, null);

is not right. And should be replaced by the following statement:

TextEdit edits = rewrite.rewriteAST(doc, null);

In the end, parse the modified doc into CompilationUnit again, the changes will be applied. What's more, the statement:

node.setStructuralProperty(SimpleType.NAME_PROPERTY, rewrite.getAST().newSimpleName("int"));

is not needed.