Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 324F6200D89 for ; Wed, 20 Dec 2017 05:29:18 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 30ABA160C2A; Wed, 20 Dec 2017 04:29:18 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id EA79E160C2B for ; Wed, 20 Dec 2017 05:29:13 +0100 (CET) Received: (qmail 33000 invoked by uid 500); 20 Dec 2017 04:29:13 -0000 Mailing-List: contact commits-help@groovy.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@groovy.apache.org Delivered-To: mailing list commits@groovy.apache.org Received: (qmail 32463 invoked by uid 99); 20 Dec 2017 04:29:12 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 20 Dec 2017 04:29:12 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 85025F1810; Wed, 20 Dec 2017 04:29:09 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: sunlan@apache.org To: commits@groovy.apache.org Date: Wed, 20 Dec 2017 04:29:17 -0000 Message-Id: <9bda85071be0428397c325e4d2700be2@git.apache.org> In-Reply-To: <48be9b2ce20b4b3a90bfd5192834b3a3@git.apache.org> References: <48be9b2ce20b4b3a90bfd5192834b3a3@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [09/47] groovy git commit: Move source files to proper packages archived-at: Wed, 20 Dec 2017 04:29:18 -0000 http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/transform/AutoClone.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/AutoClone.java b/src/main/groovy/transform/AutoClone.java deleted file mode 100644 index dc96181..0000000 --- a/src/main/groovy/transform/AutoClone.java +++ /dev/null @@ -1,281 +0,0 @@ -/* - * 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. - *

- * 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. - *

- * Example usage: - *

- * import groovy.transform.AutoClone
- * {@code @AutoClone}
- * class Person {
- *   String first, last
- *   List favItems
- *   Date since
- * }
- * 
- * Which will create a class equivalent to the following: - *
- * 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
- *   }
- *   ...
- * }
- * 
- * Which can be used as follows: - *
- * 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)
- * 
- * 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. - *

- * 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. - *

- * 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. - *

- * 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: - *

- * 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
- * }
- * 
- * Which will create classes equivalent to the following: - *
- * 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)
- *   }
- *   ...
- * }
- * 
- * 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. - *

- * 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: - *

- * 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
- * }
- * 
- * Which will create classes equivalent to the following: - *
- * 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
- *   }
- *   ...
- * }
- * 
- * 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. - *

- * As a final example, if your class already implements the {@code Serializable} - * or {@code Externalizable} interface, you can choose the following cloning style: - *

- * {@code @AutoClone(style=SERIALIZATION)}
- * class Person implements Serializable {
- *   String first, last
- *   Date birthday
- * }
- * 
- * which outputs a class with the following form: - *
- * 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() }
- *   }
- *   ...
- * }
- * 
- * 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. - *

- * Further references on cloning: - *

- * - * @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. - *

- * 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. - *

- * 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. - *

- * 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. - *

- * 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/transform/AutoCloneStyle.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/AutoCloneStyle.java b/src/main/groovy/transform/AutoCloneStyle.java deleted file mode 100644 index ef9be51..0000000 --- a/src/main/groovy/transform/AutoCloneStyle.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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/transform/AutoExternalize.groovy ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/AutoExternalize.groovy b/src/main/groovy/transform/AutoExternalize.groovy deleted file mode 100644 index d1356b9..0000000 --- a/src/main/groovy/transform/AutoExternalize.groovy +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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. - *

- * Example usage: - *

- * import groovy.transform.*
- * {@code @AutoExternalize}
- * class Person {
- *   String first, last
- *   List favItems
- *   Date since
- * }
- * 
- * Which will create a class of the following form: - *
- * 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()
- *   }
- *   ...
- * }
- * 
- *

- * 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/transform/AutoFinal.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/AutoFinal.java b/src/main/groovy/transform/AutoFinal.java deleted file mode 100644 index 58ce3ba..0000000 --- a/src/main/groovy/transform/AutoFinal.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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. - *

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. - *

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. - *

- * Example usage: - *

- * {@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'
- * 
- * for this case, the constructor for the Person class will be - * equivalent to the following code: - *
- * Person(final String first, final String last) {
- *   ...
- * }
- * 
- * And after normal default parameter processing takes place, the following overloaded methods will exist: - *
- * String fullName(final boolean reversed, final String separator) { ... }
- * String fullName(final boolean reversed) { fullName(reversed, ' ') }
- * String fullName() { fullName(false) }
- * 
- * and the closure will have become: - *
- * { final String n0, final String n1 -> "$n0$separator$n1" }
- * 
- * - * @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. - *

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/transform/AutoImplement.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/AutoImplement.java b/src/main/groovy/transform/AutoImplement.java deleted file mode 100644 index 57e8152..0000000 --- a/src/main/groovy/transform/AutoImplement.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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. - *

- * Example usage: - *

- * import groovy.transform.AutoImplement
- *
- * {@code @AutoImplement}
- * class EmptyStringIterator implements Iterator {
- *     boolean hasNext() { false }
- * }
- *
- * assert !new EmptyStringIterator().hasNext()
- * 
- * 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: - *
- * {@code @AutoImplement}
- * class EmptyStringIterator implements Iterator { }
- * 
- * 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: - *
- * import groovy.transform.AutoImplement
- * import static groovy.test.GroovyAssert.shouldFail
- *
- * {@code @AutoImplement}(exception=UnsupportedOperationException)
- * class EmptyStringIterator implements Iterator {
- *     boolean hasNext() { false }
- * }
- *
- * shouldFail(UnsupportedOperationException) {
- *     new EmptyStringIterator().next()
- * }
- * 
- * 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: - *
- * {@code @AutoImplement}(exception=UnsupportedOperationException, message='Not supported for this empty iterator')
- * class EmptyStringIterator implements Iterator {
- *     boolean hasNext() { false }
- * }
- *
- * def ex = shouldFail(UnsupportedOperationException) {
- *     new EmptyStringIterator().next()
- * }
- * assert ex.message == 'Not supported for this empty iterator'
- * 
- * 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: - *
- * {@code @AutoImplement}(code = { throw new UnsupportedOperationException("Not supported for ${getClass().simpleName}") })
- * class EmptyStringIterator implements Iterator {
- *     boolean hasNext() { false }
- * }
- *
- * def ex = shouldFail(UnsupportedOperationException) {
- *     new EmptyStringIterator().next()
- * }
- * assert ex.message == 'Not supported for EmptyStringIterator'
- * 
- * - * @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 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/transform/BaseScript.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/BaseScript.java b/src/main/groovy/transform/BaseScript.java deleted file mode 100644 index 227333a..0000000 --- a/src/main/groovy/transform/BaseScript.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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. - *

- * 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 this 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: - *

- * abstract class CustomScript extends Script {
- *     int getTheMeaningOfLife() { 42 }
- * }
- *
- * @BaseScript CustomScript baseScript
- *
- * assert baseScript == this
- * assert theMeaningOfLife == 42
- * assert theMeaningOfLife == baseScript.theMeaningOfLife
- * 
- * In this example, the base script of the current script will be changed to - * CustomScript allowing usage of getTheMeaningOfLife() - * method. baseScript variable will become typed shortcut for - * this object which enables better IDE support. - *

- * 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: - *

- * 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"
- * 
- * That will produce the following output: - *
- * preRunning
- * Script body run
- * Script body run
- * Script body run
- * postRunning
- * 
- * - * 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. - *

- *

More examples:

- *
- * // 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.
- * @groovy.transform.BaseScript CarScript carScript
- *
- * $carDsl
- * """
- *
- * // Checks to see that Car object has changed.
- * assert car.distance == 20
- * assert car.state == 'stopped'
- * 
- * - * @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/transform/Canonical.groovy ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/Canonical.groovy b/src/main/groovy/transform/Canonical.groovy deleted file mode 100644 index 6f99c80..0000000 --- a/src/main/groovy/transform/Canonical.groovy +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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. - *

- * You can write classes in this shortened form: - *

- * 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
- * 
- * - * 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. - *
- * 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']
- * 
- * - * 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: - *
- * {@code @Canonical}(includeNames=true, excludes='c')
- * {@code @}{@link ToString}(excludes='a,b')
- * class MyClass { ... }
- * 
- * The generated {@code toString} will include property names and exclude the {@code a} and {@code b} properties. - *

- * A class created using {@code @Canonical} has the following characteristics: - *

    - *
  • A no-arg constructor is provided which allows you to set properties by name using Groovy's normal bean conventions. - *
  • Tuple-style constructors are provided which allow you to set properties in the same order as they are defined. - *
  • 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. - *

    - * If you want similar functionality to what this annotation provides but also require immutability, see the - * {@code @}{@link Immutable} annotation. - * - *

    More examples:

    - *
    - * import groovy.transform.*
    - *
    - * @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'
    - *
    - * @Canonical
    - * @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)'
    - * 
    - * - * @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/transform/CompilationUnitAware.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/CompilationUnitAware.java b/src/main/groovy/transform/CompilationUnitAware.java deleted file mode 100644 index b609f43..0000000 --- a/src/main/groovy/transform/CompilationUnitAware.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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/transform/CompileDynamic.groovy ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/CompileDynamic.groovy b/src/main/groovy/transform/CompileDynamic.groovy deleted file mode 100644 index c5247d4..0000000 --- a/src/main/groovy/transform/CompileDynamic.groovy +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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/transform/CompileStatic.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/CompileStatic.java b/src/main/groovy/transform/CompileStatic.java deleted file mode 100644 index 16dbc33..0000000 --- a/src/main/groovy/transform/CompileStatic.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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. - *

    - * 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. - *

    - * 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 Jochen "blackdrag" Theodorou - * @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/transform/ConditionalInterrupt.groovy ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/ConditionalInterrupt.groovy b/src/main/groovy/transform/ConditionalInterrupt.groovy deleted file mode 100644 index 66aa64c..0000000 --- a/src/main/groovy/transform/ConditionalInterrupt.groovy +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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. - *

    - * 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. - *

    - * 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. - *

    - * The following is sample usage of the annotation: - *

    - * @ConditionalInterrupt({ counter++> 10})
    - * import groovy.transform.ConditionalInterrupt
    - *
    - * counter = 0
    - * def scriptMethod() {
    - *      4.times {
    - *          println 'executing script method...'
    - *      }
    - * }
    - *
    - * scriptMethod()
    - * 
    - * Which results in the following code being generated (XXXXXX will be replaced with some runtime generated hashCode). Notice the checks and exceptions: - *
    - * 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
    - *   }
    - * }
    - * 
    - * - * 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: - *
    - * import groovy.transform.ConditionalInterrupt
    - *
    - * def counter = 0
    - * @ConditionalInterrupt({ counter++> 10})
    - * class MyClass {
    - *   def myMethod() {
    - *     4.times {
    - *       println 'executing script method...'
    - *     }
    - *   }
    - * }
    - *
    - * new MyClass().myMethod()
    - * 
    - * 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/transform/EqualsAndHashCode.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/EqualsAndHashCode.java b/src/main/groovy/transform/EqualsAndHashCode.java deleted file mode 100644 index 11a385e..0000000 --- a/src/main/groovy/transform/EqualsAndHashCode.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * 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. - *

    - * It allows you to write classes in this shortened form: - *

    - * 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
    - * 
    - * The {@code @EqualsAndHashCode} annotation instructs the compiler to execute an - * AST transformation which adds the necessary equals and hashCode methods to the class. - *

    - * The {@code hashCode()} method is calculated using Groovy's {@code HashCodeHelper} class - * which implements an algorithm similar to the one outlined in the book Effective Java. - *

    - * 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 java.lang.Object - *

    - * To illustrate the 'canEqual' implementation style (see http://www.artima.com/lejava/articles/equality.html - * for further details), consider this class: - *

    - * {@code @EqualsAndHashCode}
    - * class IntPair {
    - *     int x, y
    - * }
    - * 
    - * The generated equals and canEqual methods will be something like below: - *
    - * 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
    - * }
    - * 
    - * 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: - *
    - * 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
    - * 
    - * Note that if you create any domain classes which don't have exactly the - * same contract as IntPair then you should provide an appropriate - * equals and canEqual method. The easiest way to - * achieve this would be to use the {@code @Canonical} or - * {@code @EqualsAndHashCode} annotations as shown below: - *
    - * {@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
    - * 
    - * - * The alternative supported style regards any kind of inheritance as creation of - * a new type and is illustrated in the following example: - *
    - * {@code @EqualsAndHashCode(useCanEqual=false)}
    - * class IntPair {
    - *     int x, y
    - * }
    - * 
    - * The generated equals method will be something like below: - *
    - * 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
    - * }
    - * 
    - * This style is appropriate for final classes (where inheritance is not - * allowed) which have only java.lang.Object as a super class. - * Most {@code @Immutable} classes fall in to this category. For such classes, - * there is no need to introduce the canEqual() method. - *

    - * Note that if you explicitly set useCanEqual=false for child nodes - * in a class hierarchy but have it true for parent nodes and you - * also have callSuper=true in the child, then your generated - * equals methods will not strictly follow the equals contract. - *

    - * 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 IntPair and IntTriple classes - * discussed earlier, you could provide the following method in IntPair: - *

    - * boolean hasEqualXY(other) { other.x == getX() && other.y == getY() }
    - * 
    - * Then for the objects defined earlier, the following would be true: - *
    - * assert p1.hasEqualXY(t1) && t1.hasEqualXY(p1)
    - * assert p2.hasEqualXY(t1) && t1.hasEqualXY(p2)
    - * assert p3.hasEqualXY(t1) && t1.hasEqualXY(p3)
    - * 
    - * There is also support for including or excluding fields/properties by name when constructing - * the equals and hashCode methods as shown here: - *
    - * 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))
    - * 
    - * Note: {@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. - *

    More examples:

    - *
    - * import groovy.transform.EqualsAndHashCode
    - *
    - * @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
    - * 
    - * - * @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/transform/ExternalizeMethods.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/ExternalizeMethods.java b/src/main/groovy/transform/ExternalizeMethods.java deleted file mode 100644 index 5ef37a0..0000000 --- a/src/main/groovy/transform/ExternalizeMethods.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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. - *

    - * Example usage: - *

    - * import groovy.transform.*
    - * {@code @ExternalizeMethods}
    - * class Person {
    - *   String first, last
    - *   List favItems
    - *   Date since
    - * }
    - * 
    - * Which will create a class of the following form: - *
    - * 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()
    - *   }
    - *   ...
    - * }
    - * 
    - * - * @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/transform/ExternalizeVerifier.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/ExternalizeVerifier.java b/src/main/groovy/transform/ExternalizeVerifier.java deleted file mode 100644 index 185c935..0000000 --- a/src/main/groovy/transform/ExternalizeVerifier.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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/transform/Field.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/Field.java b/src/main/groovy/transform/Field.java deleted file mode 100644 index 546d045..0000000 --- a/src/main/groovy/transform/Field.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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. - *

    - * 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: - *

    - * import groovy.transform.Field
    - * {@code @Field} List awe = [1, 2, 3]
    - * def awesum() { awe.sum() }
    - * assert awesum() == 6
    - * 
    - * In this example, without the annotation, variable awe would be - * a local script variable (technically speaking it will be a local variable within - * the run method of the script class). Such a local variable would - * not be visible inside the awesum method. With the annotation, - * awe becomes a private List field in the script class and is - * visible within the awesum 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 { -} http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/transform/Generated.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/Generated.java b/src/main/groovy/transform/Generated.java deleted file mode 100644 index 98eaf5b..0000000 --- a/src/main/groovy/transform/Generated.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 Generated annotation is used to mark members that have been generated. - */ -@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE, ElementType.FIELD}) -@Retention(RetentionPolicy.RUNTIME) -public @interface Generated { -} http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/transform/Immutable.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/transform/Immutable.java b/src/main/groovy/transform/Immutable.java deleted file mode 100644 index 89876a4..0000000 --- a/src/main/groovy/transform/Immutable.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * 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 immutable classes. - *

    - * It allows you to write classes in this shortened form: - *

    - * {@code @groovy.transform.Immutable} class Customer {
    - *     String first, last
    - *     int age
    - *     Date since
    - *     Collection favItems
    - * }
    - * def d = new Date()
    - * def c1 = new Customer(first:'Tom', last:'Jones', age:21, since:d, favItems:['Books', 'Games'])
    - * def c2 = new Customer('Tom', 'Jones', 21, d, ['Books', 'Games'])
    - * assert c1 == c2
    - * 
    - * The {@code @Immutable} annotation instructs the compiler to execute an - * AST transformation which adds the necessary getters, constructors, - * equals, hashCode and other helper methods that are typically written - * when creating immutable classes with the defined properties. - *

    - * A class created in this way has the following characteristics: - *

      - *
    • The class is automatically made final. - *
    • Properties must be of an immutable type or a type with a strategy for handling non-immutable - * characteristics. Specifically, the type must be one of the primitive or wrapper types, Strings, enums, - * other {@code @Immutable} classes or known immutables (e.g. java.awt.Color, java.net.URI, java.util.UUID). - * Also handled are Cloneable classes, collections, maps and arrays, other "effectively immutable" - * classes with special handling (e.g. java.util.Date), and usages of java.util.Optional where the - * contained type is immutable (e.g. Optional<String>). - *
    • Properties automatically have private, final backing fields with getters. - * Attempts to update the property will result in a {@code ReadOnlyPropertyException}. - *
    • A map-based constructor is provided which allows you to set properties by name. - *
    • A tuple-style constructor is provided which allows you to set properties in the same order as they are defined. - *
    • Default {@code equals}, {@code hashCode} and {@code toString} methods are provided based on the property values. - * Though not normally required, you may write your own implementations of these methods. For {@code equals} and {@code hashCode}, - * if you do write your own method, it is up to you to obey the general contract for {@code equals} methods and supply - * a corresponding matching {@code hashCode} method. - * If you do provide one of these methods explicitly, the default implementation will be made available in a private - * "underscore" variant which you can call. E.g., you could provide a (not very elegant) multi-line formatted - * {@code toString} method for {@code Customer} above as follows: - *
      - *     String toString() {
      - *        _toString().replaceAll(/\(/, '(\n\t').replaceAll(/\)/, '\n)').replaceAll(/, /, '\n\t')
      - *    }
      - * 
      - * If an "underscore" version of the respective method already exists, then no default implementation is provided. - *
    • {@code Date}s, {@code Cloneable}s and arrays are defensively copied on the way in (constructor) and out (getters). - * Arrays and {@code Cloneable} objects use the {@code clone} method. For your own classes, - * it is up to you to define this method and use deep cloning if appropriate. - *
    • {@code Collection}s and {@code Map}s are wrapped by immutable wrapper classes (but not deeply cloned!). - * Attempts to update them will result in an {@code UnsupportedOperationException}. - *
    • Fields that are enums or other {@code @Immutable} classes are allowed but for an - * otherwise possible mutable property type, an error is thrown. - *
    • You don't have to follow Groovy's normal property conventions, e.g. you can create an explicit private field and - * then you can write explicit get and set methods. Such an approach, isn't currently prohibited (to give you some - * wiggle room to get around these conventions) but any fields created in this way are deemed not to be part of the - * significant state of the object and aren't factored into the {@code equals} or {@code hashCode} methods. - * Similarly, you may use static properties (though usually this is discouraged) and these too will be ignored - * as far as significant state is concerned. If you do break standard conventions, you do so at your own risk and - * your objects may no longer be immutable. It is up to you to ensure that your objects remain immutable at least - * to the extent expected in other parts of your program! - *
    - * Immutable classes are particularly useful for functional and concurrent styles of programming - * and for use as key values within maps. If you want similar functionality to what this annotation - * provides but don't need immutability then consider using {@code @Canonical}. - *

    - * Customising behaviour: - *

    - * You can customise the toString() method provided for you by {@code @Immutable} - * by also adding the {@code @ToString} annotation to your class definition. - *

    - * Limitations: - *

      - *
    • - * As outlined above, Arrays and {@code Cloneable} objects use the {@code clone} method. For your own classes, - * it is up to you to define this method and use deep cloning if appropriate. - *
    • - *
    • - * As outlined above, {@code Collection}s and {@code Map}s are wrapped by immutable wrapper classes (but not deeply cloned!). - *
    • - *
    • - * Currently {@code BigInteger} and {@code BigDecimal} are deemed immutable but see: - * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6348370 - *
    • - *
    • - * {@code java.awt.Color} is treated as "effectively immutable" but is not final so while not normally used with child - * classes, it isn't strictly immutable. Use at your own risk. - *
    • - *
    • - * {@code java.util.Date} is treated as "effectively immutable" but is not final so it isn't strictly immutable. - * Use at your own risk. - *
    • - *
    • - * Groovy's normal map-style naming conventions will not be available if the first property - * has type {@code LinkedHashMap} or if there is a single Map, AbstractMap or HashMap property. - *
    • - *
    - *

    More examples:

    - -------------------------------------------------------------------------------- - *
    - * import groovy.transform.*
    - *
    - * @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'
    - *
    - * @Canonical
    - * @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)'
    - * 
    - * - * @author Paul King - * @author Andre Steingress - * @see groovy.transform.ToString - * @see groovy.transform.Canonical - * @since 1.7 - */ -@java.lang.annotation.Documented -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE}) -@GroovyASTTransformationClass("org.codehaus.groovy.transform.ImmutableASTTransformation") -public @interface Immutable { - /** - * Allows you to provide {@code @Immutable} with a list of classes which - * are deemed immutable. By supplying a class in this list, you are vouching - * for its immutability and {@code @Immutable} will do no further checks. - * Example: - *
    -     * import groovy.transform.*
    -     * {@code @Immutable}(knownImmutableClasses = [Address])
    -     * class Person {
    -     *     String first, last
    -     *     Address address
    -     * }
    -     *
    -     * {@code @TupleConstructor}
    -     * class Address {
    -     *     final String street
    -     * }
    -     * 
    - * - * @since 1.8.7 - */ - Class[] knownImmutableClasses() default {}; - - /** - * Allows you to provide {@code @Immutable} with a list of property names which - * are deemed immutable. By supplying a property's name in this list, you are vouching - * for its immutability and {@code @Immutable} will do no further checks. - * Example: - *
    -     * {@code @groovy.transform.Immutable}(knownImmutables = ['address'])
    -     * class Person {
    -     *     String first, last
    -     *     Address address
    -     * }
    -     * ...
    -     * 
    - * - * @since 2.1.0 - */ - String[] knownImmutables() default {}; - - /** - * If {@code true}, this adds a method {@code copyWith} which takes a Map of - * new property values and returns a new instance of the Immutable class with - * these values set. - * Example: - *
    -     * {@code @groovy.transform.Immutable}(copyWith = true)
    -     * class Person {
    -     *     String first, last
    -     * }
    -     *
    -     * def tim   = new Person( 'tim', 'yates' )
    -     * def alice = tim.copyWith( first:'alice' )
    -     *
    -     * assert tim.first   == 'tim'
    -     * assert alice.first == 'alice'
    -     * 
    - * Unknown keys in the map are ignored, and if the values would not change - * the object, then the original object is returned. - * - * If a method called {@code copyWith} that takes a single parameter already - * exists in the class, then this setting is ignored, and no method is generated. - * - * @since 2.2.0 - */ - boolean copyWith() default false; -}