Groovy 创建添加方法的全局转换
我创造了这种转变Groovy 创建添加方法的全局转换,groovy,Groovy,我创造了这种转变 package org.global import groovy.transform.CompileStatic import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.ast.ClassHelper import org.codehaus.groovy.ast.MethodNode import org.codeh
package org.global
import groovy.transform.CompileStatic
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.ClassHelper
import org.codehaus.groovy.ast.MethodNode
import org.codehaus.groovy.ast.Parameter
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.transform.ASTTransformation
import org.codehaus.groovy.transform.GroovyASTTransformation
import org.codehaus.groovy.ast.stmt.BlockStatement
import org.codehaus.groovy.ast.stmt.ExpressionStatement
import org.codehaus.groovy.ast.expr.MethodCallExpression
import org.codehaus.groovy.ast.expr.VariableExpression
import org.codehaus.groovy.ast.expr.ConstantExpression
import org.codehaus.groovy.ast.expr.ArgumentListExpression
@CompileStatic
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
public class SayHelloTransformation implements ASTTransformation {
public void visit(ASTNode[] astNodes, SourceUnit sourceUnit) {
BlockStatement statement = new BlockStatement()
statement.addStatement(
new ExpressionStatement (
new MethodCallExpression (
new VariableExpression("this"),
new ConstantExpression("println"),
new ArgumentListExpression(
new ConstantExpression("hello world")
)
)
)
)
MethodNode sayHelloMethod = new MethodNode(
"sayHello", 0x0001, ClassHelper.VOID_TYPE, Parameter.EMPTY_ARRAY,
ClassNode.EMPTY_ARRAY, statement
)
sourceUnit.AST.methods.add(sayHelloMethod)
}
}
我编译了它。然后我添加了带有描述符的META-INF
文件夹
org.global.SayHelloTransformation
所以整体结构是这样的
META-INF\
services\
org.codehaus.groovy.transform.ASTTransformation
org\
global\
SayHelloTransformation.class
SayHelloTransformation.groovy
META-INF\
services\
org.codehaus.groovy.transform.ASTTransformation
org\
global\
SayHelloTransformation.class
SayHelloTransformation.groovy
SomeClass.class
SomeClass.groovy
test.groovy
然后我将SomeClass.groovy
添加到与SayHelloTransformation.groovy
class SomeClass {
}
和test.groovy
文件
新建SomeClass().sayHello()
但我有个例外
Caught: groovy.lang.MissingMethodException: No signature of method: SomeClass.sayHello() is applicable for argument types: (
) values: []
groovy.lang.MissingMethodException: No signature of method: SomeClass.sayHello() is applicable for argument types: () values
: []
at test.run(test.groovy:2)
整个结构是这样的
META-INF\
services\
org.codehaus.groovy.transform.ASTTransformation
org\
global\
SayHelloTransformation.class
SayHelloTransformation.groovy
META-INF\
services\
org.codehaus.groovy.transform.ASTTransformation
org\
global\
SayHelloTransformation.class
SayHelloTransformation.groovy
SomeClass.class
SomeClass.groovy
test.groovy
您是否试图在定义AST的同一项目中测试转换?如果需要,则需要在通过
GroovyShell
加载的脚本中进行测试,否则编译已经完成,无法应用转换。另一种方法是使用辅助项目来测试AST。我使用groovyc
进行编译,因此所有文件都在同一个文件夹中。正如我在问题中所展示的那样。我只需要一个使用转换的工作示例,然后需要分别编译它们。GroovyShell或单独的项目。您不能在编译转换的同一编译中运行转换。抱歉,我仍然不明白。因此,基本上应该移出什么-我有一个文件夹,其中包含META-INF
和package
以及.class
文件,用于转换。那么如何使用它呢?是的,你应该使用合适的构建工具或IDE。使用Maven和Gradle,您可以运行使用转换的测试。这两个工具分别编译测试,所以您都会很好。在IDE中,您必须在测试中使用一些技巧,比如assertScript
,以便稍后编译测试。