Skip to content

Commit

Permalink
Fixes #1254: Value and FieldDefaults should skip static fields
Browse files Browse the repository at this point in the history
  • Loading branch information
rspilker committed Dec 5, 2016
1 parent 7969951 commit 0727c8b
Show file tree
Hide file tree
Showing 13 changed files with 33 additions and 18 deletions.
1 change: 1 addition & 0 deletions doc/changelog.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Lombok Changelog

### v1.16.11 "Edgy Guinea Pig"
* v1.16.10 is the latest release
* CHANGE: `@Value` and `@FieldDefaults` no longer touch static fields [Issue #1254](https://github.com/rzwitserloot/lombok/issues/1254)
* 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)
* BUGFIX: `val` in lambda expressions now work as expected [Issue #911](https://github.com/rzwitserloot/lombok/issues/911)
Expand Down
8 changes: 5 additions & 3 deletions src/core/lombok/eclipse/handlers/HandleFieldDefaults.java
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -97,14 +97,16 @@ public void setFieldDefaultsForField(EclipseNode fieldNode, ASTNode pos, AccessL
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;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/core/lombok/experimental/FieldDefaults.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
* <p>
* Complete documentation is found at <a href="https://projectlombok.org/features/experimental/FieldDefaults.html">the project lombok features page for &#64;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)
Expand Down
2 changes: 1 addition & 1 deletion src/core/lombok/experimental/NonFinal.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

/**
* 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)
Expand Down
2 changes: 1 addition & 1 deletion src/core/lombok/experimental/PackagePrivate.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

/**
* 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)
Expand Down
8 changes: 5 additions & 3 deletions src/core/lombok/javac/handlers/HandleFieldDefaults.java
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -84,14 +84,16 @@ public void setFieldDefaultsForField(JavacNode fieldNode, AccessLevel level, boo
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;
}
}
Expand Down
2 changes: 2 additions & 0 deletions test/transform/resource/after-delombok/FieldDefaults.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
class FieldDefaults1 {
static int STATIC = 3;
final int x;
int y;
FieldDefaults1(int x) {
this.x = x;
}
}
class FieldDefaults2 {
static int STATIC = 3;
int x;
private int y;
}
4 changes: 2 additions & 2 deletions test/transform/resource/after-delombok/ValueStaticField.java
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down
6 changes: 6 additions & 0 deletions test/transform/resource/after-ecj/FieldDefaults.java
Original file line number Diff line number Diff line change
@@ -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();
}
Expand Down
4 changes: 2 additions & 2 deletions test/transform/resource/after-ecj/ValueStaticField.java
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions test/transform/resource/before/FieldDefaults.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@lombok.experimental.FieldDefaults(makeFinal = true)
class FieldDefaults1 {
static int STATIC = 3;
int x;
@lombok.experimental.NonFinal int y;

Expand All @@ -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;
}
4 changes: 2 additions & 2 deletions website/features/Value.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ <h3>Overview</h3>
</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">
Expand Down
4 changes: 2 additions & 2 deletions website/features/experimental/FieldDefaults.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ <h3>Overview</h3>
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>
Expand Down

0 comments on commit 0727c8b

Please sign in to comment.