You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2017/12/20 04:29:39 UTC

[31/47] groovy git commit: Move source files to proper packages

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/ASTTest.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/ASTTest.java b/src/main/groovy/groovy/transform/ASTTest.java
new file mode 100644
index 0000000..1cdb480
--- /dev/null
+++ b/src/main/groovy/groovy/transform/ASTTest.java
@@ -0,0 +1,71 @@
+/*
+ *  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.codehaus.groovy.control.CompilePhase;
+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;
+
+/**
+ * This AST transformation aims at helping in debugging other AST transformations. It provides a basic
+ * infrastructure for performing tests on AST nodes. You can place this annotation on any node which
+ * accepts an annotation (types, methods, annotations, constructors, fields, local variables, packages
+ * or parameters), then use a script which is run against this AST node at a specific phase. For example,
+ * you could test the {@link Field} AST transformation this way:
+ *
+ * <pre class="groovyTestCase">
+ * import groovy.transform.*
+ *
+ * {@code @ASTTest}(value = {
+ *    def owner = node.declaringClass
+ *    assert owner.fields.any { it.name == 'x' }
+ *  })
+ * {@code @Field int x}
+ *
+ * </pre>
+ *
+ * The closure code is executed after the specified phase has completed. If no phase is selected, then the
+ * code is executed after the {@link org.codehaus.groovy.control.CompilePhase#SEMANTIC_ANALYSIS semantic analysis} phase.
+ * The <code>node</code> variable refers to the AST node where the AST test annotation is put. In the previous example,
+ * it means that <i>node</i> refers to the declaration node (int x).
+ *
+ * @author Cedric Champeau
+ * @since 2.0.0
+ *
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD,
+ElementType.LOCAL_VARIABLE, ElementType.PACKAGE, ElementType.PARAMETER})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.ASTTestTransformation")
+public @interface ASTTest {
+    /**
+     * The compile phase after which the test code should run.
+     */
+    CompilePhase phase() default CompilePhase.SEMANTIC_ANALYSIS;
+
+    /**
+     * A closure which is executed against the annotated node after the specified phase has completed.
+     */
+    Class value();
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/AnnotationCollector.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/AnnotationCollector.java b/src/main/groovy/groovy/transform/AnnotationCollector.java
new file mode 100644
index 0000000..b9f2161
--- /dev/null
+++ b/src/main/groovy/groovy/transform/AnnotationCollector.java
@@ -0,0 +1,199 @@
+/*
+ *  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 java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The AnnotationCollector can be used to define aliases for groups of 
+ * annotations. The Alias needs to be a class or annotation annotated with 
+ * AnnotationCollector, otherwise nothing is required. The alias will be 
+ * replaced on the AST level and will never appear in later. Any members of the 
+ * class or annotation will be ignored, but could be used by a custom processor.
+ * Annotation arguments are mapped to the aliased annotations
+ * if existing. Should the default processor not be able to map one of the
+ * arguments and error will be given. Is this not wished or if you want a 
+ * different mapping a custom processor has to be used. There are two ways of 
+ * using the alias. The first way is by providing the annotations as list/array:
+ * <pre class="groovyTestCase">
+ *          import groovy.transform.*
+ *          &#64;AnnotationCollector([ToString, EqualsAndHashCode, Immutable])
+ *          &#64;interface Alias {}
+
+ *          &#64;Alias(excludes=["a"])
+ *          class Foo {
+ *              Integer a, b
+ *          }
+ *          assert Foo.class.annotations.size()==3 
+ *          assert new Foo(1,2).toString() == "Foo(2)"
+ * </pre>
+ * In the example above we have Alias as the alias annotation and an argument
+ * excludes which will be mapped to ToString and EqualsAndHashCode. Immutable 
+ * doesn't have excludes, thus nothing will be done there.<br>
+ * The other way is to add annotations to the alias:
+ * <pre class="groovyTestCase">
+ * import groovy.transform.*
+ * &#64;ToString(excludes=["a"])
+ * &#64;EqualsAndHashCode
+ * &#64;Immutable
+ * &#64;AnnotationCollector
+ * &#64;interface Alias {}
+ *
+ * &#64;Alias
+ * class Foo {
+ *     Integer a, b
+ * }
+ * assert Foo.class.annotations.size()==3
+ * assert new Foo(1,2).toString() == "Foo(2)"
+ * </pre>
+ * In the example above we have again Alias as the alias annotation, but
+ * this time the argument is part of the alias. Instead of mapping excludes to
+ * ToString as well as EqualsAndHashCode, only ToString will have the excludes.
+ * Again the alias can have an argument excludes, which would overwrite the 
+ * excludes given in from the definition and be mapped to ToString as well as
+ * EqualsAndHashCode.
+ * If both ways are combined, then the list overwrites annotation usage.
+ * NOTE: The aliasing does not support aliasing of aliased annotations. 
+ * <p>More examples:</p>
+ * <pre class="groovyTestCase">
+ * //--------------------------------------------------------------------------
+ * import groovy.transform.*
+ * &#64;AnnotationCollector([EqualsAndHashCode, ToString])
+ * &#64;interface Simple {}
+ *
+ *
+ * &#64;Simple
+ * class User {
+ *     String username
+ *     int age
+ * }
+ *
+ * def user = new User(username: 'mrhaki', age: 39)
+ * assert user.toString() == 'User(mrhaki, 39)'
+ *
+ * // We still have 2 annotations:
+ * assert User.class.annotations.size() == 2
+ *
+ *
+ * // We can use the attributes from the 
+ * // grouped annotations.
+ * &#64;Simple(excludes = 'street')
+ * class Address {
+ *     String street, town
+ * }
+ *
+ * def address = new Address(street: 'Evergreen Terrace', town: 'Springfield') 
+ * assert address.toString() == 'Address(Springfield)'
+ * </pre>
+ * <pre class="groovyTestCase">
+ * //--------------------------------------------------------------------------
+ * // Use a custom processor to handle attributes.
+ * import org.codehaus.groovy.transform.*
+ * import org.codehaus.groovy.ast.*
+ * import org.codehaus.groovy.control.*
+ *
+ * class SimpleProcessor extends AnnotationCollectorTransform {
+ *
+ *     public List&lt;AnnotationNode&gt; visit(AnnotationNode collector, 
+ *                                       AnnotationNode aliasAnnotationUsage, 
+ *                                       AnnotatedNode aliasAnnotated, 
+ *                                       SourceUnit source) {
+ *
+ *         // Get attributes and attribute value for dontUse.
+ *         def attributes = aliasAnnotationUsage.getMembers()
+ *         def dontUse = attributes.get('dontUse')
+ *         attributes.remove('dontUse')
+ *
+ *         if (dontUse) {
+ *             // Assign value of dontUse to excludes attributes.
+ *             aliasAnnotationUsage.addMember("excludes", dontUse)
+ *         }
+ *
+ *         super.visit(collector, aliasAnnotationUsage, aliasAnnotated, source)
+ *     }
+ *
+ * }
+ *
+ * new GroovyShell(this.class.classLoader).evaluate '''
+ * import groovy.transform.*
+ *
+ * &#64;AnnotationCollector(value = [EqualsAndHashCode, ToString], processor = 'SimpleProcessor')
+ * &#64;interface Simple {}
+ *
+ *
+ * &#64;Simple(dontUse = 'age')
+ * class User {
+ *     String username
+ *     int age
+ * }
+ *
+ * def user = new User(username: 'mrhaki', age: 39)
+ * assert user.toString() == 'User(mrhaki)'
+ * '''
+ * </pre>
+ * <pre class="groovyTestCase">
+ * //--------------------------------------------------------------------------
+ * // Use AnnotationCollector as last annotation to group the
+ * // previous annotations.
+ * import groovy.transform.*
+ * &#64;EqualsAndHashCode
+ * &#64;ToString
+ * &#64;AnnotationCollector
+ * &#64;interface Simple {}
+ *
+ *
+ * &#64;Simple
+ * class User {
+ *     String username
+ * }
+ *
+ * def user = new User(username: 'mrhaki')
+ * assert user.toString() == 'User(mrhaki)'
+ * </pre>
+ * 
+ * @author <a href="mailto:blackdrag@gmx.org">Jochen "blackdrag" Theodorou</a>
+ * @see org.codehaus.groovy.transform.AnnotationCollectorTransform
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
+public @interface AnnotationCollector {
+    /**
+     * Processor used for computing custom logic or the list of annotations, or 
+     * both. The default is org.codehaus.groovy.transform.AnnotationCollectorTransform.
+     * Custom processors need to extend that class. 
+     */
+    String processor() default "org.codehaus.groovy.transform.AnnotationCollectorTransform";
+
+    /**
+     * When the collector annotation is replaced, whether to check for duplicates between
+     * the replacement annotations and existing explicit annotations.
+     * If you use a custom processor, it is up to that processor whether it honors or ignores
+     * this parameter. The default processor honors the parameter.
+     */
+    AnnotationCollectorMode mode() default AnnotationCollectorMode.DUPLICATE;
+
+    /**
+     * List of aliased annotations.
+     */
+    Class[] value() default {};
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/AnnotationCollectorMode.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/AnnotationCollectorMode.java b/src/main/groovy/groovy/transform/AnnotationCollectorMode.java
new file mode 100644
index 0000000..308d0c0
--- /dev/null
+++ b/src/main/groovy/groovy/transform/AnnotationCollectorMode.java
@@ -0,0 +1,50 @@
+/*
+ * 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;
+
+public enum AnnotationCollectorMode {
+    // TODO should we support @Repeatable from Java 8?
+    /**
+     * Annotations from the annotation collection will always be inserted. After all transforms have been run, it will
+     * be an error if multiple annotations (excluding those with SOURCE retention) exist.
+     */
+    DUPLICATE,
+
+    /**
+     * Annotations from the collector will be added and any existing annotations with the same name will be removed.
+     */
+    PREFER_COLLECTOR,
+
+    /**
+     * Annotations from the collector will be ignored if any existing annotations with the same name are found.
+     */
+    PREFER_EXPLICIT,
+
+    /**
+     * Annotations from the collector will be added and any existing annotations with the same name will be removed but any new parameters found within existing annotations will be merged into the added annotation.
+     */
+    PREFER_COLLECTOR_MERGED,
+
+    /**
+     * Annotations from the collector will be ignored if any existing annotations with the same name are found but any new parameters on the collector annotation will be added to existing annotations.
+     */
+    PREFER_EXPLICIT_MERGED
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/AutoClone.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/AutoClone.java b/src/main/groovy/groovy/transform/AutoClone.java
new file mode 100644
index 0000000..995a187
--- /dev/null
+++ b/src/main/groovy/groovy/transform/AutoClone.java
@@ -0,0 +1,281 @@
+/*
+ *  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.codehaus.groovy.transform.GroovyASTTransformationClass;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Class annotation used to assist in the creation of {@code Cloneable} classes.
+ * The {@code @AutoClone} annotation instructs the compiler to execute an
+ * AST transformation which adds a public {@code clone()} method and adds
+ * {@code Cloneable} to the list of interfaces which the class implements.
+ * <p>
+ * Because the JVM doesn't have a one-size fits all cloning strategy, several
+ * customizations exist for the cloning implementation. By default, the {@code clone()}
+ * method will call {@code super.clone()} before calling {@code clone()} on each
+ * {@code Cloneable} property of the class.
+ * <p>
+ * Example usage:
+ * <pre>
+ * import groovy.transform.AutoClone
+ * {@code @AutoClone}
+ * class Person {
+ *   String first, last
+ *   List favItems
+ *   Date since
+ * }
+ * </pre>
+ * Which will create a class equivalent to the following:
+ * <pre>
+ * class Person implements Cloneable {
+ *   ...
+ *   public Person clone() throws CloneNotSupportedException {
+ *     Person result = (Person) super.clone()
+ *     result.favItems = favItems instanceof Cloneable ? (List) favItems.clone() : favItems
+ *     result.since = (Date) since.clone()
+ *     return result
+ *   }
+ *   ...
+ * }
+ * </pre>
+ * Which can be used as follows:
+ * <pre>
+ * def p = new Person(first:'John', last:'Smith', favItems:['ipod', 'shiraz'], since:new Date())
+ * def p2 = p.clone()
+ *
+ * assert p instanceof Cloneable
+ * assert p.favItems instanceof Cloneable
+ * assert p.since instanceof Cloneable
+ * assert !(p.first instanceof Cloneable)
+ *
+ * assert !p.is(p2)
+ * assert !p.favItems.is(p2.favItems)
+ * assert !p.since.is(p2.since)
+ * assert p.first.is(p2.first)
+ * </pre>
+ * In the above example, {@code super.clone()} is called which in this case
+ * calls {@code clone()} from {@code java.lang.Object}. This does a bit-wise
+ * copy of all the properties (references and primitive values). Properties
+ * like {@code first} has type {@code String} which is not {@code Cloneable}
+ * so it is left as the bit-wise copy. Both {@code Date} and {@code ArrayList}
+ * are {@code Cloneable} so the {@code clone()} method on each of those properties
+ * will be called. For the list, a shallow copy is made during its {@code clone()} method.
+ * <p>
+ * If your classes require deep cloning, it is up to you to provide the appropriate
+ * deep cloning logic in the respective {@code clone()} method for your class.
+ * <p>
+ * If one of your properties contains an object that doesn't support cloning
+ * or attempts deep copying of a data structure containing an object that
+ * doesn't support cloning, then a {@code CloneNotSupportedException} may occur
+ * at runtime.
+ * <p>
+ * Another popular cloning strategy is known as the copy constructor pattern.
+ * If any of your fields are {@code final} and {@code Cloneable} you should set
+ * {@code style=COPY_CONSTRUCTOR} which will then use the copy constructor pattern.
+ * Here is an example making use of the copy constructor pattern:
+ * <pre>
+ * import groovy.transform.AutoClone
+ * import static groovy.transform.AutoCloneStyle.*
+ * {@code @AutoClone(style=COPY_CONSTRUCTOR)}
+ * class Person {
+ *   final String first, last
+ *   final Date birthday
+ * }
+ * {@code @AutoClone(style=COPY_CONSTRUCTOR)}
+ * class Customer extends Person {
+ *   final int numPurchases
+ *   final List favItems
+ * }
+ * </pre>
+ * Which will create classes equivalent to the following:
+ * <pre>
+ * class Person implements Cloneable {
+ *   ...
+ *   protected Person(Person other) throws CloneNotSupportedException {
+ *     first = other.first
+ *     last = other.last
+ *     birthday = (Date) other.birthday.clone()
+ *   }
+ *   public Person clone() throws CloneNotSupportedException {
+ *     return new Person(this)
+ *   }
+ *   ...
+ * }
+ * class Customer extends Person {
+ *   ...
+ *   protected Customer(Customer other) throws CloneNotSupportedException {
+ *     super(other)
+ *     numPurchases = other.numPurchases
+ *     favItems = other.favItems instanceof Cloneable ? (List) other.favItems.clone() : other.favItems
+ *   }
+ *   public Customer clone() throws CloneNotSupportedException {
+ *     return new Customer(this)
+ *   }
+ *   ...
+ * }
+ * </pre>
+ * If you use this style on a child class, the parent class must
+ * also have a copy constructor (created using this annotation or by hand).
+ * This approach can be slightly slower than the traditional cloning approach
+ * but the {@code Cloneable} fields of your class can be final. When using the copy constructor style,
+ * you can provide your own custom constructor by hand if you wish. If you do so, it is up to you to
+ * correctly copy, clone or deep clone the properties of your class.
+ * <p>
+ * As a variation of the last two styles, if you set {@code style=SIMPLE}
+ * then the no-arg constructor will be called followed by setting the
+ * individual properties (and/or fields) calling {@code clone()} if the
+ * property/field implements {@code Cloneable}. Here is an example:
+ * <pre>
+ * import groovy.transform.AutoClone
+ * import static groovy.transform.AutoCloneStyle.*
+ * {@code @AutoClone(style=SIMPLE)}
+ * class Person {
+ *   final String first, last
+ *   final Date birthday
+ * }
+ * {@code @AutoClone(style=SIMPLE)}
+ * class Customer {
+ *   final List favItems
+ * }
+ * </pre>
+ * Which will create classes equivalent to the following:
+ * <pre>
+ * class Person implements Cloneable {
+ *   ...
+ *   public Person clone() throws CloneNotSupportedException {
+ *     def result = new Person()
+ *     copyOrCloneMembers(result)
+ *     return result
+ *   }
+ *   protected void copyOrCloneMembers(Person other) {
+ *     other.first = first
+ *     other.last = last
+ *     other.birthday = (Date) birthday.clone()
+ *   }
+ *   ...
+ * }
+ * class Customer extends Person {
+ *   ...
+ *   public Customer clone() throws CloneNotSupportedException {
+ *     def result = new Customer()
+ *     copyOrCloneMembers(result)
+ *     return result
+ *   }
+ *   protected void copyOrCloneMembers(Customer other) {
+ *     super.copyOrCloneMembers(other)
+ *     other.favItems = favItems instanceof Cloneable ? (List) favItems.clone() : favItems
+ *   }
+ *   ...
+ * }
+ * </pre>
+ * You would typically use this style only for base classes where you didn't
+ * want the normal {@code Object} {@code clone()} method to be called and
+ * you would typically need to use the {@code SIMPLE} style for any child classes.
+ * <p>
+ * As a final example, if your class already implements the {@code Serializable}
+ * or {@code Externalizable} interface, you can choose the following cloning style:
+ * <pre>
+ * {@code @AutoClone(style=SERIALIZATION)}
+ * class Person implements Serializable {
+ *   String first, last
+ *   Date birthday
+ * }
+ * </pre>
+ * which outputs a class with the following form:
+ * <pre>
+ * class Person implements Cloneable, Serializable {
+ *   ...
+ *   Person clone() throws CloneNotSupportedException {
+ *     def baos = new ByteArrayOutputStream()
+ *     baos.withObjectOutputStream{ it.writeObject(this) }
+ *     def bais = new ByteArrayInputStream(baos.toByteArray())
+ *     bais.withObjectInputStream(getClass().classLoader){ (Person) it.readObject() }
+ *   }
+ *   ...
+ * }
+ * </pre>
+ * This will output an error if your class doesn't implement one of
+ * {@code Serializable} or {@code Externalizable}, will typically be
+ * significantly slower than the other approaches, also doesn't
+ * allow fields to be final, will take up more memory as even immutable classes
+ * like String will be cloned but does have the advantage that it performs
+ * deep cloning automatically.
+ * <p>
+ * Further references on cloning:
+ * <ul>
+ * <li><a href="http://www.codeguru.com/java/tij/tij0128.shtml">http://www.codeguru.com/java/tij/tij0128.shtml</a>
+ * <li><a href="http://www.artima.com/objectsandjava/webuscript/ClonCollInner1.html">http://www.artima.com/objectsandjava/webuscript/ClonCollInner1.html</a>
+ * <li><a href="http://courses.dce.harvard.edu/~cscie160/JDCTipsCloning">http://courses.dce.harvard.edu/~cscie160/JDCTipsCloning</a>
+ * <li><a href="http://www.agiledeveloper.com/articles/cloning072002.htm">http://www.agiledeveloper.com/articles/cloning072002.htm</a>
+ * </ul>
+ *
+ * @author Paul King
+ * @see AutoCloneStyle
+ * @see ExternalizeMethods
+ * @since 1.8.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.AutoCloneASTTransformation")
+public @interface AutoClone {
+    /**
+     * Comma separated list of property (and/or field) names to exclude from cloning.
+     * For convenience, a String with comma separated names can be used in addition
+     * to an array (using Groovy's literal list notation) of String values.
+     * <p>
+     * NOTE: When using the {@code CLONE} style, property (and/or field) copying might occur as part of
+     * calling {@code super.clone()} which will ignore this list. You can then use this list to
+     * streamline the provided {@code clone()} implementation by selecting which Cloneable properties
+     * (and/or fields) will have a subsequent call to their {@code clone()} method. If you have
+     * immutable properties (and/or fields) this can be useful as the extra {@code clone()} will
+     * not be necessary and cloning will be more efficient.
+     * <p>
+     * NOTE: This doesn't affect property (and/or field) copying that might occur as part
+     * of serialization when using the {@code SERIALIZATION} style, i.e. this flag is ignored;
+     * instead adjust your serialization code to include or exclude the desired
+     * properties (and/or fields) which should carry over during cloning.
+     */
+    String[] excludes() default {};
+
+    /**
+     * Include fields as well as properties when cloning.
+     * <p>
+     * NOTE: When using the {@code CLONE} style, field copying might occur as part of
+     * calling {@code super.clone()} and might be all you require; if you turn on
+     * this flag, the provided {@code clone()} implementation will also
+     * subsequently call {@code clone()} for each {@code Cloneable} field which can be
+     * useful if you have mutable fields.
+     * <p>
+     * NOTE: This doesn't affect field copying that might occur as part of
+     * serialization when using the {@code SERIALIZATION} style, i.e. this flag is ignored;
+     * instead adjust your serialization code to include or exclude your fields.
+     */
+    boolean includeFields() default false;
+
+    /**
+     * Style to use when cloning.
+     */
+    AutoCloneStyle style() default AutoCloneStyle.CLONE;
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/AutoCloneStyle.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/AutoCloneStyle.java b/src/main/groovy/groovy/transform/AutoCloneStyle.java
new file mode 100644
index 0000000..81b0ebd
--- /dev/null
+++ b/src/main/groovy/groovy/transform/AutoCloneStyle.java
@@ -0,0 +1,48 @@
+/*
+ *  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;
+
+/**
+ * Intended style to use for cloning when using the {@code @}AutoClone annotation.
+ *
+ * @author Paul King
+ * @since 1.8.0
+ * @see groovy.transform.AutoClone
+ */
+public enum AutoCloneStyle {
+    /**
+     * Uses only cloning.
+     */
+    CLONE,
+
+    /**
+     * Uses the no-arg constructor followed by property/field copying/cloning.
+     */
+    SIMPLE,
+
+    /**
+     * Uses the copy constructor pattern.
+     */
+    COPY_CONSTRUCTOR,
+
+    /**
+     * Uses serialization to clone.
+     */
+    SERIALIZATION
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/AutoExternalize.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/AutoExternalize.groovy b/src/main/groovy/groovy/transform/AutoExternalize.groovy
new file mode 100644
index 0000000..d1356b9
--- /dev/null
+++ b/src/main/groovy/groovy/transform/AutoExternalize.groovy
@@ -0,0 +1,66 @@
+/*
+ *  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
+
+/**
+ * Class annotation used to assist in the creation of {@code Externalizable} classes.
+ * The {@code @AutoExternalize} annotation instructs the compiler to execute an
+ * AST transformation which adds {@code writeExternal()} and {@code readExternal()} methods
+ * to a class and adds {@code Externalizable} to the interfaces which the class implements.
+ * The {@code writeExternal()} method writes each property (or field) for the class while the
+ * {@code readExternal()} method will read each one back in the same order. Properties or fields
+ * marked as {@code transient} are ignored.
+ * <p>
+ * Example usage:
+ * <pre>
+ * import groovy.transform.*
+ * {@code @AutoExternalize}
+ * class Person {
+ *   String first, last
+ *   List favItems
+ *   Date since
+ * }
+ * </pre>
+ * Which will create a class of the following form:
+ * <pre>
+ * class Person implements Externalizable {
+ *   ...
+ *   public void writeExternal(ObjectOutput out) throws IOException {
+ *     out.writeObject(first)
+ *     out.writeObject(last)
+ *     out.writeObject(favItems)
+ *     out.writeObject(since)
+ *   }
+ *
+ *   public void readExternal(ObjectInput oin) {
+ *     first = oin.readObject()
+ *     last = oin.readObject()
+ *     favItems = oin.readObject()
+ *     since = oin.readObject()
+ *   }
+ *   ...
+ * }
+ * </pre>
+ * <p>
+ * The {@code @AutoExternalize} transform is implemented as a combination of the {@code @ExternalizeMethods} and {@code @ExternalizeVerifier} transforms.
+ *
+ * @since 1.8.0
+ */
+@AnnotationCollector([ExternalizeMethods, ExternalizeVerifier])
+@interface AutoExternalize { }

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/AutoFinal.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/AutoFinal.java b/src/main/groovy/groovy/transform/AutoFinal.java
new file mode 100644
index 0000000..58ce3ba
--- /dev/null
+++ b/src/main/groovy/groovy/transform/AutoFinal.java
@@ -0,0 +1,99 @@
+/*
+ *  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.codehaus.groovy.control.CompilerConfiguration;
+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;
+
+/**
+ * Annotation to automatically add the final qualifier to method, constructor,
+ * and closure parameters.
+ * <p>The annotation can be placed at the class level in which case it applies to
+ * all methods, constructors, and closures within the class and any inner classes.
+ * It can also be applied to an individual method, constructor, field with a
+ * Closure initial value or a Closure assigned to a local variable. In the case
+ * of fields (or local variables) it only adjusts the parameters of the referenced
+ * Closure not the field (or local variable) itself.
+ * <p>If you wish to automatically apply the
+ * annotation to all classes of a project, consider using
+ * {@code groovyc --configscript}. Google "Customising The Groovy Compiler",
+ * or see {@link CompilerConfiguration} for further details.
+ * This will ensure that all arguments will automatically be final,
+ * completely eliminating the need to clutter the code with final keywords
+ * in any parameter list.
+ * <p>
+ * <em>Example usage:</em>
+ * <pre class="groovyTestCase">
+ * {@code @groovy.transform.AutoFinal}
+ * class Person {
+ *     final String first, last
+ *     Person(String first, String last) {
+ *         this.first = first
+ *         this.last = last
+ *     }
+ *     String fullName(boolean reversed = false, String separator = ' ') {
+ *         final concatCls = { String n0, String n1 -> "$n0$separator$n1" }
+ *         concatCls(reversed ? last : first, reversed ? first : last)
+ *     }
+ * }
+ *
+ * final js = new Person('John', 'Smith')
+ * assert js.fullName() == 'John Smith'
+ * assert js.fullName(true, ', ') == 'Smith, John'
+ * </pre>
+ * for this case, the constructor for the <code>Person</code> class will be
+ * equivalent to the following code:
+ * <pre>
+ * Person(final String first, final String last) {
+ *   ...
+ * }
+ * </pre>
+ * And after normal default parameter processing takes place, the following overloaded methods will exist:
+ * <pre>
+ * String fullName(final boolean reversed, final String separator) { ... }
+ * String fullName(final boolean reversed) { fullName(reversed, ' ') }
+ * String fullName() { fullName(false) }
+ * </pre>
+ * and the closure will have become:
+ * <pre>
+ * { final String n0, final String n1 -> "$n0$separator$n1" }
+ * </pre>
+ *
+ * @since 2.5.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.LOCAL_VARIABLE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.AutoFinalASTTransformation")
+public @interface AutoFinal {
+    /**
+     * Indicates that adding final to parameters should not be applied on this node.
+     * <p>Normally not required since leaving off the annotation will achieve the same affect.
+     * However, it can be useful for selectively disabling this annotation in just a small part
+     * of an otherwise annotated class. As an example, it would make sense to set this to {@code false} on
+     * a method which altered parameters in a class already marked as {@code @AutoFinal}.
+     * All nodes in the class except that single method would be processed.
+     */
+    boolean enabled() default true;
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/AutoImplement.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/AutoImplement.java b/src/main/groovy/groovy/transform/AutoImplement.java
new file mode 100644
index 0000000..57e8152
--- /dev/null
+++ b/src/main/groovy/groovy/transform/AutoImplement.java
@@ -0,0 +1,128 @@
+/*
+ * 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.codehaus.groovy.transform.GroovyASTTransformationClass;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Class annotation used to provide default dummy methods for a class extending an abstract super class or
+ * implementing one or more interfaces.
+ * <p>
+ * Example usage:
+ * <pre>
+ * import groovy.transform.AutoImplement
+ *
+ * {@code @AutoImplement}
+ * class EmptyStringIterator implements Iterator<String> {
+ *     boolean hasNext() { false }
+ * }
+ *
+ * assert !new EmptyStringIterator().hasNext()
+ * </pre>
+ * In the above example, since {@code hasNext} returns false, the {@code next} method
+ * should never be called, so any dummy implementation would do for {@code next}.
+ * The "empty" implementation provided by default when using {@code @AutoImplement}
+ * will suffice - which effectively returns {@code null} in Groovy for non-void,
+ * non-primitive methods.
+ *
+ * As a point of interest, the default implementation for methods returning primitive
+ * types is to return the default value (which incidentally never satisfies Groovy truth).
+ * For {@code boolean} this means returning {@code false}, so for the above example we
+ * could have (albeit perhaps less instructive of our intent) by just using:
+ * <pre>
+ * {@code @AutoImplement}
+ * class EmptyStringIterator implements Iterator<String> { }
+ * </pre>
+ * If we didn't want to assume that callers of our {@code EmptyStringIterator} correctly followed
+ * the {@code Iterator} contract, then we might want to guard against inappropriate calls to {@code next}.
+ * Rather than just returning {@code null}, we might want to throw an exception. This is easily done using
+ * the {@code exception} annotation attribute as shown below:
+ * <pre>
+ * import groovy.transform.AutoImplement
+ * import static groovy.test.GroovyAssert.shouldFail
+ *
+ * {@code @AutoImplement}(exception=UnsupportedOperationException)
+ * class EmptyStringIterator implements Iterator<String> {
+ *     boolean hasNext() { false }
+ * }
+ *
+ * shouldFail(UnsupportedOperationException) {
+ *     new EmptyStringIterator().next()
+ * }
+ * </pre>
+ * All implemented methods will throw an instance of this exception constructed using its no-arg constructor.
+ *
+ * You can also supply a single {@code message} annotation attribute in which case the message will be passed
+ * as an argument during exception construction as shown in the following example:
+ * <pre>
+ * {@code @AutoImplement}(exception=UnsupportedOperationException, message='Not supported for this empty iterator')
+ * class EmptyStringIterator implements Iterator<String> {
+ *     boolean hasNext() { false }
+ * }
+ *
+ * def ex = shouldFail(UnsupportedOperationException) {
+ *     new EmptyStringIterator().next()
+ * }
+ * assert ex.message == 'Not supported for this empty iterator'
+ * </pre>
+ * Finally, you can alternatively supply a {@code code} annotation attribute in which case a closure
+ * block can be supplied which should contain the code to execute for all implemented methods. This can be
+ * seen in the following example:
+ * <pre>
+ * {@code @AutoImplement}(code = { throw new UnsupportedOperationException("Not supported for ${getClass().simpleName}") })
+ * class EmptyStringIterator implements Iterator<String> {
+ *     boolean hasNext() { false }
+ * }
+ *
+ * def ex = shouldFail(UnsupportedOperationException) {
+ *     new EmptyStringIterator().next()
+ * }
+ * assert ex.message == 'Not supported for EmptyStringIterator'
+ * </pre>
+ *
+ * @since 2.5.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.AutoImplementASTTransformation")
+public @interface AutoImplement {
+    /**
+     * If defined, all unimplemented methods will throw this exception.
+     * Will be ignored if {@code code} is defined.
+     */
+    Class<? extends RuntimeException> exception() default Undefined.EXCEPTION.class;
+
+    /**
+     * If {@code exception} is defined, {@code message} can be used to specify the exception message.
+     * Will be ignored if {@code code} is defined or {@code exception} isn't defined.
+     */
+    String message() default Undefined.STRING;
+
+    /**
+     * If defined, all unimplemented methods will execute the code found within the supplied closure.
+     */
+    Class code() default Undefined.CLASS.class;
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/BaseScript.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/BaseScript.java b/src/main/groovy/groovy/transform/BaseScript.java
new file mode 100644
index 0000000..2720b79
--- /dev/null
+++ b/src/main/groovy/groovy/transform/BaseScript.java
@@ -0,0 +1,154 @@
+/*
+ *  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 groovy.lang.Script;
+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;
+
+/**
+ * Variable annotation used for changing the base script class of the current script.
+ * <p>
+ * The type of the variable annotated with {@code @BaseScript} must extend {@link groovy.lang.Script}.
+ * It will be used as the base script class.
+ * The annotated variable will become shortcut to <code>this</code> object.
+ * Using this annotation will override base script set by Groovy compiler or
+ * {@link org.codehaus.groovy.control.CompilerConfiguration} of {@link groovy.lang.GroovyShell}
+ * Example usage:
+ * <pre>
+ * abstract class CustomScript extends Script {
+ *     int getTheMeaningOfLife() { 42 }
+ * }
+ *
+ * &#64;BaseScript CustomScript baseScript
+ *
+ * assert baseScript == this
+ * assert theMeaningOfLife == 42
+ * assert theMeaningOfLife == baseScript.theMeaningOfLife
+ * </pre>
+ * In this example, the base script of the current script will be changed to 
+ * <code>CustomScript</code> allowing usage of <code>getTheMeaningOfLife()</code>
+ * method. <code>baseScript</code> variable will become typed shortcut for 
+ * <code>this</code> object which enables better IDE support.
+ * </p><p>
+ * The custom base script may implement the run() method and specify a different
+ * method name to be used for the script body by declaring a single abstract method.
+ * For example:
+ * <pre>
+ * abstract class CustomScriptBodyMethod extends Script {
+ *     abstract def runScript()
+ *     def preRun() { println "preRunning" }
+ *     def postRun() { println "postRunning" }
+ *     def run() {
+ *         preRun()
+ *         try {
+ *             3.times { runScript() }
+ *         } finally {
+ *             postRun()
+ *         }
+ *     }
+ * }
+ *
+ * {@code @BaseScript} CustomScriptBodyMethod baseScript
+ * println "Script body run"
+ * </pre>
+ * That will produce the following output:
+ * <pre>
+ * preRunning
+ * Script body run
+ * Script body run
+ * Script body run
+ * postRunning
+ * </pre>
+ *
+ * Note that while you can declare arguments for the script body's method, as
+ * the AST is currently implemented they are not accessible in the script body code.
+ * </p>
+ * <p>More examples:</p>
+ * <pre class="groovyTestCase">
+ * // Simple Car class to save state and distance.
+ * class Car {
+ *     String state
+ *     Long distance = 0
+ * }
+ *
+ * // Custom Script with methods that change the Car's state.
+ * // The Car object is passed via the binding.
+ * abstract class CarScript extends Script {
+ *     def start() {
+ *         this.binding.car.state = 'started'
+ *     }
+ *
+ *     def stop() {
+ *         this.binding.car.state = 'stopped'
+ *     }
+ *
+ *     def drive(distance) {
+ *         this.binding.car.distance += distance
+ *     }
+ * }
+ *
+ *
+ * // Define Car object here, so we can use it in assertions later on.
+ * def car = new Car()
+ * // Add to script binding (CarScript references this.binding.car).
+ * def binding = new Binding(car: car)
+ *
+ * // Configure the GroovyShell.
+ * def shell = new GroovyShell(this.class.classLoader, binding)
+ *
+ * // Simple DSL to start, drive and stop the car.
+ * // The methods are defined in the CarScript class.
+ * def carDsl = '''
+ * start()
+ * drive 20
+ * stop()
+ * '''
+ *
+ *
+ * // Run DSL script.
+ * shell.evaluate """
+ * // Use BaseScript annotation to set script
+ * // for evaluating the DSL.
+ * &#64;groovy.transform.BaseScript CarScript carScript
+ *
+ * $carDsl
+ * """
+ *
+ * // Checks to see that Car object has changed.
+ * assert car.distance == 20
+ * assert car.state == 'stopped'
+ * </pre>
+ * 
+ * @author Paul King
+ * @author Vladimir Orany
+ * @author Jim White
+ * @since 2.2.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.LOCAL_VARIABLE, ElementType.PACKAGE, ElementType.TYPE /*, ElementType.IMPORT*/})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.BaseScriptASTTransformation")
+public @interface BaseScript {
+    Class value() default Script.class;
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/Canonical.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/Canonical.groovy b/src/main/groovy/groovy/transform/Canonical.groovy
new file mode 100644
index 0000000..6f99c80
--- /dev/null
+++ b/src/main/groovy/groovy/transform/Canonical.groovy
@@ -0,0 +1,131 @@
+/*
+ *  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
+/**
+ * The {@code @Canonical} meta-annotation combines the {@code @EqualsAndHashCode},
+ * {@code @ToString} and {@code @TupleConstructor} annotations. It is used to assist in
+ * the creation of mutable classes. It instructs the compiler to execute AST transformations
+ * which add positional constructors, equals, hashCode and a pretty print toString to your class.
+ * <p>
+ * You can write classes in this shortened form:
+ * <pre class="groovyTestCase">
+ * import groovy.transform.Canonical
+ * {@code @Canonical} class Customer {
+ *     String first, last
+ *     int age
+ *     Date since
+ *     Collection favItems = ['Food']
+ *     def object 
+ * }
+ * def d = new Date()
+ * def anyObject = new Object()
+ * def c1 = new Customer(first:'Tom', last:'Jones', age:21, since:d, favItems:['Books', 'Games'], object: anyObject)
+ * def c2 = new Customer('Tom', 'Jones', 21, d, ['Books', 'Games'], anyObject)
+ * assert c1 == c2
+ * </pre>
+ *
+ * You don't need to provide all arguments in constructor calls. If using named parameters, any property names not
+ * referenced will be given their default value (as per Java's default unless an explicit initialization constant is
+ * provided when defining the property). If using a tuple constructor, parameters are supplied in the order in which
+ * the properties are defined. Supplied parameters fill the tuple from the left. Any parameters missing on the right
+ * are given their default value.
+ * <pre>
+ * def c3 = new Customer(last: 'Jones', age: 21)
+ * def c4 = new Customer('Tom', 'Jones')
+ *
+ * assert null == c3.since
+ * assert 0 == c4.age
+ * assert c3.favItems == ['Food'] && c4.favItems == ['Food']
+ * </pre>
+ *
+ * If you don't need all of the functionality of {@code @Canonical}, you can simply directly use one or more of the individual
+ * annotations which {@code @Canonical} aggregates.
+ * In addition, you can use {@code @Canonical} in combination with explicit use one or more of the individual annotations in
+ * cases where you need to further customize the annotation attributes.
+ * Any applicable annotation attributes from {@code @Canonical} missing from the explicit annotation will be merged
+ * but any existing annotation attributes within the explicit annotation take precedence. So, for example in this case here:
+ * <pre>
+ * {@code @Canonical}(includeNames=true, excludes='c')
+ * {@code @}{@link ToString}(excludes='a,b')
+ * class MyClass { ... }
+ * </pre>
+ * The generated {@code toString} will include property names and exclude the {@code a} and {@code b} properties.
+ * <p>
+ * A class created using {@code @Canonical} has the following characteristics:
+ * <ul>
+ * <li>A no-arg constructor is provided which allows you to set properties by name using Groovy's normal bean conventions.
+ * <li>Tuple-style constructors are provided which allow you to set properties in the same order as they are defined.
+ * <li>Default {@code equals}, {@code hashCode} and {@code toString} methods are provided based on the property values.
+ * See the GroovyDoc for the individual annotations for more details.
+ * <p>
+ * If you want similar functionality to what this annotation provides but also require immutability, see the
+ * {@code @}{@link Immutable} annotation.
+ * 
+ * <p>More examples:</p>
+ * <pre class="groovyTestCase">
+ * import groovy.transform.*
+ *
+ * &#64;Canonical
+ * class Building {
+ *     String name
+ *     int floors
+ *     boolean officeSpace
+ * }
+ *
+ * // Constructors are added.
+ * def officeSpace = new Building('Initech office', 1, true)
+ *
+ * // toString() added.
+ * assert officeSpace.toString() == 'Building(Initech office, 1, true)'
+ *
+ * // Default values are used if constructor
+ * // arguments are not assigned.
+ * def theOffice = new Building('Wernham Hogg Paper Company')
+ * assert theOffice.floors == 0
+ * theOffice.officeSpace = true
+ *
+ * def anotherOfficeSpace = new Building(name: 'Initech office', floors: 1, officeSpace: true)
+ *
+ * // equals() method is added.
+ * assert anotherOfficeSpace == officeSpace
+ *
+ * // equals() and hashCode() are added, so duplicate is not in Set.
+ * def offices = [officeSpace, anotherOfficeSpace, theOffice] as Set  
+ * assert offices.size() == 2 
+ * assert offices.name.join(',') == 'Initech office,Wernham Hogg Paper Company'
+ *
+ * &#64;Canonical
+ * &#64;ToString(excludes='age')  // Customize one of the transformations.
+ * class Person {
+ *     String name
+ *     int age
+ * }
+ *
+ * def mrhaki = new Person('mrhaki', 37)
+ * assert mrhaki.toString() == 'Person(mrhaki)'
+ * </pre>
+ *
+ * @see groovy.transform.EqualsAndHashCode
+ * @see groovy.transform.ToString
+ * @see groovy.transform.TupleConstructor
+ * @see groovy.transform.Immutable
+ * @since 1.8.0
+ */
+@AnnotationCollector(value=[ToString, TupleConstructor, EqualsAndHashCode], mode=AnnotationCollectorMode.PREFER_EXPLICIT_MERGED)
+public @interface Canonical { }

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/CompilationUnitAware.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/CompilationUnitAware.java b/src/main/groovy/groovy/transform/CompilationUnitAware.java
new file mode 100644
index 0000000..b609f43
--- /dev/null
+++ b/src/main/groovy/groovy/transform/CompilationUnitAware.java
@@ -0,0 +1,30 @@
+/*
+ *  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.codehaus.groovy.control.CompilationUnit;
+
+/**
+ * This interface is for AST transformations which must be aware of the compilation unit where they are applied.
+ *
+ * @author Cedric Champeau
+ */
+public interface CompilationUnitAware {
+    void setCompilationUnit(CompilationUnit unit);
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/CompileDynamic.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/CompileDynamic.groovy b/src/main/groovy/groovy/transform/CompileDynamic.groovy
new file mode 100644
index 0000000..c5247d4
--- /dev/null
+++ b/src/main/groovy/groovy/transform/CompileDynamic.groovy
@@ -0,0 +1,34 @@
+/*
+ *  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 java.lang.annotation.Documented
+
+/**
+ * An annotation which is just a shortcut for @CompileStatic(TypeCheckingMode.SKIP).
+ * This can be used for example if you statically compile a full class but you want to skip
+ * some methods without having to use the full annotation.
+ *
+ * @author Cedric Champeau
+ * @since 2.1.0
+ */
+@Documented
+@AnnotationCollector(processor = "org.codehaus.groovy.transform.CompileDynamicProcessor")
+public @interface CompileDynamic {
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/CompileStatic.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/CompileStatic.java b/src/main/groovy/groovy/transform/CompileStatic.java
new file mode 100644
index 0000000..16dbc33
--- /dev/null
+++ b/src/main/groovy/groovy/transform/CompileStatic.java
@@ -0,0 +1,63 @@
+/*
+ *  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.codehaus.groovy.transform.GroovyASTTransformationClass;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This will let the Groovy compiler use compile time checks in the style of Java
+ * then perform static compilation, thus bypassing the Groovy meta object protocol.
+ * <p>
+ * When a class is annotated, all methods, properties, files, inner classes, etc.
+ * of the annotated class will be type checked. When a method is annotated, static
+ * compilation applies only to items (closures and anonymous inner classes) within
+ * the method.
+ * <p>
+ * By using {@link TypeCheckingMode#SKIP}, static compilation can be skipped on an
+ * element within a class or method otherwise marked with CompileStatic. For example
+ * a class can be annotated with CompileStatic, and a method within can be marked
+ * to skip static checking to use dynamic language features.
+ *
+ * @author <a href="mailto:blackdrag@gmx.org">Jochen "blackdrag" Theodorou</a>
+ * @author Cedric Champeau
+ *
+ * @see CompileDynamic
+ */
+@Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({   ElementType.METHOD,         ElementType.TYPE,
+            ElementType.CONSTRUCTOR
+})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.sc.StaticCompileTransformation")
+public @interface CompileStatic {
+    TypeCheckingMode value() default TypeCheckingMode.PASS;
+
+    /**
+     * The list of (classpath resources) paths to type checking DSL scripts, also known
+     * as type checking extensions.
+     * @return an array of paths to groovy scripts that must be on compile classpath
+     */
+    String[] extensions() default {};
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/ConditionalInterrupt.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/ConditionalInterrupt.groovy b/src/main/groovy/groovy/transform/ConditionalInterrupt.groovy
new file mode 100644
index 0000000..66aa64c
--- /dev/null
+++ b/src/main/groovy/groovy/transform/ConditionalInterrupt.groovy
@@ -0,0 +1,155 @@
+/*
+ *  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.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 "interrupt-safe" executions of scripts by adding a custom check for interruption
+ * into loops (for, while, ...) and at the start of closures and methods.
+ * <p>
+ * This is especially useful when executing foreign scripts that you do not have control over. Inject this
+ * transformation into a script that you need to interrupt based on some custom criteria.
+ * <p>
+ * Annotating anything in a script will cause for loops, while loops, methods, and closures to make a
+ * check against the specified closure. If the closure yields true (according to GroovyTruth), then the script
+ * will throw an InterruptedException. The annotation by default applies to any classes defined in the script
+ * as well. Annotated a class will cause (by default) all classes in the entire file ('Compilation Unit') to be
+ * enhanced. You can fine tune what is enhanced using the annotation parameters.
+ * <p>
+ * The following is sample usage of the annotation:
+ * <pre>
+ * <code>@ConditionalInterrupt({ counter++> 10})</code>
+ * import groovy.transform.ConditionalInterrupt
+ *
+ * counter = 0
+ * def scriptMethod() {
+ *      4.times {
+ *          println 'executing script method...'
+ *      }
+ * }
+ *
+ * scriptMethod()
+ * </pre>
+ * Which results in the following code being generated (XXXXXX will be replaced with some runtime generated hashCode). Notice the checks and exceptions:
+ * <pre>
+ * public class script1291741477073 extends groovy.lang.Script {
+ *   Object counter = 0
+ *
+ *   public java.lang.Object run() {
+ *     counter = 0
+ *   }
+ *
+ *   public java.lang.Object scriptMethod() {
+ *     if (this.conditionalTransformXXXXXX$condition()) {
+ *       throw new java.lang.InterruptedException('Execution interrupted. The following condition failed: { counter++> 10}')
+ *     }
+ *     4.times({
+ *       if (this.conditionalTransformXXXXXX$condition()) {
+ *         throw new java.lang.InterruptedException('Execution interrupted. The following condition failed: { counter++> 10}')
+ *       }
+ *       this.println('executing script method...')
+ *     })
+ *   }
+ *
+ *   private java.lang.Object conditionalTransformXXXXXX$condition() {
+ *     counter++ > 10
+ *   }
+ * }
+ * </pre>
+ *
+ * Note that when you're annotating scripts, the variable scoping semantics are unchanged. Therefore, you must be
+ * careful about the variable scope you're using. Make sure that variables you reference in the closure parameter
+ * are in scope during script execution. The following example will throw a MissingPropertyException because
+ * counter is not in scope for a class:
+ * <pre>
+ * import groovy.transform.ConditionalInterrupt
+ *
+ * def counter = 0
+ * <code>@ConditionalInterrupt({ counter++> 10})</code>
+ * class MyClass {
+ *   def myMethod() {
+ *     4.times {
+ *       println 'executing script method...'
+ *     }
+ *   }
+ * }
+ *
+ * new MyClass().myMethod()
+ * </pre>
+ * Additional usage examples can be found in the unit test for this class.
+ *
+ * @see TimedInterrupt
+ * @see ThreadInterrupt
+ * @author Cedric Champeau
+ * @author Hamlet D'Arcy
+ * @author Paul King
+ * @since 1.8.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target([ElementType.PACKAGE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.LOCAL_VARIABLE])
+@GroovyASTTransformationClass(["org.codehaus.groovy.transform.ConditionalInterruptibleASTTransformation"])
+@interface ConditionalInterrupt {
+  /**
+   * Set this to false if you have multiple classes within one source file and only
+   * want a conditional check on some of the classes. Place annotations on the classes
+   * you want enhanced. Set to true (the default) for blanket coverage of conditional
+   * checks on all methods, loops and closures within all classes/script code.
+   *
+   * For even finer-grained control see {@code applyToAllMembers}.
+   *
+   * @see #applyToAllMembers()
+   */
+  boolean applyToAllClasses() default true
+
+  /**
+   * Set this to false if you have multiple methods/closures within a class or script and only
+   * want conditional checks on some of them. Place annotations on the methods/closures that
+   * you want enhanced. When false, {@code applyToAllClasses} is automatically set to false.
+   *
+   * Set to true (the default) for blanket coverage of conditional checks on all methods, loops
+   * and closures within the class/script.
+   *
+   * @since 2.2.0
+   * @see #applyToAllClasses()
+   */
+  boolean applyToAllMembers() default true
+
+  /**
+   * By default a conditional check is added to the start of all user-defined methods. To turn this off simply
+   * set this parameter to false.
+   */
+  boolean checkOnMethodStart() default true
+
+  /**
+   * Sets the type of exception which is thrown.
+   */
+  Class thrown() default InterruptedException
+
+  /**
+   * Conditional check - set as a closure expression.
+   */
+  Class value()
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/EqualsAndHashCode.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/EqualsAndHashCode.java b/src/main/groovy/groovy/transform/EqualsAndHashCode.java
new file mode 100644
index 0000000..592c6ba
--- /dev/null
+++ b/src/main/groovy/groovy/transform/EqualsAndHashCode.java
@@ -0,0 +1,276 @@
+/*
+ *  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.codehaus.groovy.transform.GroovyASTTransformationClass;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Class annotation used to assist in creating appropriate {@code equals()} and {@code hashCode()} methods.
+ * <p>
+ * It allows you to write classes in this shortened form:
+ * <pre class="groovyTestCase">
+ * import groovy.transform.EqualsAndHashCode
+ * {@code @EqualsAndHashCode}
+ * class Person {
+ *     String first, last
+ *     int age
+ * }
+ * def p1 = new Person(first:'John', last:'Smith', age:21)
+ * def p2 = new Person(first:'John', last:'Smith', age:21)
+ * assert p1 == p2
+ * def map = [:]
+ * map[p1] = 45
+ * assert map[p2] == 45
+ * </pre>
+ * The {@code @EqualsAndHashCode} annotation instructs the compiler to execute an
+ * AST transformation which adds the necessary equals and hashCode methods to the class.
+ * <p>
+ * The {@code hashCode()} method is calculated using Groovy's {@code HashCodeHelper} class
+ * which implements an algorithm similar to the one outlined in the book <em>Effective Java</em>.
+ * <p>
+ * The {@code equals()} method compares the values of the individual properties (and optionally fields)
+ * of the class.  It can also optionally call equals on the super class. Two different equals method
+ * implementations are supported both of which support the equals contract outlined in the javadoc
+ * for <code>java.lang.Object</code>
+ * <p>
+ * To illustrate the 'canEqual' implementation style (see http://www.artima.com/lejava/articles/equality.html
+ * for further details), consider this class:
+ * <pre>
+ * {@code @EqualsAndHashCode}
+ * class IntPair {
+ *     int x, y
+ * }
+ * </pre>
+ * The generated <code>equals</code> and <code>canEqual</code> methods will be something like below:
+ * <pre>
+ * public boolean equals(java.lang.Object other)
+ *     if (other == null) return false
+ *     if (this.is(other)) return true
+ *     if (!(other instanceof IntPair)) return false
+ *     if (!other.canEqual(this)) return false
+ *     if (x != other.x) return false
+ *     if (y != other.y) return false
+ *     return true
+ * }
+ *
+ * public boolean canEqual(java.lang.Object other) {
+ *     return other instanceof IntPair
+ * }
+ * </pre>
+ * If no further options are specified, this is the default style for {@code @Canonical} and
+ * {@code @EqualsAndHashCode} annotated classes. The advantage of this style is that it allows inheritance
+ * to be used in limited cases where its purpose is for overriding implementation details rather than
+ * creating a derived type with different behavior. This is useful when using JPA Proxies for example or
+ * as shown in the following examples:
+ * <pre class="groovyTestCase">
+ * import groovy.transform.*
+ * {@code @Canonical} class IntPair { int x, y }
+ * def p1 = new IntPair(1, 2)
+ *
+ * // overridden getter but deemed an IntPair as far as domain is concerned
+ * def p2 = new IntPair(1, 1) { int getY() { 2 } }
+ *
+ * // additional helper method added through inheritance but
+ * // deemed an IntPair as far as our domain is concerned
+ * {@code @InheritConstructors} class IntPairWithSum extends IntPair {
+ *     def sum() { x + y }
+ * }
+ *
+ * def p3 = new IntPairWithSum(1, 2)
+ *
+ * assert p1 == p2 && p2 == p1
+ * assert p1 == p3 && p3 == p1
+ * assert p3 == p2 && p2 == p3
+ * </pre>
+ * Note that if you create any domain classes which don't have exactly the
+ * same contract as <code>IntPair</code> then you should provide an appropriate
+ * <code>equals</code> and <code>canEqual</code> method. The easiest way to
+ * achieve this would be to use the {@code @Canonical} or
+ * {@code @EqualsAndHashCode} annotations as shown below:
+ * <pre>
+ * {@code @EqualsAndHashCode}
+ * {@code @TupleConstructor(includeSuperProperties=true)}
+ * class IntTriple extends IntPair { int z }
+ * def t1 = new IntTriple(1, 2, 3)
+ * assert p1 != t1 && p2 != t1 && t1 != p3
+ * </pre>
+ *
+ * The alternative supported style regards any kind of inheritance as creation of
+ * a new type and is illustrated in the following example:
+ * <pre>
+ * {@code @EqualsAndHashCode(useCanEqual=false)}
+ * class IntPair {
+ *     int x, y
+ * }
+ * </pre>
+ * The generated equals method will be something like below:
+ * <pre>
+ * public boolean equals(java.lang.Object other)
+ *     if (other == null) return false
+ *     if (this.is(other)) return true
+ *     if (IntPair != other.getClass()) return false
+ *     if (x != other.x) return false
+ *     if (y != other.y) return false
+ *     return true
+ * }
+ * </pre>
+ * This style is appropriate for final classes (where inheritance is not
+ * allowed) which have only <code>java.lang.Object</code> as a super class.
+ * Most {@code @Immutable} classes fall in to this category. For such classes,
+ * there is no need to introduce the <code>canEqual()</code> method.
+ * <p>
+ * Note that if you explicitly set <code>useCanEqual=false</code> for child nodes
+ * in a class hierarchy but have it <code>true</code> for parent nodes and you
+ * also have <code>callSuper=true</code> in the child, then your generated
+ * equals methods will not strictly follow the equals contract.
+ * <p>
+ * Note that when used in the recommended fashion, the two implementations supported adhere
+ * to the equals contract. You can provide your own equivalence relationships if you need,
+ * e.g. for comparing instances of the <code>IntPair</code> and <code>IntTriple</code> classes
+ * discussed earlier, you could provide the following method in <code>IntPair</code>:
+ * <pre>
+ * boolean hasEqualXY(other) { other.x == getX() && other.y == getY() }
+ * </pre>
+ * Then for the objects defined earlier, the following would be true:
+ * <pre>
+ * assert p1.hasEqualXY(t1) && t1.hasEqualXY(p1)
+ * assert p2.hasEqualXY(t1) && t1.hasEqualXY(p2)
+ * assert p3.hasEqualXY(t1) && t1.hasEqualXY(p3)
+ * </pre>
+ * There is also support for including or excluding fields/properties by name when constructing
+ * the equals and hashCode methods as shown here:
+ * <pre class="groovyTestCase">
+ * import groovy.transform.*
+ * {@code @EqualsAndHashCode}(excludes="z")
+ * {@code @TupleConstructor}
+ * public class Point2D {
+ *     int x, y, z
+ * }
+ *
+ * assert  new Point2D(1, 1, 1).equals(new Point2D(1, 1, 2))
+ * assert !new Point2D(1, 1, 1).equals(new Point2D(2, 1, 1))
+ *
+ * {@code @EqualsAndHashCode}(excludes=["y", "z"])
+ * {@code @TupleConstructor}
+ * public class Point1D {
+ *     int x, y, z
+ * }
+ *
+ * assert  new Point1D(1, 1, 1).equals(new Point1D(1, 1, 2))
+ * assert  new Point1D(1, 1, 1).equals(new Point1D(1, 2, 1))
+ * assert !new Point1D(1, 1, 1).equals(new Point1D(2, 1, 1))
+ * </pre>
+ * <b>Note:</b> {@code @EqualsAndHashCode} is a transform to help reduce boilerplate
+ * in the common cases. It provides a useful implementation of {@code equals()}
+ * and {@code hashCode()} but not necessarily the most appropriate or
+ * efficient one for every use case. You should write custom versions if your
+ * scenario demands it. In particular, if you have
+ * mutually-referential classes, the implementations provided may not be suitable
+ * and may recurse infinitely (leading to a {@code StackOverflowError}). In such cases,
+ * you need to remove the infinite loop from your data structures or write your own custom methods.
+ * If your data structures are self-referencing, the code generated by this transform will try to avoid
+ * infinite recursion but the algorithm used may not suit your scenario, so use with caution if
+ * you have such structures.
+ * A future version of this transform may better handle some additional recursive scenarios.
+ * <p>More examples:</p>
+ * <pre class="groovyTestCase">
+ * import groovy.transform.EqualsAndHashCode
+ *
+ * &#64;EqualsAndHashCode(includeFields=true)
+ * class User {
+ *     String name
+ *     boolean active
+ *     List likes
+ *     private int age = 37
+ * }
+ *
+ * def user = new User(name: 'mrhaki', active: false, likes: ['Groovy', 'Java'])
+ * def mrhaki = new User(name: 'mrhaki', likes: ['Groovy', 'Java'])
+ * def hubert = new User(name: 'Hubert Klein Ikkink', likes: ['Groovy', 'Java'])
+ *
+ * assert user == mrhaki
+ * assert mrhaki != hubert
+ *
+ * Set users = new HashSet()
+ * users.add user
+ * users.add mrhaki
+ * users.add hubert
+ * assert users.size() == 2
+ * </pre>
+ *
+ * @see org.codehaus.groovy.util.HashCodeHelper
+ * @author Paul King
+ * @since 1.8.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.EqualsAndHashCodeASTTransformation")
+public @interface EqualsAndHashCode {
+    /**
+     * List of field and/or property names to exclude from the equals and hashCode calculations.
+     * Must not be used if 'includes' is used. For convenience, a String with comma separated names
+     * can be used in addition to an array (using Groovy's literal list notation) of String values.
+     */
+    String[] excludes() default {};
+
+    /**
+     * List of field and/or property names to include within the equals and hashCode calculations.
+     * Must not be used if 'excludes' is used. For convenience, a String with comma separated names
+     * can be used in addition to an array (using Groovy's literal list notation) of String values.
+     * The default value is a special marker value indicating that no includes are defined; all fields
+     * and/or properties are included if 'includes' remains undefined and 'excludes' is explicitly or
+     * implicitly an empty list.
+     */
+    String[] includes() default {Undefined.STRING};
+
+    /**
+     * Whether to cache hashCode calculations. You should only set this to true if
+     * you know the object is immutable (or technically mutable but never changed).
+     */
+    boolean cache() default false;
+
+    /**
+     * Whether to include super in equals and hashCode calculations.
+     */
+    boolean callSuper() default false;
+
+    /**
+     * Include fields as well as properties in equals and hashCode calculations.
+     */
+    boolean includeFields() default false;
+
+    /**
+     * Generate a canEqual method to be used by equals.
+     */
+    boolean useCanEqual() default true;
+
+    /**
+     * Whether to include all fields and/or properties in equals and hashCode calculations, including those
+     * with names that are considered internal.
+     *
+     * @since 2.5.0
+     */
+    boolean allNames() default false;
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/ExternalizeMethods.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/ExternalizeMethods.java b/src/main/groovy/groovy/transform/ExternalizeMethods.java
new file mode 100644
index 0000000..5ef37a0
--- /dev/null
+++ b/src/main/groovy/groovy/transform/ExternalizeMethods.java
@@ -0,0 +1,89 @@
+/*
+ *  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.codehaus.groovy.transform.GroovyASTTransformationClass;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Class annotation used to assist in the creation of {@code Externalizable} classes.
+ * The {@code @ExternalizeMethods} annotation instructs the compiler to execute an
+ * AST transformation which adds {@code writeExternal()} and {@code readExternal()} methods
+ * to a class and adds {@code Externalizable} to the interfaces which the class implements.
+ * The {@code writeExternal()} method writes each property (and optionally field) of the class
+ * while the {@code readExternal()} method will read each one back in the same order.
+ * Properties or fields marked as {@code transient} are ignored.
+ * This annotation is typically used in conjunction with the {@code @ExternalizeVerifier} annotation but
+ * most usually not directly but rather via {@code @AutoExternalizable} which is a shortcut for both annotations.
+ * <p>
+ * Example usage:
+ * <pre>
+ * import groovy.transform.*
+ * {@code @ExternalizeMethods}
+ * class Person {
+ *   String first, last
+ *   List favItems
+ *   Date since
+ * }
+ * </pre>
+ * Which will create a class of the following form:
+ * <pre>
+ * class Person implements Externalizable {
+ *   ...
+ *   public void writeExternal(ObjectOutput out) throws IOException {
+ *     out.writeObject(first)
+ *     out.writeObject(last)
+ *     out.writeObject(favItems)
+ *     out.writeObject(since)
+ *   }
+ *
+ *   public void readExternal(ObjectInput oin) {
+ *     first = (String) oin.readObject()
+ *     last = (String) oin.readObject()
+ *     favItems = (List) oin.readObject()
+ *     since = (Date) oin.readObject()
+ *   }
+ *   ...
+ * }
+ * </pre>
+ *
+ * @author Paul King
+ * @since 1.8.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.ExternalizeMethodsASTTransformation")
+public @interface ExternalizeMethods {
+    /**
+     * Comma separated list of property names to exclude from externalizing.
+     * For convenience, a String with comma separated names
+     * can be used in addition to an array (using Groovy's literal list notation) of String values.
+     */
+    String[] excludes() default {};
+
+    /**
+     * Include fields as well as properties when externalizing.
+     */
+    boolean includeFields() default false;
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/ExternalizeVerifier.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/ExternalizeVerifier.java b/src/main/groovy/groovy/transform/ExternalizeVerifier.java
new file mode 100644
index 0000000..185c935
--- /dev/null
+++ b/src/main/groovy/groovy/transform/ExternalizeVerifier.java
@@ -0,0 +1,62 @@
+/*
+ *  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.codehaus.groovy.transform.GroovyASTTransformationClass;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Class annotation used to assist in the creation of {@code Externalizable} classes.
+ * The {@code @ExternalizeVerifier} annotation instructs the compiler to check
+ * that a class has {@code writeExternal()} and {@code readExternal()} methods,
+ * implements the {@code Externalizable} interface and that each property (and optionally field) is not final
+ * and, optionally for non-primitives, has a type which is either {@code Externalizable} or {@code Serializable}.
+ * Properties or fields marked as {@code transient} are ignored.
+ * This annotation is typically used in conjunction with the {@code @ExternalizeMethods} annotation but
+ * most usually not directly but rather via {@code @AutoExternalizable} which is a shortcut for both annotations.
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.ExternalizeVerifierASTTransformation")
+public @interface ExternalizeVerifier {
+    /**
+     * Comma separated list of property names to exclude from externalization verification.
+     * For convenience, a String with comma separated names
+     * can be used in addition to an array (using Groovy's literal list notation) of String values.
+     */
+    String[] excludes() default {};
+
+    /**
+     * Include fields as well as properties when verifying externalization properties.
+     */
+    boolean includeFields() default false;
+
+    /**
+     * Turns on strict type checking for property (or field) types. In strict mode, such types must also implement Serializable or Externalizable.
+     * If your properties have interface types that don't implement Serializable but all the concrete implementations do, or the
+     * type is of a non-Serializable class but the property will be null at runtime, then your instances will still be serializable
+     * but you can't turn on strict checking.
+     */
+    boolean checkPropertyTypes() default false;
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/groovy/transform/Field.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/Field.java b/src/main/groovy/groovy/transform/Field.java
new file mode 100644
index 0000000..bcc64e8
--- /dev/null
+++ b/src/main/groovy/groovy/transform/Field.java
@@ -0,0 +1,55 @@
+/*
+ *  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.codehaus.groovy.transform.GroovyASTTransformationClass;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Variable annotation used for changing the scope of a variable within a script from
+ * being within the run method of the script to being at the class level for the script.
+ * <p>
+ * The annotated variable will become a private field of the script class.
+ * The type of the field will be the same as the type of the variable. Example usage:
+ * <pre class="groovyTestCase">
+ * import groovy.transform.Field
+ * {@code @Field} List awe = [1, 2, 3]
+ * def awesum() { awe.sum() }
+ * assert awesum() == 6
+ * </pre>
+ * In this example, without the annotation, variable <code>awe</code> would be
+ * a local script variable (technically speaking it will be a local variable within
+ * the <code>run</code> method of the script class). Such a local variable would
+ * not be visible inside the <code>awesum</code> method. With the annotation,
+ * <code>awe</code> becomes a private List field in the script class and is
+ * visible within the <code>awesum</code> method.
+ *
+ * @author Paul King
+ * @since 1.8.0
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.LOCAL_VARIABLE})
+@GroovyASTTransformationClass("org.codehaus.groovy.transform.FieldASTTransformation")
+public @interface Field {
+}