Spu*_*ick 5 groovy abstract-syntax-tree
我目前正在尝试实现一些Groovy编译时AST转换,但我遇到了麻烦:
如何为字段的赋值语句指定AST转换?即AST转换应转换以下代码:
class MyClass {
@MyTransformation
String myField
public void init() {
}
}
Run Code Online (Sandbox Code Playgroud)
变成类似的东西
class MyClass {
String myField
public void init() {
this.myField = "initialized!"
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试了这个AST构建器调用:
def ast = new AstBuilder().buildFromSpec {
expression{
declaration {
variable "myField"
token "="
constant "initialized!"
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是在声明类的"init"方法中插入结果语句后,它会插入一个变量赋值,如
java.lang.Object myField = "initialized!"
Run Code Online (Sandbox Code Playgroud)
我查看了Ast Builder TestCase中包含的示例,但它们仅涵盖了类体中的字段声明,而不是字段的赋值.我自己尝试使用fieldNodeall会导致编译错误.我将编译阶段设置为INSTRUCTION_SELECTION; 我认为这应该没问题.
我该如何实现这一目标?基于该AstBuilder#buildFromSpec方法的解决方案是优选的,但是任何帮助都将受到高度赞赏.
小智 5
我通常建议不要使用AST构建器.它适用于原型设计,但您并不能真正控制其生成的内容.特别是,在这里,它无法处理您创建的变量表达式应引用字段节点的事实.AST Builder非常了解AST,但不应该用于生产代码恕我直言.
这是一个自包含的示例,演示了如何实现您想要的功能.@ASTTest中的代码对应于您的转换代码:
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
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!