0
# AST and Compilation
1
2
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.
3
4
## Capabilities
5
6
### AST Node Base Classes
7
8
Core AST node classes that represent elements of Groovy source code.
9
10
```java { .api }
11
abstract class ASTNode {
12
/**
13
* Gets the line number where this node appears in source.
14
*/
15
int getLineNumber();
16
17
/**
18
* Gets the column number where this node appears in source.
19
*/
20
int getColumnNumber();
21
22
/**
23
* Gets the last line number of this node.
24
*/
25
int getLastLineNumber();
26
27
/**
28
* Gets the last column number of this node.
29
*/
30
int getLastColumnNumber();
31
32
/**
33
* Gets the text representation of this node.
34
*/
35
String getText();
36
37
/**
38
* Sets the source position for this node.
39
*/
40
void setSourcePosition(ASTNode node);
41
42
/**
43
* Copies source position from another node.
44
*/
45
void copyNodeMetaData(ASTNode other);
46
}
47
```
48
49
### Class Nodes
50
51
AST representation of classes and their structure.
52
53
```java { .api }
54
class ClassNode extends AnnotatedNode {
55
/**
56
* Creates a class node with the given name.
57
*/
58
ClassNode(String name);
59
60
/**
61
* Creates a class node for the given class.
62
*/
63
ClassNode(Class<?> clazz);
64
65
/**
66
* Gets the name of this class.
67
*/
68
String getName();
69
70
/**
71
* Gets the unresolved name of this class.
72
*/
73
String getUnresolvedName();
74
75
/**
76
* Gets all methods declared in this class.
77
*/
78
List<MethodNode> getMethods();
79
80
/**
81
* Gets all fields declared in this class.
82
*/
83
List<FieldNode> getFields();
84
85
/**
86
* Gets all properties declared in this class.
87
*/
88
List<PropertyNode> getProperties();
89
90
/**
91
* Gets all constructors declared in this class.
92
*/
93
List<ConstructorNode> getDeclaredConstructors();
94
95
/**
96
* Gets the superclass of this class.
97
*/
98
ClassNode getSuperClass();
99
100
/**
101
* Sets the superclass of this class.
102
*/
103
void setSuperClass(ClassNode superClass);
104
105
/**
106
* Gets the interfaces implemented by this class.
107
*/
108
ClassNode[] getInterfaces();
109
110
/**
111
* Sets the interfaces implemented by this class.
112
*/
113
void setInterfaces(ClassNode[] interfaces);
114
115
/**
116
* Gets the modifiers for this class.
117
*/
118
int getModifiers();
119
120
/**
121
* Sets the modifiers for this class.
122
*/
123
void setModifiers(int modifiers);
124
125
/**
126
* Checks if this class is an interface.
127
*/
128
boolean isInterface();
129
130
/**
131
* Checks if this class is abstract.
132
*/
133
boolean isAbstract();
134
135
/**
136
* Checks if this class is an enum.
137
*/
138
boolean isEnum();
139
140
/**
141
* Checks if this class is an annotation.
142
*/
143
boolean isAnnotationDefinition();
144
}
145
```
146
147
### Method Nodes
148
149
AST representation of methods and their signatures.
150
151
```java { .api }
152
class MethodNode extends AnnotatedNode {
153
/**
154
* Creates a method node.
155
*/
156
MethodNode(String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code);
157
158
/**
159
* Gets the name of this method.
160
*/
161
String getName();
162
163
/**
164
* Gets the modifiers for this method.
165
*/
166
int getModifiers();
167
168
/**
169
* Sets the modifiers for this method.
170
*/
171
void setModifiers(int modifiers);
172
173
/**
174
* Gets the return type of this method.
175
*/
176
ClassNode getReturnType();
177
178
/**
179
* Sets the return type of this method.
180
*/
181
void setReturnType(ClassNode returnType);
182
183
/**
184
* Gets the parameters of this method.
185
*/
186
Parameter[] getParameters();
187
188
/**
189
* Sets the parameters of this method.
190
*/
191
void setParameters(Parameter[] parameters);
192
193
/**
194
* Gets the exceptions thrown by this method.
195
*/
196
ClassNode[] getExceptions();
197
198
/**
199
* Sets the exceptions thrown by this method.
200
*/
201
void setExceptions(ClassNode[] exceptions);
202
203
/**
204
* Gets the code body of this method.
205
*/
206
Statement getCode();
207
208
/**
209
* Sets the code body of this method.
210
*/
211
void setCode(Statement code);
212
213
/**
214
* Checks if this method is abstract.
215
*/
216
boolean isAbstract();
217
218
/**
219
* Checks if this method is static.
220
*/
221
boolean isStatic();
222
223
/**
224
* Checks if this method is public.
225
*/
226
boolean isPublic();
227
228
/**
229
* Checks if this method is private.
230
*/
231
boolean isPrivate();
232
233
/**
234
* Checks if this method is protected.
235
*/
236
boolean isProtected();
237
}
238
```
239
240
### Field and Property Nodes
241
242
AST representation of fields and properties.
243
244
```java { .api }
245
class FieldNode extends AnnotatedNode {
246
/**
247
* Creates a field node.
248
*/
249
FieldNode(String name, int modifiers, ClassNode type, ClassNode declaringClass, Expression initialExpression);
250
251
/**
252
* Gets the name of this field.
253
*/
254
String getName();
255
256
/**
257
* Gets the type of this field.
258
*/
259
ClassNode getType();
260
261
/**
262
* Sets the type of this field.
263
*/
264
void setType(ClassNode type);
265
266
/**
267
* Gets the modifiers for this field.
268
*/
269
int getModifiers();
270
271
/**
272
* Sets the modifiers for this field.
273
*/
274
void setModifiers(int modifiers);
275
276
/**
277
* Gets the initial expression for this field.
278
*/
279
Expression getInitialExpression();
280
281
/**
282
* Sets the initial expression for this field.
283
*/
284
void setInitialValueExpression(Expression initialValueExpression);
285
286
/**
287
* Gets the class that declares this field.
288
*/
289
ClassNode getDeclaringClass();
290
291
/**
292
* Checks if this field is static.
293
*/
294
boolean isStatic();
295
296
/**
297
* Checks if this field is final.
298
*/
299
boolean isFinal();
300
301
/**
302
* Checks if this field is public.
303
*/
304
boolean isPublic();
305
306
/**
307
* Checks if this field is private.
308
*/
309
boolean isPrivate();
310
311
/**
312
* Checks if this field is protected.
313
*/
314
boolean isProtected();
315
}
316
317
class PropertyNode extends AnnotatedNode {
318
/**
319
* Creates a property node.
320
*/
321
PropertyNode(String name, int modifiers, ClassNode type, ClassNode declaringClass, Expression initialExpression, Statement getterBlock, Statement setterBlock);
322
323
/**
324
* Gets the name of this property.
325
*/
326
String getName();
327
328
/**
329
* Gets the type of this property.
330
*/
331
ClassNode getType();
332
333
/**
334
* Sets the type of this property.
335
*/
336
void setType(ClassNode type);
337
338
/**
339
* Gets the modifiers for this property.
340
*/
341
int getModifiers();
342
343
/**
344
* Gets the getter block for this property.
345
*/
346
Statement getGetterBlock();
347
348
/**
349
* Sets the getter block for this property.
350
*/
351
void setGetterBlock(Statement getterBlock);
352
353
/**
354
* Gets the setter block for this property.
355
*/
356
Statement getSetterBlock();
357
358
/**
359
* Sets the setter block for this property.
360
*/
361
void setSetterBlock(Statement setterBlock);
362
363
/**
364
* Gets the field associated with this property.
365
*/
366
FieldNode getField();
367
368
/**
369
* Sets the field associated with this property.
370
*/
371
void setField(FieldNode field);
372
}
373
```
374
375
### Module and Package Nodes
376
377
AST representation of modules, packages, and compilation units.
378
379
```java { .api }
380
class ModuleNode extends ASTNode {
381
/**
382
* Creates a module node.
383
*/
384
ModuleNode(SourceUnit sourceUnit);
385
386
/**
387
* Gets all classes declared in this module.
388
*/
389
List<ClassNode> getClasses();
390
391
/**
392
* Adds a class to this module.
393
*/
394
void addClass(ClassNode node);
395
396
/**
397
* Gets the main class of this module.
398
*/
399
ClassNode getScriptClassDummy();
400
401
/**
402
* Gets the statement block for script code.
403
*/
404
BlockStatement getStatementBlock();
405
406
/**
407
* Sets the statement block for script code.
408
*/
409
void setStatementBlock(BlockStatement statementBlock);
410
411
/**
412
* Gets all import statements.
413
*/
414
List<ImportNode> getImports();
415
416
/**
417
* Adds an import statement.
418
*/
419
void addImport(String alias, ClassNode type);
420
421
/**
422
* Gets all static import statements.
423
*/
424
Map<String, ImportNode> getStaticImports();
425
426
/**
427
* Adds a static import statement.
428
*/
429
void addStaticImport(ClassNode type, String fieldName, String alias);
430
431
/**
432
* Gets the package name.
433
*/
434
String getPackageName();
435
436
/**
437
* Sets the package name.
438
*/
439
void setPackageName(String packageName);
440
}
441
442
class PackageNode extends ASTNode {
443
/**
444
* Creates a package node.
445
*/
446
PackageNode(String name);
447
448
/**
449
* Gets the package name.
450
*/
451
String getName();
452
453
/**
454
* Gets the package name without the final dot.
455
*/
456
String getPackageName();
457
}
458
```
459
460
### AST Builder
461
462
Programmatic AST construction utilities.
463
464
```java { .api }
465
class AstBuilder {
466
/**
467
* Creates an AST builder.
468
*/
469
AstBuilder();
470
471
/**
472
* Builds AST from string source code.
473
*/
474
List<ASTNode> buildFromString(String source);
475
476
/**
477
* Builds AST from string source with specified phase.
478
*/
479
List<ASTNode> buildFromString(CompilePhase phase, String source);
480
481
/**
482
* Builds AST from string source with statementsOnly flag.
483
*/
484
List<ASTNode> buildFromString(CompilePhase phase, boolean statementsOnly, String source);
485
486
/**
487
* Builds AST from closure code.
488
*/
489
List<ASTNode> buildFromCode(Closure closure);
490
491
/**
492
* Builds AST from closure code with specified phase.
493
*/
494
List<ASTNode> buildFromCode(CompilePhase phase, Closure closure);
495
496
/**
497
* Builds AST from closure code with statementsOnly flag.
498
*/
499
List<ASTNode> buildFromCode(CompilePhase phase, boolean statementsOnly, Closure closure);
500
501
/**
502
* Builds AST from specification closure.
503
*/
504
List<ASTNode> buildFromSpec(Closure specification);
505
}
506
```
507
508
### Annotation Nodes
509
510
AST representation of annotations and their values.
511
512
```java { .api }
513
class AnnotationNode extends ASTNode {
514
/**
515
* Creates an annotation node.
516
*/
517
AnnotationNode(ClassNode type);
518
519
/**
520
* Gets the type of this annotation.
521
*/
522
ClassNode getClassNode();
523
524
/**
525
* Gets all members of this annotation.
526
*/
527
Map<String, Expression> getMembers();
528
529
/**
530
* Gets a specific member value.
531
*/
532
Expression getMember(String name);
533
534
/**
535
* Sets a member value.
536
*/
537
void setMember(String name, Expression value);
538
539
/**
540
* Adds a member value.
541
*/
542
void addMember(String name, Expression value);
543
544
/**
545
* Checks if this annotation has a member with the given name.
546
*/
547
boolean hasMember(String name);
548
549
/**
550
* Checks if this annotation has a runtime retention.
551
*/
552
boolean hasRuntimeRetention();
553
554
/**
555
* Checks if this annotation has a source retention.
556
*/
557
boolean hasSourceRetention();
558
559
/**
560
* Checks if this annotation has a class retention.
561
*/
562
boolean hasClassRetention();
563
}
564
```
565
566
## Usage Examples
567
568
### Programmatic AST Creation
569
570
```java
571
import org.codehaus.groovy.ast.*;
572
import org.codehaus.groovy.ast.builder.AstBuilder;
573
574
// Build AST from string
575
AstBuilder builder = new AstBuilder();
576
List<ASTNode> nodes = builder.buildFromString(
577
"class HelloWorld { void sayHello() { println 'Hello!' } }"
578
);
579
580
ClassNode classNode = (ClassNode) nodes.get(0);
581
System.out.println("Class name: " + classNode.getName());
582
583
for (MethodNode method : classNode.getMethods()) {
584
System.out.println("Method: " + method.getName());
585
}
586
```
587
588
### AST Transformation Framework
589
590
```java
591
import org.codehaus.groovy.transform.GroovyASTTransformation;
592
import org.codehaus.groovy.control.CompilePhase;
593
import org.codehaus.groovy.ast.ASTNode;
594
import org.codehaus.groovy.control.SourceUnit;
595
596
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
597
public class MyASTTransformation implements ASTTransformation {
598
599
public void visit(ASTNode[] nodes, SourceUnit source) {
600
// Custom AST transformation logic
601
for (ASTNode node : nodes) {
602
if (node instanceof ClassNode) {
603
ClassNode classNode = (ClassNode) node;
604
// Modify the AST
605
addToStringMethod(classNode);
606
}
607
}
608
}
609
610
private void addToStringMethod(ClassNode classNode) {
611
// Add a toString method to the class
612
// Implementation details...
613
}
614
}
615
```
616
617
### Dynamic Class Generation
618
619
```java
620
import org.codehaus.groovy.ast.*;
621
import org.codehaus.groovy.ast.stmt.*;
622
import org.codehaus.groovy.ast.expr.*;
623
624
// Create a new class programmatically
625
ClassNode classNode = new ClassNode("DynamicClass",
626
ClassNode.ACC_PUBLIC, ClassHelper.OBJECT_TYPE);
627
628
// Add a field
629
FieldNode field = new FieldNode("name",
630
ClassNode.ACC_PRIVATE, ClassHelper.STRING_TYPE, classNode,
631
new ConstantExpression("default"));
632
classNode.addField(field);
633
634
// Add a getter method
635
MethodNode getter = new MethodNode("getName",
636
ClassNode.ACC_PUBLIC, ClassHelper.STRING_TYPE,
637
Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY,
638
new ReturnStatement(new FieldExpression(field)));
639
classNode.addMethod(getter);
640
641
// Compile and use the class
642
GroovyClassLoader loader = new GroovyClassLoader();
643
Class<?> dynamicClass = loader.defineClass(classNode);
644
Object instance = dynamicClass.newInstance();
645
```