2017-02-16 3 views
0

Я пытаюсь редактировать несколько классов Java с помощью Java AST. Но мои изменения не будут отображаться в файлах классов Java.Eclipse AST не меняет файлы классов при смене TypeDeclaration

Что конкретно я хочу делать? Я хочу взять IPackageFragment и посетить все ICompilationUnit s. Для каждого объявленного класса я хочу установить суперкласс для определенного класса (используя квалифицированное имя суперкласса because it is an Xtend class). Я также попытался применить изменения с помощью класса Document.

Например: Класс main.model.someClass должен наследовать от wrappers.main.model.someClassWrapper

Я относительно новым для API JDT, поэтому я не могу найти причину, почему файлы классов не изменились. Я уже проверил this post, но это мне не помогло. Я попытался как можно ближе остановиться на примерах из How To Train the JDT Dragon других советов/примеров, которые я получил от Stackoverflow. Но это не сработает.

Это, как я это делаю:

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 
} 

И это класс посетитель:

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(); 
     } 
    } 
} 

Заранее спасибо за любую помощь!

ответ

1

Я предполагаю, что ваши правки будут пустыми, не так ли?

По телефону CompilationUnit.recordModifications() вы сообщаете AST, чтобы создать ASTRewrite, в который будут внесены изменения.

От ASTRewrite.create(..) Вы создаёте второйASTRewrite, который ничего не знает о записываемых модификациях.

Единственный API для использования записанных изменений - CompilationUnit.rewrite(IDocument,Map) (см. Ссылки на поле AST.rewriter).

Если вам нужно использовать свой собственный ASTRewrite, примените «Описательный подход», используя, например, ASTRewrite.set(..).

+0

Спасибо, что обратились за помощью. – ConveniencePatterns

Смежные вопросы