From 1b06f4aa2960ba18d26a4d0218dd486872176971 Mon Sep 17 00:00:00 2001 From: Jan Rieke Date: Thu, 26 Mar 2020 00:32:51 +0100 Subject: [SuperBuilder] fix IndexOutOfBounds (fixes #2407) --- src/core/lombok/eclipse/handlers/HandleSuperBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java index 82af39fa..436cc6a0 100644 --- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java @@ -242,7 +242,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { String superclassBuilderClassName = builderClassNameTemplate.replace("*", superclassClassName); char[][] tokens = Arrays.copyOf(qualifiedTypeReference.tokens, qualifiedTypeReference.tokens.length + 1); - tokens[tokens.length] = superclassBuilderClassName.toCharArray(); + tokens[tokens.length-1] = superclassBuilderClassName.toCharArray(); long[] poss = new long[tokens.length]; Arrays.fill(poss, p); -- cgit From d34fdeb3b4b44aae8c03cee0d3b1dd35a3d74e31 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Tue, 14 Apr 2020 23:15:50 +0200 Subject: [fixes #2246] Add null check --- src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java | 8 +++++--- test/transform/resource/after-delombok/TypeUseAnnotations.java | 10 ++++++++++ test/transform/resource/after-ecj/TypeUseAnnotations.java | 9 +++++++++ test/transform/resource/before/TypeUseAnnotations.java | 2 ++ 4 files changed, 26 insertions(+), 3 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 4df7a90b..2c6e1e77 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -660,9 +660,11 @@ public class EclipseHandlerUtil { Annotation[][] b = new Annotation[a.length][]; for (int i = 0; i < a.length; i++) { - b[i] = new Annotation[a[i].length]; - for (int j = 0 ; j < a[i].length; j++) { - b[i][j] = copyAnnotation(a[i][j], a[i][j]); + if (a[i] != null) { + b[i] = new Annotation[a[i].length]; + for (int j = 0 ; j < a[i].length; j++) { + b[i][j] = copyAnnotation(a[i][j], a[i][j]); + } } } diff --git a/test/transform/resource/after-delombok/TypeUseAnnotations.java b/test/transform/resource/after-delombok/TypeUseAnnotations.java index 1e1536bf..fbf32577 100644 --- a/test/transform/resource/after-delombok/TypeUseAnnotations.java +++ b/test/transform/resource/after-delombok/TypeUseAnnotations.java @@ -7,8 +7,18 @@ import java.util.List; } class TypeUseAnnotations { List<@TA(x = 5) String> foo; + List bar; + + class Inner { + } + @java.lang.SuppressWarnings("all") public List<@TA(x = 5) String> getFoo() { return this.foo; } + + @java.lang.SuppressWarnings("all") + public List getBar() { + return this.bar; + } } diff --git a/test/transform/resource/after-ecj/TypeUseAnnotations.java b/test/transform/resource/after-ecj/TypeUseAnnotations.java index 156643b9..7041b59e 100644 --- a/test/transform/resource/after-ecj/TypeUseAnnotations.java +++ b/test/transform/resource/after-ecj/TypeUseAnnotations.java @@ -5,11 +5,20 @@ import java.util.List; int x(); } class TypeUseAnnotations { + class Inner { + Inner() { + super(); + } + } @lombok.Getter List<@TA(x = 5) String> foo; + @lombok.Getter List bar; TypeUseAnnotations() { super(); } public @java.lang.SuppressWarnings("all") List<@TA(x = 5) String> getFoo() { return this.foo; } + public @java.lang.SuppressWarnings("all") List getBar() { + return this.bar; + } } \ No newline at end of file diff --git a/test/transform/resource/before/TypeUseAnnotations.java b/test/transform/resource/before/TypeUseAnnotations.java index c09a291d..7175930f 100644 --- a/test/transform/resource/before/TypeUseAnnotations.java +++ b/test/transform/resource/before/TypeUseAnnotations.java @@ -8,4 +8,6 @@ import java.util.List; } class TypeUseAnnotations { @lombok.Getter List<@TA(x=5) String> foo; + @lombok.Getter List bar; + class Inner { } } -- cgit From dede79bc224eb16566a027f83214c04e065b575b Mon Sep 17 00:00:00 2001 From: Jan Rieke Date: Mon, 6 Apr 2020 21:43:58 +0200 Subject: copy more Jackson annotation to the builder, also for @Singular methods --- src/core/lombok/core/handlers/HandlerUtil.java | 9 +- .../eclipse/handlers/EclipseHandlerUtil.java | 37 ++++- .../singulars/EclipseGuavaSingularizer.java | 12 +- .../EclipseJavaUtilListSetSingularizer.java | 12 +- .../singulars/EclipseJavaUtilMapSingularizer.java | 8 +- .../lombok/javac/handlers/HandleJacksonized.java | 1 - .../lombok/javac/handlers/JavacHandlerUtil.java | 18 ++- .../javac/handlers/JavacSingularsRecipes.java | 16 +- .../jackson/annotation/JsonAnySetter.java | 12 ++ .../after-delombok/JacksonBuilderSingular.java | 177 +++++++++++++++++++++ .../resource/after-ecj/JacksonBuilderSingular.java | 164 +++++++++++++++++++ .../resource/before/JacksonBuilderSingular.java | 31 ++++ 12 files changed, 476 insertions(+), 21 deletions(-) create mode 100644 test/stubs/com/fasterxml/jackson/annotation/JsonAnySetter.java create mode 100644 test/transform/resource/after-delombok/JacksonBuilderSingular.java create mode 100644 test/transform/resource/after-ecj/JacksonBuilderSingular.java create mode 100644 test/transform/resource/before/JacksonBuilderSingular.java (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java index 94fd21d9..a8d56041 100644 --- a/src/core/lombok/core/handlers/HandlerUtil.java +++ b/src/core/lombok/core/handlers/HandlerUtil.java @@ -76,7 +76,7 @@ public class HandlerUtil { return 43; } - public static final List NONNULL_ANNOTATIONS, BASE_COPYABLE_ANNOTATIONS, COPY_TO_SETTER_ANNOTATIONS, JACKSON_COPY_TO_BUILDER_ANNOTATIONS; + public static final List NONNULL_ANNOTATIONS, BASE_COPYABLE_ANNOTATIONS, COPY_TO_SETTER_ANNOTATIONS, COPY_TO_BUILDER_SINGULAR_SETTER_ANNOTATIONS, JACKSON_COPY_TO_BUILDER_ANNOTATIONS; static { NONNULL_ANNOTATIONS = Collections.unmodifiableList(Arrays.asList(new String[] { "androidx.annotation.NonNull", @@ -314,6 +314,13 @@ public class HandlerUtil { COPY_TO_SETTER_ANNOTATIONS = Collections.unmodifiableList(Arrays.asList(new String[] { "com.fasterxml.jackson.annotation.JsonProperty", "com.fasterxml.jackson.annotation.JsonSetter", + "com.fasterxml.jackson.annotation.JsonDeserialize", + "com.fasterxml.jackson.annotation.JsonIgnore", + "com.fasterxml.jackson.annotation.JacksonInject", + "com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty", + })); + COPY_TO_BUILDER_SINGULAR_SETTER_ANNOTATIONS = Collections.unmodifiableList(Arrays.asList(new String[] { + "com.fasterxml.jackson.annotation.JsonAnySetter", })); JACKSON_COPY_TO_BUILDER_ANNOTATIONS = Collections.unmodifiableList(Arrays.asList(new String[] { "com.fasterxml.jackson.annotation.JsonFormat", diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 4df7a90b..d066dc0f 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -26,6 +26,7 @@ import static lombok.eclipse.Eclipse.*; import static lombok.eclipse.EclipseAugments.*; import static lombok.eclipse.handlers.EclipseHandlerUtil.EclipseReflectiveMembers.*; +import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -817,6 +818,20 @@ public class EclipseHandlerUtil { * Searches the given field node for annotations that are specifically intentioned to be copied to the setter. */ public static Annotation[] findCopyableToSetterAnnotations(EclipseNode node) { + return findAnnotationsInList(node, COPY_TO_SETTER_ANNOTATIONS); + } + + /** + * Searches the given field node for annotations that are specifically intentioned to be copied to the builder's singular method. + */ + public static Annotation[] findCopyableToBuilderSingularSetterAnnotations(EclipseNode node) { + return findAnnotationsInList(node, COPY_TO_BUILDER_SINGULAR_SETTER_ANNOTATIONS); + } + + /** + * Searches the given field node for annotations that are in the given list, and returns those. + */ + private static Annotation[] findAnnotationsInList(EclipseNode node, java.util.List annotationsToFind) { AbstractVariableDeclaration avd = (AbstractVariableDeclaration) node.get(); if (avd.annotations == null) return EMPTY_ANNOTATIONS_ARRAY; List result = new ArrayList(); @@ -824,7 +839,7 @@ public class EclipseHandlerUtil { for (Annotation annotation : avd.annotations) { TypeReference typeRef = annotation.type; if (typeRef != null && typeRef.getTypeName() != null) { - for (String bn : COPY_TO_SETTER_ANNOTATIONS) if (typeMatches(bn, node, typeRef)) { + for (String bn : annotationsToFind) if (typeMatches(bn, node, typeRef)) { result.add(annotation); break; } @@ -2418,6 +2433,26 @@ public class EclipseHandlerUtil { return array == null ? null : array.clone(); } + public static T[] concat(T[] first, T[] second, Class type) { + if (first == null) + return second; + if (second == null) + return first; + if (first.length == 0) + return second; + if (second.length == 0) + return first; + T[] result = newArray(type, first.length + second.length); + System.arraycopy(first, 0, result, 0, first.length); + System.arraycopy(second, 0, result, first.length, second.length); + return result; + } + + @SuppressWarnings("unchecked") + private static T[] newArray(Class type, int length) { + return (T[]) Array.newInstance(type, length); + } + public static boolean isDirectDescendantOfObject(EclipseNode typeNode) { if (!(typeNode.get() instanceof TypeDeclaration)) throw new IllegalArgumentException("not a type node"); TypeDeclaration typeDecl = (TypeDeclaration) typeNode.get(); diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java index 392418ff..395d2e59 100755 --- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java +++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java @@ -175,8 +175,10 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer { md.returnType = returnType; char[] prefixedSingularName = data.getSetterPrefix().length == 0 ? data.getSingularName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getSingularName())).toCharArray(); md.selector = fluent ? prefixedSingularName : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray(); - md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); - + Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToBuilderSingularSetterAnnotations(data.getAnnotation().up())); + md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); + if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md); data.setGeneratedByRecursive(md); HandleNonNull.INSTANCE.fix(injectMethod(builderType, md)); @@ -213,8 +215,10 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer { md.returnType = returnType; char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray(); md.selector = fluent ? prefixedSelector : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray(); - md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); - + Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up())); + md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); + if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md); data.setGeneratedByRecursive(md); injectMethod(builderType, md); diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java index 375f4e2c..deab4530 100755 --- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java +++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java @@ -153,8 +153,10 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula md.returnType = returnType; char[] prefixedSingularName = data.getSetterPrefix().length == 0 ? data.getSingularName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getSingularName())).toCharArray(); md.selector = fluent ? prefixedSingularName : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray(); - md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); - + Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToBuilderSingularSetterAnnotations(data.getAnnotation().up())); + md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); + if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md); data.setGeneratedByRecursive(md); HandleNonNull.INSTANCE.fix(injectMethod(builderType, md)); @@ -189,8 +191,10 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula md.returnType = returnType; char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray(); md.selector = fluent ? prefixedSelector : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray(); - md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); - + Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up())); + md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); + if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md); data.setGeneratedByRecursive(md); injectMethod(builderType, md); diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java index cb7d9ed6..1a40369d 100755 --- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java +++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java @@ -252,7 +252,9 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer String setterName = HandlerUtil.buildAccessorName(setterPrefix, name); md.selector = setterName.toCharArray(); - md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToBuilderSingularSetterAnnotations(data.getAnnotation().up())); + md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md); data.setGeneratedByRecursive(md); @@ -326,7 +328,9 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer String setterName = HandlerUtil.buildAccessorName(setterPrefix, name); md.selector = setterName.toCharArray(); - md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource()); + Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up())); + md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class); if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md); data.setGeneratedByRecursive(md); diff --git a/src/core/lombok/javac/handlers/HandleJacksonized.java b/src/core/lombok/javac/handlers/HandleJacksonized.java index aff0bf63..0aa02d1b 100644 --- a/src/core/lombok/javac/handlers/HandleJacksonized.java +++ b/src/core/lombok/javac/handlers/HandleJacksonized.java @@ -149,7 +149,6 @@ public class HandleJacksonized extends JavacAnnotationHandler { // @SuperBuilder? Make it package-private! if (superBuilderAnnotationNode != null) builderClass.mods.flags = builderClass.mods.flags & ~Flags.PRIVATE; - } private String getBuilderClassName(JCAnnotation ast, JavacNode annotationNode, JavacNode annotatedNode, JCClassDecl td, AnnotationValues builderAnnotation, JavacTreeMaker maker) { diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index a3e876c4..5241a209 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1520,6 +1520,20 @@ public class JavacHandlerUtil { * Searches the given field node for annotations that are specifically intentioned to be copied to the setter. */ public static List findCopyableToSetterAnnotations(JavacNode node) { + return findAnnotationsInList(node, COPY_TO_SETTER_ANNOTATIONS); + } + + /** + * Searches the given field node for annotations that are specifically intentioned to be copied to the builder's singular method. + */ + public static List findCopyableToBuilderSingularSetterAnnotations(JavacNode node) { + return findAnnotationsInList(node, COPY_TO_BUILDER_SINGULAR_SETTER_ANNOTATIONS); + } + + /** + * Searches the given field node for annotations that are in the given list, and returns those. + */ + private static List findAnnotationsInList(JavacNode node, java.util.List annotationsToFind) { JCAnnotation anno = null; String annoName = null; for (JavacNode child : node.down()) { @@ -1537,7 +1551,7 @@ public class JavacHandlerUtil { if (annoName == null) return List.nil(); if (!annoName.isEmpty()) { - for (String bn : COPY_TO_SETTER_ANNOTATIONS) if (typeMatches(bn, node, anno.annotationType)) return List.of(anno); + for (String bn : annotationsToFind) if (typeMatches(bn, node, anno.annotationType)) return List.of(anno); } ListBuffer result = new ListBuffer(); @@ -1545,7 +1559,7 @@ public class JavacHandlerUtil { if (child.getKind() == Kind.ANNOTATION) { JCAnnotation annotation = (JCAnnotation) child.get(); boolean match = false; - if (!match) for (String bn : COPY_TO_SETTER_ANNOTATIONS) if (typeMatches(bn, node, annotation.annotationType)) { + if (!match) for (String bn : annotationsToFind) if (typeMatches(bn, node, annotation.annotationType)) { result.append(annotation); break; } diff --git a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java index ba052b5a..7cd52c8c 100644 --- a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java +++ b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java @@ -182,11 +182,12 @@ public class JavacSingularsRecipes { return this; } - protected JCModifiers makeMods(JavacTreeMaker maker, CheckerFrameworkVersion cfv, JavacNode node, boolean deprecate, AccessLevel access) { + protected JCModifiers makeMods(JavacTreeMaker maker, CheckerFrameworkVersion cfv, JavacNode node, boolean deprecate, AccessLevel access, List methodAnnotations) { JCAnnotation deprecateAnn = deprecate ? maker.Annotation(genJavaLangTypeRef(node, "Deprecated"), List.nil()) : null; JCAnnotation rrAnn = cfv.generateReturnsReceiver() ? maker.Annotation(genTypeRef(node, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.nil()) : null; List annsOnMethod = (deprecateAnn != null && rrAnn != null) ? List.of(deprecateAnn, rrAnn) : deprecateAnn != null ? List.of(deprecateAnn) : rrAnn != null ? List.of(rrAnn) : List.nil(); + annsOnMethod = mergeAnnotations(annsOnMethod,methodAnnotations); return maker.Modifiers(toJavacModifier(access), annsOnMethod); } @@ -271,10 +272,10 @@ public class JavacSingularsRecipes { generateClearMethod(cfv, deprecate, maker, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, source, access); } - private void finishAndInjectMethod(CheckerFrameworkVersion cfv, JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean deprecate, ListBuffer statements, Name methodName, List jcVariableDecls, AccessLevel access, Boolean ignoreNullCollections) { + private void finishAndInjectMethod(CheckerFrameworkVersion cfv, JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean deprecate, ListBuffer statements, Name methodName, List jcVariableDecls, List methodAnnotations, AccessLevel access, Boolean ignoreNullCollections) { if (returnStatement != null) statements.append(returnStatement); JCBlock body = maker.Block(0, statements.toList()); - JCModifiers mods = makeMods(maker, cfv, builderType, deprecate, access); + JCModifiers mods = makeMods(maker, cfv, builderType, deprecate, access, methodAnnotations); List typeParams = List.nil(); List thrown = List.nil(); @@ -298,7 +299,7 @@ public class JavacSingularsRecipes { statements.add(clearStatement); Name methodName = builderType.toName(HandlerUtil.buildAccessorName("clear", data.getPluralName().toString())); - finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, methodName, List.nil(), access, null); + finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, methodName, List.nil(), List.nil(), access, null); } protected abstract JCStatement generateClearStatements(JavacTreeMaker maker, SingularData data, JavacNode builderType); @@ -312,7 +313,8 @@ public class JavacSingularsRecipes { if (!setterPrefix.isEmpty()) name = builderType.toName(HandlerUtil.buildAccessorName(setterPrefix, name.toString())); statements.prepend(createConstructBuilderVarIfNeeded(maker, data, builderType, source)); - finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, name, params, access, null); + List methodAnnotations = copyAnnotations(findCopyableToBuilderSingularSetterAnnotations(data.annotation.up())); + finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, name, params, methodAnnotations, access, null); } protected JCVariableDecl generateSingularMethodParameter(int typeIndex, JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source, Name name) { @@ -357,8 +359,10 @@ public class JavacSingularsRecipes { } else { statements.prepend(JavacHandlerUtil.generateNullCheck(maker, null, data.getPluralName(), builderType, "%s cannot be null")); } + + List methodAnnotations = copyAnnotations(findCopyableToSetterAnnotations(data.annotation.up())); - finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, name, List.of(param), access, ignoreNullCollections); + finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, name, List.of(param), methodAnnotations, access, ignoreNullCollections); } protected ListBuffer generatePluralMethodStatements(JavacTreeMaker maker, SingularData data, JavacNode builderType, JCTree source) { diff --git a/test/stubs/com/fasterxml/jackson/annotation/JsonAnySetter.java b/test/stubs/com/fasterxml/jackson/annotation/JsonAnySetter.java new file mode 100644 index 00000000..51d2c3fa --- /dev/null +++ b/test/stubs/com/fasterxml/jackson/annotation/JsonAnySetter.java @@ -0,0 +1,12 @@ +package com.fasterxml.jackson.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface JsonAnySetter { + boolean enabled() default true; +} diff --git a/test/transform/resource/after-delombok/JacksonBuilderSingular.java b/test/transform/resource/after-delombok/JacksonBuilderSingular.java new file mode 100644 index 00000000..feaa6832 --- /dev/null +++ b/test/transform/resource/after-delombok/JacksonBuilderSingular.java @@ -0,0 +1,177 @@ +import java.util.List; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +@com.fasterxml.jackson.databind.annotation.JsonDeserialize(builder = JacksonBuilderSingular.JacksonBuilderSingularBuilder.class) +public class JacksonBuilderSingular { + @JsonAnySetter + private Map any; + @JsonProperty("v_a_l_u_e_s") + private List values; + @JsonAnySetter + private ImmutableMap guavaAny; + @JsonProperty("guava_v_a_l_u_e_s") + private ImmutableList guavaValues; + @java.lang.SuppressWarnings("all") + JacksonBuilderSingular(final Map any, final List values, final ImmutableMap guavaAny, final ImmutableList guavaValues) { + this.any = any; + this.values = values; + this.guavaAny = guavaAny; + this.guavaValues = guavaValues; + } + @java.lang.SuppressWarnings("all") + @com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder(withPrefix = "", buildMethodName = "build") + public static class JacksonBuilderSingularBuilder { + @java.lang.SuppressWarnings("all") + private java.util.ArrayList any$key; + @java.lang.SuppressWarnings("all") + private java.util.ArrayList any$value; + @java.lang.SuppressWarnings("all") + private java.util.ArrayList values; + @java.lang.SuppressWarnings("all") + private com.google.common.collect.ImmutableMap.Builder guavaAny; + @java.lang.SuppressWarnings("all") + private com.google.common.collect.ImmutableList.Builder guavaValues; + @java.lang.SuppressWarnings("all") + JacksonBuilderSingularBuilder() { + } + @JsonAnySetter + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder any(final String anyKey, final Object anyValue) { + if (this.any$key == null) { + this.any$key = new java.util.ArrayList(); + this.any$value = new java.util.ArrayList(); + } + this.any$key.add(anyKey); + this.any$value.add(anyValue); + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder any(final java.util.Map any) { + if (any == null) { + throw new java.lang.NullPointerException("any cannot be null"); + } + if (this.any$key == null) { + this.any$key = new java.util.ArrayList(); + this.any$value = new java.util.ArrayList(); + } + for (final java.util.Map.Entry $lombokEntry : any.entrySet()) { + this.any$key.add($lombokEntry.getKey()); + this.any$value.add($lombokEntry.getValue()); + } + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder clearAny() { + if (this.any$key != null) { + this.any$key.clear(); + this.any$value.clear(); + } + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder value(final String value) { + if (this.values == null) this.values = new java.util.ArrayList(); + this.values.add(value); + return this; + } + @JsonProperty("v_a_l_u_e_s") + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder values(final java.util.Collection values) { + if (values == null) { + throw new java.lang.NullPointerException("values cannot be null"); + } + if (this.values == null) this.values = new java.util.ArrayList(); + this.values.addAll(values); + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder clearValues() { + if (this.values != null) this.values.clear(); + return this; + } + @JsonAnySetter + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaAny(final String key, final Object value) { + if (this.guavaAny == null) this.guavaAny = com.google.common.collect.ImmutableMap.builder(); + this.guavaAny.put(key, value); + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaAny(final java.util.Map guavaAny) { + if (guavaAny == null) { + throw new java.lang.NullPointerException("guavaAny cannot be null"); + } + if (this.guavaAny == null) this.guavaAny = com.google.common.collect.ImmutableMap.builder(); + this.guavaAny.putAll(guavaAny); + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder clearGuavaAny() { + this.guavaAny = null; + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaValue(final String guavaValue) { + if (this.guavaValues == null) this.guavaValues = com.google.common.collect.ImmutableList.builder(); + this.guavaValues.add(guavaValue); + return this; + } + @JsonProperty("guava_v_a_l_u_e_s") + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaValues(final java.lang.Iterable guavaValues) { + if (guavaValues == null) { + throw new java.lang.NullPointerException("guavaValues cannot be null"); + } + if (this.guavaValues == null) this.guavaValues = com.google.common.collect.ImmutableList.builder(); + this.guavaValues.addAll(guavaValues); + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular.JacksonBuilderSingularBuilder clearGuavaValues() { + this.guavaValues = null; + return this; + } + @java.lang.SuppressWarnings("all") + public JacksonBuilderSingular build() { + java.util.Map any; + switch (this.any$key == null ? 0 : this.any$key.size()) { + case 0: + any = java.util.Collections.emptyMap(); + break; + case 1: + any = java.util.Collections.singletonMap(this.any$key.get(0), this.any$value.get(0)); + break; + default: + any = new java.util.LinkedHashMap(this.any$key.size() < 1073741824 ? 1 + this.any$key.size() + (this.any$key.size() - 3) / 3 : java.lang.Integer.MAX_VALUE); + for (int $i = 0; $i < this.any$key.size(); $i++) any.put(this.any$key.get($i), (Object) this.any$value.get($i)); + any = java.util.Collections.unmodifiableMap(any); + } + java.util.List values; + switch (this.values == null ? 0 : this.values.size()) { + case 0: + values = java.util.Collections.emptyList(); + break; + case 1: + values = java.util.Collections.singletonList(this.values.get(0)); + break; + default: + values = java.util.Collections.unmodifiableList(new java.util.ArrayList(this.values)); + } + com.google.common.collect.ImmutableMap guavaAny = this.guavaAny == null ? com.google.common.collect.ImmutableMap.of() : this.guavaAny.build(); + com.google.common.collect.ImmutableList guavaValues = this.guavaValues == null ? com.google.common.collect.ImmutableList.of() : this.guavaValues.build(); + return new JacksonBuilderSingular(any, values, guavaAny, guavaValues); + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "JacksonBuilderSingular.JacksonBuilderSingularBuilder(any$key=" + this.any$key + ", any$value=" + this.any$value + ", values=" + this.values + ", guavaAny=" + this.guavaAny + ", guavaValues=" + this.guavaValues + ")"; + } + } + @java.lang.SuppressWarnings("all") + public static JacksonBuilderSingular.JacksonBuilderSingularBuilder builder() { + return new JacksonBuilderSingular.JacksonBuilderSingularBuilder(); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/JacksonBuilderSingular.java b/test/transform/resource/after-ecj/JacksonBuilderSingular.java new file mode 100644 index 00000000..50f6a797 --- /dev/null +++ b/test/transform/resource/after-ecj/JacksonBuilderSingular.java @@ -0,0 +1,164 @@ +import java.util.List; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import lombok.Builder; +import lombok.Singular; +import lombok.extern.jackson.Jacksonized; +public @Jacksonized @Builder @com.fasterxml.jackson.databind.annotation.JsonDeserialize(builder = JacksonBuilderSingular.JacksonBuilderSingularBuilder.class) class JacksonBuilderSingular { + public static @java.lang.SuppressWarnings("all") @com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder(withPrefix = "",buildMethodName = "build") class JacksonBuilderSingularBuilder { + private @java.lang.SuppressWarnings("all") java.util.ArrayList any$key; + private @java.lang.SuppressWarnings("all") java.util.ArrayList any$value; + private @java.lang.SuppressWarnings("all") java.util.ArrayList values; + private @java.lang.SuppressWarnings("all") com.google.common.collect.ImmutableMap.Builder guavaAny; + private @java.lang.SuppressWarnings("all") com.google.common.collect.ImmutableList.Builder guavaValues; + @java.lang.SuppressWarnings("all") JacksonBuilderSingularBuilder() { + super(); + } + public @JsonAnySetter @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder any(final String anyKey, final Object anyValue) { + if ((this.any$key == null)) + { + this.any$key = new java.util.ArrayList(); + this.any$value = new java.util.ArrayList(); + } + this.any$key.add(anyKey); + this.any$value.add(anyValue); + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder any(final java.util.Map any) { + if ((any == null)) + { + throw new java.lang.NullPointerException("any cannot be null"); + } + if ((this.any$key == null)) + { + this.any$key = new java.util.ArrayList(); + this.any$value = new java.util.ArrayList(); + } + for (java.util.Map.Entry $lombokEntry : any.entrySet()) + { + this.any$key.add($lombokEntry.getKey()); + this.any$value.add($lombokEntry.getValue()); + } + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder clearAny() { + if ((this.any$key != null)) + { + this.any$key.clear(); + this.any$value.clear(); + } + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder value(final String value) { + if ((this.values == null)) + this.values = new java.util.ArrayList(); + this.values.add(value); + return this; + } + public @JsonProperty("v_a_l_u_e_s") @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder values(final java.util.Collection values) { + if ((values == null)) + { + throw new java.lang.NullPointerException("values cannot be null"); + } + if ((this.values == null)) + this.values = new java.util.ArrayList(); + this.values.addAll(values); + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder clearValues() { + if ((this.values != null)) + this.values.clear(); + return this; + } + public @JsonAnySetter @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaAny(final String key, final Object value) { + if ((this.guavaAny == null)) + this.guavaAny = com.google.common.collect.ImmutableMap.builder(); + this.guavaAny.put(key, value); + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaAny(final java.util.Map guavaAny) { + if ((guavaAny == null)) + { + throw new java.lang.NullPointerException("guavaAny cannot be null"); + } + if ((this.guavaAny == null)) + this.guavaAny = com.google.common.collect.ImmutableMap.builder(); + this.guavaAny.putAll(guavaAny); + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder clearGuavaAny() { + this.guavaAny = null; + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaValue(final String guavaValue) { + if ((this.guavaValues == null)) + this.guavaValues = com.google.common.collect.ImmutableList.builder(); + this.guavaValues.add(guavaValue); + return this; + } + public @JsonProperty("guava_v_a_l_u_e_s") @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder guavaValues(final java.lang.Iterable guavaValues) { + if ((guavaValues == null)) + { + throw new java.lang.NullPointerException("guavaValues cannot be null"); + } + if ((this.guavaValues == null)) + this.guavaValues = com.google.common.collect.ImmutableList.builder(); + this.guavaValues.addAll(guavaValues); + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder clearGuavaValues() { + this.guavaValues = null; + return this; + } + public @java.lang.SuppressWarnings("all") JacksonBuilderSingular build() { + java.util.Map any; + switch (((this.any$key == null) ? 0 : this.any$key.size())) { + case 0 : + any = java.util.Collections.emptyMap(); + break; + case 1 : + any = java.util.Collections.singletonMap(this.any$key.get(0), this.any$value.get(0)); + break; + default : + any = new java.util.LinkedHashMap(((this.any$key.size() < 0x40000000) ? ((1 + this.any$key.size()) + ((this.any$key.size() - 3) / 3)) : java.lang.Integer.MAX_VALUE)); + for (int $i = 0;; ($i < this.any$key.size()); $i ++) + any.put(this.any$key.get($i), this.any$value.get($i)); + any = java.util.Collections.unmodifiableMap(any); + } + java.util.List values; + switch (((this.values == null) ? 0 : this.values.size())) { + case 0 : + values = java.util.Collections.emptyList(); + break; + case 1 : + values = java.util.Collections.singletonList(this.values.get(0)); + break; + default : + values = java.util.Collections.unmodifiableList(new java.util.ArrayList(this.values)); + } + com.google.common.collect.ImmutableMap guavaAny = ((this.guavaAny == null) ? com.google.common.collect.ImmutableMap.of() : this.guavaAny.build()); + com.google.common.collect.ImmutableList guavaValues = ((this.guavaValues == null) ? com.google.common.collect.ImmutableList.of() : this.guavaValues.build()); + return new JacksonBuilderSingular(any, values, guavaAny, guavaValues); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (((((((((("JacksonBuilderSingular.JacksonBuilderSingularBuilder(any$key=" + this.any$key) + ", any$value=") + this.any$value) + ", values=") + this.values) + ", guavaAny=") + this.guavaAny) + ", guavaValues=") + this.guavaValues) + ")"); + } + } + private @JsonAnySetter @Singular("any") Map any; + private @JsonProperty("v_a_l_u_e_s") @Singular List values; + private @JsonAnySetter @Singular("guavaAny") ImmutableMap guavaAny; + private @JsonProperty("guava_v_a_l_u_e_s") @Singular ImmutableList guavaValues; + @java.lang.SuppressWarnings("all") JacksonBuilderSingular(final Map any, final List values, final ImmutableMap guavaAny, final ImmutableList guavaValues) { + super(); + this.any = any; + this.values = values; + this.guavaAny = guavaAny; + this.guavaValues = guavaValues; + } + public static @java.lang.SuppressWarnings("all") JacksonBuilderSingular.JacksonBuilderSingularBuilder builder() { + return new JacksonBuilderSingular.JacksonBuilderSingularBuilder(); + } +} \ No newline at end of file diff --git a/test/transform/resource/before/JacksonBuilderSingular.java b/test/transform/resource/before/JacksonBuilderSingular.java new file mode 100644 index 00000000..c179c760 --- /dev/null +++ b/test/transform/resource/before/JacksonBuilderSingular.java @@ -0,0 +1,31 @@ +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +import lombok.Builder; +import lombok.Singular; +import lombok.extern.jackson.Jacksonized; + +@Jacksonized +@Builder +public class JacksonBuilderSingular { + @JsonAnySetter + @Singular("any") + private Map any; + + @JsonProperty("v_a_l_u_e_s") + @Singular + private List values; + + @JsonAnySetter + @Singular("guavaAny") + private ImmutableMap guavaAny; + + @JsonProperty("guava_v_a_l_u_e_s") + @Singular + private ImmutableList guavaValues; +} -- cgit From 265c56d229093a307ebf231baa191663f953cf1e Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Sat, 25 Apr 2020 19:20:23 +0200 Subject: [fixes #1969] Enum.values() requires enumConstantsCounter to be set --- src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java index 2db7591c..9343011f 100644 --- a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java +++ b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java @@ -136,9 +136,8 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler Date: Fri, 1 May 2020 23:56:17 +0200 Subject: [SuperBuilder] allow constructor customization --- .../eclipse/handlers/HandleSuperBuilder.java | 28 +++++++++++++++-- .../lombok/javac/handlers/HandleSuperBuilder.java | 35 ++++++++++++++++++++-- .../after-delombok/SuperBuilderCustomized.java | 15 +++++----- .../resource/after-ecj/SuperBuilderCustomized.java | 8 +++-- .../resource/before/SuperBuilderCustomized.java | 10 +++++++ 5 files changed, 81 insertions(+), 15 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java index a49c20a4..455d40ed 100644 --- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java @@ -274,8 +274,10 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { // If there is no superclass, superclassBuilderClassExpression is still == null at this point. // You can use it to check whether to inherit or not. - generateBuilderBasedConstructor(cfv, tdParent, typeParams, builderFields, annotationNode, builderClassName, - superclassBuilderClass != null); + if (!constructorExists(tdParent, builderClassName)) { + generateBuilderBasedConstructor(cfv, tdParent, typeParams, builderFields, annotationNode, builderClassName, + superclassBuilderClass != null); + } // Create the abstract builder class, or reuse an existing one. EclipseNode builderType = findInnerClass(tdParent, builderClassName); @@ -1159,4 +1161,26 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { System.arraycopy(name, 0, out, prefix.length, name.length); return out; } + + private boolean constructorExists(EclipseNode type, String builderClassName) { + if (type != null && type.get() instanceof TypeDeclaration) { + TypeDeclaration typeDecl = (TypeDeclaration)type.get(); + if (typeDecl.methods != null) for (AbstractMethodDeclaration def : typeDecl.methods) { + if (def instanceof ConstructorDeclaration) { + if ((def.bits & ASTNode.IsDefaultConstructor) != 0) continue; + if (!def.isConstructor()) continue; + if (isTolerate(type, def)) continue; + if (def.arguments.length != 1) continue; + + // Cannot use typeMatches() here, because the parameter could be fully-qualified, partially-qualified, or not qualified. + // A string-compare of the last part should work. If it's a false-positive, users could still @Tolerate it. + char[] typeName = def.arguments[0].type.getLastToken(); + if (builderClassName.equals(String.valueOf(typeName))) + return true; + } + } + } + + return false; + } } diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java index 2dc3247d..b7cd6f9a 100644 --- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java @@ -354,8 +354,10 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { } // Generate a constructor in the annotated class that takes a builder as argument. - generateBuilderBasedConstructor(cfv, tdParent, typeParams, builderFields, annotationNode, builderClassName, - superclassBuilderClassExpression != null); + if (!constructorExists(tdParent, builderClassName)) { + generateBuilderBasedConstructor(cfv, tdParent, typeParams, builderFields, annotationNode, builderClassName, + superclassBuilderClassExpression != null); + } if (isAbstract) { // Only non-abstract classes get the builder() and toBuilder() methods. @@ -1070,4 +1072,33 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { } return typeParameter; } + + /** + * Checks if there is a manual constructor in the given type with a single parameter (builder). + */ + private boolean constructorExists(JavacNode type, String builderClassName) { + if (type != null && type.get() instanceof JCClassDecl) { + for (JCTree def : ((JCClassDecl)type.get()).defs) { + if (def instanceof JCMethodDecl) { + JCMethodDecl md = (JCMethodDecl) def; + String name = md.name.toString(); + boolean matches = name.equals(""); + if (isTolerate(type, md)) + continue; + if (matches && md.params != null && md.params.length() == 1) { + // Cannot use typeMatches() here, because the parameter could be fully-qualified, partially-qualified, or not qualified. + // A string-compare of the last part should work. If it's a false-positive, users could still @Tolerate it. + String typeName = md.params.get(0).getType().toString(); + int lastIndexOfDot = typeName.lastIndexOf('.'); + if (lastIndexOfDot >= 0) { + typeName = typeName.substring(lastIndexOfDot+1); + } + if ((builderClassName+"").equals(typeName)) + return true; + } + } + } + } + return false; + } } diff --git a/test/transform/resource/after-delombok/SuperBuilderCustomized.java b/test/transform/resource/after-delombok/SuperBuilderCustomized.java index bffa72fa..f66133c9 100644 --- a/test/transform/resource/after-delombok/SuperBuilderCustomized.java +++ b/test/transform/resource/after-delombok/SuperBuilderCustomized.java @@ -23,6 +23,13 @@ public class SuperBuilderCustomized { } } int field1; + protected Parent(ParentBuilder b) { + if (b.field1 == 0) throw new IllegalArgumentException("field1 must be != 0"); + this.field1 = b.field1; + } + public static SuperBuilderCustomized.Parent.ParentBuilder builder(int field1) { + return new SuperBuilderCustomized.Parent.ParentBuilderImpl().field1(field1); + } @java.lang.SuppressWarnings("all") private static final class ParentBuilderImpl extends SuperBuilderCustomized.Parent.ParentBuilder { @java.lang.SuppressWarnings("all") @@ -39,14 +46,6 @@ public class SuperBuilderCustomized { return new SuperBuilderCustomized.Parent(this); } } - @java.lang.SuppressWarnings("all") - protected Parent(final SuperBuilderCustomized.Parent.ParentBuilder b) { - this.field1 = b.field1; - } - @java.lang.SuppressWarnings("all") - public static SuperBuilderCustomized.Parent.ParentBuilder builder() { - return new SuperBuilderCustomized.Parent.ParentBuilderImpl(); - } } public static class Child extends Parent { private static final class ChildBuilderImpl extends ChildBuilder { diff --git a/test/transform/resource/after-ecj/SuperBuilderCustomized.java b/test/transform/resource/after-ecj/SuperBuilderCustomized.java index 32317f6a..fe0e1238 100644 --- a/test/transform/resource/after-ecj/SuperBuilderCustomized.java +++ b/test/transform/resource/after-ecj/SuperBuilderCustomized.java @@ -32,12 +32,14 @@ public class SuperBuilderCustomized { } } int field1; - protected @java.lang.SuppressWarnings("all") Parent(final SuperBuilderCustomized.Parent.ParentBuilder b) { + protected Parent(ParentBuilder b) { super(); + if ((b.field1 == 0)) + throw new IllegalArgumentException("field1 must be != 0"); this.field1 = b.field1; } - public static @java.lang.SuppressWarnings("all") SuperBuilderCustomized.Parent.ParentBuilder builder() { - return new SuperBuilderCustomized.Parent.ParentBuilderImpl(); + public static SuperBuilderCustomized.Parent.ParentBuilder builder(int field1) { + return new SuperBuilderCustomized.Parent.ParentBuilderImpl().field1(field1); } } public static @lombok.experimental.SuperBuilder class Child extends Parent { diff --git a/test/transform/resource/before/SuperBuilderCustomized.java b/test/transform/resource/before/SuperBuilderCustomized.java index 77830587..8e641d90 100644 --- a/test/transform/resource/before/SuperBuilderCustomized.java +++ b/test/transform/resource/before/SuperBuilderCustomized.java @@ -14,6 +14,16 @@ public class SuperBuilderCustomized { } } int field1; + + protected Parent(ParentBuilder b) { + if (b.field1 == 0) + throw new IllegalArgumentException("field1 must be != 0"); + this.field1 = b.field1; + } + + public static SuperBuilderCustomized.Parent.ParentBuilder builder(int field1) { + return new SuperBuilderCustomized.Parent.ParentBuilderImpl().field1(field1); + } } @lombok.experimental.SuperBuilder -- cgit From b767427f06b60dd236bc2c0d6ea41a0e8446fe08 Mon Sep 17 00:00:00 2001 From: Jan Rieke Date: Mon, 11 May 2020 08:33:13 +0200 Subject: [SuperBuilder] don't warn on existing toBuilder method --- src/core/lombok/eclipse/handlers/HandleSuperBuilder.java | 2 +- src/core/lombok/javac/handlers/HandleSuperBuilder.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java index 455d40ed..7c8e4ea3 100644 --- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java @@ -390,10 +390,10 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { // Add the toBuilder() method to the annotated class. switch (methodExists(TO_BUILDER_METHOD_NAME_STRING, tdParent, 0)) { case EXISTS_BY_USER: - annotationNode.addWarning("Not generating toBuilder() as it already exists."); break; case NOT_EXISTS: injectMethod(tdParent, generateToBuilderMethod(cfv, builderClassName, builderImplClassName, tdParent, typeParams, ast)); + break; default: // Should not happen. } diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java index b7cd6f9a..4cd64b77 100644 --- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java @@ -377,14 +377,14 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { if (toBuilder) { switch (methodExists(TO_BUILDER_METHOD_NAME, tdParent, 0)) { case EXISTS_BY_USER: - annotationNode.addWarning("Not generating toBuilder() as it already exists."); - return; + break; case NOT_EXISTS: JCMethodDecl md = generateToBuilderMethod(cfv, builderClassName, builderImplClassName, annotationNode, tdParent, typeParams); if (md != null) { recursiveSetGeneratedBy(md, ast, annotationNode.getContext()); injectMethod(tdParent, md); } + break; default: // Should not happen. } -- cgit From 39d2c280fbaced63f5697481af6b37ab81891798 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Thu, 18 Jun 2020 22:08:25 +0200 Subject: Fixes #1543: in equals, by default first compare the primitives --- doc/changelog.markdown | 3 +++ src/core/lombok/EqualsAndHashCode.java | 4 +++- src/core/lombok/core/LombokNode.java | 1 + .../core/handlers/InclusionExclusionUtils.java | 18 ++++++++++++------ src/core/lombok/eclipse/EclipseNode.java | 19 +++++++++++++++---- src/core/lombok/eclipse/handlers/HandleBuilder.java | 2 +- .../lombok/eclipse/handlers/HandleSuperBuilder.java | 2 +- src/core/lombok/javac/JavacNode.java | 20 +++++++++++++++----- src/core/lombok/javac/handlers/HandleBuilder.java | 2 +- .../lombok/javac/handlers/HandleSuperBuilder.java | 2 +- .../resource/after-delombok/BuilderDefaults.java | 8 ++++---- .../after-delombok/EqualsAndHashCodeRank.java | 6 +++--- .../resource/after-ecj/BuilderDefaults.java | 10 +++++----- .../resource/after-ecj/EqualsAndHashCodeRank.java | 18 +++++++++--------- 14 files changed, 74 insertions(+), 41 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 00545483..af77d480 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -2,6 +2,8 @@ Lombok Changelog ---------------- ### v1.18.13 "Edgy Guinea Pig" +* PERFORMANCE: The generated equals method will first compare primitives. Manual re-ordering is possible using `@Include(rank=n)`. [Pull Request #2485](https://github.com/rzwitserloot/lombok/pull/2485), [Issue #1543](https://github.com/rzwitserloot/lombok/issues/1543) +* IMPROBABLE BREAKING CHANGE: The generated hashcode has changed for classes that include both primitive fields and reference fields. * PLATFORM: Added support for compiling projects with OpenJ9 [Pull Request #2437](https://github.com/rzwitserloot/lombok/pull/2437) * BREAKING CHANGE: mapstruct users should now add a dependency to lombok-mapstruct-binding. This solves compiling modules with lombok (and mapstruct). * FEATURE: Similar to `@Builder`, you can now configure a `@SuperBuilder`'s 'setter' prefixes via `@SuperBuilder(setterPrefix = "set")` for example. We still discourage doing this. [Pull Request #2357](https://github.com/rzwitserloot/lombok/pull/2357). @@ -14,6 +16,7 @@ Lombok Changelog * BUGFIX: Javac sets incorrect annotated type on with methods. [Issue #2463](https://github.com/rzwitserloot/lombok/issues/2463) * FEATURE: `@Jacksonized` on a `@Builder` or `@SuperBuilder` will configure [Jackson](https://github.com/FasterXML/jackson) to use this builder when deserializing. [Pull Request #2387](https://github.com/rzwitserloot/lombok/pull/2387) thanks to __@JanRieke__. [@Jacksonized documentation](https://projectlombok.org/features/experimental/Jacksonized). + ### v1.18.12 (February 1st, 2020) * PLATFORM: Support for JDK13 (including `yield` in switch expressions, as well as delombok having a nicer style for arrow-style switch blocks, and text blocks). * PLATFORM: Support for JDK14 (including `pattern match` instanceof expressions). diff --git a/src/core/lombok/EqualsAndHashCode.java b/src/core/lombok/EqualsAndHashCode.java index 02596f24..2f53bdec 100644 --- a/src/core/lombok/EqualsAndHashCode.java +++ b/src/core/lombok/EqualsAndHashCode.java @@ -125,7 +125,9 @@ public @interface EqualsAndHashCode { /** * Higher ranks are considered first. Members of the same rank are considered in the order they appear in the source file. - * + * + * If not explicitly set, the {@code default} rank for primitives is 1000. + * * @return ordering within the generating {@code equals} and {@code hashCode} methods; higher numbers are considered first. */ int rank() default 0; diff --git a/src/core/lombok/core/LombokNode.java b/src/core/lombok/core/LombokNode.java index e52cd5b3..46054077 100644 --- a/src/core/lombok/core/LombokNode.java +++ b/src/core/lombok/core/LombokNode.java @@ -288,6 +288,7 @@ public abstract class LombokNode, L extends LombokNode type) { @@ -164,13 +170,13 @@ public class InclusionExclusionUtils { if (n.isEmpty()) n = name; namesToAutoExclude.add(n); } - members.add(new Included(child, inc, false)); + members.add(new Included(child, inc, false, markInclude.isExplicit("rank"))); continue; } if (onlyExplicitlyIncluded) continue; if (oldIncludes != null) { - if (child.getKind() == Kind.FIELD && oldIncludes.contains(name)) members.add(new Included(child, null, false)); + if (child.getKind() == Kind.FIELD && oldIncludes.contains(name)) members.add(new Included(child, null, false, false)); continue; } if (child.getKind() != Kind.FIELD) continue; @@ -178,7 +184,7 @@ public class InclusionExclusionUtils { if (child.isTransient() && !includeTransient) continue; if (name.startsWith("$")) continue; if (child.isEnumMember()) continue; - members.add(new Included(child, null, true)); + members.add(new Included(child, null, true, false)); } /* delete default-included fields with the same name as an explicit inclusion */ { @@ -219,8 +225,8 @@ public class InclusionExclusionUtils { Collections.sort(members, new Comparator>() { @Override public int compare(Included a, Included b) { - int ra = a.getInc() == null ? 0 : a.getInc().rank(); - int rb = b.getInc() == null ? 0 : b.getInc().rank(); + int ra = a.hasExplicitRank() ? a.getInc().rank() : a.node.isPrimitive() ? 1000 : 0; + int rb = b.hasExplicitRank() ? b.getInc().rank() : b.node.isPrimitive() ? 1000 : 0; return compareRankOrPosition(ra, rb, a.getNode(), b.getNode()); } diff --git a/src/core/lombok/eclipse/EclipseNode.java b/src/core/lombok/eclipse/EclipseNode.java index 9db491f5..5aa29466 100644 --- a/src/core/lombok/eclipse/EclipseNode.java +++ b/src/core/lombok/eclipse/EclipseNode.java @@ -23,10 +23,6 @@ package lombok.eclipse; import java.util.List; -import lombok.core.AnnotationValues; -import lombok.core.AST.Kind; -import lombok.eclipse.handlers.EclipseHandlerUtil; - import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.Annotation; @@ -36,11 +32,16 @@ import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.Initializer; import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; +import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.Statement; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import lombok.core.AST.Kind; +import lombok.core.AnnotationValues; +import lombok.eclipse.handlers.EclipseHandlerUtil; + /** * Eclipse specific version of the LombokNode class. */ @@ -264,6 +265,16 @@ public class EclipseNode extends lombok.core.LombokNode { List> fieldNodes = new ArrayList>(); for (BuilderFieldData bfd : builderFields) { for (EclipseNode f : bfd.createdFields) { - fieldNodes.add(new Included(f, null, true)); + fieldNodes.add(new Included(f, null, true, false)); } } MethodDeclaration md = HandleToString.createToString(builderType, fieldNodes, true, false, ast, FieldAccess.ALWAYS_FIELD); diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java index 7c8e4ea3..cc4d55be 100644 --- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java @@ -354,7 +354,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { List> fieldNodes = new ArrayList>(); for (BuilderFieldData bfd : builderFields) { for (EclipseNode f : bfd.createdFields) { - fieldNodes.add(new Included(f, null, true)); + fieldNodes.add(new Included(f, null, true, false)); } } // Let toString() call super.toString() if there is a superclass, so that it also shows fields from the superclass' builder. diff --git a/src/core/lombok/javac/JavacNode.java b/src/core/lombok/javac/JavacNode.java index 19bbeae3..08d22d98 100644 --- a/src/core/lombok/javac/JavacNode.java +++ b/src/core/lombok/javac/JavacNode.java @@ -27,10 +27,6 @@ import java.util.List; import javax.lang.model.element.Element; import javax.tools.Diagnostic; -import lombok.core.AnnotationValues; -import lombok.core.AST.Kind; -import lombok.javac.handlers.JavacHandlerUtil; - import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.model.JavacTypes; @@ -43,8 +39,12 @@ import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCModifiers; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; +import com.sun.tools.javac.util.Name; + +import lombok.core.AST.Kind; +import lombok.core.AnnotationValues; +import lombok.javac.handlers.JavacHandlerUtil; /** * Javac specific version of the LombokNode class. @@ -345,6 +345,16 @@ public class JavacNode extends lombok.core.LombokNode { java.util.List> fieldNodes = new ArrayList>(); for (BuilderFieldData bfd : builderFields) { for (JavacNode f : bfd.createdFields) { - fieldNodes.add(new Included(f, null, true)); + fieldNodes.add(new Included(f, null, true, false)); } } diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java index 4cd64b77..f6bf9e1f 100644 --- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java @@ -304,7 +304,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler { java.util.List> fieldNodes = new ArrayList>(); for (BuilderFieldData bfd : builderFields) { for (JavacNode f : bfd.createdFields) { - fieldNodes.add(new Included(f, null, true)); + fieldNodes.add(new Included(f, null, true, false)); } } diff --git a/test/transform/resource/after-delombok/BuilderDefaults.java b/test/transform/resource/after-delombok/BuilderDefaults.java index 5a563024..42b751ce 100644 --- a/test/transform/resource/after-delombok/BuilderDefaults.java +++ b/test/transform/resource/after-delombok/BuilderDefaults.java @@ -85,10 +85,10 @@ public final class BuilderDefaults { if (!(o instanceof BuilderDefaults)) return false; final BuilderDefaults other = (BuilderDefaults) o; if (this.getX() != other.getX()) return false; + if (this.getZ() != other.getZ()) return false; final java.lang.Object this$name = this.getName(); final java.lang.Object other$name = other.getName(); if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false; - if (this.getZ() != other.getZ()) return false; return true; } @java.lang.Override @@ -97,10 +97,10 @@ public final class BuilderDefaults { final int PRIME = 59; int result = 1; result = result * PRIME + this.getX(); - final java.lang.Object $name = this.getName(); - result = result * PRIME + ($name == null ? 43 : $name.hashCode()); final long $z = this.getZ(); result = result * PRIME + (int) ($z >>> 32 ^ $z); + final java.lang.Object $name = this.getName(); + result = result * PRIME + ($name == null ? 43 : $name.hashCode()); return result; } @java.lang.Override @@ -108,4 +108,4 @@ public final class BuilderDefaults { public java.lang.String toString() { return "BuilderDefaults(x=" + this.getX() + ", name=" + this.getName() + ", z=" + this.getZ() + ")"; } -} +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/EqualsAndHashCodeRank.java b/test/transform/resource/after-delombok/EqualsAndHashCodeRank.java index ad2ddbb1..fcf371b6 100644 --- a/test/transform/resource/after-delombok/EqualsAndHashCodeRank.java +++ b/test/transform/resource/after-delombok/EqualsAndHashCodeRank.java @@ -9,9 +9,9 @@ public class EqualsAndHashCodeRank { if (!(o instanceof EqualsAndHashCodeRank)) return false; final EqualsAndHashCodeRank other = (EqualsAndHashCodeRank) o; if (!other.canEqual((java.lang.Object) this)) return false; - if (this.b != other.b) return false; if (this.a != other.a) return false; if (this.c != other.c) return false; + if (this.b != other.b) return false; return true; } @java.lang.SuppressWarnings("all") @@ -23,9 +23,9 @@ public class EqualsAndHashCodeRank { public int hashCode() { final int PRIME = 59; int result = 1; - result = result * PRIME + this.b; result = result * PRIME + this.a; result = result * PRIME + this.c; + result = result * PRIME + this.b; return result; } -} +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/BuilderDefaults.java b/test/transform/resource/after-ecj/BuilderDefaults.java index 46f55bef..c9be219d 100644 --- a/test/transform/resource/after-ecj/BuilderDefaults.java +++ b/test/transform/resource/after-ecj/BuilderDefaults.java @@ -72,25 +72,25 @@ public final @Value @Builder class BuilderDefaults { final BuilderDefaults other = (BuilderDefaults) o; if ((this.getX() != other.getX())) return false; + if ((this.getZ() != other.getZ())) + return false; final java.lang.Object this$name = this.getName(); final java.lang.Object other$name = other.getName(); if (((this$name == null) ? (other$name != null) : (! this$name.equals(other$name)))) return false; - if ((this.getZ() != other.getZ())) - return false; return true; } public @java.lang.Override @java.lang.SuppressWarnings("all") int hashCode() { final int PRIME = 59; int result = 1; result = ((result * PRIME) + this.getX()); - final java.lang.Object $name = this.getName(); - result = ((result * PRIME) + (($name == null) ? 43 : $name.hashCode())); final long $z = this.getZ(); result = ((result * PRIME) + (int) ($z ^ ($z >>> 32))); + final java.lang.Object $name = this.getName(); + result = ((result * PRIME) + (($name == null) ? 43 : $name.hashCode())); return result; } public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { return (((((("BuilderDefaults(x=" + this.getX()) + ", name=") + this.getName()) + ", z=") + this.getZ()) + ")"); } -} +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/EqualsAndHashCodeRank.java b/test/transform/resource/after-ecj/EqualsAndHashCodeRank.java index 1ea899a8..ef221261 100644 --- a/test/transform/resource/after-ecj/EqualsAndHashCodeRank.java +++ b/test/transform/resource/after-ecj/EqualsAndHashCodeRank.java @@ -7,18 +7,18 @@ public @EqualsAndHashCode class EqualsAndHashCodeRank { super(); } public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) { - if (o == this) + if ((o == this)) return true; - if (!(o instanceof EqualsAndHashCodeRank)) + if ((! (o instanceof EqualsAndHashCodeRank))) return false; final EqualsAndHashCodeRank other = (EqualsAndHashCodeRank) o; - if (!other.canEqual((java.lang.Object) this)) + if ((! other.canEqual((java.lang.Object) this))) return false; - if (this.b != other.b) + if ((this.a != other.a)) return false; - if (this.a != other.a) + if ((this.c != other.c)) return false; - if (this.c != other.c) + if ((this.b != other.b)) return false; return true; } @@ -28,9 +28,9 @@ public @EqualsAndHashCode class EqualsAndHashCodeRank { public @java.lang.Override @java.lang.SuppressWarnings("all") int hashCode() { final int PRIME = 59; int result = 1; - result = result * PRIME + this.b; - result = result * PRIME + this.a; - result = result * PRIME + this.c; + result = ((result * PRIME) + this.a); + result = ((result * PRIME) + this.c); + result = ((result * PRIME) + this.b); return result; } } -- cgit From ed8ea0d8043cb8df6ae3fb962ab3a2087f4adeb6 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Fri, 19 Jun 2020 00:47:00 +0200 Subject: #1543: First primitives, then primitive wrappers, then other references --- doc/changelog.markdown | 2 +- src/core/lombok/EqualsAndHashCode.java | 2 +- src/core/lombok/core/LombokNode.java | 13 ++++++++++++ src/core/lombok/core/handlers/HandlerUtil.java | 21 ++++++++++++++++++++ .../core/handlers/InclusionExclusionUtils.java | 4 ++-- src/core/lombok/eclipse/EclipseNode.java | 23 ++++++++++++++++++++++ src/core/lombok/javac/JavacNode.java | 13 ++++++++++++ src/utils/lombok/eclipse/Eclipse.java | 7 ++----- src/utils/lombok/javac/Javac.java | 19 ++++++++---------- .../after-delombok/ValueStaticConstructorOf.java | 10 +++++----- .../after-ecj/ValueStaticConstructorOf.java | 14 ++++++------- 11 files changed, 96 insertions(+), 32 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/doc/changelog.markdown b/doc/changelog.markdown index af77d480..952d9384 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -2,7 +2,7 @@ Lombok Changelog ---------------- ### v1.18.13 "Edgy Guinea Pig" -* PERFORMANCE: The generated equals method will first compare primitives. Manual re-ordering is possible using `@Include(rank=n)`. [Pull Request #2485](https://github.com/rzwitserloot/lombok/pull/2485), [Issue #1543](https://github.com/rzwitserloot/lombok/issues/1543) +* PERFORMANCE: The generated equals method will first compare primitives, then primitive wrappers and then reference fields. Manual re-ordering is possible using `@Include(rank=n)`. [Pull Request #2485](https://github.com/rzwitserloot/lombok/pull/2485), [Issue #1543](https://github.com/rzwitserloot/lombok/issues/1543) * IMPROBABLE BREAKING CHANGE: The generated hashcode has changed for classes that include both primitive fields and reference fields. * PLATFORM: Added support for compiling projects with OpenJ9 [Pull Request #2437](https://github.com/rzwitserloot/lombok/pull/2437) * BREAKING CHANGE: mapstruct users should now add a dependency to lombok-mapstruct-binding. This solves compiling modules with lombok (and mapstruct). diff --git a/src/core/lombok/EqualsAndHashCode.java b/src/core/lombok/EqualsAndHashCode.java index 2f53bdec..6805d214 100644 --- a/src/core/lombok/EqualsAndHashCode.java +++ b/src/core/lombok/EqualsAndHashCode.java @@ -126,7 +126,7 @@ public @interface EqualsAndHashCode { /** * Higher ranks are considered first. Members of the same rank are considered in the order they appear in the source file. * - * If not explicitly set, the {@code default} rank for primitives is 1000. + * If not explicitly set, the {@code default} rank for primitives is 1000, and for primitive wrappers 800. * * @return ordering within the generating {@code equals} and {@code hashCode} methods; higher numbers are considered first. */ diff --git a/src/core/lombok/core/LombokNode.java b/src/core/lombok/core/LombokNode.java index 46054077..abfc66a6 100644 --- a/src/core/lombok/core/LombokNode.java +++ b/src/core/lombok/core/LombokNode.java @@ -292,6 +292,19 @@ public abstract class LombokNode, L extends LombokNode node, ConfigurationKey key, String featureName) { FlagUsageType fut = node.getAst().readConfiguration(key); @@ -742,4 +744,23 @@ public class HandlerUtil { } return b.toString(); } + + /** 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)$"); + + public static boolean isPrimitive(String typeName) { + return PRIMITIVE_TYPE_NAME_PATTERN.matcher(typeName).matches(); + } + + /** Matches any of the 8 primitive wrapper names, such as {@code Boolean}. */ + private static final Pattern PRIMITIVE_WRAPPER_TYPE_NAME_PATTERN = Pattern.compile("^(?:java\\.lang\\.)?(?:Boolean|Byte|Short|Integer|Long|Float|Double|Character)$"); + + public static int defaultEqualsAndHashcodeIncludeRank(String typeName) { + // Modification in this code should be documented + // 1. In the changelog this should be marked as an INPROBABLE BREAKING CHANGE, since the hashcode will change + // 2. In the javadoc of EqualsAndHashcode.Include#rank + if (isPrimitive(typeName)) return 1000; + if (PRIMITIVE_WRAPPER_TYPE_NAME_PATTERN.matcher(typeName).matches()) return 800; + return 0; + } } diff --git a/src/core/lombok/core/handlers/InclusionExclusionUtils.java b/src/core/lombok/core/handlers/InclusionExclusionUtils.java index 609a5e36..e785db3f 100644 --- a/src/core/lombok/core/handlers/InclusionExclusionUtils.java +++ b/src/core/lombok/core/handlers/InclusionExclusionUtils.java @@ -225,8 +225,8 @@ public class InclusionExclusionUtils { Collections.sort(members, new Comparator>() { @Override public int compare(Included a, Included b) { - int ra = a.hasExplicitRank() ? a.getInc().rank() : a.node.isPrimitive() ? 1000 : 0; - int rb = b.hasExplicitRank() ? b.getInc().rank() : b.node.isPrimitive() ? 1000 : 0; + int ra = a.hasExplicitRank() ? a.getInc().rank() : HandlerUtil.defaultEqualsAndHashcodeIncludeRank(a.node.fieldOrMethodBaseType()); + int rb = b.hasExplicitRank() ? b.getInc().rank() : HandlerUtil.defaultEqualsAndHashcodeIncludeRank(b.node.fieldOrMethodBaseType()); return compareRankOrPosition(ra, rb, a.getNode(), b.getNode()); } diff --git a/src/core/lombok/eclipse/EclipseNode.java b/src/core/lombok/eclipse/EclipseNode.java index 5aa29466..12e9ccdb 100644 --- a/src/core/lombok/eclipse/EclipseNode.java +++ b/src/core/lombok/eclipse/EclipseNode.java @@ -275,6 +275,29 @@ public class EclipseNode extends lombok.core.LombokNode 0) return false; - return PRIMITIVE_TYPE_NAME_PATTERN.matcher(toQualifiedName(ref.getTypeName())).matches(); + return HandlerUtil.isPrimitive(toQualifiedName(ref.getTypeName())); } /** diff --git a/src/utils/lombok/javac/Javac.java b/src/utils/lombok/javac/Javac.java index 3cc72f4e..234c7f73 100644 --- a/src/utils/lombok/javac/Javac.java +++ b/src/utils/lombok/javac/Javac.java @@ -37,12 +37,6 @@ import javax.lang.model.type.NoType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeVisitor; -import lombok.core.ClassLiteral; -import lombok.core.FieldSelect; -import lombok.javac.JavacTreeMaker.TreeTag; -import lombok.javac.JavacTreeMaker.TypeTag; -import lombok.permit.Permit; - import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Source; import com.sun.tools.javac.code.Symtab; @@ -61,6 +55,13 @@ import com.sun.tools.javac.tree.JCTree.JCLiteral; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; +import lombok.core.ClassLiteral; +import lombok.core.FieldSelect; +import lombok.core.handlers.HandlerUtil; +import lombok.javac.JavacTreeMaker.TreeTag; +import lombok.javac.JavacTreeMaker.TypeTag; +import lombok.permit.Permit; + /** * Container for static utility methods relevant to lombok's operation on javac. */ @@ -69,9 +70,6 @@ public class Javac { // prevent instantiation } - /** 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)$"); - private static final Pattern VERSION_PARSER = Pattern.compile("^(\\d{1,6})\\.?(\\d{1,6})?.*$"); private static final Pattern SOURCE_PARSER = Pattern.compile("^JDK(\\d{1,6})_?(\\d{1,6})?.*$"); @@ -135,8 +133,7 @@ public class Javac { * expression) represents a primitive type. */ public static boolean isPrimitive(JCExpression ref) { - String typeName = ref.toString(); - return PRIMITIVE_TYPE_NAME_PATTERN.matcher(typeName).matches(); + return HandlerUtil.isPrimitive(ref.toString()); } /** diff --git a/test/transform/resource/after-delombok/ValueStaticConstructorOf.java b/test/transform/resource/after-delombok/ValueStaticConstructorOf.java index fe75f823..e4564628 100644 --- a/test/transform/resource/after-delombok/ValueStaticConstructorOf.java +++ b/test/transform/resource/after-delombok/ValueStaticConstructorOf.java @@ -23,12 +23,12 @@ public final class ValueStaticConstructorOf { if (o == this) return true; if (!(o instanceof ValueStaticConstructorOf)) return false; final ValueStaticConstructorOf other = (ValueStaticConstructorOf) o; - final java.lang.Object this$name = this.getName(); - final java.lang.Object other$name = other.getName(); - if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false; final java.lang.Object this$price = this.getPrice(); final java.lang.Object other$price = other.getPrice(); if (this$price == null ? other$price != null : !this$price.equals(other$price)) return false; + final java.lang.Object this$name = this.getName(); + final java.lang.Object other$name = other.getName(); + if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false; return true; } @java.lang.Override @@ -36,10 +36,10 @@ public final class ValueStaticConstructorOf { public int hashCode() { final int PRIME = 59; int result = 1; - final java.lang.Object $name = this.getName(); - result = result * PRIME + ($name == null ? 43 : $name.hashCode()); final java.lang.Object $price = this.getPrice(); result = result * PRIME + ($price == null ? 43 : $price.hashCode()); + final java.lang.Object $name = this.getName(); + result = result * PRIME + ($name == null ? 43 : $name.hashCode()); return result; } @java.lang.Override diff --git a/test/transform/resource/after-ecj/ValueStaticConstructorOf.java b/test/transform/resource/after-ecj/ValueStaticConstructorOf.java index 6cf71ed4..87883566 100644 --- a/test/transform/resource/after-ecj/ValueStaticConstructorOf.java +++ b/test/transform/resource/after-ecj/ValueStaticConstructorOf.java @@ -19,23 +19,23 @@ public final @Value(staticConstructor = "of") class ValueStaticConstructorOf { if ((! (o instanceof ValueStaticConstructorOf))) return false; final ValueStaticConstructorOf other = (ValueStaticConstructorOf) o; - final java.lang.Object this$name = this.getName(); - final java.lang.Object other$name = other.getName(); - if (((this$name == null) ? (other$name != null) : (! this$name.equals(other$name)))) - return false; final java.lang.Object this$price = this.getPrice(); final java.lang.Object other$price = other.getPrice(); if (((this$price == null) ? (other$price != null) : (! this$price.equals(other$price)))) return false; + final java.lang.Object this$name = this.getName(); + final java.lang.Object other$name = other.getName(); + if (((this$name == null) ? (other$name != null) : (! this$name.equals(other$name)))) + return false; return true; } public @java.lang.Override @java.lang.SuppressWarnings("all") int hashCode() { final int PRIME = 59; int result = 1; - final java.lang.Object $name = this.getName(); - result = ((result * PRIME) + (($name == null) ? 43 : $name.hashCode())); final java.lang.Object $price = this.getPrice(); result = ((result * PRIME) + (($price == null) ? 43 : $price.hashCode())); + final java.lang.Object $name = this.getName(); + result = ((result * PRIME) + (($name == null) ? 43 : $name.hashCode())); return result; } public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { @@ -44,4 +44,4 @@ public final @Value(staticConstructor = "of") class ValueStaticConstructorOf { public static @java.lang.SuppressWarnings("all") ValueStaticConstructorOf of(final String name, final Double price) { return new ValueStaticConstructorOf(name, price); } -} \ No newline at end of file +} -- cgit From e964c995caa948e3b9ac3fc531a09e200124ec73 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Wed, 24 Jun 2020 22:12:39 +0200 Subject: Fix UtilityClass test case --- src/core/lombok/eclipse/handlers/HandleUtilityClass.java | 2 +- src/core/lombok/javac/handlers/HandleUtilityClass.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/eclipse/handlers/HandleUtilityClass.java b/src/core/lombok/eclipse/handlers/HandleUtilityClass.java index ada09d0e..2349f839 100644 --- a/src/core/lombok/eclipse/handlers/HandleUtilityClass.java +++ b/src/core/lombok/eclipse/handlers/HandleUtilityClass.java @@ -113,7 +113,7 @@ public class HandleUtilityClass extends EclipseAnnotationHandler { if (typeNode.up().getKind() == Kind.COMPILATION_UNIT) markStatic = false; if (markStatic && typeNode.up().getKind() == Kind.TYPE) { TypeDeclaration typeDecl = (TypeDeclaration) typeNode.up().get(); - if ((typeDecl.modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0) markStatic = false; + if ((typeDecl.modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation)) != 0) markStatic = false; } if (markStatic) classDecl.modifiers |= ClassFileConstants.AccStatic; diff --git a/src/core/lombok/javac/handlers/HandleUtilityClass.java b/src/core/lombok/javac/handlers/HandleUtilityClass.java index 95de4c47..5d651689 100644 --- a/src/core/lombok/javac/handlers/HandleUtilityClass.java +++ b/src/core/lombok/javac/handlers/HandleUtilityClass.java @@ -110,7 +110,7 @@ public class HandleUtilityClass extends JavacAnnotationHandler { if (typeNode.up().getKind() == Kind.COMPILATION_UNIT) markStatic = false; if (markStatic && typeNode.up().getKind() == Kind.TYPE) { JCClassDecl typeDecl = (JCClassDecl) typeNode.up().get(); - if ((typeDecl.mods.flags & (Flags.INTERFACE | Flags.ANNOTATION | Flags.ENUM)) != 0) markStatic = false; + if ((typeDecl.mods.flags & (Flags.INTERFACE | Flags.ANNOTATION)) != 0) markStatic = false; } if (markStatic) classDecl.mods.flags |= Flags.STATIC; -- cgit From 4e359da7cc079c8283f758f464b65f1bcaa78a7b Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Fri, 19 Jun 2020 17:25:41 +0200 Subject: Replace getSimpleName() with getName() --- src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java | 11 ++--------- src/core/lombok/javac/JavacAST.java | 4 ++-- 2 files changed, 4 insertions(+), 11 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 6b9571c7..1b4f510c 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -233,14 +233,7 @@ public class EclipseHandlerUtil { * @param typeRef A type reference to check. */ public static boolean typeMatches(Class type, EclipseNode node, TypeReference typeRef) { - if (typeRef == null || typeRef.getTypeName() == null || typeRef.getTypeName().length == 0) return false; - String lastPartA = new String(typeRef.getTypeName()[typeRef.getTypeName().length -1]); - String lastPartB = type.getSimpleName(); - if (!lastPartA.equals(lastPartB)) return false; - String typeName = toQualifiedName(typeRef.getTypeName()); - - TypeResolver resolver = new TypeResolver(node.getImportList()); - return resolver.typeMatches(node, type.getName(), typeName); + return typeMatches(type.getName(), node, typeRef); } /** @@ -254,7 +247,7 @@ public class EclipseHandlerUtil { char[][] tn = typeRef == null ? null : typeRef.getTypeName(); if (tn == null || tn.length == 0) return false; char[] lastPartA = tn[tn.length - 1]; - int lastIndex = type.lastIndexOf('.') + 1; + int lastIndex = Math.max(type.lastIndexOf('.'), type.lastIndexOf('$')) + 1; if (lastPartA.length != type.length() - lastIndex) return false; for (int i = 0; i < lastPartA.length; i++) if (lastPartA[i] != type.charAt(i + lastIndex)) return false; String typeName = toQualifiedName(tn); diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index f6cd5571..bb5cfc61 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -258,7 +258,7 @@ public class JavacAST extends AST { if (typeUse == null) return null; - if (typeUse.getClass().getSimpleName().equals("JCAnnotatedType")) { + if (typeUse.getClass().getName().equals("com.sun.tools.javac.tree.JCTree$JCAnnotatedType")) { initJcAnnotatedType(typeUse.getClass()); Collection anns = Permit.permissiveReadField(Collection.class, JCANNOTATEDTYPE_ANNOTATIONS, typeUse); JCExpression underlying = Permit.permissiveReadField(JCExpression.class, JCANNOTATEDTYPE_UNDERLYINGTYPE, typeUse); @@ -381,7 +381,7 @@ public class JavacAST extends AST { if (statement instanceof JCClassDecl) return buildType((JCClassDecl) statement); if (statement instanceof JCVariableDecl) return buildLocalVar((JCVariableDecl) statement, Kind.LOCAL); if (statement instanceof JCTry) return buildTry((JCTry) statement); - if (statement.getClass().getSimpleName().equals("JCLambda")) return buildLambda(statement); + if (statement.getClass().getName().equals("com.sun.tools.javac.tree.JCTree$JCLambda")) return buildLambda(statement); if (setAndGetAsHandled(statement)) return null; return drill(statement); -- cgit From 3ffef5d23be17e9bffca30936d43bca852feaa93 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Sun, 21 Jun 2020 13:45:32 +0200 Subject: Prevent NullPointerException --- src/core/lombok/eclipse/EclipseAST.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/eclipse/EclipseAST.java b/src/core/lombok/eclipse/EclipseAST.java index e724fb50..b45ac72d 100644 --- a/src/core/lombok/eclipse/EclipseAST.java +++ b/src/core/lombok/eclipse/EclipseAST.java @@ -318,6 +318,7 @@ public class EclipseAST extends AST { Field f = EcjReflectionCheck.typeReferenceAnnotations; if (f == null) return null; annss = (Annotation[][]) f.get(tr); + if (annss == null) return null; return annss[annss.length - 1]; } catch (Throwable t) { return null; -- cgit From e75517d561790bf8ee01763a1c75e091d03132e9 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Thu, 25 Jun 2020 23:01:06 +0200 Subject: Avoid class.getSimpleName except in static initializers or error messages --- .../core/handlers/InclusionExclusionUtils.java | 9 +++----- .../lombok/eclipse/handlers/HandleConstructor.java | 10 ++++++--- .../lombok/javac/handlers/HandleConstructor.java | 9 +++++--- src/delombok/lombok/delombok/PrettyPrinter.java | 24 +++++++++++----------- src/utils/lombok/javac/JavacTreeMaker.java | 5 +---- .../javac/java8/CommentCollectingTokenizer.java | 4 ++-- 6 files changed, 31 insertions(+), 30 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/core/handlers/InclusionExclusionUtils.java b/src/core/lombok/core/handlers/InclusionExclusionUtils.java index e785db3f..0aa6c47b 100644 --- a/src/core/lombok/core/handlers/InclusionExclusionUtils.java +++ b/src/core/lombok/core/handlers/InclusionExclusionUtils.java @@ -112,7 +112,7 @@ public class InclusionExclusionUtils { return name; } - public static , L extends LombokNode, N, I extends Annotation> List> handleIncludeExcludeMarking(Class inclType, String replaceName, Class exclType, LombokNode typeNode, AnnotationValues annotation, LombokNode annotationNode, boolean includeTransient) { + private static , L extends LombokNode, N, I extends Annotation> List> handleIncludeExcludeMarking(Class inclType, String replaceName, Class exclType, LombokNode typeNode, AnnotationValues annotation, LombokNode annotationNode, boolean includeTransient) { List oldExcludes = (annotation != null && annotation.isExplicit("exclude")) ? annotation.getAsStringList("exclude") : null; List oldIncludes = (annotation != null && annotation.isExplicit("of")) ? annotation.getAsStringList("of") : null; @@ -124,9 +124,6 @@ public class InclusionExclusionUtils { if (typeNode == null || typeNode.getKind() != Kind.TYPE) return null; checkForBogusFieldNames(typeNode, annotation, oldExcludes, oldIncludes); - String inclTypeName = innerAnnName(inclType); - String exclTypeName = innerAnnName(exclType); - if (oldExcludes != null && oldIncludes != null) { oldExcludes = null; if (annotation != null) annotation.setWarning("exclude", "exclude and of are mutually exclusive; the 'exclude' parameter will be ignored."); @@ -140,7 +137,7 @@ public class InclusionExclusionUtils { if (markExclude || markInclude != null) memberAnnotationMode = true; if (markInclude != null && markExclude) { - child.addError("@" + exclTypeName + " and @" + inclTypeName + " are mutually exclusive; the @Include annotation will be ignored"); + child.addError("@" + innerAnnName(exclType) + " and @" + innerAnnName(inclType) + " are mutually exclusive; the @Include annotation will be ignored"); markInclude = null; } @@ -163,7 +160,7 @@ public class InclusionExclusionUtils { I inc = markInclude.getInstance(); if (child.getKind() == Kind.METHOD) { if (child.countMethodParameters() > 0) { - child.addError("Methods included with @" + inclTypeName + " must have no arguments; it will not be included"); + child.addError("Methods included with @" + innerAnnName(inclType) + " must have no arguments; it will not be included"); continue; } String n = replaceName != null ? markInclude.getAsString(replaceName) : ""; diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java index 129fa7c0..06c9ecd9 100755 --- a/src/core/lombok/eclipse/handlers/HandleConstructor.java +++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java @@ -84,13 +84,14 @@ import org.mangosdk.spi.ProviderFor; public class HandleConstructor { @ProviderFor(EclipseAnnotationHandler.class) public static class HandleNoArgsConstructor extends EclipseAnnotationHandler { + private static final String NAME = NoArgsConstructor.class.getSimpleName(); private HandleConstructor handleConstructor = new HandleConstructor(); @Override public void handle(AnnotationValues annotation, Annotation ast, EclipseNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.NO_ARGS_CONSTRUCTOR_FLAG_USAGE, "@NoArgsConstructor", ConfigurationKeys.ANY_CONSTRUCTOR_FLAG_USAGE, "any @xArgsConstructor"); EclipseNode typeNode = annotationNode.up(); - if (!checkLegality(typeNode, annotationNode, NoArgsConstructor.class.getSimpleName())) return; + if (!checkLegality(typeNode, annotationNode, NAME)) return; NoArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); String staticName = ann.staticName(); @@ -106,13 +107,14 @@ public class HandleConstructor { @ProviderFor(EclipseAnnotationHandler.class) public static class HandleRequiredArgsConstructor extends EclipseAnnotationHandler { + private static final String NAME = RequiredArgsConstructor.class.getSimpleName(); private HandleConstructor handleConstructor = new HandleConstructor(); @Override public void handle(AnnotationValues annotation, Annotation ast, EclipseNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.REQUIRED_ARGS_CONSTRUCTOR_FLAG_USAGE, "@RequiredArgsConstructor", ConfigurationKeys.ANY_CONSTRUCTOR_FLAG_USAGE, "any @xArgsConstructor"); EclipseNode typeNode = annotationNode.up(); - if (!checkLegality(typeNode, annotationNode, RequiredArgsConstructor.class.getSimpleName())) return; + if (!checkLegality(typeNode, annotationNode, NAME)) return; RequiredArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); if (level == AccessLevel.NONE) return; @@ -166,13 +168,15 @@ public class HandleConstructor { @ProviderFor(EclipseAnnotationHandler.class) public static class HandleAllArgsConstructor extends EclipseAnnotationHandler { + private static final String NAME = AllArgsConstructor.class.getSimpleName(); + private HandleConstructor handleConstructor = new HandleConstructor(); @Override public void handle(AnnotationValues annotation, Annotation ast, EclipseNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.ALL_ARGS_CONSTRUCTOR_FLAG_USAGE, "@AllArgsConstructor", ConfigurationKeys.ANY_CONSTRUCTOR_FLAG_USAGE, "any @xArgsConstructor"); EclipseNode typeNode = annotationNode.up(); - if (!checkLegality(typeNode, annotationNode, AllArgsConstructor.class.getSimpleName())) return; + if (!checkLegality(typeNode, annotationNode, NAME)) return; AllArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); if (level == AccessLevel.NONE) return; diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index e0abb53b..2a683767 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -68,6 +68,7 @@ import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult; public class HandleConstructor { @ProviderFor(JavacAnnotationHandler.class) public static class HandleNoArgsConstructor extends JavacAnnotationHandler { + private static final String NAME = NoArgsConstructor.class.getSimpleName(); private HandleConstructor handleConstructor = new HandleConstructor(); @Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { @@ -76,7 +77,7 @@ public class HandleConstructor { deleteAnnotationIfNeccessary(annotationNode, NoArgsConstructor.class); deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); JavacNode typeNode = annotationNode.up(); - if (!checkLegality(typeNode, annotationNode, NoArgsConstructor.class.getSimpleName())) return; + if (!checkLegality(typeNode, annotationNode, NAME)) return; List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@NoArgsConstructor(onConstructor", annotationNode); NoArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); @@ -89,6 +90,7 @@ public class HandleConstructor { @ProviderFor(JavacAnnotationHandler.class) public static class HandleRequiredArgsConstructor extends JavacAnnotationHandler { + private static final String NAME = RequiredArgsConstructor.class.getSimpleName(); private HandleConstructor handleConstructor = new HandleConstructor(); @Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { @@ -97,7 +99,7 @@ public class HandleConstructor { deleteAnnotationIfNeccessary(annotationNode, RequiredArgsConstructor.class); deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); JavacNode typeNode = annotationNode.up(); - if (!checkLegality(typeNode, annotationNode, RequiredArgsConstructor.class.getSimpleName())) return; + if (!checkLegality(typeNode, annotationNode, NAME)) return; List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@RequiredArgsConstructor(onConstructor", annotationNode); RequiredArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); @@ -138,6 +140,7 @@ public class HandleConstructor { @ProviderFor(JavacAnnotationHandler.class) public static class HandleAllArgsConstructor extends JavacAnnotationHandler { + private static final String NAME = AllArgsConstructor.class.getSimpleName(); private HandleConstructor handleConstructor = new HandleConstructor(); @Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { @@ -146,7 +149,7 @@ public class HandleConstructor { deleteAnnotationIfNeccessary(annotationNode, AllArgsConstructor.class); deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); JavacNode typeNode = annotationNode.up(); - if (!checkLegality(typeNode, annotationNode, AllArgsConstructor.class.getSimpleName())) return; + if (!checkLegality(typeNode, annotationNode, NAME)) return; List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@AllArgsConstructor(onConstructor", annotationNode); AllArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java index 7eb8410b..238dd379 100644 --- a/src/delombok/lombok/delombok/PrettyPrinter.java +++ b/src/delombok/lombok/delombok/PrettyPrinter.java @@ -1323,7 +1323,7 @@ public class PrettyPrinter extends JCTree.Visitor { print(";"); needsNewLine = true; needsAlign = true; - } else if (tree.stats.head.getClass().getSimpleName().equals("JCYield")) { + } else if (tree.stats.head.getClass().getName().endsWith("$JCYield")) { print((JCExpression) readObject(tree.stats.head, "value", null)); print(";"); needsNewLine = true; @@ -1600,25 +1600,25 @@ public class PrettyPrinter extends JCTree.Visitor { } @Override public void visitTree(JCTree tree) { - String simpleName = tree.getClass().getSimpleName(); - if ("JCTypeUnion".equals(simpleName)) { + String className = tree.getClass().getName(); + if (className.endsWith("$JCTypeUnion")) { List types = readObject(tree, "alternatives", List.nil()); print(types, " | "); - } else if ("JCTypeIntersection".equals(simpleName)) { + } else if (className.endsWith("$JCTypeIntersection")) { print(readObject(tree, "bounds", List.nil()), " & "); - } else if ("JCMemberReference".equals(simpleName)) { + } else if (className.endsWith("$JCMemberReference")) { printMemberReference0(tree); - } else if ("JCLambda".equals(simpleName)) { + } else if (className.endsWith("$JCLambda")) { printLambda0(tree); - } else if ("JCAnnotatedType".equals(simpleName)) { + } else if (className.endsWith("$JCAnnotatedType")) { printAnnotatedType0(tree); - } else if ("JCPackageDecl".equals(simpleName)) { + } else if (className.endsWith("$JCPackageDecl")) { // Starting with JDK9, this is inside the import list, but we've already printed it. Just ignore it. - } else if ("JCSwitchExpression".equals(simpleName)) { // Introduced as preview feature in JDK12 + } else if (className.endsWith(".JCSwitchExpression")) { // Introduced as preview feature in JDK12 printSwitchExpression(tree); - } else if ("JCYield".equals(simpleName)) { // Introduced as preview feature in JDK13, part of switch expressions. + } else if (className.endsWith("$JCYield")) { // Introduced as preview feature in JDK13, part of switch expressions. printYieldExpression(tree); - } else if ("JCBindingPattern".equals(simpleName)) { // Introduced as preview in JDK14 + } else if (className.endsWith("$JCBindingPattern")) { // Introduced as preview in JDK14 printBindingPattern(tree); } else { throw new AssertionError("Unhandled tree type: " + tree.getClass() + ": " + tree); @@ -1638,7 +1638,7 @@ public class PrettyPrinter extends JCTree.Visitor { if (o == null) return false; if (jcAnnotatedTypeInit) return jcAnnotatedTypeClass == o.getClass(); Class c = o.getClass(); - if (c.getSimpleName().equals("JCAnnotatedType")) { + if (c.getName().endsWith("$JCAnnotatedType")) { jcAnnotatedTypeClass = c; jcAnnotatedTypeInit = true; return true; diff --git a/src/utils/lombok/javac/JavacTreeMaker.java b/src/utils/lombok/javac/JavacTreeMaker.java index 20f4b66d..15a11151 100644 --- a/src/utils/lombok/javac/JavacTreeMaker.java +++ b/src/utils/lombok/javac/JavacTreeMaker.java @@ -343,10 +343,7 @@ public class JavacTreeMaker { Method method = getFromCache(m); try { if (m.returnType.isPrimitive()) { - Object res = method.invoke(owner, args); - String sn = res.getClass().getSimpleName().toLowerCase(); - if (!sn.startsWith(m.returnType.getSimpleName())) throw new ClassCastException(res.getClass() + " to " + m.returnType); - return (J) res; + return (J) method.invoke(owner, args); } return m.returnType.cast(method.invoke(owner, args)); } catch (InvocationTargetException e) { diff --git a/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java b/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java index 08477e61..d7b1d569 100644 --- a/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java +++ b/src/utils/lombok/javac/java8/CommentCollectingTokenizer.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2019 The Project Lombok Authors. + * Copyright (C) 2013-2020 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -59,7 +59,7 @@ class CommentCollectingTokenizer extends JavaTokenizer { @Override public Token readToken() { Token token = super.readToken(); prevEndPosition = pos(); - if (textBlockStarts != null && (prevEndPosition - token.pos > 5) && token.getClass().getSimpleName().equals("StringToken")) { + if (textBlockStarts != null && (prevEndPosition - token.pos > 5) && token.getClass().getName().endsWith("$StringToken")) { char[] start = reader.getRawCharacters(token.pos, token.pos + 3); if (start[0] == '"' && start[1] == '"' && start[2] == '"') textBlockStarts.add(token.pos); } -- cgit From a3d71d68473d23f5cf722d8c1bff31781d6d9c66 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Wed, 24 Jun 2020 19:31:09 +0200 Subject: Fix broken test cases --- .../lombok/eclipse/handlers/HandleBuilder.java | 27 +++++++++++----------- .../eclipse/handlers/HandleSuperBuilder.java | 16 ++++++------- .../after-ecj/CheckerFrameworkSuperBuilder.java | 5 ++++ .../resource/after-ecj/SimpleTypeResolution.java | 2 ++ .../CheckerFrameworkBasic.java.messages | 2 +- .../CheckerFrameworkSuperBuilder.java.messages | 2 +- 6 files changed, 31 insertions(+), 23 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java index f848469f..801fe7e7 100755 --- a/src/core/lombok/eclipse/handlers/HandleBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java @@ -57,6 +57,7 @@ import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression; import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; +import org.eclipse.jdt.internal.compiler.ast.Receiver; import org.eclipse.jdt.internal.compiler.ast.ReturnStatement; import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; @@ -683,7 +684,7 @@ public class HandleBuilder extends EclipseAnnotationHandler { return decl; } - static Argument[] generateBuildArgs(CheckerFrameworkVersion cfv, EclipseNode type, List builderFields, ASTNode source) { + static Receiver generateBuildReceiver(CheckerFrameworkVersion cfv, EclipseNode type, List builderFields, ASTNode source) { if (!cfv.generateCalledMethods()) return null; List mandatories = new ArrayList(); @@ -706,9 +707,11 @@ public class HandleBuilder extends EclipseAnnotationHandler { } ann.memberValue = arr; } - Argument arg = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, generateTypeReference(type, source.sourceStart), Modifier.FINAL); - arg.annotations = new Annotation[] {ann}; - return new Argument[] {arg}; + + QualifiedTypeReference typeReference = (QualifiedTypeReference) generateTypeReference(type, source.sourceStart); + typeReference.annotations = new Annotation[typeReference.tokens.length][]; + typeReference.annotations[0] = new Annotation[] {ann}; + return new Receiver(new char[] { 't', 'h', 'i', 's' }, 0, typeReference, null, Modifier.FINAL); } public MethodDeclaration generateBuildMethod(CheckerFrameworkVersion cfv, EclipseNode tdParent, boolean isStatic, String name, char[] staticName, TypeReference returnType, List builderFields, EclipseNode type, TypeReference[] thrownExceptions, boolean addCleaning, ASTNode source, AccessLevel access) { @@ -802,7 +805,7 @@ public class HandleBuilder extends EclipseAnnotationHandler { if (cfv.generateSideEffectFree()) { out.annotations = new Annotation[] {generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE)}; } - out.arguments = generateBuildArgs(cfv, type, builderFields, source); + out.receiver = generateBuildReceiver(cfv, type, builderFields, source); if (staticName == null) createRelevantNonNullAnnotation(type, out); out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null); return out; @@ -953,16 +956,14 @@ public class HandleBuilder extends EclipseAnnotationHandler { MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, paramName, nameOfSetFlag, chain, toEclipseModifier(access), sourceNode, methodAnnsList, annotations != null ? Arrays.asList(copyAnnotations(source, annotations)) : Collections.emptyList()); if (cfv.generateCalledMethods()) { - Argument[] arr = setter.arguments == null ? new Argument[0] : setter.arguments; - Argument[] newArr = new Argument[arr.length + 1]; - System.arraycopy(arr, 0, newArr, 1, arr.length); - newArr[0] = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, generateTypeReference(builderType, 0), Modifier.FINAL); char[][] nameNotCalled = fromQualifiedName(CheckerFrameworkVersion.NAME__NOT_CALLED); - SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameNotCalled, poss( - source, nameNotCalled.length)), source.sourceStart); + SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameNotCalled, poss(source, nameNotCalled.length)), source.sourceStart); ann.memberValue = new StringLiteral(setterName.toCharArray(), 0, 0, 0); - newArr[0].annotations = new Annotation[] {ann}; - setter.arguments = newArr; + + QualifiedTypeReference typeReference = (QualifiedTypeReference) generateTypeReference(builderType, 0); + typeReference.annotations = new Annotation[typeReference.tokens.length][]; + typeReference.annotations[0] = new Annotation[] {ann}; + setter.receiver = new Receiver(new char[] { 't', 'h', 'i', 's' }, 0, typeReference, null, Modifier.FINAL); } injectMethod(builderType, setter); } diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java index cc4d55be..2ba456da 100644 --- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java @@ -57,6 +57,7 @@ import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; +import org.eclipse.jdt.internal.compiler.ast.Receiver; import org.eclipse.jdt.internal.compiler.ast.ReturnStatement; import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; @@ -831,7 +832,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { if (overrideAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn}; else if (overrideAnn != null) out.annotations = new Annotation[] {overrideAnn}; else if (sefAnn != null) out.annotations = new Annotation[] {sefAnn}; - out.arguments = HandleBuilder.generateBuildArgs(cfv, builderType, builderFields, source); + out.receiver = HandleBuilder.generateBuildReceiver(cfv, builderType, builderFields, source); out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null); return out; } @@ -856,7 +857,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { allocationStatement.arguments = new Expression[] {new ThisReference(0, 0)}; statements.add(new ReturnStatement(allocationStatement, 0, 0)); out.statements = statements.isEmpty() ? null : statements.toArray(new Statement[0]); - out.arguments = HandleBuilder.generateBuildArgs(cfv, builderType, builderFields, source); + out.receiver = HandleBuilder.generateBuildReceiver(cfv, builderType, builderFields, source); createRelevantNonNullAnnotation(builderType, out); out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null); return out; @@ -970,15 +971,14 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, paramName, nameOfSetFlag, returnType, returnStatement, ClassFileConstants.AccPublic, sourceNode, methodAnnsList, annosOnParam != null ? Arrays.asList(copyAnnotations(source, annosOnParam)) : Collections.emptyList()); if (cfv.generateCalledMethods()) { - Argument[] arr = setter.arguments == null ? new Argument[0] : setter.arguments; - Argument[] newArr = new Argument[arr.length + 1]; - System.arraycopy(arr, 0, newArr, 1, arr.length); - newArr[0] = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, generateTypeReference(builderType, 0), Modifier.FINAL); char[][] nameNotCalled = fromQualifiedName(CheckerFrameworkVersion.NAME__NOT_CALLED); SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameNotCalled, poss(source, nameNotCalled.length)), source.sourceStart); ann.memberValue = new StringLiteral(setterName.toCharArray(), 0, 0, 0); - newArr[0].annotations = new Annotation[] {ann}; - setter.arguments = newArr; + + QualifiedTypeReference typeReference = (QualifiedTypeReference) generateTypeReference(builderType, 0); + typeReference.annotations = new Annotation[typeReference.tokens.length][]; + typeReference.annotations[0] = new Annotation[] {ann}; + setter.receiver = new Receiver(new char[] { 't', 'h', 'i', 's' }, 0, typeReference, null, Modifier.FINAL); } injectMethod(builderType, setter); } diff --git a/test/transform/resource/after-ecj/CheckerFrameworkSuperBuilder.java b/test/transform/resource/after-ecj/CheckerFrameworkSuperBuilder.java index 5bd4e1b3..43568236 100644 --- a/test/transform/resource/after-ecj/CheckerFrameworkSuperBuilder.java +++ b/test/transform/resource/after-ecj/CheckerFrameworkSuperBuilder.java @@ -9,6 +9,7 @@ class CheckerFrameworkSuperBuilder { private @java.lang.SuppressWarnings("all") int z; private @java.lang.SuppressWarnings("all") java.util.ArrayList names; public ParentBuilder() { + super(); } protected abstract @org.checkerframework.checker.builder.qual.ReturnsReceiver @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") B self(); public abstract @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") C build(final @org.checkerframework.checker.builder.qual.CalledMethods({"y", "z"}) CheckerFrameworkSuperBuilder.Parent.ParentBuilder this); @@ -52,6 +53,7 @@ class CheckerFrameworkSuperBuilder { } private static final @java.lang.SuppressWarnings("all") class ParentBuilderImpl extends CheckerFrameworkSuperBuilder.Parent.ParentBuilder { private ParentBuilderImpl() { + super(); } protected @java.lang.Override @org.checkerframework.checker.builder.qual.ReturnsReceiver @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.Parent.ParentBuilderImpl self() { return this; @@ -98,6 +100,7 @@ class CheckerFrameworkSuperBuilder { private @java.lang.SuppressWarnings("all") boolean a$set; private @java.lang.SuppressWarnings("all") int b; public ChildBuilder() { + super(); } protected abstract @java.lang.Override @org.checkerframework.checker.builder.qual.ReturnsReceiver @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") B self(); public abstract @java.lang.Override @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") C build(final @org.checkerframework.checker.builder.qual.CalledMethods("b") CheckerFrameworkSuperBuilder.Child.ChildBuilder this); @@ -116,6 +119,7 @@ class CheckerFrameworkSuperBuilder { } private static final @java.lang.SuppressWarnings("all") class ChildBuilderImpl extends CheckerFrameworkSuperBuilder.Child.ChildBuilder { private ChildBuilderImpl() { + super(); } protected @java.lang.Override @org.checkerframework.checker.builder.qual.ReturnsReceiver @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.Child.ChildBuilderImpl self() { return this; @@ -142,5 +146,6 @@ class CheckerFrameworkSuperBuilder { } } CheckerFrameworkSuperBuilder() { + super(); } } diff --git a/test/transform/resource/after-ecj/SimpleTypeResolution.java b/test/transform/resource/after-ecj/SimpleTypeResolution.java index c413623e..d8321ca4 100644 --- a/test/transform/resource/after-ecj/SimpleTypeResolution.java +++ b/test/transform/resource/after-ecj/SimpleTypeResolution.java @@ -1,11 +1,13 @@ class SimpleTypeResolutionFail { private @Getter int x; SimpleTypeResolutionFail() { + super(); } } class SimpleTypeResolutionSuccess { private @lombok.Getter int x; SimpleTypeResolutionSuccess() { + super(); } public @java.lang.SuppressWarnings("all") int getX() { return this.x; diff --git a/test/transform/resource/messages-ecj/CheckerFrameworkBasic.java.messages b/test/transform/resource/messages-ecj/CheckerFrameworkBasic.java.messages index 9bfcba0c..8cc7fb58 100644 --- a/test/transform/resource/messages-ecj/CheckerFrameworkBasic.java.messages +++ b/test/transform/resource/messages-ecj/CheckerFrameworkBasic.java.messages @@ -1 +1 @@ -8 org.checkerframework cannot be resolved to a type +6 org.checkerframework.common cannot be resolved to a type diff --git a/test/transform/resource/messages-ecj/CheckerFrameworkSuperBuilder.java.messages b/test/transform/resource/messages-ecj/CheckerFrameworkSuperBuilder.java.messages index d385a95c..8cc7fb58 100644 --- a/test/transform/resource/messages-ecj/CheckerFrameworkSuperBuilder.java.messages +++ b/test/transform/resource/messages-ecj/CheckerFrameworkSuperBuilder.java.messages @@ -1 +1 @@ -6 org.checkerframework cannot be resolved to a type +6 org.checkerframework.common cannot be resolved to a type -- cgit From 9425e99b49d1a203c692fd2001ff3fd3d1612303 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Sun, 28 Jun 2020 00:58:54 +0200 Subject: [fixes #2469] Support static reference as logger topic --- src/core/lombok/core/AnnotationValues.java | 8 +++++ .../eclipse/handlers/EclipseHandlerUtil.java | 21 ++++++++++--- src/core/lombok/eclipse/handlers/HandleLog.java | 36 ++++++++++++---------- src/core/lombok/javac/handlers/HandleLog.java | 33 +++++++++++--------- .../resource/after-delombok/LoggerCommons.java | 5 +++ .../LoggerCustomWithTopicAndName.java | 6 ++++ .../resource/after-delombok/LoggerJBossLog.java | 6 ++++ .../resource/after-delombok/LoggerJul.java | 5 +++ .../resource/after-delombok/LoggerLog4j.java | 5 +++ .../resource/after-delombok/LoggerLog4j2.java | 5 +++ .../resource/after-delombok/LoggerSlf4j.java | 17 ++++++++++ .../after-delombok/LoggerSlf4jInvalidTopic.java | 5 +++ .../resource/after-delombok/LoggerXSlf4j.java | 5 +++ .../resource/after-ecj/LoggerCommons.java | 9 ++++++ .../after-ecj/LoggerCustomWithTopicAndName.java | 9 ++++++ .../resource/after-ecj/LoggerJBossLog.java | 9 ++++++ test/transform/resource/after-ecj/LoggerJul.java | 9 ++++++ test/transform/resource/after-ecj/LoggerLog4j.java | 9 ++++++ .../transform/resource/after-ecj/LoggerLog4j2.java | 9 ++++++ test/transform/resource/after-ecj/LoggerSlf4j.java | 27 ++++++++++++++++ .../after-ecj/LoggerSlf4jInvalidTopic.java | 9 ++++++ .../transform/resource/after-ecj/LoggerXSlf4j.java | 11 ++++++- test/transform/resource/before/LoggerCommons.java | 5 +++ .../before/LoggerCustomWithTopicAndName.java | 5 +++ test/transform/resource/before/LoggerJBossLog.java | 5 +++ test/transform/resource/before/LoggerJul.java | 5 +++ test/transform/resource/before/LoggerLog4j.java | 5 +++ test/transform/resource/before/LoggerLog4j2.java | 5 +++ test/transform/resource/before/LoggerSlf4j.java | 14 +++++++++ .../resource/before/LoggerSlf4jInvalidTopic.java | 5 +++ test/transform/resource/before/LoggerXSlf4j.java | 5 +++ .../LoggerSlf4jInvalidTopic.java.messages | 2 ++ .../LoggerSlf4jInvalidTopic.java.messages | 1 + .../LoggerSlf4jInvalidTopic.java.messages | 1 + 34 files changed, 279 insertions(+), 37 deletions(-) create mode 100644 test/transform/resource/after-delombok/LoggerSlf4jInvalidTopic.java create mode 100644 test/transform/resource/after-ecj/LoggerSlf4jInvalidTopic.java create mode 100644 test/transform/resource/before/LoggerSlf4jInvalidTopic.java create mode 100644 test/transform/resource/messages-delombok/LoggerSlf4jInvalidTopic.java.messages create mode 100644 test/transform/resource/messages-ecj/LoggerSlf4jInvalidTopic.java.messages create mode 100644 test/transform/resource/messages-idempotent/LoggerSlf4jInvalidTopic.java.messages (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/core/AnnotationValues.java b/src/core/lombok/core/AnnotationValues.java index eec5abd8..78bb1fb5 100644 --- a/src/core/lombok/core/AnnotationValues.java +++ b/src/core/lombok/core/AnnotationValues.java @@ -411,6 +411,14 @@ public class AnnotationValues { List l = getActualExpressions(annotationMethodName); return l.isEmpty() ? null : l.get(0); } + + /** + * Returns the guessed value for the provided {@code annotationMethodName}. + */ + public Object getValueGuess(String annotationMethodName) { + AnnotationValue v = values.get(annotationMethodName); + return v == null || v.valueGuesses.isEmpty() ? null : v.valueGuesses.get(0); + } /** Generates an error message on the stated annotation value (you should only call this method if you know it's there!) */ public void setError(String annotationMethodName, String message) { diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 1b4f510c..e674409c 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -49,6 +49,7 @@ import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer; import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference; import org.eclipse.jdt.internal.compiler.ast.AssertStatement; +import org.eclipse.jdt.internal.compiler.ast.BinaryExpression; import org.eclipse.jdt.internal.compiler.ast.Block; import org.eclipse.jdt.internal.compiler.ast.CastExpression; import org.eclipse.jdt.internal.compiler.ast.CharLiteral; @@ -380,7 +381,7 @@ public class EclipseHandlerUtil { } } - private static Expression copyAnnotationMemberValue(Expression in) { + public static Expression copyAnnotationMemberValue(Expression in) { Expression out = copyAnnotationMemberValue0(in); out.constant = in.constant; return out; @@ -421,12 +422,11 @@ public class EclipseHandlerUtil { if (in instanceof SingleNameReference) { SingleNameReference snr = (SingleNameReference) in; - long p = (long) s << 32 | e; - return new SingleNameReference(snr.token, p); + return new SingleNameReference(snr.token, pos(in)); } if (in instanceof QualifiedNameReference) { QualifiedNameReference qnr = (QualifiedNameReference) in; - return new QualifiedNameReference(qnr.tokens, qnr.sourcePositions, s, e); + return new QualifiedNameReference(qnr.tokens, poss(in, qnr.tokens.length), s, e); } // class refs @@ -442,11 +442,22 @@ public class EclipseHandlerUtil { out.sourceEnd = e; out.bits = in.bits; out.implicitConversion = in.implicitConversion; - out.statementEnd = in.statementEnd; + out.statementEnd = e; out.expressions = copy; return out; } + if (in instanceof BinaryExpression) { + BinaryExpression be = (BinaryExpression) in; + BinaryExpression out = new BinaryExpression(be); + out.left = copyAnnotationMemberValue(be.left); + out.right = copyAnnotationMemberValue(be.right); + out.sourceStart = s; + out.sourceEnd = e; + out.statementEnd = e; + return out; + } + return in; } diff --git a/src/core/lombok/eclipse/handlers/HandleLog.java b/src/core/lombok/eclipse/handlers/HandleLog.java index 7a140193..a0e431e5 100644 --- a/src/core/lombok/eclipse/handlers/HandleLog.java +++ b/src/core/lombok/eclipse/handlers/HandleLog.java @@ -51,6 +51,7 @@ import lombok.core.configuration.LogDeclaration.LogFactoryParameter; import lombok.core.handlers.LoggingFramework; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseNode; +import lombok.eclipse.handlers.EclipseHandlerUtil.MemberExistsResult; public class HandleLog { private static final IdentifierName LOG = IdentifierName.valueOf("log"); @@ -59,7 +60,7 @@ public class HandleLog { throw new UnsupportedOperationException(); } - public static void processAnnotation(LoggingFramework framework, AnnotationValues annotation, Annotation source, EclipseNode annotationNode, String loggerTopic) { + public static void processAnnotation(LoggingFramework framework, AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { EclipseNode owner = annotationNode.up(); switch (owner.getKind()) { @@ -84,15 +85,18 @@ public class HandleLog { annotationNode.addWarning("Field '" + logFieldName + "' already exists."); return; } - - if (loggerTopic != null && loggerTopic.trim().isEmpty()) loggerTopic = null; + + Object valueGuess = annotation.getValueGuess("topic"); + Expression loggerTopic = (Expression) annotation.getActualExpression("topic"); + + if (valueGuess instanceof String && ((String) valueGuess).trim().isEmpty()) loggerTopic = null; if (framework.getDeclaration().getParametersWithTopic() == null && loggerTopic != null) { annotationNode.addError(framework.getAnnotationAsString() + " does not allow a topic."); loggerTopic = null; } if (framework.getDeclaration().getParametersWithoutTopic() == null && loggerTopic == null) { annotationNode.addError(framework.getAnnotationAsString() + " requires a topic."); - loggerTopic = ""; + loggerTopic = new StringLiteral(new char[]{}, 0, 0, 0); } ClassLiteralAccess loggingType = selfType(owner, source); @@ -122,7 +126,7 @@ public class HandleLog { return result; } - private static FieldDeclaration createField(LoggingFramework framework, Annotation source, ClassLiteralAccess loggingType, String logFieldName, boolean useStatic, String loggerTopic) { + private static FieldDeclaration createField(LoggingFramework framework, Annotation source, ClassLiteralAccess loggingType, String logFieldName, boolean useStatic, Expression loggerTopic) { int pS = source.sourceStart, pE = source.sourceEnd; long p = (long) pS << 32 | pE; @@ -165,7 +169,7 @@ public class HandleLog { return typeReference; } - private static final Expression[] createFactoryParameters(ClassLiteralAccess loggingType, Annotation source, List parameters, String loggerTopic) { + private static final Expression[] createFactoryParameters(ClassLiteralAccess loggingType, Annotation source, List parameters, Expression loggerTopic) { Expression[] expressions = new Expression[parameters.size()]; int pS = source.sourceStart, pE = source.sourceEnd; @@ -192,7 +196,7 @@ public class HandleLog { expressions[i] = factoryParameterCall; break; case TOPIC: - expressions[i] = new StringLiteral(loggerTopic.toCharArray(), pS, pE, 0); + expressions[i] = EclipseHandlerUtil.copyAnnotationMemberValue(loggerTopic); break; case NULL: expressions[i] = new NullLiteral(pS, pE); @@ -219,7 +223,7 @@ public class HandleLog { public static class HandleCommonsLog extends EclipseAnnotationHandler { @Override public void handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_COMMONS_FLAG_USAGE, "@apachecommons.CommonsLog", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.COMMONS, annotation, source, annotationNode, annotation.getInstance().topic()); + processAnnotation(LoggingFramework.COMMONS, annotation, source, annotationNode); } } @@ -230,7 +234,7 @@ public class HandleLog { public static class HandleJulLog extends EclipseAnnotationHandler { @Override public void handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_JUL_FLAG_USAGE, "@java.Log", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.JUL, annotation, source, annotationNode, annotation.getInstance().topic()); + processAnnotation(LoggingFramework.JUL, annotation, source, annotationNode); } } @@ -241,7 +245,7 @@ public class HandleLog { public static class HandleLog4jLog extends EclipseAnnotationHandler { @Override public void handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_LOG4J_FLAG_USAGE, "@Log4j", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.LOG4J, annotation, source, annotationNode, annotation.getInstance().topic()); + processAnnotation(LoggingFramework.LOG4J, annotation, source, annotationNode); } } @@ -252,7 +256,7 @@ public class HandleLog { public static class HandleLog4j2Log extends EclipseAnnotationHandler { @Override public void handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_LOG4J2_FLAG_USAGE, "@Log4j2", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.LOG4J2, annotation, source, annotationNode, annotation.getInstance().topic()); + processAnnotation(LoggingFramework.LOG4J2, annotation, source, annotationNode); } } @@ -263,7 +267,7 @@ public class HandleLog { public static class HandleSlf4jLog extends EclipseAnnotationHandler { @Override public void handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_SLF4J_FLAG_USAGE, "@Slf4j", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.SLF4J, annotation, source, annotationNode, annotation.getInstance().topic()); + processAnnotation(LoggingFramework.SLF4J, annotation, source, annotationNode); } } @@ -274,7 +278,7 @@ public class HandleLog { public static class HandleXSlf4jLog extends EclipseAnnotationHandler { @Override public void handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_XSLF4J_FLAG_USAGE, "@XSlf4j", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.XSLF4J, annotation, source, annotationNode, annotation.getInstance().topic()); + processAnnotation(LoggingFramework.XSLF4J, annotation, source, annotationNode); } } @@ -285,7 +289,7 @@ public class HandleLog { public static class HandleJBossLog extends EclipseAnnotationHandler { @Override public void handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_JBOSSLOG_FLAG_USAGE, "@JBossLog", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.JBOSSLOG, annotation, source, annotationNode, annotation.getInstance().topic()); + processAnnotation(LoggingFramework.JBOSSLOG, annotation, source, annotationNode); } } @@ -296,7 +300,7 @@ public class HandleLog { public static class HandleFloggerLog extends EclipseAnnotationHandler { @Override public void handle(AnnotationValues annotation, Annotation source, EclipseNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_FLOGGER_FLAG_USAGE, "@Flogger", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.FLOGGER, annotation, source, annotationNode, ""); + processAnnotation(LoggingFramework.FLOGGER, annotation, source, annotationNode); } } @@ -313,7 +317,7 @@ public class HandleLog { return; } LoggingFramework framework = new LoggingFramework(lombok.CustomLog.class, logDeclaration); - processAnnotation(framework, annotation, source, annotationNode, annotation.getInstance().topic()); + processAnnotation(framework, annotation, source, annotationNode); } } } diff --git a/src/core/lombok/javac/handlers/HandleLog.java b/src/core/lombok/javac/handlers/HandleLog.java index 522f8576..3173b3ba 100644 --- a/src/core/lombok/javac/handlers/HandleLog.java +++ b/src/core/lombok/javac/handlers/HandleLog.java @@ -56,7 +56,7 @@ public class HandleLog { throw new UnsupportedOperationException(); } - public static void processAnnotation(LoggingFramework framework, AnnotationValues annotation, JavacNode annotationNode, String loggerTopic) { + public static void processAnnotation(LoggingFramework framework, AnnotationValues annotation, JavacNode annotationNode) { deleteAnnotationIfNeccessary(annotationNode, framework.getAnnotationClass()); JavacNode typeNode = annotationNode.up(); @@ -76,14 +76,17 @@ public class HandleLog { return; } - if (loggerTopic != null && loggerTopic.trim().isEmpty()) loggerTopic = null; + Object valueGuess = annotation.getValueGuess("topic"); + JCExpression loggerTopic = (JCExpression) annotation.getActualExpression("topic"); + + if (valueGuess instanceof String && ((String) valueGuess).trim().isEmpty()) loggerTopic = null; if (framework.getDeclaration().getParametersWithTopic() == null && loggerTopic != null) { annotationNode.addError(framework.getAnnotationAsString() + " does not allow a topic."); loggerTopic = null; } if (framework.getDeclaration().getParametersWithoutTopic() == null && loggerTopic == null) { annotationNode.addError(framework.getAnnotationAsString() + " requires a topic."); - loggerTopic = ""; + loggerTopic = typeNode.getTreeMaker().Literal(""); } JCFieldAccess loggingType = selfType(typeNode); @@ -101,7 +104,7 @@ public class HandleLog { return maker.Select(maker.Ident(name), typeNode.toName("class")); } - private static boolean createField(LoggingFramework framework, JavacNode typeNode, JCFieldAccess loggingType, JCTree source, String logFieldName, boolean useStatic, String loggerTopic) { + private static boolean createField(LoggingFramework framework, JavacNode typeNode, JCFieldAccess loggingType, JCTree source, String logFieldName, boolean useStatic, JCExpression loggerTopic) { JavacTreeMaker maker = typeNode.getTreeMaker(); LogDeclaration logDeclaration = framework.getDeclaration(); @@ -121,7 +124,7 @@ public class HandleLog { return true; } - private static JCExpression[] createFactoryParameters(JavacNode typeNode, JCFieldAccess loggingType, java.util.List parameters, String loggerTopic) { + private static JCExpression[] createFactoryParameters(JavacNode typeNode, JCFieldAccess loggingType, java.util.List parameters, JCExpression loggerTopic) { JCExpression[] expressions = new JCExpression[parameters.size()]; JavacTreeMaker maker = typeNode.getTreeMaker(); @@ -136,7 +139,7 @@ public class HandleLog { expressions[i] = maker.Apply(List.nil(), method, List.nil()); break; case TOPIC: - expressions[i] = maker.Literal(loggerTopic); + expressions[i] = (JCExpression) loggerTopic.clone(); break; case NULL: expressions[i] = maker.Literal(CTC_BOT, null); @@ -156,7 +159,7 @@ public class HandleLog { public static class HandleCommonsLog extends JavacAnnotationHandler { @Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_COMMONS_FLAG_USAGE, "@apachecommons.CommonsLog", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.COMMONS, annotation, annotationNode, annotation.getInstance().topic()); + processAnnotation(LoggingFramework.COMMONS, annotation, annotationNode); } } @@ -167,7 +170,7 @@ public class HandleLog { public static class HandleJulLog extends JavacAnnotationHandler { @Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_JUL_FLAG_USAGE, "@java.Log", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.JUL, annotation, annotationNode, annotation.getInstance().topic()); + processAnnotation(LoggingFramework.JUL, annotation, annotationNode); } } @@ -178,7 +181,7 @@ public class HandleLog { public static class HandleLog4jLog extends JavacAnnotationHandler { @Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_LOG4J_FLAG_USAGE, "@Log4j", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.LOG4J, annotation, annotationNode, annotation.getInstance().topic()); + processAnnotation(LoggingFramework.LOG4J, annotation, annotationNode); } } @@ -189,7 +192,7 @@ public class HandleLog { public static class HandleLog4j2Log extends JavacAnnotationHandler { @Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_LOG4J2_FLAG_USAGE, "@Log4j2", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.LOG4J2, annotation, annotationNode, annotation.getInstance().topic()); + processAnnotation(LoggingFramework.LOG4J2, annotation, annotationNode); } } @@ -200,7 +203,7 @@ public class HandleLog { public static class HandleSlf4jLog extends JavacAnnotationHandler { @Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_SLF4J_FLAG_USAGE, "@Slf4j", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.SLF4J, annotation, annotationNode, annotation.getInstance().topic()); + processAnnotation(LoggingFramework.SLF4J, annotation, annotationNode); } } @@ -211,7 +214,7 @@ public class HandleLog { public static class HandleXSlf4jLog extends JavacAnnotationHandler { @Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_XSLF4J_FLAG_USAGE, "@XSlf4j", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.XSLF4J, annotation, annotationNode, annotation.getInstance().topic()); + processAnnotation(LoggingFramework.XSLF4J, annotation, annotationNode); } } @@ -222,7 +225,7 @@ public class HandleLog { public static class HandleJBossLog extends JavacAnnotationHandler { @Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_JBOSSLOG_FLAG_USAGE, "@JBossLog", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.JBOSSLOG, annotation, annotationNode, annotation.getInstance().topic()); + processAnnotation(LoggingFramework.JBOSSLOG, annotation, annotationNode); } } @@ -233,7 +236,7 @@ public class HandleLog { public static class HandleFloggerLog extends JavacAnnotationHandler { @Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.LOG_FLOGGER_FLAG_USAGE, "@Flogger", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log"); - processAnnotation(LoggingFramework.FLOGGER, annotation, annotationNode, ""); + processAnnotation(LoggingFramework.FLOGGER, annotation, annotationNode); } } @@ -250,7 +253,7 @@ public class HandleLog { return; } LoggingFramework framework = new LoggingFramework(lombok.CustomLog.class, logDeclaration); - processAnnotation(framework, annotation, annotationNode, annotation.getInstance().topic()); + processAnnotation(framework, annotation, annotationNode); } } } diff --git a/test/transform/resource/after-delombok/LoggerCommons.java b/test/transform/resource/after-delombok/LoggerCommons.java index 954e730b..4b943da7 100644 --- a/test/transform/resource/after-delombok/LoggerCommons.java +++ b/test/transform/resource/after-delombok/LoggerCommons.java @@ -10,3 +10,8 @@ class LoggerCommonsWithDifferentName { @java.lang.SuppressWarnings("all") private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog("DifferentName"); } +class LoggerCommonsWithStaticField { + @java.lang.SuppressWarnings("all") + private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LoggerCommonsWithStaticField.TOPIC); + static final String TOPIC = "StaticField"; +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/LoggerCustomWithTopicAndName.java b/test/transform/resource/after-delombok/LoggerCustomWithTopicAndName.java index abb785b9..4db02cc1 100644 --- a/test/transform/resource/after-delombok/LoggerCustomWithTopicAndName.java +++ b/test/transform/resource/after-delombok/LoggerCustomWithTopicAndName.java @@ -3,6 +3,12 @@ class LoggerCustomLog { private static final MyLoggerFactory log = MyLoggerFactory.create(LoggerCustomLog.class.getName(), "t", null, LoggerCustomLog.class, "t"); } +class LoggerCustomLogWithStaticField { + @java.lang.SuppressWarnings("all") + private static final MyLoggerFactory log = MyLoggerFactory.create(LoggerCustomLogWithStaticField.class.getName(), LoggerCustomLogWithStaticField.TOPIC, null, LoggerCustomLogWithStaticField.class, LoggerCustomLogWithStaticField.TOPIC); + static final String TOPIC = "StaticField"; +} + class MyLoggerFactory { static MyLoggerFactory create(String name, String t1, Object o, Class clazz, String t2) { return null; diff --git a/test/transform/resource/after-delombok/LoggerJBossLog.java b/test/transform/resource/after-delombok/LoggerJBossLog.java index 41c18805..5fd98aa6 100644 --- a/test/transform/resource/after-delombok/LoggerJBossLog.java +++ b/test/transform/resource/after-delombok/LoggerJBossLog.java @@ -17,3 +17,9 @@ class LoggerJBossLogWithDifferentLoggerName { @java.lang.SuppressWarnings("all") private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger("DifferentLogger"); } + +class LoggerJBossLogWithStaticField { + @java.lang.SuppressWarnings("all") + private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LoggerJBossLogWithStaticField.TOPIC); + static final String TOPIC = "StaticField"; +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/LoggerJul.java b/test/transform/resource/after-delombok/LoggerJul.java index 63f96733..cfb44fde 100644 --- a/test/transform/resource/after-delombok/LoggerJul.java +++ b/test/transform/resource/after-delombok/LoggerJul.java @@ -10,3 +10,8 @@ class LoggerJulWithDifferentName { @java.lang.SuppressWarnings("all") private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger("DifferentName"); } +class LoggerJulWithStaticField { + @java.lang.SuppressWarnings("all") + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggerJulWithStaticField.TOPIC); + static final String TOPIC = "StaticField"; +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/LoggerLog4j.java b/test/transform/resource/after-delombok/LoggerLog4j.java index 7d9d4409..cef83621 100644 --- a/test/transform/resource/after-delombok/LoggerLog4j.java +++ b/test/transform/resource/after-delombok/LoggerLog4j.java @@ -10,3 +10,8 @@ class LoggerLog4jWithDifferentName { @java.lang.SuppressWarnings("all") private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger("DifferentName"); } +class LoggerLog4jWithStaticField { + @java.lang.SuppressWarnings("all") + private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LoggerLog4jWithStaticField.TOPIC); + static final String TOPIC = "StaticField"; +} diff --git a/test/transform/resource/after-delombok/LoggerLog4j2.java b/test/transform/resource/after-delombok/LoggerLog4j2.java index 3d8b7b5b..b32c7722 100644 --- a/test/transform/resource/after-delombok/LoggerLog4j2.java +++ b/test/transform/resource/after-delombok/LoggerLog4j2.java @@ -10,3 +10,8 @@ class LoggerLog4j2WithDifferentName { @java.lang.SuppressWarnings("all") private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger("DifferentName"); } +class LoggerLog4j2WithStaticField { + @java.lang.SuppressWarnings("all") + private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LoggerLog4j2WithStaticField.TOPIC); + static final String TOPIC = "StaticField"; +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/LoggerSlf4j.java b/test/transform/resource/after-delombok/LoggerSlf4j.java index 68d685f0..70f11ae4 100644 --- a/test/transform/resource/after-delombok/LoggerSlf4j.java +++ b/test/transform/resource/after-delombok/LoggerSlf4j.java @@ -17,3 +17,20 @@ class LoggerSlf4jWithDifferentLoggerName { @java.lang.SuppressWarnings("all") private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("DifferentLogger"); } + +class LoggerSlf4jWithStaticField { + @java.lang.SuppressWarnings("all") + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jWithStaticField.TOPIC); + static final String TOPIC = "StaticField"; +} + +class LoggerSlf4jWithTwoStaticFields { + @java.lang.SuppressWarnings("all") + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jWithTwoStaticFields.TOPIC + LoggerSlf4jWithTwoStaticFields.TOPIC); + static final String TOPIC = "StaticField"; +} + +class LoggerSlf4jWithTwoLiterals { + @java.lang.SuppressWarnings("all") + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("A" + "B"); +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/LoggerSlf4jInvalidTopic.java b/test/transform/resource/after-delombok/LoggerSlf4jInvalidTopic.java new file mode 100644 index 00000000..86e6ae2c --- /dev/null +++ b/test/transform/resource/after-delombok/LoggerSlf4jInvalidTopic.java @@ -0,0 +1,5 @@ +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic = 42) +class LoggerSlf4jWithIntegerTopic { +} \ No newline at end of file diff --git a/test/transform/resource/after-delombok/LoggerXSlf4j.java b/test/transform/resource/after-delombok/LoggerXSlf4j.java index 781733cf..ba0ec3f8 100644 --- a/test/transform/resource/after-delombok/LoggerXSlf4j.java +++ b/test/transform/resource/after-delombok/LoggerXSlf4j.java @@ -10,3 +10,8 @@ class LoggerXSlf4jWithDifferentName { @java.lang.SuppressWarnings("all") private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger("DifferentName"); } +class LoggerXSlf4jWithStaticField { + @java.lang.SuppressWarnings("all") + private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LoggerXSlf4jWithStaticField.TOPIC); + static final String TOPIC = "StaticField"; +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerCommons.java b/test/transform/resource/after-ecj/LoggerCommons.java index df102a12..b2ca055f 100644 --- a/test/transform/resource/after-ecj/LoggerCommons.java +++ b/test/transform/resource/after-ecj/LoggerCommons.java @@ -22,4 +22,13 @@ import lombok.extern.apachecommons.CommonsLog; LoggerCommonsWithDifferentName() { super(); } +} +@CommonsLog(topic = LoggerCommonsWithStaticField.TOPIC) class LoggerCommonsWithStaticField { + private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LoggerCommonsWithStaticField.TOPIC); + static final String TOPIC = "StaticField"; + () { + } + LoggerCommonsWithStaticField() { + super(); + } } \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerCustomWithTopicAndName.java b/test/transform/resource/after-ecj/LoggerCustomWithTopicAndName.java index 91cf6d8d..f6f85744 100644 --- a/test/transform/resource/after-ecj/LoggerCustomWithTopicAndName.java +++ b/test/transform/resource/after-ecj/LoggerCustomWithTopicAndName.java @@ -6,6 +6,15 @@ super(); } } +@lombok.CustomLog(topic = LoggerCustomLogWithStaticField.TOPIC) class LoggerCustomLogWithStaticField { + private static final MyLoggerFactory log = MyLoggerFactory.create(LoggerCustomLogWithStaticField.class.getName(), LoggerCustomLogWithStaticField.TOPIC, null, LoggerCustomLogWithStaticField.class, LoggerCustomLogWithStaticField.TOPIC); + static final String TOPIC = "StaticField"; + () { + } + LoggerCustomLogWithStaticField() { + super(); + } +} class MyLoggerFactory { MyLoggerFactory() { super(); diff --git a/test/transform/resource/after-ecj/LoggerJBossLog.java b/test/transform/resource/after-ecj/LoggerJBossLog.java index e5c35708..c47f6c9e 100644 --- a/test/transform/resource/after-ecj/LoggerJBossLog.java +++ b/test/transform/resource/after-ecj/LoggerJBossLog.java @@ -35,4 +35,13 @@ class LoggerJBossLogOuter { LoggerJBossLogWithDifferentLoggerName() { super(); } +} +@JBossLog(topic = LoggerJBossLogWithStaticField.TOPIC) class LoggerJBossLogWithStaticField { + private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LoggerJBossLogWithStaticField.TOPIC); + static final String TOPIC = "StaticField"; + () { + } + LoggerJBossLogWithStaticField() { + super(); + } } \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerJul.java b/test/transform/resource/after-ecj/LoggerJul.java index 8aa4f59a..20cc5407 100644 --- a/test/transform/resource/after-ecj/LoggerJul.java +++ b/test/transform/resource/after-ecj/LoggerJul.java @@ -22,4 +22,13 @@ import lombok.extern.java.Log; LoggerJulWithDifferentName() { super(); } +} +@Log(topic = LoggerJulWithStaticField.TOPIC) class LoggerJulWithStaticField { + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggerJulWithStaticField.TOPIC); + static final String TOPIC = "StaticField"; + () { + } + LoggerJulWithStaticField() { + super(); + } } \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerLog4j.java b/test/transform/resource/after-ecj/LoggerLog4j.java index 948412e2..e7d6c813 100644 --- a/test/transform/resource/after-ecj/LoggerLog4j.java +++ b/test/transform/resource/after-ecj/LoggerLog4j.java @@ -22,4 +22,13 @@ import lombok.extern.log4j.Log4j; LoggerLog4jWithDifferentName() { super(); } +} +@Log4j(topic = LoggerLog4jWithStaticField.TOPIC) class LoggerLog4jWithStaticField { + private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LoggerLog4jWithStaticField.TOPIC); + static final String TOPIC = "StaticField"; + () { + } + LoggerLog4jWithStaticField() { + super(); + } } \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerLog4j2.java b/test/transform/resource/after-ecj/LoggerLog4j2.java index c2fcd428..88def98d 100644 --- a/test/transform/resource/after-ecj/LoggerLog4j2.java +++ b/test/transform/resource/after-ecj/LoggerLog4j2.java @@ -22,4 +22,13 @@ import lombok.extern.log4j.Log4j2; LoggerLog4j2WithDifferentName() { super(); } +} +@Log4j2(topic = LoggerLog4j2WithStaticField.TOPIC) class LoggerLog4j2WithStaticField { + private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LoggerLog4j2WithStaticField.TOPIC); + static final String TOPIC = "StaticField"; + () { + } + LoggerLog4j2WithStaticField() { + super(); + } } \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerSlf4j.java b/test/transform/resource/after-ecj/LoggerSlf4j.java index 9c5405cb..c303a895 100644 --- a/test/transform/resource/after-ecj/LoggerSlf4j.java +++ b/test/transform/resource/after-ecj/LoggerSlf4j.java @@ -36,4 +36,31 @@ class LoggerSlf4jOuter { LoggerSlf4jWithDifferentLoggerName() { super(); } +} + +@Slf4j(topic = LoggerSlf4jWithStaticField.TOPIC) class LoggerSlf4jWithStaticField { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jWithStaticField.TOPIC); + static final String TOPIC = "StaticField"; + () { + } + LoggerSlf4jWithStaticField() { + super(); + } +} +@Slf4j(topic = (LoggerSlf4jWithTwoStaticFields.TOPIC + LoggerSlf4jWithTwoStaticFields.TOPIC)) class LoggerSlf4jWithTwoStaticFields { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger((LoggerSlf4jWithTwoStaticFields.TOPIC + LoggerSlf4jWithTwoStaticFields.TOPIC)); + static final String TOPIC = "StaticField"; + () { + } + LoggerSlf4jWithTwoStaticFields() { + super(); + } +} +@Slf4j(topic = ExtendedStringLiteral{AB}) class LoggerSlf4jWithTwoLiterals { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("AB"); + () { + } + LoggerSlf4jWithTwoLiterals() { + super(); + } } \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerSlf4jInvalidTopic.java b/test/transform/resource/after-ecj/LoggerSlf4jInvalidTopic.java new file mode 100644 index 00000000..33e212e3 --- /dev/null +++ b/test/transform/resource/after-ecj/LoggerSlf4jInvalidTopic.java @@ -0,0 +1,9 @@ +import lombok.extern.slf4j.Slf4j; +@Slf4j(topic = 42) class LoggerSlf4jWithIntegerTopic { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(42); + () { + } + LoggerSlf4jWithIntegerTopic() { + super(); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/LoggerXSlf4j.java b/test/transform/resource/after-ecj/LoggerXSlf4j.java index 916859a4..04acdd77 100644 --- a/test/transform/resource/after-ecj/LoggerXSlf4j.java +++ b/test/transform/resource/after-ecj/LoggerXSlf4j.java @@ -22,4 +22,13 @@ import lombok.extern.slf4j.XSlf4j; LoggerXSlf4jWithDifferentName() { super(); } -} \ No newline at end of file +} +@XSlf4j(topic = LoggerXSlf4jWithStaticField.TOPIC) class LoggerXSlf4jWithStaticField { + private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LoggerXSlf4jWithStaticField.TOPIC); + static final String TOPIC = "StaticField"; + () { + } + LoggerXSlf4jWithStaticField() { + super(); + } +} diff --git a/test/transform/resource/before/LoggerCommons.java b/test/transform/resource/before/LoggerCommons.java index 00419d00..e209c1d0 100644 --- a/test/transform/resource/before/LoggerCommons.java +++ b/test/transform/resource/before/LoggerCommons.java @@ -11,3 +11,8 @@ class LoggerCommonsWithImport { @CommonsLog(topic="DifferentName") class LoggerCommonsWithDifferentName { } + +@CommonsLog(topic=LoggerCommonsWithStaticField.TOPIC) +class LoggerCommonsWithStaticField { + static final String TOPIC = "StaticField"; +} \ No newline at end of file diff --git a/test/transform/resource/before/LoggerCustomWithTopicAndName.java b/test/transform/resource/before/LoggerCustomWithTopicAndName.java index b40ed86a..5b803217 100644 --- a/test/transform/resource/before/LoggerCustomWithTopicAndName.java +++ b/test/transform/resource/before/LoggerCustomWithTopicAndName.java @@ -3,6 +3,11 @@ class LoggerCustomLog { } +@lombok.CustomLog(topic=LoggerCustomLogWithStaticField.TOPIC) +class LoggerCustomLogWithStaticField { + static final String TOPIC = "StaticField"; +} + class MyLoggerFactory { static MyLoggerFactory create(String name, String t1, Object o, Class clazz, String t2) { return null; diff --git a/test/transform/resource/before/LoggerJBossLog.java b/test/transform/resource/before/LoggerJBossLog.java index fbd88177..f3480867 100644 --- a/test/transform/resource/before/LoggerJBossLog.java +++ b/test/transform/resource/before/LoggerJBossLog.java @@ -17,4 +17,9 @@ class LoggerJBossLogOuter { @JBossLog(topic="DifferentLogger") class LoggerJBossLogWithDifferentLoggerName { +} + +@JBossLog(topic=LoggerJBossLogWithStaticField.TOPIC) +class LoggerJBossLogWithStaticField { + static final String TOPIC = "StaticField"; } \ No newline at end of file diff --git a/test/transform/resource/before/LoggerJul.java b/test/transform/resource/before/LoggerJul.java index 006cc344..7b10d015 100644 --- a/test/transform/resource/before/LoggerJul.java +++ b/test/transform/resource/before/LoggerJul.java @@ -10,4 +10,9 @@ class LoggerJulWithImport { @Log(topic="DifferentName") class LoggerJulWithDifferentName { +} + +@Log(topic=LoggerJulWithStaticField.TOPIC) +class LoggerJulWithStaticField { + static final String TOPIC = "StaticField"; } \ No newline at end of file diff --git a/test/transform/resource/before/LoggerLog4j.java b/test/transform/resource/before/LoggerLog4j.java index 351049c5..b7086a05 100644 --- a/test/transform/resource/before/LoggerLog4j.java +++ b/test/transform/resource/before/LoggerLog4j.java @@ -10,4 +10,9 @@ class LoggerLog4jWithImport { @Log4j(topic="DifferentName") class LoggerLog4jWithDifferentName { +} + +@Log4j(topic=LoggerLog4jWithStaticField.TOPIC) +class LoggerLog4jWithStaticField { + static final String TOPIC = "StaticField"; } \ No newline at end of file diff --git a/test/transform/resource/before/LoggerLog4j2.java b/test/transform/resource/before/LoggerLog4j2.java index c9cf9412..10b3aae5 100644 --- a/test/transform/resource/before/LoggerLog4j2.java +++ b/test/transform/resource/before/LoggerLog4j2.java @@ -10,4 +10,9 @@ class LoggerLog4j2WithImport { @Log4j2(topic="DifferentName") class LoggerLog4j2WithDifferentName { +} + +@Log4j2(topic=LoggerLog4j2WithStaticField.TOPIC) +class LoggerLog4j2WithStaticField { + static final String TOPIC = "StaticField"; } \ No newline at end of file diff --git a/test/transform/resource/before/LoggerSlf4j.java b/test/transform/resource/before/LoggerSlf4j.java index 1113a63e..3f8284e8 100644 --- a/test/transform/resource/before/LoggerSlf4j.java +++ b/test/transform/resource/before/LoggerSlf4j.java @@ -17,4 +17,18 @@ class LoggerSlf4jOuter { @Slf4j(topic="DifferentLogger") class LoggerSlf4jWithDifferentLoggerName { +} + +@Slf4j(topic=LoggerSlf4jWithStaticField.TOPIC) +class LoggerSlf4jWithStaticField { + static final String TOPIC = "StaticField"; +} + +@Slf4j(topic=LoggerSlf4jWithTwoStaticFields.TOPIC + LoggerSlf4jWithTwoStaticFields.TOPIC) +class LoggerSlf4jWithTwoStaticFields { + static final String TOPIC = "StaticField"; +} + +@Slf4j(topic="A"+"B") +class LoggerSlf4jWithTwoLiterals { } \ No newline at end of file diff --git a/test/transform/resource/before/LoggerSlf4jInvalidTopic.java b/test/transform/resource/before/LoggerSlf4jInvalidTopic.java new file mode 100644 index 00000000..eed02f01 --- /dev/null +++ b/test/transform/resource/before/LoggerSlf4jInvalidTopic.java @@ -0,0 +1,5 @@ +import lombok.extern.slf4j.Slf4j; + +@Slf4j(topic=42) +class LoggerSlf4jWithIntegerTopic { +} \ No newline at end of file diff --git a/test/transform/resource/before/LoggerXSlf4j.java b/test/transform/resource/before/LoggerXSlf4j.java index a8bcb0c3..f70f2e2d 100644 --- a/test/transform/resource/before/LoggerXSlf4j.java +++ b/test/transform/resource/before/LoggerXSlf4j.java @@ -10,4 +10,9 @@ class LoggerXSlf4jWithImport { @XSlf4j(topic="DifferentName") class LoggerXSlf4jWithDifferentName { +} + +@XSlf4j(topic=LoggerXSlf4jWithStaticField.TOPIC) +class LoggerXSlf4jWithStaticField { + static final String TOPIC = "StaticField"; } \ No newline at end of file diff --git a/test/transform/resource/messages-delombok/LoggerSlf4jInvalidTopic.java.messages b/test/transform/resource/messages-delombok/LoggerSlf4jInvalidTopic.java.messages new file mode 100644 index 00000000..8de0a120 --- /dev/null +++ b/test/transform/resource/messages-delombok/LoggerSlf4jInvalidTopic.java.messages @@ -0,0 +1,2 @@ +3 incompatible types: int cannot be converted to java.lang.String +-1 not flagged modified \ No newline at end of file diff --git a/test/transform/resource/messages-ecj/LoggerSlf4jInvalidTopic.java.messages b/test/transform/resource/messages-ecj/LoggerSlf4jInvalidTopic.java.messages new file mode 100644 index 00000000..9bc2a82b --- /dev/null +++ b/test/transform/resource/messages-ecj/LoggerSlf4jInvalidTopic.java.messages @@ -0,0 +1 @@ +3 Type mismatch: cannot convert from int to String \ No newline at end of file diff --git a/test/transform/resource/messages-idempotent/LoggerSlf4jInvalidTopic.java.messages b/test/transform/resource/messages-idempotent/LoggerSlf4jInvalidTopic.java.messages new file mode 100644 index 00000000..d894fad1 --- /dev/null +++ b/test/transform/resource/messages-idempotent/LoggerSlf4jInvalidTopic.java.messages @@ -0,0 +1 @@ +3 incompatible types: int cannot be converted to java.lang.String \ No newline at end of file -- cgit From 84556ebb00af1817d521bc011333a0ed02162cc4 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Tue, 30 Jun 2020 17:22:38 +0200 Subject: [fixes #2433] Add config key to turn off @SuppressWarnings("all") --- src/core/lombok/ConfigurationKeys.java | 7 ++++++ .../eclipse/handlers/EclipseHandlerUtil.java | 6 ++++- src/core/lombok/eclipse/handlers/HandleGetter.java | 9 +++++--- src/core/lombok/javac/handlers/HandleGetter.java | 7 +++++- .../lombok/javac/handlers/JavacHandlerUtil.java | 20 ++++++++-------- .../after-delombok/SkipSuppressWarnings.java | 24 +++++++++++++++++++ .../resource/after-ecj/SkipSuppressWarnings.java | 27 ++++++++++++++++++++++ .../resource/before/SkipSuppressWarnings.java | 9 ++++++++ .../SkipSuppressWarnings.java.messages | 1 + 9 files changed, 96 insertions(+), 14 deletions(-) create mode 100644 test/transform/resource/after-delombok/SkipSuppressWarnings.java create mode 100644 test/transform/resource/after-ecj/SkipSuppressWarnings.java create mode 100644 test/transform/resource/before/SkipSuppressWarnings.java create mode 100644 test/transform/resource/messages-ecj/SkipSuppressWarnings.java.messages (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java index 46cf7412..60b98a94 100644 --- a/src/core/lombok/ConfigurationKeys.java +++ b/src/core/lombok/ConfigurationKeys.java @@ -89,6 +89,13 @@ public class ConfigurationKeys { */ public static final ConfigurationKey ADD_FINDBUGS_SUPPRESSWARNINGS_ANNOTATIONS = new ConfigurationKey("lombok.extern.findbugs.addSuppressFBWarnings", "Generate @edu.umd.cs.findbugs.annotations.SuppressFBWarnings on all generated code (default: false).") {}; + /** + * lombok configuration: {@code lombok.addSuppressWarnings} = {@code true} | {@code false}. + * + * If {@code true}, lombok generates {@code @java.lang.SuppressWarnings("all")} on all fields, methods, and types that are generated. + */ + public static final ConfigurationKey ADD_SUPPRESSWARNINGS_ANNOTATIONS = new ConfigurationKey("lombok.addSuppressWarnings", "Generate @java.lang.SuppressWarnings(\"all\") on all generated code (default: true).") {}; + /** * lombok configuration: {@code lombok.addNullAnnotations = }one of: [{@code none}, {@code javax}, {@code eclipse}, {@code jetbrains}, {@code netbeans}, {@code androidx}, {@code android.support}, {@code checkerframework}, {@code findbugs}, {@code spring}, {@code JML}, or a custom set of fully qualified annotation types]. * diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index e674409c..de76e32d 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -1962,7 +1962,11 @@ public class EclipseHandlerUtil { private static final char[][] EDU_UMD_CS_FINDBUGS_ANNOTATIONS_SUPPRESSFBWARNINGS = Eclipse.fromQualifiedName("edu.umd.cs.findbugs.annotations.SuppressFBWarnings"); public static Annotation[] addSuppressWarningsAll(EclipseNode node, ASTNode source, Annotation[] originalAnnotationArray) { - Annotation[] anns = addAnnotation(source, originalAnnotationArray, TypeConstants.JAVA_LANG_SUPPRESSWARNINGS, new StringLiteral(ALL, 0, 0, 0)); + Annotation[] anns = originalAnnotationArray; + + if (!Boolean.FALSE.equals(node.getAst().readConfiguration(ConfigurationKeys.ADD_SUPPRESSWARNINGS_ANNOTATIONS))) { + anns = addAnnotation(source, anns, TypeConstants.JAVA_LANG_SUPPRESSWARNINGS, new StringLiteral(ALL, 0, 0, 0)); + } if (Boolean.TRUE.equals(node.getAst().readConfiguration(ConfigurationKeys.ADD_FINDBUGS_SUPPRESSWARNINGS_ANNOTATIONS))) { MemberValuePair mvp = new MemberValuePair(JUSTIFICATION, 0, 0, new StringLiteral(GENERATED_CODE, 0, 0, 0)); diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java index 30b4a699..9cd1e2a1 100644 --- a/src/core/lombok/eclipse/handlers/HandleGetter.java +++ b/src/core/lombok/eclipse/handlers/HandleGetter.java @@ -285,10 +285,13 @@ public class HandleGetter extends EclipseAnnotationHandler { } if (addSuppressWarningsUnchecked) { + List suppressions = new ArrayList(2); + if (!Boolean.FALSE.equals(fieldNode.getAst().readConfiguration(ConfigurationKeys.ADD_SUPPRESSWARNINGS_ANNOTATIONS))) { + suppressions.add(new StringLiteral(ALL, 0, 0, 0)); + } + suppressions.add(new StringLiteral(UNCHECKED, 0, 0, 0)); ArrayInitializer arr = new ArrayInitializer(); - arr.expressions = new Expression[2]; - arr.expressions[0] = new StringLiteral(ALL, 0, 0, 0); - arr.expressions[1] = new StringLiteral(UNCHECKED, 0, 0, 0); + arr.expressions = suppressions.toArray(new Expression[0]); method.annotations = addAnnotation(source, method.annotations, TypeConstants.JAVA_LANG_SUPPRESSWARNINGS, arr); } diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index 985873c1..22f43d61 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -265,7 +265,12 @@ public class HandleGetter extends JavacAnnotationHandler { decl.mods.annotations = decl.mods.annotations.appendList(delegates); if (addSuppressWarningsUnchecked) { - addAnnotation(decl.mods, field, source.pos, source, field.getContext(), "java.lang.SuppressWarnings", treeMaker.NewArray(null, List.nil(), List.of(treeMaker.Literal("all"), treeMaker.Literal("unchecked")))); + ListBuffer suppressions = new ListBuffer(); + if (!Boolean.FALSE.equals(field.getAst().readConfiguration(ConfigurationKeys.ADD_SUPPRESSWARNINGS_ANNOTATIONS))) { + suppressions.add(treeMaker.Literal("all")); + } + suppressions.add(treeMaker.Literal("unchecked")); + addAnnotation(decl.mods, field, source.pos, source, field.getContext(), "java.lang.SuppressWarnings", treeMaker.NewArray(null, List.nil(), suppressions.toList())); } copyJavadoc(field, decl, CopyJavadoc.GETTER); diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index e0f6276f..3655e680 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1277,15 +1277,17 @@ public class JavacHandlerUtil { public static void addSuppressWarningsAll(JCModifiers mods, JavacNode node, int pos, JCTree source, Context context) { if (!LombokOptionsFactory.getDelombokOptions(context).getFormatPreferences().generateSuppressWarnings()) return; - boolean addJLSuppress = true; - - for (JCAnnotation ann : mods.annotations) { - JCTree type = ann.getAnnotationType(); - Name n = null; - if (type instanceof JCIdent) n = ((JCIdent) type).name; - else if (type instanceof JCFieldAccess) n = ((JCFieldAccess) type).name; - if (n != null && n.contentEquals("SuppressWarnings")) { - addJLSuppress = false; + boolean addJLSuppress = !Boolean.FALSE.equals(node.getAst().readConfiguration(ConfigurationKeys.ADD_SUPPRESSWARNINGS_ANNOTATIONS)); + + if (addJLSuppress) { + for (JCAnnotation ann : mods.annotations) { + JCTree type = ann.getAnnotationType(); + Name n = null; + if (type instanceof JCIdent) n = ((JCIdent) type).name; + else if (type instanceof JCFieldAccess) n = ((JCFieldAccess) type).name; + if (n != null && n.contentEquals("SuppressWarnings")) { + addJLSuppress = false; + } } } if (addJLSuppress) addAnnotation(mods, node, pos, source, context, "java.lang.SuppressWarnings", node.getTreeMaker().Literal("all")); diff --git a/test/transform/resource/after-delombok/SkipSuppressWarnings.java b/test/transform/resource/after-delombok/SkipSuppressWarnings.java new file mode 100644 index 00000000..151d4e17 --- /dev/null +++ b/test/transform/resource/after-delombok/SkipSuppressWarnings.java @@ -0,0 +1,24 @@ +class SkipSuppressWarnings { + private String field = ""; + private final java.util.concurrent.atomic.AtomicReference field2 = new java.util.concurrent.atomic.AtomicReference(); + + public String getField() { + return this.field; + } + + @java.lang.SuppressWarnings({"unchecked"}) + public String getField2() { + java.lang.Object value = this.field2.get(); + if (value == null) { + synchronized (this.field2) { + value = this.field2.get(); + if (value == null) { + final String actualValue = ""; + value = actualValue == null ? this.field2 : actualValue; + this.field2.set(value); + } + } + } + return (String) (value == this.field2 ? null : value); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/SkipSuppressWarnings.java b/test/transform/resource/after-ecj/SkipSuppressWarnings.java new file mode 100644 index 00000000..53032519 --- /dev/null +++ b/test/transform/resource/after-ecj/SkipSuppressWarnings.java @@ -0,0 +1,27 @@ +class SkipSuppressWarnings { + private @lombok.Getter String field = ""; + private final @lombok.Getter(lazy = true) java.util.concurrent.atomic.AtomicReference field2 = new java.util.concurrent.atomic.AtomicReference(); + SkipSuppressWarnings() { + super(); + } + public String getField() { + return this.field; + } + public @java.lang.SuppressWarnings({"unchecked"}) String getField2() { + java.lang.Object value = this.field2.get(); + if ((value == null)) + { + synchronized (this.field2) + { + value = this.field2.get(); + if ((value == null)) + { + final String actualValue = ""; + value = ((actualValue == null) ? this.field2 : actualValue); + this.field2.set(value); + } + } + } + return (String) ((value == this.field2) ? null : value); + } +} \ No newline at end of file diff --git a/test/transform/resource/before/SkipSuppressWarnings.java b/test/transform/resource/before/SkipSuppressWarnings.java new file mode 100644 index 00000000..ed36eeb9 --- /dev/null +++ b/test/transform/resource/before/SkipSuppressWarnings.java @@ -0,0 +1,9 @@ +//CONF: lombok.addSuppressWarnings = false + +class SkipSuppressWarnings { + @lombok.Getter + private String field = ""; + + @lombok.Getter(lazy=true) + private final String field2 = ""; +} \ No newline at end of file diff --git a/test/transform/resource/messages-ecj/SkipSuppressWarnings.java.messages b/test/transform/resource/messages-ecj/SkipSuppressWarnings.java.messages new file mode 100644 index 00000000..5e7d759c --- /dev/null +++ b/test/transform/resource/messages-ecj/SkipSuppressWarnings.java.messages @@ -0,0 +1 @@ +7 Unnecessary @SuppressWarnings("unchecked") \ No newline at end of file -- cgit From 857a57cb1601773a9544d4eaed2f9fecc0741d46 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 10 Jul 2020 02:48:05 +0200 Subject: [bugfix] eclipse version differences for weird LUB types --- .../eclipse/handlers/EclipseHandlerUtil.java | 61 +++++++++++++++++++--- 1 file changed, 53 insertions(+), 8 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index de76e32d..6bfcf16e 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -330,14 +330,16 @@ public class EclipseHandlerUtil { public static final Field STRING_LITERAL__LINE_NUMBER; public static final Field ANNOTATION__MEMBER_VALUE_PAIR_NAME; public static final Field TYPE_REFERENCE__ANNOTATIONS; - public static final Class INTERSECTION_BINDING; - public static final Field INTERSECTION_BINDING_TYPES; + public static final Class INTERSECTION_BINDING1, INTERSECTION_BINDING2; + public static final Field INTERSECTION_BINDING_TYPES1, INTERSECTION_BINDING_TYPES2; static { STRING_LITERAL__LINE_NUMBER = getField(StringLiteral.class, "lineNumber"); ANNOTATION__MEMBER_VALUE_PAIR_NAME = getField(Annotation.class, "memberValuePairName"); TYPE_REFERENCE__ANNOTATIONS = getField(TypeReference.class, "annotations"); - INTERSECTION_BINDING = getClass("org.eclipse.jdt.internal.compiler.lookup.IntersectionTypeBinding18"); - INTERSECTION_BINDING_TYPES = INTERSECTION_BINDING == null ? null : getField(INTERSECTION_BINDING, "intersectingTypes"); + INTERSECTION_BINDING1 = getClass("org.eclipse.jdt.internal.compiler.lookup.IntersectionTypeBinding18"); + INTERSECTION_BINDING2 = getClass("org.eclipse.jdt.internal.compiler.lookup.IntersectionCastTypeBinding"); + INTERSECTION_BINDING_TYPES1 = INTERSECTION_BINDING1 == null ? null : getField(INTERSECTION_BINDING1, "intersectingTypes"); + INTERSECTION_BINDING_TYPES2 = INTERSECTION_BINDING2 == null ? null : getField(INTERSECTION_BINDING2, "intersectingTypes"); } public static int reflectInt(Field f, Object o) { @@ -1045,11 +1047,54 @@ public class EclipseHandlerUtil { return res; } - + + private static final char[] OBJECT_SIG = "Ljava/lang/Object;".toCharArray(); + + private static int compare(char[] a, char[] b) { + if (a == null) return b == null ? 0 : -1; + if (b == null) return +1; + int len = Math.min(a.length, b.length); + for (int i = 0; i < len; i++) { + if (a[i] < b[i]) return -1; + if (a[i] > b[i]) return +1; + } + return a.length < b.length ? -1 : a.length > b.length ? +1 : 0; + } + public static TypeReference makeType(TypeBinding binding, ASTNode pos, boolean allowCompound) { - if (binding.getClass() == EclipseReflectiveMembers.INTERSECTION_BINDING) { - Object[] arr = (Object[]) EclipseReflectiveMembers.reflect(EclipseReflectiveMembers.INTERSECTION_BINDING_TYPES, binding); - binding = (TypeBinding) arr[0]; + Object[] arr = null; + if (binding.getClass() == EclipseReflectiveMembers.INTERSECTION_BINDING1) { + arr = (Object[]) EclipseReflectiveMembers.reflect(EclipseReflectiveMembers.INTERSECTION_BINDING_TYPES1, binding); + } else if (binding.getClass() == EclipseReflectiveMembers.INTERSECTION_BINDING2) { + arr = (Object[]) EclipseReflectiveMembers.reflect(EclipseReflectiveMembers.INTERSECTION_BINDING_TYPES2, binding); + } + + if (arr != null) { + // Is there a class? Alphabetically lowest wins. + TypeBinding winner = null; + int winLevel = 0; // 100 = array, 50 = class, 20 = typevar, 15 = wildcard, 10 = interface, 1 = Object. + for (Object b : arr) { + if (b instanceof TypeBinding) { + TypeBinding tb = (TypeBinding) b; + int level = 0; + if (tb.isArrayType()) level = 100; + else if (tb.isClass()) level = 50; + else if (tb.isTypeVariable()) level = 20; + else if (tb.isWildcard()) level = 15; + else level = 10; + + if (level == 50 && compare(tb.signature(), OBJECT_SIG) == 0) level = 1; + + if (winLevel > level) continue; + if (winLevel < level) { + winner = tb; + winLevel = level; + continue; + } + if (compare(winner.signature(), tb.signature()) > 0) winner = tb; + } + } + binding = winner; } int dims = binding.dimensions(); binding = binding.leafComponentType(); -- cgit From 32e7cd18571200c41736e70daa4815893e9ea8c3 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 10 Jul 2020 02:48:35 +0200 Subject: [bugfix] eclipse version differences in constants for registering operator type --- src/core/lombok/eclipse/handlers/HandleNonNull.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/eclipse/handlers/HandleNonNull.java b/src/core/lombok/eclipse/handlers/HandleNonNull.java index c4d42c2e..903d098b 100644 --- a/src/core/lombok/eclipse/handlers/HandleNonNull.java +++ b/src/core/lombok/eclipse/handlers/HandleNonNull.java @@ -40,7 +40,6 @@ import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.IfStatement; import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.NullLiteral; -import org.eclipse.jdt.internal.compiler.ast.OperatorIds; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.Statement; import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement; @@ -232,11 +231,11 @@ public class HandleNonNull extends EclipseAnnotationHandler { Expression cond = isIf ? ((IfStatement) stat).condition : ((AssertStatement) stat).assertExpression; if (!(cond instanceof EqualExpression)) return null; EqualExpression bin = (EqualExpression) cond; - int operatorId = ((bin.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT); + String op = bin.operatorToString(); if (isIf) { - if (operatorId != OperatorIds.EQUAL_EQUAL) return null; + if (!"==".equals(op)) return null; } else { - if (operatorId != OperatorIds.NOT_EQUAL) return null; + if (!"!=".equals(op)) return null; } if (!(bin.left instanceof SingleNameReference)) return null; if (!(bin.right instanceof NullLiteral)) return null; -- cgit From 1fd2401bade3db3bb3a1bd88727823776f39be0c Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 10 Jul 2020 02:50:38 +0200 Subject: [test] more flexible options for limiting your tests. --- .../eclipse/handlers/HandleSuperBuilder.java | 23 +++++++++++----------- test/core/src/lombok/AbstractRunTests.java | 18 +++++++++++++++++ test/core/src/lombok/DirectoryRunner.java | 10 ++++++++-- 3 files changed, 38 insertions(+), 13 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java index 2ba456da..b1e7c419 100644 --- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java @@ -145,9 +145,9 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { generateBuilderMethod = true; } if (!checkName("buildMethodName", buildMethodName, annotationNode)) return; - + boolean toBuilder = superbuilderAnnotation.toBuilder(); - + EclipseNode tdParent = annotationNode.up(); java.util.List builderFields = new ArrayList(); @@ -234,7 +234,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { TypeReference extendsClause = td.superclass; TypeReference superclassBuilderClass = null; TypeReference[] typeArguments = new TypeReference[] { - new SingleTypeReference(classGenericName.toCharArray(), 0), + new SingleTypeReference(classGenericName.toCharArray(), 0), new SingleTypeReference(builderGenericName.toCharArray(), 0) }; if (extendsClause instanceof QualifiedTypeReference) { @@ -333,14 +333,14 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { cleanDecl.type = TypeReference.baseTypeReference(TypeIds.T_boolean, 0); injectFieldAndMarkGenerated(builderType, cleanDecl); } - + if (toBuilder) { // Generate $fillValuesFrom() method in the abstract builder. injectMethod(builderType, generateFillValuesMethod(tdParent, superclassBuilderClass != null, builderGenericName, classGenericName, builderClassName, typeParams)); // Generate $fillValuesFromInstanceIntoBuilder() method in the builder implementation class. injectMethod(builderType, generateStaticFillValuesMethod(tdParent, builderClassName, typeParams, builderFields, ast, superbuilderAnnotation.setterPrefix())); } - + // Generate abstract self() and build() methods in the abstract builder. injectMethod(builderType, generateAbstractSelfMethod(cfv, tdParent, superclassBuilderClass != null, builderGenericName)); injectMethod(builderType, generateAbstractBuildMethod(cfv, builderType, buildMethodName, builderFields, superclassBuilderClass != null, classGenericName, ast)); @@ -386,7 +386,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { } sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderImplType, annotationNode); } - + if (toBuilder) { // Add the toBuilder() method to the annotated class. switch (methodExists(TO_BUILDER_METHOD_NAME_STRING, tdParent, 0)) { @@ -399,9 +399,10 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { // Should not happen. } } - + // Create the self() and build() methods in the BuilderImpl. injectMethod(builderImplType, generateSelfMethod(cfv, builderImplType, typeParams, p)); + if (methodExists(buildMethodName, builderImplType, -1) == MemberExistsResult.NOT_EXISTS) { injectMethod(builderImplType, generateBuildMethod(cfv, builderImplType, buildMethodName, returnType, builderFields, ast)); } @@ -419,7 +420,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { } } } - + private EclipseNode generateBuilderAbstractClass(EclipseNode tdParent, String builderClass, TypeReference superclassBuilderClass, TypeParameter[] typeParams, ASTNode source, String classGenericName, String builderGenericName) { @@ -448,7 +449,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { builder.superclass = copyType(superclassBuilderClass, source); builder.createDefaultConstructor(false, true); - + builder.traverse(new SetGeneratedByVisitor(source), (ClassScope) null); return injectType(tdParent, builder); } @@ -806,8 +807,8 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler { out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; out.modifiers = ClassFileConstants.AccProtected; Annotation overrideAnn = makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, builderImplType.get()); - Annotation rrAnn = cfv.generateReturnsReceiver() ? generateNamedAnnotation(builderImplType.get(), CheckerFrameworkVersion.NAME__RETURNS_RECEIVER): null; - Annotation sefAnn = cfv.generatePure() ? generateNamedAnnotation(builderImplType.get(), CheckerFrameworkVersion.NAME__PURE): null; + Annotation rrAnn = cfv.generateReturnsReceiver() ? generateNamedAnnotation(builderImplType.get(), CheckerFrameworkVersion.NAME__RETURNS_RECEIVER) : null; + Annotation sefAnn = cfv.generatePure() ? generateNamedAnnotation(builderImplType.get(), CheckerFrameworkVersion.NAME__PURE) : null; if (rrAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn, sefAnn}; else if (rrAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn}; else if (sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn}; diff --git a/test/core/src/lombok/AbstractRunTests.java b/test/core/src/lombok/AbstractRunTests.java index 6d2b6312..8e73e122 100644 --- a/test/core/src/lombok/AbstractRunTests.java +++ b/test/core/src/lombok/AbstractRunTests.java @@ -190,6 +190,8 @@ public abstract class AbstractRunTests { for (CompilerMessage actualMessage : actualMessages) { System.out.println(actualMessage); } + System.out.println("**** Actual File ******"); + System.out.println(lineNumber(actualFile)); System.out.println("*******************"); } if (dumpActualFilesHere != null) { @@ -199,6 +201,22 @@ public abstract class AbstractRunTests { } } + private CharSequence lineNumber(String content) { + StringBuilder out = new StringBuilder(); + int pos = 0; + int ln = 1; + while (true) { + out.append(String.format("%4d ", ln)); + int idx = content.indexOf('\n', pos); + if (idx == -1) { + return out.append(content.substring(pos)); + } + out.append(content.substring(pos, idx + 1)); + ln++; + pos = idx + 1; + } + } + @SuppressWarnings("null") /* eclipse bug workaround; it falsely thinks stuffAc will always be null. */ private static void compareMessages(String name, LombokImmutableList expected, LinkedHashSet actual) { Iterator expectedIterator = expected.iterator(); diff --git a/test/core/src/lombok/DirectoryRunner.java b/test/core/src/lombok/DirectoryRunner.java index e4792ca9..a174355d 100644 --- a/test/core/src/lombok/DirectoryRunner.java +++ b/test/core/src/lombok/DirectoryRunner.java @@ -47,7 +47,7 @@ public class DirectoryRunner extends Runner { @Override public int getVersion() { return Javac.getJavaCompilerVersion(); } - }, + }, JAVAC { @Override public int getVersion() { return DELOMBOK.getVersion(); @@ -85,11 +85,17 @@ public class DirectoryRunner extends Runner { if (!file.isFile() || !file.getName().endsWith(".java")) return false; boolean positiveFilter = false; for (String dfof : DEBUG_FOCUS_ON_FILE) { + if (dfof.isEmpty()) continue; if (!dfof.endsWith(".java")) dfof = dfof + ".java"; boolean invert = dfof.startsWith("!"); if (invert) dfof = dfof.substring(1); positiveFilter = positiveFilter || !invert; - if (file.getName().equals(dfof)) return !invert; + int starIdx = dfof.indexOf('*'); + if (starIdx == -1) { + if (file.getName().equals(dfof)) return !invert; + } else { + if (file.getName().startsWith(dfof.substring(0, starIdx)) && file.getName().endsWith(dfof.substring(starIdx + 1))) return !invert; + } } return !positiveFilter; } -- cgit From 355ea57b8075eacca39d3e0cbcdec67585d095fe Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Tue, 14 Jul 2020 11:17:38 +0200 Subject: Handle each Eclipse ASTs not more than two times (diet + full) --- src/core/lombok/eclipse/EclipseAST.java | 2 +- src/core/lombok/eclipse/TransformEclipseAST.java | 27 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/eclipse/EclipseAST.java b/src/core/lombok/eclipse/EclipseAST.java index b45ac72d..d53856af 100644 --- a/src/core/lombok/eclipse/EclipseAST.java +++ b/src/core/lombok/eclipse/EclipseAST.java @@ -350,7 +350,7 @@ public class EclipseAST extends AST { if (!changed) clearChanged(); } - private static boolean isComplete(CompilationUnitDeclaration unit) { + public static boolean isComplete(CompilationUnitDeclaration unit) { return (unit.bits & ASTNode.HasAllMethodBodies) != 0; } diff --git a/src/core/lombok/eclipse/TransformEclipseAST.java b/src/core/lombok/eclipse/TransformEclipseAST.java index 6fcde937..f7b6976f 100644 --- a/src/core/lombok/eclipse/TransformEclipseAST.java +++ b/src/core/lombok/eclipse/TransformEclipseAST.java @@ -24,6 +24,7 @@ package lombok.eclipse; import static lombok.eclipse.handlers.EclipseHandlerUtil.*; import java.lang.reflect.Field; +import java.util.WeakHashMap; import lombok.ConfigurationKeys; import lombok.core.LombokConfiguration; @@ -63,6 +64,7 @@ public class TransformEclipseAST { public static boolean disableLombok = false; private static final HistogramTracker lombokTracker; + private static WeakHashMap completlyHandled = new WeakHashMap(); static { String v = System.getProperty("lombok.histogram"); @@ -129,6 +131,30 @@ public class TransformEclipseAST { return existing; } + /** + * Check if lombok already handled the given AST. This method will return + * true once for diet mode and once for full mode. + * + * The reason for this is that Eclipse invokes the transform method multiple + * times during compilation and it is enough to transform it once and not + * repeat the whole thing over and over again. + * + * @param ast The AST node belonging to the compilation unit (java speak for a single source file). + * @return true if this AST was already handled by lombok. + */ + public static boolean alreadyTransformed(CompilationUnitDeclaration ast) { + Boolean state = completlyHandled.get(ast); + if (state != null) { + if (state) return true; + if (!EclipseAST.isComplete(ast)) return true; + + completlyHandled.put(ast, Boolean.TRUE); + } else { + completlyHandled.put(ast, Boolean.FALSE); + } + return false; + } + /** * This method is called immediately after Eclipse finishes building a CompilationUnitDeclaration, which is * the top-level AST node when Eclipse parses a source file. The signature is 'magic' - you should not @@ -144,6 +170,7 @@ public class TransformEclipseAST { if (disableLombok) return; if (Symbols.hasSymbol("lombok.disable")) return; + if (alreadyTransformed(ast)) return; // Do NOT abort if (ast.bits & ASTNode.HasAllMethodBodies) != 0 - that doesn't work. -- cgit From f44c642d406c2ad9ca6d679ca1b336e68ff28853 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Mon, 27 Jul 2020 13:37:59 +0200 Subject: Use enum instead of Boolean; switch to synchronized map --- src/core/lombok/eclipse/TransformEclipseAST.java | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/eclipse/TransformEclipseAST.java b/src/core/lombok/eclipse/TransformEclipseAST.java index f7b6976f..59a0709e 100644 --- a/src/core/lombok/eclipse/TransformEclipseAST.java +++ b/src/core/lombok/eclipse/TransformEclipseAST.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2019 The Project Lombok Authors. + * Copyright (C) 2009-2020 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,6 +24,8 @@ package lombok.eclipse; import static lombok.eclipse.handlers.EclipseHandlerUtil.*; import java.lang.reflect.Field; +import java.util.Collections; +import java.util.Map; import java.util.WeakHashMap; import lombok.ConfigurationKeys; @@ -64,7 +66,7 @@ public class TransformEclipseAST { public static boolean disableLombok = false; private static final HistogramTracker lombokTracker; - private static WeakHashMap completlyHandled = new WeakHashMap(); + private static Map transformationStates = Collections.synchronizedMap(new WeakHashMap()); static { String v = System.getProperty("lombok.histogram"); @@ -143,14 +145,14 @@ public class TransformEclipseAST { * @return true if this AST was already handled by lombok. */ public static boolean alreadyTransformed(CompilationUnitDeclaration ast) { - Boolean state = completlyHandled.get(ast); - if (state != null) { - if (state) return true; + State state = transformationStates.get(ast); + + if (state == State.FULL) return true; + if (state == State.DIET) { if (!EclipseAST.isComplete(ast)) return true; - - completlyHandled.put(ast, Boolean.TRUE); + transformationStates.put(ast, State.FULL); } else { - completlyHandled.put(ast, Boolean.FALSE); + transformationStates.put(ast, State.DIET); } return false; } @@ -270,4 +272,9 @@ public class TransformEclipseAST { nextPriority = Math.min(nextPriority, handlers.handleAnnotation(top, annotationNode, annotation, priority)); } } + + private static enum State { + DIET, + FULL + } } -- cgit From edbfdfe8c52c17a38bf2b526d14a4f622c5402f7 Mon Sep 17 00:00:00 2001 From: Kay Schubert Date: Mon, 17 Aug 2020 15:57:45 +0200 Subject: Issue 2552 - generate class initializer body only after field member injection --- src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java index 9343011f..cee3912c 100644 --- a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java +++ b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java @@ -171,10 +171,10 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler