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
,以便稍后编译测试。