Eclipse AST not changing class files when changing TypeDeclaration

家住魔仙堡 提交于 2019-12-12 04:34:53

问题


I am trying to edit several Java classes with the Java AST. But my changes wont show in the Java class files.

What specifically do I want to do? I want to take an IPackageFragment and visit all the ICompilationUnits. For every declared class I want to set the super class to a specific class (using the qualified name of the super class, because it is an Xtend class). I also tried applying the edits via the Document class.

For example: A class main.model.someClass should inherit from wrappers.main.model.someClassWrapper

I am relatively new to the JDT API, so I cannot find the reason why the class files are not changed. I already checked this post, but it did not help me. I tried to stay as close as possible to the examples from How To Train the JDT Dragon other tips/examples I got from Stackoverflow. But it will not work.

This is how I do it:

private void editTypesIn(IPackageFragment myPackage) throws JavaModelException {
    for (ICompilationUnit unit : myPackage.getCompilationUnits()) {
        TypeVisitor visitor = new TypeVisitor(myPackage.getElementName(), unit);
        unit.becomeWorkingCopy(new NullProgressMonitor());
        CompilationUnit parse = parse(unit);
        parse.recordModifications();
        parse.accept(visitor);
    }
}

private static CompilationUnit parse(ICompilationUnit unit) {
    ASTParser parser = ASTParser.newParser(AST.JLS8);
    parser.setKind(ASTParser.K_COMPILATION_UNIT);
    parser.setSource(unit);
    parser.setResolveBindings(true);
    return (CompilationUnit) parser.createAST(null); // parse
}

And this is the visitor class:

public class TypeVisitor extends ASTVisitor {
    private final String currentPackage;
    private final ICompilationUnit compilationUnit;

    public TypeVisitor(String currentPackage, ICompilationUnit compilationUnit) {
        this.currentPackage = currentPackage;
        this.compilationUnit = compilationUnit;
    }

    @Override
    public boolean visit(TypeDeclaration node) {
        if (!node.isInterface()) { // is class
            setSuperClass(node, "wrappers." + currentPackage + "." + node.getName().toString() + "Wrapper");
        }
        return super.visit(node);
    }

    public void setSuperClass(TypeDeclaration declaration, String qualifiedName) {
        try {
            // create ast and rewrite:
            AST ast = declaration.getAST();
            ASTRewrite astRewrite = ASTRewrite.create(ast);
            // set super:
            Name name = ast.newName(qualifiedName);
            Type type = ast.newSimpleType(name);
            declaration.setSuperclassType(type);
            // apply changes
            TextEdit edits = astRewrite.rewriteAST();
            compilationUnit.applyTextEdit(edits, new NullProgressMonitor());
            compilationUnit.commitWorkingCopy(true, new NullProgressMonitor());
        } catch (JavaModelException exception) {
            exception.printStackTrace();
        } catch (IllegalArgumentException exception) {
            exception.printStackTrace();
        } catch (MalformedTreeException exception) {
            exception.printStackTrace();
        }
    }
}

Thanks in advance for any help!


回答1:


I guess your edits will be empty, right?

By calling CompilationUnit.recordModifications() you tell the AST to internally create an ASTRewrite into which modifications will be recorded.

By ASTRewrite.create(..) you are creating a second ASTRewrite which knows nothing of the modifications being recorded.

The only API for consuming the recorded modifications is CompilationUnit.rewrite(IDocument,Map) (see references to field AST.rewriter).

If you need to use your own ASTRewrite apply the "Descriptive approach", using, e.g., ASTRewrite.set(..).



来源:https://stackoverflow.com/questions/42279095/eclipse-ast-not-changing-class-files-when-changing-typedeclaration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!