全局变换中缺少AST类

时间:2016-03-07 01:19:12

标签: gradle groovy

我正在编写一个转换,为已经有特定注释的字段添加一些额外的注释。

我有以下配置,我提供给编译器

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

将其提供给gradle

转换按预期运行,但source.AST.classes仅返回单个类。该类始终是正在编译的所有类的第一个字母表类。例如,如果我有Bar和Foo类,它将返回Bar。如果我创建另一个名为Alpha的类,将返回Alpha。

我的问题是什么可能导致转换不能获得所有类?是否存在以这种方式添加全局变换的问题,或者可能阻止其他类可见的问题?

1 个答案:

答案 0 :(得分:1)

我使用inline方法解决了这个问题,而不是在config脚本中创建一个类。我不确定为什么原始方法不起作用,也许这是一个错误,但这里是解决方案。

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