关于全局转换的事情是,转换代码应该在编译开始时可用。我首先要做的就是将变压器放在罐子里!但正如你所说,这是一项草率的工作。
你想要做的是让你的 ast 转换类在其他人进入编译阶段之前编译。这就是你要做的!
准备变压器
创建一个名为的目录precompiled
in src
文件夹!并以正确的打包结构在此目录中添加 Transformation 类和转换器使用的类(例如注释)。
然后创建一个名为org.codehaus.groovy.transform.ASTTransformation
在被称为precompiled/META-INF/services
你将拥有以下结构。
precompiled
--amanu
----LoggingASTTransformation.groovy
--META-INF
----services
------org.codehaus.groovy.transform.ASTTransformation
然后在变压器的完全限定名称中写入org.codehaus.groovy.transform.ASTTransformation
文件,对于上面的示例,完全限定名称将是amanu.LoggingASTTransformation
执行
package amanu
import org.codehaus.groovy.transform.GroovyASTTransformation
import org.codehaus.groovy.transform.ASTTransformation
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.control.SourceUnit
@GroovyASTTransformation(phase=CompilePhase.CANONICALIZATION)
class TeamDomainASTTransformation implements ASTTransformation{
public void visit(ASTNode[] nodes, SourceUnit sourceUnit) {
println ("*********************** VISIT ************")
source.getAST()?.getClasses()?.each { classNode ->
//Class node is a class that is contained in the file being compiled
classNode.addProperty("filed", ClassNode.ACC_PUBLIC, new ClassNode(Class.forName("java.lang.String")), null, null, null)
}
}
}
汇编
实施此操作后,您可以通过两种方式出发!第一种方法是将其放入罐子中,就像您一样!另一种是使用groovy脚本先于其他人编译它。为了在 grails 中做到这一点,我们使用_Events.groovy
script.
您可以从插件或主项目中执行此操作,这并不重要。如果不存在,创建一个名为_Events.groovy
并添加以下内容。
代码复制自莱因哈德-塞勒.blogspot.com有修改
eventCompileStart = {target ->
...
compileAST(pluginBasedir, classesDirPath)
...
}
def compileAST(def srcBaseDir, def destDir) {
ant.sequential {
echo "Precompiling AST Transformations ..."
echo "src ${srcBaseDir} ${destDir}"
path id: "grails.compile.classpath", compileClasspath
def classpathId = "grails.compile.classpath"
mkdir dir: destDir
groovyc(destdir: destDir,
srcDir: "$srcBaseDir/src/precompiled",
classpathref: classpathId,
stacktrace: "yes",
encoding: "UTF-8")
copy(toDir:"$destDir/META-INF"){
fileset(dir:"$srcBaseDir/src/precompiled/META-INF")
}
echo "done precompiling AST Transformations"
}
}
前面的脚本将在编译其他脚本之前编译转换器!这使得转换器可用于转换您的域类。
别忘了
如果您使用类路径中添加的类以外的任何类,则也必须预编译它们。上面的脚本将编译所有内容precompiled
目录,您还可以添加不需要 ast 但在该目录中需要它的类!
如果您想在转换中使用域类,您可能需要在以下位置进行预编译evenCompileEnd
堵塞!但这会让事情变得更慢!
Update
@Douglas Mendes 提到有一种简单的方法可以进行预编译。哪个更简洁。
eventCompileStart = {
target -> projectCompiler.srcDirectories.add(0, "./src/precompiled")
}