diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java
index b54e4d30..18d7cb9a 100644
--- a/src/core/lombok/ConfigurationKeys.java
+++ b/src/core/lombok/ConfigurationKeys.java
@@ -747,7 +747,7 @@ public class ConfigurationKeys {
/**
* lombok configuration: {@code lombok.copyJacksonAnnotationsToSetters} = {@code true} | {@code false}.
*
- * If true, copy certain Jackson annotations from a field to its corresponding getter. This was the behavior from lombok 1.18.16 to 1.18.34.
+ * If true, copy certain Jackson annotations from a field to its corresponding getter. This was the behavior from lombok 1.18.16 to 1.18.36.
* However, it turned out to be harmful in certain situations. Thus, the default is now false.
*/
public static final ConfigurationKey COPY_JACKSON_ANNOTATIONS_TO_SETTERS = new ConfigurationKey("lombok.copyJacksonAnnotationsToSetters", "Copy these annotations to getters, setters, with methods, builder-setters, etc.") {};
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index f357a6c4..3a18d049 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -828,8 +828,14 @@ public class EclipseHandlerUtil {
/**
* Searches the given field node for annotations that are specifically intentioned to be copied to the setter.
+ *
+ * @param forceCopy If true, always copy the annotations regardless of the lombok configuration.
*/
- public static Annotation[] findCopyableToSetterAnnotations(EclipseNode node) {
+ public static Annotation[] findCopyableToSetterAnnotations(EclipseNode node, boolean forceCopy) {
+ if (!forceCopy) {
+ Boolean copyAnnotations = node.getAst().readConfiguration(ConfigurationKeys.COPY_JACKSON_ANNOTATIONS_TO_SETTERS);
+ if (copyAnnotations == null || !copyAnnotations) return EMPTY_ANNOTATIONS_ARRAY;
+ }
return findAnnotationsInList(node, JACKSON_COPY_TO_SETTER_ANNOTATIONS);
}
diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java
index a63d3b36..a22eb49b 100755
--- a/src/core/lombok/eclipse/handlers/HandleBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java
@@ -1047,7 +1047,7 @@ public class HandleBuilder extends EclipseAnnotationHandler {
}
List methodAnnsList = Collections.emptyList();
- Annotation[] methodAnns = EclipseHandlerUtil.findCopyableToSetterAnnotations(bfd.originalFieldNode);
+ Annotation[] methodAnns = EclipseHandlerUtil.findCopyableToSetterAnnotations(bfd.originalFieldNode, true);
if (methodAnns != null && methodAnns.length > 0) methodAnnsList = Arrays.asList(methodAnns);
ASTNode source = job.sourceNode.get();
MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, bfd.name, bfd.nameOfSetFlag, job.oldChain, toEclipseModifier(job.accessInners),
diff --git a/src/core/lombok/eclipse/handlers/HandleJacksonized.java b/src/core/lombok/eclipse/handlers/HandleJacksonized.java
index 466cc338..abb50fe0 100644
--- a/src/core/lombok/eclipse/handlers/HandleJacksonized.java
+++ b/src/core/lombok/eclipse/handlers/HandleJacksonized.java
@@ -31,6 +31,7 @@ import java.util.List;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
@@ -47,6 +48,7 @@ import lombok.core.handlers.HandlerUtil;
import lombok.eclipse.Eclipse;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
+import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;
import lombok.extern.jackson.Jacksonized;
import lombok.spi.Provides;
@@ -62,6 +64,7 @@ public class HandleJacksonized extends EclipseAnnotationHandler {
private static final char[][] JSON_POJO_BUILDER_ANNOTATION = Eclipse.fromQualifiedName("com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder");
private static final char[][] JSON_DESERIALIZE_ANNOTATION = Eclipse.fromQualifiedName("com.fasterxml.jackson.databind.annotation.JsonDeserialize");
+ private static final char[][] JSON_PROPERTY_ANNOTATION = Eclipse.fromQualifiedName("com.fasterxml.jackson.annotation.JsonProperty");
@Override public void handle(AnnotationValues annotation, Annotation ast, EclipseNode annotationNode) {
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.JACKSONIZED_FLAG_USAGE, "@Jacksonized");
@@ -77,8 +80,10 @@ public class HandleJacksonized extends EclipseAnnotationHandler {
EclipseNode builderAnnotationNode = findAnnotation(Builder.class, annotatedNode);
EclipseNode superBuilderAnnotationNode = findAnnotation(SuperBuilder.class, annotatedNode);
- if (builderAnnotationNode == null && superBuilderAnnotationNode == null) {
- annotationNode.addWarning("@Jacksonized requires @Builder or @SuperBuilder for it to mean anything.");
+ EclipseNode accessorsAnnotationNode = (annotatedNode.getKind() == Kind.TYPE) ? findAnnotation(Accessors.class, annotatedNode) : null;
+
+ if (builderAnnotationNode == null && superBuilderAnnotationNode == null && accessorsAnnotationNode == null) {
+ annotationNode.addWarning("@Jacksonized requires @Builder, @SuperBuilder, or @Accessors for it to mean anything.");
return;
}
@@ -92,7 +97,18 @@ public class HandleJacksonized extends EclipseAnnotationHandler {
annotationNode.addError("Builders on abstract classes cannot be @Jacksonized (the builder would never be used).");
return;
}
+
+ if (builderAnnotationNode != null || superBuilderAnnotationNode != null) {
+ handleJacksonizedBuilder(ast, annotationNode, annotatedNode, tdNode, td, builderAnnotationNode, superBuilderAnnotationNode);
+ }
+
+ if (accessorsAnnotationNode != null) {
+ handleJacksonizedAccessors(ast, annotationNode, annotatedNode, tdNode, td, accessorsAnnotationNode);
+ }
+ }
+
+ private void handleJacksonizedBuilder(Annotation ast, EclipseNode annotationNode, EclipseNode annotatedNode, EclipseNode tdNode, TypeDeclaration td, EclipseNode builderAnnotationNode, EclipseNode superBuilderAnnotationNode) {
AnnotationValues builderAnnotation = builderAnnotationNode != null ? createAnnotation(Builder.class, builderAnnotationNode) : null;
AnnotationValues superBuilderAnnotation = superBuilderAnnotationNode != null ? createAnnotation(SuperBuilder.class, superBuilderAnnotationNode) : null;
@@ -144,6 +160,38 @@ public class HandleJacksonized extends EclipseAnnotationHandler {
builderClass.modifiers = builderClass.modifiers & ~ClassFileConstants.AccPrivate;
}
+ private void handleJacksonizedAccessors(Annotation ast, EclipseNode annotationNode, EclipseNode annotatedNode, EclipseNode tdNode, TypeDeclaration td, EclipseNode accessorsAnnotationNode) {
+ AnnotationValues accessorsAnnotation = accessorsAnnotationNode != null ?
+ createAnnotation(Accessors.class, accessorsAnnotationNode) :
+ null;
+ boolean fluent = accessorsAnnotation != null && accessorsAnnotation.getInstance().fluent();
+
+ if (!fluent) {
+ // No changes required for chained-only accessors.
+ return;
+ }
+
+ // Add @JsonProperty to all fields. It will be automatically copied to the getter/setters later.
+ for (EclipseNode eclipseNode : tdNode.down()) {
+ if (eclipseNode.getKind() == Kind.FIELD) {
+ createJsonPropertyForField(eclipseNode, annotationNode);
+ }
+ }
+ }
+
+ private void createJsonPropertyForField(EclipseNode fieldNode, EclipseNode annotationNode) {
+ if (hasAnnotation("com.fasterxml.jackson.annotation.JsonProperty", fieldNode)) {
+ return;
+ }
+ ASTNode astNode = fieldNode.get();
+ if (astNode instanceof FieldDeclaration) {
+ FieldDeclaration fd = (FieldDeclaration)astNode;
+ StringLiteral fieldName = new StringLiteral(fd.name, 0, 0, 0);
+ ((FieldDeclaration)astNode).annotations = addAnnotation(fieldNode.get(), fd.annotations, JSON_PROPERTY_ANNOTATION, fieldName);
+ }
+ }
+
+
private String getBuilderClassName(Annotation ast, EclipseNode annotationNode, EclipseNode annotatedNode, TypeDeclaration td, AnnotationValues builderAnnotation) {
String builderClassName = builderAnnotation != null ?
builderAnnotation.getInstance().builderClassName() : null;
diff --git a/src/core/lombok/eclipse/handlers/HandleSetter.java b/src/core/lombok/eclipse/handlers/HandleSetter.java
index 99552efc..5c372019 100644
--- a/src/core/lombok/eclipse/handlers/HandleSetter.java
+++ b/src/core/lombok/eclipse/handlers/HandleSetter.java
@@ -228,7 +228,7 @@ public class HandleSetter extends EclipseAnnotationHandler {
if (isFieldDeprecated(fieldNode) || deprecate) {
deprecated = new Annotation[] { generateDeprecatedAnnotation(source) };
}
- method.annotations = copyAnnotations(source, onMethod.toArray(new Annotation[0]), deprecated, findCopyableToSetterAnnotations(fieldNode));
+ method.annotations = copyAnnotations(source, onMethod.toArray(new Annotation[0]), deprecated, findCopyableToSetterAnnotations(fieldNode, false));
Argument param = new Argument(paramName, p, copyType(field.type, source), Modifier.FINAL);
param.sourceStart = pS; param.sourceEnd = pE;
method.arguments = new Argument[] { param };
diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
index 82e561de..c37da9d7 100644
--- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
@@ -1007,7 +1007,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler {
if (Arrays.equals(setterName.toCharArray(), existingName) && !isTolerate(fieldNode, existing[i])) return;
}
- List methodAnnsList = Arrays.asList(EclipseHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode));
+ List methodAnnsList = Arrays.asList(EclipseHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode, true));
addCheckerFrameworkReturnsReceiver(returnType, job.source, job.checkerFramework);
MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, paramName, nameOfSetFlag, returnType, returnStatement, ClassFileConstants.AccPublic,
job.sourceNode, methodAnnsList, annosOnParam != null ? Arrays.asList(copyAnnotations(job.source, annosOnParam)) : Collections.emptyList());
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
index a43e0331..eff24cd4 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
@@ -219,7 +219,7 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(builderType, new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray();
md.selector = fluent ? prefixedSelector : HandlerUtil.buildAccessorName(builderType, "addAll", new String(data.getPluralName())).toCharArray();
Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, data.getSource());
- Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up()));
+ Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up(), false));
md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class);
if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md);
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
index 810a7878..c94666e0 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
@@ -195,7 +195,7 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(builderType, new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray();
md.selector = fluent ? prefixedSelector : HandlerUtil.buildAccessorName(builderType, "addAll", new String(data.getPluralName())).toCharArray();
Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, data.getSource());
- Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up()));
+ Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up(), false));
md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class);
if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md);
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
index 16ed2d44..0e3ab0dd 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
@@ -332,7 +332,7 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
md.selector = setterName.toCharArray();
Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, data.getSource());
- Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up()));
+ Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up(), false));
md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class);
if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md);
diff --git a/src/core/lombok/extern/jackson/Jacksonized.java b/src/core/lombok/extern/jackson/Jacksonized.java
index 4b7d7e54..fd482d00 100644
--- a/src/core/lombok/extern/jackson/Jacksonized.java
+++ b/src/core/lombok/extern/jackson/Jacksonized.java
@@ -27,8 +27,6 @@ import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
import lombok.Builder;
import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;
diff --git a/src/core/lombok/javac/handlers/HandleJacksonized.java b/src/core/lombok/javac/handlers/HandleJacksonized.java
index f956d782..7b41ec13 100644
--- a/src/core/lombok/javac/handlers/HandleJacksonized.java
+++ b/src/core/lombok/javac/handlers/HandleJacksonized.java
@@ -116,7 +116,7 @@ public class HandleJacksonized extends JavacAnnotationHandler {
JavacTreeMaker maker = fieldNode.getTreeMaker();
JCExpression jsonPropertyType = chainDots(fieldNode, "com", "fasterxml", "jackson", "annotation", "JsonProperty");
- JCAnnotation annotationJsonProperty = maker.Annotation(jsonPropertyType, List.of(maker.Literal(fieldNode.getName())));
+ JCAnnotation annotationJsonProperty = maker.Annotation(jsonPropertyType, List.of(maker.Literal(fieldNode.getName())));
recursiveSetGeneratedBy(annotationJsonProperty, annotationNode);
JCVariableDecl fieldDecl = ((JCVariableDecl)fieldNode.get());
fieldDecl.mods.annotations = fieldDecl.mods.annotations.append(annotationJsonProperty);
diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
index 3669bf2e..2390c7aa 100644
--- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
@@ -21,9 +21,9 @@
*/
package lombok.javac.handlers;
-import static lombok.javac.handlers.HandleBuilder.*;
import static lombok.core.handlers.HandlerUtil.*;
import static lombok.javac.Javac.*;
+import static lombok.javac.handlers.HandleBuilder.*;
import static lombok.javac.handlers.JavacHandlerUtil.*;
import java.util.ArrayList;
@@ -968,7 +968,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler {
List methodAnns = JavacHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode, true);
returnType = addCheckerFrameworkReturnsReceiver(returnType, maker, job.builderType, job.checkerFramework);
- JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, paramName, nameOfSetFlag, returnType, returnStatement, job.sourceNode, methodAnns, annosOnParam, false);
+ JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, paramName, nameOfSetFlag, returnType, returnStatement, job.sourceNode, methodAnns, annosOnParam, true);
if (job.sourceNode.up().getKind() == Kind.METHOD) {
copyJavadocFromParam(originalFieldNode.up(), newMethod, paramName.toString());
} else {
diff --git a/test/transform/resource/after-ecj/JacksonizedAccessors.java b/test/transform/resource/after-ecj/JacksonizedAccessors.java
new file mode 100644
index 00000000..83fe581c
--- /dev/null
+++ b/test/transform/resource/after-ecj/JacksonizedAccessors.java
@@ -0,0 +1,16 @@
+public @lombok.extern.jackson.Jacksonized @lombok.experimental.Accessors(fluent = true) @lombok.Getter @lombok.Setter class JacksonizedAccessors {
+ private @com.fasterxml.jackson.annotation.JsonProperty("intValue") int intValue;
+ public JacksonizedAccessors() {
+ super();
+ }
+ public @java.lang.SuppressWarnings("all") @lombok.Generated @com.fasterxml.jackson.annotation.JsonProperty("intValue") int intValue() {
+ return this.intValue;
+ }
+ /**
+ * @return {@code this}.
+ */
+ public @java.lang.SuppressWarnings("all") @lombok.Generated @com.fasterxml.jackson.annotation.JsonProperty("intValue") JacksonizedAccessors intValue(final int intValue) {
+ this.intValue = intValue;
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/test/transform/resource/before/JacksonizedAccessors.java b/test/transform/resource/before/JacksonizedAccessors.java
index 3242890e..0fe01684 100644
--- a/test/transform/resource/before/JacksonizedAccessors.java
+++ b/test/transform/resource/before/JacksonizedAccessors.java
@@ -1,12 +1,7 @@
-import lombok.Getter;
-import lombok.Setter;
-import lombok.experimental.Accessors;
-import lombok.extern.jackson.Jacksonized;
-
-@Jacksonized
-@Accessors(fluent = true)
-@Getter
-@Setter
+@lombok.extern.jackson.Jacksonized
+@lombok.experimental.Accessors(fluent = true)
+@lombok.Getter
+@lombok.Setter
public class JacksonizedAccessors {
private int intValue;
-}
+}
\ No newline at end of file