Groovy AST Transformations
What is Groovy?●   A dynamic programming language that runs on    the JVM●   Language is essentially a superset of Java, i...
Where is Groovy?●   Groovy as a scripting language●   Frameworks for application development    ●   Grails – Web framework...
Where is Groovy? (cont...)●   Building projects    ●   Gradle    ●   Gant
How does Groovy code become         bytcode?
What is an Abstract Syntax Tree?●   Rooted tree of nodes●   Composed of nodes that correspond to Groovy    language constr...
What is an AST Transformation?●   Compiler hook Groovy provides into    compilation process●   Means of extending language...
Local AST Transformations●   More common●   Applied to specific declarations whose AST is to    be modified by the transfo...
Global AST Transformations●   Less common●   Applied to every source unit in compilation●   Uses jar file service provider...
Groovys Built-in AST               Transformations●   Code generation●   Design pattern implementation●   Simplified loggi...
Code Generation●   @ToString●   @EqualsAndHashCode●   @TupleConstructor●   @Canonical●   @Lazy●   @InheritConstructors
Example - @ToString@groovy.transform.ToStringclass Person {    String first, last}def person = new Person(first:"Hamlet", ...
Design Pattern Implementation●   @Delgate●   @Singleton●   @Immutable●   @Mixin●   @Category
Example - @Delegateclass Delegate1Class {   public void method1() {}   public void method2(String p) {}}public class Owner...
Simplified Logging●   @Log●   @Log4j●   @Slf4j●   @Commons
Concurrency Support●   @Synchronized●   @WithReadLock●   @WithWriteLock
Cloning and Externalization●   @AutoClone●   @AutoExternalize
JavaBeans Support●   @Bindable●   @Vetoable●   @ListenerList
Scripting Safety●   @TimedInterrupt●   @ThreadInterrupt●   @ConditionalInterrupt
Static Typing●   @TypeChecked●   @CompileStatic
Example - @TypeChecked@groovy.transform.TypeCheckedNumber test() {    // Cannot find matching method    MyMethod()    // V...
Miscellaneous●   @Field●   @PackageScope●   @Newify
Location of Built-in AST             Transformations●   Annotation definition usually found in    groovy.transform or groo...
Custom AST Transformations●   Defined in exactly same manner as built-in AST    transformations●   Steps    1. Create AST ...
The Implementation Class●   Implements the ASTTransformation interface    ●   Single method        void visit(ASTNode node...
HelloWorldASTTransformation@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)public class HelloWorldASTTransfo...
The Annotation Type Declaration●   Indicate declaration types to which AST    transformation is applicable with @Target   ...
HelloWorld@Target([ElementType.METHOD])@GroovyASTTransformationClass("HelloWorldASTTransformation")public @interface Hello...
HelloWorldExample@HelloWorldvoid myMethod() {}myMethod()
The Hard Part – Creating AST                  objects●   Tools to help    ●   AST Browser    ●   ASTBuilder●   Ways to cre...
Implementing createPrintlnStatement                 Manuallyprivate Statement createPrintlnStatement() {    Statement prin...
Implementing createPrintlnStatement using             buildFromSpec private Statement createPrintlnStatement() {     List<...
Implementing createPrintlnStatement using            buildFromStringprivate Statement createPrintlnStatement() {    List<A...
Implementing createPrintlnStatement using             buildFromCodeprivate Statement createPrintlnStatement() {    List<AS...
Resources●   Groovy code itself provides excellent examples●   AST Browser is invaluable for seeing what code    is genera...
Upcoming SlideShare
Loading in...5
×

Groovy AST Transformations

1,280

Published on

Introduction to Groovy AST Transformations for Detroit JUG January 2013

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,280
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
15
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide
  • 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
  • Transcript of "Groovy AST Transformations"

    1. 1. Groovy AST Transformations
    2. 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. 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
    4. 4. Where is Groovy? (cont...)● Building projects ● Gradle ● Gant
    5. 5. How does Groovy code become bytcode?
    6. 6. What is an Abstract Syntax Tree?● Rooted tree of nodes● Composed of nodes that correspond to Groovy language constructs● We are interested in Groovys 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. 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. 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. 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
    10. 10. Groovys Built-in AST Transformations● Code generation● Design pattern implementation● Simplified logging● Concurrency support● Cloning and externalization● JavaBeans support● Script safety● Static typing● Miscellaneous
    11. 11. Code Generation● @ToString● @EqualsAndHashCode● @TupleConstructor● @Canonical● @Lazy● @InheritConstructors
    12. 12. Example - @ToString@groovy.transform.ToStringclass Person { String first, last}def person = new Person(first:"Hamlet", last:"DArcy")println "${person.toString()}"Result with @ToString transformation:Person(Hamlet, DArcy)Result without @ToString transformation:Person@175078b
    13. 13. Design Pattern Implementation● @Delgate● @Singleton● @Immutable● @Mixin● @Category
    14. 14. Example - @Delegateclass Delegate1Class { public void method1() {} public void method2(String p) {}}public class OwnerClass { @Delegate Delegate1Class delegate1 = new Delegate1Class()}The @Delegate AST transformation implements delegation byadding all of the public methods from the delegate class to theowner class.
    15. 15. Simplified Logging● @Log● @Log4j● @Slf4j● @Commons
    16. 16. Concurrency Support● @Synchronized● @WithReadLock● @WithWriteLock
    17. 17. Cloning and Externalization● @AutoClone● @AutoExternalize
    18. 18. JavaBeans Support● @Bindable● @Vetoable● @ListenerList
    19. 19. Scripting Safety● @TimedInterrupt● @ThreadInterrupt● @ConditionalInterrupt
    20. 20. Static Typing● @TypeChecked● @CompileStatic
    21. 21. Example - @TypeChecked@groovy.transform.TypeCheckedNumber 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"}
    22. 22. Miscellaneous● @Field● @PackageScope● @Newify
    23. 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. 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. 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
    26. 26. HelloWorldASTTransformation@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)public class HelloWorldASTTransformation implements ASTTransformation { public void visit(ASTNode[] nodes, SourceUnit source) { MethodNode methodNode = (MethodNode)nodes[1] Statement methodCode = methodNode.getCode() // // Add greeting to beginning of code block. // methodCode.getStatements().add(0, createPrintlnStatement()) }
    27. 27. The Annotation Type Declaration● Indicate declaration types to which AST transformation is applicable with @Target annotation● Indicate implementation class with @GroovyASTTransformationClass annotation
    28. 28. HelloWorld@Target([ElementType.METHOD])@GroovyASTTransformationClass("HelloWorldASTTransformation")public @interface HelloWorld {}
    29. 29. HelloWorldExample@HelloWorldvoid myMethod() {}myMethod()
    30. 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. 31. Implementing createPrintlnStatement Manuallyprivate Statement createPrintlnStatement() { Statement printlnStatement = new ExpressionStatement( new MethodCallExpression( new VariableExpression("this"), new ConstantExpression("println"), new ArgumentListExpression( new ConstantExpression("Hello World!!!!")) )) return printlnStatement}
    32. 32. Implementing createPrintlnStatement using buildFromSpec private Statement createPrintlnStatement() { List<ASTNode> results = new AstBuilder().buildFromSpec { expression { methodCall { variable "this" constant "println" argumentList { constant "Hello World!!!!" } } } } return results[0] }
    33. 33. Implementing createPrintlnStatement using buildFromStringprivate Statement createPrintlnStatement() { List<ASTNode> result = new AstBuilder().buildFromString("println Hello World!!!!; return") return result[0]}
    34. 34. Implementing createPrintlnStatement using buildFromCodeprivate Statement createPrintlnStatement() { List<ASTNode> result = new AstBuilder().buildFromCode { println "Hello World!!!!" return } return result[0]}
    35. 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 DArcy● Unit tests for ASTBuilder● Shameless plug: Groovy Under the Hood in GroovyMag
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×