CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-codehaus-groovy--groovy-all

Apache Groovy - A powerful multi-faceted programming language for the JVM platform with comprehensive module support

Pending
Overview
Eval results
Files

ast-transforms.mddocs/

AST Transformations

Groovy's AST (Abstract Syntax Tree) transformations provide compile-time code generation and modification through annotations, enabling powerful metaprogramming capabilities without runtime overhead.

Code Generation Transforms

@ToString

Automatically generates toString() method implementation.

@interface ToString {
    String[] excludes() default {}
    String[] includes() default {}
    boolean includeNames() default false
    boolean includeFields() default false
    boolean includeSuper() default false
    boolean includeSuperProperties() default false
    boolean ignoreNulls() default false
    boolean includePackage() default false
    boolean cache() default false
    boolean allProperties() default false
}

Usage examples:

import groovy.transform.ToString

@ToString
class Person {
    String name
    int age
    String email
}

@ToString(includeNames=true, excludes=['email'])
class Employee {
    String name
    int age
    String email
    String department
}

def person = new Person(name: 'John', age: 30, email: 'john@example.com')
println person.toString()  // Person(John, 30, john@example.com)

def employee = new Employee(name: 'Jane', age: 25, email: 'jane@company.com', department: 'IT')
println employee.toString()  // Employee(name:Jane, age:25, department:IT)

@EqualsAndHashCode

Generates equals() and hashCode() methods with proper implementations.

@interface EqualsAndHashCode {
    String[] excludes() default {}
    String[] includes() default {}
    boolean callSuper() default false
    boolean includeFields() default false
    boolean cache() default false
    boolean useCanEqual() default true
    boolean allProperties() default false
}

Usage example:

import groovy.transform.EqualsAndHashCode

@EqualsAndHashCode
class Point {
    int x
    int y
}

@EqualsAndHashCode(excludes=['id'])
class User {
    String id
    String name
    String email
}

def p1 = new Point(x: 10, y: 20)
def p2 = new Point(x: 10, y: 20)
assert p1 == p2
assert p1.hashCode() == p2.hashCode()

@TupleConstructor

Generates constructor accepting parameters for specified properties.

@interface TupleConstructor {
    String[] excludes() default {}
    String[] includes() default {}
    boolean includeFields() default false
    boolean includeProperties() default true
    boolean includeSuperFields() default false
    boolean includeSuperProperties() default false
    boolean callSuper() default false
    boolean force() default false
    boolean defaults() default true
    boolean useSetters() default false
    boolean allNames() default false
    boolean allProperties() default false
}

Usage example:

import groovy.transform.TupleConstructor

@TupleConstructor
class Book {
    String title
    String author
    int year
}

@TupleConstructor(includes=['name', 'age'])
class Person {
    String name
    int age
    String email = 'unknown@example.com'
}

def book = new Book('1984', 'George Orwell', 1949)
def person = new Person('John', 30)

Design Pattern Transforms

@Singleton

Implements the Singleton design pattern with various strategies.

@interface Singleton {
    String property() default 'instance'
    boolean lazy() default true
    boolean strict() default true
}

Usage examples:

import groovy.transform.Singleton

@Singleton
class DatabaseConnection {
    String url = 'jdbc:h2:mem:testdb'
    
    void connect() {
        println "Connecting to $url"
    }
}

@Singleton(lazy=false, strict=false)
class Logger {
    void log(String message) {
        println "[${new Date()}] $message"
    }
}

// Usage
DatabaseConnection.instance.connect()
Logger.instance.log('Application started')

@Immutable

Creates immutable classes with defensive copying and validation.

@interface Immutable {
    String[] excludes() default {}
    String[] includes() default {}
    boolean copyWith() default false
    boolean knownImmutableClasses() default false
    String[] knownImmutables() default {}
}

Usage example:

import groovy.transform.Immutable

@Immutable
class Point3D {
    double x, y, z
}

@Immutable(copyWith=true)
class Person {
    String name
    int age
    List<String> hobbies
}

def point = new Point3D(1.0, 2.0, 3.0)
def person = new Person('John', 30, ['reading', 'swimming'])

// Create modified copies
def olderPerson = person.copyWith(age: 31)

@Builder

Implements the Builder pattern for object construction.

