mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-14 12:16:49 +00:00
[WIP]
This commit is contained in:
1 parent
a0a2ef4fbc
commit
7ea95700c3
5 files changed
+93
-4
No files matched your search
@@ -79,7 +79,7 @@ public class HandlerUtil {
|
||||
return 43;
|
||||
}
|
||||
|
||||
public static final List<String> NONNULL_ANNOTATIONS, BASE_COPYABLE_ANNOTATIONS, COPY_TO_SETTER_ANNOTATIONS, COPY_TO_BUILDER_SINGULAR_SETTER_ANNOTATIONS, JACKSON_COPY_TO_BUILDER_ANNOTATIONS;
|
||||
public static final List<String> NONNULL_ANNOTATIONS, BASE_COPYABLE_ANNOTATIONS, COPY_TO_GETTER_ANNOTATIONS, COPY_TO_SETTER_ANNOTATIONS, COPY_TO_BUILDER_SINGULAR_SETTER_ANNOTATIONS, JACKSON_COPY_TO_BUILDER_ANNOTATIONS;
|
||||
static {
|
||||
// This is a list of annotations with a __highly specific meaning__: All annotations in this list indicate that passing null for the relevant item is __never__ acceptable, regardless of settings or circumstance.
|
||||
// In other words, things like 'this models a database table, and the db table column has a nonnull constraint', or 'this represents a web form, and if this is null, the form is invalid' __do not count__ and should not be in this list;
|
||||
@@ -423,6 +423,23 @@ public class HandlerUtil {
|
||||
"org.checkerframework.common.value.qual.UnknownVal",
|
||||
"org.checkerframework.framework.qual.PurityUnqualified",
|
||||
}));
|
||||
COPY_TO_GETTER_ANNOTATIONS = Collections.unmodifiableList(Arrays.asList(new String[] {
|
||||
"com.fasterxml.jackson.annotation.JacksonInject",
|
||||
"com.fasterxml.jackson.annotation.JsonAlias",
|
||||
"com.fasterxml.jackson.annotation.JsonFormat",
|
||||
"com.fasterxml.jackson.annotation.JsonIgnore",
|
||||
"com.fasterxml.jackson.annotation.JsonIgnoreProperties",
|
||||
"com.fasterxml.jackson.annotation.JsonProperty",
|
||||
"com.fasterxml.jackson.annotation.JsonSetter",
|
||||
"com.fasterxml.jackson.annotation.JsonSubTypes",
|
||||
"com.fasterxml.jackson.annotation.JsonTypeInfo",
|
||||
"com.fasterxml.jackson.annotation.JsonUnwrapped",
|
||||
"com.fasterxml.jackson.annotation.JsonView",
|
||||
"com.fasterxml.jackson.databind.annotation.JsonDeserialize",
|
||||
"com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper",
|
||||
"com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty",
|
||||
"com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText",
|
||||
}));
|
||||
COPY_TO_SETTER_ANNOTATIONS = Collections.unmodifiableList(Arrays.asList(new String[] {
|
||||
"com.fasterxml.jackson.annotation.JacksonInject",
|
||||
"com.fasterxml.jackson.annotation.JsonAlias",
|
||||
|
||||
+2
-1
@@ -38,9 +38,10 @@ import lombok.experimental.SuperBuilder;
|
||||
* {@code @}{@link Builder}, {@code @}{@link SuperBuilder}, and
|
||||
* {@code @}{@link Accessors}.
|
||||
* <p>
|
||||
* For {@code @}{@link Accessors}{@code (fluent = true)}, it automatically
|
||||
* For {@code @}{@link Accessors}{@code (fluent = true)} on a type, it automatically
|
||||
* configures Jackson to use the generated setters and getters for
|
||||
* (de-)serialization by inserting {@code @}{@link JsonProperty} annotations.
|
||||
* (Note that {@code @Jacksonized} {@code @Accessors} on fields are not supported.)
|
||||
* <p>
|
||||
* For {@code @}{@link Builder} and {@code @}{@link SuperBuilder}, it
|
||||
* automatically configures the generated builder class to be used by Jackson's
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
|
||||
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.JCExpression;
|
||||
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
|
||||
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
|
||||
@@ -56,7 +57,7 @@ import lombok.spi.Provides;
|
||||
* needs for builders.
|
||||
*/
|
||||
@Provides
|
||||
@HandlerPriority(-512) // Above Handle(Super)Builder's level (builders must be already generated).
|
||||
@HandlerPriority(-512) // Above Handle(Super)Builder's level (builders must be already generated), but before all handlers generating getters/setters.
|
||||
public class HandleJacksonized extends JavacAnnotationHandler<Jacksonized> {
|
||||
|
||||
@Override public void handle(AnnotationValues<Jacksonized> annotation, JCAnnotation ast, JavacNode annotationNode) {
|
||||
@@ -79,7 +80,49 @@ public class HandleJacksonized extends JavacAnnotationHandler<Jacksonized> {
|
||||
annotationNode.addWarning("@Jacksonized requires @Builder, @SuperBuilder, or @Accessors for it to mean anything.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (builderAnnotationNode != null || superBuilderAnnotationNode != null) {
|
||||
handleJacksonizedBuilder(annotationNode, annotatedNode, tdNode, td, builderAnnotationNode, superBuilderAnnotationNode);
|
||||
}
|
||||
|
||||
if (accessorsAnnotationNode != null) {
|
||||
handleJacksonizedAccessors(annotationNode, annotatedNode, tdNode, td, accessorsAnnotationNode);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleJacksonizedAccessors(JavacNode annotationNode, JavacNode annotatedNode, JavacNode tdNode, JCClassDecl td, JavacNode 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 (JavacNode javacNode : tdNode.down()) {
|
||||
if (javacNode.getKind() == Kind.FIELD) {
|
||||
createJsonPropertyForField(javacNode, annotationNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createJsonPropertyForField(JavacNode fieldNode, JavacNode annotationNode) {
|
||||
if (hasAnnotation("com.fasterxml.jackson.annotation.JsonProperty", fieldNode)) {
|
||||
return;
|
||||
}
|
||||
JavacTreeMaker maker = fieldNode.getTreeMaker();
|
||||
|
||||
JCExpression jsonPropertyType = chainDots(fieldNode, "com", "fasterxml", "jackson", "annotation", "JsonProperty");
|
||||
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);
|
||||
}
|
||||
|
||||
private void handleJacksonizedBuilder(JavacNode annotationNode, JavacNode annotatedNode, JavacNode tdNode, JCClassDecl td, JavacNode builderAnnotationNode, JavacNode superBuilderAnnotationNode) {
|
||||
if (builderAnnotationNode != null && superBuilderAnnotationNode != null) {
|
||||
annotationNode.addError("@Jacksonized cannot process both @Builder and @SuperBuilder on the same class.");
|
||||
return;
|
||||
@@ -155,7 +198,7 @@ public class HandleJacksonized extends JavacAnnotationHandler<Jacksonized> {
|
||||
// @SuperBuilder? Make it package-private!
|
||||
if (superBuilderAnnotationNode != null)
|
||||
builderClass.mods.flags = builderClass.mods.flags & ~Flags.PRIVATE;
|
||||
}
|
||||
}
|
||||
|
||||
private String getBuilderClassName(JavacNode annotationNode, JavacNode annotatedNode, JCClassDecl td, AnnotationValues<Builder> builderAnnotation, JavacTreeMaker maker) {
|
||||
String builderClassName = builderAnnotation != null ?
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
public class JacksonizedAccessors {
|
||||
@com.fasterxml.jackson.annotation.JsonProperty("intValue")
|
||||
private int intValue;
|
||||
@java.lang.SuppressWarnings("all")
|
||||
@com.fasterxml.jackson.annotation.JsonProperty("intValue")
|
||||
public int intValue() {
|
||||
return this.intValue;
|
||||
}
|
||||
/**
|
||||
* @return {@code this}.
|
||||
*/
|
||||
@java.lang.SuppressWarnings("all")
|
||||
@com.fasterxml.jackson.annotation.JsonProperty("intValue")
|
||||
public JacksonizedAccessors intValue(final int intValue) {
|
||||
this.intValue = intValue;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
@Jacksonized
|
||||
@Accessors(fluent = true)
|
||||
@Getter
|
||||
public class JacksonizedAccessors {
|
||||
private int intValue;
|
||||
}
|
||||
Reference in new issue
Block a user