2016-03-07 70 views
1

我正在編寫一個轉換,以將一些額外的註釋添加到已具有特定註釋的字段。全局轉換中缺少AST類

我有以下的配置,我提供的編譯器

import groovy.transform.CompileStatic 
import groovy.transform.PackageScope 
import org.codehaus.groovy.ast.ASTNode 
import org.codehaus.groovy.ast.AnnotationNode 
import org.codehaus.groovy.ast.ClassHelper 
import org.codehaus.groovy.ast.FieldNode 
import org.codehaus.groovy.control.CompilePhase 
import org.codehaus.groovy.control.SourceUnit 
import org.codehaus.groovy.transform.AbstractASTTransformation 
import org.codehaus.groovy.transform.GroovyASTTransformation 

@CompileStatic 
@GroovyASTTransformation(phase = CompilePhase.CONVERSION) 
class InjectorTransform extends AbstractASTTransformation { 
    @Override void visit(ASTNode[] nodes, SourceUnit source) { 
    source.AST.classes*.fields.flatten().each { 
     def field = it as FieldNode 
     def found = field.annotations.find { it.classNode.name == 'javax.inject.Inject' } 

     if (found) { 
     field.addAnnotation(new AnnotationNode(ClassHelper.make(PackageScope))) 
     } 
    } 
    } 
} 

withConfig(configuration) { 
    ast(CompileStatic) 
    ast(new InjectorTransform()) 
} 

我提供這種使用groovyOptions.configurationScript

如預期,但僅source.AST.classes返回單個類的變換奔跑搖籃。這個類總是所有正在編譯的類的第一個按字母順序排列的類。例如,如果我有Bar和Foo類,它將返回Bar。如果我創建另一個名爲Alpha的類,Alpha將被返回。

我的問題是什麼可能導致轉換沒有得到所有的類?以這種方式添加全局變換是否存在問題,還是可能會阻止其他類可見的問題?

回答

1

我通過使用inline方法而不是在配置腳本中創建類來解決此問題。我不知道爲什麼原始方法不起作用,也許這是一個錯誤,但在這裏的解決方案。

import groovy.transform.CompileStatic 
import groovy.transform.PackageScope 
import org.codehaus.groovy.ast.AnnotationNode 
import org.codehaus.groovy.ast.ClassHelper 
import org.codehaus.groovy.ast.FieldNode 

import static org.codehaus.groovy.control.CompilePhase.CONVERSION 

withConfig(configuration) { 
    ast(CompileStatic) 
    inline(phase: CONVERSION) { source, context, classNode -> 
    source.AST.classes*.fields.flatten().each { 
     def field = it as FieldNode 
     def found = field.annotations.find { it.classNode.name == 'Inject' } 

     if (found) { 
     field.addAnnotation(new AnnotationNode(ClassHelper.make(PackageScope))) 
     } 
    } 
    } 
}