groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pa...@apache.org
Subject groovy git commit: improve doco for immutable-related annotations
Date Sun, 04 Feb 2018 09:42:24 GMT
Repository: groovy
Updated Branches:
  refs/heads/GROOVY_2_6_X dd278d61c -> f347a8faf


improve doco for immutable-related annotations


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

Branch: refs/heads/GROOVY_2_6_X
Commit: f347a8faf83964cc3877390b9ddb3411cf42a487
Parents: dd278d6
Author: paulk <paulk@asert.com.au>
Authored: Sun Feb 4 18:41:57 2018 +1000
Committer: paulk <paulk@asert.com.au>
Committed: Sun Feb 4 19:42:11 2018 +1000

----------------------------------------------------------------------
 .../transform/ImmutableASTTransformation.java   |  4 +-
 src/spec/doc/core-metaprogramming.adoc          | 64 +++++++++++++++++---
 2 files changed, 57 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/f347a8fa/src/main/java/org/codehaus/groovy/transform/ImmutableASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/transform/ImmutableASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/ImmutableASTTransformation.java
index 9e25e18..79c7c46 100644
--- a/src/main/java/org/codehaus/groovy/transform/ImmutableASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/ImmutableASTTransformation.java
@@ -233,6 +233,7 @@ public class ImmutableASTTransformation extends AbstractASTTransformation
{
             if (unsupportedTupleAttribute(tupleCons, "includeProperties")) return;
             if (unsupportedTupleAttribute(tupleCons, "includeSuperFields")) return;
             if (unsupportedTupleAttribute(tupleCons, "callSuper")) return;
+            if (unsupportedTupleAttribute(tupleCons, "useSetters")) return;
             if (unsupportedTupleAttribute(tupleCons, "force")) return;
         }
         if (!validateConstructors(cNode)) return;
@@ -341,9 +342,9 @@ public class ImmutableASTTransformation extends AbstractASTTransformation
{
         return list.size() == 1 && list.get(0).getField().getType().equals(HASHMAP_TYPE);
     }
 
