Repository: groovy
Updated Branches:
  refs/heads/master f86bf659a -> 7f7acff71


improve doco for @TupleConstructor


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/7f7acff7
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/7f7acff7
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/7f7acff7

Branch: refs/heads/master
Commit: 7f7acff7170042872aa5f5cfaa1676a7be07a869
Parents: f86bf65
Author: paulk <pa...@asert.com.au>
Authored: Sat Feb 3 16:15:38 2018 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Sat Feb 3 16:15:38 2018 +1000

----------------------------------------------------------------------
 .../groovy/transform/TupleConstructor.java      |  3 +-
 src/spec/doc/core-metaprogramming.adoc          | 57 +++++++++++++-------
 .../test/CodeGenerationASTTransformsTest.groovy | 19 ++++++-
 3 files changed, 59 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/7f7acff7/src/main/groovy/groovy/transform/TupleConstructor.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/transform/TupleConstructor.java 
b/src/main/groovy/groovy/transform/TupleConstructor.java
index cbc384d..d43f18b 100644
--- a/src/main/groovy/groovy/transform/TupleConstructor.java
+++ b/src/main/groovy/groovy/transform/TupleConstructor.java
@@ -188,7 +188,8 @@ public @interface TupleConstructor {
     String[] excludes() default {};
 
     /**
-     * List of field and/or property names to include within the constructor.
+     * List of field and/or property names to include within the constructor. 
The order of inclusion
+     * is determined by the order in which the names are specified.
      * 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;

http://git-wip-us.apache.org/repos/asf/groovy/blob/7f7acff7/src/spec/doc/core-metaprogramming.adoc
----------------------------------------------------------------------
diff --git a/src/spec/doc/core-metaprogramming.adoc 
b/src/spec/doc/core-metaprogramming.adoc
index f47d327..ec27f18 100644
--- a/src/spec/doc/core-metaprogramming.adoc
+++ b/src/spec/doc/core-metaprogramming.adoc
@@ -893,11 +893,19 @@ 
include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=
 ===== `@groovy.transform.TupleConstructor`
 
 The `@TupleConstructor` annotation aims at eliminating boilerplate code by 
generating constructors for you. A tuple
-constructor is created having a parameter for each property (and possibly 
fields). Each parameter has a default value
+constructor is created having a parameter for each property (and possibly each 
field). Each parameter has a default value
 (using the initial value of the property if present or otherwise Java's 
default value according to the properties type).
-In later compilation phases, the Groovy compiler's standard default value 
processing behavior is then applied.
-The end result is that multiple constructors are placed within the bytecode of 
your class. This provides a
-well understood semantics and is also useful for Java integration purposes. As 
an example, the
+
+===== Implementation Details
+
+Normally you don't need to understand the imp[ementation details of the 
generated constructor(s); you just use them in the normal way.
+However, if you want to add multiple constructors, understand Java integration 
options or meet requirements of some
+dependency injection frameworks, then some details are useful.
+
+As previously mentioned, the generated constructor has default values applied. 
In later compilation phases,
+the Groovy compiler's standard default value processing behavior is then 
applied.
+The end result is that multiple constructors are placed within the bytecode of 
your class.
+This provides a well understood semantics and is also useful for Java 
integration purposes. As an example, the
 following code will generate 3 constructors:
 
 [source,groovy]
@@ -920,9 +928,17 @@ Setting the `defaults` attribute (see the available 
configuration options table)
 * Map-style named arguments won't be available
 
 This attribute is normally only used in situations where another Java 
framework is
-expecting exactly one constructor, e.g. injection frameworks, JUnit 
parameterized runners.
+expecting exactly one constructor, e.g. injection frameworks or JUnit 
parameterized runners.
+
+===== Immutability support
+
+If the `@ImmutableBase` annotation (normally added by the `@Immutable` 
meta-annotation) is also found on the class with the `@TupleConstructor` 
annotation,
+then the generated constructor will have all the necessary logic required for 
immutable classes (defensive copy in, cloning, etc.). Some of the
+annotation attributes won't be supported in this case.
 
-The `@TupleConstructor` AST transformation accepts several configuration 
options:
+===== Customization options
+
+The `@TupleConstructor` AST transformation accepts several annotation 
attributes:
 
 [cols="1,1,2,3a",options="header"]
 |=======================================================================
@@ -937,26 +953,26 @@ 
include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=
 ----
 
include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includes,indent=0]
 ----
-|includeFields|False|Should fields be included in tuple constructor 
generation, in addition to properties|
-[source,groovy]
-----
-include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includeFields,indent=0]
-----
 |includeProperties|True|Should properties be included in tuple constructor 
generation|
 [source,groovy]
 ----
 
include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includeProperties,indent=0]
 ----
-|includeSuperFields|False|Should fields from super classes be included in 
tuple constructor generation|
+|includeFields|False|Should fields be included in tuple constructor 
generation, in addition to properties|
 [source,groovy]
 ----
-include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includeSuperFields,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includeFields,indent=0]
 ----
 |includeSuperProperties|True|Should properties from super classes be included 
in tuple constructor generation|
 [source,groovy]
 ----
 
include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includeSuperProperties,indent=0]
 ----
+|includeSuperFields|False|Should fields from super classes be included in 
tuple constructor generation|
+[source,groovy]
+----
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includeSuperFields,indent=0]
+----
 |callSuper|False|Should super properties be called within a call to the parent 
constructor rather than set as properties|
 [source,groovy]
 ----
@@ -968,6 +984,12 @@ true, the constructor will be generated and it's your 
responsibility to ensure t
 ----
 
include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_force,indent=0]
 ----
+|defaults|True|Indicates that default value processing is enabled for 
constructor parameters.
+Set to false to obtain exactly one constructor but with initial value support 
and named-arguments disabled. |
+[source,groovy]
+----
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_defaults_false,indent=0]
+----
 |useSetters|False|By default, the transformation will directly set the backing 
field of each property
 from its corresponding constructor parameter. Setting this attribute to true, 
the constructor will instead call setters if
 they exist. It's usually deemed bad style from within a constructor to call 
setters that can be overridden. It's your
@@ -976,16 +998,15 @@ responsibility to avoid such bad style.|
 ----
 
include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_useSetters,indent=0]
 ----
-|defaults|True|Indicates that default value processing is enabled for 
constructor parameters.
-Set to false to obtain exactly one constructor but with initial value support 
and named-arguments disabled. |
+|allNames|False|Should fields and/or properties with internal names be 
included within the constructor|
 [source,groovy]
 ----
-include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_defaults_false,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_allNames,indent=0]
 ----
-|allNames|False|Should fields and/or properties with internal names be 
included within the constructor|
+|allProperties|False|Should JavaBean properties be included within the 
constructor|
 [source,groovy]
 ----
-include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_allNames,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_allProperties,indent=0]
 ----
 |pre|empty|A closure containing statements to be inserted at the start of the 
generated constructor(s)|
 [source,groovy]

http://git-wip-us.apache.org/repos/asf/groovy/blob/7f7acff7/src/spec/test/CodeGenerationASTTransformsTest.groovy
----------------------------------------------------------------------
diff --git a/src/spec/test/CodeGenerationASTTransformsTest.groovy 
b/src/spec/test/CodeGenerationASTTransformsTest.groovy
index f6332ca..85af1d5 100644
--- a/src/spec/test/CodeGenerationASTTransformsTest.groovy
+++ b/src/spec/test/CodeGenerationASTTransformsTest.groovy
@@ -399,7 +399,6 @@ def p1 = new Person(firstName: 'Jack', lastName: 
'Nicholson')
 def p2 = new Person('Jack', 'Nicholson')
 // generated tuple constructor with default value for second property
 def p3 = new Person('Jack')
-
 // end::tupleconstructor_simple[]
 
 assert p1.firstName == p2.firstName
@@ -617,6 +616,24 @@ assert new Person('john', 'smith').toString() == 
'Person(john smith)'
 '''
 
         assertScript '''
+import groovy.transform.TupleConstructor
+
+// tag::tupleconstructor_example_allProperties[]
+@TupleConstructor(allProperties=true)
+class Person {
+    String first
+    private String last
+    void setLast(String last) {
+        this.last = last
+    }
+    String getName() { "$first $last" }
+}
+
+assert new Person('john', 'smith').name == 'john smith'
+// end::tupleconstructor_example_allProperties[]
+'''
+
+        assertScript '''
 // tag::tupleconstructor_example_useSetters[]
 import groovy.transform.*
 

Reply via email to