diff options
12 files changed, 476 insertions, 21 deletions
diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java index 94fd21d9..a8d56041 100644 --- a/src/core/lombok/core/handlers/HandlerUtil.java +++ b/src/core/lombok/core/handlers/HandlerUtil.java @@ -76,7 +76,7 @@ public class HandlerUtil { return 43; } - public static final List<String> NONNULL_ANNOTATIONS, BASE_COPYABLE_ANNOTATIONS, COPY_TO_SETTER_ANNOTATIONS, JACKSON_COPY_TO_BUILDER_ANNOTATIONS; + 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; static { NONNULL_ANNOTATIONS = Collections.unmodifiableList(Arrays.asList(new String[] { "androidx.annotation.NonNull", @@ -314,6 +314,13 @@ public class HandlerUtil { COPY_TO_SETTER_ANNOTATIONS = Collections.unmodifiableList(Arrays.asList(new String[] { "com.fasterxml.jackson.annotation.JsonProperty", "com.fasterxml.jackson.annotation.JsonSetter", + "com.fasterxml.jackson.annotation.JsonDeserialize", + "com.fasterxml.jackson.annotation.JsonIgnore", + "com.fasterxml.jackson.annotation.JacksonInject", + "com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty", + })); + COPY_TO_BUILDER_SINGULAR_SETTER_ANNOTATIONS = Collections.unmodifiableList(Arrays.asList(new String[] { + "com.fasterxml.jackson.annotation.JsonAnySetter", })); JACKSON_COPY_TO_BUILDER_ANNOTATIONS = Collections.unmodifiableList(Arrays.asList(new String[] { "com.fasterxml.jackson.annotation.JsonFormat", diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 2c6e1e77..6b9571c7 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -26,6 +26,7 @@ import static lombok.eclipse.Eclipse.*; import static lombok.eclipse.EclipseAugments.*; import static lombok.eclipse.handlers.EclipseHandlerUtil.EclipseReflectiveMembers.*; +import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -819,6 +820,20 @@ public class EclipseHandlerUtil { * Searches the given field node for annotations that are specifically intentioned to be copied to the setter. */ public static Annotation[] findCopyableToSetterAnnotations(EclipseNode node) { + return findAnnotationsInList(node, COPY_TO_SETTER_ANNOTATIONS); + } + + /** + * Searches the given field node for annotations that are specifically intentioned to be copied to the builder's singular method. + */ + public static Annotation[] findCopyableToBuilderSingularSetterAnnotations(EclipseNode node) { + return findAnnotationsInList(node, COPY_TO_BUILDER_SINGULAR_SETTER_ANNOTATIONS); + } + + /** + * 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<String> annotationsToFind) { AbstractVariableDeclaration avd = (AbstractVariableDeclaration) node.get(); if (avd.annotations == null) return EMPTY_ANNOTATIONS_ARRAY; List<Annotation> result = new ArrayList<Annotation>(); @@ -826,7 +841,7 @@ public class EclipseHandlerUtil { for (Annotation annotation : avd.annotations) { TypeReference typeRef = annotation.type; if (typeRef != null && typeRef.getTypeName() != null) { - for (String bn : COPY_TO_SETTER_ANNOTATIONS) if (typeMatches(bn, node, typeRef)) { + for (String bn : annotationsToFind) if (typeMatches(bn, node, typeRef)) { result.add(annotation); break; } @@ -2420,6 +2435,26 @@ public class EclipseHandlerUtil { return array == null ? null : array.clone(); } + public static <T> T[] concat(T[] first, T[] second, Class<T> type) { + if (first == null) + return second; + if (second == null) + return first; + if (first.length == 0) + return second; + if (second.length == 0) + return first; + T[] result = newArray(type, first.length + second.length); + System.arraycopy(first, 0, result, 0, first.length); + System.arraycopy(second, 0, result, first.length, second.length); + return result; + } + + @SuppressWarnings("unchecked") + private static <T> T[] newArray(Class<T> type, int length) { + return (T[]) Array.newInstance(type, length); + } + public static boolean isDirectDescendantOfObject(EclipseNode typeNode) { if (!(typeNode.get() instanceof TypeDeclaration)) throw new IllegalArgumentException("not a type node"); TypeDeclaration typeDecl = (TypeDeclaration) typeNode.get(); diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java index 392418ff..395d2e59 100755 --- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java +++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java @@ -175,8 +175,10 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer { md.returnType = returnType; char[] prefixedSingularName = data.getSetterPrefix().length == 0 ? data.getSingularName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getSingularName())).toCharArray(); md.selector = fluent ? prefixedSingularName : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray(); - md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); - + Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToBuilderSingularSetterAnnotations(data.getAnnotation().up())); + md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); + if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md); data.setGeneratedByRecursive(md); HandleNonNull.INSTANCE.fix(injectMethod(builderType, md)); @@ -213,8 +215,10 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer { md.returnType = returnType; char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray(); md.selector = fluent ? prefixedSelector : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray(); - md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); - + Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up())); + md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); + if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md); data.setGeneratedByRecursive(md); injectMethod(builderType, md); diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java index 375f4e2c..deab4530 100755 --- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java +++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java @@ -153,8 +153,10 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula md.returnType = returnType; char[] prefixedSingularName = data.getSetterPrefix().length == 0 ? data.getSingularName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getSingularName())).toCharArray(); md.selector = fluent ? prefixedSingularName : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray(); - md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); - + Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToBuilderSingularSetterAnnotations(data.getAnnotation().up())); + md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); + if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md); data.setGeneratedByRecursive(md); HandleNonNull.INSTANCE.fix(injectMethod(builderType, md)); @@ -189,8 +191,10 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula md.returnType = returnType; char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray(); md.selector = fluent ? prefixedSelector : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray(); - md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); - + Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up())); + md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); + if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md); data.setGeneratedByRecursive(md); injectMethod(builderType, md); diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java index cb7d9ed6..1a40369d 100755 --- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java +++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java @@ -252,7 +252,9 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer String setterName = HandlerUtil.buildAccessorName(setterPrefix, name); md.selector = setterName.toCharArray(); - md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToBuilderSingularSetterAnnotations(data.getAnnotation().up())); + md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md); data.setGeneratedByRecursive(md); @@ -326,7 +328,9 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer String setterName = HandlerUtil.buildAccessorName(setterPrefix, name); md.selector = setterName.toCharArray(); - md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up())); + md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md); data.setGeneratedByRecursive(md); diff --git a/src/core/lombok/javac/handlers/HandleJacksonized.java b/src/core/lombok/javac/handlers/HandleJacksonized.java index aff0bf63..0aa02d1b 100644 --- a/src/core/lombok/javac/handlers/HandleJacksonized.java +++ b/src/core/lombok/javac/handlers/HandleJacksonized.java @@ -149,7 +149,6 @@ 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(JCAnnotation ast, JavacNode annotationNode, JavacNode annotatedNode, JCClassDecl td, AnnotationValues<Builder> builderAnnotation, JavacTreeMaker maker) { diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index a3e876c4..5241a209 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1520,6 +1520,20 @@ public class JavacHandlerUtil { * Searches the given field node for annotations that are specifically intentioned to be copied to the setter. */ public static List<JCAnnotation> findCopyableToSetterAnnotations(JavacNode node) { + return findAnnotationsInList(node, COPY_TO_SETTER_ANNOTATIONS); + } + + /** + * Searches the given field node for annotations that are specifically intentioned to be copied to the builder's singular method. + */ + public static List<JCAnnotation> findCopyableToBuilderSingularSetterAnnotations(JavacNode node) { + return findAnnotationsInList(node, COPY_TO_BUILDER_SINGULAR_SETTER_ANNOTATIONS); + } + + /** + * Searches the given field node for annotations that are in the given list, and returns those. + */ + private static List<JCAnnotation> findAnnotationsInList(JavacNode node, java.util.List<String> annotationsToFind) { JCAnnotation anno = null; String annoName = null; for (JavacNode child : node.down()) { @@ -1537,7 +1551,7 @@ public class JavacHandlerUtil { if (annoName == null) return List.nil(); if (!annoName.isEmpty()) { - for (String bn : COPY_TO_SETTER_ANNOTATIONS) if (typeMatches(bn, node, anno.annotationType)) return List.of(anno); + for (String bn : annotationsToFind) if (typeMatches(bn, node, anno.annotationType)) return List.of(anno); } ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>(); @@ -1545,7 +1559,7 @@ public class JavacHandlerUtil { if (child.getKind() == Kind.ANNOTATION) { JCAnnotation annotation = (JCAnnotation) child.get(); boolean match = false; - if (!match) for (String bn : COPY_TO_SETTER_ANNOTATIONS) if (typeMatches(bn, node, annotation.annotationType)) { + if (!match) for (String bn : annotationsToFind) if (typeMatches(bn, node, annotation.annotationType)) { result.append(annotation); break; } diff --git a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java index ba052b5a..7cd52c8c 100644 --- a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java +++ b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java @@ -182,11 +182,12 @@ public class JavacSingularsRecipes { return this; } - protected JCModifiers makeMods(JavacTreeMaker maker, CheckerFrameworkVersion cfv, JavacNode node, boolean deprecate, AccessLevel access) { + protected JCModifiers makeMods(JavacTreeMaker maker, CheckerFrameworkVersion cfv, JavacNode node, boolean deprecate, AccessLevel access, List<JCAnnotation> methodAnnotations) { JCAnnotation deprecateAnn = deprecate ? maker.Annotation(genJavaLangTypeRef(node, "Deprecated"), List.<JCExpression>nil()) : null; JCAnnotation rrAnn = cfv.generateReturnsReceiver() ? maker.Annotation(genTypeRef(node, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.<JCExpression>nil()) : null; List<JCAnnotation> annsOnMethod = (deprecateAnn != null && rrAnn != null) ? List.of(deprecateAnn, rrAnn) : deprecateAnn != null ? List.of(deprecateAnn) : rrAnn != null ? List.of(rrAnn) : List.<JCAnnotation>nil(); + annsOnMethod = mergeAnnotations(annsOnMethod,methodAnnotations); return maker.Modifiers(toJavacModifier(access), annsOnMethod); } @@ -271,10 +272,10 @@ public class JavacSingularsRecipes { generateClearMethod(cfv, deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source, access); } - private void finishAndInjectMethod(CheckerFrameworkVersion cfv, JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean deprecate, ListBuffer<JCStatement> statements, Name methodName, List<JCVariableDecl> jcVariableDecls, AccessLevel access, Boolean ignoreNullCollections) { + private void finishAndInjectMethod(CheckerFrameworkVersion cfv, JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean deprecate, ListBuffer<JCStatement> statements, Name methodName, List<JCVariableDecl> jcVariableDecls, List<JCAnnotation> methodAnnotations, AccessLevel access, Boolean ignoreNullCollections) { if (returnStatement != null) statements.append(returnStatement); JCBlock body = maker.Block(0, statements.toList()); - JCModifiers mods = makeMods(maker, cfv, builderType, deprecate, access); + JCModifiers mods = makeMods(maker, cfv, builderType, deprecate, access, methodAnnotations); List<JCTypeParameter> typeParams = List.nil(); List<JCExpression> thrown = List.nil(); @@ -298,7 +299,7 @@ public class JavacSingularsRecipes { statements.add(clearStatement); Name methodName = builderType.toName(HandlerUtil.buildAccessorName("clear", data.getPluralName().toString())); - finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, methodName, List.<JCVariableDecl>nil(), access, null); + finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, methodName, List.<JCVariableDecl>nil(), List.<JCAnnotation>nil(), access, null); } protected abstract JCStatement generateClearStatements(JavacTreeMaker maker, SingularData data, JavacNode builderType); @@ -312,7 +313,8 @@ public class JavacSingularsRecipes { if (!setterPrefix.isEmpty()) name = builderType.toName(HandlerUtil.buildAccessorName(setterPrefix, name.toString())); statements.prepend(createConstructBuilderVarIfNeeded(maker, data, builderType, source)); - finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, name, params, access, null); + List<JCAnnotation> methodAnnotations = copyAnnotations(findCopyableToBuilderSingularSetterAnnotations(data.annotation.up())); + finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, name, params, methodAnnotations, access, null); } protected JCVariableDecl generateSingularMethodParameter(int typeIndex, JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source, Name name) { @@ -357,8 +359,10 @@ public class JavacSingularsRecipes { } else { statements.prepend(JavacHandlerUtil.generateNullCheck(maker, null, data.getPluralName(), builderType, "%s cannot be null")); } + + List<JCAnnotation> methodAnnotations = copyAnnotations(findCopyableToSetterAnnotations(data.annotation.up())); - finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, name, List.of(param), access, ignoreNullCollections); + finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, name, List.of(param), methodAnnotations, access, ignoreNullCollections); } protected ListBuffer<JCStatement> generatePluralMethodStatements(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source) { diff --git a/test/stubs/com/fasterxml/jackson/annotation/JsonAnySetter.java b/test/stubs/com/fasterxml/jackson/annotation/JsonAnySetter.java new file mode 100644 index 00000000..51d2c3fa --- /dev/null +++ b/test/stubs/com/fasterxml/jackson/annotation/JsonAnySetter.java @@ -0,0 +1,12 @@ +package com.fasterxml.jackson.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface JsonAnySetter { + boolean enabled() default true; +} diff --git a/test/transform/resource/after-delombok/JacksonBuilderSingular.java b/test/transform/resource/after-delombok/JacksonBuilderSingular.java new file mode 100644 index 00000000..feaa6832 --- /dev/null +++ b/test/transform/resource/after-delombok/JacksonBuilderSingular.java @@ -0,0 +1,177 @@ +import java.util.List; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(builder = JacksonBuilderSingular.JacksonBuilderSingularBuilder.class) +public class JacksonBuilderSingular { + @JsonAnySetter + private Map<String, Object> any; + @JsonProperty("v_a_l_u_e_s") + private List<String> values; + @JsonAnySetter + private ImmutableMap<String, Object> guavaAny; + @JsonProperty("guava_v_a_l_u_e_s") + private ImmutableList<String> guavaValues; + @java.lang.SuppressWarnings("all") + JacksonBuilderSingular(final Map<String, Object> any, final List<String> values, final ImmutableMap<String, Object> guavaAny, final ImmutableList<String> guavaValues) { + this.any = any; + this.values = values; + this.guavaAny = guavaAny; + this.guavaValues = guavaValues; + } + @java.lang.SuppressWarnings("all") + @com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder(withPrefix = "", buildMethodName = "build") + public static class JacksonBuilderSingularBuilder { + @java.lang.SuppressWarnings("all") + private java.util.ArrayList<String> any$key; + @java.lang.SuppressWarnings("all") + private java.util.ArrayList<Object> any$value; + @java.lang.SuppressWarnings("all") + private java.util.ArrayList<String> values; + @java.lang.SuppressWarnings("all") + private com.google.common.collect.ImmutableMap.Builder<String, Object> guavaAny; + @java.lang.SuppressWarnings("all") + private com.google.common.collect.ImmutableList.Builder<String> guavaValues; + @java.lang.SuppressWarnings("all") + JacksonBuilderSingularBuilder() { + } + @JsonAnySetter + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder any(final String anyKey, final Object anyValue) { + if (this.any$key == null) { + this.any$key = new java.util.ArrayList<String>(); + this.any$value = new java.util.ArrayList<Object>(); + } + this.any$key.add(anyKey); + this.any$value.add(anyValue); + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder any(final java.util.Map<? extends String, ? extends Object> any) { + if (any == null) { + throw new java.lang.NullPointerException("any cannot be null"); + } + if (this.any$key == null) { + this.any$key = new java.util.ArrayList<String>(); + this.any$value = new java.util.ArrayList<Object>(); + } + for (final java.util.Map.Entry<? extends String, ? extends Object> $lombokEntry : any.entrySet()) { + this.any$key.add($lombokEntry.getKey()); + this.any$value.add($lombokEntry.getValue()); + } + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder clearAny() { + if (this.any$key != null) { + this.any$key.clear(); + this.any$value.clear(); + } + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder value(final String value) { + if (this.values == null) this.values = new java.util.ArrayList<String>(); + this.values.add(value); + return this; + } + @JsonProperty("v_a_l_u_e_s") + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder values(final java.util.Collection<? extends String> values) { + if (values == null) { + throw new java.lang.NullPointerException("values cannot be null"); + } + if (this.values == null) this.values = new java.util.ArrayList<String>(); + this.values.addAll(values); + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder clearValues() { + if (this.values != null) this.values.clear(); + return this; + } + @JsonAnySetter + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaAny(final String key, final Object value) { + if (this.guavaAny == null) this.guavaAny = com.google.common.collect.ImmutableMap.builder(); + this.guavaAny.put(key, value); + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaAny(final java.util.Map<? extends String, ? extends Object> guavaAny) { + if (guavaAny == null) { + throw new java.lang.NullPointerException("guavaAny cannot be null"); + } + if (this.guavaAny == null) this.guavaAny = com.google.common.collect.ImmutableMap.builder(); + this.guavaAny.putAll(guavaAny); + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder clearGuavaAny() { + this.guavaAny = null; + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaValue(final String guavaValue) { + if (this.guavaValues == null) this.guavaValues = com.google.common.collect.ImmutableList.builder(); + this.guavaValues.add(guavaValue); + return this; + } + @JsonProperty("guava_v_a_l_u_e_s") + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaValues(final java.lang.Iterable<? extends String> guavaValues) { + if (guavaValues == null) { + throw new java.lang.NullPointerException("guavaValues cannot be null"); + } + if (this.guavaValues == null) this.guavaValues = com.google.common.collect.ImmutableList.builder(); + this.guavaValues.addAll(guavaValues); + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder clearGuavaValues() { + this.guavaValues = null; + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular build() { + java.util.Map<String, Object> any; + switch (this.any$key == null ? 0 : this.any$key.size()) { + case 0: + any = java.util.Collections.emptyMap(); + break; + case 1: + any = java.util.Collections.singletonMap(this.any$key.get(0), this.any$value.get(0)); + break; + default: + any = new java.util.LinkedHashMap<String, Object>(this.any$key.size() < 1073741824 ? 1 + this.any$key.size() + (this.any$key.size() - 3) / 3 : java.lang.Integer.MAX_VALUE); + for (int $i = 0; $i < this.any$key.size(); $i++) any.put(this.any$key.get($i), (Object) this.any$value.get($i)); + any = java.util.Collections.unmodifiableMap(any); + } + java.util.List<String> 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<String>(this.values)); + } + com.google.common.collect.ImmutableMap<String, Object> guavaAny = this.guavaAny == null ? com.google.common.collect.ImmutableMap.<String, Object>of() : this.guavaAny.build(); + com.google.common.collect.ImmutableList<String> guavaValues = this.guavaValues == null ? com.google.common.collect.ImmutableList.<String>of() : this.guavaValues.build(); + return new JacksonBuilderSingular(any, values, guavaAny, guavaValues); + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "JacksonBuilderSingular.JacksonBuilderSingularBuilder(any$key=" + this.any$key + ", any$value=" + this.any$value + ", values=" + this.values + ", guavaAny=" + this.guavaAny + ", guavaValues=" + this.guavaValues + ")"; + } + } + @java.lang.SuppressWarnings("all") + public static JacksonBuilderSingular.JacksonBuilderSingularBuilder builder() { + return new JacksonBuilderSingular.JacksonBuilderSingularBuilder(); + } +}
\ No newline at end of file diff --git a/test/transform/resource/after-ecj/JacksonBuilderSingular.java b/test/transform/resource/after-ecj/JacksonBuilderSingular.java new file mode 100644 index 00000000..50f6a797 --- /dev/null +++ b/test/transform/resource/after-ecj/JacksonBuilderSingular.java @@ -0,0 +1,164 @@ +import java.util.List; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import lombok.Builder; +import lombok.Singular; +import lombok.extern.jackson.Jacksonized; +public @Jacksonized @Builder @com.fasterxml.jackson.databind.annotation.JsonDeserialize(builder = JacksonBuilderSingular.JacksonBuilderSingularBuilder.class) class JacksonBuilderSingular { + public static @java.lang.SuppressWarnings("all") @com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder(withPrefix = "",buildMethodName = "build") class JacksonBuilderSingularBuilder { + private @java.lang.SuppressWarnings("all") java.util.ArrayList<String> any$key; + private @java.lang.SuppressWarnings("all") java.util.ArrayList<Object> any$value; + private @java.lang.SuppressWarnings("all") java.util.ArrayList<String> values; + private @java.lang.SuppressWarnings("all") com.google.common.collect.ImmutableMap.Builder<String, Object> guavaAny; + private @java.lang.SuppressWarnings("all") com.google.common.collect.ImmutableList.Builder<String> guavaValues; + @java.lang.SuppressWarnings("all") JacksonBuilderSingularBuilder() { + super(); + } + public @JsonAnySetter @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder any(final String anyKey, final Object anyValue) { + if ((this.any$key == null)) + { + this.any$key = new java.util.ArrayList<String>(); + this.any$value = new java.util.ArrayList<Object>(); + } + this.any$key.add(anyKey); + this.any$value.add(anyValue); + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder any(final java.util.Map<? extends String, ? extends Object> any) { + if ((any == null)) + { + throw new java.lang.NullPointerException("any cannot be null"); + } + if ((this.any$key == null)) + { + this.any$key = new java.util.ArrayList<String>(); + this.any$value = new java.util.ArrayList<Object>(); + } + for (java.util.Map.Entry<? extends String, ? extends Object> $lombokEntry : any.entrySet()) + { + this.any$key.add($lombokEntry.getKey()); + this.any$value.add($lombokEntry.getValue()); + } + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder clearAny() { + if ((this.any$key != null)) + { + this.any$key.clear(); + this.any$value.clear(); + } + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder value(final String value) { + if ((this.values == null)) + this.values = new java.util.ArrayList<String>(); + this.values.add(value); + return this; + } + public @JsonProperty("v_a_l_u_e_s") @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder values(final java.util.Collection<? extends String> values) { + if ((values == null)) + { + throw new java.lang.NullPointerException("values cannot be null"); + } + if ((this.values == null)) + this.values = new java.util.ArrayList<String>(); + this.values.addAll(values); + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder clearValues() { + if ((this.values != null)) + this.values.clear(); + return this; + } + public @JsonAnySetter @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaAny(final String key, final Object value) { + if ((this.guavaAny == null)) + this.guavaAny = com.google.common.collect.ImmutableMap.builder(); + this.guavaAny.put(key, value); + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaAny(final java.util.Map<? extends String, ? extends Object> guavaAny) { + if ((guavaAny == null)) + { + throw new java.lang.NullPointerException("guavaAny cannot be null"); + } + if ((this.guavaAny == null)) + this.guavaAny = com.google.common.collect.ImmutableMap.builder(); + this.guavaAny.putAll(guavaAny); + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder clearGuavaAny() { + this.guavaAny = null; + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaValue(final String guavaValue) { + if ((this.guavaValues == null)) + this.guavaValues = com.google.common.collect.ImmutableList.builder(); + this.guavaValues.add(guavaValue); + return this; + } + public @JsonProperty("guava_v_a_l_u_e_s") @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaValues(final java.lang.Iterable<? extends String> guavaValues) { + if ((guavaValues == null)) + { + throw new java.lang.NullPointerException("guavaValues cannot be null"); + } + if ((this.guavaValues == null)) + this.guavaValues = com.google.common.collect.ImmutableList.builder(); + this.guavaValues.addAll(guavaValues); + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder clearGuavaValues() { + this.guavaValues = null; + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular build() { + java.util.Map<String, Object> any; + switch (((this.any$key == null) ? 0 : this.any$key.size())) { + case 0 : + any = java.util.Collections.emptyMap(); + break; + case 1 : + any = java.util.Collections.singletonMap(this.any$key.get(0), this.any$value.get(0)); + break; + default : + any = new java.util.LinkedHashMap<String, Object>(((this.any$key.size() < 0x40000000) ? ((1 + this.any$key.size()) + ((this.any$key.size() - 3) / 3)) : java.lang.Integer.MAX_VALUE)); + for (int $i = 0;; ($i < this.any$key.size()); $i ++) + any.put(this.any$key.get($i), this.any$value.get($i)); + any = java.util.Collections.unmodifiableMap(any); + } + java.util.List<String> 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<String>(this.values)); + } + com.google.common.collect.ImmutableMap<String, Object> guavaAny = ((this.guavaAny == null) ? com.google.common.collect.ImmutableMap.<String, Object>of() : this.guavaAny.build()); + com.google.common.collect.ImmutableList<String> guavaValues = ((this.guavaValues == null) ? com.google.common.collect.ImmutableList.<String>of() : this.guavaValues.build()); + return new JacksonBuilderSingular(any, values, guavaAny, guavaValues); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (((((((((("JacksonBuilderSingular.JacksonBuilderSingularBuilder(any$key=" + this.any$key) + ", any$value=") + this.any$value) + ", values=") + this.values) + ", guavaAny=") + this.guavaAny) + ", guavaValues=") + this.guavaValues) + ")"); + } + } + private @JsonAnySetter @Singular("any") Map<String, Object> any; + private @JsonProperty("v_a_l_u_e_s") @Singular List<String> values; + private @JsonAnySetter @Singular("guavaAny") ImmutableMap<String, Object> guavaAny; + private @JsonProperty("guava_v_a_l_u_e_s") @Singular ImmutableList<String> guavaValues; + @java.lang.SuppressWarnings("all") JacksonBuilderSingular(final Map<String, Object> any, final List<String> values, final ImmutableMap<String, Object> guavaAny, final ImmutableList<String> guavaValues) { + super(); + this.any = any; + this.values = values; + this.guavaAny = guavaAny; + this.guavaValues = guavaValues; + } + public static @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder builder() { + return new JacksonBuilderSingular.JacksonBuilderSingularBuilder(); + } +}
\ No newline at end of file diff --git a/test/transform/resource/before/JacksonBuilderSingular.java b/test/transform/resource/before/JacksonBuilderSingular.java new file mode 100644 index 00000000..c179c760 --- /dev/null +++ b/test/transform/resource/before/JacksonBuilderSingular.java @@ -0,0 +1,31 @@ +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +import lombok.Builder; +import lombok.Singular; +import lombok.extern.jackson.Jacksonized; + +@Jacksonized +@Builder +public class JacksonBuilderSingular { + @JsonAnySetter + @Singular("any") + private Map<String, Object> any; + + @JsonProperty("v_a_l_u_e_s") + @Singular + private List<String> values; + + @JsonAnySetter + @Singular("guavaAny") + private ImmutableMap<String, Object> guavaAny; + + @JsonProperty("guava_v_a_l_u_e_s") + @Singular + private ImmutableList<String> guavaValues; +} |