3

我有一個的IFile具有以下內容:附加註釋到類JDT

package com.example; 
//@SimpleAnnotation(Blab.ckass) 
//@CustomAnnotation(arg1 = Blup.class , arg2 = Blup.Row.class) 
public class SimpleClassWithAnnotation { 

} 

我如何可以添加註釋(註釋的一個)的類?我試過使用this線程的解決方案,但源碼不變。這裏是代碼片段,我用:

final ASTParser parser = ASTParser.newParser(AST.JLS3); 
    parser.setSource(this.cu); 
    ICompilationUnit cu = JavaCore.createCompilationUnitFrom(this.ifile); 
    final CompilationUnit astRoot = (CompilationUnit) parser.createAST(null); 
    final AST ast = astRoot.getAST(); 
    astRoot.recordModifications(); 
    final NormalAnnotation newNormalAnnotation = astRoot.getAST().newNormalAnnotation(); 
    newNormalAnnotation.setTypeName(astRoot.getAST().newName("AnnotationTest")); 

這是一個嘗試添加一個簡單的註解@AnnotationTest。不過,我需要這樣的事情:@CustomAnnotation(arg1 = Blup.class , arg2 = Blup.Row.class)

在此先感謝!

回答

6

經過很多嘗試,我得到了解決方案。問題就像Unni Kris提到的那樣,我必須使用ASTRewriter來操縱AST樹。另一個問題是如何將更改保存迴文件。我找到了一個解決方案,我不確定這個解決方案100%正確,但至少對我有用。

private void addAnnotations(final ICompilationUnit cu) throws MalformedTreeException, BadLocationException, CoreException { 

    // parse compilation unit 
    final ASTParser parser = ASTParser.newParser(AST.JLS3); 
    parser.setSource(cu); 
    final CompilationUnit astRoot = (CompilationUnit) parser.createAST(null); 


    // create a ASTRewrite 
    final AST ast = astRoot.getAST(); 
    final ASTRewrite rewriter = ASTRewrite.create(ast); 



    final ListRewrite listRewrite = rewriter.getListRewrite(astRoot, CompilationUnit.TYPES_PROPERTY); 
    final NormalAnnotation eventHandlerAnnotation = astRoot.getAST().newNormalAnnotation(); 
    eventHandlerAnnotation.setTypeName(astRoot.getAST().newName("CustomAnnotation")); 
    eventHandlerAnnotation.values().add(createAnnotationMember(ast, "arg1", "Blup")); 
    eventHandlerAnnotation.values().add(createQualifiedAnnotationMember(ast, "arg2", "IsWorkbenchTest", "Blab")); 


    final SingleMemberAnnotation runWithFop = astRoot.getAST().newSingleMemberAnnotation(); 
    runWithFop.setTypeName(astRoot.getAST().newName("SimpleAnnotation")); 
    final TypeLiteral newTypeLiteral = astRoot.getAST().newTypeLiteral(); 
    newTypeLiteral.setType(astRoot.getAST().newSimpleType(astRoot.getAST().newSimpleName("Blop"))); 
    runWithFop.setValue(newTypeLiteral); 
    listRewrite.insertAt(runWithFop, 0, null); 
    listRewrite.insertAt(eventHandlerAnnotation, 0, null); 
    final TextEdit edits = rewriter.rewriteAST(); 

    // apply the text edits to the compilation unit 
    final Document document = new Document(cu.getSource()); 
    edits.apply(document); 

    // this is the code for adding statements 
    cu.getBuffer().setContents(formatFileContent(document.get())); 
    cu.save(null, true); 
} 
protected MemberValuePair createQualifiedAnnotationMember(final AST ast, final String name, final String value, final String value2) { 
    final MemberValuePair mV = ast.newMemberValuePair(); 
    mV.setName(ast.newSimpleName(name)); 
    final TypeLiteral typeLiteral = ast.newTypeLiteral(); 
    final QualifiedType newQualifiedName = ast.newQualifiedType(ast.newSimpleType(ast.newSimpleName(value)), ast.newSimpleName(value2)); 
    typeLiteral.setType(newQualifiedName); 
    mV.setValue(typeLiteral); 
    return mV; 
} 

protected MemberValuePair createAnnotationMember(final AST ast, final String name, final String value) { 

    final MemberValuePair mV = ast.newMemberValuePair(); 
    mV.setName(ast.newSimpleName(name)); 
    final TypeLiteral typeLiteral = ast.newTypeLiteral(); 
    typeLiteral.setType(ast.newSimpleType(ast.newSimpleName(value))); 
    mV.setValue(typeLiteral); 
    return mV; 
} 

我還發現一個插件顯示Eclipse的Java文件的AST結構(ASTView)。這幫助我弄清楚瞭如何創建註釋結構。只需創建一個具有所需結構的java文件並查看AST Structure的外觀。這裏是例子:

Eclipse Screenshot

1

所做的修改僅適用於AST,並未記錄到Java源代碼文件中。

檢查下面的鏈接。這提供了關於如何將AST更改寫入文件的見解。

http://www.eclipse.org/articles/article.php?file=Article-JavaCodeManipulation_AST/index.html

更新:

您可以添加註釋值,像象下面這樣:

MemberValuePair mV = astRoot.getAST().newMemberValuePair(); 
mV.setName(astRoot.getAST().newSimpleName("name")); 
TypeLiteral typeLiteral = astRoot.getAST().newTypeLiteral(); 
typeLiteral.setType(astRoot.getAST().newSimpleType(astRoot.getAST().newSimpleName("Blup"))); 
mV.setValue(typeLiteral); 
newNormalAnnotation.values().add(mV); 

您可以將NormalAnnotation然後添加到類的修飾語清單。

+0

我已閱讀,我看到了,我必須以某種方式保存到文件回來。我不確定如何將Annotation附加到類標題。 – aphex

+0

更新了答案...與你的查詢 –

+0

謝謝,我想我有想法 – aphex

1

使用您的解決方案:

final ListRewrite listRewrite = rewriter.getListRewrite(astRoot, CompilationUnit.TYPES_PROPERTY); 

我得到註釋和類之間的一個空行。所以我試圖添加註釋作爲修飾符,它似乎工作得很好。下面是一個例子,如何做到這一點:

final MarkerAnnotation javaTaskInfoA = ast.newMarkerAnnotation(); 
javaTaskInfoA.setTypeName(ast.newSimpleName(JavaTaskInfo.class.getSimpleName())); 
acu.accept(new ASTVisitor() { public boolean visit(TypeDeclaration node) { 
    rewriter.getListRewrite(node, node.getModifiersProperty()).insertAt(javaTaskInfoA, 0, null); 
    return false; 
}}); 

馬立克