Package: groovy.transform

## [Java] Annotation Type NamedVariant

- groovy.transform.NamedVariant

-     @Documented
      @Retention(RetentionPolicy.SOURCE)
      @Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
      public @interface NamedVariant

  Allows construction of a named-arg equivalent method or constructor. The method or constructor will have at least a first argument of type `Map` and may have more arguments. As such, it can be called using Groovy's named-arg syntax. The original method/constructor is retained and is called by the generated method/constructor. One benefit of this approach is the potential for improved type checking. The annotated "tuple" method/constructor can be type rich and will be checked as such during normal compilation. The generated method/constructor using the map argument will be named-argument friendly but the map also hides type information. The generated method however contains no business logic so the chance of errors is minimal. Any arguments identified as named arguments will be supplied as part of the map. Any additional arguments are supplied in the normal tuple style. Named parameters are identified in one of three ways:

  1. Use one or more `@NamedParam` annotations to explicitly identify such parameters
  2. Use one or more `@NamedDelegate` annotations to explicitly identify such parameters as delegate parameters
  3. If no parameters with `@NamedParam` or `@NamedDelegate` annotations are found then:
     - If `autoDelegate` is false (the default), all parameters are treated as if they were named parameters
     - If `autoDelegate` is true, the first parameter is treated as if it is a delegate parameter
  You can also mix and match the `@NamedParam` and `@NamedDelegate` annotations. Named arguments will be supplied via the map with their property name (configurable via annotation attributes within `@NamedParam`) being the key and value being the argument value. For named delegates, any properties of the delegate can become map keys. Duplicate keys across delegate properties or named parameters are not allowed. The type of delegate parameters must be compatible with Groovy's `as` cast operation from a `Map`. Here is an example using implicit named parameters.

       import groovy.transform.*

       @NamedVariant
       int makeSense(int dollars, int cents) {
           100 * dollars + cents
       }

       assert makeSense(dollars: 2, cents: 50) == 250

  Here is an example using a delegate parameter.

       import groovy.transform.*

       @ToString(includeNames=true)
       class Color {
           Integer r, g, b
       }

       @NamedVariant
       String foo(@NamedDelegate Color shade) {
           shade
       }

       def result = foo(g: 12, b: 42, r: 12)
       assert result.toString() == 'Color(r:12, g:12, b:42)'

  You could also explicitly annotate the `shade` argument with the `@NamedDelegate` annotation if you wanted. The generated method will be something like this:

       String foo(Map args) {
           return foo(args as Color)
       }

  The generated method/constructor retains the visibility and return type of the original method/constructor but the VisibilityOptions annotation can be added to customize the visibility. You could have the annotated method/constructor private for instance but have the generated one be public.

  Joint compilation note: the variant exposed to Java callers in the same compilation unit is the simple all-Map form (`returnType methodName(Map namedArgs)`, or `ClassName(Map)` for constructors). Mixed configurations using `@NamedParam` or `@NamedDelegate` alongside positional parameters produce a richer positional-plus-Map signature at runtime; the stub form is a strict subset. Java callers using the all-Map form compile and run; callers needing the positional-plus-Map form should call from Groovy or supply a hand-written delegating method.

  See Also:
    VisibilityOptions
    NamedParam
    NamedDelegate
  Since:
    2.5.0

- - ### Element Summary

    Optional Element Summary
    Type | Name and Description
    --- | ---
    `boolean` | `autoDelegate` If true, add an implicit `@NamedDelegate` to the first parameter if no `@NamedDelegate` or `@NamedParam` annotations are found on any parameter.
    `boolean` | `coerce` If true, will use `as` to convert map parameter to required class
    `String` | `visibilityId` If specified, must match the optional "id" attribute in an applicable `VisibilityOptions` annotation.

  - ### Inherited Methods Summary

    Inherited Methods
    Methods inherited from class | Name
    --- | ---
    `class Object` | `equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Element Detail

    - #### public boolean autoDelegate

      If true, add an implicit `@NamedDelegate` to the first parameter if no `@NamedDelegate` or `@NamedParam` annotations are found on any parameter.

      Since:
        2.5.3
      Default:
        false

    - #### public boolean coerce

      If true, will use `as` to convert map parameter to required class

      Since:
        3.0.6
      Default:
        false

    - #### public String visibilityId

      If specified, must match the optional "id" attribute in an applicable `VisibilityOptions` annotation.

      Default:
        Undefined.STRING