+    @Deprecated
     static List<PropertyNode> getProperties(ClassNode cNode, boolean includeSuperProperties,
boolean allProperties) {
         List<PropertyNode> list = getInstanceProperties(cNode);
-        //addPseudoProperties
         if (includeSuperProperties) {
             ClassNode next = cNode.getSuperClass();
             while (next != null) {
@@ -356,6 +357,7 @@ public class ImmutableASTTransformation extends AbstractASTTransformation
{
         return list;
     }
 
+    @Deprecated
     static void createConstructorOrdered(ClassNode cNode, List<PropertyNode> list)
{
         final MapExpression argMap = new MapExpression();
         final Parameter[] orderedParams = new Parameter[list.size()];

http://git-wip-us.apache.org/repos/asf/groovy/blob/f347a8fa/src/spec/doc/core-metaprogramming.adoc
----------------------------------------------------------------------
diff --git a/src/spec/doc/core-metaprogramming.adoc b/src/spec/doc/core-metaprogramming.adoc
index 94cca81..57f726f 100644
--- a/src/spec/doc/core-metaprogramming.adoc
+++ b/src/spec/doc/core-metaprogramming.adoc
@@ -1077,7 +1077,7 @@ annotations:
 include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=canonical_simple,indent=0]
 ----
 
-A similar immutable class can be generated using the <<xform-Immutable,@Immutable>>
AST transformation instead.
+A similar immutable class can be generated using the <<xform-Immutable,@Immutable>>
meta-annotation instead.
 The `@Canonical` meta-annotation supports the configuration options found in the annotations
 it aggregates. See those annotations for more details.
 
@@ -1698,24 +1698,57 @@ include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=del
 [[xform-Immutable]]
 ===== `@groovy.transform.Immutable`
 
-The `@Immutable` AST transformation simplifies the creation of immutable classes, that is
to say classes for which
-members are deemed immutable. For that, all you have to do is annotating the class like in
the following example:
+The `@Immutable` meta-annotation combines the following annotations:
+
+* <<xform-ToString,@ToString>>
+* <<xform-EqualsAndHashCode,@EqualsAndHashCode>>
+* <<xform-ImmutableBase,@ImmutableBase>>
+* <<xform-TupleConstructor,@TupleConstructor>>
+* <<xform-MapConstructor,@MapConstructor>>
+* <<xform-KnownImmutable,@KnownImmutable>>
+
+The `@Immutable` meta-annotation simplifies the creation of immutable classes. Immutable
classes are useful
+since they are often easier to reason about and are inherently thread-safe.
+See http://www.informit.com/store/effective-java-9780134685991[Effective Java, Minimize Mutability]
for all the details
+about how to achieve immutable classes in Java. The `@Immutable` meta-annotation does most
of the things described
+in _Effective Java_ for you automatically.
+To use the meta-annotation, all you have to do is annotate the class like in the following
example:
 
 [source,groovy]
 ----
 include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=immutable_simple,indent=0]
 ----
 
-Immutable classes generated with `@Immutable` are automatically made final. For a class to
be immutable, you have to
+One of the requirements for immutable classes is that there is no way to modify any state
information within the class.
+One requirement to achieve this is to use immutable classes for each property or alternatively
perform special coding
+such as defensive copy in and defensive copy out for any mutable properties within the constructors
+and property getters. Between `@ImmutableBase`, `@MapConstructor` and `@TupleConstructor`
properties
+are either identified as immutable or the special coding for numerous known cases is handled
automatically.
+Various mechanisms are provided for you to extend the handled property types which are allowed.
See
+`@ImmutableBase` and `@KnownImmutable` for details.
+
+The results of applying `@Immutable` to a class are pretty similar to those of
+applying the <<xform-Canonical,@Canonical>> meta-annotation but the generated
class will have extra
+logic to handle immutability. You will observe this by, for instance, trying to modify a
property
+which will result in a `ReadOnlyPropertyException` being thrown since the backing field for
the property
+will have been automatically made final.
+
+The `@Immutable` meta-annotation supports the configuration options found in the annotations
+it aggregates. See those annotations for more details.
+
+[[xform-ImmutableBase]]
+===== `@groovy.transform.ImmutableBase`
+
+Immutable classes generated with `@ImmutableBase` are automatically made final. Also, the
type of each property is checked
+and various checks are made on the class, for example, public instance fields currently aren't
allowed.
+
+For a class to be immutable, you have to
 make sure that properties are of an immutable type (primitive or boxed types), of a known-immutable
type or another
-class annotated with `@Immutable`. The effect of applying `@Immutable` to a class are pretty
similar to those of
-applying the <<xform-Canonical,@Canonical>> AST transformation, but with an immutable
class: automatic generation of
-`toString`, `equals` and `hashCode` methods for example, but trying to modify a property
would throw a `ReadOnlyPropertyException`
-in that case.
+class annotated with `@KnownImmutable` (which includes those annotated with the `@Immutable`
meta-annotation).
 
-Since `@Immutable` relies on a predefined list of known immutable classes (like `java.net.URI`
or `java.lang.String`
+Since `@ImmutableBase` relies on a predefined list of known immutable classes (like `java.net.URI`
or `java.lang.String`
 and fails if you use a type which is not in that list, you are allowed to instruct the transformation
that some types
-are deemed immutable thanks to the following parameters:
+are deemed immutable thanks to the following annotation attributes:
 
 [cols="1,1,2,3a",options="header"]
 |=======================================================================
@@ -1738,6 +1771,17 @@ include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=imm
 ----
 |=======================================================================
 
+If you deem a type as immutable and it isn't one of the ones automatically handled, then
it is up to you
+to correctly code that class to ensure immutability.
+
+[[xform-KnownImmutable]]
+===== `@groovy.transform.KnownImmutable`
+
+The `@KnownImmutable` annotation isn't actually one that triggers any AST transformations.
It is simply
+a marker annotation. You can annotate your classes with the annotation (including Java classes)
and they
+will be recognized as acceptable types for members within an immutable class. This saves
you having to
+explicitly use the `knownImmutables` or `knownImmutableClasses` annotation attributes from
`@ImmutableBase`.
+
 [[xform-Memoized]]
 ===== `@groovy.transform.Memoized`
 


Mime
View raw message