From 06537da4e0d1c420c6669f6ce1490ea56adc4d7d Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Mon, 18 Feb 2013 22:42:39 +0100 Subject: Changed @Value to no longer imply @Wither. Usually you want only a few or no withers at all, and adding them is a lot simpler than removing them. This is a breaking change, but then that's why @Value was in experimental in the first place. --- doc/changelog.markdown | 3 ++- src/core/lombok/eclipse/handlers/HandleValue.java | 1 - src/core/lombok/experimental/Value.java | 4 ++-- src/core/lombok/javac/handlers/HandleValue.java | 3 +-- .../resource/after-delombok/ValuePlain.java | 24 ---------------------- test/transform/resource/after-ecj/ValuePlain.java | 18 ---------------- .../experimental/ValueExample_post.jpage | 20 ------------------ website/features/experimental/Value.html | 20 +++++++----------- 8 files changed, 12 insertions(+), 81 deletions(-) diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 33a96226..95bcf8b2 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -2,7 +2,8 @@ Lombok Changelog ---------------- ### v0.11.7 (Edgy Guinea Pig) -* FEATURE: Reintroduced `onMethod`, `onConstructor` and `onParam` to `@Getter`, `@Setter`, `@Wither`, and `@XArgsConstructor`. These parameters allow you to add annotations to the methods/constructors that lombok will generate. This is a workaround feature: The stability of the feature on future versions of javac is not guaranteed, and if a better way to implement this feature is found, this feature's current incarnation will be removed without a reasonable period of deprecation. [Documentation on the onX feature](http://projectlombok.org/feature/onX.html) +* CHANGE: {Experimental} The experimental `@Value` feature no longer implies the also experimental `@Wither`. If you like your `@Value` classes to make withers, add `@Wither` to the class right next to `@Value`. +* FEATURE: {Experimental} Reintroduced `onMethod`, `onConstructor` and `onParam` to `@Getter`, `@Setter`, `@Wither`, and `@XArgsConstructor`. These parameters allow you to add annotations to the methods/constructors that lombok will generate. This is a workaround feature: The stability of the feature on future versions of javac is not guaranteed, and if a better way to implement this feature is found, this feature's current incarnation will be removed without a reasonable period of deprecation. [Documentation on the onX feature](http://projectlombok.org/feature/onX.html) ### v0.11.6 (October 30th, 2012) * FEATURE: Lombok can be disabled entirely for any given compile run by using JVM switch `-Dlombok.disable`. This might be useful for code style checkers and such. diff --git a/src/core/lombok/eclipse/handlers/HandleValue.java b/src/core/lombok/eclipse/handlers/HandleValue.java index b74fbede..b69b1669 100644 --- a/src/core/lombok/eclipse/handlers/HandleValue.java +++ b/src/core/lombok/eclipse/handlers/HandleValue.java @@ -76,7 +76,6 @@ public class HandleValue extends EclipseAnnotationHandler { //and hitting 'find callers'. new HandleGetter().generateGetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true); - new HandleWither().generateWitherForType(typeNode, annotationNode, AccessLevel.PUBLIC, true); new HandleEqualsAndHashCode().generateEqualsAndHashCodeForType(typeNode, annotationNode); new HandleToString().generateToStringForType(typeNode, annotationNode); new HandleConstructor().generateAllArgsConstructor(typeNode, AccessLevel.PUBLIC, ann.staticConstructor(), true, Collections.emptyList(), ast); diff --git a/src/core/lombok/experimental/Value.java b/src/core/lombok/experimental/Value.java index 6c07d2fc..048066df 100644 --- a/src/core/lombok/experimental/Value.java +++ b/src/core/lombok/experimental/Value.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 The Project Lombok Authors. + * Copyright (C) 2012-2013 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ import java.lang.annotation.Target; /** * Generates a lot of code which fits with a class that is a representation of an immutable entity. *

- * Equivalent to {@code @Getter @Wither @FieldDefaults(makeFinal=true, level=AccessLevel.PRIVATE) @RequiredArgsConstructor @ToString @EqualsAndHashCode}. + * Equivalent to {@code @Getter @FieldDefaults(makeFinal=true, level=AccessLevel.PRIVATE) @RequiredArgsConstructor @ToString @EqualsAndHashCode}. *

* Complete documentation is found at the project lombok features page for @Value. * diff --git a/src/core/lombok/javac/handlers/HandleValue.java b/src/core/lombok/javac/handlers/HandleValue.java index 8b0b9568..f5b10bc1 100644 --- a/src/core/lombok/javac/handlers/HandleValue.java +++ b/src/core/lombok/javac/handlers/HandleValue.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 The Project Lombok Authors. + * Copyright (C) 2012-2013 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -67,7 +67,6 @@ public class HandleValue extends JavacAnnotationHandler { // TODO move this to the end OR move it to the top in eclipse. new HandleConstructor().generateAllArgsConstructor(typeNode, AccessLevel.PUBLIC, staticConstructorName, true, annotationNode); new HandleGetter().generateGetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true); - new HandleWither().generateWitherForType(typeNode, annotationNode, AccessLevel.PUBLIC, true); new HandleEqualsAndHashCode().generateEqualsAndHashCodeForType(typeNode, annotationNode); new HandleToString().generateToStringForType(typeNode, annotationNode); } diff --git a/test/transform/resource/after-delombok/ValuePlain.java b/test/transform/resource/after-delombok/ValuePlain.java index ffeed858..d1cfa3d7 100644 --- a/test/transform/resource/after-delombok/ValuePlain.java +++ b/test/transform/resource/after-delombok/ValuePlain.java @@ -15,14 +15,6 @@ final class Value1 { public String getName() { return this.name; } - @java.lang.SuppressWarnings("all") - public Value1 withX(final int x) { - return this.x == x ? this : new Value1(x, this.name); - } - @java.lang.SuppressWarnings("all") - public Value1 withName(final String name) { - return this.name == name ? this : new Value1(this.x, name); - } @java.lang.Override @java.lang.SuppressWarnings("all") public boolean equals(final java.lang.Object o) { @@ -68,14 +60,6 @@ class Value2 { public String getName() { return this.name; } - @java.lang.SuppressWarnings("all") - public Value2 withX(final int x) { - return this.x == x ? this : new Value2(x, this.name); - } - @java.lang.SuppressWarnings("all") - public Value2 withName(final String name) { - return this.name == name ? this : new Value2(this.x, name); - } @java.lang.Override @java.lang.SuppressWarnings("all") public boolean equals(final java.lang.Object o) { @@ -126,14 +110,6 @@ final class Value3 { public int getY() { return this.y; } - @java.lang.SuppressWarnings("all") - public Value3 withX(final int x) { - return this.x == x ? this : new Value3(x, this.y); - } - @java.lang.SuppressWarnings("all") - public Value3 withY(final int y) { - return this.y == y ? this : new Value3(this.x, y); - } @java.lang.Override @java.lang.SuppressWarnings("all") public boolean equals(final java.lang.Object o) { diff --git a/test/transform/resource/after-ecj/ValuePlain.java b/test/transform/resource/after-ecj/ValuePlain.java index c8498a93..b798b308 100644 --- a/test/transform/resource/after-ecj/ValuePlain.java +++ b/test/transform/resource/after-ecj/ValuePlain.java @@ -8,12 +8,6 @@ final @lombok.experimental.Value class Value1 { public @java.lang.SuppressWarnings("all") String getName() { return this.name; } - public @java.lang.SuppressWarnings("all") Value1 withX(final int x) { - return ((this.x == x) ? this : new Value1(x, this.name)); - } - public @java.lang.SuppressWarnings("all") Value1 withName(final String name) { - return ((this.name == name) ? this : new Value1(this.x, name)); - } public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) { if ((o == this)) return true; @@ -54,12 +48,6 @@ final @lombok.experimental.Value class Value1 { public @java.lang.SuppressWarnings("all") String getName() { return this.name; } - public @java.lang.SuppressWarnings("all") Value2 withX(final int x) { - return ((this.x == x) ? this : new Value2(x, this.name)); - } - public @java.lang.SuppressWarnings("all") Value2 withName(final String name) { - return ((this.name == name) ? this : new Value2(this.x, name)); - } public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) { if ((o == this)) return true; @@ -105,12 +93,6 @@ final @Value class Value3 { public @java.lang.SuppressWarnings("all") int getY() { return this.y; } - public @java.lang.SuppressWarnings("all") Value3 withX(final int x) { - return ((this.x == x) ? this : new Value3(x, this.y)); - } - public @java.lang.SuppressWarnings("all") Value3 withY(final int y) { - return ((this.y == y) ? this : new Value3(this.x, y)); - } public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) { if ((o == this)) return true; diff --git a/usage_examples/experimental/ValueExample_post.jpage b/usage_examples/experimental/ValueExample_post.jpage index 47de72a5..ac9b64d1 100644 --- a/usage_examples/experimental/ValueExample_post.jpage +++ b/usage_examples/experimental/ValueExample_post.jpage @@ -30,18 +30,6 @@ public final class ValueExample { return this.tags; } - public ValueExample withName(String name) { - return this.name == name ? this : new ValueExample(name, age, score, tags); - } - - public ValueExample withScore(double score) { - return this.score == score ? this : new ValueExample(name, age, score, tags); - } - - public ValueExample withTags(String[] tags) { - return this.tags == tags ? this : new ValueExample(name, age, score, tags); - } - @java.lang.Override public boolean equals(Object o) { if (o == this) return true; @@ -99,14 +87,6 @@ public final class ValueExample { return this.value; } - public Exercise withName(String name) { - return this.name == name ? this : new Exercise(name, value); - } - - public Exercise withValue(T value) { - return this.value == value ? this : new Exercise(name, value); - } - @java.lang.Override public boolean equals(Object o) { if (o == this) return true; diff --git a/website/features/experimental/Value.html b/website/features/experimental/Value.html index fb726d7b..d2acfee4 100644 --- a/website/features/experimental/Value.html +++ b/website/features/experimental/Value.html @@ -15,8 +15,9 @@

Since

- @Value was introduced as experimental feature in lombok v0.11.4. -

+ @Value was introduced as experimental feature in lombok v0.11.4. +

+ @Value no longer implies @Wither since lombok v0.11.8.

Experimental

@@ -24,19 +25,16 @@ Experimental because:
  • Various choices still have to be vetted as being the correct 'least surprise' choice: Should the class be made final by default, etc.
  • -
  • Dependent on @Wither which is experimental.
Current status: positive - Currently we feel this feature may move out of experimental status with no or minor changes soon.

Overview

- @Value is the immutable variant of @Data; all fields are made private and final by default, and instead of setters, each field gets a so-called 'wither', - which is a method that produces a clone with each field having the same value, except for the field you want a new value for. The class itself is also made final by default, because immutability is not something that can - be forced onto a subclass. Like @Data, useful toString(), equals() and hashCode() methods are also generated, each field gets a getter method, and a constructor that covers every + @Value is the immutable variant of @Data; all fields are made private and final by default, and setters are not generated. The class itself is also made final by default, because immutability is not something that can be forced onto a subclass. Like @Data, useful toString(), equals() and hashCode() methods are also generated, each field gets a getter method, and a constructor that covers every argument (except final fields that are initialized in the field declaration) is also generated.

- In practice, @Value is shorthand for: final @ToString @EqualsAndHashCode @AllArgsConstructor @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @Getter @Wither. + In practice, @Value is shorthand for: final @ToString @EqualsAndHashCode @AllArgsConstructor @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @Getter.

It is possible to override the final-by-default and private-by-default behaviour using either an explicit access level on a field, or by using the @NonFinal or @PackagePrivate annotations.
It is possible to override any default behaviour for any of the 'parts' that make up @Value by explicitly using that annotation. @@ -57,13 +55,9 @@

Small print

- Look for the documentation on the 'parts' of @Value: @ToString, @EqualsAndHashCode, - @AllArgsConstructor, @FieldDefaults, @Getter, - @Wither. + Look for the documentation on the 'parts' of @Value: @ToString, @EqualsAndHashCode, @AllArgsConstructor, @FieldDefaults, and @Getter.

- For classes with generics, it's useful to have a static method which serves as a constructor, because inference of generic parameters via static methods works in java6 and avoids having to use the diamond operator. - While you can force this by applying an explicit @AllArgsConstructor annotation, there's also the @Value(staticConstructor="of") feature, which will make the generated all-arguments constructor - private, and generates a public static method named of which is a wrapper around this private constructor. + For classes with generics, it's useful to have a static method which serves as a constructor, because inference of generic parameters via static methods works in java6 and avoids having to use the diamond operator. While you can force this by applying an explicit @AllArgsConstructor(staticConstructor="of") annotation, there's also the @Value(staticConstructor="of") feature, which will make the generated all-arguments constructor private, and generates a public static method named of which is a wrapper around this private constructor.

-- cgit