All Downloads are FREE. Search and download functionalities are using the official Maven repository.

groovy.transform.NamedVariant Maven / Gradle / Ivy

The newest version!
/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package groovy.transform;

import org.apache.groovy.lang.annotation.Incubating;
import org.codehaus.groovy.transform.GroovyASTTransformationClass;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Allows construction of a named-arg equivalent method or constructor.
 * The method or constructor will have at least a first argument of type
 * {@code 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 {@code @NamedParam} annotations to explicitly identify such parameters
  2. *
  3. Use one or more {@code @NamedDelegate} annotations to explicitly identify such parameters as * delegate parameters
  4. *
  5. If no parameters with {@code @NamedParam} or {@code @NamedDelegate} annotations are found then: *
      *
    • If {@code autoDelegate} is false (the default), all parameters are treated as if they were named parameters
    • *
    • If {@code autoDelegate} is true, the first parameters is treated as if it was a delegate parameter
    • *
    *
  6. *
* You can also mix and match the {@code @NamedParam} and {@code @NamedDelegate} annotations. * * Named arguments will be supplied via the map with their property name (configurable via * annotation attributes within {@code @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 {@code as} cast operation from a {@code Map}. * * Here is an example using implicit named parameters. *
 * import groovy.transform.*
 *
 * {@code @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.*
 *
 * {@code @ToString(includeNames=true)}
 * class Color {
 *     Integer r, g, b
 * }
 *
 * {@code @NamedVariant}
 * String foo({@code @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 {@code shade} argument with the {@code @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 {@link 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. * * @see VisibilityOptions * @see NamedParam * @see NamedDelegate * @since 2.5.0 */ @Incubating @Retention(RetentionPolicy.SOURCE) @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) @GroovyASTTransformationClass("org.codehaus.groovy.transform.NamedVariantASTTransformation") public @interface NamedVariant { /** * If specified, must match the optional "id" attribute in an applicable {@code VisibilityOptions} annotation. */ String visibilityId() default Undefined.STRING; /** * If true, add an implicit {@code @NamedDelegate} to the first parameter if no {@code @NamedDelegate} or {@code @NamedParam} annotations are found on any parameter. * * @since 2.5.3 */ boolean autoDelegate() default false; /** * If true, will use {@code as} to convert map parameter to required class * * @since 3.0.6 */ boolean coerce() default false; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy