2. What is Groovy?
● A dynamic programming language that runs on
the JVM
● Language is essentially a superset of Java, in
fact grammar to parse Groovy is constructed
from Java grammar
● Groovy source code is translated into Java
bytecode by the Groovy compiler for execution
on the JVM
3. Where is Groovy?
● Groovy as a scripting language
● Frameworks for application development
● Grails – Web framework
● Griffon – Swing applications
● Gaelyk – Google App Engine
● Testing
● Easyb – Behavior Driven Development
● Spock – BDD and mocking
● Gmock - Mocking
6. What is an Abstract Syntax Tree?
● Rooted tree of nodes
● Composed of nodes that correspond to Groovy
language constructs
● We are interested in Groovy's AST syntax tree
● Composed of ASTNodes from the
org.codehaus.groovy.ast package and
subpackages
● Tree structure lends itself to processing using
Visitor design pattern
7. What is an AST Transformation?
● Compiler hook Groovy provides into
compilation process
● Means of extending language without grammar
changes
● Allows manipulation of AST during compilation
prior to bytecode generation
● Two types
● Local
● Global
8. Local AST Transformations
● More common
● Applied to specific declarations whose AST is to
be modified by the transformation
● Annotation indicates AST transformation should
be applied to declaration
● AST is walked and AST transformation applied
to nodes that are annotated with transformation
annotation (Visitor design pattern)
● Many supplied with Groovy distribution
9. Global AST Transformations
● Less common
● Applied to every source unit in compilation
● Uses jar file service provider mechanism to
identify global AST transformations
● Jar file added to classpath of compiler that
contains service locator file identifying name of
class that implements AST transformation
12. Example - @ToString
@groovy.transform.ToString
class Person {
String first, last
}
def person = new Person(first:"Hamlet", last:"D'Arcy")
println "${person.toString()}"
Result with @ToString transformation:
Person(Hamlet, D'Arcy)
Result without @ToString transformation:
Person@175078b
14. Example - @Delegate
class Delegate1Class {
public void method1() {}
public void method2(String p) {}
}
public class OwnerClass {
@Delegate Delegate1Class delegate1 = new Delegate1Class()
}
The @Delegate AST transformation implements delegation by
adding all of the public methods from the delegate class to the
owner class.
21. Example - @TypeChecked
@groovy.transform.TypeChecked
Number test() {
// Cannot find matching method
MyMethod()
// Variable is undelcared
println myField
// Cannot assign String to int
int object = "myString"
// Cannot return value of type String on method returning type Number
return "myString"
}
23. Location of Built-in AST
Transformations
● Annotation definition usually found in
groovy.transform or groovy.lang
● Implementation class usually found in
org.codehaus.groovy.transform
24. Custom AST Transformations
● Defined in exactly same manner as built-in AST
transformations
● Steps
1. Create AST transformation implementation class that
implements the ASTTransformation interface
2. Create AST transformation annotation declaration and
link it to the implementation class with the
@GroovyASTTransformationClass annotation
25. The Implementation Class
● Implements the ASTTransformation interface
● Single method
void visit(ASTNode nodes[], SourceUnit source)
● Compiler invokes this method on AST of annotated
element
● nodes array contains AnnotationNode for AST
transformation annotation and AnnotatedNode
corresponding to annotated declaration
27. The Annotation Type Declaration
● Indicate declaration types to which AST
transformation is applicable with @Target
annotation
● Indicate implementation class with
@GroovyASTTransformationClass
annotation
30. The Hard Part – Creating AST
objects
● Tools to help
● AST Browser
● ASTBuilder
● Ways to create AST objects
● Manually using ASTNode subclass constructors
(leveraging AST Browser)
● Using ASTBuilder.buildFromSpec
● Using ASTBuilder.buildFromString
● Using ASTBuilder.buildFromCode
31. Implementing createPrintlnStatement
Manually
private Statement createPrintlnStatement() {
Statement printlnStatement =
new ExpressionStatement(
new MethodCallExpression(
new VariableExpression("this"),
new ConstantExpression("println"),
new ArgumentListExpression(
new ConstantExpression("Hello World!!!!"))
))
return printlnStatement
}
33. Implementing createPrintlnStatement using
buildFromString
private Statement createPrintlnStatement() {
List<ASTNode> result =
new AstBuilder().buildFromString("println 'Hello World!!!!'; return")
return result[0]
}
34. Implementing createPrintlnStatement using
buildFromCode
private Statement createPrintlnStatement() {
List<ASTNode> result = new AstBuilder().buildFromCode {
println "Hello World!!!!"
return
}
return result[0]
}
35. Resources
● Groovy code itself provides excellent examples
● AST Browser is invaluable for seeing what code
is generated by a transformation
●
Groovy in Action (2nd edition) in MEAP –
Chapter 9 written by Hamlet D'Arcy
● Unit tests for ASTBuilder
● Shameless plug: Groovy Under the Hood in
GroovyMag
Hinweis der Redaktion
Grails – MVC framework with controllers and service classes in Groovy Griffon – Grails-like application framework for developing rich desktop applications Gaelyk – lightweight Groovy toolkit for building and deploying applications on Google App Engine Easyb – test specifications written in Groovy
Gant – tool for scripting Ant tasks using Groovy instead of XML to specify logic Gradle – enterprise-grade build system - Groovy build scripts - Dependency management - Used by hibernate, Grails, Groovy
This AST is a rooted tree made up of nodes that describes the various constructs within source code in a form that can be easily processed using the Visitor design pattern ( http://en.wikipedia.org/wiki/Visitor_pattern ). The Visitor design pattern essentially constructs a visitor object that traverses the tree and performs some action on each node in the tree.
Focus on automating repetative task of writing common methods likequals, hashCode and constructors
Verify using javap on OwnerClass
- Shorthand notation for every ASTNode type - API simplified - Helps eliminates some verbosity and complexity - Returns script class node as well - desired AST in first entry