- How to pass parameters into an AST in a configuration script
- How to use a custom AST in a configuration script
1. AST parameters in a configuration script
Let's say you wanted to do
@groovy.transform.TupleConstructor(includes=['foo'])
in a configuration script. How do you pass the includes? Use a map. The equivalent configuration script would be
withConfig(configuration) {
ast(groovy.transform.TupleConstructor, includes:['foo'])
}
2. Custom AST in a configuration script
If you wanted to create your own AST and use it in a configuration script, I suggest looking at Groovy as a starting point. Here, I'll use groovy.transform.TupleConstructor and org.codehaus.groovy.transform.TupleConstructorASTTransformation as an example to solve Nikolay's problem. Here is the result
import java.lang.annotation.ElementType
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
import java.lang.annotation.Target
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.ast.AnnotatedNode
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.ConstructorNode
import org.codehaus.groovy.ast.Parameter
import org.codehaus.groovy.ast.stmt.BlockStatement
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.transform.AbstractASTTransformation
import org.codehaus.groovy.transform.GroovyASTTransformation
import org.codehaus.groovy.transform.GroovyASTTransformationClass
@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
public class DefaultConstructorASTTransformation extends AbstractASTTransformation {
public void visit(ASTNode[] nodes, SourceUnit source) {
init(nodes, source)
AnnotatedNode parent = (AnnotatedNode) nodes[1]
if (parent instanceof ClassNode) {
ClassNode cNode = (ClassNode) parent
// doesn't already have a default constructor
if (!cNode.getDeclaredConstructor(new Parameter[0])) {
cNode.addConstructor(new ConstructorNode(
ACC_PUBLIC, new Parameter[0], cNode.EMPTY_ARRAY, new BlockStatement()))
}
}
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@GroovyASTTransformationClass("DefaultConstructorASTTransformation")
public @interface DefaultConstructor {}
withConfig(configuration) {
ast(DefaultConstructor)
}