更改 TypeDeclaration 时 Eclipse AST 不更改 class 文件

Eclipse AST not changing class files when changing TypeDeclaration

我正在尝试使用 Java AST 编辑几个 Java classes。但是我的更改不会显示在 Java class 文件中。

我具体想做什么?我想要 IPackageFragment 并访问所有 ICompilationUnit。对于每个声明的 class,我想将超级 class 设置为特定的 class(使用超级 class、 的限定名称)。我还尝试通过 Document class.

应用编辑

例如:一个classmain.model.someClass应该继承自wrappers.main.model.someClassWrapper

我对 JDT API 比较陌生,所以我找不到 class 文件未更改的原因。我已经检查了 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 其他 tips/examples 我从 Whosebug 得到的。但是不行。

我是这样做的:

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
}

这是访客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();
        }
    }
}

在此先感谢您的帮助!

我猜你的编辑会是空的,对吧?

通过调用 CompilationUnit.recordModifications(),您告诉 AST 在内部创建一个 ASTRewrite,其中将记录修改。

通过 ASTRewrite.create(..),您正在创建一个 second ASTRewrite,它对正在记录的修改一无所知。

使用记录修改的唯一 API 是 CompilationUnit.rewrite(IDocument,Map)(参见字段 AST.rewriter 的引用)。

如果您需要使用自己的 ASTRewrite,请应用 "Descriptive approach",例如,使用 ASTRewrite.set(..)