From 4c8607f2a4b2cc0daeb1ad4e3af1d4e553ff2abe Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Wed, 10 May 2023 17:02:19 +0200 Subject: [PATCH] [fixes #3315] Copy annotations on record components --- .../eclipse/handlers/EclipseHandlerUtil.java | 16 ++-- .../after-delombok/JacksonizedOnRecord.java | 86 +++++++++++++++++++ .../after-ecj/JacksonizedOnRecord.java | 69 +++++++++++++++ .../resource/before/JacksonizedOnRecord.java | 12 +++ 4 files changed, 175 insertions(+), 8 deletions(-) create mode 100644 test/transform/resource/after-delombok/JacksonizedOnRecord.java create mode 100644 test/transform/resource/after-ecj/JacksonizedOnRecord.java create mode 100644 test/transform/resource/before/JacksonizedOnRecord.java diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 9af88937..752ed0e6 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -809,12 +809,12 @@ public class EclipseHandlerUtil { * Searches the given field node for annotations and returns each one that is 'copyable' (either via configuration or from the base list). */ public static Annotation[] findCopyableAnnotations(EclipseNode node) { - AbstractVariableDeclaration avd = (AbstractVariableDeclaration) node.get(); - if (avd.annotations == null) return EMPTY_ANNOTATIONS_ARRAY; List result = new ArrayList(); List configuredCopyable = node.getAst().readConfiguration(ConfigurationKeys.COPYABLE_ANNOTATIONS); - - for (Annotation annotation : avd.annotations) { + for (EclipseNode child : node.down()) { + if (child.getKind() != Kind.ANNOTATION) continue; + + Annotation annotation = (Annotation) child.get(); TypeReference typeRef = annotation.type; boolean match = false; if (typeRef != null && typeRef.getTypeName() != null) { @@ -850,11 +850,11 @@ public class EclipseHandlerUtil { * Searches the given field node for annotations that are in the given list, and returns those. */ private static Annotation[] findAnnotationsInList(EclipseNode node, java.util.List annotationsToFind) { - AbstractVariableDeclaration avd = (AbstractVariableDeclaration) node.get(); - if (avd.annotations == null) return EMPTY_ANNOTATIONS_ARRAY; List result = new ArrayList(); - - for (Annotation annotation : avd.annotations) { + for (EclipseNode child : node.down()) { + if (child.getKind() != Kind.ANNOTATION) continue; + + Annotation annotation = (Annotation) child.get(); TypeReference typeRef = annotation.type; if (typeRef != null && typeRef.getTypeName() != null) { for (String bn : annotationsToFind) if (typeMatches(bn, node, typeRef)) { diff --git a/test/transform/resource/after-delombok/JacksonizedOnRecord.java b/test/transform/resource/after-delombok/JacksonizedOnRecord.java new file mode 100644 index 00000000..af7d961c --- /dev/null +++ b/test/transform/resource/after-delombok/JacksonizedOnRecord.java @@ -0,0 +1,86 @@ +//version 14: +import java.util.List; +import javax.annotation.Nullable; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(builder = JacksonizedOnRecord.JacksonizedOnRecordBuilder.class) +public record JacksonizedOnRecord(@JsonProperty("test") @Nullable String string, @JsonAnySetter List values) { + + @java.lang.SuppressWarnings("all") + @JsonIgnoreProperties + @com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder(withPrefix = "", buildMethodName = "build") + public static class JacksonizedOnRecordBuilder { + @java.lang.SuppressWarnings("all") + private String string; + @java.lang.SuppressWarnings("all") + private java.util.ArrayList values; + + @java.lang.SuppressWarnings("all") + JacksonizedOnRecordBuilder() { + } + + /** + * @return {@code this}. + */ + @JsonProperty("test") + @java.lang.SuppressWarnings("all") + public JacksonizedOnRecord.JacksonizedOnRecordBuilder string(@Nullable final String string) { + this.string = string; + return this; + } + + @JsonAnySetter + @java.lang.SuppressWarnings("all") + public JacksonizedOnRecord.JacksonizedOnRecordBuilder value(final String value) { + if (this.values == null) this.values = new java.util.ArrayList(); + this.values.add(value); + return this; + } + + @java.lang.SuppressWarnings("all") + public JacksonizedOnRecord.JacksonizedOnRecordBuilder values(final java.util.Collection values) { + if (values == null) { + throw new java.lang.NullPointerException("values cannot be null"); + } + if (this.values == null) this.values = new java.util.ArrayList(); + this.values.addAll(values); + return this; + } + + @java.lang.SuppressWarnings("all") + public JacksonizedOnRecord.JacksonizedOnRecordBuilder clearValues() { + if (this.values != null) this.values.clear(); + return this; + } + + @java.lang.SuppressWarnings("all") + public JacksonizedOnRecord build() { + java.util.List values; + switch (this.values == null ? 0 : this.values.size()) { + case 0: + values = java.util.Collections.emptyList(); + break; + case 1: + values = java.util.Collections.singletonList(this.values.get(0)); + break; + default: + values = java.util.Collections.unmodifiableList(new java.util.ArrayList(this.values)); + } + return new JacksonizedOnRecord(this.string, values); + } + + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "JacksonizedOnRecord.JacksonizedOnRecordBuilder(string=" + this.string + ", values=" + this.values + ")"; + } + } + + @java.lang.SuppressWarnings("all") + public static JacksonizedOnRecord.JacksonizedOnRecordBuilder builder() { + return new JacksonizedOnRecord.JacksonizedOnRecordBuilder(); + } +} diff --git a/test/transform/resource/after-ecj/JacksonizedOnRecord.java b/test/transform/resource/after-ecj/JacksonizedOnRecord.java new file mode 100644 index 00000000..46e592bb --- /dev/null +++ b/test/transform/resource/after-ecj/JacksonizedOnRecord.java @@ -0,0 +1,69 @@ +import java.util.List; +import javax.annotation.Nullable; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +public @lombok.extern.jackson.Jacksonized @lombok.Builder @JsonIgnoreProperties @com.fasterxml.jackson.databind.annotation.JsonDeserialize(builder = JacksonizedOnRecord.JacksonizedOnRecordBuilder.class) record JacksonizedOnRecord(String string, List values) { + public static @java.lang.SuppressWarnings("all") @JsonIgnoreProperties @com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder(withPrefix = "",buildMethodName = "build") class JacksonizedOnRecordBuilder { + private @java.lang.SuppressWarnings("all") String string; + private @java.lang.SuppressWarnings("all") java.util.ArrayList values; + @java.lang.SuppressWarnings("all") JacksonizedOnRecordBuilder() { + super(); + } + /** + * @return {@code this}. + */ + public @JsonProperty("test") @java.lang.SuppressWarnings("all") JacksonizedOnRecord.JacksonizedOnRecordBuilder string(final @Nullable String string) { + this.string = string; + return this; + } + public @JsonAnySetter @java.lang.SuppressWarnings("all") JacksonizedOnRecord.JacksonizedOnRecordBuilder value(final String value) { + if ((this.values == null)) + this.values = new java.util.ArrayList(); + this.values.add(value); + return this; + } + public @java.lang.SuppressWarnings("all") JacksonizedOnRecord.JacksonizedOnRecordBuilder values(final java.util.Collection values) { + if ((values == null)) + { + throw new java.lang.NullPointerException("values cannot be null"); + } + if ((this.values == null)) + this.values = new java.util.ArrayList(); + this.values.addAll(values); + return this; + } + public @java.lang.SuppressWarnings("all") JacksonizedOnRecord.JacksonizedOnRecordBuilder clearValues() { + if ((this.values != null)) + this.values.clear(); + return this; + } + public @java.lang.SuppressWarnings("all") JacksonizedOnRecord build() { + java.util.List values; + switch (((this.values == null) ? 0 : this.values.size())) { + case 0 : + values = java.util.Collections.emptyList(); + break; + case 1 : + values = java.util.Collections.singletonList(this.values.get(0)); + break; + default : + values = java.util.Collections.unmodifiableList(new java.util.ArrayList(this.values)); + } + return new JacksonizedOnRecord(this.string, values); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (((("JacksonizedOnRecord.JacksonizedOnRecordBuilder(string=" + this.string) + ", values=") + this.values) + ")"); + } + } +/* Implicit */ private final String string; +/* Implicit */ private final List values; + public JacksonizedOnRecord(@JsonProperty("test") @Nullable String string, @lombok.Singular List values) { + super(); + .string = string; + .values = values; + } + public static @java.lang.SuppressWarnings("all") JacksonizedOnRecord.JacksonizedOnRecordBuilder builder() { + return new JacksonizedOnRecord.JacksonizedOnRecordBuilder(); + } +} diff --git a/test/transform/resource/before/JacksonizedOnRecord.java b/test/transform/resource/before/JacksonizedOnRecord.java new file mode 100644 index 00000000..273e4a84 --- /dev/null +++ b/test/transform/resource/before/JacksonizedOnRecord.java @@ -0,0 +1,12 @@ +//version 14: +import java.util.List; +import javax.annotation.Nullable; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@lombok.extern.jackson.Jacksonized +@lombok.Builder +@JsonIgnoreProperties +public record JacksonizedOnRecord(@JsonProperty("test") @Nullable String string, @JsonAnySetter @lombok.Singular List values) { +}