diff options
21 files changed, 116 insertions, 24 deletions
diff --git a/doc/changelog.markdown b/doc/changelog.markdown index af6afad4..d5aa7ba1 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -1,11 +1,15 @@ Lombok Changelog ---------------- -### v1.16.11 "Edgy Guinea Pig" -* v1.16.10 is the latest release +### v1.16.13 "Edgy Guinea Pig" +* v1.16.12 is the latest stable release of Project Lombok. + +### v1.16.12 (December 5th, 2016) * FEATURE: `var` is the mutable sister of `val`. For now experimental, and opt-in using `ALLOW` in the flagUsage configuration key. Thanks for the contribution, Bulgakov Alexander. -* BUGFIX: Annotation Processors that use ecj internally (dagger) no longer give linkage errors [Issue #1218](https://github.com/rzwitserloot/lombok/issues/1218) +* CHANGE: `@Value` and `@FieldDefaults` no longer touch static fields [Issue #1254](https://github.com/rzwitserloot/lombok/issues/1254) * BUGFIX: `val` in lambda expressions now work as expected [Issue #911](https://github.com/rzwitserloot/lombok/issues/911) +* BUGFIX: `Getter(lazy=true)` now emits an error message when used on a transient field [Issue #1236](https://github.com/rzwitserloot/lombok/issues/1236) +* BUGFIX: Annotation Processors that use ecj internally (dagger) no longer give linkage errors [Issue #1218](https://github.com/rzwitserloot/lombok/issues/1218) * PLATFORM: Red Hat JBoss Developer Studio is now correctly identified by the installer [Issue #1164](https://github.com/rzwitserloot/lombok/issues/1164) * BUGFIX: delombok: for-loops with initializers that are not local variables would be generated incorrectly [Issue #1076](https://github.com/rzwitserloot/lombok/issues/1076) diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java index 20b10601..4fdb7216 100644 --- a/src/core/lombok/core/Version.java +++ b/src/core/lombok/core/Version.java @@ -30,7 +30,7 @@ public class Version { // ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries). // Note: In 'X.Y.Z', if Z is odd, its a snapshot build built from the repository, so many different 0.10.3 versions can exist, for example. // Official builds always end in an even number. (Since 0.10.2). - private static final String VERSION = "1.16.11"; + private static final String VERSION = "1.16.13"; private static final String RELEASE_NAME = "Edgy Guinea Pig"; // private static final String RELEASE_NAME = "Candid Duck"; diff --git a/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java b/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java index 5ea5a210..702713fe 100644 --- a/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java +++ b/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2014 The Project Lombok Authors. + * Copyright (C) 2012-2016 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 @@ -97,14 +97,16 @@ public class HandleFieldDefaults extends EclipseASTAdapter { if (level != null && level != AccessLevel.NONE) { if ((field.modifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected)) == 0) { if (!hasAnnotation(PackagePrivate.class, fieldNode)) { - field.modifiers |= EclipseHandlerUtil.toEclipseModifier(level); + if ((field.modifiers & ClassFileConstants.AccStatic) == 0) { + field.modifiers |= EclipseHandlerUtil.toEclipseModifier(level); + } } } } if (makeFinal && (field.modifiers & ClassFileConstants.AccFinal) == 0) { if (!hasAnnotation(NonFinal.class, fieldNode)) { - if ((field.modifiers & ClassFileConstants.AccStatic) == 0 || field.initialization != null) { + if ((field.modifiers & ClassFileConstants.AccStatic) == 0) { field.modifiers |= ClassFileConstants.AccFinal; } } diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java index 14f2fb72..77d678f2 100644 --- a/src/core/lombok/eclipse/handlers/HandleGetter.java +++ b/src/core/lombok/eclipse/handlers/HandleGetter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2014 The Project Lombok Authors. + * Copyright (C) 2009-2016 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 @@ -183,6 +183,10 @@ public class HandleGetter extends EclipseAnnotationHandler<Getter> { errorNode.addError("'lazy' requires the field to be private and final."); return; } + if ((field.modifiers & ClassFileConstants.AccTransient) != 0) { + errorNode.addError("'lazy' is not supported on transient fields."); + return; + } if (field.initialization == null) { errorNode.addError("'lazy' requires field initialization."); return; diff --git a/src/core/lombok/experimental/FieldDefaults.java b/src/core/lombok/experimental/FieldDefaults.java index dbc4993b..384abda5 100644 --- a/src/core/lombok/experimental/FieldDefaults.java +++ b/src/core/lombok/experimental/FieldDefaults.java @@ -33,9 +33,9 @@ import lombok.AccessLevel; * <p> * Complete documentation is found at <a href="https://projectlombok.org/features/experimental/FieldDefaults.html">the project lombok features page for @FieldDefaults</a>. * <p> - * If {@code makeFinal} is {@code true}, then each field that is not annotated with {@code @NonFinal} will have the {@code final} modifier added. + * If {@code makeFinal} is {@code true}, then each (instance) field that is not annotated with {@code @NonFinal} will have the {@code final} modifier added. * <p> - * If {@code level} is set, then each field that is package private (i.e. no access modifier) and does not have the {@code @PackagePrivate} annotation will + * If {@code level} is set, then each (instance) field that is package private (i.e. no access modifier) and does not have the {@code @PackagePrivate} annotation will * have the appropriate access level modifier added. */ @Target(ElementType.TYPE) diff --git a/src/core/lombok/experimental/NonFinal.java b/src/core/lombok/experimental/NonFinal.java index 0c31dd2a..12a45d22 100644 --- a/src/core/lombok/experimental/NonFinal.java +++ b/src/core/lombok/experimental/NonFinal.java @@ -28,7 +28,7 @@ import java.lang.annotation.Target; /** * Used to indicate the explicit intention for the annotated entity to <em>not</em> be {@code final}. - * Currently used by {@code FieldDefaults} to avoid having it make a field final. + * Currently used by {@code FieldDefaults} and {@code Value} to avoid having it make a field final. */ @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.SOURCE) diff --git a/src/core/lombok/experimental/PackagePrivate.java b/src/core/lombok/experimental/PackagePrivate.java index bfe5638b..42002818 100644 --- a/src/core/lombok/experimental/PackagePrivate.java +++ b/src/core/lombok/experimental/PackagePrivate.java @@ -28,7 +28,7 @@ import java.lang.annotation.Target; /** * Used to indicate the explicit intention for the annotated entity to have the <em>package private</em> access level. - * Currently used by {@code FieldDefaults} to avoid having it make a field one of {@code public}, {@code protected}, or {@code private}. + * Currently used by {@code FieldDefaults} and {@code Value} to avoid having it make a field one of {@code public}, {@code protected}, or {@code private}. */ @Target({ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.SOURCE) diff --git a/src/core/lombok/javac/handlers/HandleFieldDefaults.java b/src/core/lombok/javac/handlers/HandleFieldDefaults.java index 12c22059..52f6c39c 100644 --- a/src/core/lombok/javac/handlers/HandleFieldDefaults.java +++ b/src/core/lombok/javac/handlers/HandleFieldDefaults.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2015 The Project Lombok Authors. + * Copyright (C) 2012-2016 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 @@ -84,14 +84,16 @@ public class HandleFieldDefaults extends JavacASTAdapter { if (level != null && level != AccessLevel.NONE) { if ((field.mods.flags & (Flags.PUBLIC | Flags.PRIVATE | Flags.PROTECTED)) == 0) { if (!hasAnnotationAndDeleteIfNeccessary(PackagePrivate.class, fieldNode)) { - field.mods.flags |= toJavacModifier(level); + if ((field.mods.flags & Flags.STATIC) == 0) { + field.mods.flags |= toJavacModifier(level); + } } } } if (makeFinal && (field.mods.flags & Flags.FINAL) == 0) { if (!hasAnnotationAndDeleteIfNeccessary(NonFinal.class, fieldNode)) { - if ((field.mods.flags & Flags.STATIC) == 0 || field.init != null) { + if ((field.mods.flags & Flags.STATIC) == 0) { field.mods.flags |= Flags.FINAL; } } diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index a330dbc1..0a2fe362 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2014 The Project Lombok Authors. + * Copyright (C) 2009-2016 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 @@ -182,6 +182,10 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { source.addError("'lazy' requires the field to be private and final."); return; } + if ((fieldDecl.mods.flags & Flags.TRANSIENT) != 0) { + source.addError("'lazy' is not supported on transient fields."); + return; + } if (fieldDecl.init == null) { source.addError("'lazy' requires field initialization."); return; diff --git a/test/transform/resource/after-delombok/FieldDefaults.java b/test/transform/resource/after-delombok/FieldDefaults.java index 8a84f442..6f866a9a 100644 --- a/test/transform/resource/after-delombok/FieldDefaults.java +++ b/test/transform/resource/after-delombok/FieldDefaults.java @@ -1,4 +1,5 @@ class FieldDefaults1 { + static int STATIC = 3; final int x; int y; FieldDefaults1(int x) { @@ -6,6 +7,7 @@ class FieldDefaults1 { } } class FieldDefaults2 { + static int STATIC = 3; int x; private int y; }
\ No newline at end of file diff --git a/test/transform/resource/after-delombok/GetterLazyTransient.java b/test/transform/resource/after-delombok/GetterLazyTransient.java new file mode 100644 index 00000000..dbebad90 --- /dev/null +++ b/test/transform/resource/after-delombok/GetterLazyTransient.java @@ -0,0 +1,26 @@ +class GetterLazyTransient { + private final java.util.concurrent.atomic.AtomicReference<java.lang.Object> nonTransientField = new java.util.concurrent.atomic.AtomicReference<java.lang.Object>(); + private final transient int transientField = 2; + private final transient int nonLazyTransientField = 3; + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public int getNonTransientField() { + java.lang.Object value = this.nonTransientField.get(); + if (value == null) { + synchronized (this.nonTransientField) { + value = this.nonTransientField.get(); + if (value == null) { + final int actualValue = 1; + value = actualValue; + this.nonTransientField.set(value); + } + } + } + return (java.lang.Integer) value; + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public int getNonLazyTransientField() { + return this.nonLazyTransientField; + } +} diff --git a/test/transform/resource/after-delombok/ValueStaticField.java b/test/transform/resource/after-delombok/ValueStaticField.java index cec136f4..b4d60724 100644 --- a/test/transform/resource/after-delombok/ValueStaticField.java +++ b/test/transform/resource/after-delombok/ValueStaticField.java @@ -1,6 +1,6 @@ final class ValueStaticField { - private static int x; - private static final String PASSWORD = "Ken sent me"; + static int x; + static String PASSWORD = "Ken sent me"; @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") public ValueStaticField() { diff --git a/test/transform/resource/after-ecj/FieldDefaults.java b/test/transform/resource/after-ecj/FieldDefaults.java index e76c1251..a6941b7b 100644 --- a/test/transform/resource/after-ecj/FieldDefaults.java +++ b/test/transform/resource/after-ecj/FieldDefaults.java @@ -1,14 +1,20 @@ @lombok.experimental.FieldDefaults(makeFinal = true) class FieldDefaults1 { + static int STATIC = 3; final int x; @lombok.experimental.NonFinal int y; + <clinit>() { + } FieldDefaults1(int x) { super(); this.x = x; } } @lombok.experimental.FieldDefaults(level = lombok.AccessLevel.PRIVATE) class FieldDefaults2 { + static int STATIC = 3; @lombok.experimental.PackagePrivate int x; private int y; + <clinit>() { + } FieldDefaults2() { super(); } diff --git a/test/transform/resource/after-ecj/GetterLazyTransient.java b/test/transform/resource/after-ecj/GetterLazyTransient.java new file mode 100644 index 00000000..9bc0d9ae --- /dev/null +++ b/test/transform/resource/after-ecj/GetterLazyTransient.java @@ -0,0 +1,28 @@ +class GetterLazyTransient { + private final @lombok.Getter(lazy = true) java.util.concurrent.atomic.AtomicReference<java.lang.Object> nonTransientField = new java.util.concurrent.atomic.AtomicReference<java.lang.Object>(); + private final transient @lombok.Getter(lazy = true) int transientField = 2; + private final transient @lombok.Getter int nonLazyTransientField = 3; + GetterLazyTransient() { + super(); + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") int getNonTransientField() { + java.lang.Object value = this.nonTransientField.get(); + if ((value == null)) + { + synchronized (this.nonTransientField) + { + value = this.nonTransientField.get(); + if ((value == null)) + { + final int actualValue = 1; + value = actualValue; + this.nonTransientField.set(value); + } + } + } + return (java.lang.Integer) value; + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") int getNonLazyTransientField() { + return this.nonLazyTransientField; + } +}
\ No newline at end of file diff --git a/test/transform/resource/after-ecj/ValueStaticField.java b/test/transform/resource/after-ecj/ValueStaticField.java index 4ce84a02..75e337ce 100644 --- a/test/transform/resource/after-ecj/ValueStaticField.java +++ b/test/transform/resource/after-ecj/ValueStaticField.java @@ -1,7 +1,7 @@ import lombok.Value; final @Value class ValueStaticField { - private static int x; - private static final String PASSWORD = "Ken sent me"; + static int x; + static String PASSWORD = "Ken sent me"; <clinit>() { } public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") boolean equals(final java.lang.Object o) { diff --git a/test/transform/resource/before/FieldDefaults.java b/test/transform/resource/before/FieldDefaults.java index ffe89734..97389411 100644 --- a/test/transform/resource/before/FieldDefaults.java +++ b/test/transform/resource/before/FieldDefaults.java @@ -1,5 +1,6 @@ @lombok.experimental.FieldDefaults(makeFinal = true) class FieldDefaults1 { + static int STATIC = 3; int x; @lombok.experimental.NonFinal int y; @@ -10,6 +11,7 @@ class FieldDefaults1 { @lombok.experimental.FieldDefaults(level = lombok.AccessLevel.PRIVATE) class FieldDefaults2 { + static int STATIC = 3; @lombok.experimental.PackagePrivate int x; int y; }
\ No newline at end of file diff --git a/test/transform/resource/before/GetterLazyTransient.java b/test/transform/resource/before/GetterLazyTransient.java new file mode 100644 index 00000000..1a913669 --- /dev/null +++ b/test/transform/resource/before/GetterLazyTransient.java @@ -0,0 +1,10 @@ +class GetterLazyTransient { + @lombok.Getter(lazy=true) + private final int nonTransientField = 1; + + @lombok.Getter(lazy=true) + private final transient int transientField = 2; + + @lombok.Getter + private final transient int nonLazyTransientField = 3; +} diff --git a/test/transform/resource/messages-delombok/GetterLazyTransient.java.messages b/test/transform/resource/messages-delombok/GetterLazyTransient.java.messages new file mode 100644 index 00000000..8c1873eb --- /dev/null +++ b/test/transform/resource/messages-delombok/GetterLazyTransient.java.messages @@ -0,0 +1 @@ +5 'lazy' is not supported on transient fields.
\ No newline at end of file diff --git a/test/transform/resource/messages-ecj/GetterLazyTransient.java.messages b/test/transform/resource/messages-ecj/GetterLazyTransient.java.messages new file mode 100644 index 00000000..8c1873eb --- /dev/null +++ b/test/transform/resource/messages-ecj/GetterLazyTransient.java.messages @@ -0,0 +1 @@ +5 'lazy' is not supported on transient fields.
\ No newline at end of file diff --git a/website/features/Value.html b/website/features/Value.html index 3bae89fc..6c86a77b 100644 --- a/website/features/Value.html +++ b/website/features/Value.html @@ -30,8 +30,8 @@ </p><p> In practice, <code>@Value</code> is shorthand for: <code>final @ToString @EqualsAndHashCode @AllArgsConstructor @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @Getter</code>, except that explicitly including an implementation of any of the relevant methods simply means that part won't be generated and no warning will be emitted. For example, if you write your own <code>toString</code>, no error occurs, and lombok will not generate a <code>toString</code>. Also, <em>any</em> explicit constructor, no matter the arguments list, implies lombok will not generate a constructor. If you do want lombok to generate the all-args constructor, add <code>@AllArgsConstructor</code> to the class. You can mark any constructor or method with <code>@lombok.experimental.Tolerate</code> to hide them from lombok. </p><p> - 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 <code>@NonFinal</code> or <code>@PackagePrivate</code> annotations.<br /> - It is possible to override any default behaviour for any of the 'parts' that make up <code>@Value</code> by explicitly using that annotation. + It is possible to override the final-by-default and private-by-default behavior using either an explicit access level on a field, or by using the <code>@NonFinal</code> or <code>@PackagePrivate</code> annotations.<br /> + It is possible to override any default behavior for any of the 'parts' that make up <code>@Value</code> by explicitly using that annotation. </p> </div> <div class="snippets"> diff --git a/website/features/experimental/FieldDefaults.html b/website/features/experimental/FieldDefaults.html index 90d5ae6d..a253198b 100644 --- a/website/features/experimental/FieldDefaults.html +++ b/website/features/experimental/FieldDefaults.html @@ -36,10 +36,10 @@ to each field in the annotated class or enum. It can also add <code>final</code> to each field in the annotated class or enum. </p> </p><p> - To add <code>final</code> to each field, use <code>@FieldDefaults(makeFinal=true)</code>. Any non-final field which must remain nonfinal + To add <code>final</code> to each (instance) field, use <code>@FieldDefaults(makeFinal=true)</code>. Any non-final field which must remain nonfinal can be annotated with <code>@NonFinal</code> (also in the <code>lombok.experimental</code> package). </p><p> - To add an access modifier to each field, use <code>@FieldDefaults(level=AccessLevel.PRIVATE)</code>. Any field that does not already have an + To add an access modifier to each (instance) field, use <code>@FieldDefaults(level=AccessLevel.PRIVATE)</code>. Any field that does not already have an access modifier (i.e. any field that looks like package private access) is changed to have the appropriate access modifier. Any package private field which must remain package private can be annotated with <code>@PackagePrivate</code> (also in the <code>lombok.experimental</code> package). </p> |