Search code examples
groovynamed-parameters

Groovy named parameters in traits


Given example with @NamedVariant groovy transform - everything works as expected:

import groovy.transform.NamedVariant

class A {
    @NamedVariant
    def func(String key1 = "val1", String key2 = "val2") {
        print "key1=$key1, key=$key2"
    }
}

new A().func(key2: "xxx")

but when I move the func to a trait like this:

import groovy.transform.NamedVariant

class A implements B {}

trait B {
    @NamedVariant
    def func(String key1 = "val1", String key2 = "val2") {
        print "key1=$key1, key=$key2"
    }
}

new A().func(key2: "xxx")

It fails to compile with this error message:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
ideaGroovyConsole.groovy: -1: Error during @NamedVariant processing. Class B$Trait$Helper already has a named-arg method of type [org.codehaus.groovy.ast.Parameter@6fd1660[name: namedArgs, type: java.util.Map, hasDefaultValue: false]]
 @ line -1, column -1.

Does groovy support @NamedVariant transform inside traits or am I doing something wrong?


Solution

  • Quoting the groovy docs on traits and AST transformations:

    Traits are not officially compatible with AST transformations. Some of them, like @CompileStatic will be applied on the trait itself (not on implementing classes), while others will apply on both the implementing class and the trait. There is absolutely no guarantee that an AST transformation will run on a trait as it does on a regular class, so use it at your own risk!

    NamedVariant is an AST transformation which in essence means that the groovy docs are telling us there is no guarantee this will work.

    We can validate that NamedVariant is an AST transformation by looking at the source for NamedVariant here and here.