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

groovy.lang.Category 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.lang;

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;

/**
 * Transforms an instance-style Groovy class or interface to become a static-style
 * conventional Groovy category.
 * 

* Groovy categories are the original mechanism used * by Groovy when augmenting classes with new methods. Writing categories required * using a class writing style where all methods were static and an additional * self parameter was defined. The self parameter and static nature of the methods * disappeared once applied by Groovy's metaclass framework but some regarded * the writing style as a little noisy. This transformation allows you to write * your categories without the "apparent noise" but adds it back in during * compilation so that the classes appear as normal categories. *

* It might seem strange writing your class/object enhancements using a succinct * notation, then having "noise" added, then having the noise removed during * category application. If this worries you, then you may also like to consider * using Groovy's {@code ExpandoMetaClass} mechanism which avoids * the category definition altogether. If you already have an investment in * categories or like some of the other features which categories currently give you, * then read on. *

* The mechanics: during compilation, all methods are transformed to static ones with an additional * self parameter of the type you supply as the annotation parameter (the default type * for the self parameters is {@code Object} which might be more broad reaching than * you like so it is usually wise to specify a type). * Properties invoked using 'this' references are transformed so that * they are instead invoked on the additional self parameter and not on * the Category instance. (Remember that once the category is applied, the reverse * will occur and we will be back to conceptually having methods on the {@code this} * references again!) *

* Classes conforming to the conventional Groovy category conventions can be used * within {@code use} statements or mixed in at runtime with the {@code mixin} method on classes. *

* An example showing a {@code use} statement (allowing fine-grained application of * the category methods): *

 * {@code @Category}(Integer)
 * class IntegerOps {
 *     def triple() {
 *         this * 3
 *     }
 * }
 *
 * use (IntegerOps) {
 *     assert 25.triple() == 75
 * }
 * 
* Or, "mixing in" your methods at runtime: *
 * {@code @Category}(List)
 * class Shuffler {
 *     def shuffle() {
 *         def result = new ArrayList(this)
 *         Collections.shuffle(result)
 *         result
 *     }
 * }
 *
 * class Sentence extends ArrayList {
 *     Sentence(Collection initial) { super(initial) }
 * }
 * Sentence.mixin Shuffler
 *
 * def words = ["The", "quick", "brown", "fox"]
 * println new Sentence(words).shuffle()
 * // => [quick, fox, The, brown]       (order will vary)
 * 
* * @author Alex Tkachman */ @java.lang.annotation.Documented @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) @GroovyASTTransformationClass("org.codehaus.groovy.transform.CategoryASTTransformation") public @interface Category { Class value () default Object.class; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy