Apache Groovy is a powerful multi-faceted programming language for the JVM platform
—
Abstract Syntax Tree classes and compilation support for programmatic code generation, AST transformations, and compile-time meta-programming. These APIs are essential for building Groovy-based tools, IDEs, and custom compile-time transformations.
Core AST node classes that represent elements of Groovy source code.
abstract class ASTNode {
/**
* Gets the line number where this node appears in source.
*/
int getLineNumber();
/**
* Gets the column number where this node appears in source.
*/
int getColumnNumber();
/**
* Gets the last line number of this node.
*/
int getLastLineNumber();
/**
* Gets the last column number of this node.
*/
int getLastColumnNumber();
/**
* Gets the text representation of this node.
*/
String getText();
/**
* Sets the source position for this node.
*/
void setSourcePosition(ASTNode node);
/**
* Copies source position from another node.
*/
void copyNodeMetaData(ASTNode other);
}AST representation of classes and their structure.
class ClassNode extends AnnotatedNode {
/**
* Creates a class node with the given name.
*/
ClassNode(String name);
/**
* Creates a class node for the given class.
*/
ClassNode(Class<?> clazz);
/**
* Gets the name of this class.
*/
String getName();
/**
* Gets the unresolved name of this class.
*/
String getUnresolvedName();
/**
* Gets all methods declared in this class.
*/
List<MethodNode> getMethods();
/**
* Gets all fields declared in this class.
*/
List<FieldNode> getFields();
/**
* Gets all properties declared in this class.
*/
List<PropertyNode> getProperties();
/**
* Gets all constructors declared in this class.
*/
List<ConstructorNode> getDeclaredConstructors();
/**
* Gets the superclass of this class.
*/
ClassNode getSuperClass();
/**
* Sets the superclass of this class.
*/
void setSuperClass(ClassNode superClass);
/**
* Gets the interfaces implemented by this class.
*/
ClassNode[] getInterfaces();
/**
* Sets the interfaces implemented by this class.
*/
void setInterfaces(ClassNode[] interfaces);
/**
* Gets the modifiers for this class.
*/
int getModifiers();
/**
* Sets the modifiers for this class.
*/
void setModifiers(int modifiers);
/**
* Checks if this class is an interface.
*/
boolean isInterface();
/**
* Checks if this class is abstract.
*/
boolean isAbstract();
/**
* Checks if this class is an enum.
*/
boolean isEnum();
/**
* Checks if this class is an annotation.
*/
boolean isAnnotationDefinition();
}AST representation of methods and their signatures.
class MethodNode extends AnnotatedNode {
/**
* Creates a method node.
*/
MethodNode(String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code);
/**
* Gets the name of this method.
*/
String getName();
/**
* Gets the modifiers for this method.
*/
int getModifiers();
/**
* Sets the modifiers for this method.
*/
void setModifiers(int modifiers);
/**
* Gets the return type of this method.
*/
ClassNode getReturnType();
/**
* Sets the return type of this method.
*/
void setReturnType(ClassNode returnType);
/**
* Gets the parameters of this method.
*/
Parameter[] getParameters();
/**
* Sets the parameters of this method.
*/
void setParameters(Parameter[] parameters);
/**
* Gets the exceptions thrown by this method.
*/
ClassNode[] getExceptions();
/**
* Sets the exceptions thrown by this method.
*/
void setExceptions(ClassNode[] exceptions);
/**
* Gets the code body of this method.
*/
Statement getCode();
/**
* Sets the code body of this method.
*/
void setCode(Statement code);
/**
* Checks if this method is abstract.
*/
boolean isAbstract();
/**
* Checks if this method is static.
*/
boolean isStatic();
/**
* Checks if this method is public.
*/
boolean isPublic();
/**
* Checks if this method is private.
*/
boolean isPrivate();
/**
* Checks if this method is protected.
*/
boolean isProtected();
}AST representation of fields and properties.
class FieldNode extends AnnotatedNode {
/**
* Creates a field node.
*/
FieldNode(String name, int modifiers, ClassNode type, ClassNode declaringClass, Expression initialExpression);
/**
* Gets the name of this field.
*/
String getName();
/**
* Gets the type of this field.
*/
ClassNode getType();
/**
* Sets the type of this field.
*/
void setType(ClassNode type);
/**
* Gets the modifiers for this field.
*/
int getModifiers();
/**
* Sets the modifiers for this field.
*/
void setModifiers(int modifiers);
/**
* Gets the initial expression for this field.
*/
Expression getInitialExpression();
/**
* Sets the initial expression for this field.
*/
void setInitialValueExpression(Expression initialValueExpression);
/**
* Gets the class that declares this field.
*/
ClassNode getDeclaringClass();
/**
* Checks if this field is static.
*/
boolean isStatic();
/**
* Checks if this field is final.
*/
boolean isFinal();
/**
* Checks if this field is public.
*/
boolean isPublic();
/**
* Checks if this field is private.
*/
boolean isPrivate();
/**
* Checks if this field is protected.
*/
boolean isProtected();
}
class PropertyNode extends AnnotatedNode {
/**
* Creates a property node.
*/
PropertyNode(String name, int modifiers, ClassNode type, ClassNode declaringClass, Expression initialExpression, Statement getterBlock, Statement setterBlock);
/**
* Gets the name of this property.
*/
String getName();
/**
* Gets the type of this property.
*/
ClassNode getType();
/**
* Sets the type of this property.
*/
void setType(ClassNode type);
/**
* Gets the modifiers for this property.
*/
int getModifiers();
/**
* Gets the getter block for this property.
*/
Statement getGetterBlock();
/**
* Sets the getter block for this property.
*/
void setGetterBlock(Statement getterBlock);
/**
* Gets the setter block for this property.
*/
Statement getSetterBlock();
/**
* Sets the setter block for this property.
*/
void setSetterBlock(Statement setterBlock);
/**
* Gets the field associated with this property.
*/
FieldNode getField();
/**
* Sets the field associated with this property.
*/
void setField(FieldNode field);
}AST representation of modules, packages, and compilation units.
class ModuleNode extends ASTNode {
/**
* Creates a module node.
*/
ModuleNode(SourceUnit sourceUnit);
/**
* Gets all classes declared in this module.
*/
List<ClassNode> getClasses();
/**
* Adds a class to this module.
*/
void addClass(ClassNode node);
/**
* Gets the main class of this module.
*/
ClassNode getScriptClassDummy();
/**
* Gets the statement block for script code.
*/
BlockStatement getStatementBlock();
/**
* Sets the statement block for script code.
*/
void setStatementBlock(BlockStatement statementBlock);
/**
* Gets all import statements.
*/
List<ImportNode> getImports();
/**
* Adds an import statement.
*/
void addImport(String alias, ClassNode type);
/**
* Gets all static import statements.
*/
Map<String, ImportNode> getStaticImports();
/**
* Adds a static import statement.
*/
void addStaticImport(ClassNode type, String fieldName, String alias);
/**
* Gets the package name.
*/
String getPackageName();
/**
* Sets the package name.
*/
void setPackageName(String packageName);
}
class PackageNode extends ASTNode {
/**
* Creates a package node.
*/
PackageNode(String name);
/**
* Gets the package name.
*/
String getName();
/**
* Gets the package name without the final dot.
*/
String getPackageName();
}Programmatic AST construction utilities.
class AstBuilder {
/**
* Creates an AST builder.
*/
AstBuilder();
/**
* Builds AST from string source code.
*/
List<ASTNode> buildFromString(String source);
/**
* Builds AST from string source with specified phase.
*/
List<ASTNode> buildFromString(CompilePhase phase, String source);
/**
* Builds AST from string source with statementsOnly flag.
*/
List<ASTNode> buildFromString(CompilePhase phase, boolean statementsOnly, String source);
/**
* Builds AST from closure code.
*/
List<ASTNode> buildFromCode(Closure closure);
/**
* Builds AST from closure code with specified phase.
*/
List<ASTNode> buildFromCode(CompilePhase phase, Closure closure);
/**
* Builds AST from closure code with statementsOnly flag.
*/
List<ASTNode> buildFromCode(CompilePhase phase, boolean statementsOnly, Closure closure);
/**
* Builds AST from specification closure.
*/
List<ASTNode> buildFromSpec(Closure specification);
}AST representation of annotations and their values.
class AnnotationNode extends ASTNode {
/**
* Creates an annotation node.
*/
AnnotationNode(ClassNode type);
/**
* Gets the type of this annotation.
*/
ClassNode getClassNode();
/**
* Gets all members of this annotation.
*/
Map<String, Expression> getMembers();
/**
* Gets a specific member value.
*/
Expression getMember(String name);
/**
* Sets a member value.
*/
void setMember(String name, Expression value);
/**
* Adds a member value.
*/
void addMember(String name, Expression value);
/**
* Checks if this annotation has a member with the given name.
*/
boolean hasMember(String name);
/**
* Checks if this annotation has a runtime retention.
*/
boolean hasRuntimeRetention();
/**
* Checks if this annotation has a source retention.
*/
boolean hasSourceRetention();
/**
* Checks if this annotation has a class retention.
*/
boolean hasClassRetention();
}import org.codehaus.groovy.ast.*;
import org.codehaus.groovy.ast.builder.AstBuilder;
// Build AST from string
AstBuilder builder = new AstBuilder();
List<ASTNode> nodes = builder.buildFromString(
"class HelloWorld { void sayHello() { println 'Hello!' } }"
);
ClassNode classNode = (ClassNode) nodes.get(0);
System.out.println("Class name: " + classNode.getName());
for (MethodNode method : classNode.getMethods()) {
System.out.println("Method: " + method.getName());
}import org.codehaus.groovy.transform.GroovyASTTransformation;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.control.SourceUnit;
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
public class MyASTTransformation implements ASTTransformation {
public void visit(ASTNode[] nodes, SourceUnit source) {
// Custom AST transformation logic
for (ASTNode node : nodes) {
if (node instanceof ClassNode) {
ClassNode classNode = (ClassNode) node;
// Modify the AST
addToStringMethod(classNode);
}
}
}
private void addToStringMethod(ClassNode classNode) {
// Add a toString method to the class
// Implementation details...
}
}import org.codehaus.groovy.ast.*;
import org.codehaus.groovy.ast.stmt.*;
import org.codehaus.groovy.ast.expr.*;
// Create a new class programmatically
ClassNode classNode = new ClassNode("DynamicClass",
ClassNode.ACC_PUBLIC, ClassHelper.OBJECT_TYPE);
// Add a field
FieldNode field = new FieldNode("name",
ClassNode.ACC_PRIVATE, ClassHelper.STRING_TYPE, classNode,
new ConstantExpression("default"));
classNode.addField(field);
// Add a getter method
MethodNode getter = new MethodNode("getName",
ClassNode.ACC_PUBLIC, ClassHelper.STRING_TYPE,
Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY,
new ReturnStatement(new FieldExpression(field)));
classNode.addMethod(getter);
// Compile and use the class
GroovyClassLoader loader = new GroovyClassLoader();
Class<?> dynamicClass = loader.defineClass(classNode);
Object instance = dynamicClass.newInstance();Install with Tessl CLI
npx tessl i tessl/maven-org-codehaus-groovy--groovy