Código dinâmico com Groovy AST Transformations

O que são AST Transformations?

Antes de transformar código fonte em byte codes, o compilador Groovy nos fornece alguns hooks para que possamos gerar código customizado.

Exemplos de Transformations do próprio Groovy

O próprio Groovy já possui algumas anotações que são processadas por AST Transformations.

  • @EqualsAndHashCode: adiciona equals() e hashCode()
  • @Log: adiciona uma instância de log
  • @Immutable: faz com que um bean seja imutável

Criando a anotação @JPAEntity

É uma anotação como qualquer outra. A unica coisa que devemos fazer diferente é anotá-la com @GroovyASTTransformationClass, especificando qual classe vai processá-la.

Criando JPAEntityASTTransformation

Criar uma ASTTransformation envolve implementar o método void visit(ASTNode[] nodes, SourceUnit sourceUnit). Você recebe a árvore de compilação ASTNode, que é uma representação estrutural do seu código fonte. Nosso objetivo é adicionar a ela novos nós que representam novos trechos de código.

1. Esqueleto da classe

  • Por comodidade, estendemos AbstractASTTransformation em vez de implementarmos diretamente ASTTransformation; ela nos fornece alguns métodos convenientes.
  • @CompileStatic melhora o desempenho do transformador na compilação.
  • phase: Na fase CANONICALIZATION, a árvore AST completa e está sendo pós-processada. Em geral, usamos esta fase. Para mais detalhes, veja a documentação oficial.

2. Gerando código boilerplate a partir de uma String

Aqui, escrevemos todo o código que queremos adicionar à nossa entidade anotada com JPAEntity.

3. Modificando a árvore AST

Por fim, devemos adicionar à árvore original os nós gerados na etapa anterior. Esta parte é bem simples e envolve apenas manipular algumas listas.

Utilizando a Transformation

Agora basta anotarmos qualquer classe com @JPAEntity e ela se torna uma entidade com:

  • equals e hashCode implementados a partir do id
  • @Entity usando full qualified name da classe
  • @Table usando o nome simples da classe mais um número aleatório de 6 dígitos
  • implementação de Serializable

Teste unitário

Ao escrever uma ASTTransformation, é importante termos uma maneira de testá-la rapidamente. Para isso, vamos criar um teste unitário e invocar manualmente o compilador Groovy.

Conclusão

AST Transformations são uma forma relativamente simples e poderosa de deixar nosso código Groovy mais limpo e fácil de entender. Permite-nos também reaproveitar código de maneira transparente e flexível.

thdesenvolvedores

Blog de desenvolvimento da Touch Health

Bruno Viana

Written by

thdesenvolvedores

Blog de desenvolvimento da Touch Health