当前位置: 首页 > 知识库问答 >
问题:

时髦编译时 AST 转换:对字段的赋值

厍建义
2023-03-14

我目前正在尝试实现一些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!"

我浏览了Ast Builder TestCase中包含的示例,但它们只涵盖了类主体中的字段声明,而不是字段分配。我自己使用field dNode的尝试都导致了编译器错误。我将编译阶段设置为INSTRUCTION_SELECTION;我认为这应该没问题。

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

共有1个答案

印子平
2023-03-14

我通常建议不要使用AST构建器。它有利于原型设计,但你并不能真正控制它生成的内容。特别是,在这里,它无法处理您创建的变量表达式应引用字段节点的事实。AST生成器非常适合了解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

希望这有帮助!

 类似资料:
  • 我正在尝试使用AST转换替换类的方法。 我首先检查该方法是否存在,然后将其删除(基于此)。 我看到集合上的大小发生了变化,但该方法仍然可以在类节点上访问。 删除该方法后,我想添加一个同名的新方法: 但是,这会导致以下错误: 正确的方法是什么? 更新:由于我打算做的就是替换该方法的现有功能,因此我创建了一个新的块语句,并使用 在现有方法上设置了它。

  • 我想开发一个Groovy AST转换,在某些类上添加一些方法。所以我写了一个注释类和相应的转换类。然后,我用我的Groovy AST注释来注释一个java类。 当我使用嵌入式时髦编译器编译 java 注释类时(例如,通过以下代码段:),执行转换并将方法添加到代码段中称为的已编译类中。 但我无法用Gradle groovy插件和Intellij IDEA正确编译java类。 问题:每个人都可以帮助我

  • 我想在将源代码传递给编译器之前,在编译时转换java源代码。换句话说,我想创建一个能够转换的预处理器 转换为任何其他代码,如: null 我很乐意为这两种方法找到一个java代码预处理的简单示例。 有没有人认为有什么聪明的方法来进行代码转换,而不是用多个ivy模块完全改变现有的大型代码库?注释似乎是最好的方法,但我不明白该怎么做。

  • 我想在编译时向某些类添加一个泛型字段。为了实现这个目标,我按照官方文档实现了我自己的 AST 注释和转换类,并使用 AST 注释注释了所需的类。 但是我在编译时得到了这个错误: org . codehaus . groovy . control . multiplecompilationerrorsexception:启动失败:/home/.../groovy/Sample.groovy: -1:

  • 我正在寻找Groovy AST转换,它可以在我的类中生成构建器模式代码。 我知道有一些类似于< code>@Canonnical或< code>@ToString或< code>@EqualsAndHashCode的增强器可以自动生成有用的方法,希望有@GenerateBuilder。我想这样使用它:

  • 我写了我自己的AST转换,它应该生成getter和setter方法(在这里创建getter方法)。但是他们不工作,不能理解原因。 使用属性创建注释 我的AST转换代码应该为注释字段创建getter方法 注释检查 在哪个地方我犯了错误? 运行结果: 线程“main”groovy中出现异常。lang.MissingMethodException:没有方法ua的签名。家插科打诨。用法实例getMyCou