Groovy se trata de un compilador con nueve etapas distintas que pasan desde la lectura de los archivos hasta la final escritura del bytecode. Para la compilación, se crea un árbol de sintaxis abstracto (AST – Abstract Syntax Tree), que se trata de un árbol con nodos y hojas representativos del código.
Groovy se encarga de modificar este árbol hasta que se convierte en un bytecode ejecutable. Por ello, las alteraciones en el AST son llamadas Transformaciones AST, y permiten la intervención en la generación de nuestro AST para cambiar el bytecode final.
Sin embargo, la tarea no es escribir bytecode; eso es tarea del compilador. Nuestro rol es la modificación del AST para la adición de nodos nuevos.
La creación de estas alteraciones no es algo fácil gracias a que necesita de un extenso conocimiento de los “internals” en Groovy y de cómo es representado el código en los AST. Esto requerirá saber sobre todas las clases usadas por el compilador para la representación.
Por otro lado, esta técnica posee ventajas por encima de la metaprogramación en “runtime” ya que los cambios son visibles en el bytecode. Por lo tanto, los cambios serán visibles a la hora de llamarlo desde lenguajes como Java, mientras que en el otro caso sólo se verían desde Groovy.
Gracias que no necesitaremos utilizar Groovy para entender la modificación, el rendimiento de nuestro equipo será mejor y más eficiente.
Además, para adaptarse a nuestras necesidades, Groovy permite dos tipos de transformaciones AST distintas.
Las primeras son las globales, que son aplicadas al código en su totalidad, sin necesitar marcar el código que buscamos alterar. Lo importante es recordar que el cambio afecta al código completo, por lo que el impacto puede ser bastante grande.
Las otras son locales, donde necesitaremos anotar el código específico que buscamos transformar. Por ello, tienden a ser más comunes aún si no se pueden aplicar en la totalidad de las fases del compilador.