Groovy AST Compilation Time: Field Assignment

I'm currently trying to implement some AST transformations after a Groovy transform, but I ran into a problem:

How to specify AST conversion for assignment operator in a field? that is, the AST conversion should convert the following code:

class MyClass {
    @MyTransformation
    String myField

    public void init() {
    }
}

into something like

class MyClass {
    String myField

    public void init() {
        this.myField = "initialized!"
    }
}

I tried this with this AST call:

def ast = new AstBuilder().buildFromSpec {
        expression{
            declaration {
                variable "myField"
                token "="
                constant "initialized!"
            }
        }
}

But after inserting the resulting statement into the "init" method of the declaration class, instead of it, a variable assignment was added instead, as in

java.lang.Object myField = "initialized!"

, Ast Builder TestCase, , . fieldNode . INSTRUCTION_SELECTION; , .

? , AstBuilder#buildFromSpec, , .

+4
1

AST-. , , . , , node. AST Builder AST, IMHO.

, , , . @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

, !

+4

All Articles