Search code examples
javaeclipseclasssignatureeclipse-jdt

Modifying the signature of a type


I am trying to programmatically change the signature of a type, to be precise I want to let a class implement an interface or to add implements SomeInterface to its signature in other words.

I get an object for the type as follows:

IType ejbType = jproject.findType(ejbClass);

Then I would expect ITypeto have a method like setSuperInterfaceNames(String[]) but there is only a method getSuperInterfaceNames().

Is there any possibility to satisfy my requirement with jdt?


Solution

  • You can use Eclipse AST to modify the code. Roughly, the steps are:

    1) Parse the source file [CompilationUnit unit = parseAst(ejbType.getCompilationUnit())]

    public static CompilationUnit parseAst(ICompilationUnit unit, SubMonitor progress) {
        ASTParser parser = ASTParser.newParser(AST.JLS8);
        parser.setSource(unit);
        parser.setResolveBindings(true);
        return (CompilationUnit)parser.createAST(progress);
    }
    

    2) Find the Type you want to modify in your CompilationUnit, by using the visitor pattern:

    unit.accept(new ASTVisitor() {
        @Override
        public boolean visit(TypeDeclaration node) {
            IType type = (IType) node.resolveBinding().getTypeDeclaration().getJavaElement();
            if (ejbType.equals(type)) {
                modifyTypeDeclaration(node);
            }
            return false;
        }
    });
    

    3) Implement modifyTypeDeclaration(TypeDeclaration node).

    I usualy use ASTRewrite to collect all changes to a compilation unit (*.java file), bevor writing it back, which looks something like this.

    ICompilationUnit cu = ejbType.getCompilationUnit();
    cu.becomeWorkingCopy(...);
    CompilationUnit unit = parseAst(ejbType.getCompilationUnit())
    final ASTRewrite rewrite = ASTRewrite.create(unit.getAST());
    collectChangesToUnit(unit, rewrite);
    cu.applyTextEdit(rewrite.rewriteAST(), ...);
    cu.commitWorkingCopy(false, ...);
    

    If your case is realy simple you could also modify the TypeDeclaration directly.