In the current project that I’m working on right now, the base backend programing language is Groovy. I didn’t have the chance to work with it before, so it was a great opportunity to learn it and find its secrets.
The good news is that I had experience with Java so the syntax was pretty much similar, also Groovy runs on top of the JVM, which means that is compiled into JVM bytecode. Besides that it is great that you can add Groovy code to existing Java applications cause the generated bytecode is totally compatible with the one generated by Java.
You can use existing powerful Java libraries out of the box, even not specify data types so at the end it behaves like a dynamic language, it also performs type inference.
One of the things that amazed me was the ability to modify a classes at compilation time, before bytecode generation.
AST Transformations
AST means Abstract Syntax Tree which is composed of nodes that correspond to Groovy language constructs. The tree structure lends itself to process using visitor design pattern.
An AST Transformation is a compiler hook that Groovy provides into the compilation process, allows the manipulation of the AST during compilation prior to bytecode generation.
There are two types of AST transformations, local and global.
Local are more common, are annotation driven and indicates the AST transformation to be applied. AST is walked and AST transformation applied to nodes that are annotated with transformation annotation. Groovy comes with many local AST transformation like @ToString, @EqualsAndHashCode, etc.
Global are less common, are applied to every source unit in compilation. Uses jar file service provider mechanism to identify global AST transformations.
Implementing AST Transformation
One of the requirements of the current project was to be able to internationalize some text fields of the domain classes, allowing multi language support.
When I read the requirement, instantly came into my mind the idea of implementing it using a local transformation, marking those fields to be i18n with an annotation.
As an example, will present a domain class with some fields that will become multi language, here is the entity.
As you can see, I marked the title and text fields as internationalizable, using a custom @I18N annotation that is defined below.
@GroovyASTTransformationClass is responsible of telling the compiler what ASTTransformation should be applied when finding @I18N annotation.
The fieldName allows the developer to specify the name that the multi language field will have, next is the corresponding transformation class that will perform the work of adding the new internationalizable fields.
It implements org.codehaus.groovy.transform.ASTTransformation
The new fields are instances of I18NMap class, where the key is the iso code and the value is the text in its native language.
Hope with this little example you find AST Transformations something useful, to take into account in some situations.