如何在Grails插件中实现Groovy全局AST转换?
我想在编译时修改一些Grails域类。我最初认为这是Groovy全局ASTTransformation的工作,因为我不想注释我的域类(本地转换器需要)。最好的方法是什么 我还尝试模仿DefaultGrailDomainClassInjector.java,在同一个包中创建自己的类,实现相同的接口,但我可能不知道如何将其打包到正确的位置,因为我从未看到调用我的方法 另一方面,我能够手动创建一个JAR,其中包含一个已编译的AST转换类,以及普通Groovy全局转换所需的META-INF/services工件。我将该JAR放入项目的“lib”目录中,成功地调用了visit()。显然,这是一项草率的工作,因为我希望将AST转换的源代码放在Grails插件中,如果不需要的话,也不需要单独的JAR工件,而且我无法通过将JAR放在Grails插件的“lib”中来实现这种方法,而是必须将其放在Grails应用程序的“lib”中如何在Grails插件中实现Groovy全局AST转换?,grails,groovy,grails-plugin,Grails,Groovy,Grails Plugin,我想在编译时修改一些Grails域类。我最初认为这是Groovy全局ASTTransformation的工作,因为我不想注释我的域类(本地转换器需要)。最好的方法是什么 我还尝试模仿DefaultGrailDomainClassInjector.java,在同一个包中创建自己的类,实现相同的接口,但我可能不知道如何将其打包到正确的位置,因为我从未看到调用我的方法 另一方面,我能够手动创建一个JAR,其中包含一个已编译的AST转换类,以及普通Groovy全局转换所需的META-INF/servic
这篇文章也帮了一点忙:关于全局转换的事情编译开始时,转换代码应该是可用的。把变压器放在罐子里是我首先做的!但正如你所说,这是一份草率的工作。 您要做的是在其他人进入编译阶段之前编译ast转换类。这就是你要做的 准备变压器 在
src
文件夹中创建一个名为precompiled
的目录!并使用正确的打包结构在此目录中添加transformer使用的转换类和类(如注释)
precompiled
--amanu
----LoggingASTTransformation.groovy
--META-INF
----services
------org.codehaus.groovy.transform.ASTTransformation
然后在calledprecompiled/META-INF/services
中创建一个名为org.codehaus.groovy.transform.ASTTransformation
的文件,您将拥有以下结构
precompiled
--amanu
----LoggingASTTransformation.groovy
--META-INF
----services
------org.codehaus.groovy.transform.ASTTransformation
然后在org.codehaus.groovy.transform.ASTTransformation
文件中写入转换器的完全限定名,因为上面的示例中,完全限定名是amanu.LoggingASTTransformation
实施
汇编
在实现了这一点之后,您可以通过两种方式进行操作!第一种方法是像你一样把它放在罐子里!另一种是使用groovy脚本在其他脚本之前编译它。为了在grails中实现这一点,我们使用\u Events.groovy
脚本
您可以从插件或主项目中执行此操作,这并不重要。如果不存在,请创建一个名为\u Events.groovy的文件,并添加以下内容
代码经过修改后从中复制
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但该目录中需要的类
如果要在转换中使用域类,可能需要在evencileend
块中进行预编译!但这会让事情变得更慢
更新
@道格拉斯·门德斯(Douglas Mendes)提到,有一种简单的方法可以引起预编译。这更简洁
eventCompileStart = {
target -> projectCompiler.srcDirectories.add(0, "./src/precompiled")
}
还有一种更简单的方法可以首先使用_Events.groovy编译AST源文件夹:eventCompileStart={target->projectCompiler.srcDirectories.add(0,“./src/precompiled”)}
链接是死的,活的: