Introduction to Groovy runtime metaprogramming and AST transforms - by Marcin Grzejszczak author of the http://toomuchcoding.blogspot.com blog.
The sources can be found here
Mercurial Bitbucket - https://bitbucket.org/gregorin1987/too-much-coding/src/e5ab7c69ab7b2796075fd6f087fbf31346aa2d2b/Groovy/ast/?at=default
Git Github - https://github.com/marcingrzejszczak/too-much-coding/tree/master/Groovy/ast
9. Meta Object Protocol
●
●
●
●
MetaObject is an object that manipulates, creates, describes, or
implements other objects (including itself).
Stored info includes base object's type, interface, class, methods etc.
MetaObjects are examples of reflection concept
The Meta-Object-Protocol (MOP) is the collection of rules of how a request
for a method call is handled by the Groovy runtime system
10. MetaClass
MetaClass defines the behaviour of any given Groovy or Java class ●
●
●
The MetaClass interface has two parts:
○ Client API - via the extend MetaObjectProtocol interface
○ Contract with the Groovy runtime system.
In general the compiler and Groovy runtime engine interact with methods
on MetaClass class
In general the MetaClass clients interact with the method defined by the
MetaObjectProtocol interface
11. Expando
●
●
●
Kind of a dynamic bean.
It will memorize
○ added properties
○ added methods (from closures)
Useful for
○ mocking
○ when you don’t want to create a new class (you just want to record
behaviour)
12. Expando
def player = new Expando(name: 'Robert')
assert 'Robert' == player.name
player.surname = 'Lewandowski'
assert 'Lewandowski' == player.surname
player.presentYourself = {
return "Name: $name, Surname: $surname"
}
String result = player
.presentYourself()
assert 'Name: Robert, Surname: Lewandowski' == result
13. ExpandoMetaClass
A special implementation of a MetaClass that allows you to
(using closures):
● dynamically add methods,
● constructors,
● properties and static methods
14. ExpandoMetaClass
●
ExpandoMetaClass - Borrowing Methods — Borrowing methods from other classes
●
ExpandoMetaClass - Constructors — Adding or overriding constructors
●
ExpandoMetaClass Domain-Specific Language
●
ExpandoMetaClass - Dynamic Method Names — Dynamically creating method names
●
ExpandoMetaClass - GroovyObject Methods — Overriding invokeMethod, getProperty and setProperty
●
ExpandoMetaClass - Interfaces — Adding methods on interfaces
●
ExpandoMetaClass - Methods — Adding or overriding instance methods
●
ExpandoMetaClass - Overriding static invokeMethod — Overriding invokeMethod for static methods
●
ExpandoMetaClass - Properties — Adding or overriding properties
●
ExpandoMetaClass - Runtime Discovery — Overriding invokeMethod for static methods
●
ExpandoMetaClass - Static Methods — Adding or overriding static methods
16. Add that method! - watch out!
Integer.metaClass.getTimesTens = {
return 10 * delegate
}
Remember that :
● You are mixing here a method to a class not to an object
● In the same JVM all objects of that class will have that method added
to MetaClass! (You can image the downsides of this)
● It’s safer to use categories - only a block of code will have those
methods mixed in
17. MOP - find that missing method!
Taken from Venkat's
Programming Groovy 2
19. Runtime - drawbacks
● efficiency - finding if method exists
● method / property missing - people start
asking questions how can that even compile
● no IDE support
20. Abstract Syntax Tree
● Representation of the abstract syntactic structure of
source code
● Each node of the tree denotes a construct occurring in
the source code.
● The syntax is "abstract" in not representing every detail
appearing in the real syntax.
21. An abstract syntax tree for the following
code for the Euclidean algorithm:
while b ≠ 0
if a > b
a=a−b
else
b=b−a
return a
22.
23. AST Transformation
● Compile-time metaprogramming
● Bytecode manipulation
● Either global or local
○ Global in any compiler phase
○ Local in a semantic analysis phase
or later
24. Did you know that…?
Groovy compiler has 9 phases?
● Initialization
●
Parsing
●
Conversion
●
Semantic Analysis (important for Local AST transforms)
●
Canonicalization
●
Instruction Selection
●
Class Generation
●
Output
●
Finalization
27. Local AST transforms for dummies
●
●
●
●
Check the Guidebook
Define an annotation
Create an AST transform for the annotation
Build the transform
28.
29. AST transforms - not that easy :(
● Creating implementation is not trivial
○ Verify node
○ Verify preconditions
○ Make the implementation
● Use tools
○ AstBuilder from string
○ AstBuilder from code
○ AstBuilder from spec
● The code might get really messy
30.
31. Sources and recommended readings
●
●
●
●
●
Wikipedia (MonkeyPatch, MOP)
http://groovy.codehaus.org/
Groovy AST Demisitified
Groovy AST tutorials
Project Lombok for Java