mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-13 18:15:55 +00:00
ecj: Jacksonized for accessors [WIP]
This commit is contained in:
1 parent
ef4afa4957
commit
70dd3f0940
14 files changed
+88
-25
No files matched your search
@@ -747,7 +747,7 @@ public class ConfigurationKeys {
|
||||
/**
|
||||
* lombok configuration: {@code lombok.copyJacksonAnnotationsToSetters} = {@code true} | {@code false}.
|
||||
*
|
||||
* If <code>true</code>, 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 <code>true</code>, 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 <code>false</code>.
|
||||
*/
|
||||
public static final ConfigurationKey<Boolean> COPY_JACKSON_ANNOTATIONS_TO_SETTERS = new ConfigurationKey<Boolean>("lombok.copyJacksonAnnotationsToSetters", "Copy these annotations to getters, setters, with methods, builder-setters, etc.") {};
|
||||
|
||||
@@ -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 <code>true</code>, 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -1047,7 +1047,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
}
|
||||
|
||||
List<Annotation> methodAnnsList = Collections.<Annotation>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),
|
||||
|
||||
@@ -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<Jacksonized> {
|
||||
|
||||
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<Jacksonized> annotation, Annotation ast, EclipseNode annotationNode) {
|
||||
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.JACKSONIZED_FLAG_USAGE, "@Jacksonized");
|
||||
@@ -77,8 +80,10 @@ public class HandleJacksonized extends EclipseAnnotationHandler<Jacksonized> {
|
||||
|
||||
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<Jacksonized> {
|
||||
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<Builder> builderAnnotation = builderAnnotationNode != null ? createAnnotation(Builder.class, builderAnnotationNode) : null;
|
||||
AnnotationValues<SuperBuilder> superBuilderAnnotation = superBuilderAnnotationNode != null ? createAnnotation(SuperBuilder.class, superBuilderAnnotationNode) : null;
|
||||
|
||||
@@ -144,6 +160,38 @@ public class HandleJacksonized extends EclipseAnnotationHandler<Jacksonized> {
|
||||
builderClass.modifiers = builderClass.modifiers & ~ClassFileConstants.AccPrivate;
|
||||
}
|
||||
|
||||
private void handleJacksonizedAccessors(Annotation ast, EclipseNode annotationNode, EclipseNode annotatedNode, EclipseNode tdNode, TypeDeclaration td, EclipseNode accessorsAnnotationNode) {
|
||||
AnnotationValues<Accessors> 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<Builder> builderAnnotation) {
|
||||
String builderClassName = builderAnnotation != null ?
|
||||
builderAnnotation.getInstance().builderClassName() : null;
|
||||
|
||||
@@ -228,7 +228,7 @@ public class HandleSetter extends EclipseAnnotationHandler<Setter> {
|
||||
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 };
|
||||
|
||||
@@ -1007,7 +1007,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
if (Arrays.equals(setterName.toCharArray(), existingName) && !isTolerate(fieldNode, existing[i])) return;
|
||||
}
|
||||
|
||||
List<Annotation> methodAnnsList = Arrays.asList(EclipseHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode));
|
||||
List<Annotation> 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.<Annotation>emptyList());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -116,7 +116,7 @@ public class HandleJacksonized extends JavacAnnotationHandler<Jacksonized> {
|
||||
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.<JCExpression>of(maker.Literal(fieldNode.getName())));
|
||||
recursiveSetGeneratedBy(annotationJsonProperty, annotationNode);
|
||||
JCVariableDecl fieldDecl = ((JCVariableDecl)fieldNode.get());
|
||||
fieldDecl.mods.annotations = fieldDecl.mods.annotations.append(annotationJsonProperty);
|
||||
|
||||
@@ -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<SuperBuilder> {
|
||||
List<JCAnnotation> 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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user