@interface Builder {
    String builderClassName() default ''
    String builderMethodName() default 'builder'
    String buildMethodName() default 'build'
    String prefix() default ''
    boolean includeSuperProperties() default false
    boolean useSetters() default false
    String[] excludes() default {}
    String[] includes() default {}
    boolean allNames() default false
    boolean allProperties() default false
}

Usage example:

import groovy.transform.builder.Builder
import groovy.transform.builder.ExternalStrategy

@Builder
class Computer {
    String cpu
    String memory
    String storage
    String graphics
}

@Builder(builderStrategy=ExternalStrategy, forClass=Person)
class PersonBuilder {}

// Usage
def computer = Computer.builder()
    .cpu('Intel i7')
    .memory('16GB')
    .storage('1TB SSD')
    .graphics('NVIDIA RTX')
    .build()

Behavior Modification Transforms

@CompileStatic

Enables static compilation for improved performance and type safety.

@interface CompileStatic {
    TypeCheckingMode value() default TypeCheckingMode.PASS
    String[] extensions() default {}
}

Usage example:

import groovy.transform.CompileStatic

@CompileStatic
class Calculator {
    int add(int a, int b) {
        return a + b  // Statically compiled
    }
    
    double multiply(double x, double y) {
        return x * y  // Type-safe operations
    }
}

@TypeChecked

Enables static type checking without full static compilation.

@interface TypeChecked {
    TypeCheckingMode value() default TypeCheckingMode.PASS
    String[] extensions() default {}
}

Usage example:

import groovy.transform.TypeChecked

@TypeChecked
class StringProcessor {
    String process(String input) {
        return input.toUpperCase().trim()  // Type-checked at compile time
    }
}

@Memoized

Caches method results for improved performance with repeated calls.

@interface Memoized {
    int protectedCacheSize() default 0
    int maxCacheSize() default 0
}

Usage example:

import groovy.transform.Memoized
import groovy.transform.CompileStatic

@CompileStatic
class FibonacciCalculator {
    @Memoized
    long fibonacci(int n) {
        if (n <= 1) return n
        return fibonacci(n - 1) + fibonacci(n - 2)
    }
    
    @Memoized(maxCacheSize=100)
    double expensiveCalculation(double input) {
        // Simulate expensive computation
        Thread.sleep(1000)
        return Math.pow(input, 3) + Math.sin(input)
    }
}

@Synchronized

Provides method-level synchronization with configurable lock objects.

@interface Synchronized {
    String value() default ''
}

Usage example:

import groovy.transform.Synchronized

class Counter {
    private int count = 0
    private final Object lockA = new Object()
    private final Object lockB = new Object()
    
    @Synchronized
    void increment() {
        count++
    }
    
    @Synchronized('lockA')
    void methodA() {
        // Uses lockA for synchronization
    }
    
    @Synchronized('lockB')  
    void methodB() {
        // Uses lockB for synchronization
    }
    
    @Synchronized
    int getCount() {
        return count
    }
}

Metaprogramming Transforms

@Delegate

Implements the Delegation pattern by forwarding method calls.

@interface Delegate {
    Class[] excludeTypes() default {}
    String[] excludes() default {}
    String[] includes() default {}
    boolean deprecated() default false
    boolean allNames() default false
    boolean methodAnnotations() default false
    boolean parameterAnnotations() default false
    boolean interfaces() default true
}

Usage example:

import groovy.transform.Delegate

class EventManager {
    @Delegate List<String> events = []
    @Delegate(excludes=['clear']) Map<String, Object> properties = [:]
    
    void logEvent(String event) {
        println "Event logged: $event"
        events.add(event)
    }
}

def manager = new EventManager()
manager.add('startup')  // Delegated to List
manager.put('version', '1.0')  // Delegated to Map
// manager.clear() // Not available due to excludes

@Category

Creates category classes for adding methods to existing types.

@interface Category {
    Class value()
}

Usage example:

import groovy.transform.Category

@Category(String)
class StringExtensions {
    boolean isPalindrome() {
        return this == this.reverse()
    }
    
    String toCamelCase() {
        return this.tokenize('_').collect { 
            it.toLowerCase().capitalize() 
        }.join('')
    }
}

// Usage
use(StringExtensions) {
    assert 'racecar'.isPalindrome()
    assert 'hello_world'.toCamelCase() == 'HelloWorld'
}

@Mixin

Adds mixin capabilities to classes.

