You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2016/03/02 20:25:02 UTC
[2/2] groovy git commit: More example code to show usage of
annotations based on MrHaki's Groovy Goodness blog posts (closes #275,
closes #271)
More example code to show usage of annotations based on MrHaki's Groovy Goodness blog posts (closes #275, closes #271)
* More examples for API doc readers to understand how to use the annotations.
* Used HTML entity code for @-symbol instead of enclosing in {@code...} block.
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/120aee12
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/120aee12
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/120aee12
Branch: refs/heads/master
Commit: 120aee1226f8dbe2b7eb42ea77f9239e520c7103
Parents: 80d1364
Author: Hubert Klein Ikkink <h....@gmail.com>
Authored: Wed Mar 2 15:44:52 2016 +0100
Committer: pascalschumacher <pa...@gmx.net>
Committed: Wed Mar 2 20:15:58 2016 +0100
----------------------------------------------------------------------
.../groovy/transform/AnnotationCollector.java | 94 ++++++++++++++++++++
src/main/groovy/transform/BaseScript.java | 56 ++++++++++++
.../groovy/transform/EqualsAndHashCode.java | 25 ++++++
src/main/groovy/transform/Immutable.java | 44 +++++++++
src/main/groovy/transform/ToString.java | 16 ++--
src/main/groovy/transform/TupleConstructor.java | 10 +--
6 files changed, 232 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/120aee12/src/main/groovy/transform/AnnotationCollector.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/transform/AnnotationCollector.java b/src/main/groovy/transform/AnnotationCollector.java
index 01a9b73..23a7335 100644
--- a/src/main/groovy/transform/AnnotationCollector.java
+++ b/src/main/groovy/transform/AnnotationCollector.java
@@ -73,6 +73,100 @@ import java.lang.annotation.Target;
* 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>
+ * //--------------------------------------------------------------------------
+ * @AnnotationCollector([EqualsAndHashCode, ToString])
+ * @interface Simple {}
+ *
+ *
+ * @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.
+ * @Simple(excludes = 'street')
+ * class Address {
+ * String street, town
+ * }
+ *
+ * def address = new Address(street: 'Evergreen Terrace', town: 'Springfield')
+ * assert address.toString() == 'Address(Springfield)'
+ * </pre>
+ * <pre>
+ * //--------------------------------------------------------------------------
+ * // 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<AnnotationNode> 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.*
+ *
+ * @AnnotationCollector(value = [EqualsAndHashCode, ToString], processor = 'SimpleProcessor')
+ * @interface Simple {}
+ *
+ *
+ * @Simple(dontUse = 'age')
+ * class User {
+ * String username
+ * int age
+ * }
+ *
+ * def user = new User(username: 'mrhaki', age: 39)
+ * assert user.toString() == 'User(mrhaki)'
+ * '''
+ * </pre>
+ * <pre>
+ * //--------------------------------------------------------------------------
+ * // Use AnnotationCollector as last annotation to group the
+ * // previous annotations.
+ * @EqualsAndHashCode
+ * @ToString
+ * @AnnotationCollector
+ * @interface Simple {}
+ *
+ *
+ * @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
http://git-wip-us.apache.org/repos/asf/groovy/blob/120aee12/src/main/groovy/transform/BaseScript.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/transform/BaseScript.java b/src/main/groovy/transform/BaseScript.java
index 5eb3a7a..af3e594 100644
--- a/src/main/groovy/transform/BaseScript.java
+++ b/src/main/groovy/transform/BaseScript.java
@@ -84,6 +84,62 @@ import java.lang.annotation.Target;
* 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>
+ * // 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'
+ * </pre>
+ *
* @author Paul King
* @author Vladimir Orany
* @author Jim White
http://git-wip-us.apache.org/repos/asf/groovy/blob/120aee12/src/main/groovy/transform/EqualsAndHashCode.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/transform/EqualsAndHashCode.java b/src/main/groovy/transform/EqualsAndHashCode.java
index 51bd1b5..2c75279 100644
--- a/src/main/groovy/transform/EqualsAndHashCode.java
+++ b/src/main/groovy/transform/EqualsAndHashCode.java
@@ -192,6 +192,31 @@ import java.lang.annotation.Target;
* 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>
+ * 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
+ * </pre>
*
* @see org.codehaus.groovy.util.HashCodeHelper
* @author Paul King
http://git-wip-us.apache.org/repos/asf/groovy/blob/120aee12/src/main/groovy/transform/Immutable.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/transform/Immutable.java b/src/main/groovy/transform/Immutable.java
index 0cbffdc..314abbc 100644
--- a/src/main/groovy/transform/Immutable.java
+++ b/src/main/groovy/transform/Immutable.java
@@ -122,6 +122,50 @@ import java.lang.annotation.Target;
* has type {@code LinkedHashMap} or if there is a single Map, AbstractMap or HashMap property.
* </li>
* </ul>
+ * <p>More examples:</p>
+ --------------------------------------------------------------------------------
+ * <pre>
+ * 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)'
+ * </pre>
*
* @author Paul King
* @author Andre Steingress
http://git-wip-us.apache.org/repos/asf/groovy/blob/120aee12/src/main/groovy/transform/ToString.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/transform/ToString.java b/src/main/groovy/transform/ToString.java
index 342a363..1d56f5f 100644
--- a/src/main/groovy/transform/ToString.java
+++ b/src/main/groovy/transform/ToString.java
@@ -134,7 +134,7 @@ import java.lang.annotation.Target;
* // includeNames to output the names of the properties.
* import groovy.transform.ToString
*
- * {@code @ToString(includeNames=true)}
+ * @@ToString(includeNames=true)
* class Person {
* String name
* List likes
@@ -150,7 +150,7 @@ import java.lang.annotation.Target;
* // includeFields to not only output properties, but also field values.
* import groovy.transform.ToString
*
- * {@code @ToString(includeNames=true, includeFields=true)}
+ * @ToString(includeNames=true, includeFields=true)
* class Person {
* String name
* List likes
@@ -166,14 +166,14 @@ import java.lang.annotation.Target;
* // Use includeSuper to include properties from super class in output.
* import groovy.transform.ToString
*
- * {@code @ToString(includeNames=true)}
+ * @ToString(includeNames=true)
* class Person {
* String name
* List likes
* private boolean active = false
* }
*
- * {@code @ToString(includeSuper=true, includeNames=true)}
+ * @ToString(includeSuper=true, includeNames=true)
* class Student extends Person {
* List courses
* }
@@ -187,7 +187,7 @@ import java.lang.annotation.Target;
* // excludes active field and likes property from output
* import groovy.transform.ToString
*
- * {@code @ToString(includeNames=true, includeFields=true, excludes='active,likes')}
+ * @ToString(includeNames=true, includeFields=true, excludes='active,likes')
* class Person {
* String name
* List likes
@@ -205,7 +205,7 @@ import java.lang.annotation.Target;
*
* import groovy.transform.*
*
- * {@code @ToString(includePackage=false)}
+ * @ToString(includePackage=false)
* class Course {
* String title
* Integer maxAttendees
@@ -222,7 +222,7 @@ import java.lang.annotation.Target;
*
* import groovy.transform.*
*
- * {@code @ToString(ignoreNulls=true)}
+ * @ToString(ignoreNulls=true)
* class Course {
* String title
* Integer maxAttendees
@@ -239,7 +239,7 @@ import java.lang.annotation.Target;
*
* import groovy.transform.*
*
- * {@code @ToString(cache=true)}
+ * @@ToString(cache=true)
* class Course {
* String title
* Integer maxAttendees
http://git-wip-us.apache.org/repos/asf/groovy/blob/120aee12/src/main/groovy/transform/TupleConstructor.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/transform/TupleConstructor.java b/src/main/groovy/transform/TupleConstructor.java
index 2d7ac9d..e472667 100644
--- a/src/main/groovy/transform/TupleConstructor.java
+++ b/src/main/groovy/transform/TupleConstructor.java
@@ -60,7 +60,7 @@ import java.lang.annotation.Target;
* //--------------------------------------------------------------------------
* import groovy.transform.TupleConstructor
*
- * {@code @TupleConstructor()}
+ * @TupleConstructor()
* class Person {
* String name
* List likes
@@ -82,7 +82,7 @@ import java.lang.annotation.Target;
* // includeFields in the constructor creation.
* import groovy.transform.TupleConstructor
*
- * {@code @TupleConstructor(includeFields=true)}
+ * @TupleConstructor(includeFields=true)
* class Person {
* String name
* List likes
@@ -103,7 +103,7 @@ import java.lang.annotation.Target;
* // even if we define our own constructors.
* import groovy.transform.TupleConstructor
*
- * {@code @TupleConstructor(force=true)}
+ * @TupleConstructor(force=true)
* class Person {
* String name
* List likes
@@ -131,7 +131,7 @@ import java.lang.annotation.Target;
* // include properties and fields from super class.
* import groovy.transform.TupleConstructor
*
- * {@code @TupleConstructor(includeFields=true)}
+ * @TupleConstructor(includeFields=true)
* class Person {
* String name
* List likes
@@ -140,7 +140,7 @@ import java.lang.annotation.Target;
* boolean isActivated() { active }
* }
*
- * {@code @TupleConstructor(callSuper=true, includeSuperProperties=true, includeSuperFields=true)}
+ * @TupleConstructor(callSuper=true, includeSuperProperties=true, includeSuperFields=true)
* class Student extends Person {
* List courses
* }