Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Groovy编译时AST转换:字段赋值_Groovy_Abstract Syntax Tree - Fatal编程技术网

Groovy编译时AST转换:字段赋值

Groovy编译时AST转换:字段赋值,groovy,abstract-syntax-tree,Groovy,Abstract Syntax Tree,我目前正在尝试实现一些Groovy编译时AST转换,但遇到了麻烦: 如何为字段的赋值语句指定AST转换?i、 e.AST转换应转换以下代码: class MyClass { @MyTransformation String myField public void init() { } } 变成 class MyClass { String myField public void init() { this.myField =

我目前正在尝试实现一些Groovy编译时AST转换,但遇到了麻烦:

如何为字段的赋值语句指定AST转换?i、 e.AST转换应转换以下代码:

class MyClass {
    @MyTransformation
    String myField

    public void init() {
    }
}
变成

class MyClass {
    String myField

    public void init() {
        this.myField = "initialized!"
    }
}
我尝试了这个AST生成器调用:

def ast = new AstBuilder().buildFromSpec {
        expression{
            declaration {
                variable "myField"
                token "="
                constant "initialized!"
            }
        }
}
但是在声明类的“init”方法中插入结果语句之后,它反而插入了一个变量赋值,如中所示

java.lang.Object myField = "initialized!"
我查看了中包含的示例,但它们只涉及类主体中的字段声明,而不涉及字段赋值。我自己使用
fieldNode
的尝试都导致了编译器错误。我将编译阶段设置为
指令选择
;我想这应该没问题


我如何做到这一点?基于
AstBuilder#buildFromSpec
方法的解决方案是首选,但任何帮助都将不胜感激。

我通常建议不要使用AST builder。这对原型设计很好,但是你不能真正控制它生成的内容。特别是在这里,它无法处理您创建的变量表达式应该引用字段节点这一事实。AST构建器很好地了解了AST,但不应在生产代码IMHO中使用

下面是一个自包含的示例,演示如何实现您想要的。@astest中的代码将对应于您的转换代码:

import groovy.transform.ASTTest                                                         
import org.codehaus.groovy.ast.expr.BinaryExpression                            
import org.codehaus.groovy.ast.expr.VariableExpression                          
import org.codehaus.groovy.ast.expr.ConstantExpression                          
import org.codehaus.groovy.ast.stmt.ExpressionStatement                         
import org.codehaus.groovy.syntax.Token                                         
import org.codehaus.groovy.syntax.Types      

class MyClass {                                                                         
    String myField                                                                      

    @ASTTest(phase=SEMANTIC_ANALYSIS,value={                                            
            def classNode = node.declaringClass                                         
            def field = classNode.getDeclaredField('myField')                           
            def assignment = new BinaryExpression(                                      
              new VariableExpression(field),                                              
              Token.newSymbol(Types.EQUAL, 0, 0),                                         
              new ConstantExpression('initialized!')                                      
            )                                                                                   
            node.code.addStatement(new ExpressionStatement(assignment))                 
    })                                                                          
    public void init() {                                                                
    }                                                                                   
}                                                                                       
def c = new MyClass()                                                                   
c.init()                                                                                
println c.myField

希望这有帮助

谢谢,这是一个很好的回答。它不仅解决了我当前的问题,而且还为我指出了最佳实践和我不熟悉的
@astest
注释。