@interface Mixin {
    Class[] value()
}

@Trait

Defines and uses traits for multiple inheritance of behavior.

@interface Trait {}

Usage example:

trait Flyable {
    void fly() {
        println "${this.class.simpleName} is flying"
    }
}

trait Swimmable {
    void swim() {
        println "${this.class.simpleName} is swimming"
    }
}

class Duck implements Flyable, Swimmable {
    String name
}

class Fish implements Swimmable {
    String species
}

def duck = new Duck(name: 'Donald')
duck.fly()   // Duck is flying
duck.swim()  // Duck is swimming

def fish = new Fish(species: 'Goldfish')  
fish.swim()  // Fish is swimming

Utility Transforms

@Canonical

Combines @ToString, @EqualsAndHashCode, and @TupleConstructor.

@interface Canonical {
    String[] excludes() default {}
    String[] includes() default {}
    boolean includeFields() default false
    boolean includeProperties() default true
    boolean includeSuperFields() default false
    boolean includeSuperProperties() default false
    boolean callSuper() default false
    boolean force() default false
    boolean useSetters() default false
    boolean allNames() default false
    boolean allProperties() default false
}

Usage example:

import groovy.transform.Canonical

@Canonical
class Product {
    String name
    BigDecimal price
    String category
}

def product1 = new Product('Laptop', 999.99, 'Electronics')
def product2 = new Product('Laptop', 999.99, 'Electronics')

assert product1 == product2
println product1.toString()

@InheritConstructors

Inherits constructors from the superclass.

@interface InheritConstructors {
    boolean constructorAnnotations() default false
    boolean parameterAnnotations() default false
}

Usage example:

import groovy.transform.InheritConstructors

class CustomException extends RuntimeException {
    // Inherits all RuntimeException constructors
}

@InheritConstructors
class MyList extends ArrayList {
    // Inherits all ArrayList constructors
    
    void customMethod() {
        println "Custom functionality"
    }
}

Custom AST Transformations

Creating Custom Transforms

import org.codehaus.groovy.transform.GroovyASTTransformation
import org.codehaus.groovy.transform.ASTTransformation
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.MethodNode

@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
class LogMethodCallsTransformation implements ASTTransformation {
    
    void visit(ASTNode[] nodes, SourceUnit source) {
        // Custom transformation logic
        nodes.each { node ->
            if (node instanceof ClassNode) {
                addLoggingToMethods(node)
            }
        }
    }
    
    private void addLoggingToMethods(ClassNode classNode) {
        classNode.methods.each { MethodNode method ->
            // Add logging statements to method bodies
            // Implementation details...
        }
    }
}

// Usage annotation
@interface LogMethodCalls {}

Local AST Transformations

import org.codehaus.groovy.transform.GroovyASTTransformationClass
import java.lang.annotation.ElementType
import java.lang.annotation.Target
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy

@Retention(RetentionPolicy.SOURCE)
@Target([ElementType.TYPE])
@GroovyASTTransformationClass(["com.example.LogMethodCallsTransformation"])
@interface LogMethodCalls {}

// Apply to classes
@LogMethodCalls
class MyService {
    void processData() {
        // Method calls will be logged automatically
    }
}

Error Handling and Debugging

Compilation Errors

// Common AST transformation errors and solutions

// 1. Conflicting transformations
@ToString
@CompileStatic
class Example {
    // Some combinations may cause issues
}

// 2. Missing dependencies
@Builder // Requires specific dependencies
class MyClass {
    String property
}

// 3. Incorrect annotation usage
@Singleton(property="wrongType") // Should be String
class BadSingleton {}

Debugging AST Transformations

// Enable AST transformation debugging
System.setProperty("groovy.ast.debug", "true")

// Use AST viewer tools to inspect generated code
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.control.CompilerConfiguration

def config = new CompilerConfiguration()
config.debug = true
config.verbose = true

// Examine generated bytecode
import groovy.transform.ToString

@ToString
class DebugExample {
    String name
    int value
}

// The generated toString method can be inspected
def example = new DebugExample(name: 'test', value: 42)
println example.toString()

Install with Tessl CLI

npx tessl i tessl/maven-org-codehaus-groovy--groovy-all

docs

ast-transforms.md

cli.md

core-language.md

index.md

json.md

sql.md

swing.md

templates.md

xml.md

tile.json