From 7a575e1e5d1c78fa5be1deca7fc308bd9eb390dd Mon Sep 17 00:00:00 2001 From: Werner Dietl Date: Mon, 28 May 2018 13:32:49 -0400 Subject: Copy all field annotations to the corresponding builder parameter. Maybe some filtering is necessary and should be added later. --- src/core/lombok/javac/handlers/HandleBuilder.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index 1a471029..335dee1a 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -85,6 +85,7 @@ public class HandleBuilder extends JavacAnnotationHandler { } private static class BuilderFieldData { + List annotations; JCExpression type; Name rawName; Name name; @@ -151,6 +152,7 @@ public class HandleBuilder extends JavacAnnotationHandler { BuilderFieldData bfd = new BuilderFieldData(); bfd.rawName = fd.name; bfd.name = removePrefixFromField(fieldNode); + bfd.annotations = fd.mods.annotations; bfd.type = fd.vartype; bfd.singularData = getSingularData(fieldNode); bfd.originalFieldNode = fieldNode; @@ -329,6 +331,7 @@ public class HandleBuilder extends JavacAnnotationHandler { JCVariableDecl raw = (JCVariableDecl) param.get(); bfd.name = raw.name; bfd.rawName = raw.name; + bfd.annotations = raw.mods.annotations; bfd.type = raw.vartype; bfd.singularData = getSingularData(param); bfd.originalFieldNode = param; @@ -678,13 +681,13 @@ public class HandleBuilder extends JavacAnnotationHandler { public void makeSetterMethodsForBuilder(JavacNode builderType, BuilderFieldData fieldNode, JavacNode source, boolean fluent, boolean chain) { boolean deprecate = isFieldDeprecated(fieldNode.originalFieldNode); if (fieldNode.singularData == null || fieldNode.singularData.getSingularizer() == null) { - makeSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.nameOfSetFlag, source, fluent, chain); + makeSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.nameOfSetFlag, source, fluent, chain, fieldNode.annotations); } else { fieldNode.singularData.getSingularizer().generateMethods(fieldNode.singularData, deprecate, builderType, source.get(), fluent, chain); } } - private void makeSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain) { + private void makeSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain, List annosOnParam) { Name fieldName = ((JCVariableDecl) fieldNode.get()).name; for (JavacNode child : builderType.down()) { @@ -698,7 +701,7 @@ public class HandleBuilder extends JavacAnnotationHandler { JavacTreeMaker maker = fieldNode.getTreeMaker(); - JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, nameOfSetFlag, chain, source, List.nil(), List.nil()); + JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, nameOfSetFlag, chain, source, List.nil(), annosOnParam); injectMethod(builderType, newMethod); } -- cgit From 79bfcc4f7ae4bcd61f7f942bfefb940c77927b71 Mon Sep 17 00:00:00 2001 From: Werner Dietl Date: Mon, 27 Aug 2018 18:36:13 -0400 Subject: Add configuration key, handle whereever NULLABLE is handled, support Eclipse. --- src/core/lombok/ConfigurationKeys.java | 8 ++++++++ src/core/lombok/core/handlers/HandlerUtil.java | 5 +++++ src/core/lombok/eclipse/handlers/HandleBuilder.java | 12 +++++++++--- .../lombok/eclipse/handlers/HandleConstructor.java | 3 ++- src/core/lombok/eclipse/handlers/HandleGetter.java | 1 + src/core/lombok/eclipse/handlers/HandleSetter.java | 3 ++- src/core/lombok/eclipse/handlers/HandleWither.java | 3 ++- src/core/lombok/javac/handlers/HandleBuilder.java | 7 ++++++- src/core/lombok/javac/handlers/HandleConstructor.java | 3 ++- src/core/lombok/javac/handlers/HandleGetter.java | 3 ++- src/core/lombok/javac/handlers/HandleSetter.java | 3 ++- src/core/lombok/javac/handlers/HandleWither.java | 3 ++- src/core/lombok/javac/handlers/JavacHandlerUtil.java | 17 +++++++++++++++++ src/utils/lombok/eclipse/Eclipse.java | 18 ++++++++++++++++++ 14 files changed, 78 insertions(+), 11 deletions(-) diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java index 184ded27..beb0d1e0 100644 --- a/src/core/lombok/ConfigurationKeys.java +++ b/src/core/lombok/ConfigurationKeys.java @@ -563,4 +563,12 @@ public class ConfigurationKeys { * If set to {@code true}, no further {@code lombok.config} files will be checked. */ public static final ConfigurationKey STOP_BUBBLING = new ConfigurationKey("config.stopBubbling", "Tell the configuration system it should stop looking for other configuration files (default: false).") {}; + + /** + * lombok configuration: {@code lombok.copyAnnotations} += <String: fully-qualified annotation class name>. + * + * Copy these annotations to getters, setters, etc. + */ + public static final ConfigurationKey> COPY_ANNOTATIONS = new ConfigurationKey>("lombok.copyAnnotations", "Copy these annotations to getters, setters, etc.") {}; + } diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java index 0d64c550..48c48c20 100644 --- a/src/core/lombok/core/handlers/HandlerUtil.java +++ b/src/core/lombok/core/handlers/HandlerUtil.java @@ -230,6 +230,11 @@ public class HandlerUtil { public static final String DEFAULT_EXCEPTION_FOR_NON_NULL = "java.lang.NullPointerException"; + /** Returns the configuration value for ConfigurationKeys.COPY_ANNOTATIONS. */ + public static List copyAnnotationNames(AST ast) { + return ast.readConfiguration(ConfigurationKeys.COPY_ANNOTATIONS); + } + /** * Generates a getter name from a given field name. * diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java index 4d20f052..77c29634 100644 --- a/src/core/lombok/eclipse/handlers/HandleBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java @@ -106,6 +106,7 @@ public class HandleBuilder extends EclipseAnnotationHandler { } private static class BuilderFieldData { + Annotation[] annotations; TypeReference type; char[] rawName; char[] name; @@ -199,9 +200,14 @@ public class HandleBuilder extends EclipseAnnotationHandler { EclipseNode isDefault = findAnnotation(Builder.Default.class, fieldNode); boolean isFinal = ((fd.modifiers & ClassFileConstants.AccFinal) != 0) || (valuePresent && !hasAnnotation(NonFinal.class, fieldNode)); + Annotation[] nonNulls = findAnnotations(fd, NON_NULL_PATTERN); + Annotation[] nullables = findAnnotations(fd, NULLABLE_PATTERN); + Annotation[] copyAnnotations = findExactAnnotations(fd, copyAnnotationNames(fieldNode.getAst())); + BuilderFieldData bfd = new BuilderFieldData(); bfd.rawName = fieldNode.getName().toCharArray(); bfd.name = removePrefixFromField(fieldNode); + bfd.annotations = copyAnnotations(fd, nonNulls, nullables, copyAnnotations); bfd.type = fd.type; bfd.singularData = getSingularData(fieldNode, ast); bfd.originalFieldNode = fieldNode; @@ -744,13 +750,13 @@ public class HandleBuilder extends EclipseAnnotationHandler { public void makeSetterMethodsForBuilder(EclipseNode builderType, BuilderFieldData bfd, EclipseNode sourceNode, boolean fluent, boolean chain) { boolean deprecate = isFieldDeprecated(bfd.originalFieldNode); if (bfd.singularData == null || bfd.singularData.getSingularizer() == null) { - makeSimpleSetterMethodForBuilder(builderType, deprecate, bfd.createdFields.get(0), bfd.nameOfSetFlag, sourceNode, fluent, chain); + makeSimpleSetterMethodForBuilder(builderType, deprecate, bfd.createdFields.get(0), bfd.nameOfSetFlag, sourceNode, fluent, chain, bfd.annotations); } else { bfd.singularData.getSingularizer().generateMethods(bfd.singularData, deprecate, builderType, fluent, chain); } } - private void makeSimpleSetterMethodForBuilder(EclipseNode builderType, boolean deprecate, EclipseNode fieldNode, char[] nameOfSetFlag, EclipseNode sourceNode, boolean fluent, boolean chain) { + private void makeSimpleSetterMethodForBuilder(EclipseNode builderType, boolean deprecate, EclipseNode fieldNode, char[] nameOfSetFlag, EclipseNode sourceNode, boolean fluent, boolean chain, Annotation[] annotations) { TypeDeclaration td = (TypeDeclaration) builderType.get(); AbstractMethodDeclaration[] existing = td.methods; if (existing == null) existing = EMPTY; @@ -767,7 +773,7 @@ public class HandleBuilder extends EclipseAnnotationHandler { String setterName = fluent ? fieldNode.getName() : HandlerUtil.buildAccessorName("set", fieldNode.getName()); MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, nameOfSetFlag, chain, ClassFileConstants.AccPublic, - sourceNode, Collections.emptyList(), Collections.emptyList()); + sourceNode, Collections.emptyList(), Arrays.asList(annotations)); injectMethod(builderType, setter); } diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java index 6c7b4caf..cb9c2b4b 100644 --- a/src/core/lombok/eclipse/handlers/HandleConstructor.java +++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java @@ -405,11 +405,12 @@ public class HandleConstructor { Argument parameter = new Argument(fieldName, fieldPos, copyType(field.type, source), Modifier.FINAL); Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN); Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN); + Annotation[] copyAnnotations = findExactAnnotations(field, copyAnnotationNames(fieldNode.getAst())); if (nonNulls.length != 0) { Statement nullCheck = generateNullCheck(parameter, sourceNode); if (nullCheck != null) nullChecks.add(nullCheck); } - parameter.annotations = copyAnnotations(source, nonNulls, nullables); + parameter.annotations = copyAnnotations(source, nonNulls, nullables, copyAnnotations); params.add(parameter); } diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java index d0c2cc23..45ddb2cc 100644 --- a/src/core/lombok/eclipse/handlers/HandleGetter.java +++ b/src/core/lombok/eclipse/handlers/HandleGetter.java @@ -274,6 +274,7 @@ public class HandleGetter extends EclipseAnnotationHandler { onMethod.toArray(new Annotation[0]), findAnnotations(field, NON_NULL_PATTERN), findAnnotations(field, NULLABLE_PATTERN), + findExactAnnotations(field, copyAnnotationNames(fieldNode.getAst())), findDelegatesAndMarkAsHandled(fieldNode), deprecated); } diff --git a/src/core/lombok/eclipse/handlers/HandleSetter.java b/src/core/lombok/eclipse/handlers/HandleSetter.java index d4df0deb..bd34b313 100644 --- a/src/core/lombok/eclipse/handlers/HandleSetter.java +++ b/src/core/lombok/eclipse/handlers/HandleSetter.java @@ -238,6 +238,7 @@ public class HandleSetter extends EclipseAnnotationHandler { Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN); Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN); + Annotation[] copyAnnotations = findExactAnnotations(field, copyAnnotationNames(fieldNode.getAst())); List statements = new ArrayList(5); if (nonNulls.length == 0) { statements.add(assignment); @@ -255,7 +256,7 @@ public class HandleSetter extends EclipseAnnotationHandler { statements.add(returnStatement); } method.statements = statements.toArray(new Statement[0]); - param.annotations = copyAnnotations(source, nonNulls, nullables, onParam.toArray(new Annotation[0])); + param.annotations = copyAnnotations(source, nonNulls, nullables, copyAnnotations, onParam.toArray(new Annotation[0])); method.traverse(new SetGeneratedByVisitor(source), parent.scope); return method; diff --git a/src/core/lombok/eclipse/handlers/HandleWither.java b/src/core/lombok/eclipse/handlers/HandleWither.java index c035fc26..e9831ce1 100644 --- a/src/core/lombok/eclipse/handlers/HandleWither.java +++ b/src/core/lombok/eclipse/handlers/HandleWither.java @@ -242,6 +242,7 @@ public class HandleWither extends EclipseAnnotationHandler { Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN); Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN); + Annotation[] copyAnnotations = findExactAnnotations(field, copyAnnotationNames(fieldNode.getAst())); if (!makeAbstract) { List args = new ArrayList(); @@ -285,7 +286,7 @@ public class HandleWither extends EclipseAnnotationHandler { method.statements = statements.toArray(new Statement[0]); } - param.annotations = copyAnnotations(source, nonNulls, nullables, onParam.toArray(new Annotation[0])); + param.annotations = copyAnnotations(source, nonNulls, nullables, copyAnnotations, onParam.toArray(new Annotation[0])); method.traverse(new SetGeneratedByVisitor(source), parent.scope); return method; diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index 335dee1a..75bfb01c 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -149,10 +149,15 @@ public class HandleBuilder extends JavacAnnotationHandler { JCVariableDecl fd = (JCVariableDecl) fieldNode.get(); JavacNode isDefault = findAnnotation(Builder.Default.class, fieldNode, false); boolean isFinal = (fd.mods.flags & Flags.FINAL) != 0 || (valuePresent && !hasAnnotation(NonFinal.class, fieldNode)); + + List nonNulls = findAnnotations(fieldNode, NON_NULL_PATTERN); + List nullables = findAnnotations(fieldNode, NULLABLE_PATTERN); + List copyAnnotations = findExactAnnotations(fieldNode, copyAnnotationNames(fieldNode.getAst())); + BuilderFieldData bfd = new BuilderFieldData(); bfd.rawName = fd.name; bfd.name = removePrefixFromField(fieldNode); - bfd.annotations = fd.mods.annotations; + bfd.annotations = nonNulls.appendList(nullables).appendList(copyAnnotations); bfd.type = fd.vartype; bfd.singularData = getSingularData(fieldNode); bfd.originalFieldNode = fieldNode; diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index 76caaffe..b0fa3d29 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -331,8 +331,9 @@ public class HandleConstructor { Name rawName = field.name; List nonNulls = findAnnotations(fieldNode, NON_NULL_PATTERN); List nullables = findAnnotations(fieldNode, NULLABLE_PATTERN); + List copyAnnotations = findExactAnnotations(fieldNode, copyAnnotationNames(fieldNode.getAst())); long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, typeNode.getContext()); - JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, nonNulls.appendList(nullables)), fieldName, field.vartype, null); + JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, nonNulls.appendList(nullables).appendList(copyAnnotations)), fieldName, field.vartype, null); params.append(param); if (!nonNulls.isEmpty()) { JCStatement nullCheck = generateNullCheck(maker, fieldNode, param, source); diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index 4fc6155c..6e4b2685 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -245,10 +245,11 @@ public class HandleGetter extends JavacAnnotationHandler { List nonNulls = findAnnotations(field, NON_NULL_PATTERN); List nullables = findAnnotations(field, NULLABLE_PATTERN); + List copyAnnotations = findExactAnnotations(field, copyAnnotationNames(field.getAst())); List delegates = findDelegatesAndRemoveFromField(field); - List annsOnMethod = copyAnnotations(onMethod).appendList(nonNulls).appendList(nullables); + List annsOnMethod = copyAnnotations(onMethod).appendList(nonNulls).appendList(nullables).appendList(copyAnnotations); if (isFieldDeprecated(field)) { annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(genJavaLangTypeRef(field, "Deprecated"), List.nil())); } diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index 0ddaa7d7..631ea193 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -228,9 +228,10 @@ public class HandleSetter extends JavacAnnotationHandler { ListBuffer statements = new ListBuffer(); List nonNulls = findAnnotations(field, NON_NULL_PATTERN); List nullables = findAnnotations(field, NULLABLE_PATTERN); + List copyAnnotations = findExactAnnotations(field, copyAnnotationNames(field.getAst())); Name methodName = field.toName(setterName); - List annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables); + List annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables).appendList(copyAnnotations); long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext()); JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(flags, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); diff --git a/src/core/lombok/javac/handlers/HandleWither.java b/src/core/lombok/javac/handlers/HandleWither.java index 87f3c16a..e6fc2d02 100644 --- a/src/core/lombok/javac/handlers/HandleWither.java +++ b/src/core/lombok/javac/handlers/HandleWither.java @@ -224,6 +224,7 @@ public class HandleWither extends JavacAnnotationHandler { List nonNulls = findAnnotations(field, NON_NULL_PATTERN); List nullables = findAnnotations(field, NULLABLE_PATTERN); + List copyAnnotations = findExactAnnotations(field, copyAnnotationNames(field.getAst())); Name methodName = field.toName(witherName); @@ -231,7 +232,7 @@ public class HandleWither extends JavacAnnotationHandler { JCBlock methodBody = null; long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext()); - List annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables); + List annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables).appendList(copyAnnotations); JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 92c642d4..cb729183 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1335,6 +1335,23 @@ public class JavacHandlerUtil { return result.toList(); } + /** + * Searches the given field node for annotations and returns each one that matches the provided list of names. + */ + public static List findExactAnnotations(JavacNode fieldNode, java.util.List names) { + ListBuffer result = new ListBuffer(); + for (JavacNode child : fieldNode.down()) { + if (child.getKind() == Kind.ANNOTATION) { + JCAnnotation annotation = (JCAnnotation) child.get(); + String annoname = annotation.annotationType.toString(); + if (names.contains(annoname)) { + result.append(annotation); + } + } + } + return result.toList(); + } + /** * Generates a new statement that checks if the given variable is null, and if so, throws a configured exception with the * variable name as message. diff --git a/src/utils/lombok/eclipse/Eclipse.java b/src/utils/lombok/eclipse/Eclipse.java index 5dbe3e2d..42adeeac 100644 --- a/src/utils/lombok/eclipse/Eclipse.java +++ b/src/utils/lombok/eclipse/Eclipse.java @@ -155,6 +155,24 @@ public class Eclipse { return result.toArray(EMPTY_ANNOTATIONS_ARRAY); } + /** + * Searches the given field node for annotations and returns each one that matches the provided list of names. + */ + public static Annotation[] findExactAnnotations(FieldDeclaration field, List names) { + List result = new ArrayList(); + if (field.annotations == null) return EMPTY_ANNOTATIONS_ARRAY; + for (Annotation annotation : field.annotations) { + TypeReference typeRef = annotation.type; + if (typeRef != null && typeRef.getTypeName() != null) { + String annoname = toQualifiedName(typeRef.getTypeName()); + if (names.contains(annoname)) { + result.add(annotation); + } + } + } + return result.toArray(EMPTY_ANNOTATIONS_ARRAY); + } + /** Matches any of the 8 primitive names, such as {@code boolean}. */ private static final Pattern PRIMITIVE_TYPE_NAME_PATTERN = Pattern.compile( "^(boolean|byte|short|int|long|float|double|char)$"); -- cgit From fc35839c793dfe2e3294c0f526dcc4cb5741533b Mon Sep 17 00:00:00 2001 From: Werner Dietl Date: Mon, 27 Aug 2018 18:56:16 -0400 Subject: Copy annotations in Eclipse HandleBuilder. --- src/core/lombok/eclipse/handlers/HandleBuilder.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java index 77c29634..167d1ba0 100644 --- a/src/core/lombok/eclipse/handlers/HandleBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java @@ -382,6 +382,7 @@ public class HandleBuilder extends EclipseAnnotationHandler { Argument arg = (Argument) param.get(); bfd.rawName = arg.name; bfd.name = arg.name; + bfd.annotations = arg.annotations; bfd.type = arg.type; bfd.singularData = getSingularData(param, ast); bfd.originalFieldNode = param; -- cgit From 859cb5cf8c4b8beb7a93336b5484414c7ee42c05 Mon Sep 17 00:00:00 2001 From: Werner Dietl Date: Thu, 30 Aug 2018 00:09:09 -0400 Subject: First attempt at adding Getter test cases. --- .../resource/after-delombok/GetterTypeAnnosCopy.java | 18 ++++++++++++++++++ .../resource/after-delombok/GetterTypeAnnosNoCopy.java | 17 +++++++++++++++++ .../transform/resource/before/GetterTypeAnnosCopy.java | 16 ++++++++++++++++ .../resource/before/GetterTypeAnnosNoCopy.java | 14 ++++++++++++++ 4 files changed, 65 insertions(+) create mode 100644 test/transform/resource/after-delombok/GetterTypeAnnosCopy.java create mode 100644 test/transform/resource/after-delombok/GetterTypeAnnosNoCopy.java create mode 100644 test/transform/resource/before/GetterTypeAnnosCopy.java create mode 100644 test/transform/resource/before/GetterTypeAnnosNoCopy.java diff --git a/test/transform/resource/after-delombok/GetterTypeAnnosCopy.java b/test/transform/resource/after-delombok/GetterTypeAnnosCopy.java new file mode 100644 index 00000000..cde6cbdd --- /dev/null +++ b/test/transform/resource/after-delombok/GetterTypeAnnosCopy.java @@ -0,0 +1,18 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class GetterTypeAnnos { + @TA + List<@TA String> foo; + + @TA + @java.lang.SuppressWarnings("all") + public List<@TA String> getFoo() { + return this.foo; + } +} diff --git a/test/transform/resource/after-delombok/GetterTypeAnnosNoCopy.java b/test/transform/resource/after-delombok/GetterTypeAnnosNoCopy.java new file mode 100644 index 00000000..58054de6 --- /dev/null +++ b/test/transform/resource/after-delombok/GetterTypeAnnosNoCopy.java @@ -0,0 +1,17 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class GetterTypeAnnos { + @TA + List<@TA String> foo; + + @java.lang.SuppressWarnings("all") + public List<@TA String> getFoo() { + return this.foo; + } +} diff --git a/test/transform/resource/before/GetterTypeAnnosCopy.java b/test/transform/resource/before/GetterTypeAnnosCopy.java new file mode 100644 index 00000000..69152e1f --- /dev/null +++ b/test/transform/resource/before/GetterTypeAnnosCopy.java @@ -0,0 +1,16 @@ +//CONF: lombok.copyAnnotations += TA + +import lombok.Getter; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class GetterTypeAnnos { + @Getter + @TA List<@TA String> foo; +} diff --git a/test/transform/resource/before/GetterTypeAnnosNoCopy.java b/test/transform/resource/before/GetterTypeAnnosNoCopy.java new file mode 100644 index 00000000..48513f32 --- /dev/null +++ b/test/transform/resource/before/GetterTypeAnnosNoCopy.java @@ -0,0 +1,14 @@ +import lombok.Getter; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class GetterTypeAnnos { + @Getter + @TA List<@TA String> foo; +} -- cgit From ced71c5468310c389e23ccee66420b255278be03 Mon Sep 17 00:00:00 2001 From: Werner Dietl Date: Thu, 30 Aug 2018 12:22:03 -0400 Subject: Fix whitespace. --- test/transform/resource/before/GetterTypeAnnosCopy.java | 2 +- test/transform/resource/before/GetterTypeAnnosNoCopy.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/transform/resource/before/GetterTypeAnnosCopy.java b/test/transform/resource/before/GetterTypeAnnosCopy.java index 69152e1f..b48b8337 100644 --- a/test/transform/resource/before/GetterTypeAnnosCopy.java +++ b/test/transform/resource/before/GetterTypeAnnosCopy.java @@ -12,5 +12,5 @@ import java.util.List; class GetterTypeAnnos { @Getter - @TA List<@TA String> foo; + @TA List<@TA String> foo; } diff --git a/test/transform/resource/before/GetterTypeAnnosNoCopy.java b/test/transform/resource/before/GetterTypeAnnosNoCopy.java index 48513f32..bf4d9486 100644 --- a/test/transform/resource/before/GetterTypeAnnosNoCopy.java +++ b/test/transform/resource/before/GetterTypeAnnosNoCopy.java @@ -10,5 +10,5 @@ import java.util.List; class GetterTypeAnnos { @Getter - @TA List<@TA String> foo; + @TA List<@TA String> foo; } -- cgit From c3f34a8447ee4be38193a0c98ab4d265556bd8d7 Mon Sep 17 00:00:00 2001 From: Werner Dietl Date: Thu, 30 Aug 2018 12:23:07 -0400 Subject: Test cases for remaining features. --- .../after-delombok/BuilderTypeAnnosCopy.java | 51 ++++++++++++++++++++++ .../after-delombok/BuilderTypeAnnosNoCopy.java | 51 ++++++++++++++++++++++ .../after-delombok/ConstructorsTypeAnnosCopy.java | 17 ++++++++ .../ConstructorsTypeAnnosNoCopy.java | 17 ++++++++ .../after-delombok/SetterTypeAnnosCopy.java | 17 ++++++++ .../after-delombok/SetterTypeAnnosNoCopy.java | 17 ++++++++ .../after-delombok/WitherTypeAnnosCopy.java | 21 +++++++++ .../after-delombok/WitherTypeAnnosNoCopy.java | 21 +++++++++ .../resource/before/BuilderTypeAnnosCopy.java | 14 ++++++ .../resource/before/BuilderTypeAnnosNoCopy.java | 12 +++++ .../resource/before/ConstructorsTypeAnnosCopy.java | 14 ++++++ .../before/ConstructorsTypeAnnosNoCopy.java | 12 +++++ .../resource/before/SetterTypeAnnosCopy.java | 16 +++++++ .../resource/before/SetterTypeAnnosNoCopy.java | 14 ++++++ .../resource/before/WitherTypeAnnosCopy.java | 19 ++++++++ .../resource/before/WitherTypeAnnosNoCopy.java | 17 ++++++++ 16 files changed, 330 insertions(+) create mode 100644 test/transform/resource/after-delombok/BuilderTypeAnnosCopy.java create mode 100644 test/transform/resource/after-delombok/BuilderTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-delombok/ConstructorsTypeAnnosCopy.java create mode 100644 test/transform/resource/after-delombok/ConstructorsTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-delombok/SetterTypeAnnosCopy.java create mode 100644 test/transform/resource/after-delombok/SetterTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-delombok/WitherTypeAnnosCopy.java create mode 100644 test/transform/resource/after-delombok/WitherTypeAnnosNoCopy.java create mode 100644 test/transform/resource/before/BuilderTypeAnnosCopy.java create mode 100644 test/transform/resource/before/BuilderTypeAnnosNoCopy.java create mode 100644 test/transform/resource/before/ConstructorsTypeAnnosCopy.java create mode 100644 test/transform/resource/before/ConstructorsTypeAnnosNoCopy.java create mode 100644 test/transform/resource/before/SetterTypeAnnosCopy.java create mode 100644 test/transform/resource/before/SetterTypeAnnosNoCopy.java create mode 100644 test/transform/resource/before/WitherTypeAnnosCopy.java create mode 100644 test/transform/resource/before/WitherTypeAnnosNoCopy.java diff --git a/test/transform/resource/after-delombok/BuilderTypeAnnosCopy.java b/test/transform/resource/after-delombok/BuilderTypeAnnosCopy.java new file mode 100644 index 00000000..8b0ea537 --- /dev/null +++ b/test/transform/resource/after-delombok/BuilderTypeAnnosCopy.java @@ -0,0 +1,51 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class BuilderTypeAnnos { + @TA + private List<@TA String> foo; + + @java.lang.SuppressWarnings("all") + BuilderTypeAnnos(@TA final List<@TA String> foo) { + this.foo = foo; + } + + + @java.lang.SuppressWarnings("all") + public static class BuilderTypeAnnosBuilder { + @java.lang.SuppressWarnings("all") + private List<@TA String> foo; + + @java.lang.SuppressWarnings("all") + BuilderTypeAnnosBuilder() { + } + + @java.lang.SuppressWarnings("all") + public BuilderTypeAnnosBuilder foo(@TA final List<@TA String> foo) { + this.foo = foo; + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderTypeAnnos build() { + return new BuilderTypeAnnos(foo); + } + + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "BuilderTypeAnnos.BuilderTypeAnnosBuilder(foo=" + this.foo + ")"; + } + } + + @java.lang.SuppressWarnings("all") + public static BuilderTypeAnnosBuilder builder() { + return new BuilderTypeAnnosBuilder(); + } +} + diff --git a/test/transform/resource/after-delombok/BuilderTypeAnnosNoCopy.java b/test/transform/resource/after-delombok/BuilderTypeAnnosNoCopy.java new file mode 100644 index 00000000..b08e03a3 --- /dev/null +++ b/test/transform/resource/after-delombok/BuilderTypeAnnosNoCopy.java @@ -0,0 +1,51 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class BuilderTypeAnnos { + @TA + private List<@TA String> foo; + + @java.lang.SuppressWarnings("all") + BuilderTypeAnnos(final List<@TA String> foo) { + this.foo = foo; + } + + + @java.lang.SuppressWarnings("all") + public static class BuilderTypeAnnosBuilder { + @java.lang.SuppressWarnings("all") + private List<@TA String> foo; + + @java.lang.SuppressWarnings("all") + BuilderTypeAnnosBuilder() { + } + + @java.lang.SuppressWarnings("all") + public BuilderTypeAnnosBuilder foo(final List<@TA String> foo) { + this.foo = foo; + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderTypeAnnos build() { + return new BuilderTypeAnnos(foo); + } + + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "BuilderTypeAnnos.BuilderTypeAnnosBuilder(foo=" + this.foo + ")"; + } + } + + @java.lang.SuppressWarnings("all") + public static BuilderTypeAnnosBuilder builder() { + return new BuilderTypeAnnosBuilder(); + } +} + diff --git a/test/transform/resource/after-delombok/ConstructorsTypeAnnosCopy.java b/test/transform/resource/after-delombok/ConstructorsTypeAnnosCopy.java new file mode 100644 index 00000000..28d6ed09 --- /dev/null +++ b/test/transform/resource/after-delombok/ConstructorsTypeAnnosCopy.java @@ -0,0 +1,17 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class ConstructorsTypeAnnos { + @TA + List<@TA String> foo; + + @java.lang.SuppressWarnings("all") + public ConstructorsTypeAnnos(@TA final List<@TA String> foo) { + this.foo = foo; + } +} diff --git a/test/transform/resource/after-delombok/ConstructorsTypeAnnosNoCopy.java b/test/transform/resource/after-delombok/ConstructorsTypeAnnosNoCopy.java new file mode 100644 index 00000000..e27131ef --- /dev/null +++ b/test/transform/resource/after-delombok/ConstructorsTypeAnnosNoCopy.java @@ -0,0 +1,17 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class ConstructorsTypeAnnos { + @TA + List<@TA String> foo; + + @java.lang.SuppressWarnings("all") + public ConstructorsTypeAnnos(final List<@TA String> foo) { + this.foo = foo; + } +} diff --git a/test/transform/resource/after-delombok/SetterTypeAnnosCopy.java b/test/transform/resource/after-delombok/SetterTypeAnnosCopy.java new file mode 100644 index 00000000..b45c3234 --- /dev/null +++ b/test/transform/resource/after-delombok/SetterTypeAnnosCopy.java @@ -0,0 +1,17 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class SetterTypeAnnos { + @TA + List<@TA String> foo; + + @java.lang.SuppressWarnings("all") + public void setFoo(@TA final List<@TA String> foo) { + this.foo = foo; + } +} diff --git a/test/transform/resource/after-delombok/SetterTypeAnnosNoCopy.java b/test/transform/resource/after-delombok/SetterTypeAnnosNoCopy.java new file mode 100644 index 00000000..e773bd9c --- /dev/null +++ b/test/transform/resource/after-delombok/SetterTypeAnnosNoCopy.java @@ -0,0 +1,17 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class SetterTypeAnnos { + @TA + List<@TA String> foo; + + @java.lang.SuppressWarnings("all") + public void setFoo(final List<@TA String> foo) { + this.foo = foo; + } +} diff --git a/test/transform/resource/after-delombok/WitherTypeAnnosCopy.java b/test/transform/resource/after-delombok/WitherTypeAnnosCopy.java new file mode 100644 index 00000000..8cbb7e5d --- /dev/null +++ b/test/transform/resource/after-delombok/WitherTypeAnnosCopy.java @@ -0,0 +1,21 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class WitherTypeAnnos { + @TA + final List<@TA String> foo; + + WitherTypeAnnos(@TA List<@TA String> foo) { + this.foo = foo; + } + + @java.lang.SuppressWarnings("all") + public WitherTypeAnnos withFoo(@TA final List<@TA String> foo) { + return this.foo == foo ? this : new WitherTypeAnnos(foo); + } +} diff --git a/test/transform/resource/after-delombok/WitherTypeAnnosNoCopy.java b/test/transform/resource/after-delombok/WitherTypeAnnosNoCopy.java new file mode 100644 index 00000000..18c25e04 --- /dev/null +++ b/test/transform/resource/after-delombok/WitherTypeAnnosNoCopy.java @@ -0,0 +1,21 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class WitherTypeAnnos { + @TA + final List<@TA String> foo; + + WitherTypeAnnos(@TA List<@TA String> foo) { + this.foo = foo; + } + + @java.lang.SuppressWarnings("all") + public WitherTypeAnnos withFoo(final List<@TA String> foo) { + return this.foo == foo ? this : new WitherTypeAnnos(foo); + } +} diff --git a/test/transform/resource/before/BuilderTypeAnnosCopy.java b/test/transform/resource/before/BuilderTypeAnnosCopy.java new file mode 100644 index 00000000..e5ea9e41 --- /dev/null +++ b/test/transform/resource/before/BuilderTypeAnnosCopy.java @@ -0,0 +1,14 @@ +//CONF: lombok.copyAnnotations += TA + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +@lombok.Builder +class BuilderTypeAnnos { + private @TA List<@TA String> foo; +} diff --git a/test/transform/resource/before/BuilderTypeAnnosNoCopy.java b/test/transform/resource/before/BuilderTypeAnnosNoCopy.java new file mode 100644 index 00000000..2defba7b --- /dev/null +++ b/test/transform/resource/before/BuilderTypeAnnosNoCopy.java @@ -0,0 +1,12 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +@lombok.Builder +class BuilderTypeAnnos { + private @TA List<@TA String> foo; +} diff --git a/test/transform/resource/before/ConstructorsTypeAnnosCopy.java b/test/transform/resource/before/ConstructorsTypeAnnosCopy.java new file mode 100644 index 00000000..229927c3 --- /dev/null +++ b/test/transform/resource/before/ConstructorsTypeAnnosCopy.java @@ -0,0 +1,14 @@ +//CONF: lombok.copyAnnotations += TA + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +@lombok.AllArgsConstructor +class ConstructorsTypeAnnos { + @TA List<@TA String> foo; +} diff --git a/test/transform/resource/before/ConstructorsTypeAnnosNoCopy.java b/test/transform/resource/before/ConstructorsTypeAnnosNoCopy.java new file mode 100644 index 00000000..7bc27008 --- /dev/null +++ b/test/transform/resource/before/ConstructorsTypeAnnosNoCopy.java @@ -0,0 +1,12 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +@lombok.AllArgsConstructor +class ConstructorsTypeAnnos { + @TA List<@TA String> foo; +} diff --git a/test/transform/resource/before/SetterTypeAnnosCopy.java b/test/transform/resource/before/SetterTypeAnnosCopy.java new file mode 100644 index 00000000..d9d086f0 --- /dev/null +++ b/test/transform/resource/before/SetterTypeAnnosCopy.java @@ -0,0 +1,16 @@ +//CONF: lombok.copyAnnotations += TA + +import lombok.Setter; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class SetterTypeAnnos { + @Setter + @TA List<@TA String> foo; +} diff --git a/test/transform/resource/before/SetterTypeAnnosNoCopy.java b/test/transform/resource/before/SetterTypeAnnosNoCopy.java new file mode 100644 index 00000000..e3666543 --- /dev/null +++ b/test/transform/resource/before/SetterTypeAnnosNoCopy.java @@ -0,0 +1,14 @@ +import lombok.Setter; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class SetterTypeAnnos { + @Setter + @TA List<@TA String> foo; +} diff --git a/test/transform/resource/before/WitherTypeAnnosCopy.java b/test/transform/resource/before/WitherTypeAnnosCopy.java new file mode 100644 index 00000000..645682f5 --- /dev/null +++ b/test/transform/resource/before/WitherTypeAnnosCopy.java @@ -0,0 +1,19 @@ +//CONF: lombok.copyAnnotations += TA + +import lombok.experimental.Wither; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class WitherTypeAnnos { + @Wither final @TA List<@TA String> foo; + + WitherTypeAnnos(@TA List<@TA String> foo) { + this.foo = foo; + } +} diff --git a/test/transform/resource/before/WitherTypeAnnosNoCopy.java b/test/transform/resource/before/WitherTypeAnnosNoCopy.java new file mode 100644 index 00000000..d278af55 --- /dev/null +++ b/test/transform/resource/before/WitherTypeAnnosNoCopy.java @@ -0,0 +1,17 @@ +import lombok.experimental.Wither; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface TA { +} + +class WitherTypeAnnos { + @Wither final @TA List<@TA String> foo; + + WitherTypeAnnos(@TA List<@TA String> foo) { + this.foo = foo; + } +} -- cgit From 65fc9897b3c2183cef305a71cf6b064fb9756253 Mon Sep 17 00:00:00 2001 From: Werner Dietl Date: Thu, 30 Aug 2018 23:17:29 -0400 Subject: Handle null annotation array correctly. --- src/core/lombok/eclipse/handlers/HandleBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java index 167d1ba0..3e373a00 100644 --- a/src/core/lombok/eclipse/handlers/HandleBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java @@ -774,7 +774,7 @@ public class HandleBuilder extends EclipseAnnotationHandler { String setterName = fluent ? fieldNode.getName() : HandlerUtil.buildAccessorName("set", fieldNode.getName()); MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, nameOfSetFlag, chain, ClassFileConstants.AccPublic, - sourceNode, Collections.emptyList(), Arrays.asList(annotations)); + sourceNode, Collections.emptyList(), annotations != null ? Arrays.asList(annotations) : Collections.emptyList()); injectMethod(builderType, setter); } -- cgit From cd8434feee79c6e119de0a254e071c6c49a8938e Mon Sep 17 00:00:00 2001 From: Werner Dietl Date: Thu, 30 Aug 2018 23:18:33 -0400 Subject: Eclipse expected output. --- .../resource/after-ecj/BuilderTypeAnnosCopy.java | 31 ++++++++++++++++++++++ .../resource/after-ecj/BuilderTypeAnnosNoCopy.java | 31 ++++++++++++++++++++++ .../after-ecj/ConstructorsTypeAnnosCopy.java | 12 +++++++++ .../after-ecj/ConstructorsTypeAnnosNoCopy.java | 12 +++++++++ .../resource/after-ecj/GetterTypeAnnosCopy.java | 15 +++++++++++ .../resource/after-ecj/GetterTypeAnnosNoCopy.java | 15 +++++++++++ .../resource/after-ecj/SetterTypeAnnosCopy.java | 15 +++++++++++ .../resource/after-ecj/SetterTypeAnnosNoCopy.java | 15 +++++++++++ .../resource/after-ecj/WitherTypeAnnosCopy.java | 16 +++++++++++ .../resource/after-ecj/WitherTypeAnnosNoCopy.java | 16 +++++++++++ 10 files changed, 178 insertions(+) create mode 100644 test/transform/resource/after-ecj/BuilderTypeAnnosCopy.java create mode 100644 test/transform/resource/after-ecj/BuilderTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-ecj/ConstructorsTypeAnnosCopy.java create mode 100644 test/transform/resource/after-ecj/ConstructorsTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-ecj/GetterTypeAnnosCopy.java create mode 100644 test/transform/resource/after-ecj/GetterTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-ecj/SetterTypeAnnosCopy.java create mode 100644 test/transform/resource/after-ecj/SetterTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-ecj/WitherTypeAnnosCopy.java create mode 100644 test/transform/resource/after-ecj/WitherTypeAnnosNoCopy.java diff --git a/test/transform/resource/after-ecj/BuilderTypeAnnosCopy.java b/test/transform/resource/after-ecj/BuilderTypeAnnosCopy.java new file mode 100644 index 00000000..8dfc8164 --- /dev/null +++ b/test/transform/resource/after-ecj/BuilderTypeAnnosCopy.java @@ -0,0 +1,31 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { +} +@lombok.Builder class BuilderTypeAnnos { + public static @java.lang.SuppressWarnings("all") class BuilderTypeAnnosBuilder { + private @java.lang.SuppressWarnings("all") List foo; + @java.lang.SuppressWarnings("all") BuilderTypeAnnosBuilder() { + super(); + } + public @java.lang.SuppressWarnings("all") BuilderTypeAnnosBuilder foo(final @TA List foo) { + this.foo = foo; + return this; + } + public @java.lang.SuppressWarnings("all") BuilderTypeAnnos build() { + return new BuilderTypeAnnos(foo); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (("BuilderTypeAnnos.BuilderTypeAnnosBuilder(foo=" + this.foo) + ")"); + } + } + private @TA List<@TA String> foo; + @java.lang.SuppressWarnings("all") BuilderTypeAnnos(final @TA List foo) { + super(); + this.foo = foo; + } + public static @java.lang.SuppressWarnings("all") BuilderTypeAnnosBuilder builder() { + return new BuilderTypeAnnosBuilder(); + } +} diff --git a/test/transform/resource/after-ecj/BuilderTypeAnnosNoCopy.java b/test/transform/resource/after-ecj/BuilderTypeAnnosNoCopy.java new file mode 100644 index 00000000..a2dfcc2f --- /dev/null +++ b/test/transform/resource/after-ecj/BuilderTypeAnnosNoCopy.java @@ -0,0 +1,31 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { +} +@lombok.Builder class BuilderTypeAnnos { + public static @java.lang.SuppressWarnings("all") class BuilderTypeAnnosBuilder { + private @java.lang.SuppressWarnings("all") List foo; + @java.lang.SuppressWarnings("all") BuilderTypeAnnosBuilder() { + super(); + } + public @java.lang.SuppressWarnings("all") BuilderTypeAnnosBuilder foo(final List foo) { + this.foo = foo; + return this; + } + public @java.lang.SuppressWarnings("all") BuilderTypeAnnos build() { + return new BuilderTypeAnnos(foo); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (("BuilderTypeAnnos.BuilderTypeAnnosBuilder(foo=" + this.foo) + ")"); + } + } + private @TA List<@TA String> foo; + @java.lang.SuppressWarnings("all") BuilderTypeAnnos(final List foo) { + super(); + this.foo = foo; + } + public static @java.lang.SuppressWarnings("all") BuilderTypeAnnosBuilder builder() { + return new BuilderTypeAnnosBuilder(); + } +} diff --git a/test/transform/resource/after-ecj/ConstructorsTypeAnnosCopy.java b/test/transform/resource/after-ecj/ConstructorsTypeAnnosCopy.java new file mode 100644 index 00000000..ad372fc9 --- /dev/null +++ b/test/transform/resource/after-ecj/ConstructorsTypeAnnosCopy.java @@ -0,0 +1,12 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { +} +@lombok.AllArgsConstructor class ConstructorsTypeAnnos { + @TA List<@TA String> foo; + public @java.lang.SuppressWarnings("all") ConstructorsTypeAnnos(final @TA List foo) { + super(); + this.foo = foo; + } +} diff --git a/test/transform/resource/after-ecj/ConstructorsTypeAnnosNoCopy.java b/test/transform/resource/after-ecj/ConstructorsTypeAnnosNoCopy.java new file mode 100644 index 00000000..ce4b1b3b --- /dev/null +++ b/test/transform/resource/after-ecj/ConstructorsTypeAnnosNoCopy.java @@ -0,0 +1,12 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { +} +@lombok.AllArgsConstructor class ConstructorsTypeAnnos { + @TA List<@TA String> foo; + public @java.lang.SuppressWarnings("all") ConstructorsTypeAnnos(final List foo) { + super(); + this.foo = foo; + } +} diff --git a/test/transform/resource/after-ecj/GetterTypeAnnosCopy.java b/test/transform/resource/after-ecj/GetterTypeAnnosCopy.java new file mode 100644 index 00000000..1b4f03c5 --- /dev/null +++ b/test/transform/resource/after-ecj/GetterTypeAnnosCopy.java @@ -0,0 +1,15 @@ +import lombok.Getter; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { +} +class GetterTypeAnnos { + @Getter @TA List<@TA String> foo; + GetterTypeAnnos() { + super(); + } + public @TA @java.lang.SuppressWarnings("all") List getFoo() { + return this.foo; + } +} diff --git a/test/transform/resource/after-ecj/GetterTypeAnnosNoCopy.java b/test/transform/resource/after-ecj/GetterTypeAnnosNoCopy.java new file mode 100644 index 00000000..a43d3215 --- /dev/null +++ b/test/transform/resource/after-ecj/GetterTypeAnnosNoCopy.java @@ -0,0 +1,15 @@ +import lombok.Getter; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { +} +class GetterTypeAnnos { + @Getter @TA List<@TA String> foo; + GetterTypeAnnos() { + super(); + } + public @java.lang.SuppressWarnings("all") List getFoo() { + return this.foo; + } +} diff --git a/test/transform/resource/after-ecj/SetterTypeAnnosCopy.java b/test/transform/resource/after-ecj/SetterTypeAnnosCopy.java new file mode 100644 index 00000000..ef290cbf --- /dev/null +++ b/test/transform/resource/after-ecj/SetterTypeAnnosCopy.java @@ -0,0 +1,15 @@ +import lombok.Setter; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { +} +class SetterTypeAnnos { + @Setter @TA List<@TA String> foo; + SetterTypeAnnos() { + super(); + } + public @java.lang.SuppressWarnings("all") void setFoo(final @TA List foo) { + this.foo = foo; + } +} diff --git a/test/transform/resource/after-ecj/SetterTypeAnnosNoCopy.java b/test/transform/resource/after-ecj/SetterTypeAnnosNoCopy.java new file mode 100644 index 00000000..17e27782 --- /dev/null +++ b/test/transform/resource/after-ecj/SetterTypeAnnosNoCopy.java @@ -0,0 +1,15 @@ +import lombok.Setter; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { +} +class SetterTypeAnnos { + @Setter @TA List<@TA String> foo; + SetterTypeAnnos() { + super(); + } + public @java.lang.SuppressWarnings("all") void setFoo(final List foo) { + this.foo = foo; + } +} diff --git a/test/transform/resource/after-ecj/WitherTypeAnnosCopy.java b/test/transform/resource/after-ecj/WitherTypeAnnosCopy.java new file mode 100644 index 00000000..b4f3c687 --- /dev/null +++ b/test/transform/resource/after-ecj/WitherTypeAnnosCopy.java @@ -0,0 +1,16 @@ +import lombok.experimental.Wither; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { +} +class WitherTypeAnnos { + final @Wither @TA List<@TA String> foo; + WitherTypeAnnos(@TA List<@TA String> foo) { + super(); + this.foo = foo; + } + public @java.lang.SuppressWarnings("all") WitherTypeAnnos withFoo(final @TA List foo) { + return ((this.foo == foo) ? this : new WitherTypeAnnos(foo)); + } +} diff --git a/test/transform/resource/after-ecj/WitherTypeAnnosNoCopy.java b/test/transform/resource/after-ecj/WitherTypeAnnosNoCopy.java new file mode 100644 index 00000000..4f0b0710 --- /dev/null +++ b/test/transform/resource/after-ecj/WitherTypeAnnosNoCopy.java @@ -0,0 +1,16 @@ +import lombok.experimental.Wither; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { +} +class WitherTypeAnnos { + final @Wither @TA List<@TA String> foo; + WitherTypeAnnos(@TA List<@TA String> foo) { + super(); + this.foo = foo; + } + public @java.lang.SuppressWarnings("all") WitherTypeAnnos withFoo(final List foo) { + return ((this.foo == foo) ? this : new WitherTypeAnnos(foo)); + } +} -- cgit From cc8370ab2d7b3ca15023364c99e53735e62e13d7 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Tue, 4 Sep 2018 01:47:59 +0200 Subject: code review and fixes for the ‘copyable annotations’ setting concept. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/lombok/ConfigurationKeys.java | 6 +-- src/core/lombok/core/handlers/HandlerUtil.java | 6 +-- .../eclipse/handlers/EclipseHandlerUtil.java | 18 ++++++++ .../lombok/eclipse/handlers/HandleBuilder.java | 13 ++++-- .../lombok/eclipse/handlers/HandleConstructor.java | 2 +- src/core/lombok/eclipse/handlers/HandleGetter.java | 2 +- src/core/lombok/eclipse/handlers/HandleSetter.java | 4 +- src/core/lombok/eclipse/handlers/HandleWither.java | 4 +- src/core/lombok/javac/handlers/HandleBuilder.java | 15 ++++--- .../lombok/javac/handlers/HandleConstructor.java | 4 +- src/core/lombok/javac/handlers/HandleGetter.java | 4 +- src/core/lombok/javac/handlers/HandleSetter.java | 4 +- src/core/lombok/javac/handlers/HandleWither.java | 4 +- .../lombok/javac/handlers/JavacHandlerUtil.java | 8 ++-- src/utils/lombok/eclipse/Eclipse.java | 22 +--------- .../resource/after-delombok/BuilderTypeAnnos.java | 45 +++++++++++++++++++ .../after-delombok/BuilderTypeAnnosCopy.java | 51 ---------------------- .../after-delombok/BuilderTypeAnnosNoCopy.java | 51 ---------------------- .../after-delombok/ConstructorsTypeAnnos.java | 18 ++++++++ .../after-delombok/ConstructorsTypeAnnosCopy.java | 17 -------- .../ConstructorsTypeAnnosNoCopy.java | 17 -------- .../resource/after-delombok/GetterTypeAnnos.java | 19 ++++++++ .../after-delombok/GetterTypeAnnosCopy.java | 18 -------- .../after-delombok/GetterTypeAnnosNoCopy.java | 17 -------- .../resource/after-delombok/SetterTypeAnnos.java | 18 ++++++++ .../after-delombok/SetterTypeAnnosCopy.java | 17 -------- .../after-delombok/SetterTypeAnnosNoCopy.java | 17 -------- .../resource/after-delombok/WitherTypeAnnos.java | 21 +++++++++ .../after-delombok/WitherTypeAnnosCopy.java | 21 --------- .../after-delombok/WitherTypeAnnosNoCopy.java | 21 --------- .../resource/after-ecj/BuilderTypeAnnos.java | 33 ++++++++++++++ .../resource/after-ecj/BuilderTypeAnnosCopy.java | 31 ------------- .../resource/after-ecj/BuilderTypeAnnosNoCopy.java | 31 ------------- .../resource/after-ecj/ConstructorsTypeAnnos.java | 14 ++++++ .../after-ecj/ConstructorsTypeAnnosCopy.java | 12 ----- .../after-ecj/ConstructorsTypeAnnosNoCopy.java | 12 ----- .../resource/after-ecj/GetterTypeAnnos.java | 17 ++++++++ .../resource/after-ecj/GetterTypeAnnosCopy.java | 15 ------- .../resource/after-ecj/GetterTypeAnnosNoCopy.java | 15 ------- .../resource/after-ecj/SetterTypeAnnos.java | 17 ++++++++ .../resource/after-ecj/SetterTypeAnnosCopy.java | 15 ------- .../resource/after-ecj/SetterTypeAnnosNoCopy.java | 15 ------- .../resource/after-ecj/WitherTypeAnnos.java | 18 ++++++++ .../resource/after-ecj/WitherTypeAnnosCopy.java | 16 ------- .../resource/after-ecj/WitherTypeAnnosNoCopy.java | 16 ------- .../resource/before/BuilderTypeAnnos.java | 14 ++++++ .../resource/before/BuilderTypeAnnosCopy.java | 14 ------ .../resource/before/BuilderTypeAnnosNoCopy.java | 12 ----- .../resource/before/ConstructorsTypeAnnos.java | 14 ++++++ .../resource/before/ConstructorsTypeAnnosCopy.java | 14 ------ .../before/ConstructorsTypeAnnosNoCopy.java | 12 ----- .../transform/resource/before/GetterTypeAnnos.java | 15 +++++++ .../resource/before/GetterTypeAnnosCopy.java | 16 ------- .../resource/before/GetterTypeAnnosNoCopy.java | 14 ------ .../transform/resource/before/SetterTypeAnnos.java | 15 +++++++ .../resource/before/SetterTypeAnnosCopy.java | 16 ------- .../resource/before/SetterTypeAnnosNoCopy.java | 14 ------ .../transform/resource/before/WitherTypeAnnos.java | 18 ++++++++ .../resource/before/WitherTypeAnnosCopy.java | 19 -------- .../resource/before/WitherTypeAnnosNoCopy.java | 17 -------- 60 files changed, 358 insertions(+), 627 deletions(-) create mode 100644 test/transform/resource/after-delombok/BuilderTypeAnnos.java delete mode 100644 test/transform/resource/after-delombok/BuilderTypeAnnosCopy.java delete mode 100644 test/transform/resource/after-delombok/BuilderTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-delombok/ConstructorsTypeAnnos.java delete mode 100644 test/transform/resource/after-delombok/ConstructorsTypeAnnosCopy.java delete mode 100644 test/transform/resource/after-delombok/ConstructorsTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-delombok/GetterTypeAnnos.java delete mode 100644 test/transform/resource/after-delombok/GetterTypeAnnosCopy.java delete mode 100644 test/transform/resource/after-delombok/GetterTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-delombok/SetterTypeAnnos.java delete mode 100644 test/transform/resource/after-delombok/SetterTypeAnnosCopy.java delete mode 100644 test/transform/resource/after-delombok/SetterTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-delombok/WitherTypeAnnos.java delete mode 100644 test/transform/resource/after-delombok/WitherTypeAnnosCopy.java delete mode 100644 test/transform/resource/after-delombok/WitherTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-ecj/BuilderTypeAnnos.java delete mode 100644 test/transform/resource/after-ecj/BuilderTypeAnnosCopy.java delete mode 100644 test/transform/resource/after-ecj/BuilderTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-ecj/ConstructorsTypeAnnos.java delete mode 100644 test/transform/resource/after-ecj/ConstructorsTypeAnnosCopy.java delete mode 100644 test/transform/resource/after-ecj/ConstructorsTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-ecj/GetterTypeAnnos.java delete mode 100644 test/transform/resource/after-ecj/GetterTypeAnnosCopy.java delete mode 100644 test/transform/resource/after-ecj/GetterTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-ecj/SetterTypeAnnos.java delete mode 100644 test/transform/resource/after-ecj/SetterTypeAnnosCopy.java delete mode 100644 test/transform/resource/after-ecj/SetterTypeAnnosNoCopy.java create mode 100644 test/transform/resource/after-ecj/WitherTypeAnnos.java delete mode 100644 test/transform/resource/after-ecj/WitherTypeAnnosCopy.java delete mode 100644 test/transform/resource/after-ecj/WitherTypeAnnosNoCopy.java create mode 100644 test/transform/resource/before/BuilderTypeAnnos.java delete mode 100644 test/transform/resource/before/BuilderTypeAnnosCopy.java delete mode 100644 test/transform/resource/before/BuilderTypeAnnosNoCopy.java create mode 100644 test/transform/resource/before/ConstructorsTypeAnnos.java delete mode 100644 test/transform/resource/before/ConstructorsTypeAnnosCopy.java delete mode 100644 test/transform/resource/before/ConstructorsTypeAnnosNoCopy.java create mode 100644 test/transform/resource/before/GetterTypeAnnos.java delete mode 100644 test/transform/resource/before/GetterTypeAnnosCopy.java delete mode 100644 test/transform/resource/before/GetterTypeAnnosNoCopy.java create mode 100644 test/transform/resource/before/SetterTypeAnnos.java delete mode 100644 test/transform/resource/before/SetterTypeAnnosCopy.java delete mode 100644 test/transform/resource/before/SetterTypeAnnosNoCopy.java create mode 100644 test/transform/resource/before/WitherTypeAnnos.java delete mode 100644 test/transform/resource/before/WitherTypeAnnosCopy.java delete mode 100644 test/transform/resource/before/WitherTypeAnnosNoCopy.java diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java index beb0d1e0..89748f60 100644 --- a/src/core/lombok/ConfigurationKeys.java +++ b/src/core/lombok/ConfigurationKeys.java @@ -565,10 +565,10 @@ public class ConfigurationKeys { public static final ConfigurationKey STOP_BUBBLING = new ConfigurationKey("config.stopBubbling", "Tell the configuration system it should stop looking for other configuration files (default: false).") {}; /** - * lombok configuration: {@code lombok.copyAnnotations} += <String: fully-qualified annotation class name>. + * lombok configuration: {@code lombok.copyableAnnotations} += <String: fully-qualified annotation class name>. * - * Copy these annotations to getters, setters, etc. + * Copy these annotations to getters, setters, withers, builder-setters, etc. */ - public static final ConfigurationKey> COPY_ANNOTATIONS = new ConfigurationKey>("lombok.copyAnnotations", "Copy these annotations to getters, setters, etc.") {}; + public static final ConfigurationKey> COPYABLE_ANNOTATIONS = new ConfigurationKey>("lombok.copyableAnnotations", "Copy these annotations to getters, setters, withers, builder-setters, etc.") {}; } diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java index 48c48c20..1694e305 100644 --- a/src/core/lombok/core/handlers/HandlerUtil.java +++ b/src/core/lombok/core/handlers/HandlerUtil.java @@ -230,9 +230,9 @@ public class HandlerUtil { public static final String DEFAULT_EXCEPTION_FOR_NON_NULL = "java.lang.NullPointerException"; - /** Returns the configuration value for ConfigurationKeys.COPY_ANNOTATIONS. */ - public static List copyAnnotationNames(AST ast) { - return ast.readConfiguration(ConfigurationKeys.COPY_ANNOTATIONS); + /** Returns the configuration value for ConfigurationKeys.COPYABLE_ANNOTATIONS. */ + public static List getCopyableAnnotationNames(AST ast) { + return ast.readConfiguration(ConfigurationKeys.COPYABLE_ANNOTATIONS); } /** diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 1e29764a..e7a58de3 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -672,6 +672,24 @@ public class EclipseHandlerUtil { } } + private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY = new Annotation[0]; + + /** + * Searches the given field node for annotations and returns each one that matches the provided list of names. + */ + public static Annotation[] findExactAnnotations(AbstractVariableDeclaration field, List names) { + List result = new ArrayList(); + if (field.annotations == null) return EMPTY_ANNOTATIONS_ARRAY; + for (Annotation annotation : field.annotations) { + TypeReference typeRef = annotation.type; + if (typeRef != null && typeRef.getTypeName() != null) { + String annoName = toQualifiedName(typeRef.getTypeName()); + if (names.contains(annoName)) result.add(annotation); + } + } + return result.toArray(EMPTY_ANNOTATIONS_ARRAY); + } + /** * Checks if the provided annotation type is likely to be the intended type for the given annotation node. * diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java index 3e373a00..f05896ab 100644 --- a/src/core/lombok/eclipse/handlers/HandleBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java @@ -202,8 +202,8 @@ public class HandleBuilder extends EclipseAnnotationHandler { Annotation[] nonNulls = findAnnotations(fd, NON_NULL_PATTERN); Annotation[] nullables = findAnnotations(fd, NULLABLE_PATTERN); - Annotation[] copyAnnotations = findExactAnnotations(fd, copyAnnotationNames(fieldNode.getAst())); - + Annotation[] copyAnnotations = findExactAnnotations(fd, getCopyableAnnotationNames(fieldNode.getAst())); + BuilderFieldData bfd = new BuilderFieldData(); bfd.rawName = fieldNode.getName().toCharArray(); bfd.name = removePrefixFromField(fieldNode); @@ -380,9 +380,14 @@ public class HandleBuilder extends EclipseAnnotationHandler { if (param.getKind() != Kind.ARGUMENT) continue; BuilderFieldData bfd = new BuilderFieldData(); Argument arg = (Argument) param.get(); + + Annotation[] nonNulls = findAnnotations(arg, NON_NULL_PATTERN); + Annotation[] nullables = findAnnotations(arg, NULLABLE_PATTERN); + Annotation[] copyAnnotations = findExactAnnotations(arg, getCopyableAnnotationNames(param.getAst())); + bfd.rawName = arg.name; bfd.name = arg.name; - bfd.annotations = arg.annotations; + bfd.annotations = copyAnnotations(arg, nonNulls, nullables, copyAnnotations); bfd.type = arg.type; bfd.singularData = getSingularData(param, ast); bfd.originalFieldNode = param; @@ -774,7 +779,7 @@ public class HandleBuilder extends EclipseAnnotationHandler { String setterName = fluent ? fieldNode.getName() : HandlerUtil.buildAccessorName("set", fieldNode.getName()); MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, nameOfSetFlag, chain, ClassFileConstants.AccPublic, - sourceNode, Collections.emptyList(), annotations != null ? Arrays.asList(annotations) : Collections.emptyList()); + sourceNode, Collections.emptyList(), annotations != null ? Arrays.asList(copyAnnotations(sourceNode.get(), annotations)) : Collections.emptyList()); injectMethod(builderType, setter); } diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java index cb9c2b4b..3d947a73 100644 --- a/src/core/lombok/eclipse/handlers/HandleConstructor.java +++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java @@ -405,7 +405,7 @@ public class HandleConstructor { Argument parameter = new Argument(fieldName, fieldPos, copyType(field.type, source), Modifier.FINAL); Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN); Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN); - Annotation[] copyAnnotations = findExactAnnotations(field, copyAnnotationNames(fieldNode.getAst())); + Annotation[] copyAnnotations = findExactAnnotations(field, getCopyableAnnotationNames(fieldNode.getAst())); if (nonNulls.length != 0) { Statement nullCheck = generateNullCheck(parameter, sourceNode); if (nullCheck != null) nullChecks.add(nullCheck); diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java index 45ddb2cc..58af8c1e 100644 --- a/src/core/lombok/eclipse/handlers/HandleGetter.java +++ b/src/core/lombok/eclipse/handlers/HandleGetter.java @@ -274,7 +274,7 @@ public class HandleGetter extends EclipseAnnotationHandler { onMethod.toArray(new Annotation[0]), findAnnotations(field, NON_NULL_PATTERN), findAnnotations(field, NULLABLE_PATTERN), - findExactAnnotations(field, copyAnnotationNames(fieldNode.getAst())), + findExactAnnotations(field, getCopyableAnnotationNames(fieldNode.getAst())), findDelegatesAndMarkAsHandled(fieldNode), deprecated); } diff --git a/src/core/lombok/eclipse/handlers/HandleSetter.java b/src/core/lombok/eclipse/handlers/HandleSetter.java index bd34b313..ca81fef7 100644 --- a/src/core/lombok/eclipse/handlers/HandleSetter.java +++ b/src/core/lombok/eclipse/handlers/HandleSetter.java @@ -238,7 +238,7 @@ public class HandleSetter extends EclipseAnnotationHandler { Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN); Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN); - Annotation[] copyAnnotations = findExactAnnotations(field, copyAnnotationNames(fieldNode.getAst())); + Annotation[] copyableAnnotations = findExactAnnotations(field, getCopyableAnnotationNames(fieldNode.getAst())); List statements = new ArrayList(5); if (nonNulls.length == 0) { statements.add(assignment); @@ -256,7 +256,7 @@ public class HandleSetter extends EclipseAnnotationHandler { statements.add(returnStatement); } method.statements = statements.toArray(new Statement[0]); - param.annotations = copyAnnotations(source, nonNulls, nullables, copyAnnotations, onParam.toArray(new Annotation[0])); + param.annotations = copyAnnotations(source, nonNulls, nullables, copyableAnnotations, onParam.toArray(new Annotation[0])); method.traverse(new SetGeneratedByVisitor(source), parent.scope); return method; diff --git a/src/core/lombok/eclipse/handlers/HandleWither.java b/src/core/lombok/eclipse/handlers/HandleWither.java index e9831ce1..11032e9c 100644 --- a/src/core/lombok/eclipse/handlers/HandleWither.java +++ b/src/core/lombok/eclipse/handlers/HandleWither.java @@ -242,7 +242,7 @@ public class HandleWither extends EclipseAnnotationHandler { Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN); Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN); - Annotation[] copyAnnotations = findExactAnnotations(field, copyAnnotationNames(fieldNode.getAst())); + Annotation[] copyableAnnotations = findExactAnnotations(field, getCopyableAnnotationNames(fieldNode.getAst())); if (!makeAbstract) { List args = new ArrayList(); @@ -286,7 +286,7 @@ public class HandleWither extends EclipseAnnotationHandler { method.statements = statements.toArray(new Statement[0]); } - param.annotations = copyAnnotations(source, nonNulls, nullables, copyAnnotations, onParam.toArray(new Annotation[0])); + param.annotations = copyAnnotations(source, nonNulls, nullables, copyableAnnotations, onParam.toArray(new Annotation[0])); method.traverse(new SetGeneratedByVisitor(source), parent.scope); return method; diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index 75bfb01c..7577eeb2 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -149,15 +149,15 @@ public class HandleBuilder extends JavacAnnotationHandler { JCVariableDecl fd = (JCVariableDecl) fieldNode.get(); JavacNode isDefault = findAnnotation(Builder.Default.class, fieldNode, false); boolean isFinal = (fd.mods.flags & Flags.FINAL) != 0 || (valuePresent && !hasAnnotation(NonFinal.class, fieldNode)); - + List nonNulls = findAnnotations(fieldNode, NON_NULL_PATTERN); List nullables = findAnnotations(fieldNode, NULLABLE_PATTERN); - List copyAnnotations = findExactAnnotations(fieldNode, copyAnnotationNames(fieldNode.getAst())); - + List copyableAnnotations = findExactAnnotations(fieldNode, getCopyableAnnotationNames(fieldNode.getAst())); + BuilderFieldData bfd = new BuilderFieldData(); bfd.rawName = fd.name; bfd.name = removePrefixFromField(fieldNode); - bfd.annotations = nonNulls.appendList(nullables).appendList(copyAnnotations); + bfd.annotations = nonNulls.appendList(nullables).appendList(copyableAnnotations); bfd.type = fd.vartype; bfd.singularData = getSingularData(fieldNode); bfd.originalFieldNode = fieldNode; @@ -333,10 +333,15 @@ public class HandleBuilder extends JavacAnnotationHandler { for (JavacNode param : fillParametersFrom.down()) { if (param.getKind() != Kind.ARGUMENT) continue; BuilderFieldData bfd = new BuilderFieldData(); + + List nonNulls = findAnnotations(param, NON_NULL_PATTERN); + List nullables = findAnnotations(param, NULLABLE_PATTERN); + List copyableAnnotations = findExactAnnotations(param, getCopyableAnnotationNames(param.getAst())); + JCVariableDecl raw = (JCVariableDecl) param.get(); bfd.name = raw.name; bfd.rawName = raw.name; - bfd.annotations = raw.mods.annotations; + bfd.annotations = nonNulls.appendList(nullables).appendList(copyableAnnotations); bfd.type = raw.vartype; bfd.singularData = getSingularData(param); bfd.originalFieldNode = param; diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index b0fa3d29..1e45d73f 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -331,9 +331,9 @@ public class HandleConstructor { Name rawName = field.name; List nonNulls = findAnnotations(fieldNode, NON_NULL_PATTERN); List nullables = findAnnotations(fieldNode, NULLABLE_PATTERN); - List copyAnnotations = findExactAnnotations(fieldNode, copyAnnotationNames(fieldNode.getAst())); + List copyableAnnotations = findExactAnnotations(fieldNode, getCopyableAnnotationNames(fieldNode.getAst())); long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, typeNode.getContext()); - JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, nonNulls.appendList(nullables).appendList(copyAnnotations)), fieldName, field.vartype, null); + JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, nonNulls.appendList(nullables).appendList(copyableAnnotations)), fieldName, field.vartype, null); params.append(param); if (!nonNulls.isEmpty()) { JCStatement nullCheck = generateNullCheck(maker, fieldNode, param, source); diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index 6e4b2685..04b300a8 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -245,11 +245,11 @@ public class HandleGetter extends JavacAnnotationHandler { List nonNulls = findAnnotations(field, NON_NULL_PATTERN); List nullables = findAnnotations(field, NULLABLE_PATTERN); - List copyAnnotations = findExactAnnotations(field, copyAnnotationNames(field.getAst())); + List copyableAnnotations = findExactAnnotations(field, getCopyableAnnotationNames(field.getAst())); List delegates = findDelegatesAndRemoveFromField(field); - List annsOnMethod = copyAnnotations(onMethod).appendList(nonNulls).appendList(nullables).appendList(copyAnnotations); + List annsOnMethod = copyAnnotations(onMethod).appendList(nonNulls).appendList(nullables).appendList(copyableAnnotations); if (isFieldDeprecated(field)) { annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(genJavaLangTypeRef(field, "Deprecated"), List.nil())); } diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index 631ea193..e5e9481d 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -228,10 +228,10 @@ public class HandleSetter extends JavacAnnotationHandler { ListBuffer statements = new ListBuffer(); List nonNulls = findAnnotations(field, NON_NULL_PATTERN); List nullables = findAnnotations(field, NULLABLE_PATTERN); - List copyAnnotations = findExactAnnotations(field, copyAnnotationNames(field.getAst())); + List copyableAnnotations = findExactAnnotations(field, getCopyableAnnotationNames(field.getAst())); Name methodName = field.toName(setterName); - List annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables).appendList(copyAnnotations); + List annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables).appendList(copyableAnnotations); long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext()); JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(flags, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); diff --git a/src/core/lombok/javac/handlers/HandleWither.java b/src/core/lombok/javac/handlers/HandleWither.java index e6fc2d02..b0e32d61 100644 --- a/src/core/lombok/javac/handlers/HandleWither.java +++ b/src/core/lombok/javac/handlers/HandleWither.java @@ -224,7 +224,7 @@ public class HandleWither extends JavacAnnotationHandler { List nonNulls = findAnnotations(field, NON_NULL_PATTERN); List nullables = findAnnotations(field, NULLABLE_PATTERN); - List copyAnnotations = findExactAnnotations(field, copyAnnotationNames(field.getAst())); + List copyableAnnotations = findExactAnnotations(field, getCopyableAnnotationNames(field.getAst())); Name methodName = field.toName(witherName); @@ -232,7 +232,7 @@ public class HandleWither extends JavacAnnotationHandler { JCBlock methodBody = null; long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext()); - List annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables).appendList(copyAnnotations); + List annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables).appendList(copyableAnnotations); JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index cb729183..1cc28072 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1343,15 +1343,13 @@ public class JavacHandlerUtil { for (JavacNode child : fieldNode.down()) { if (child.getKind() == Kind.ANNOTATION) { JCAnnotation annotation = (JCAnnotation) child.get(); - String annoname = annotation.annotationType.toString(); - if (names.contains(annoname)) { - result.append(annotation); - } + String annoName = annotation.annotationType.toString(); + if (names.contains(annoName)) result.append(annotation); } } return result.toList(); } - + /** * Generates a new statement that checks if the given variable is null, and if so, throws a configured exception with the * variable name as message. diff --git a/src/utils/lombok/eclipse/Eclipse.java b/src/utils/lombok/eclipse/Eclipse.java index 42adeeac..5b3c453e 100644 --- a/src/utils/lombok/eclipse/Eclipse.java +++ b/src/utils/lombok/eclipse/Eclipse.java @@ -31,11 +31,11 @@ import lombok.core.ClassLiteral; import lombok.core.FieldSelect; import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; +import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess; import org.eclipse.jdt.internal.compiler.ast.Clinit; import org.eclipse.jdt.internal.compiler.ast.Expression; -import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.Literal; import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; @@ -139,7 +139,7 @@ public class Eclipse { * * Only the simple name is checked - the package and any containing class are ignored. */ - public static Annotation[] findAnnotations(FieldDeclaration field, Pattern namePattern) { + public static Annotation[] findAnnotations(AbstractVariableDeclaration field, Pattern namePattern) { List result = new ArrayList(); if (field.annotations == null) return EMPTY_ANNOTATIONS_ARRAY; for (Annotation annotation : field.annotations) { @@ -155,24 +155,6 @@ public class Eclipse { return result.toArray(EMPTY_ANNOTATIONS_ARRAY); } - /** - * Searches the given field node for annotations and returns each one that matches the provided list of names. - */ - public static Annotation[] findExactAnnotations(FieldDeclaration field, List names) { - List result = new ArrayList(); - if (field.annotations == null) return EMPTY_ANNOTATIONS_ARRAY; - for (Annotation annotation : field.annotations) { - TypeReference typeRef = annotation.type; - if (typeRef != null && typeRef.getTypeName() != null) { - String annoname = toQualifiedName(typeRef.getTypeName()); - if (names.contains(annoname)) { - result.add(annotation); - } - } - } - return result.toArray(EMPTY_ANNOTATIONS_ARRAY); - } - /** Matches any of the 8 primitive names, such as {@code boolean}. */ private static final Pattern PRIMITIVE_TYPE_NAME_PATTERN = Pattern.compile( "^(boolean|byte|short|int|long|float|double|char)$"); diff --git a/test/transform/resource/after-delombok/BuilderTypeAnnos.java b/test/transform/resource/after-delombok/BuilderTypeAnnos.java new file mode 100644 index 00000000..8a31762a --- /dev/null +++ b/test/transform/resource/after-delombok/BuilderTypeAnnos.java @@ -0,0 +1,45 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TA { +} +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TB { +} +class BuilderTypeAnnos { + @TA + @TB + private List foo; + @java.lang.SuppressWarnings("all") + BuilderTypeAnnos(@TA final List foo) { + this.foo = foo; + } + @java.lang.SuppressWarnings("all") + public static class BuilderTypeAnnosBuilder { + @java.lang.SuppressWarnings("all") + private List foo; + @java.lang.SuppressWarnings("all") + BuilderTypeAnnosBuilder() { + } + @java.lang.SuppressWarnings("all") + public BuilderTypeAnnosBuilder foo(@TA final List foo) { + this.foo = foo; + return this; + } + @java.lang.SuppressWarnings("all") + public BuilderTypeAnnos build() { + return new BuilderTypeAnnos(foo); + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "BuilderTypeAnnos.BuilderTypeAnnosBuilder(foo=" + this.foo + ")"; + } + } + @java.lang.SuppressWarnings("all") + public static BuilderTypeAnnosBuilder builder() { + return new BuilderTypeAnnosBuilder(); + } +} + diff --git a/test/transform/resource/after-delombok/BuilderTypeAnnosCopy.java b/test/transform/resource/after-delombok/BuilderTypeAnnosCopy.java deleted file mode 100644 index 8b0ea537..00000000 --- a/test/transform/resource/after-delombok/BuilderTypeAnnosCopy.java +++ /dev/null @@ -1,51 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class BuilderTypeAnnos { - @TA - private List<@TA String> foo; - - @java.lang.SuppressWarnings("all") - BuilderTypeAnnos(@TA final List<@TA String> foo) { - this.foo = foo; - } - - - @java.lang.SuppressWarnings("all") - public static class BuilderTypeAnnosBuilder { - @java.lang.SuppressWarnings("all") - private List<@TA String> foo; - - @java.lang.SuppressWarnings("all") - BuilderTypeAnnosBuilder() { - } - - @java.lang.SuppressWarnings("all") - public BuilderTypeAnnosBuilder foo(@TA final List<@TA String> foo) { - this.foo = foo; - return this; - } - - @java.lang.SuppressWarnings("all") - public BuilderTypeAnnos build() { - return new BuilderTypeAnnos(foo); - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { - return "BuilderTypeAnnos.BuilderTypeAnnosBuilder(foo=" + this.foo + ")"; - } - } - - @java.lang.SuppressWarnings("all") - public static BuilderTypeAnnosBuilder builder() { - return new BuilderTypeAnnosBuilder(); - } -} - diff --git a/test/transform/resource/after-delombok/BuilderTypeAnnosNoCopy.java b/test/transform/resource/after-delombok/BuilderTypeAnnosNoCopy.java deleted file mode 100644 index b08e03a3..00000000 --- a/test/transform/resource/after-delombok/BuilderTypeAnnosNoCopy.java +++ /dev/null @@ -1,51 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class BuilderTypeAnnos { - @TA - private List<@TA String> foo; - - @java.lang.SuppressWarnings("all") - BuilderTypeAnnos(final List<@TA String> foo) { - this.foo = foo; - } - - - @java.lang.SuppressWarnings("all") - public static class BuilderTypeAnnosBuilder { - @java.lang.SuppressWarnings("all") - private List<@TA String> foo; - - @java.lang.SuppressWarnings("all") - BuilderTypeAnnosBuilder() { - } - - @java.lang.SuppressWarnings("all") - public BuilderTypeAnnosBuilder foo(final List<@TA String> foo) { - this.foo = foo; - return this; - } - - @java.lang.SuppressWarnings("all") - public BuilderTypeAnnos build() { - return new BuilderTypeAnnos(foo); - } - - @java.lang.Override - @java.lang.SuppressWarnings("all") - public java.lang.String toString() { - return "BuilderTypeAnnos.BuilderTypeAnnosBuilder(foo=" + this.foo + ")"; - } - } - - @java.lang.SuppressWarnings("all") - public static BuilderTypeAnnosBuilder builder() { - return new BuilderTypeAnnosBuilder(); - } -} - diff --git a/test/transform/resource/after-delombok/ConstructorsTypeAnnos.java b/test/transform/resource/after-delombok/ConstructorsTypeAnnos.java new file mode 100644 index 00000000..2d59681c --- /dev/null +++ b/test/transform/resource/after-delombok/ConstructorsTypeAnnos.java @@ -0,0 +1,18 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TA { +} +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TB { +} +class ConstructorsTypeAnnos { + @TA + @TB + List foo; + @java.lang.SuppressWarnings("all") + public ConstructorsTypeAnnos(@TA final List foo) { + this.foo = foo; + } +} diff --git a/test/transform/resource/after-delombok/ConstructorsTypeAnnosCopy.java b/test/transform/resource/after-delombok/ConstructorsTypeAnnosCopy.java deleted file mode 100644 index 28d6ed09..00000000 --- a/test/transform/resource/after-delombok/ConstructorsTypeAnnosCopy.java +++ /dev/null @@ -1,17 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class ConstructorsTypeAnnos { - @TA - List<@TA String> foo; - - @java.lang.SuppressWarnings("all") - public ConstructorsTypeAnnos(@TA final List<@TA String> foo) { - this.foo = foo; - } -} diff --git a/test/transform/resource/after-delombok/ConstructorsTypeAnnosNoCopy.java b/test/transform/resource/after-delombok/ConstructorsTypeAnnosNoCopy.java deleted file mode 100644 index e27131ef..00000000 --- a/test/transform/resource/after-delombok/ConstructorsTypeAnnosNoCopy.java +++ /dev/null @@ -1,17 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class ConstructorsTypeAnnos { - @TA - List<@TA String> foo; - - @java.lang.SuppressWarnings("all") - public ConstructorsTypeAnnos(final List<@TA String> foo) { - this.foo = foo; - } -} diff --git a/test/transform/resource/after-delombok/GetterTypeAnnos.java b/test/transform/resource/after-delombok/GetterTypeAnnos.java new file mode 100644 index 00000000..4a22c822 --- /dev/null +++ b/test/transform/resource/after-delombok/GetterTypeAnnos.java @@ -0,0 +1,19 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TA { +} +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TB { +} +class GetterTypeAnnos { + @TA + @TB + List foo; + @TA + @java.lang.SuppressWarnings("all") + public List getFoo() { + return this.foo; + } +} diff --git a/test/transform/resource/after-delombok/GetterTypeAnnosCopy.java b/test/transform/resource/after-delombok/GetterTypeAnnosCopy.java deleted file mode 100644 index cde6cbdd..00000000 --- a/test/transform/resource/after-delombok/GetterTypeAnnosCopy.java +++ /dev/null @@ -1,18 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class GetterTypeAnnos { - @TA - List<@TA String> foo; - - @TA - @java.lang.SuppressWarnings("all") - public List<@TA String> getFoo() { - return this.foo; - } -} diff --git a/test/transform/resource/after-delombok/GetterTypeAnnosNoCopy.java b/test/transform/resource/after-delombok/GetterTypeAnnosNoCopy.java deleted file mode 100644 index 58054de6..00000000 --- a/test/transform/resource/after-delombok/GetterTypeAnnosNoCopy.java +++ /dev/null @@ -1,17 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class GetterTypeAnnos { - @TA - List<@TA String> foo; - - @java.lang.SuppressWarnings("all") - public List<@TA String> getFoo() { - return this.foo; - } -} diff --git a/test/transform/resource/after-delombok/SetterTypeAnnos.java b/test/transform/resource/after-delombok/SetterTypeAnnos.java new file mode 100644 index 00000000..77ddf9ce --- /dev/null +++ b/test/transform/resource/after-delombok/SetterTypeAnnos.java @@ -0,0 +1,18 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TA { +} +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TB { +} +class SetterTypeAnnos { + @TA + @TB + List foo; + @java.lang.SuppressWarnings("all") + public void setFoo(@TA final List foo) { + this.foo = foo; + } +} diff --git a/test/transform/resource/after-delombok/SetterTypeAnnosCopy.java b/test/transform/resource/after-delombok/SetterTypeAnnosCopy.java deleted file mode 100644 index b45c3234..00000000 --- a/test/transform/resource/after-delombok/SetterTypeAnnosCopy.java +++ /dev/null @@ -1,17 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class SetterTypeAnnos { - @TA - List<@TA String> foo; - - @java.lang.SuppressWarnings("all") - public void setFoo(@TA final List<@TA String> foo) { - this.foo = foo; - } -} diff --git a/test/transform/resource/after-delombok/SetterTypeAnnosNoCopy.java b/test/transform/resource/after-delombok/SetterTypeAnnosNoCopy.java deleted file mode 100644 index e773bd9c..00000000 --- a/test/transform/resource/after-delombok/SetterTypeAnnosNoCopy.java +++ /dev/null @@ -1,17 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class SetterTypeAnnos { - @TA - List<@TA String> foo; - - @java.lang.SuppressWarnings("all") - public void setFoo(final List<@TA String> foo) { - this.foo = foo; - } -} diff --git a/test/transform/resource/after-delombok/WitherTypeAnnos.java b/test/transform/resource/after-delombok/WitherTypeAnnos.java new file mode 100644 index 00000000..b57438af --- /dev/null +++ b/test/transform/resource/after-delombok/WitherTypeAnnos.java @@ -0,0 +1,21 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TA { +} +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TB { +} +class WitherTypeAnnos { + @TA + @TB + final List foo; + WitherTypeAnnos(@TA @TB List foo) { + this.foo = foo; + } + @java.lang.SuppressWarnings("all") + public WitherTypeAnnos withFoo(@TA final List foo) { + return this.foo == foo ? this : new WitherTypeAnnos(foo); + } +} diff --git a/test/transform/resource/after-delombok/WitherTypeAnnosCopy.java b/test/transform/resource/after-delombok/WitherTypeAnnosCopy.java deleted file mode 100644 index 8cbb7e5d..00000000 --- a/test/transform/resource/after-delombok/WitherTypeAnnosCopy.java +++ /dev/null @@ -1,21 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class WitherTypeAnnos { - @TA - final List<@TA String> foo; - - WitherTypeAnnos(@TA List<@TA String> foo) { - this.foo = foo; - } - - @java.lang.SuppressWarnings("all") - public WitherTypeAnnos withFoo(@TA final List<@TA String> foo) { - return this.foo == foo ? this : new WitherTypeAnnos(foo); - } -} diff --git a/test/transform/resource/after-delombok/WitherTypeAnnosNoCopy.java b/test/transform/resource/after-delombok/WitherTypeAnnosNoCopy.java deleted file mode 100644 index 18c25e04..00000000 --- a/test/transform/resource/after-delombok/WitherTypeAnnosNoCopy.java +++ /dev/null @@ -1,21 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class WitherTypeAnnos { - @TA - final List<@TA String> foo; - - WitherTypeAnnos(@TA List<@TA String> foo) { - this.foo = foo; - } - - @java.lang.SuppressWarnings("all") - public WitherTypeAnnos withFoo(final List<@TA String> foo) { - return this.foo == foo ? this : new WitherTypeAnnos(foo); - } -} diff --git a/test/transform/resource/after-ecj/BuilderTypeAnnos.java b/test/transform/resource/after-ecj/BuilderTypeAnnos.java new file mode 100644 index 00000000..1c310f38 --- /dev/null +++ b/test/transform/resource/after-ecj/BuilderTypeAnnos.java @@ -0,0 +1,33 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) @interface TA { +} +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) @interface TB { +} +@lombok.Builder class BuilderTypeAnnos { + public static @java.lang.SuppressWarnings("all") class BuilderTypeAnnosBuilder { + private @java.lang.SuppressWarnings("all") List foo; + @java.lang.SuppressWarnings("all") BuilderTypeAnnosBuilder() { + super(); + } + public @java.lang.SuppressWarnings("all") BuilderTypeAnnosBuilder foo(final @TA List foo) { + this.foo = foo; + return this; + } + public @java.lang.SuppressWarnings("all") BuilderTypeAnnos build() { + return new BuilderTypeAnnos(foo); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (("BuilderTypeAnnos.BuilderTypeAnnosBuilder(foo=" + this.foo) + ")"); + } + } + private @TA @TB List foo; + @java.lang.SuppressWarnings("all") BuilderTypeAnnos(final @TA List foo) { + super(); + this.foo = foo; + } + public static @java.lang.SuppressWarnings("all") BuilderTypeAnnosBuilder builder() { + return new BuilderTypeAnnosBuilder(); + } +} diff --git a/test/transform/resource/after-ecj/BuilderTypeAnnosCopy.java b/test/transform/resource/after-ecj/BuilderTypeAnnosCopy.java deleted file mode 100644 index 8dfc8164..00000000 --- a/test/transform/resource/after-ecj/BuilderTypeAnnosCopy.java +++ /dev/null @@ -1,31 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { -} -@lombok.Builder class BuilderTypeAnnos { - public static @java.lang.SuppressWarnings("all") class BuilderTypeAnnosBuilder { - private @java.lang.SuppressWarnings("all") List foo; - @java.lang.SuppressWarnings("all") BuilderTypeAnnosBuilder() { - super(); - } - public @java.lang.SuppressWarnings("all") BuilderTypeAnnosBuilder foo(final @TA List foo) { - this.foo = foo; - return this; - } - public @java.lang.SuppressWarnings("all") BuilderTypeAnnos build() { - return new BuilderTypeAnnos(foo); - } - public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { - return (("BuilderTypeAnnos.BuilderTypeAnnosBuilder(foo=" + this.foo) + ")"); - } - } - private @TA List<@TA String> foo; - @java.lang.SuppressWarnings("all") BuilderTypeAnnos(final @TA List foo) { - super(); - this.foo = foo; - } - public static @java.lang.SuppressWarnings("all") BuilderTypeAnnosBuilder builder() { - return new BuilderTypeAnnosBuilder(); - } -} diff --git a/test/transform/resource/after-ecj/BuilderTypeAnnosNoCopy.java b/test/transform/resource/after-ecj/BuilderTypeAnnosNoCopy.java deleted file mode 100644 index a2dfcc2f..00000000 --- a/test/transform/resource/after-ecj/BuilderTypeAnnosNoCopy.java +++ /dev/null @@ -1,31 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { -} -@lombok.Builder class BuilderTypeAnnos { - public static @java.lang.SuppressWarnings("all") class BuilderTypeAnnosBuilder { - private @java.lang.SuppressWarnings("all") List foo; - @java.lang.SuppressWarnings("all") BuilderTypeAnnosBuilder() { - super(); - } - public @java.lang.SuppressWarnings("all") BuilderTypeAnnosBuilder foo(final List foo) { - this.foo = foo; - return this; - } - public @java.lang.SuppressWarnings("all") BuilderTypeAnnos build() { - return new BuilderTypeAnnos(foo); - } - public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { - return (("BuilderTypeAnnos.BuilderTypeAnnosBuilder(foo=" + this.foo) + ")"); - } - } - private @TA List<@TA String> foo; - @java.lang.SuppressWarnings("all") BuilderTypeAnnos(final List foo) { - super(); - this.foo = foo; - } - public static @java.lang.SuppressWarnings("all") BuilderTypeAnnosBuilder builder() { - return new BuilderTypeAnnosBuilder(); - } -} diff --git a/test/transform/resource/after-ecj/ConstructorsTypeAnnos.java b/test/transform/resource/after-ecj/ConstructorsTypeAnnos.java new file mode 100644 index 00000000..3491239f --- /dev/null +++ b/test/transform/resource/after-ecj/ConstructorsTypeAnnos.java @@ -0,0 +1,14 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) @interface TA { +} +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) @interface TB { +} +@lombok.AllArgsConstructor class ConstructorsTypeAnnos { + @TA @TB List foo; + public @java.lang.SuppressWarnings("all") ConstructorsTypeAnnos(final @TA List foo) { + super(); + this.foo = foo; + } +} diff --git a/test/transform/resource/after-ecj/ConstructorsTypeAnnosCopy.java b/test/transform/resource/after-ecj/ConstructorsTypeAnnosCopy.java deleted file mode 100644 index ad372fc9..00000000 --- a/test/transform/resource/after-ecj/ConstructorsTypeAnnosCopy.java +++ /dev/null @@ -1,12 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { -} -@lombok.AllArgsConstructor class ConstructorsTypeAnnos { - @TA List<@TA String> foo; - public @java.lang.SuppressWarnings("all") ConstructorsTypeAnnos(final @TA List foo) { - super(); - this.foo = foo; - } -} diff --git a/test/transform/resource/after-ecj/ConstructorsTypeAnnosNoCopy.java b/test/transform/resource/after-ecj/ConstructorsTypeAnnosNoCopy.java deleted file mode 100644 index ce4b1b3b..00000000 --- a/test/transform/resource/after-ecj/ConstructorsTypeAnnosNoCopy.java +++ /dev/null @@ -1,12 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { -} -@lombok.AllArgsConstructor class ConstructorsTypeAnnos { - @TA List<@TA String> foo; - public @java.lang.SuppressWarnings("all") ConstructorsTypeAnnos(final List foo) { - super(); - this.foo = foo; - } -} diff --git a/test/transform/resource/after-ecj/GetterTypeAnnos.java b/test/transform/resource/after-ecj/GetterTypeAnnos.java new file mode 100644 index 00000000..9ffc7f1c --- /dev/null +++ b/test/transform/resource/after-ecj/GetterTypeAnnos.java @@ -0,0 +1,17 @@ +import lombok.Getter; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) @interface TA { +} +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) @interface TB { +} +class GetterTypeAnnos { + @Getter @TA @TB List foo; + GetterTypeAnnos() { + super(); + } + public @TA @java.lang.SuppressWarnings("all") List getFoo() { + return this.foo; + } +} diff --git a/test/transform/resource/after-ecj/GetterTypeAnnosCopy.java b/test/transform/resource/after-ecj/GetterTypeAnnosCopy.java deleted file mode 100644 index 1b4f03c5..00000000 --- a/test/transform/resource/after-ecj/GetterTypeAnnosCopy.java +++ /dev/null @@ -1,15 +0,0 @@ -import lombok.Getter; -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { -} -class GetterTypeAnnos { - @Getter @TA List<@TA String> foo; - GetterTypeAnnos() { - super(); - } - public @TA @java.lang.SuppressWarnings("all") List getFoo() { - return this.foo; - } -} diff --git a/test/transform/resource/after-ecj/GetterTypeAnnosNoCopy.java b/test/transform/resource/after-ecj/GetterTypeAnnosNoCopy.java deleted file mode 100644 index a43d3215..00000000 --- a/test/transform/resource/after-ecj/GetterTypeAnnosNoCopy.java +++ /dev/null @@ -1,15 +0,0 @@ -import lombok.Getter; -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { -} -class GetterTypeAnnos { - @Getter @TA List<@TA String> foo; - GetterTypeAnnos() { - super(); - } - public @java.lang.SuppressWarnings("all") List getFoo() { - return this.foo; - } -} diff --git a/test/transform/resource/after-ecj/SetterTypeAnnos.java b/test/transform/resource/after-ecj/SetterTypeAnnos.java new file mode 100644 index 00000000..860694ea --- /dev/null +++ b/test/transform/resource/after-ecj/SetterTypeAnnos.java @@ -0,0 +1,17 @@ +import lombok.Setter; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) @interface TA { +} +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) @interface TB { +} +class SetterTypeAnnos { + @Setter @TA @TB List foo; + SetterTypeAnnos() { + super(); + } + public @java.lang.SuppressWarnings("all") void setFoo(final @TA List foo) { + this.foo = foo; + } +} diff --git a/test/transform/resource/after-ecj/SetterTypeAnnosCopy.java b/test/transform/resource/after-ecj/SetterTypeAnnosCopy.java deleted file mode 100644 index ef290cbf..00000000 --- a/test/transform/resource/after-ecj/SetterTypeAnnosCopy.java +++ /dev/null @@ -1,15 +0,0 @@ -import lombok.Setter; -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { -} -class SetterTypeAnnos { - @Setter @TA List<@TA String> foo; - SetterTypeAnnos() { - super(); - } - public @java.lang.SuppressWarnings("all") void setFoo(final @TA List foo) { - this.foo = foo; - } -} diff --git a/test/transform/resource/after-ecj/SetterTypeAnnosNoCopy.java b/test/transform/resource/after-ecj/SetterTypeAnnosNoCopy.java deleted file mode 100644 index 17e27782..00000000 --- a/test/transform/resource/after-ecj/SetterTypeAnnosNoCopy.java +++ /dev/null @@ -1,15 +0,0 @@ -import lombok.Setter; -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { -} -class SetterTypeAnnos { - @Setter @TA List<@TA String> foo; - SetterTypeAnnos() { - super(); - } - public @java.lang.SuppressWarnings("all") void setFoo(final List foo) { - this.foo = foo; - } -} diff --git a/test/transform/resource/after-ecj/WitherTypeAnnos.java b/test/transform/resource/after-ecj/WitherTypeAnnos.java new file mode 100644 index 00000000..e41d9e13 --- /dev/null +++ b/test/transform/resource/after-ecj/WitherTypeAnnos.java @@ -0,0 +1,18 @@ +import lombok.experimental.Wither; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) @interface TA { +} +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) @interface TB { +} +class WitherTypeAnnos { + final @Wither @TA @TB List foo; + WitherTypeAnnos(@TA @TB List foo) { + super(); + this.foo = foo; + } + public @java.lang.SuppressWarnings("all") WitherTypeAnnos withFoo(final @TA List foo) { + return ((this.foo == foo) ? this : new WitherTypeAnnos(foo)); + } +} diff --git a/test/transform/resource/after-ecj/WitherTypeAnnosCopy.java b/test/transform/resource/after-ecj/WitherTypeAnnosCopy.java deleted file mode 100644 index b4f3c687..00000000 --- a/test/transform/resource/after-ecj/WitherTypeAnnosCopy.java +++ /dev/null @@ -1,16 +0,0 @@ -import lombok.experimental.Wither; -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { -} -class WitherTypeAnnos { - final @Wither @TA List<@TA String> foo; - WitherTypeAnnos(@TA List<@TA String> foo) { - super(); - this.foo = foo; - } - public @java.lang.SuppressWarnings("all") WitherTypeAnnos withFoo(final @TA List foo) { - return ((this.foo == foo) ? this : new WitherTypeAnnos(foo)); - } -} diff --git a/test/transform/resource/after-ecj/WitherTypeAnnosNoCopy.java b/test/transform/resource/after-ecj/WitherTypeAnnosNoCopy.java deleted file mode 100644 index 4f0b0710..00000000 --- a/test/transform/resource/after-ecj/WitherTypeAnnosNoCopy.java +++ /dev/null @@ -1,16 +0,0 @@ -import lombok.experimental.Wither; -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA { -} -class WitherTypeAnnos { - final @Wither @TA List<@TA String> foo; - WitherTypeAnnos(@TA List<@TA String> foo) { - super(); - this.foo = foo; - } - public @java.lang.SuppressWarnings("all") WitherTypeAnnos withFoo(final List foo) { - return ((this.foo == foo) ? this : new WitherTypeAnnos(foo)); - } -} diff --git a/test/transform/resource/before/BuilderTypeAnnos.java b/test/transform/resource/before/BuilderTypeAnnos.java new file mode 100644 index 00000000..6b7bc1d8 --- /dev/null +++ b/test/transform/resource/before/BuilderTypeAnnos.java @@ -0,0 +1,14 @@ +//CONF: lombok.copyableAnnotations += TA +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TA { +} +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TB { +} +@lombok.Builder +class BuilderTypeAnnos { + private @TA @TB List foo; +} diff --git a/test/transform/resource/before/BuilderTypeAnnosCopy.java b/test/transform/resource/before/BuilderTypeAnnosCopy.java deleted file mode 100644 index e5ea9e41..00000000 --- a/test/transform/resource/before/BuilderTypeAnnosCopy.java +++ /dev/null @@ -1,14 +0,0 @@ -//CONF: lombok.copyAnnotations += TA - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -@lombok.Builder -class BuilderTypeAnnos { - private @TA List<@TA String> foo; -} diff --git a/test/transform/resource/before/BuilderTypeAnnosNoCopy.java b/test/transform/resource/before/BuilderTypeAnnosNoCopy.java deleted file mode 100644 index 2defba7b..00000000 --- a/test/transform/resource/before/BuilderTypeAnnosNoCopy.java +++ /dev/null @@ -1,12 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -@lombok.Builder -class BuilderTypeAnnos { - private @TA List<@TA String> foo; -} diff --git a/test/transform/resource/before/ConstructorsTypeAnnos.java b/test/transform/resource/before/ConstructorsTypeAnnos.java new file mode 100644 index 00000000..d767f321 --- /dev/null +++ b/test/transform/resource/before/ConstructorsTypeAnnos.java @@ -0,0 +1,14 @@ +//CONF: lombok.copyableAnnotations += TA +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TA { +} +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TB { +} +@lombok.AllArgsConstructor +class ConstructorsTypeAnnos { + @TA @TB List foo; +} diff --git a/test/transform/resource/before/ConstructorsTypeAnnosCopy.java b/test/transform/resource/before/ConstructorsTypeAnnosCopy.java deleted file mode 100644 index 229927c3..00000000 --- a/test/transform/resource/before/ConstructorsTypeAnnosCopy.java +++ /dev/null @@ -1,14 +0,0 @@ -//CONF: lombok.copyAnnotations += TA - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -@lombok.AllArgsConstructor -class ConstructorsTypeAnnos { - @TA List<@TA String> foo; -} diff --git a/test/transform/resource/before/ConstructorsTypeAnnosNoCopy.java b/test/transform/resource/before/ConstructorsTypeAnnosNoCopy.java deleted file mode 100644 index 7bc27008..00000000 --- a/test/transform/resource/before/ConstructorsTypeAnnosNoCopy.java +++ /dev/null @@ -1,12 +0,0 @@ -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -@lombok.AllArgsConstructor -class ConstructorsTypeAnnos { - @TA List<@TA String> foo; -} diff --git a/test/transform/resource/before/GetterTypeAnnos.java b/test/transform/resource/before/GetterTypeAnnos.java new file mode 100644 index 00000000..34177503 --- /dev/null +++ b/test/transform/resource/before/GetterTypeAnnos.java @@ -0,0 +1,15 @@ +//CONF: lombok.copyableAnnotations += TA +import lombok.Getter; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TA { +} +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TB { +} +class GetterTypeAnnos { + @Getter + @TA @TB List foo; +} diff --git a/test/transform/resource/before/GetterTypeAnnosCopy.java b/test/transform/resource/before/GetterTypeAnnosCopy.java deleted file mode 100644 index b48b8337..00000000 --- a/test/transform/resource/before/GetterTypeAnnosCopy.java +++ /dev/null @@ -1,16 +0,0 @@ -//CONF: lombok.copyAnnotations += TA - -import lombok.Getter; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class GetterTypeAnnos { - @Getter - @TA List<@TA String> foo; -} diff --git a/test/transform/resource/before/GetterTypeAnnosNoCopy.java b/test/transform/resource/before/GetterTypeAnnosNoCopy.java deleted file mode 100644 index bf4d9486..00000000 --- a/test/transform/resource/before/GetterTypeAnnosNoCopy.java +++ /dev/null @@ -1,14 +0,0 @@ -import lombok.Getter; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class GetterTypeAnnos { - @Getter - @TA List<@TA String> foo; -} diff --git a/test/transform/resource/before/SetterTypeAnnos.java b/test/transform/resource/before/SetterTypeAnnos.java new file mode 100644 index 00000000..8031136d --- /dev/null +++ b/test/transform/resource/before/SetterTypeAnnos.java @@ -0,0 +1,15 @@ +//CONF: lombok.copyableAnnotations += TA +import lombok.Setter; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TA { +} +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TB { +} +class SetterTypeAnnos { + @Setter + @TA @TB List foo; +} diff --git a/test/transform/resource/before/SetterTypeAnnosCopy.java b/test/transform/resource/before/SetterTypeAnnosCopy.java deleted file mode 100644 index d9d086f0..00000000 --- a/test/transform/resource/before/SetterTypeAnnosCopy.java +++ /dev/null @@ -1,16 +0,0 @@ -//CONF: lombok.copyAnnotations += TA - -import lombok.Setter; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class SetterTypeAnnos { - @Setter - @TA List<@TA String> foo; -} diff --git a/test/transform/resource/before/SetterTypeAnnosNoCopy.java b/test/transform/resource/before/SetterTypeAnnosNoCopy.java deleted file mode 100644 index e3666543..00000000 --- a/test/transform/resource/before/SetterTypeAnnosNoCopy.java +++ /dev/null @@ -1,14 +0,0 @@ -import lombok.Setter; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class SetterTypeAnnos { - @Setter - @TA List<@TA String> foo; -} diff --git a/test/transform/resource/before/WitherTypeAnnos.java b/test/transform/resource/before/WitherTypeAnnos.java new file mode 100644 index 00000000..97cd3d9f --- /dev/null +++ b/test/transform/resource/before/WitherTypeAnnos.java @@ -0,0 +1,18 @@ +//CONF: lombok.copyableAnnotations += TA +import lombok.experimental.Wither; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.List; +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TA { +} +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) +@interface TB { +} +class WitherTypeAnnos { + @Wither final @TA @TB List foo; + + WitherTypeAnnos(@TA @TB List foo) { + this.foo = foo; + } +} diff --git a/test/transform/resource/before/WitherTypeAnnosCopy.java b/test/transform/resource/before/WitherTypeAnnosCopy.java deleted file mode 100644 index 645682f5..00000000 --- a/test/transform/resource/before/WitherTypeAnnosCopy.java +++ /dev/null @@ -1,19 +0,0 @@ -//CONF: lombok.copyAnnotations += TA - -import lombok.experimental.Wither; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class WitherTypeAnnos { - @Wither final @TA List<@TA String> foo; - - WitherTypeAnnos(@TA List<@TA String> foo) { - this.foo = foo; - } -} diff --git a/test/transform/resource/before/WitherTypeAnnosNoCopy.java b/test/transform/resource/before/WitherTypeAnnosNoCopy.java deleted file mode 100644 index d278af55..00000000 --- a/test/transform/resource/before/WitherTypeAnnosNoCopy.java +++ /dev/null @@ -1,17 +0,0 @@ -import lombok.experimental.Wither; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Target; -import java.util.List; - -@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) -@interface TA { -} - -class WitherTypeAnnos { - @Wither final @TA List<@TA String> foo; - - WitherTypeAnnos(@TA List<@TA String> foo) { - this.foo = foo; - } -} -- cgit From d7873f2d21564e8e7f22409fe03681d7dd4c8c1e Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Tue, 11 Sep 2018 01:41:22 +0200 Subject: Replaced the notion of ‘nullable’ and ‘nonnull’ get copied to ‘any ‘copyable’ annotations get copied’, with ‘copyable’ defined as a specific FQN-style list of well-known nullity-indicating annotations, plus whatever you configured in lombok.config. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also some work on the notion of TYPE_USE annotations. --- src/core/lombok/ConfigurationKeys.java | 5 +- src/core/lombok/NonNull.java | 2 +- src/core/lombok/core/TypeLibrary.java | 6 ++ src/core/lombok/core/handlers/HandlerUtil.java | 39 +++++--- .../eclipse/handlers/EclipseHandlerUtil.java | 36 +++++-- .../lombok/eclipse/handlers/HandleBuilder.java | 12 +-- .../lombok/eclipse/handlers/HandleConstructor.java | 12 +-- src/core/lombok/eclipse/handlers/HandleGetter.java | 12 +-- src/core/lombok/eclipse/handlers/HandleSetter.java | 8 +- .../eclipse/handlers/HandleSuperBuilder.java | 9 +- src/core/lombok/eclipse/handlers/HandleWither.java | 8 +- src/core/lombok/javac/handlers/HandleBuilder.java | 12 +-- .../lombok/javac/handlers/HandleConstructor.java | 15 ++- src/core/lombok/javac/handlers/HandleGetter.java | 8 +- src/core/lombok/javac/handlers/HandleSetter.java | 8 +- .../lombok/javac/handlers/HandleSuperBuilder.java | 3 +- src/core/lombok/javac/handlers/HandleWither.java | 8 +- .../lombok/javac/handlers/JavacHandlerUtil.java | 53 +++++++++- .../BuilderSingularAnnotatedTypes.java | 110 +++++++++++++++++++++ .../after-ecj/BuilderSingularAnnotatedTypes.java | 105 ++++++++++++++++++++ .../before/BuilderSingularAnnotatedTypes.java | 12 +++ 21 files changed, 381 insertions(+), 102 deletions(-) create mode 100644 test/transform/resource/after-delombok/BuilderSingularAnnotatedTypes.java create mode 100644 test/transform/resource/after-ecj/BuilderSingularAnnotatedTypes.java create mode 100644 test/transform/resource/before/BuilderSingularAnnotatedTypes.java diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java index 89748f60..2cca27fa 100644 --- a/src/core/lombok/ConfigurationKeys.java +++ b/src/core/lombok/ConfigurationKeys.java @@ -27,6 +27,7 @@ import lombok.core.configuration.CallSuperType; import lombok.core.configuration.ConfigurationKey; import lombok.core.configuration.FlagUsageType; import lombok.core.configuration.NullCheckExceptionType; +import lombok.core.configuration.TypeName; /** * A container class containing all lombok configuration keys that do not belong to a specific annotation. @@ -565,10 +566,10 @@ public class ConfigurationKeys { public static final ConfigurationKey STOP_BUBBLING = new ConfigurationKey("config.stopBubbling", "Tell the configuration system it should stop looking for other configuration files (default: false).") {}; /** - * lombok configuration: {@code lombok.copyableAnnotations} += <String: fully-qualified annotation class name>. + * lombok configuration: {@code lombok.copyableAnnotations} += <TypeName: fully-qualified annotation class name>. * * Copy these annotations to getters, setters, withers, builder-setters, etc. */ - public static final ConfigurationKey> COPYABLE_ANNOTATIONS = new ConfigurationKey>("lombok.copyableAnnotations", "Copy these annotations to getters, setters, withers, builder-setters, etc.") {}; + public static final ConfigurationKey> COPYABLE_ANNOTATIONS = new ConfigurationKey>("lombok.copyableAnnotations", "Copy these annotations to getters, setters, withers, builder-setters, etc.") {}; } diff --git a/src/core/lombok/NonNull.java b/src/core/lombok/NonNull.java index 58538583..caf6ed05 100644 --- a/src/core/lombok/NonNull.java +++ b/src/core/lombok/NonNull.java @@ -41,7 +41,7 @@ import java.lang.annotation.Target; * this annotation will be deleted from the lombok package. If the need to update an import statement scares * you, you should use your own annotation named {@code @NonNull} instead of this one. */ -@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE}) +@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE}) @Retention(RetentionPolicy.CLASS) @Documented public @interface NonNull { diff --git a/src/core/lombok/core/TypeLibrary.java b/src/core/lombok/core/TypeLibrary.java index cdaf7a70..ceaf5f90 100644 --- a/src/core/lombok/core/TypeLibrary.java +++ b/src/core/lombok/core/TypeLibrary.java @@ -45,6 +45,12 @@ public class TypeLibrary { qualified = null; } + public TypeLibrary(TypeLibrary parent) { + unqualifiedToQualifiedMap = new HashMap(); + unqualified = null; + qualified = null; + } + public void lock() { this.locked = true; } diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java index 1694e305..296b70b4 100644 --- a/src/core/lombok/core/handlers/HandlerUtil.java +++ b/src/core/lombok/core/handlers/HandlerUtil.java @@ -27,7 +27,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.regex.Pattern; import lombok.AllArgsConstructor; import lombok.ConfigurationKeys; @@ -77,6 +76,33 @@ public class HandlerUtil { return 43; } + public static final List NONNULL_ANNOTATIONS, BASE_COPYABLE_ANNOTATIONS; + static { + NONNULL_ANNOTATIONS = Collections.unmodifiableList(Arrays.asList(new String[] { + "lombok.NonNull", + "javax.annotation.Nonnull", + "edu.umd.cs.findbugs.annotations.NonNull", + "org.jetbrains.annotations.NotNull", + "android.support.annotation.NonNull", + "org.eclipse.jdt.annotation.NonNull", + })); + BASE_COPYABLE_ANNOTATIONS = Collections.unmodifiableList(Arrays.asList(new String[] { + "lombok.NonNull", + "javax.annotation.Nonnull", + "edu.umd.cs.findbugs.annotations.NonNull", + "org.jetbrains.annotations.NotNull", + "android.support.annotation.NonNull", + "org.eclipse.jdt.annotation.NonNull", + "javax.annotation.Nullable", + "javax.annotation.CheckForNull", + "edu.umd.cs.findbugs.annotations.UnknownNullness", + "edu.umd.cs.findbugs.annotations.Nullable", + "org.jetbrains.annotations.Nullable", + "android.support.annotation.Nullable", + "org.eclipse.jdt.annotation.Nullable", + })); + } + /** Checks if the given name is a valid identifier. * * If it is, this returns {@code true} and does nothing else. @@ -222,19 +248,8 @@ public class HandlerUtil { constructor and the implied starts-out-as-null state that goes with it is in fact mandatory' which happens with javax.validation.constraints.NotNull. Various problems with spring have also been reported. See issue #287, issue #271, and issue #43. */ - /** Matches the simple part of any annotation that lombok considers as indicative of NonNull status. */ - public static final Pattern NON_NULL_PATTERN = Pattern.compile("^(?:nonnull)$", Pattern.CASE_INSENSITIVE); - - /** Matches the simple part of any annotation that lombok considers as indicative of Nullable status. */ - public static final Pattern NULLABLE_PATTERN = Pattern.compile("^(?:nullable|checkfornull)$", Pattern.CASE_INSENSITIVE); - public static final String DEFAULT_EXCEPTION_FOR_NON_NULL = "java.lang.NullPointerException"; - /** Returns the configuration value for ConfigurationKeys.COPYABLE_ANNOTATIONS. */ - public static List getCopyableAnnotationNames(AST ast) { - return ast.readConfiguration(ConfigurationKeys.COPYABLE_ANNOTATIONS); - } - /** * Generates a getter name from a given field name. * diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index e7a58de3..a972c1fe 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -48,6 +48,7 @@ import lombok.core.AnnotationValues; import lombok.core.AnnotationValues.AnnotationValue; import lombok.core.TypeResolver; import lombok.core.configuration.NullCheckExceptionType; +import lombok.core.configuration.TypeName; import lombok.core.debug.ProblemReporter; import lombok.core.handlers.HandlerUtil; import lombok.eclipse.Eclipse; @@ -672,19 +673,42 @@ public class EclipseHandlerUtil { } } + public static boolean hasNonNullAnnotations(EclipseNode node) { + AbstractVariableDeclaration avd = (AbstractVariableDeclaration) node.get(); + if (avd.annotations == null) return false; + for (Annotation annotation : avd.annotations) { + TypeReference typeRef = annotation.type; + if (typeRef != null && typeRef.getTypeName() != null) { + for (String bn : NONNULL_ANNOTATIONS) if (typeMatches(bn, node, typeRef)) return true; + } + } + return false; + } + private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY = new Annotation[0]; /** - * Searches the given field node for annotations and returns each one that matches the provided list of names. + * 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[] findExactAnnotations(AbstractVariableDeclaration field, List names) { + public static Annotation[] findCopyableAnnotations(EclipseNode node) { + AbstractVariableDeclaration avd = (AbstractVariableDeclaration) node.get(); + if (avd.annotations == null) return EMPTY_ANNOTATIONS_ARRAY; List result = new ArrayList(); - if (field.annotations == null) return EMPTY_ANNOTATIONS_ARRAY; - for (Annotation annotation : field.annotations) { + List configuredCopyable = node.getAst().readConfiguration(ConfigurationKeys.COPYABLE_ANNOTATIONS); + + for (Annotation annotation : avd.annotations) { TypeReference typeRef = annotation.type; + boolean match = false; if (typeRef != null && typeRef.getTypeName() != null) { - String annoName = toQualifiedName(typeRef.getTypeName()); - if (names.contains(annoName)) result.add(annotation); + for (TypeName cn : configuredCopyable) if (typeMatches(cn.toString(), node, typeRef)) { + result.add(annotation); + match = true; + break; + } + if (!match) for (String bn : BASE_COPYABLE_ANNOTATIONS) if (typeMatches(bn, node, typeRef)) { + result.add(annotation); + break; + } } } return result.toArray(EMPTY_ANNOTATIONS_ARRAY); diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java index f05896ab..280afc26 100644 --- a/src/core/lombok/eclipse/handlers/HandleBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java @@ -200,14 +200,12 @@ public class HandleBuilder extends EclipseAnnotationHandler { EclipseNode isDefault = findAnnotation(Builder.Default.class, fieldNode); boolean isFinal = ((fd.modifiers & ClassFileConstants.AccFinal) != 0) || (valuePresent && !hasAnnotation(NonFinal.class, fieldNode)); - Annotation[] nonNulls = findAnnotations(fd, NON_NULL_PATTERN); - Annotation[] nullables = findAnnotations(fd, NULLABLE_PATTERN); - Annotation[] copyAnnotations = findExactAnnotations(fd, getCopyableAnnotationNames(fieldNode.getAst())); + Annotation[] copyableAnnotations = findCopyableAnnotations(fieldNode); BuilderFieldData bfd = new BuilderFieldData(); bfd.rawName = fieldNode.getName().toCharArray(); bfd.name = removePrefixFromField(fieldNode); - bfd.annotations = copyAnnotations(fd, nonNulls, nullables, copyAnnotations); + bfd.annotations = copyAnnotations(fd, copyableAnnotations); bfd.type = fd.type; bfd.singularData = getSingularData(fieldNode, ast); bfd.originalFieldNode = fieldNode; @@ -381,13 +379,11 @@ public class HandleBuilder extends EclipseAnnotationHandler { BuilderFieldData bfd = new BuilderFieldData(); Argument arg = (Argument) param.get(); - Annotation[] nonNulls = findAnnotations(arg, NON_NULL_PATTERN); - Annotation[] nullables = findAnnotations(arg, NULLABLE_PATTERN); - Annotation[] copyAnnotations = findExactAnnotations(arg, getCopyableAnnotationNames(param.getAst())); + Annotation[] copyableAnnotations = findCopyableAnnotations(param); bfd.rawName = arg.name; bfd.name = arg.name; - bfd.annotations = copyAnnotations(arg, nonNulls, nullables, copyAnnotations); + bfd.annotations = copyAnnotations(arg, copyableAnnotations); bfd.type = arg.type; bfd.singularData = getSingularData(param, ast); bfd.originalFieldNode = param; diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java index 3d947a73..cb07115a 100644 --- a/src/core/lombok/eclipse/handlers/HandleConstructor.java +++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java @@ -139,7 +139,7 @@ public class HandleConstructor { FieldDeclaration fieldDecl = (FieldDeclaration) child.get(); if (!filterField(fieldDecl)) continue; boolean isFinal = (fieldDecl.modifiers & ClassFileConstants.AccFinal) != 0; - boolean isNonNull = nullMarked && findAnnotations(fieldDecl, NON_NULL_PATTERN).length != 0; + boolean isNonNull = nullMarked && hasNonNullAnnotations(child); if ((isFinal || isNonNull) && fieldDecl.initialization == null) fields.add(child); } return fields; @@ -403,14 +403,12 @@ public class HandleConstructor { assigns.add(assignment); long fieldPos = (((long) field.sourceStart) << 32) | field.sourceEnd; Argument parameter = new Argument(fieldName, fieldPos, copyType(field.type, source), Modifier.FINAL); - Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN); - Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN); - Annotation[] copyAnnotations = findExactAnnotations(field, getCopyableAnnotationNames(fieldNode.getAst())); - if (nonNulls.length != 0) { + Annotation[] copyableAnnotations = findCopyableAnnotations(fieldNode); + if (hasNonNullAnnotations(fieldNode)) { Statement nullCheck = generateNullCheck(parameter, sourceNode); if (nullCheck != null) nullChecks.add(nullCheck); } - parameter.annotations = copyAnnotations(source, nonNulls, nullables, copyAnnotations); + parameter.annotations = copyAnnotations(source, copyableAnnotations); params.add(parameter); } @@ -547,7 +545,7 @@ public class HandleConstructor { assigns.add(nameRef); Argument parameter = new Argument(field.name, fieldPos, copyType(field.type, source), Modifier.FINAL); - parameter.annotations = copyAnnotations(source, findAnnotations(field, NON_NULL_PATTERN), findAnnotations(field, NULLABLE_PATTERN)); + parameter.annotations = copyAnnotations(source, findCopyableAnnotations(fieldNode)); params.add(parameter); } diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java index 58af8c1e..7d3fe62f 100644 --- a/src/core/lombok/eclipse/handlers/HandleGetter.java +++ b/src/core/lombok/eclipse/handlers/HandleGetter.java @@ -236,8 +236,6 @@ public class HandleGetter extends EclipseAnnotationHandler { } public MethodDeclaration createGetter(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, ASTNode source, boolean lazy, List onMethod) { - FieldDeclaration field = (FieldDeclaration) fieldNode.get(); - // Remember the type; lazy will change it; TypeReference returnType = copyType(((FieldDeclaration) fieldNode.get()).type, source); @@ -271,12 +269,10 @@ public class HandleGetter extends EclipseAnnotationHandler { } method.annotations = copyAnnotations(source, - onMethod.toArray(new Annotation[0]), - findAnnotations(field, NON_NULL_PATTERN), - findAnnotations(field, NULLABLE_PATTERN), - findExactAnnotations(field, getCopyableAnnotationNames(fieldNode.getAst())), - findDelegatesAndMarkAsHandled(fieldNode), - deprecated); + onMethod.toArray(new Annotation[0]), + findCopyableAnnotations(fieldNode), + findDelegatesAndMarkAsHandled(fieldNode), + deprecated); } method.traverse(new SetGeneratedByVisitor(source), parent.scope); diff --git a/src/core/lombok/eclipse/handlers/HandleSetter.java b/src/core/lombok/eclipse/handlers/HandleSetter.java index ca81fef7..529a7d19 100644 --- a/src/core/lombok/eclipse/handlers/HandleSetter.java +++ b/src/core/lombok/eclipse/handlers/HandleSetter.java @@ -236,11 +236,9 @@ public class HandleSetter extends EclipseAnnotationHandler { method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart; method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd; - Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN); - Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN); - Annotation[] copyableAnnotations = findExactAnnotations(field, getCopyableAnnotationNames(fieldNode.getAst())); + Annotation[] copyableAnnotations = findCopyableAnnotations(fieldNode); List statements = new ArrayList(5); - if (nonNulls.length == 0) { + if (!hasNonNullAnnotations(fieldNode)) { statements.add(assignment); } else { Statement nullCheck = generateNullCheck(field, sourceNode); @@ -256,7 +254,7 @@ public class HandleSetter extends EclipseAnnotationHandler { statements.add(returnStatement); } method.statements = statements.toArray(new Statement[0]); - param.annotations = copyAnnotations(source, nonNulls, nullables, copyableAnnotations, onParam.toArray(new Annotation[0])); + param.annotations = copyAnnotations(source, copyableAnnotations, onParam.toArray(new Annotation[0])); method.traverse(new SetGeneratedByVisitor(source), parent.scope); return method; diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java index 3c07ac55..559cca20 100644 --- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java @@ -493,12 +493,9 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { statements.add(assignment); } - Annotation[] nonNulls = findAnnotations((FieldDeclaration)fieldNode.originalFieldNode.get(), NON_NULL_PATTERN); - if (nonNulls.length != 0) { - Statement nullCheck = generateNullCheck((FieldDeclaration)fieldNode.originalFieldNode.get(), sourceNode); - if (nullCheck != null) { - statements.add(nullCheck); - } + if (hasNonNullAnnotations(fieldNode.originalFieldNode)) { + Statement nullCheck = generateNullCheck((FieldDeclaration) fieldNode.originalFieldNode.get(), sourceNode); + if (nullCheck != null) statements.add(nullCheck); } } diff --git a/src/core/lombok/eclipse/handlers/HandleWither.java b/src/core/lombok/eclipse/handlers/HandleWither.java index 11032e9c..a99789a6 100644 --- a/src/core/lombok/eclipse/handlers/HandleWither.java +++ b/src/core/lombok/eclipse/handlers/HandleWither.java @@ -240,9 +240,7 @@ public class HandleWither extends EclipseAnnotationHandler { method.typeParameters = null; method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; - Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN); - Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN); - Annotation[] copyableAnnotations = findExactAnnotations(field, getCopyableAnnotationNames(fieldNode.getAst())); + Annotation[] copyableAnnotations = findCopyableAnnotations(fieldNode); if (!makeAbstract) { List args = new ArrayList(); @@ -278,7 +276,7 @@ public class HandleWither extends EclipseAnnotationHandler { method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd; List statements = new ArrayList(5); - if (nonNulls.length > 0) { + if (hasNonNullAnnotations(fieldNode)) { Statement nullCheck = generateNullCheck(field, sourceNode); if (nullCheck != null) statements.add(nullCheck); } @@ -286,7 +284,7 @@ public class HandleWither extends EclipseAnnotationHandler { method.statements = statements.toArray(new Statement[0]); } - param.annotations = copyAnnotations(source, nonNulls, nullables, copyableAnnotations, onParam.toArray(new Annotation[0])); + param.annotations = copyAnnotations(source, copyableAnnotations, onParam.toArray(new Annotation[0])); method.traverse(new SetGeneratedByVisitor(source), parent.scope); return method; diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index 7577eeb2..8170898b 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -150,14 +150,10 @@ public class HandleBuilder extends JavacAnnotationHandler { JavacNode isDefault = findAnnotation(Builder.Default.class, fieldNode, false); boolean isFinal = (fd.mods.flags & Flags.FINAL) != 0 || (valuePresent && !hasAnnotation(NonFinal.class, fieldNode)); - List nonNulls = findAnnotations(fieldNode, NON_NULL_PATTERN); - List nullables = findAnnotations(fieldNode, NULLABLE_PATTERN); - List copyableAnnotations = findExactAnnotations(fieldNode, getCopyableAnnotationNames(fieldNode.getAst())); - BuilderFieldData bfd = new BuilderFieldData(); bfd.rawName = fd.name; bfd.name = removePrefixFromField(fieldNode); - bfd.annotations = nonNulls.appendList(nullables).appendList(copyableAnnotations); + bfd.annotations = findCopyableAnnotations(fieldNode); bfd.type = fd.vartype; bfd.singularData = getSingularData(fieldNode); bfd.originalFieldNode = fieldNode; @@ -334,14 +330,10 @@ public class HandleBuilder extends JavacAnnotationHandler { if (param.getKind() != Kind.ARGUMENT) continue; BuilderFieldData bfd = new BuilderFieldData(); - List nonNulls = findAnnotations(param, NON_NULL_PATTERN); - List nullables = findAnnotations(param, NULLABLE_PATTERN); - List copyableAnnotations = findExactAnnotations(param, getCopyableAnnotationNames(param.getAst())); - JCVariableDecl raw = (JCVariableDecl) param.get(); bfd.name = raw.name; bfd.rawName = raw.name; - bfd.annotations = nonNulls.appendList(nullables).appendList(copyableAnnotations); + bfd.annotations = findCopyableAnnotations(param); bfd.type = raw.vartype; bfd.singularData = getSingularData(param); bfd.originalFieldNode = param; diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index 1e45d73f..3c434d40 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -127,7 +127,7 @@ public class HandleConstructor { //Skip static fields. if ((fieldFlags & Flags.STATIC) != 0) continue; boolean isFinal = (fieldFlags & Flags.FINAL) != 0; - boolean isNonNull = nullMarked && !findAnnotations(child, NON_NULL_PATTERN).isEmpty(); + boolean isNonNull = nullMarked && hasNonNullAnnotations(child); if ((isFinal || isNonNull) && fieldDecl.init == null) fields.append(child); } return fields.toList(); @@ -329,13 +329,11 @@ public class HandleConstructor { JCVariableDecl field = (JCVariableDecl) fieldNode.get(); Name fieldName = removePrefixFromField(fieldNode); Name rawName = field.name; - List nonNulls = findAnnotations(fieldNode, NON_NULL_PATTERN); - List nullables = findAnnotations(fieldNode, NULLABLE_PATTERN); - List copyableAnnotations = findExactAnnotations(fieldNode, getCopyableAnnotationNames(fieldNode.getAst())); + List copyableAnnotations = findCopyableAnnotations(fieldNode); long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, typeNode.getContext()); - JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, nonNulls.appendList(nullables).appendList(copyableAnnotations)), fieldName, field.vartype, null); + JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, copyableAnnotations), fieldName, field.vartype, null); params.append(param); - if (!nonNulls.isEmpty()) { + if (hasNonNullAnnotations(fieldNode)) { JCStatement nullCheck = generateNullCheck(maker, fieldNode, param, source); if (nullCheck != null) nullChecks.append(nullCheck); } @@ -472,10 +470,9 @@ public class HandleConstructor { JCVariableDecl field = (JCVariableDecl) fieldNode.get(); Name fieldName = removePrefixFromField(fieldNode); JCExpression pType = cloneType(maker, field.vartype, source, typeNode.getContext()); - List nonNulls = findAnnotations(fieldNode, NON_NULL_PATTERN); - List nullables = findAnnotations(fieldNode, NULLABLE_PATTERN); + List copyableAnnotations = findCopyableAnnotations(fieldNode); long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, typeNode.getContext()); - JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, nonNulls.appendList(nullables)), fieldName, pType, null); + JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, copyableAnnotations), fieldName, pType, null); params.append(param); args.append(maker.Ident(fieldName)); } diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index 04b300a8..7a178f66 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -243,13 +243,9 @@ public class HandleGetter extends JavacAnnotationHandler { List throwsClauses = List.nil(); JCExpression annotationMethodDefaultValue = null; - List nonNulls = findAnnotations(field, NON_NULL_PATTERN); - List nullables = findAnnotations(field, NULLABLE_PATTERN); - List copyableAnnotations = findExactAnnotations(field, getCopyableAnnotationNames(field.getAst())); - + List copyableAnnotations = findCopyableAnnotations(field); List delegates = findDelegatesAndRemoveFromField(field); - - List annsOnMethod = copyAnnotations(onMethod).appendList(nonNulls).appendList(nullables).appendList(copyableAnnotations); + List annsOnMethod = copyAnnotations(onMethod).appendList(copyableAnnotations); if (isFieldDeprecated(field)) { annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(genJavaLangTypeRef(field, "Deprecated"), List.nil())); } diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index e5e9481d..28f5318d 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -226,17 +226,15 @@ public class HandleSetter extends JavacAnnotationHandler { JCAssign assign = treeMaker.Assign(fieldRef, treeMaker.Ident(fieldDecl.name)); ListBuffer statements = new ListBuffer(); - List nonNulls = findAnnotations(field, NON_NULL_PATTERN); - List nullables = findAnnotations(field, NULLABLE_PATTERN); - List copyableAnnotations = findExactAnnotations(field, getCopyableAnnotationNames(field.getAst())); + List copyableAnnotations = findCopyableAnnotations(field); Name methodName = field.toName(setterName); - List annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables).appendList(copyableAnnotations); + List annsOnParam = copyAnnotations(onParam).appendList(copyableAnnotations); long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext()); JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(flags, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); - if (nonNulls.isEmpty()) { + if (!hasNonNullAnnotations(field)) { statements.append(treeMaker.Exec(assign)); } else { JCStatement nullCheck = generateNullCheck(treeMaker, field, source); diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java index b8f572d5..bcb7ee33 100644 --- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java @@ -431,8 +431,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { statements.append(assign); } - List nonNulls = findAnnotations(bfd.originalFieldNode, NON_NULL_PATTERN); - if (!nonNulls.isEmpty()) { + if (hasNonNullAnnotations(bfd.originalFieldNode)) { JCStatement nullCheck = generateNullCheck(maker, bfd.originalFieldNode, source); if (nullCheck != null) statements.append(nullCheck); } diff --git a/src/core/lombok/javac/handlers/HandleWither.java b/src/core/lombok/javac/handlers/HandleWither.java index b0e32d61..33c4dec2 100644 --- a/src/core/lombok/javac/handlers/HandleWither.java +++ b/src/core/lombok/javac/handlers/HandleWither.java @@ -222,9 +222,7 @@ public class HandleWither extends JavacAnnotationHandler { JCVariableDecl fieldDecl = (JCVariableDecl) field.get(); - List nonNulls = findAnnotations(field, NON_NULL_PATTERN); - List nullables = findAnnotations(field, NULLABLE_PATTERN); - List copyableAnnotations = findExactAnnotations(field, getCopyableAnnotationNames(field.getAst())); + List copyableAnnotations = findCopyableAnnotations(field); Name methodName = field.toName(witherName); @@ -232,7 +230,7 @@ public class HandleWither extends JavacAnnotationHandler { JCBlock methodBody = null; long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext()); - List annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables).appendList(copyableAnnotations); + List annsOnParam = copyAnnotations(onParam).appendList(copyableAnnotations); JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); @@ -265,7 +263,7 @@ public class HandleWither extends JavacAnnotationHandler { JCConditional conditional = maker.Conditional(identityCheck, maker.Ident(field.toName("this")), newClass); JCReturn returnStatement = maker.Return(conditional); - if (nonNulls.isEmpty()) { + if (!hasNonNullAnnotations(field)) { statements.append(returnStatement); } else { JCStatement nullCheck = generateNullCheck(maker, field, source); diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 1cc28072..b1557533 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -49,6 +49,7 @@ import lombok.core.LombokImmutableList; import lombok.core.AnnotationValues.AnnotationValue; import lombok.core.TypeResolver; import lombok.core.configuration.NullCheckExceptionType; +import lombok.core.configuration.TypeName; import lombok.core.handlers.HandlerUtil; import lombok.delombok.LombokOptionsFactory; import lombok.experimental.Accessors; @@ -1335,16 +1336,58 @@ public class JavacHandlerUtil { return result.toList(); } + public static boolean hasNonNullAnnotations(JavacNode node) { + for (JavacNode child : node.down()) { + if (child.getKind() == Kind.ANNOTATION) { + JCAnnotation annotation = (JCAnnotation) child.get(); + for (String nn : NONNULL_ANNOTATIONS) if (typeMatches(nn, node, annotation.annotationType)) return true; + } + } + + return false; + } + /** - * Searches the given field node for annotations and returns each one that matches the provided list of names. + * Searches the given field node for annotations and returns each one that is 'copyable' (either via configuration or from the base list). */ - public static List findExactAnnotations(JavacNode fieldNode, java.util.List names) { + public static List findCopyableAnnotations(JavacNode node) { + JCAnnotation anno = null; + String annoName = null; + for (JavacNode child : node.down()) { + if (child.getKind() == Kind.ANNOTATION) { + if (anno != null) { + annoName = ""; + break; + } + JCAnnotation annotation = (JCAnnotation) child.get(); + annoName = annotation.annotationType.toString(); + anno = annotation; + } + } + + if (annoName == null) return List.nil(); + + java.util.List configuredCopyable = node.getAst().readConfiguration(ConfigurationKeys.COPYABLE_ANNOTATIONS); + + if (!annoName.isEmpty()) { + for (TypeName cn : configuredCopyable) if (typeMatches(cn.toString(), node, anno.annotationType)) return List.of(anno); + for (String bn : BASE_COPYABLE_ANNOTATIONS) if (typeMatches(bn, node, anno.annotationType)) return List.of(anno); + } + ListBuffer result = new ListBuffer(); - for (JavacNode child : fieldNode.down()) { + for (JavacNode child : node.down()) { if (child.getKind() == Kind.ANNOTATION) { JCAnnotation annotation = (JCAnnotation) child.get(); - String annoName = annotation.annotationType.toString(); - if (names.contains(annoName)) result.append(annotation); + boolean match = false; + for (TypeName cn : configuredCopyable) if (typeMatches(cn.toString(), node, annotation.annotationType)) { + result.append(annotation); + match = true; + break; + } + if (!match) for (String bn : BASE_COPYABLE_ANNOTATIONS) if (typeMatches(bn, node, annotation.annotationType)) { + result.append(annotation); + break; + } } } return result.toList(); diff --git a/test/transform/resource/after-delombok/BuilderSingularAnnotatedTypes.java b/test/transform/resource/after-delombok/BuilderSingularAnnotatedTypes.java new file mode 100644 index 00000000..d621d376 --- /dev/null +++ b/test/transform/resource/after-delombok/BuilderSingularAnnotatedTypes.java @@ -0,0 +1,110 @@ +import java.util.Set; +import java.util.Map; +import lombok.NonNull; +class BuilderSingularAnnotatedTypes { + private Set<@NonNull String> foos; + private Map<@NonNull String, @NonNull Integer> bars; + @java.lang.SuppressWarnings("all") + BuilderSingularAnnotatedTypes(final Set<@NonNull String> foos, final Map<@NonNull String, @NonNull Integer> bars) { + this.foos = foos; + this.bars = bars; + } + @java.lang.SuppressWarnings("all") + public static class BuilderSingularAnnotatedTypesBuilder { + @java.lang.SuppressWarnings("all") + private java.util.ArrayList<@NonNull String> foos; + @java.lang.SuppressWarnings("all") + private java.util.ArrayList<@NonNull String> bars$key; + @java.lang.SuppressWarnings("all") + private java.util.ArrayList<@NonNull Integer> bars$value; + @java.lang.SuppressWarnings("all") + BuilderSingularAnnotatedTypesBuilder() { + } + @java.lang.SuppressWarnings("all") + public BuilderSingularAnnotatedTypesBuilder foo(final @NonNull String foo) { + if (this.foos == null) this.foos = new java.util.ArrayList<@NonNull String>(); + this.foos.add(foo); + return this; + } + @java.lang.SuppressWarnings("all") + public BuilderSingularAnnotatedTypesBuilder foos(final java.util.Collection foos) { + if (this.foos == null) this.foos = new java.util.ArrayList<@NonNull String>(); + this.foos.addAll(foos); + return this; + } + @java.lang.SuppressWarnings("all") + public BuilderSingularAnnotatedTypesBuilder clearFoos() { + if (this.foos != null) this.foos.clear(); + return this; + } + @java.lang.SuppressWarnings("all") + public BuilderSingularAnnotatedTypesBuilder bar(final @NonNull String barKey, final @NonNull Integer barValue) { + if (this.bars$key == null) { + this.bars$key = new java.util.ArrayList<@NonNull String>(); + this.bars$value = new java.util.ArrayList<@NonNull Integer>(); + } + this.bars$key.add(barKey); + this.bars$value.add(barValue); + return this; + } + @java.lang.SuppressWarnings("all") + public BuilderSingularAnnotatedTypesBuilder bars(final java.util.Map bars) { + if (this.bars$key == null) { + this.bars$key = new java.util.ArrayList<@NonNull String>(); + this.bars$value = new java.util.ArrayList<@NonNull Integer>(); + } + for (final java.util.Map.Entry $lombokEntry : bars.entrySet()) { + this.bars$key.add($lombokEntry.getKey()); + this.bars$value.add($lombokEntry.getValue()); + } + return this; + } + @java.lang.SuppressWarnings("all") + public BuilderSingularAnnotatedTypesBuilder clearBars() { + if (this.bars$key != null) { + this.bars$key.clear(); + this.bars$value.clear(); + } + return this; + } + @java.lang.SuppressWarnings("all") + public BuilderSingularAnnotatedTypes build() { + java.util.Set<@NonNull String> foos; + switch (this.foos == null ? 0 : this.foos.size()) { + case 0: + foos = java.util.Collections.emptySet(); + break; + case 1: + foos = java.util.Collections.singleton(this.foos.get(0)); + break; + default: + foos = new java.util.LinkedHashSet<@NonNull String>(this.foos.size() < 1073741824 ? 1 + this.foos.size() + (this.foos.size() - 3) / 3 : java.lang.Integer.MAX_VALUE); + foos.addAll(this.foos); + foos = java.util.Collections.unmodifiableSet(foos); + } + java.util.Map<@NonNull String, @NonNull Integer> bars; + switch (this.bars$key == null ? 0 : this.bars$key.size()) { + case 0: + bars = java.util.Collections.emptyMap(); + break; + case 1: + bars = java.util.Collections.singletonMap(this.bars$key.get(0), this.bars$value.get(0)); + break; + default: + bars = new java.util.LinkedHashMap<@NonNull String, @NonNull Integer>(this.bars$key.size() < 1073741824 ? 1 + this.bars$key.size() + (this.bars$key.size() - 3) / 3 : java.lang.Integer.MAX_VALUE); + for (int $i = 0; $i < this.bars$key.size(); $i++) bars.put(this.bars$key.get($i), (@NonNull Integer) this.bars$value.get($i)); + bars = java.util.Collections.unmodifiableMap(bars); + } + return new BuilderSingularAnnotatedTypes(foos, bars); + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "BuilderSingularAnnotatedTypes.BuilderSingularAnnotatedTypesBuilder(foos=" + this.foos + ", bars$key=" + this.bars$key + ", bars$value=" + this.bars$value + ")"; + } + } + @java.lang.SuppressWarnings("all") + public static BuilderSingularAnnotatedTypesBuilder builder() { + return new BuilderSingularAnnotatedTypesBuilder(); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/BuilderSingularAnnotatedTypes.java b/test/transform/resource/after-ecj/BuilderSingularAnnotatedTypes.java new file mode 100644 index 00000000..0168a13c --- /dev/null +++ b/test/transform/resource/after-ecj/BuilderSingularAnnotatedTypes.java @@ -0,0 +1,105 @@ +import java.util.Set; +import java.util.Map; +import lombok.NonNull; +import lombok.Singular; +@lombok.Builder class BuilderSingularAnnotatedTypes { + public static @java.lang.SuppressWarnings("all") class BuilderSingularAnnotatedTypesBuilder { + private @java.lang.SuppressWarnings("all") java.util.ArrayList<@NonNull String> foos; + private @java.lang.SuppressWarnings("all") java.util.ArrayList<@NonNull String> bars$key; + private @java.lang.SuppressWarnings("all") java.util.ArrayList<@NonNull Integer> bars$value; + @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder() { + super(); + } + public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder foo(@NonNull String foo) { + if ((this.foos == null)) + this.foos = new java.util.ArrayList<@NonNull String>(); + this.foos.add(foo); + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder foos(java.util.Collection foos) { + if ((this.foos == null)) + this.foos = new java.util.ArrayList<@NonNull String>(); + this.foos.addAll(foos); + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder clearFoos() { + if ((this.foos != null)) + this.foos.clear(); + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder bar(@NonNull String barKey, @NonNull Integer barValue) { + if ((this.bars$key == null)) + { + this.bars$key = new java.util.ArrayList<@NonNull String>(); + this.bars$value = new java.util.ArrayList<@NonNull Integer>(); + } + this.bars$key.add(barKey); + this.bars$value.add(barValue); + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder bars(java.util.Map bars) { + if ((this.bars$key == null)) + { + this.bars$key = new java.util.ArrayList<@NonNull String>(); + this.bars$value = new java.util.ArrayList<@NonNull Integer>(); + } + for (java.util.Map.Entry $lombokEntry : bars.entrySet()) + { + this.bars$key.add($lombokEntry.getKey()); + this.bars$value.add($lombokEntry.getValue()); + } + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder clearBars() { + if ((this.bars$key != null)) + { + this.bars$key.clear(); + this.bars$value.clear(); + } + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypes build() { + java.util.Set<@NonNull String> foos; + switch (((this.foos == null) ? 0 : this.foos.size())) { + case 0 : + foos = java.util.Collections.emptySet(); + break; + case 1 : + foos = java.util.Collections.singleton(this.foos.get(0)); + break; + default : + foos = new java.util.LinkedHashSet<@NonNull String>(((this.foos.size() < 0x40000000) ? ((1 + this.foos.size()) + ((this.foos.size() - 3) / 3)) : java.lang.Integer.MAX_VALUE)); + foos.addAll(this.foos); + foos = java.util.Collections.unmodifiableSet(foos); + } + java.util.Map<@NonNull String, @NonNull Integer> bars; + switch (((this.bars$key == null) ? 0 : this.bars$key.size())) { + case 0 : + bars = java.util.Collections.emptyMap(); + break; + case 1 : + bars = java.util.Collections.singletonMap(this.bars$key.get(0), this.bars$value.get(0)); + break; + default : + bars = new java.util.LinkedHashMap<@NonNull String, @NonNull Integer>(((this.bars$key.size() < 0x40000000) ? ((1 + this.bars$key.size()) + ((this.bars$key.size() - 3) / 3)) : java.lang.Integer.MAX_VALUE)); + for (int $i = 0;; ($i < this.bars$key.size()); $i ++) + bars.put(this.bars$key.get($i), this.bars$value.get($i)); + bars = java.util.Collections.unmodifiableMap(bars); + } + return new BuilderSingularAnnotatedTypes(foos, bars); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (((((("BuilderSingularAnnotatedTypes.BuilderSingularAnnotatedTypesBuilder(foos=" + this.foos) + ", bars$key=") + this.bars$key) + ", bars$value=") + this.bars$value) + ")"); + } + } + private @Singular Set<@NonNull String> foos; + private @Singular Map<@NonNull String, @NonNull Integer> bars; + @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypes(final Set<@NonNull String> foos, final Map<@NonNull String, @NonNull Integer> bars) { + super(); + this.foos = foos; + this.bars = bars; + } + public static @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder builder() { + return new BuilderSingularAnnotatedTypesBuilder(); + } +} diff --git a/test/transform/resource/before/BuilderSingularAnnotatedTypes.java b/test/transform/resource/before/BuilderSingularAnnotatedTypes.java new file mode 100644 index 00000000..163507b9 --- /dev/null +++ b/test/transform/resource/before/BuilderSingularAnnotatedTypes.java @@ -0,0 +1,12 @@ +//VERSION 8: +import java.util.Set; +import java.util.Map; + +import lombok.NonNull; +import lombok.Singular; + +@lombok.Builder +class BuilderSingularAnnotatedTypes { + @Singular private Set<@NonNull String> foos; + @Singular private Map<@NonNull String, @NonNull Integer> bars; +} -- cgit From 9198551defb7dd71d872c7b86af0a3f0bf0ec545 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Mon, 17 Sep 2018 23:44:26 +0200 Subject: Finishing work on making lombok do sensible things with TYPE_USE annotations and for example their use on the typearg in a collection type which is being `@Singular`-ized. --- doc/changelog.markdown | 2 + .../eclipse/handlers/EclipseHandlerUtil.java | 18 +++ .../lombok/eclipse/handlers/HandleNonNull.java | 21 +++- .../eclipse/handlers/HandleSuperBuilder.java | 10 +- .../singulars/EclipseGuavaSingularizer.java | 10 +- .../EclipseJavaUtilListSetSingularizer.java | 11 +- .../singulars/EclipseJavaUtilMapSingularizer.java | 16 ++- .../lombok/javac/handlers/HandleSuperBuilder.java | 8 +- .../lombok/javac/handlers/JavacHandlerUtil.java | 72 ++++++++++- .../handlers/singulars/JavacGuavaSingularizer.java | 6 +- .../JavacJavaUtilListSetSingularizer.java | 6 +- .../singulars/JavacJavaUtilMapSingularizer.java | 11 +- .../BuilderSingularAnnotatedTypes.java | 58 +++++---- .../SuperBuilderSingularAnnotatedTypes.java | 137 +++++++++++++++++++++ .../after-delombok/SuperBuilderWithNonNull.java | 10 +- .../after-ecj/BuilderDefaultsWarnings.java | 4 +- .../after-ecj/BuilderSingularAnnotatedTypes.java | 60 +++++---- .../after-ecj/BuilderSingularGuavaListsSets.java | 20 +-- .../after-ecj/BuilderSingularGuavaMaps.java | 12 +- .../resource/after-ecj/BuilderSingularLists.java | 12 +- .../resource/after-ecj/BuilderSingularMaps.java | 16 +-- .../resource/after-ecj/BuilderSingularNoAuto.java | 12 +- .../after-ecj/BuilderSingularRedirectToGuava.java | 12 +- .../resource/after-ecj/BuilderSingularSets.java | 16 +-- .../BuilderSingularToBuilderWithNull.java | 4 +- .../after-ecj/BuilderSingularWithPrefixes.java | 4 +- .../resource/after-ecj/BuilderWithDeprecated.java | 8 +- .../resource/after-ecj/BuilderWithToBuilder.java | 4 +- .../resource/after-ecj/SuperBuilderBasic.java | 4 +- .../SuperBuilderSingularAnnotatedTypes.java | 131 ++++++++++++++++++++ .../SuperBuilderWithCustomBuilderMethod.java | 4 +- .../after-ecj/SuperBuilderWithGenerics.java | 4 +- .../after-ecj/SuperBuilderWithGenerics2.java | 4 +- .../after-ecj/SuperBuilderWithNonNull.java | 4 +- .../after-ecj/SuperBuilderWithPrefixes.java | 4 +- .../before/BuilderSingularAnnotatedTypes.java | 10 +- .../before/SuperBuilderSingularAnnotatedTypes.java | 14 +++ 37 files changed, 612 insertions(+), 147 deletions(-) create mode 100644 test/transform/resource/after-delombok/SuperBuilderSingularAnnotatedTypes.java create mode 100644 test/transform/resource/after-ecj/SuperBuilderSingularAnnotatedTypes.java create mode 100644 test/transform/resource/before/SuperBuilderSingularAnnotatedTypes.java diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 04c9a052..220e0dc0 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -4,6 +4,8 @@ Lombok Changelog ### v1.18.3 "Edgy Guinea Pig" * PLATFORM: Support for Eclipse Photon. [Issue #1831](https://github.com/rzwitserloot/lombok/issues/1831) * FEATURE: The `@FieldNameConstants` feature has been completely redesigned. [Issue #1774](https://github.com/rzwitserloot/lombok/issues/1774) [FieldNameConstants documentation](https://projectlombok.org/features/experimental/FieldNameConstants) +* FEATURE: Lombok's `@NonNull` annotation can now be used on types (annotation on types has been introduced in JDK 8). `@Builder`'s `@Singular` annotation now properly deals with annotations on the generics type on the collection: `@Singular List<@NonNull String> names;` now does the right thing. +* BREAKING CHANGE: Lombok will now always copy specific annotations around (from field to getter, from field to builder 'setter', etcetera): A specific curated list of known annotations where that is the right thing to do (generally, `@NonNull` style annotations from various libraries), as well as any annotations you explicitly list in the `lombok.copyableAnnotations` config key in your `lombok.config` file. Also, lombok is more consistent about copying these annotations. (Previous behaviour: Lombok used to copy any annotation whose simple name was `NonNull`, `Nullable`, or `CheckForNull`). [Issue #1570](https://github.com/rzwitserloot/lombok/issues/1570) and [Issue #1634](https://github.com/rzwitserloot/lombok/issues/1634) * BUGFIX: When using lombok to compile modularized (`module-info.java`-style) code, if the module name has dots in it, it wouldn't work. [Issue #1808](https://github.com/rzwitserloot/lombok/issues/1808) * BUGFIX: Errors about lombok not reading a module providing `org.mapstruct.ap.spi` when trying to use lombok in jigsaw-mode on JDK 11. [Issue #1806](https://github.com/rzwitserloot/lombok/issues/1806) * BUGFIX: Fix NetBeans compile on save. [Issue #1770](https://github.com/rzwitserloot/lombok/issues/1770) diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index a972c1fe..5d582aad 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -449,6 +449,24 @@ public class EclipseHandlerUtil { return out; } + public static Annotation[] getTypeUseAnnotations(TypeReference from) { + Annotation[][] a; + try { + a = (Annotation[][]) reflect(TYPE_REFERENCE__ANNOTATIONS, from); + } catch (Exception e) { + return null; + } + if (a == null) return null; + Annotation[] b = a[a.length - 1]; + return b.length == 0 ? null : b; + } + + public static void removeTypeUseAnnotations(TypeReference from) { + try { + reflectSet(TYPE_REFERENCE__ANNOTATIONS, from, null); + } catch (Exception ignore) {} + } + public static TypeReference namePlusTypeParamsToTypeReference(char[] typeName, TypeParameter[] params, long p) { if (params != null && params.length > 0) { TypeReference[] refs = new TypeReference[params.length]; diff --git a/src/core/lombok/eclipse/handlers/HandleNonNull.java b/src/core/lombok/eclipse/handlers/HandleNonNull.java index d09993ed..ebc62909 100644 --- a/src/core/lombok/eclipse/handlers/HandleNonNull.java +++ b/src/core/lombok/eclipse/handlers/HandleNonNull.java @@ -58,7 +58,26 @@ import org.mangosdk.spi.ProviderFor; @ProviderFor(EclipseAnnotationHandler.class) @HandlerPriority(value = 512) // 2^9; onParameter=@__(@NonNull) has to run first. public class HandleNonNull extends EclipseAnnotationHandler { + public static final HandleNonNull INSTANCE = new HandleNonNull(); + + public void fix(EclipseNode method) { + for (EclipseNode m : method.down()) { + if (m.getKind() != Kind.ARGUMENT) continue; + for (EclipseNode c : m.down()) { + if (c.getKind() == Kind.ANNOTATION) { + if (annotationTypeMatches(NonNull.class, c)) { + handle0((Annotation) c.get(), c, true); + } + } + } + } + } + @Override public void handle(AnnotationValues annotation, Annotation ast, EclipseNode annotationNode) { + handle0(ast, annotationNode, false); + } + + private void handle0(Annotation ast, EclipseNode annotationNode, boolean force) { handleFlagUsage(annotationNode, ConfigurationKeys.NON_NULL_FLAG_USAGE, "@NonNull"); if (annotationNode.up().getKind() == Kind.FIELD) { @@ -88,7 +107,7 @@ public class HandleNonNull extends EclipseAnnotationHandler { return; } - if (isGenerated(declaration)) return; + if (!force && isGenerated(declaration)) return; if (declaration.isAbstract()) { // This used to be a warning, but as @NonNull also has a documentary purpose, better to not warn about this. Since 1.16.7 diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java index 559cca20..3070f1dc 100644 --- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java @@ -102,6 +102,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { private static final AbstractMethodDeclaration[] EMPTY_METHODS = {}; private static class BuilderFieldData { + Annotation[] annotations; TypeReference type; char[] rawName; char[] name; @@ -154,9 +155,12 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { EclipseNode isDefault = findAnnotation(Builder.Default.class, fieldNode); boolean isFinal = ((fd.modifiers & ClassFileConstants.AccFinal) != 0) || (valuePresent && !hasAnnotation(NonFinal.class, fieldNode)); + Annotation[] copyableAnnotations = findCopyableAnnotations(fieldNode); + BuilderFieldData bfd = new BuilderFieldData(); bfd.rawName = fieldNode.getName().toCharArray(); bfd.name = removePrefixFromField(fieldNode); + bfd.annotations = copyAnnotations(fd, copyableAnnotations); bfd.type = fd.type; bfd.singularData = getSingularData(fieldNode, ast); bfd.originalFieldNode = fieldNode; @@ -665,13 +669,13 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { }; if (bfd.singularData == null || bfd.singularData.getSingularizer() == null) { - generateSimpleSetterMethodForBuilder(builderType, deprecate, bfd.createdFields.get(0), bfd.nameOfSetFlag, returnTypeMaker.make(), returnStatementMaker.make(), sourceNode); + generateSimpleSetterMethodForBuilder(builderType, deprecate, bfd.createdFields.get(0), bfd.nameOfSetFlag, returnTypeMaker.make(), returnStatementMaker.make(), sourceNode, bfd.annotations); } else { bfd.singularData.getSingularizer().generateMethods(bfd.singularData, deprecate, builderType, true, returnTypeMaker, returnStatementMaker); } } - private void generateSimpleSetterMethodForBuilder(EclipseNode builderType, boolean deprecate, EclipseNode fieldNode, char[] nameOfSetFlag, TypeReference returnType, Statement returnStatement, EclipseNode sourceNode) { + private void generateSimpleSetterMethodForBuilder(EclipseNode builderType, boolean deprecate, EclipseNode fieldNode, char[] nameOfSetFlag, TypeReference returnType, Statement returnStatement, EclipseNode sourceNode, Annotation[] annosOnParam) { TypeDeclaration td = (TypeDeclaration) builderType.get(); AbstractMethodDeclaration[] existing = td.methods; if (existing == null) existing = EMPTY_METHODS; @@ -688,7 +692,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { String setterName = fieldNode.getName(); MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, nameOfSetFlag, returnType, returnStatement, ClassFileConstants.AccPublic, - sourceNode, Collections.emptyList(), Collections.emptyList()); + sourceNode, Collections.emptyList(), annosOnParam != null ? Arrays.asList(copyAnnotations(sourceNode.get(), annosOnParam)) : Collections.emptyList()); injectMethod(builderType, setter); } diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java index f1687c9c..17fc5e09 100644 --- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java +++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java @@ -32,6 +32,7 @@ import lombok.core.GuavaTypeMap; import lombok.core.LombokImmutableList; import lombok.core.handlers.HandlerUtil; import lombok.eclipse.EclipseNode; +import lombok.eclipse.handlers.HandleNonNull; import lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer; import lombok.eclipse.handlers.EclipseSingularsRecipes.SingularData; import lombok.eclipse.handlers.EclipseSingularsRecipes.StatementMaker; @@ -150,14 +151,17 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer { md.arguments = new Argument[suffixes.size()]; for (int i = 0; i < suffixes.size(); i++) { TypeReference tr = cloneParamType(i, data.getTypeArgs(), builderType); - md.arguments[i] = new Argument(names[i], 0, tr, 0); + Annotation[] typeUseAnns = getTypeUseAnnotations(tr); + removeTypeUseAnnotations(tr); + md.arguments[i] = new Argument(names[i], 0, tr, ClassFileConstants.AccFinal); + md.arguments[i].annotations = typeUseAnns; } md.returnType = returnType; md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName(getAddMethodName(), new String(data.getSingularName())).toCharArray(); md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null; data.setGeneratedByRecursive(md); - injectMethod(builderType, md); + HandleNonNull.INSTANCE.fix(injectMethod(builderType, md)); } void generatePluralMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) { @@ -182,7 +186,7 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer { TypeReference paramType; paramType = new QualifiedTypeReference(fromQualifiedName(getAddAllTypeName()), NULL_POSS); paramType = addTypeArgs(getTypeArgumentsCount(), true, builderType, paramType, data.getTypeArgs()); - Argument param = new Argument(data.getPluralName(), 0, paramType, 0); + Argument param = new Argument(data.getPluralName(), 0, paramType, ClassFileConstants.AccFinal); md.arguments = new Argument[] {param}; md.returnType = returnType; md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName(getAddMethodName() + "All", new String(data.getPluralName())).toCharArray(); diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java index 5f86a4dc..c7315790 100644 --- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java +++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java @@ -30,6 +30,7 @@ import java.util.List; import lombok.core.handlers.HandlerUtil; import lombok.eclipse.EclipseNode; +import lombok.eclipse.handlers.HandleNonNull; import lombok.eclipse.handlers.EclipseSingularsRecipes.SingularData; import lombok.eclipse.handlers.EclipseSingularsRecipes.StatementMaker; import lombok.eclipse.handlers.EclipseSingularsRecipes.TypeReferenceMaker; @@ -138,14 +139,18 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula md.statements = statements.toArray(new Statement[statements.size()]); TypeReference paramType = cloneParamType(0, data.getTypeArgs(), builderType); - Argument param = new Argument(data.getSingularName(), 0, paramType, 0); + Annotation[] typeUseAnns = getTypeUseAnnotations(paramType); + removeTypeUseAnnotations(paramType); + Argument param = new Argument(data.getSingularName(), 0, paramType, ClassFileConstants.AccFinal); + param.annotations = typeUseAnns; md.arguments = new Argument[] {param}; md.returnType = returnType; md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray(); md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null; data.setGeneratedByRecursive(md); - injectMethod(builderType, md); + + HandleNonNull.INSTANCE.fix(injectMethod(builderType, md)); } void generatePluralMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) { @@ -169,7 +174,7 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula TypeReference paramType = new QualifiedTypeReference(TypeConstants.JAVA_UTIL_COLLECTION, NULL_POSS); paramType = addTypeArgs(1, true, builderType, paramType, data.getTypeArgs()); - Argument param = new Argument(data.getPluralName(), 0, paramType, 0); + Argument param = new Argument(data.getPluralName(), 0, paramType, ClassFileConstants.AccFinal); md.arguments = new Argument[] {param}; md.returnType = returnType; md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray(); diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java index 69c2186a..174cd5fc 100644 --- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java +++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java @@ -59,6 +59,7 @@ import lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer; import lombok.eclipse.handlers.EclipseSingularsRecipes.SingularData; import lombok.eclipse.handlers.EclipseSingularsRecipes.StatementMaker; import lombok.eclipse.handlers.EclipseSingularsRecipes.TypeReferenceMaker; +import lombok.eclipse.handlers.HandleNonNull; @ProviderFor(EclipseSingularizer.class) public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer { @@ -214,16 +215,23 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer md.statements = statements.toArray(new Statement[statements.size()]); TypeReference keyParamType = cloneParamType(0, data.getTypeArgs(), builderType); - Argument keyParam = new Argument(keyParamName, 0, keyParamType, 0); TypeReference valueParamType = cloneParamType(1, data.getTypeArgs(), builderType); - Argument valueParam = new Argument(valueParamName, 0, valueParamType, 0); + Annotation[] typeUseAnnsKey = getTypeUseAnnotations(keyParamType); + Annotation[] typeUseAnnsValue = getTypeUseAnnotations(valueParamType); + + removeTypeUseAnnotations(keyParamType); + removeTypeUseAnnotations(valueParamType); + Argument keyParam = new Argument(keyParamName, 0, keyParamType, ClassFileConstants.AccFinal); + Argument valueParam = new Argument(valueParamName, 0, valueParamType, ClassFileConstants.AccFinal); + keyParam.annotations = typeUseAnnsKey; + valueParam.annotations = typeUseAnnsValue; md.arguments = new Argument[] {keyParam, valueParam}; md.returnType = returnType; md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName("put", new String(data.getSingularName())).toCharArray(); md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null; data.setGeneratedByRecursive(md); - injectMethod(builderType, md); + HandleNonNull.INSTANCE.fix(injectMethod(builderType, md)); } private void generatePluralMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent) { @@ -280,7 +288,7 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer TypeReference paramType = new QualifiedTypeReference(JAVA_UTIL_MAP, NULL_POSS); paramType = addTypeArgs(2, true, builderType, paramType, data.getTypeArgs()); - Argument param = new Argument(data.getPluralName(), 0, paramType, 0); + Argument param = new Argument(data.getPluralName(), 0, paramType, ClassFileConstants.AccFinal); md.arguments = new Argument[] {param}; md.returnType = returnType; md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName("putAll", new String(data.getPluralName())).toCharArray(); diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java index bcb7ee33..66d6e47e 100644 --- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java @@ -80,6 +80,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { private static final String SELF_METHOD = "self"; private static class BuilderFieldData { + List annotations; JCExpression type; Name rawName; Name name; @@ -135,6 +136,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { BuilderFieldData bfd = new BuilderFieldData(); bfd.rawName = fd.name; bfd.name = removePrefixFromField(fieldNode); + bfd.annotations = findCopyableAnnotations(fieldNode); bfd.type = fd.vartype; bfd.singularData = getSingularData(fieldNode); bfd.originalFieldNode = fieldNode; @@ -616,13 +618,13 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { }}; if (fieldNode.singularData == null || fieldNode.singularData.getSingularizer() == null) { - generateSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.nameOfSetFlag, source, true, true, returnTypeMaker.make(), returnStatementMaker.make()); + generateSimpleSetterMethodForBuilder(builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.nameOfSetFlag, source, true, true, returnTypeMaker.make(), returnStatementMaker.make(), fieldNode.annotations); } else { fieldNode.singularData.getSingularizer().generateMethods(fieldNode.singularData, deprecate, builderType, source.get(), true, returnTypeMaker, returnStatementMaker); } } - private void generateSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain, JCExpression returnType, JCStatement returnStatement) { + private void generateSimpleSetterMethodForBuilder(JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain, JCExpression returnType, JCStatement returnStatement, List annosOnParam) { Name fieldName = ((JCVariableDecl) fieldNode.get()).name; for (JavacNode child : builderType.down()) { @@ -636,7 +638,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { JavacTreeMaker maker = fieldNode.getTreeMaker(); - JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, nameOfSetFlag, returnType, returnStatement, source, List.nil(), List.nil()); + JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, nameOfSetFlag, returnType, returnStatement, source, List.nil(), annosOnParam); injectMethod(builderType, newMethod); } diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index b1557533..e4e40095 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -27,6 +27,7 @@ import static lombok.javac.Javac.*; import static lombok.javac.JavacAugments.JCTree_generatedNode; import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -1039,6 +1040,57 @@ public class JavacHandlerUtil { return (field.mods.flags & Flags.ENUM) != 0; } + static class JCAnnotatedTypeReflect { + private static Class TYPE; + private static Constructor CONSTRUCTOR; + private static Field ANNOTATIONS, UNDERLYING_TYPE; + + private static void init(Class in) { + if (TYPE != null) return; + if (!in.getName().equals("com.sun.tools.javac.tree.JCTree$JCAnnotatedType")) return; + try { + CONSTRUCTOR = in.getDeclaredConstructor(List.class, JCExpression.class); + CONSTRUCTOR.setAccessible(true); + ANNOTATIONS = in.getDeclaredField("annotations"); + UNDERLYING_TYPE = in.getDeclaredField("underlyingType"); + TYPE = in; + } catch (Exception ignore) {} + } + + static boolean is(JCTree obj) { + if (obj == null) return false; + init(obj.getClass()); + return obj.getClass() == TYPE; + } + + @SuppressWarnings("unchecked") + static List getAnnotations(JCTree obj) { + init(obj.getClass()); + try { + return (List) ANNOTATIONS.get(obj); + } catch (Exception e) { + return List.nil(); + } + } + + static JCExpression getUnderlyingType(JCTree obj) { + init(obj.getClass()); + try { + return (JCExpression) UNDERLYING_TYPE.get(obj); + } catch (Exception e) { + return null; + } + } + + static JCExpression create(List annotations, JCExpression underlyingType) { + try { + return (JCExpression) CONSTRUCTOR.newInstance(annotations, underlyingType); + } catch (Exception e) { + return null; + } + } + } + // jdk9 support, types have changed, names stay the same static class ClassSymbolMembersField { private static final Field membersField; @@ -1570,6 +1622,16 @@ public class JavacHandlerUtil { return out.toList(); } + public static List getTypeUseAnnotations(JCExpression from) { + if (!JCAnnotatedTypeReflect.is(from)) return List.nil(); + return JCAnnotatedTypeReflect.getAnnotations(from); + } + + public static JCExpression removeTypeUseAnnotations(JCExpression from) { + if (!JCAnnotatedTypeReflect.is(from)) return from; + return JCAnnotatedTypeReflect.getUnderlyingType(from); + } + public static JCExpression namePlusTypeParamsToTypeReference(JavacTreeMaker maker, Name typeName, List params) { if (params.isEmpty()) { return maker.Ident(typeName); @@ -1650,7 +1712,7 @@ public class JavacHandlerUtil { } /** - * Creates a full clone of a given javac AST type node. Every part is cloned (every identifier, every select, every wildcard, every type apply). + * Creates a full clone of a given javac AST type node. Every part is cloned (every identifier, every select, every wildcard, every type apply, every type_use annotation). * * If there's any node in the tree that we don't know how to clone, that part isn't cloned. However, we wouldn't know what could possibly show up that we * can't currently clone; that's just a safeguard. @@ -1712,6 +1774,12 @@ public class JavacHandlerUtil { return maker.Wildcard(newKind, newInner); } + if (JCAnnotatedTypeReflect.is(in)) { + JCExpression underlyingType = cloneType0(maker, JCAnnotatedTypeReflect.getUnderlyingType(in)); + List anns = copyAnnotations(JCAnnotatedTypeReflect.getAnnotations(in)); + return JCAnnotatedTypeReflect.create(anns, underlyingType); + } + // This is somewhat unsafe, but it's better than outright throwing an exception here. Returning null will just cause an exception down the pipeline. return (JCExpression) in; } @@ -1887,7 +1955,7 @@ public class JavacHandlerUtil { public static boolean isDirectDescendantOfObject(JavacNode typeNode) { if (!(typeNode.get() instanceof JCClassDecl)) throw new IllegalArgumentException("not a type node"); - JCTree extending = Javac.getExtendsClause((JCClassDecl)typeNode.get()); + JCTree extending = Javac.getExtendsClause((JCClassDecl) typeNode.get()); if (extending == null) return true; String p = extending.toString(); return p.equals("Object") || p.equals("java.lang.Object"); diff --git a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java index ffaf6674..74010d52 100644 --- a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java +++ b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java @@ -39,6 +39,7 @@ import lombok.javac.handlers.JavacSingularsRecipes.StatementMaker; 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.JCBlock; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; @@ -125,7 +126,10 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer { ListBuffer params = new ListBuffer(); for (int i = 0; i < suffixes.size(); i++) { JCExpression pt = cloneParamType(i, maker, data.getTypeArgs(), builderType, source); - JCVariableDecl p = maker.VarDef(maker.Modifiers(paramFlags), names[i], pt, null); + List typeUseAnns = getTypeUseAnnotations(pt); + pt = removeTypeUseAnnotations(pt); + JCModifiers paramMods = typeUseAnns.isEmpty() ? maker.Modifiers(paramFlags) : maker.Modifiers(paramFlags, typeUseAnns); + JCVariableDecl p = maker.VarDef(paramMods, names[i], pt, null); params.append(p); } diff --git a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java index 39e53ebb..26ff8ba6 100644 --- a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java +++ b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSetSingularizer.java @@ -36,6 +36,7 @@ import lombok.javac.handlers.JavacSingularsRecipes.StatementMaker; 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.JCBlock; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; @@ -124,7 +125,10 @@ abstract class JavacJavaUtilListSetSingularizer extends JavacJavaUtilSingularize long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext()); if (!fluent) name = builderType.toName(HandlerUtil.buildAccessorName("add", name.toString())); JCExpression paramType = cloneParamType(0, maker, data.getTypeArgs(), builderType, source); - JCVariableDecl param = maker.VarDef(maker.Modifiers(paramFlags), data.getSingularName(), paramType, null); + List typeUseAnns = getTypeUseAnnotations(paramType); + paramType = removeTypeUseAnnotations(paramType); + JCModifiers paramMods = typeUseAnns.isEmpty() ? maker.Modifiers(paramFlags) : maker.Modifiers(paramFlags, typeUseAnns); + JCVariableDecl param = maker.VarDef(paramMods, data.getSingularName(), paramType, null); JCMethodDecl method = maker.MethodDef(mods, name, returnType, typeParams, List.of(param), thrown, body, null); injectMethod(builderType, method); } diff --git a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java index 34350f40..a009b88c 100644 --- a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java +++ b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilMapSingularizer.java @@ -40,6 +40,7 @@ import org.mangosdk.spi.ProviderFor; 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.JCBlock; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; @@ -165,8 +166,14 @@ public class JavacJavaUtilMapSingularizer extends JavacJavaUtilSingularizer { if (!fluent) name = builderType.toName(HandlerUtil.buildAccessorName("put", name.toString())); JCExpression paramTypeKey = cloneParamType(0, maker, data.getTypeArgs(), builderType, source); JCExpression paramTypeValue = cloneParamType(1, maker, data.getTypeArgs(), builderType, source); - JCVariableDecl paramKey = maker.VarDef(maker.Modifiers(paramFlags), keyName, paramTypeKey, null); - JCVariableDecl paramValue = maker.VarDef(maker.Modifiers(paramFlags), valueName, paramTypeValue, null); + List typeUseAnnsKey = getTypeUseAnnotations(paramTypeKey); + List typeUseAnnsValue = getTypeUseAnnotations(paramTypeValue); + paramTypeKey = removeTypeUseAnnotations(paramTypeKey); + paramTypeValue = removeTypeUseAnnotations(paramTypeValue); + JCModifiers paramModsKey = typeUseAnnsKey.isEmpty() ? maker.Modifiers(paramFlags) : maker.Modifiers(paramFlags, typeUseAnnsKey); + JCModifiers paramModsValue = typeUseAnnsValue.isEmpty() ? maker.Modifiers(paramFlags) : maker.Modifiers(paramFlags, typeUseAnnsValue); + JCVariableDecl paramKey = maker.VarDef(paramModsKey, keyName, paramTypeKey, null); + JCVariableDecl paramValue = maker.VarDef(paramModsValue, valueName, paramTypeValue, null); JCMethodDecl method = maker.MethodDef(mods, name, returnType, typeParams, List.of(paramKey, paramValue), thrown, body, null); injectMethod(builderType, method); } diff --git a/test/transform/resource/after-delombok/BuilderSingularAnnotatedTypes.java b/test/transform/resource/after-delombok/BuilderSingularAnnotatedTypes.java index d621d376..93825659 100644 --- a/test/transform/resource/after-delombok/BuilderSingularAnnotatedTypes.java +++ b/test/transform/resource/after-delombok/BuilderSingularAnnotatedTypes.java @@ -1,34 +1,42 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; import java.util.Set; import java.util.Map; import lombok.NonNull; +@Target(ElementType.TYPE_USE) +@interface MyAnnotation { +} class BuilderSingularAnnotatedTypes { - private Set<@NonNull String> foos; - private Map<@NonNull String, @NonNull Integer> bars; + private Set<@MyAnnotation @NonNull String> foos; + private Map<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer> bars; @java.lang.SuppressWarnings("all") - BuilderSingularAnnotatedTypes(final Set<@NonNull String> foos, final Map<@NonNull String, @NonNull Integer> bars) { + BuilderSingularAnnotatedTypes(final Set<@MyAnnotation @NonNull String> foos, final Map<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer> bars) { this.foos = foos; this.bars = bars; } @java.lang.SuppressWarnings("all") public static class BuilderSingularAnnotatedTypesBuilder { @java.lang.SuppressWarnings("all") - private java.util.ArrayList<@NonNull String> foos; + private java.util.ArrayList<@MyAnnotation @NonNull String> foos; @java.lang.SuppressWarnings("all") - private java.util.ArrayList<@NonNull String> bars$key; + private java.util.ArrayList<@MyAnnotation @NonNull String> bars$key; @java.lang.SuppressWarnings("all") - private java.util.ArrayList<@NonNull Integer> bars$value; + private java.util.ArrayList<@MyAnnotation @NonNull Integer> bars$value; @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder() { } @java.lang.SuppressWarnings("all") - public BuilderSingularAnnotatedTypesBuilder foo(final @NonNull String foo) { - if (this.foos == null) this.foos = new java.util.ArrayList<@NonNull String>(); + public BuilderSingularAnnotatedTypesBuilder foo(@MyAnnotation @NonNull final String foo) { + if (foo == null) { + throw new java.lang.NullPointerException("foo is marked @NonNull but is null"); + } + if (this.foos == null) this.foos = new java.util.ArrayList<@MyAnnotation @NonNull String>(); this.foos.add(foo); return this; } @java.lang.SuppressWarnings("all") - public BuilderSingularAnnotatedTypesBuilder foos(final java.util.Collection foos) { - if (this.foos == null) this.foos = new java.util.ArrayList<@NonNull String>(); + public BuilderSingularAnnotatedTypesBuilder foos(final java.util.Collection foos) { + if (this.foos == null) this.foos = new java.util.ArrayList<@MyAnnotation @NonNull String>(); this.foos.addAll(foos); return this; } @@ -38,22 +46,28 @@ class BuilderSingularAnnotatedTypes { return this; } @java.lang.SuppressWarnings("all") - public BuilderSingularAnnotatedTypesBuilder bar(final @NonNull String barKey, final @NonNull Integer barValue) { + public BuilderSingularAnnotatedTypesBuilder bar(@MyAnnotation @NonNull final String barKey, @MyAnnotation @NonNull final Integer barValue) { + if (barKey == null) { + throw new java.lang.NullPointerException("barKey is marked @NonNull but is null"); + } + if (barValue == null) { + throw new java.lang.NullPointerException("barValue is marked @NonNull but is null"); + } if (this.bars$key == null) { - this.bars$key = new java.util.ArrayList<@NonNull String>(); - this.bars$value = new java.util.ArrayList<@NonNull Integer>(); + this.bars$key = new java.util.ArrayList<@MyAnnotation @NonNull String>(); + this.bars$value = new java.util.ArrayList<@MyAnnotation @NonNull Integer>(); } this.bars$key.add(barKey); this.bars$value.add(barValue); return this; } @java.lang.SuppressWarnings("all") - public BuilderSingularAnnotatedTypesBuilder bars(final java.util.Map bars) { + public BuilderSingularAnnotatedTypesBuilder bars(final java.util.Map bars) { if (this.bars$key == null) { - this.bars$key = new java.util.ArrayList<@NonNull String>(); - this.bars$value = new java.util.ArrayList<@NonNull Integer>(); + this.bars$key = new java.util.ArrayList<@MyAnnotation @NonNull String>(); + this.bars$value = new java.util.ArrayList<@MyAnnotation @NonNull Integer>(); } - for (final java.util.Map.Entry $lombokEntry : bars.entrySet()) { + for (final java.util.Map.Entry $lombokEntry : bars.entrySet()) { this.bars$key.add($lombokEntry.getKey()); this.bars$value.add($lombokEntry.getValue()); } @@ -69,7 +83,7 @@ class BuilderSingularAnnotatedTypes { } @java.lang.SuppressWarnings("all") public BuilderSingularAnnotatedTypes build() { - java.util.Set<@NonNull String> foos; + java.util.Set<@MyAnnotation @NonNull String> foos; switch (this.foos == null ? 0 : this.foos.size()) { case 0: foos = java.util.Collections.emptySet(); @@ -78,11 +92,11 @@ class BuilderSingularAnnotatedTypes { foos = java.util.Collections.singleton(this.foos.get(0)); break; default: - foos = new java.util.LinkedHashSet<@NonNull String>(this.foos.size() < 1073741824 ? 1 + this.foos.size() + (this.foos.size() - 3) / 3 : java.lang.Integer.MAX_VALUE); + foos = new java.util.LinkedHashSet<@MyAnnotation @NonNull String>(this.foos.size() < 1073741824 ? 1 + this.foos.size() + (this.foos.size() - 3) / 3 : java.lang.Integer.MAX_VALUE); foos.addAll(this.foos); foos = java.util.Collections.unmodifiableSet(foos); } - java.util.Map<@NonNull String, @NonNull Integer> bars; + java.util.Map<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer> bars; switch (this.bars$key == null ? 0 : this.bars$key.size()) { case 0: bars = java.util.Collections.emptyMap(); @@ -91,8 +105,8 @@ class BuilderSingularAnnotatedTypes { bars = java.util.Collections.singletonMap(this.bars$key.get(0), this.bars$value.get(0)); break; default: - bars = new java.util.LinkedHashMap<@NonNull String, @NonNull Integer>(this.bars$key.size() < 1073741824 ? 1 + this.bars$key.size() + (this.bars$key.size() - 3) / 3 : java.lang.Integer.MAX_VALUE); - for (int $i = 0; $i < this.bars$key.size(); $i++) bars.put(this.bars$key.get($i), (@NonNull Integer) this.bars$value.get($i)); + bars = new java.util.LinkedHashMap<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer>(this.bars$key.size() < 1073741824 ? 1 + this.bars$key.size() + (this.bars$key.size() - 3) / 3 : java.lang.Integer.MAX_VALUE); + for (int $i = 0; $i < this.bars$key.size(); $i++) bars.put(this.bars$key.get($i), (@MyAnnotation @NonNull Integer) this.bars$value.get($i)); bars = java.util.Collections.unmodifiableMap(bars); } return new BuilderSingularAnnotatedTypes(foos, bars); diff --git a/test/transform/resource/after-delombok/SuperBuilderSingularAnnotatedTypes.java b/test/transform/resource/after-delombok/SuperBuilderSingularAnnotatedTypes.java new file mode 100644 index 00000000..1baf81aa --- /dev/null +++ b/test/transform/resource/after-delombok/SuperBuilderSingularAnnotatedTypes.java @@ -0,0 +1,137 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.Set; +import java.util.Map; +import lombok.NonNull; +@Target(ElementType.TYPE_USE) +@interface MyAnnotation { +} +class SuperBuilderSingularAnnotatedTypes { + private Set<@MyAnnotation @NonNull String> foos; + private Map<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer> bars; + @java.lang.SuppressWarnings("all") + public static abstract class SuperBuilderSingularAnnotatedTypesBuilder> { + @java.lang.SuppressWarnings("all") + private java.util.ArrayList<@MyAnnotation @NonNull String> foos; + @java.lang.SuppressWarnings("all") + private java.util.ArrayList<@MyAnnotation @NonNull String> bars$key; + @java.lang.SuppressWarnings("all") + private java.util.ArrayList<@MyAnnotation @NonNull Integer> bars$value; + @java.lang.SuppressWarnings("all") + protected abstract B self(); + @java.lang.SuppressWarnings("all") + public abstract C build(); + @java.lang.SuppressWarnings("all") + public B foo(@MyAnnotation @NonNull final String foo) { + if (foo == null) { + throw new java.lang.NullPointerException("foo is marked @NonNull but is null"); + } + if (this.foos == null) this.foos = new java.util.ArrayList<@MyAnnotation @NonNull String>(); + this.foos.add(foo); + return self(); + } + @java.lang.SuppressWarnings("all") + public B foos(final java.util.Collection foos) { + if (this.foos == null) this.foos = new java.util.ArrayList<@MyAnnotation @NonNull String>(); + this.foos.addAll(foos); + return self(); + } + @java.lang.SuppressWarnings("all") + public B clearFoos() { + if (this.foos != null) this.foos.clear(); + return self(); + } + @java.lang.SuppressWarnings("all") + public B bar(@MyAnnotation @NonNull final String barKey, @MyAnnotation @NonNull final Integer barValue) { + if (barKey == null) { + throw new java.lang.NullPointerException("barKey is marked @NonNull but is null"); + } + if (barValue == null) { + throw new java.lang.NullPointerException("barValue is marked @NonNull but is null"); + } + if (this.bars$key == null) { + this.bars$key = new java.util.ArrayList<@MyAnnotation @NonNull String>(); + this.bars$value = new java.util.ArrayList<@MyAnnotation @NonNull Integer>(); + } + this.bars$key.add(barKey); + this.bars$value.add(barValue); + return self(); + } + @java.lang.SuppressWarnings("all") + public B bars(final java.util.Map bars) { + if (this.bars$key == null) { + this.bars$key = new java.util.ArrayList<@MyAnnotation @NonNull String>(); + this.bars$value = new java.util.ArrayList<@MyAnnotation @NonNull Integer>(); + } + for (final java.util.Map.Entry $lombokEntry : bars.entrySet()) { + this.bars$key.add($lombokEntry.getKey()); + this.bars$value.add($lombokEntry.getValue()); + } + return self(); + } + @java.lang.SuppressWarnings("all") + public B clearBars() { + if (this.bars$key != null) { + this.bars$key.clear(); + this.bars$value.clear(); + } + return self(); + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "SuperBuilderSingularAnnotatedTypes.SuperBuilderSingularAnnotatedTypesBuilder(foos=" + this.foos + ", bars$key=" + this.bars$key + ", bars$value=" + this.bars$value + ")"; + } + } + @java.lang.SuppressWarnings("all") + private static final class SuperBuilderSingularAnnotatedTypesBuilderImpl extends SuperBuilderSingularAnnotatedTypesBuilder { + @java.lang.SuppressWarnings("all") + private SuperBuilderSingularAnnotatedTypesBuilderImpl() { + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + protected SuperBuilderSingularAnnotatedTypesBuilderImpl self() { + return this; + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + public SuperBuilderSingularAnnotatedTypes build() { + return new SuperBuilderSingularAnnotatedTypes(this); + } + } + @java.lang.SuppressWarnings("all") + protected SuperBuilderSingularAnnotatedTypes(final SuperBuilderSingularAnnotatedTypesBuilder b) { + java.util.Set<@MyAnnotation @NonNull String> foos; + switch (b.foos == null ? 0 : b.foos.size()) { + case 0: + foos = java.util.Collections.emptySet(); + break; + case 1: + foos = java.util.Collections.singleton(b.foos.get(0)); + break; + default: + foos = new java.util.LinkedHashSet<@MyAnnotation @NonNull String>(b.foos.size() < 1073741824 ? 1 + b.foos.size() + (b.foos.size() - 3) / 3 : java.lang.Integer.MAX_VALUE); + foos.addAll(b.foos); + foos = java.util.Collections.unmodifiableSet(foos); + } + this.foos = foos; + java.util.Map<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer> bars; + switch (b.bars$key == null ? 0 : b.bars$key.size()) { + case 0: + bars = java.util.Collections.emptyMap(); + break; + case 1: + bars = java.util.Collections.singletonMap(b.bars$key.get(0), b.bars$value.get(0)); + break; + default: + bars = new java.util.LinkedHashMap<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer>(b.bars$key.size() < 1073741824 ? 1 + b.bars$key.size() + (b.bars$key.size() - 3) / 3 : java.lang.Integer.MAX_VALUE); + for (int $i = 0; $i < b.bars$key.size(); $i++) bars.put(b.bars$key.get($i), (@MyAnnotation @NonNull Integer) b.bars$value.get($i)); + bars = java.util.Collections.unmodifiableMap(bars); + } + this.bars = bars; + } + @java.lang.SuppressWarnings("all") + public static SuperBuilderSingularAnnotatedTypesBuilder builder() { + return new SuperBuilderSingularAnnotatedTypesBuilderImpl(); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/SuperBuilderWithNonNull.java b/test/transform/resource/after-delombok/SuperBuilderWithNonNull.java index 5eba938f..cac5482b 100644 --- a/test/transform/resource/after-delombok/SuperBuilderWithNonNull.java +++ b/test/transform/resource/after-delombok/SuperBuilderWithNonNull.java @@ -18,7 +18,10 @@ public class SuperBuilderWithNonNull { @java.lang.SuppressWarnings("all") public abstract C build(); @java.lang.SuppressWarnings("all") - public B nonNullParentField(final String nonNullParentField) { + public B nonNullParentField(@lombok.NonNull final String nonNullParentField) { + if (nonNullParentField == null) { + throw new java.lang.NullPointerException("nonNullParentField is marked @NonNull but is null"); + } this.nonNullParentField = nonNullParentField; nonNullParentField$set = true; return self(); @@ -72,7 +75,10 @@ public class SuperBuilderWithNonNull { @java.lang.SuppressWarnings("all") public abstract C build(); @java.lang.SuppressWarnings("all") - public B nonNullChildField(final String nonNullChildField) { + public B nonNullChildField(@lombok.NonNull final String nonNullChildField) { + if (nonNullChildField == null) { + throw new java.lang.NullPointerException("nonNullChildField is marked @NonNull but is null"); + } this.nonNullChildField = nonNullChildField; return self(); } diff --git a/test/transform/resource/after-ecj/BuilderDefaultsWarnings.java b/test/transform/resource/after-ecj/BuilderDefaultsWarnings.java index 236632d0..1078f452 100644 --- a/test/transform/resource/after-ecj/BuilderDefaultsWarnings.java +++ b/test/transform/resource/after-ecj/BuilderDefaultsWarnings.java @@ -16,13 +16,13 @@ public @Builder class BuilderDefaultsWarnings { this.z = z; return this; } - public @java.lang.SuppressWarnings("all") BuilderDefaultsWarningsBuilder item(String item) { + public @java.lang.SuppressWarnings("all") BuilderDefaultsWarningsBuilder item(final String item) { if ((this.items == null)) this.items = new java.util.ArrayList(); this.items.add(item); return this; } - public @java.lang.SuppressWarnings("all") BuilderDefaultsWarningsBuilder items(java.util.Collection items) { + public @java.lang.SuppressWarnings("all") BuilderDefaultsWarningsBuilder items(final java.util.Collection items) { if ((this.items == null)) this.items = new java.util.ArrayList(); this.items.addAll(items); diff --git a/test/transform/resource/after-ecj/BuilderSingularAnnotatedTypes.java b/test/transform/resource/after-ecj/BuilderSingularAnnotatedTypes.java index 0168a13c..26023e1a 100644 --- a/test/transform/resource/after-ecj/BuilderSingularAnnotatedTypes.java +++ b/test/transform/resource/after-ecj/BuilderSingularAnnotatedTypes.java @@ -1,24 +1,32 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; import java.util.Set; import java.util.Map; import lombok.NonNull; import lombok.Singular; +@Target(ElementType.TYPE_USE) @interface MyAnnotation { +} @lombok.Builder class BuilderSingularAnnotatedTypes { public static @java.lang.SuppressWarnings("all") class BuilderSingularAnnotatedTypesBuilder { - private @java.lang.SuppressWarnings("all") java.util.ArrayList<@NonNull String> foos; - private @java.lang.SuppressWarnings("all") java.util.ArrayList<@NonNull String> bars$key; - private @java.lang.SuppressWarnings("all") java.util.ArrayList<@NonNull Integer> bars$value; + private @java.lang.SuppressWarnings("all") java.util.ArrayList<@MyAnnotation @NonNull String> foos; + private @java.lang.SuppressWarnings("all") java.util.ArrayList<@MyAnnotation @NonNull String> bars$key; + private @java.lang.SuppressWarnings("all") java.util.ArrayList<@MyAnnotation @NonNull Integer> bars$value; @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder() { super(); } - public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder foo(@NonNull String foo) { + public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder foo(final @MyAnnotation @NonNull String foo) { + if ((foo == null)) + { + throw new java.lang.NullPointerException("foo is marked @NonNull but is null"); + } if ((this.foos == null)) - this.foos = new java.util.ArrayList<@NonNull String>(); + this.foos = new java.util.ArrayList<@MyAnnotation @NonNull String>(); this.foos.add(foo); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder foos(java.util.Collection foos) { + public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder foos(final java.util.Collection foos) { if ((this.foos == null)) - this.foos = new java.util.ArrayList<@NonNull String>(); + this.foos = new java.util.ArrayList<@MyAnnotation @NonNull String>(); this.foos.addAll(foos); return this; } @@ -27,23 +35,31 @@ import lombok.Singular; this.foos.clear(); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder bar(@NonNull String barKey, @NonNull Integer barValue) { + public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder bar(final @MyAnnotation @NonNull String barKey, final @MyAnnotation @NonNull Integer barValue) { + if ((barKey == null)) + { + throw new java.lang.NullPointerException("barKey is marked @NonNull but is null"); + } + if ((barValue == null)) + { + throw new java.lang.NullPointerException("barValue is marked @NonNull but is null"); + } if ((this.bars$key == null)) { - this.bars$key = new java.util.ArrayList<@NonNull String>(); - this.bars$value = new java.util.ArrayList<@NonNull Integer>(); + this.bars$key = new java.util.ArrayList<@MyAnnotation @NonNull String>(); + this.bars$value = new java.util.ArrayList<@MyAnnotation @NonNull Integer>(); } this.bars$key.add(barKey); this.bars$value.add(barValue); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder bars(java.util.Map bars) { + public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder bars(final java.util.Map bars) { if ((this.bars$key == null)) { - this.bars$key = new java.util.ArrayList<@NonNull String>(); - this.bars$value = new java.util.ArrayList<@NonNull Integer>(); + this.bars$key = new java.util.ArrayList<@MyAnnotation @NonNull String>(); + this.bars$value = new java.util.ArrayList<@MyAnnotation @NonNull Integer>(); } - for (java.util.Map.Entry $lombokEntry : bars.entrySet()) + for (java.util.Map.Entry $lombokEntry : bars.entrySet()) { this.bars$key.add($lombokEntry.getKey()); this.bars$value.add($lombokEntry.getValue()); @@ -59,7 +75,7 @@ import lombok.Singular; return this; } public @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypes build() { - java.util.Set<@NonNull String> foos; + java.util.Set<@MyAnnotation @NonNull String> foos; switch (((this.foos == null) ? 0 : this.foos.size())) { case 0 : foos = java.util.Collections.emptySet(); @@ -68,11 +84,11 @@ import lombok.Singular; foos = java.util.Collections.singleton(this.foos.get(0)); break; default : - foos = new java.util.LinkedHashSet<@NonNull String>(((this.foos.size() < 0x40000000) ? ((1 + this.foos.size()) + ((this.foos.size() - 3) / 3)) : java.lang.Integer.MAX_VALUE)); + foos = new java.util.LinkedHashSet<@MyAnnotation @NonNull String>(((this.foos.size() < 0x40000000) ? ((1 + this.foos.size()) + ((this.foos.size() - 3) / 3)) : java.lang.Integer.MAX_VALUE)); foos.addAll(this.foos); foos = java.util.Collections.unmodifiableSet(foos); } - java.util.Map<@NonNull String, @NonNull Integer> bars; + java.util.Map<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer> bars; switch (((this.bars$key == null) ? 0 : this.bars$key.size())) { case 0 : bars = java.util.Collections.emptyMap(); @@ -81,7 +97,7 @@ import lombok.Singular; bars = java.util.Collections.singletonMap(this.bars$key.get(0), this.bars$value.get(0)); break; default : - bars = new java.util.LinkedHashMap<@NonNull String, @NonNull Integer>(((this.bars$key.size() < 0x40000000) ? ((1 + this.bars$key.size()) + ((this.bars$key.size() - 3) / 3)) : java.lang.Integer.MAX_VALUE)); + bars = new java.util.LinkedHashMap<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer>(((this.bars$key.size() < 0x40000000) ? ((1 + this.bars$key.size()) + ((this.bars$key.size() - 3) / 3)) : java.lang.Integer.MAX_VALUE)); for (int $i = 0;; ($i < this.bars$key.size()); $i ++) bars.put(this.bars$key.get($i), this.bars$value.get($i)); bars = java.util.Collections.unmodifiableMap(bars); @@ -92,9 +108,9 @@ import lombok.Singular; return (((((("BuilderSingularAnnotatedTypes.BuilderSingularAnnotatedTypesBuilder(foos=" + this.foos) + ", bars$key=") + this.bars$key) + ", bars$value=") + this.bars$value) + ")"); } } - private @Singular Set<@NonNull String> foos; - private @Singular Map<@NonNull String, @NonNull Integer> bars; - @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypes(final Set<@NonNull String> foos, final Map<@NonNull String, @NonNull Integer> bars) { + private @Singular Set<@MyAnnotation @NonNull String> foos; + private @Singular Map<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer> bars; + @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypes(final Set<@MyAnnotation @NonNull String> foos, final Map<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer> bars) { super(); this.foos = foos; this.bars = bars; @@ -102,4 +118,4 @@ import lombok.Singular; public static @java.lang.SuppressWarnings("all") BuilderSingularAnnotatedTypesBuilder builder() { return new BuilderSingularAnnotatedTypesBuilder(); } -} +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/BuilderSingularGuavaListsSets.java b/test/transform/resource/after-ecj/BuilderSingularGuavaListsSets.java index 12c2b293..9b50d33b 100644 --- a/test/transform/resource/after-ecj/BuilderSingularGuavaListsSets.java +++ b/test/transform/resource/after-ecj/BuilderSingularGuavaListsSets.java @@ -14,13 +14,13 @@ import lombok.Singular; @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder() { super(); } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder card(T card) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder card(final T card) { if ((this.cards == null)) this.cards = com.google.common.collect.ImmutableList.builder(); this.cards.add(card); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder cards(java.lang.Iterable cards) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder cards(final java.lang.Iterable cards) { if ((this.cards == null)) this.cards = com.google.common.collect.ImmutableList.builder(); this.cards.addAll(cards); @@ -30,13 +30,13 @@ import lombok.Singular; this.cards = null; return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder frog(Number frog) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder frog(final Number frog) { if ((this.frogs == null)) this.frogs = com.google.common.collect.ImmutableList.builder(); this.frogs.add(frog); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder frogs(java.lang.Iterable frogs) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder frogs(final java.lang.Iterable frogs) { if ((this.frogs == null)) this.frogs = com.google.common.collect.ImmutableList.builder(); this.frogs.addAll(frogs); @@ -46,13 +46,13 @@ import lombok.Singular; this.frogs = null; return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder rawSet(java.lang.Object rawSet) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder rawSet(final java.lang.Object rawSet) { if ((this.rawSet == null)) this.rawSet = com.google.common.collect.ImmutableSet.builder(); this.rawSet.add(rawSet); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder rawSet(java.lang.Iterable rawSet) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder rawSet(final java.lang.Iterable rawSet) { if ((this.rawSet == null)) this.rawSet = com.google.common.collect.ImmutableSet.builder(); this.rawSet.addAll(rawSet); @@ -62,13 +62,13 @@ import lombok.Singular; this.rawSet = null; return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder pass(String pass) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder pass(final String pass) { if ((this.passes == null)) this.passes = com.google.common.collect.ImmutableSortedSet.naturalOrder(); this.passes.add(pass); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder passes(java.lang.Iterable passes) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder passes(final java.lang.Iterable passes) { if ((this.passes == null)) this.passes = com.google.common.collect.ImmutableSortedSet.naturalOrder(); this.passes.addAll(passes); @@ -78,13 +78,13 @@ import lombok.Singular; this.passes = null; return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder user(Number rowKey, Number columnKey, String value) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder user(final Number rowKey, final Number columnKey, final String value) { if ((this.users == null)) this.users = com.google.common.collect.ImmutableTable.builder(); this.users.put(rowKey, columnKey, value); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder users(com.google.common.collect.Table users) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaListsSetsBuilder users(final com.google.common.collect.Table users) { if ((this.users == null)) this.users = com.google.common.collect.ImmutableTable.builder(); this.users.putAll(users); diff --git a/test/transform/resource/after-ecj/BuilderSingularGuavaMaps.java b/test/transform/resource/after-ecj/BuilderSingularGuavaMaps.java index 44533ac1..1dc04a07 100644 --- a/test/transform/resource/after-ecj/BuilderSingularGuavaMaps.java +++ b/test/transform/resource/after-ecj/BuilderSingularGuavaMaps.java @@ -10,13 +10,13 @@ import lombok.Singular; @java.lang.SuppressWarnings("all") BuilderSingularGuavaMapsBuilder() { super(); } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaMapsBuilder battleaxe(K key, V value) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaMapsBuilder battleaxe(final K key, final V value) { if ((this.battleaxes == null)) this.battleaxes = com.google.common.collect.ImmutableMap.builder(); this.battleaxes.put(key, value); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaMapsBuilder battleaxes(java.util.Map battleaxes) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaMapsBuilder battleaxes(final java.util.Map battleaxes) { if ((this.battleaxes == null)) this.battleaxes = com.google.common.collect.ImmutableMap.builder(); this.battleaxes.putAll(battleaxes); @@ -26,13 +26,13 @@ import lombok.Singular; this.battleaxes = null; return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaMapsBuilder vertex(Integer key, V value) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaMapsBuilder vertex(final Integer key, final V value) { if ((this.vertices == null)) this.vertices = com.google.common.collect.ImmutableSortedMap.naturalOrder(); this.vertices.put(key, value); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaMapsBuilder vertices(java.util.Map vertices) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaMapsBuilder vertices(final java.util.Map vertices) { if ((this.vertices == null)) this.vertices = com.google.common.collect.ImmutableSortedMap.naturalOrder(); this.vertices.putAll(vertices); @@ -42,13 +42,13 @@ import lombok.Singular; this.vertices = null; return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaMapsBuilder rawMap(java.lang.Object key, java.lang.Object value) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaMapsBuilder rawMap(final java.lang.Object key, final java.lang.Object value) { if ((this.rawMap == null)) this.rawMap = com.google.common.collect.ImmutableBiMap.builder(); this.rawMap.put(key, value); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularGuavaMapsBuilder rawMap(java.util.Map rawMap) { + public @java.lang.SuppressWarnings("all") BuilderSingularGuavaMapsBuilder rawMap(final java.util.Map rawMap) { if ((this.rawMap == null)) this.rawMap = com.google.common.collect.ImmutableBiMap.builder(); this.rawMap.putAll(rawMap); diff --git a/test/transform/resource/after-ecj/BuilderSingularLists.java b/test/transform/resource/after-ecj/BuilderSingularLists.java index 3e093e1a..5bb13bad 100644 --- a/test/transform/resource/after-ecj/BuilderSingularLists.java +++ b/test/transform/resource/after-ecj/BuilderSingularLists.java @@ -10,13 +10,13 @@ import lombok.Singular; @java.lang.SuppressWarnings("all") BuilderSingularListsBuilder() { super(); } - public @java.lang.SuppressWarnings("all") BuilderSingularListsBuilder child(T child) { + public @java.lang.SuppressWarnings("all") BuilderSingularListsBuilder child(final T child) { if ((this.children == null)) this.children = new java.util.ArrayList(); this.children.add(child); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularListsBuilder children(java.util.Collection children) { + public @java.lang.SuppressWarnings("all") BuilderSingularListsBuilder children(final java.util.Collection children) { if ((this.children == null)) this.children = new java.util.ArrayList(); this.children.addAll(children); @@ -27,13 +27,13 @@ import lombok.Singular; this.children.clear(); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularListsBuilder scarf(Number scarf) { + public @java.lang.SuppressWarnings("all") BuilderSingularListsBuilder scarf(final Number scarf) { if ((this.scarves == null)) this.scarves = new java.util.ArrayList(); this.scarves.add(scarf); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularListsBuilder scarves(java.util.Collection scarves) { + public @java.lang.SuppressWarnings("all") BuilderSingularListsBuilder scarves(final java.util.Collection scarves) { if ((this.scarves == null)) this.scarves = new java.util.ArrayList(); this.scarves.addAll(scarves); @@ -44,13 +44,13 @@ import lombok.Singular; this.scarves.clear(); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularListsBuilder rawList(java.lang.Object rawList) { + public @java.lang.SuppressWarnings("all") BuilderSingularListsBuilder rawList(final java.lang.Object rawList) { if ((this.rawList == null)) this.rawList = new java.util.ArrayList(); this.rawList.add(rawList); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularListsBuilder rawList(java.util.Collection rawList) { + public @java.lang.SuppressWarnings("all") BuilderSingularListsBuilder rawList(final java.util.Collection rawList) { if ((this.rawList == null)) this.rawList = new java.util.ArrayList(); this.rawList.addAll(rawList); diff --git a/test/transform/resource/after-ecj/BuilderSingularMaps.java b/test/transform/resource/after-ecj/BuilderSingularMaps.java index efcf5ef5..20945a13 100644 --- a/test/transform/resource/after-ecj/BuilderSingularMaps.java +++ b/test/transform/resource/after-ecj/BuilderSingularMaps.java @@ -14,7 +14,7 @@ import lombok.Singular; @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder() { super(); } - public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder woman(K womanKey, V womanValue) { + public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder woman(final K womanKey, final V womanValue) { if ((this.women$key == null)) { this.women$key = new java.util.ArrayList(); @@ -24,7 +24,7 @@ import lombok.Singular; this.women$value.add(womanValue); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder women(java.util.Map women) { + public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder women(final java.util.Map women) { if ((this.women$key == null)) { this.women$key = new java.util.ArrayList(); @@ -45,7 +45,7 @@ import lombok.Singular; } return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder man(K manKey, Number manValue) { + public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder man(final K manKey, final Number manValue) { if ((this.men$key == null)) { this.men$key = new java.util.ArrayList(); @@ -55,7 +55,7 @@ import lombok.Singular; this.men$value.add(manValue); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder men(java.util.Map men) { + public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder men(final java.util.Map men) { if ((this.men$key == null)) { this.men$key = new java.util.ArrayList(); @@ -76,7 +76,7 @@ import lombok.Singular; } return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder rawMap(java.lang.Object rawMapKey, java.lang.Object rawMapValue) { + public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder rawMap(final java.lang.Object rawMapKey, final java.lang.Object rawMapValue) { if ((this.rawMap$key == null)) { this.rawMap$key = new java.util.ArrayList(); @@ -86,7 +86,7 @@ import lombok.Singular; this.rawMap$value.add(rawMapValue); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder rawMap(java.util.Map rawMap) { + public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder rawMap(final java.util.Map rawMap) { if ((this.rawMap$key == null)) { this.rawMap$key = new java.util.ArrayList(); @@ -107,7 +107,7 @@ import lombok.Singular; } return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder stringMap(String stringMapKey, V stringMapValue) { + public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder stringMap(final String stringMapKey, final V stringMapValue) { if ((this.stringMap$key == null)) { this.stringMap$key = new java.util.ArrayList(); @@ -117,7 +117,7 @@ import lombok.Singular; this.stringMap$value.add(stringMapValue); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder stringMap(java.util.Map stringMap) { + public @java.lang.SuppressWarnings("all") BuilderSingularMapsBuilder stringMap(final java.util.Map stringMap) { if ((this.stringMap$key == null)) { this.stringMap$key = new java.util.ArrayList(); diff --git a/test/transform/resource/after-ecj/BuilderSingularNoAuto.java b/test/transform/resource/after-ecj/BuilderSingularNoAuto.java index fa38efc3..4d27f459 100644 --- a/test/transform/resource/after-ecj/BuilderSingularNoAuto.java +++ b/test/transform/resource/after-ecj/BuilderSingularNoAuto.java @@ -8,13 +8,13 @@ import lombok.Singular; @java.lang.SuppressWarnings("all") BuilderSingularNoAutoBuilder() { super(); } - public @java.lang.SuppressWarnings("all") BuilderSingularNoAutoBuilder things(String things) { + public @java.lang.SuppressWarnings("all") BuilderSingularNoAutoBuilder things(final String things) { if ((this.things == null)) this.things = new java.util.ArrayList(); this.things.add(things); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularNoAutoBuilder things(java.util.Collection things) { + public @java.lang.SuppressWarnings("all") BuilderSingularNoAutoBuilder things(final java.util.Collection things) { if ((this.things == null)) this.things = new java.util.ArrayList(); this.things.addAll(things); @@ -25,13 +25,13 @@ import lombok.Singular; this.things.clear(); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularNoAutoBuilder widget(String widget) { + public @java.lang.SuppressWarnings("all") BuilderSingularNoAutoBuilder widget(final String widget) { if ((this.widgets == null)) this.widgets = new java.util.ArrayList(); this.widgets.add(widget); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularNoAutoBuilder widgets(java.util.Collection widgets) { + public @java.lang.SuppressWarnings("all") BuilderSingularNoAutoBuilder widgets(final java.util.Collection widgets) { if ((this.widgets == null)) this.widgets = new java.util.ArrayList(); this.widgets.addAll(widgets); @@ -42,13 +42,13 @@ import lombok.Singular; this.widgets.clear(); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularNoAutoBuilder items(String items) { + public @java.lang.SuppressWarnings("all") BuilderSingularNoAutoBuilder items(final String items) { if ((this.items == null)) this.items = new java.util.ArrayList(); this.items.add(items); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularNoAutoBuilder items(java.util.Collection items) { + public @java.lang.SuppressWarnings("all") BuilderSingularNoAutoBuilder items(final java.util.Collection items) { if ((this.items == null)) this.items = new java.util.ArrayList(); this.items.addAll(items); diff --git a/test/transform/resource/after-ecj/BuilderSingularRedirectToGuava.java b/test/transform/resource/after-ecj/BuilderSingularRedirectToGuava.java index 4823e46e..c0f78b57 100644 --- a/test/transform/resource/after-ecj/BuilderSingularRedirectToGuava.java +++ b/test/transform/resource/after-ecj/BuilderSingularRedirectToGuava.java @@ -10,13 +10,13 @@ import lombok.Singular; @java.lang.SuppressWarnings("all") BuilderSingularRedirectToGuavaBuilder() { super(); } - public @java.lang.SuppressWarnings("all") BuilderSingularRedirectToGuavaBuilder dangerMouse(String dangerMouse) { + public @java.lang.SuppressWarnings("all") BuilderSingularRedirectToGuavaBuilder dangerMouse(final String dangerMouse) { if ((this.dangerMice == null)) this.dangerMice = com.google.common.collect.ImmutableSet.builder(); this.dangerMice.add(dangerMouse); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularRedirectToGuavaBuilder dangerMice(java.lang.Iterable dangerMice) { + public @java.lang.SuppressWarnings("all") BuilderSingularRedirectToGuavaBuilder dangerMice(final java.lang.Iterable dangerMice) { if ((this.dangerMice == null)) this.dangerMice = com.google.common.collect.ImmutableSet.builder(); this.dangerMice.addAll(dangerMice); @@ -26,13 +26,13 @@ import lombok.Singular; this.dangerMice = null; return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularRedirectToGuavaBuilder thing(Integer key, Number value) { + public @java.lang.SuppressWarnings("all") BuilderSingularRedirectToGuavaBuilder thing(final Integer key, final Number value) { if ((this.things == null)) this.things = com.google.common.collect.ImmutableSortedMap.naturalOrder(); this.things.put(key, value); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularRedirectToGuavaBuilder things(java.util.Map things) { + public @java.lang.SuppressWarnings("all") BuilderSingularRedirectToGuavaBuilder things(final java.util.Map things) { if ((this.things == null)) this.things = com.google.common.collect.ImmutableSortedMap.naturalOrder(); this.things.putAll(things); @@ -42,13 +42,13 @@ import lombok.Singular; this.things = null; return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularRedirectToGuavaBuilder doohickey(Class doohickey) { + public @java.lang.SuppressWarnings("all") BuilderSingularRedirectToGuavaBuilder doohickey(final Class doohickey) { if ((this.doohickeys == null)) this.doohickeys = com.google.common.collect.ImmutableList.builder(); this.doohickeys.add(doohickey); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularRedirectToGuavaBuilder doohickeys(java.lang.Iterable> doohickeys) { + public @java.lang.SuppressWarnings("all") BuilderSingularRedirectToGuavaBuilder doohickeys(final java.lang.Iterable> doohickeys) { if ((this.doohickeys == null)) this.doohickeys = com.google.common.collect.ImmutableList.builder(); this.doohickeys.addAll(doohickeys); diff --git a/test/transform/resource/after-ecj/BuilderSingularSets.java b/test/transform/resource/after-ecj/BuilderSingularSets.java index bf403831..eb53b1cd 100644 --- a/test/transform/resource/after-ecj/BuilderSingularSets.java +++ b/test/transform/resource/after-ecj/BuilderSingularSets.java @@ -10,13 +10,13 @@ import lombok.Singular; @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder() { super(); } - public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder dangerMouse(T dangerMouse) { + public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder dangerMouse(final T dangerMouse) { if ((this.dangerMice == null)) this.dangerMice = new java.util.ArrayList(); this.dangerMice.add(dangerMouse); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder dangerMice(java.util.Collection dangerMice) { + public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder dangerMice(final java.util.Collection dangerMice) { if ((this.dangerMice == null)) this.dangerMice = new java.util.ArrayList(); this.dangerMice.addAll(dangerMice); @@ -27,13 +27,13 @@ import lombok.Singular; this.dangerMice.clear(); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder octopus(Number octopus) { + public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder octopus(final Number octopus) { if ((this.octopodes == null)) this.octopodes = new java.util.ArrayList(); this.octopodes.add(octopus); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder octopodes(java.util.Collection octopodes) { + public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder octopodes(final java.util.Collection octopodes) { if ((this.octopodes == null)) this.octopodes = new java.util.ArrayList(); this.octopodes.addAll(octopodes); @@ -44,13 +44,13 @@ import lombok.Singular; this.octopodes.clear(); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder rawSet(java.lang.Object rawSet) { + public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder rawSet(final java.lang.Object rawSet) { if ((this.rawSet == null)) this.rawSet = new java.util.ArrayList(); this.rawSet.add(rawSet); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder rawSet(java.util.Collection rawSet) { + public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder rawSet(final java.util.Collection rawSet) { if ((this.rawSet == null)) this.rawSet = new java.util.ArrayList(); this.rawSet.addAll(rawSet); @@ -61,13 +61,13 @@ import lombok.Singular; this.rawSet.clear(); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder stringSet(String stringSet) { + public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder stringSet(final String stringSet) { if ((this.stringSet == null)) this.stringSet = new java.util.ArrayList(); this.stringSet.add(stringSet); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder stringSet(java.util.Collection stringSet) { + public @java.lang.SuppressWarnings("all") BuilderSingularSetsBuilder stringSet(final java.util.Collection stringSet) { if ((this.stringSet == null)) this.stringSet = new java.util.ArrayList(); this.stringSet.addAll(stringSet); diff --git a/test/transform/resource/after-ecj/BuilderSingularToBuilderWithNull.java b/test/transform/resource/after-ecj/BuilderSingularToBuilderWithNull.java index 7feff6e9..bbbf9268 100644 --- a/test/transform/resource/after-ecj/BuilderSingularToBuilderWithNull.java +++ b/test/transform/resource/after-ecj/BuilderSingularToBuilderWithNull.java @@ -5,13 +5,13 @@ import lombok.Singular; @java.lang.SuppressWarnings("all") BuilderSingularToBuilderWithNullBuilder() { super(); } - public @java.lang.SuppressWarnings("all") BuilderSingularToBuilderWithNullBuilder elem(String elem) { + public @java.lang.SuppressWarnings("all") BuilderSingularToBuilderWithNullBuilder elem(final String elem) { if ((this.elems == null)) this.elems = new java.util.ArrayList(); this.elems.add(elem); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularToBuilderWithNullBuilder elems(java.util.Collection elems) { + public @java.lang.SuppressWarnings("all") BuilderSingularToBuilderWithNullBuilder elems(final java.util.Collection elems) { if ((this.elems == null)) this.elems = new java.util.ArrayList(); this.elems.addAll(elems); diff --git a/test/transform/resource/after-ecj/BuilderSingularWithPrefixes.java b/test/transform/resource/after-ecj/BuilderSingularWithPrefixes.java index 12c299c6..31579497 100644 --- a/test/transform/resource/after-ecj/BuilderSingularWithPrefixes.java +++ b/test/transform/resource/after-ecj/BuilderSingularWithPrefixes.java @@ -5,13 +5,13 @@ import lombok.Singular; @java.lang.SuppressWarnings("all") BuilderSingularWithPrefixesBuilder() { super(); } - public @java.lang.SuppressWarnings("all") BuilderSingularWithPrefixesBuilder elem(String elem) { + public @java.lang.SuppressWarnings("all") BuilderSingularWithPrefixesBuilder elem(final String elem) { if ((this.elems == null)) this.elems = new java.util.ArrayList(); this.elems.add(elem); return this; } - public @java.lang.SuppressWarnings("all") BuilderSingularWithPrefixesBuilder elems(java.util.Collection elems) { + public @java.lang.SuppressWarnings("all") BuilderSingularWithPrefixesBuilder elems(final java.util.Collection elems) { if ((this.elems == null)) this.elems = new java.util.ArrayList(); this.elems.addAll(elems); diff --git a/test/transform/resource/after-ecj/BuilderWithDeprecated.java b/test/transform/resource/after-ecj/BuilderWithDeprecated.java index 09a0b786..b429c3e7 100644 --- a/test/transform/resource/after-ecj/BuilderWithDeprecated.java +++ b/test/transform/resource/after-ecj/BuilderWithDeprecated.java @@ -18,13 +18,13 @@ public @Builder class BuilderWithDeprecated { this.dep2 = dep2; return this; } - public @java.lang.Deprecated @java.lang.SuppressWarnings("all") BuilderWithDeprecatedBuilder string(String string) { + public @java.lang.Deprecated @java.lang.SuppressWarnings("all") BuilderWithDeprecatedBuilder string(final String string) { if ((this.strings == null)) this.strings = new java.util.ArrayList(); this.strings.add(string); return this; } - public @java.lang.Deprecated @java.lang.SuppressWarnings("all") BuilderWithDeprecatedBuilder strings(java.util.Collection strings) { + public @java.lang.Deprecated @java.lang.SuppressWarnings("all") BuilderWithDeprecatedBuilder strings(final java.util.Collection strings) { if ((this.strings == null)) this.strings = new java.util.ArrayList(); this.strings.addAll(strings); @@ -35,13 +35,13 @@ public @Builder class BuilderWithDeprecated { this.strings.clear(); return this; } - public @java.lang.Deprecated @java.lang.SuppressWarnings("all") BuilderWithDeprecatedBuilder number(Integer number) { + public @java.lang.Deprecated @java.lang.SuppressWarnings("all") BuilderWithDeprecatedBuilder number(final Integer number) { if ((this.numbers == null)) this.numbers = com.google.common.collect.ImmutableList.builder(); this.numbers.add(number); return this; } - public @java.lang.Deprecated @java.lang.SuppressWarnings("all") BuilderWithDeprecatedBuilder numbers(java.lang.Iterable numbers) { + public @java.lang.Deprecated @java.lang.SuppressWarnings("all") BuilderWithDeprecatedBuilder numbers(final java.lang.Iterable numbers) { if ((this.numbers == null)) this.numbers = com.google.common.collect.ImmutableList.builder(); this.numbers.addAll(numbers); diff --git a/test/transform/resource/after-ecj/BuilderWithToBuilder.java b/test/transform/resource/after-ecj/BuilderWithToBuilder.java index a8935107..636dc42d 100644 --- a/test/transform/resource/after-ecj/BuilderWithToBuilder.java +++ b/test/transform/resource/after-ecj/BuilderWithToBuilder.java @@ -21,13 +21,13 @@ import lombok.Builder; this.foo = foo; return this; } - public @java.lang.SuppressWarnings("all") BuilderWithToBuilderBuilder bar(T bar) { + public @java.lang.SuppressWarnings("all") BuilderWithToBuilderBuilder bar(final T bar) { if ((this.bars == null)) this.bars = new java.util.ArrayList(); this.bars.add(bar); return this; } - public @java.lang.SuppressWarnings("all") BuilderWithToBuilderBuilder bars(java.util.Collection bars) { + public @java.lang.SuppressWarnings("all") BuilderWithToBuilderBuilder bars(final java.util.Collection bars) { if ((this.bars == null)) this.bars = new java.util.ArrayList(); this.bars.addAll(bars); diff --git a/test/transform/resource/after-ecj/SuperBuilderBasic.java b/test/transform/resource/after-ecj/SuperBuilderBasic.java index 11fd8498..95cf5f01 100644 --- a/test/transform/resource/after-ecj/SuperBuilderBasic.java +++ b/test/transform/resource/after-ecj/SuperBuilderBasic.java @@ -13,13 +13,13 @@ public class SuperBuilderBasic { this.field1 = field1; return self(); } - public @java.lang.SuppressWarnings("all") B item(String item) { + public @java.lang.SuppressWarnings("all") B item(final String item) { if ((this.items == null)) this.items = new java.util.ArrayList(); this.items.add(item); return self(); } - public @java.lang.SuppressWarnings("all") B items(java.util.Collection items) { + public @java.lang.SuppressWarnings("all") B items(final java.util.Collection items) { if ((this.items == null)) this.items = new java.util.ArrayList(); this.items.addAll(items); diff --git a/test/transform/resource/after-ecj/SuperBuilderSingularAnnotatedTypes.java b/test/transform/resource/after-ecj/SuperBuilderSingularAnnotatedTypes.java new file mode 100644 index 00000000..bb02024d --- /dev/null +++ b/test/transform/resource/after-ecj/SuperBuilderSingularAnnotatedTypes.java @@ -0,0 +1,131 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.Set; +import java.util.Map; +import lombok.NonNull; +import lombok.Singular; +@Target(ElementType.TYPE_USE) @interface MyAnnotation { +} +@lombok.experimental.SuperBuilder class SuperBuilderSingularAnnotatedTypes { + public static abstract @java.lang.SuppressWarnings("all") class SuperBuilderSingularAnnotatedTypesBuilder> { + private @java.lang.SuppressWarnings("all") java.util.ArrayList<@MyAnnotation @NonNull String> foos; + private @java.lang.SuppressWarnings("all") java.util.ArrayList<@MyAnnotation @NonNull String> bars$key; + private @java.lang.SuppressWarnings("all") java.util.ArrayList<@MyAnnotation @NonNull Integer> bars$value; + public SuperBuilderSingularAnnotatedTypesBuilder() { + super(); + } + protected abstract @java.lang.SuppressWarnings("all") B self(); + public abstract @java.lang.SuppressWarnings("all") C build(); + public @java.lang.SuppressWarnings("all") B foo(final @MyAnnotation @NonNull String foo) { + if ((foo == null)) + { + throw new java.lang.NullPointerException("foo is marked @NonNull but is null"); + } + if ((this.foos == null)) + this.foos = new java.util.ArrayList<@MyAnnotation @NonNull String>(); + this.foos.add(foo); + return self(); + } + public @java.lang.SuppressWarnings("all") B foos(final java.util.Collection foos) { + if ((this.foos == null)) + this.foos = new java.util.ArrayList<@MyAnnotation @NonNull String>(); + this.foos.addAll(foos); + return self(); + } + public @java.lang.SuppressWarnings("all") B clearFoos() { + if ((this.foos != null)) + this.foos.clear(); + return self(); + } + public @java.lang.SuppressWarnings("all") B bar(final @MyAnnotation @NonNull String barKey, final @MyAnnotation @NonNull Integer barValue) { + if ((barKey == null)) + { + throw new java.lang.NullPointerException("barKey is marked @NonNull but is null"); + } + if ((barValue == null)) + { + throw new java.lang.NullPointerException("barValue is marked @NonNull but is null"); + } + if ((this.bars$key == null)) + { + this.bars$key = new java.util.ArrayList<@MyAnnotation @NonNull String>(); + this.bars$value = new java.util.ArrayList<@MyAnnotation @NonNull Integer>(); + } + this.bars$key.add(barKey); + this.bars$value.add(barValue); + return self(); + } + public @java.lang.SuppressWarnings("all") B bars(final java.util.Map bars) { + if ((this.bars$key == null)) + { + this.bars$key = new java.util.ArrayList<@MyAnnotation @NonNull String>(); + this.bars$value = new java.util.ArrayList<@MyAnnotation @NonNull Integer>(); + } + for (java.util.Map.Entry $lombokEntry : bars.entrySet()) + { + this.bars$key.add($lombokEntry.getKey()); + this.bars$value.add($lombokEntry.getValue()); + } + return self(); + } + public @java.lang.SuppressWarnings("all") B clearBars() { + if ((this.bars$key != null)) + { + this.bars$key.clear(); + this.bars$value.clear(); + } + return self(); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (((((("SuperBuilderSingularAnnotatedTypes.SuperBuilderSingularAnnotatedTypesBuilder(foos=" + this.foos) + ", bars$key=") + this.bars$key) + ", bars$value=") + this.bars$value) + ")"); + } + } + private static final @java.lang.SuppressWarnings("all") class SuperBuilderSingularAnnotatedTypesBuilderImpl extends SuperBuilderSingularAnnotatedTypesBuilder { + private SuperBuilderSingularAnnotatedTypesBuilderImpl() { + super(); + } + protected @java.lang.Override @java.lang.SuppressWarnings("all") SuperBuilderSingularAnnotatedTypesBuilderImpl self() { + return this; + } + public @java.lang.Override @java.lang.SuppressWarnings("all") SuperBuilderSingularAnnotatedTypes build() { + return new SuperBuilderSingularAnnotatedTypes(this); + } + } + private @Singular Set<@MyAnnotation @NonNull String> foos; + private @Singular Map<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer> bars; + protected @java.lang.SuppressWarnings("all") SuperBuilderSingularAnnotatedTypes(final SuperBuilderSingularAnnotatedTypesBuilder b) { + super(); + java.util.Set<@MyAnnotation @NonNull String> foos; + switch (((b.foos == null) ? 0 : b.foos.size())) { + case 0 : + foos = java.util.Collections.emptySet(); + break; + case 1 : + foos = java.util.Collections.singleton(b.foos.get(0)); + break; + default : + foos = new java.util.LinkedHashSet<@MyAnnotation @NonNull String>(((b.foos.size() < 0x40000000) ? ((1 + b.foos.size()) + ((b.foos.size() - 3) / 3)) : java.lang.Integer.MAX_VALUE)); + foos.addAll(b.foos); + foos = java.util.Collections.unmodifiableSet(foos); + } + this.foos = foos; + java.util.Map<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer> bars; + switch (((b.bars$key == null) ? 0 : b.bars$key.size())) { + case 0 : + bars = java.util.Collections.emptyMap(); + break; + case 1 : + bars = java.util.Collections.singletonMap(b.bars$key.get(0), b.bars$value.get(0)); + break; + default : + bars = new java.util.LinkedHashMap<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer>(((b.bars$key.size() < 0x40000000) ? ((1 + b.bars$key.size()) + ((b.bars$key.size() - 3) / 3)) : java.lang.Integer.MAX_VALUE)); + for (int $i = 0;; ($i < b.bars$key.size()); $i ++) + bars.put(b.bars$key.get($i), b.bars$value.get($i)); + bars = java.util.Collections.unmodifiableMap(bars); + } + this.bars = bars; + } + public static @java.lang.SuppressWarnings("all") SuperBuilderSingularAnnotatedTypesBuilder builder() { + return new SuperBuilderSingularAnnotatedTypesBuilderImpl(); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/SuperBuilderWithCustomBuilderMethod.java b/test/transform/resource/after-ecj/SuperBuilderWithCustomBuilderMethod.java index ed0655c7..0ec8921d 100644 --- a/test/transform/resource/after-ecj/SuperBuilderWithCustomBuilderMethod.java +++ b/test/transform/resource/after-ecj/SuperBuilderWithCustomBuilderMethod.java @@ -13,13 +13,13 @@ public class SuperBuilderWithCustomBuilderMethod { this.field1 = field1; return self(); } - public @java.lang.SuppressWarnings("all") B item(String item) { + public @java.lang.SuppressWarnings("all") B item(final String item) { if ((this.items == null)) this.items = new java.util.ArrayList(); this.items.add(item); return self(); } - public @java.lang.SuppressWarnings("all") B items(java.util.Collection items) { + public @java.lang.SuppressWarnings("all") B items(final java.util.Collection items) { if ((this.items == null)) this.items = new java.util.ArrayList(); this.items.addAll(items); diff --git a/test/transform/resource/after-ecj/SuperBuilderWithGenerics.java b/test/transform/resource/after-ecj/SuperBuilderWithGenerics.java index 0166e375..465704bb 100644 --- a/test/transform/resource/after-ecj/SuperBuilderWithGenerics.java +++ b/test/transform/resource/after-ecj/SuperBuilderWithGenerics.java @@ -13,13 +13,13 @@ public class SuperBuilderWithGenerics { this.field1 = field1; return self(); } - public @java.lang.SuppressWarnings("all") B item(String item) { + public @java.lang.SuppressWarnings("all") B item(final String item) { if ((this.items == null)) this.items = new java.util.ArrayList(); this.items.add(item); return self(); } - public @java.lang.SuppressWarnings("all") B items(java.util.Collection items) { + public @java.lang.SuppressWarnings("all") B items(final java.util.Collection items) { if ((this.items == null)) this.items = new java.util.ArrayList(); this.items.addAll(items); diff --git a/test/transform/resource/after-ecj/SuperBuilderWithGenerics2.java b/test/transform/resource/after-ecj/SuperBuilderWithGenerics2.java index 28b026ea..8429ee35 100644 --- a/test/transform/resource/after-ecj/SuperBuilderWithGenerics2.java +++ b/test/transform/resource/after-ecj/SuperBuilderWithGenerics2.java @@ -13,13 +13,13 @@ public class SuperBuilderWithGenerics2 { this.field1 = field1; return self(); } - public @java.lang.SuppressWarnings("all") B item(String item) { + public @java.lang.SuppressWarnings("all") B item(final String item) { if ((this.items == null)) this.items = new java.util.ArrayList(); this.items.add(item); return self(); } - public @java.lang.SuppressWarnings("all") B items(java.util.Collection items) { + public @java.lang.SuppressWarnings("all") B items(final java.util.Collection items) { if ((this.items == null)) this.items = new java.util.ArrayList(); this.items.addAll(items); diff --git a/test/transform/resource/after-ecj/SuperBuilderWithNonNull.java b/test/transform/resource/after-ecj/SuperBuilderWithNonNull.java index 106b8326..1c4bd53d 100644 --- a/test/transform/resource/after-ecj/SuperBuilderWithNonNull.java +++ b/test/transform/resource/after-ecj/SuperBuilderWithNonNull.java @@ -9,7 +9,7 @@ public class SuperBuilderWithNonNull { } protected abstract @java.lang.SuppressWarnings("all") B self(); public abstract @java.lang.SuppressWarnings("all") C build(); - public @java.lang.SuppressWarnings("all") B nonNullParentField(final String nonNullParentField) { + public @java.lang.SuppressWarnings("all") B nonNullParentField(final @lombok.NonNull String nonNullParentField) { this.nonNullParentField = nonNullParentField; nonNullParentField$set = true; return self(); @@ -56,7 +56,7 @@ public class SuperBuilderWithNonNull { } protected abstract @java.lang.Override @java.lang.SuppressWarnings("all") B self(); public abstract @java.lang.Override @java.lang.SuppressWarnings("all") C build(); - public @java.lang.SuppressWarnings("all") B nonNullChildField(final String nonNullChildField) { + public @java.lang.SuppressWarnings("all") B nonNullChildField(final @lombok.NonNull String nonNullChildField) { this.nonNullChildField = nonNullChildField; return self(); } diff --git a/test/transform/resource/after-ecj/SuperBuilderWithPrefixes.java b/test/transform/resource/after-ecj/SuperBuilderWithPrefixes.java index 33400b3c..5dbdfacc 100644 --- a/test/transform/resource/after-ecj/SuperBuilderWithPrefixes.java +++ b/test/transform/resource/after-ecj/SuperBuilderWithPrefixes.java @@ -16,13 +16,13 @@ this.otherField = otherField; return self(); } - public @java.lang.SuppressWarnings("all") B item(String item) { + public @java.lang.SuppressWarnings("all") B item(final String item) { if ((this.items == null)) this.items = new java.util.ArrayList(); this.items.add(item); return self(); } - public @java.lang.SuppressWarnings("all") B items(java.util.Collection items) { + public @java.lang.SuppressWarnings("all") B items(final java.util.Collection items) { if ((this.items == null)) this.items = new java.util.ArrayList(); this.items.addAll(items); diff --git a/test/transform/resource/before/BuilderSingularAnnotatedTypes.java b/test/transform/resource/before/BuilderSingularAnnotatedTypes.java index 163507b9..d54fed8d 100644 --- a/test/transform/resource/before/BuilderSingularAnnotatedTypes.java +++ b/test/transform/resource/before/BuilderSingularAnnotatedTypes.java @@ -1,12 +1,14 @@ //VERSION 8: +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; import java.util.Set; import java.util.Map; - import lombok.NonNull; import lombok.Singular; - +@Target(ElementType.TYPE_USE) +@interface MyAnnotation {} @lombok.Builder class BuilderSingularAnnotatedTypes { - @Singular private Set<@NonNull String> foos; - @Singular private Map<@NonNull String, @NonNull Integer> bars; + @Singular private Set<@MyAnnotation @NonNull String> foos; + @Singular private Map<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer> bars; } diff --git a/test/transform/resource/before/SuperBuilderSingularAnnotatedTypes.java b/test/transform/resource/before/SuperBuilderSingularAnnotatedTypes.java new file mode 100644 index 00000000..d26352d2 --- /dev/null +++ b/test/transform/resource/before/SuperBuilderSingularAnnotatedTypes.java @@ -0,0 +1,14 @@ +//VERSION 8: +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.Set; +import java.util.Map; +import lombok.NonNull; +import lombok.Singular; +@Target(ElementType.TYPE_USE) +@interface MyAnnotation {} +@lombok.experimental.SuperBuilder +class SuperBuilderSingularAnnotatedTypes { + @Singular private Set<@MyAnnotation @NonNull String> foos; + @Singular private Map<@MyAnnotation @NonNull String, @MyAnnotation @NonNull Integer> bars; +} -- cgit From aee4e76d864e01b5d453409e703ad54852fa57bb Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Tue, 18 Sep 2018 01:40:32 +0200 Subject: updated docs to reflect change to copyable annotations --- website/templates/features/Builder.html | 2 ++ website/templates/features/Data.html | 2 +- website/templates/features/GetterSetter.html | 4 +++- website/templates/features/Value.html | 2 ++ website/templates/features/constructor.html | 2 ++ website/templates/features/experimental/SuperBuilder.html | 2 ++ website/templates/features/experimental/Wither.html | 2 +- 7 files changed, 13 insertions(+), 3 deletions(-) diff --git a/website/templates/features/Builder.html b/website/templates/features/Builder.html index bc03749e..793c7b54 100644 --- a/website/templates/features/Builder.html +++ b/website/templates/features/Builder.html @@ -181,6 +181,8 @@ public class JacksonExample { With toBuilder = true applied to methods, any type parameter of the annotated method itself must also show up in the return type.

The initializer on a @Builder.Default field is removed and stored in a static method, in order to guarantee that this initializer won't be executed at all if a value is specified in the build. This does mean the initializer cannot refer to this, super or any non-static member. If lombok generates a constructor for you, it'll also initialize this field with the initializer. +

+ Various well known annotations about nullity cause null checks to be inserted and will be copied to parameter of the builder's 'setter' method. See Getter/Setter documentation's small print for more information.

diff --git a/website/templates/features/Data.html b/website/templates/features/Data.html index 59370cc8..36278819 100644 --- a/website/templates/features/Data.html +++ b/website/templates/features/Data.html @@ -33,7 +33,7 @@

See the small print of @ToString, @EqualsAndHashCode, @Getter / @Setter and @RequiredArgsConstructor.

- Any annotations named @NonNull (case insensitive) on a field are interpreted as: This field must not ever hold null. Therefore, these annotations result in an explicit null check in the generated constructor for the provided field. Also, these annotations (as well as any annotation named @Nullable) are copied to the constructor parameter, in both the true constructor and any static constructor. The same principle applies to generated getters and setters (see the documentation for @Getter / @Setter) + Various well known annotations about nullity cause null checks to be inserted and will be copied to the relevant places (such as the method for getters, and the parameter for the constructor and setters). See Getter/Setter documentation's small print for more information.

By default, any variables that start with a $ symbol are excluded automatically. You can include them by specifying an explicit annotation (@Getter or @ToString, for example) and using the 'of' parameter.

diff --git a/website/templates/features/GetterSetter.html b/website/templates/features/GetterSetter.html index 1baa5bd0..04cd1ec7 100644 --- a/website/templates/features/GetterSetter.html +++ b/website/templates/features/GetterSetter.html @@ -58,7 +58,9 @@

Any variation on boolean will not result in using the is prefix instead of the get prefix; for example, returning java.lang.Boolean results in a get prefix, not an is prefix.

- Any annotations named @NonNull (case insensitive) on the field are interpreted as: This field must not ever hold null. Therefore, these annotations result in an explicit null check in the generated setter. Also, these annotations (as well as any annotation named @Nullable or @CheckForNull) are copied to setter parameter and getter method. + A number of annotations from popular libraries that indicate non-nullness, such as javax.annotation.Nonnull, if present on the field, result in an explicit null check in the generated setter. +

+ Various well-known annotations about nullability, such as org.eclipse.jdt.annotation.NonNull, are automatically copied over to the right place (method for getters, parameter for setters). You can specify additional annotations that should always be copied via lombok configuration key lombok.copyableAnnotations.

You can annotate a class with a @Getter or @Setter annotation. Doing so is equivalent to annotating all non-static fields in that class with that annotation. @Getter/@Setter annotations on fields take precedence over the ones on classes.

diff --git a/website/templates/features/Value.html b/website/templates/features/Value.html index fdad0e12..5fe188b3 100644 --- a/website/templates/features/Value.html +++ b/website/templates/features/Value.html @@ -41,6 +41,8 @@ Look for the documentation on the 'parts' of @Value: @ToString, @EqualsAndHashCode, @AllArgsConstructor, @FieldDefaults, and @Getter.

For classes with generics, it's useful to have a static method which serves as a constructor, because inference of generic parameters via static methods works in java6 and avoids having to use the diamond operator. While you can force this by applying an explicit @AllArgsConstructor(staticConstructor="of") annotation, there's also the @Value(staticConstructor="of") feature, which will make the generated all-arguments constructor private, and generates a public static method named of which is a wrapper around this private constructor. +

+ Various well known annotations about nullity cause null checks to be inserted and will be copied to the relevant places (such as the method for getters, and the parameter for the constructor and setters). See Getter/Setter documentation's small print for more information.

@Value was an experimental feature from v0.11.4 to v0.11.9 (as @lombok.experimental.Value). It has since been moved into the core package. The old annotation is still around (and is an alias). It will eventually be removed in a future version, though.

diff --git a/website/templates/features/constructor.html b/website/templates/features/constructor.html index 716efe5a..fc0be1c6 100644 --- a/website/templates/features/constructor.html +++ b/website/templates/features/constructor.html @@ -50,6 +50,8 @@ @XArgsConstructor can also be used on an enum definition. The generated constructor will always be private, because non-private constructors aren't legal in enums. You don't have to specify AccessLevel.PRIVATE.

While suppressConstructorProperties has been marked deprecated in anticipation of a world where all java environments have the @ConstructorProperties annotation available, first GWT 2.2 and Android 2.3.3, which do not (yet) have this annotation, will have to be ancient history before this annotation parameter will be removed. +

+ Various well known annotations about nullity cause null checks to be inserted and will be copied to the parameter. See Getter/Setter documentation's small print for more information.

The flagUsage configuration keys do not trigger when a constructor is generated by @Data, @Value or any other lombok annotation.

diff --git a/website/templates/features/experimental/SuperBuilder.html b/website/templates/features/experimental/SuperBuilder.html index 9b49bc83..8189a254 100644 --- a/website/templates/features/experimental/SuperBuilder.html +++ b/website/templates/features/experimental/SuperBuilder.html @@ -63,6 +63,8 @@ An ArrayList is used to store added elements as call methods of a @Singular marked field, if the target collection is from the java.util package, even if the collection is a set or map. Because lombok ensures that generated collections are compacted, a new backing instance of a set or map must be constructed anyway, and storing the data as an ArrayList during the build process is more efficient that storing it as a map or set. This behaviour is not externally visible, an implementation detail of the current implementation of the java.util recipes for @Singular.

The generated builder code heavily relies on generics to avoid class casting when using the builder. +

+ Various well known annotations about nullity cause null checks to be inserted and will be copied to parameter of the builder's 'setter' method. See Getter/Setter documentation's small print for more information.

diff --git a/website/templates/features/experimental/Wither.html b/website/templates/features/experimental/Wither.html index 9642458b..00dc10b1 100644 --- a/website/templates/features/experimental/Wither.html +++ b/website/templates/features/experimental/Wither.html @@ -60,7 +60,7 @@

For boolean fields that start with is immediately followed by a title-case letter, nothing is prefixed to generate the wither name.

- Any annotations named @NonNull (case insensitive) on the field are interpreted as: This field must not ever hold null. Therefore, these annotations result in an explicit null check in the generated wither. Also, these annotations (as well as any annotation named @Nullable or @CheckForNull) are copied to wither parameter. + Various well known annotations about nullity cause null checks to be inserted and will be copied to the parameter. See Getter/Setter documentation's small print for more information.

-- cgit