如何在同一个AST上管理多个修改

时间:2014-03-16 14:48:43

标签: abstract-syntax-tree eclipse-jdt

我需要访问一个类中的每个方法声明,以便为这个类中的方法添加一些注释。

    void parseMethodDeclaration() {

        ICompilationUnit unit = getCompilationUnitByName(unitName);
        ASTParser parser = ASTParser.newParser(AST.JLS4);
        parser.setKind(ASTParser.K_COMPILATION_UNIT);
        parser.setSource(unit);
        parser.setResolveBindings(true);

        CompilationUnit parse = (CompilationUnit) parser.createAST(null);

         parse.accept(new ASTVisitor() {

            @Override
            public boolean visit(MethodDeclaration node) {

            String unitName = node.resolveBinding().getDeclaringClass().getName();

            // .. if some conditions are satisfied
            addComment(unitName, node);

            return super.visit(node);
        }
    });
}

addComment 方法定义如下,以便为给定方法添加注释:

void addComment(String unitName, MethodDeclaration method){

    ICompilationUnit unit = getCompilationUnitByName(unitName);
    AST ast = method.getAST();
    ASTRewrite rewriter = ASTRewrite.create(ast);
    ListRewrite listRewrite = rewriter.getListRewrite(method.getBody(), 
        Block.STATEMENTS_PROPERTY);

    Statement placeHolder = (Statement)rewriter.createStringPlaceholder("//MyComment",
        ASTNode.EMPTY_STATEMENT);

    listRewrite.insertFirst(placeHolder, null);

    TextEdit edits = rewriter.rewriteAST();
    Document document = new Document(unit.getSource());
    edits.apply(document);
    unit.getBuffer().setContents(document.get());
}

此代码适用于向第一个访问过的方法添加注释,但它不会在其他方法的正确位置应用注释。问题源于这样一个事实:我使用原始AST访问每个方法,而在将注释添加到第一个方法后,其相应的源代码(单元)将被更改。然后, listRewrite.insertFirst(placeHolder,null)会将评论放在错误的位置。

如何解决此问题。是否还有更新原始AST

1 个答案:

答案 0 :(得分:2)

最后,我通过研究不同的开源项目找到了答案。不幸的是,网上的大多数例子都是处理简单的情况,他们会立即应用一系列更改。

如果您需要访问单元的不同实体,并相应地更改该单元的不同位置,您唯一需要的是为整个单元保留相同的ASTRewrite实例。换句话说,ASTRewrite的创建,重写和应用,对于每个CompilationUnit,只应

对于每个Method声明,我们分解了addComment方法:

    ListRewrite listRewrite = rewriter.getListRewrite(method.getBody(), 
        Block.STATEMENTS_PROPERTY);
    Statement placeHolder = (Statement)rewriter.createStringPlaceholder("//MyComment",
        ASTNode.EMPTY_STATEMENT);
    listRewrite.insertFirst(placeHolder, null);

最后,每当访问整个单元时,我们都应该应用一次更改:

    TextEdit edits = rewriter.rewriteAST();
    Document document = new Document(unit.getSource());
    edits.apply(document);
    unit.getBuffer().setContents(document.get());

感谢开源社区:)