From 70f77f928ac7a6edf3ef91a41399c9a79561c871 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Thu, 9 Feb 2017 22:45:45 +0100 Subject: [i1014] Only add lombok.Generated if it is explicitly turned on --- src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 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 f822e095..ab4ca27b 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -1345,10 +1345,10 @@ public class EclipseHandlerUtil { public static Annotation[] addGenerated(EclipseNode node, ASTNode source, Annotation[] originalAnnotationArray) { Annotation[] result = originalAnnotationArray; - if (HandlerUtil.shouldAddGenerated(node, ConfigurationKeys.ADD_JAVAX_GENERATED_ANNOTATIONS)) { + if (HandlerUtil.shouldAddGenerated(node)) { result = addAnnotation(source, result, JAVAX_ANNOTATION_GENERATED, new StringLiteral(LOMBOK, 0, 0, 0)); } - if (HandlerUtil.shouldAddGenerated(node, ConfigurationKeys.ADD_LOMBOK_GENERATED_ANNOTATIONS)) { + if (Boolean.TRUE.equals(node.getAst().readConfiguration(ConfigurationKeys.ADD_LOMBOK_GENERATED_ANNOTATIONS))) { result = addAnnotation(source, result, LOMBOK_GENERATED, null); } return result; -- cgit From 2335512c8e134a1f6a7a567948543bf87613544b Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Fri, 10 Feb 2017 00:10:07 +0100 Subject: [i1274] Add outer name to type name for nested types in equals. --- doc/changelog.markdown | 1 + .../eclipse/handlers/HandleEqualsAndHashCode.java | 70 +++++++++++++--------- .../javac/handlers/HandleEqualsAndHashCode.java | 36 +++++------ .../resource/after-delombok/DataOnLocalClass.java | 2 +- .../EqualsAndHashCodeNestedShadow.java | 56 +++++++++++++++++ .../resource/after-ecj/DataOnLocalClass.java | 2 +- .../after-ecj/EqualsAndHashCodeNestedShadow.java | 58 ++++++++++++++++++ .../before/EqualsAndHashCodeNestedShadow.java | 15 +++++ 8 files changed, 190 insertions(+), 50 deletions(-) create mode 100644 test/transform/resource/after-delombok/EqualsAndHashCodeNestedShadow.java create mode 100644 test/transform/resource/after-ecj/EqualsAndHashCodeNestedShadow.java create mode 100644 test/transform/resource/before/EqualsAndHashCodeNestedShadow.java (limited to 'src/core/lombok/eclipse') diff --git a/doc/changelog.markdown b/doc/changelog.markdown index bad185fa..1f5218d9 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -6,6 +6,7 @@ Lombok Changelog * FEATURE: Generated classes, methods and fields can now also annotated with `@lombok.Generated` [Issue #1014](https://github.com/rzwitserloot/lombok/issues/1014)
* PLATFORM: Lombok can now be used together with other annotation processors that are looking for lombok-generated methods, but only if lombok is the first annotation processor executed. The most commonly used annotation processor affected by this change is [MapStruct](http://mapstruct.org/); we've worked with the mapstruct team specifically to allow any order. Other annotation processors might follow the framework we've built to make this possible; point the authors of any such processor to us and we'll get it sorted [MapStruct issue #510](https://github.com/mapstruct/mapstruct/issues/510) [Lombok issue #973](https://github.com/rzwitserloot/lombok/issues/973) * PLATFORM: Eclipse: Refactor script 'rename field' when lombok has also generated getters and/or setters for this field is nicer now [Issue #210](https://github.com/rzwitserloot/lombok/issues/210) +* BUGFIX: Something you never encountered. [Issue #1274](https://github.com/rzwitserloot/lombok/issues/1274) ### v1.16.12 (December 5th, 2016) * FEATURE: `var` is the mutable sister of `val`. For now experimental, and opt-in using `ALLOW` in the flagUsage configuration key. Thanks for the contribution, Bulgakov Alexander. diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java index a56eee89..bc25ae2a 100644 --- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java @@ -67,6 +67,7 @@ import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.NameReference; import org.eclipse.jdt.internal.compiler.ast.NullLiteral; import org.eclipse.jdt.internal.compiler.ast.OperatorIds; +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; @@ -458,7 +459,14 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler list = new ArrayList(); list.add(type.getName()); EclipseNode tNode = type.up(); @@ -468,21 +476,44 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler fields, boolean callSuper, ASTNode source, FieldAccess fieldAccess, boolean needsCanEqual, List onParam) { int pS = source.sourceStart; int pE = source.sourceEnd; long p = (long)pS << 32 | pE; - TypeDeclaration typeDecl = (TypeDeclaration)type.get(); MethodDeclaration method = new MethodDeclaration( ((CompilationUnitDeclaration) type.top().get()).compilationResult); @@ -528,7 +559,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler other = (MyType) o; */ { + /* Outer.Inner.MyType other = (Outer.Inner.MyType) o; */ { if (!fields.isEmpty() || needsCanEqual) { LocalDeclaration other = new LocalDeclaration(otherName, pS, pE); other.modifiers |= ClassFileConstants.AccFinal; setGeneratedBy(other, source); - char[] typeName = typeDecl.name; - TypeReference targetType; - if (typeDecl.typeParameters == null || typeDecl.typeParameters.length == 0) { - targetType = new SingleTypeReference(typeName, p); - setGeneratedBy(targetType, source); - other.type = new SingleTypeReference(typeName, p); - setGeneratedBy(other.type, source); - } else { - TypeReference[] typeArgs = new TypeReference[typeDecl.typeParameters.length]; - for (int i = 0; i < typeArgs.length; i++) { - typeArgs[i] = new Wildcard(Wildcard.UNBOUND); - typeArgs[i].sourceStart = pS; typeArgs[i].sourceEnd = pE; - setGeneratedBy(typeArgs[i], source); - } - targetType = new ParameterizedSingleTypeReference(typeName, typeArgs, 0, p); - setGeneratedBy(targetType, source); - other.type = new ParameterizedSingleTypeReference(typeName, copyTypes(typeArgs, source), 0, p); - setGeneratedBy(other.type, source); - } + TypeReference targetType = createTypeReference(type, p, source, true); + setGeneratedBy(targetType, source); + other.type = createTypeReference(type, p, source, true); + setGeneratedBy(other.type, source); NameReference oRef = new SingleNameReference(new char[] { 'o' }, p); setGeneratedBy(oRef, source); other.initialization = makeCastExpression(oRef, targetType, source); @@ -772,7 +788,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler list = new ArrayList(); list.add(type.getName()); JavacNode tNode = type.up(); @@ -372,20 +372,28 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler wildcards = new ListBuffer(); + for (int i = 0 ; i < typeDecl.typarams.length() ; i++) { + wildcards.append(maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null)); + } + + return maker.TypeApply(chain, wildcards.toList()); } public JCMethodDecl createEquals(JavacNode typeNode, List fields, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual, JCTree source, List onParam) { JavacTreeMaker maker = typeNode.getTreeMaker(); - JCClassDecl type = (JCClassDecl) typeNode.get(); Name oName = typeNode.toName("o"); Name otherName = typeNode.toName("other"); @@ -408,27 +416,13 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler other = (MyType) o; */ { + /* Outer.Inner.MyType other = (Outer.Inner.MyType) o; */ { if (!fields.isEmpty() || needsCanEqual) { - final JCExpression selfType1, selfType2; - ListBuffer wildcards1 = new ListBuffer(); - ListBuffer wildcards2 = new ListBuffer(); - for (int i = 0 ; i < type.typarams.length() ; i++) { - wildcards1.append(maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null)); - wildcards2.append(maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null)); - } - - if (type.typarams.isEmpty()) { - selfType1 = maker.Ident(type.name); - selfType2 = maker.Ident(type.name); - } else { - selfType1 = maker.TypeApply(maker.Ident(type.name), wildcards1.toList()); - selfType2 = maker.TypeApply(maker.Ident(type.name), wildcards2.toList()); - } + final JCExpression selfType1 = createTypeReference(typeNode, true), selfType2 = createTypeReference(typeNode, true); statements.append( maker.VarDef(maker.Modifiers(finalFlag), otherName, selfType1, maker.TypeCast(selfType2, maker.Ident(oName)))); @@ -533,7 +527,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler params = List.of(maker.VarDef(maker.Modifiers(flags, onParam), otherName, objectType, null)); JCBlock body = maker.Block(0, List.of( - maker.Return(maker.TypeTest(maker.Ident(otherName), createTypeReference(typeNode))))); + maker.Return(maker.TypeTest(maker.Ident(otherName), createTypeReference(typeNode, false))))); return recursiveSetGeneratedBy(maker.MethodDef(mods, canEqualName, returnType, List.nil(), params, List.nil(), body, null), source, typeNode.getContext()); } diff --git a/test/transform/resource/after-delombok/DataOnLocalClass.java b/test/transform/resource/after-delombok/DataOnLocalClass.java index 90ae7649..9fe16070 100644 --- a/test/transform/resource/after-delombok/DataOnLocalClass.java +++ b/test/transform/resource/after-delombok/DataOnLocalClass.java @@ -97,7 +97,7 @@ class DataOnLocalClass2 { public boolean equals(final java.lang.Object o) { if (o == this) return true; if (!(o instanceof Local.InnerLocal)) return false; - final InnerLocal other = (InnerLocal) o; + final Local.InnerLocal other = (Local.InnerLocal) o; if (!other.canEqual((java.lang.Object) this)) return false; final java.lang.Object this$name = this.getName(); final java.lang.Object other$name = other.getName(); diff --git a/test/transform/resource/after-delombok/EqualsAndHashCodeNestedShadow.java b/test/transform/resource/after-delombok/EqualsAndHashCodeNestedShadow.java new file mode 100644 index 00000000..ac687d84 --- /dev/null +++ b/test/transform/resource/after-delombok/EqualsAndHashCodeNestedShadow.java @@ -0,0 +1,56 @@ +interface EqualsAndHashCodeNestedShadow { + interface Foo { + } + class Bar { + public static class Foo extends Bar implements EqualsAndHashCodeNestedShadow.Foo { + @java.lang.Override + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public boolean equals(final java.lang.Object o) { + if (o == this) return true; + if (!(o instanceof EqualsAndHashCodeNestedShadow.Bar.Foo)) return false; + final EqualsAndHashCodeNestedShadow.Bar.Foo other = (EqualsAndHashCodeNestedShadow.Bar.Foo) o; + if (!other.canEqual((java.lang.Object) this)) return false; + return true; + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + protected boolean canEqual(final java.lang.Object other) { + return other instanceof EqualsAndHashCodeNestedShadow.Bar.Foo; + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public int hashCode() { + int result = 1; + return result; + } + } + } + class Baz { + public static class Foo extends Bar implements EqualsAndHashCodeNestedShadow.Foo { + @java.lang.Override + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public boolean equals(final java.lang.Object o) { + if (o == this) return true; + if (!(o instanceof EqualsAndHashCodeNestedShadow.Baz.Foo)) return false; + final EqualsAndHashCodeNestedShadow.Baz.Foo other = (EqualsAndHashCodeNestedShadow.Baz.Foo) o; + if (!other.canEqual((java.lang.Object) this)) return false; + return true; + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + protected boolean canEqual(final java.lang.Object other) { + return other instanceof EqualsAndHashCodeNestedShadow.Baz.Foo; + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public int hashCode() { + int result = 1; + return result; + } + } + } +} diff --git a/test/transform/resource/after-ecj/DataOnLocalClass.java b/test/transform/resource/after-ecj/DataOnLocalClass.java index 9d6bced1..a86837e3 100644 --- a/test/transform/resource/after-ecj/DataOnLocalClass.java +++ b/test/transform/resource/after-ecj/DataOnLocalClass.java @@ -73,7 +73,7 @@ class DataOnLocalClass2 { return true; if ((! (o instanceof Local.InnerLocal))) return false; - final InnerLocal other = (InnerLocal) o; + final Local.InnerLocal other = (Local.InnerLocal) o; if ((! other.canEqual((java.lang.Object) this))) return false; final java.lang.Object this$name = this.getName(); diff --git a/test/transform/resource/after-ecj/EqualsAndHashCodeNestedShadow.java b/test/transform/resource/after-ecj/EqualsAndHashCodeNestedShadow.java new file mode 100644 index 00000000..5af6e9d8 --- /dev/null +++ b/test/transform/resource/after-ecj/EqualsAndHashCodeNestedShadow.java @@ -0,0 +1,58 @@ +interface EqualsAndHashCodeNestedShadow { + interface Foo { + } + class Bar { + public static @lombok.EqualsAndHashCode(callSuper = false) class Foo extends Bar implements EqualsAndHashCodeNestedShadow.Foo { + public Foo() { + super(); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") boolean equals(final java.lang.Object o) { + if ((o == this)) + return true; + if ((! (o instanceof EqualsAndHashCodeNestedShadow.Bar.Foo))) + return false; + final EqualsAndHashCodeNestedShadow.Bar.Foo other = (EqualsAndHashCodeNestedShadow.Bar.Foo) o; + if ((! other.canEqual((java.lang.Object) this))) + return false; + return true; + } + protected @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") boolean canEqual(final java.lang.Object other) { + return (other instanceof EqualsAndHashCodeNestedShadow.Bar.Foo); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") int hashCode() { + int result = 1; + return result; + } + } + Bar() { + super(); + } + } + class Baz { + public static @lombok.EqualsAndHashCode(callSuper = false) class Foo extends Bar implements EqualsAndHashCodeNestedShadow.Foo { + public Foo() { + super(); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") boolean equals(final java.lang.Object o) { + if ((o == this)) + return true; + if ((! (o instanceof EqualsAndHashCodeNestedShadow.Baz.Foo))) + return false; + final EqualsAndHashCodeNestedShadow.Baz.Foo other = (EqualsAndHashCodeNestedShadow.Baz.Foo) o; + if ((! other.canEqual((java.lang.Object) this))) + return false; + return true; + } + protected @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") boolean canEqual(final java.lang.Object other) { + return (other instanceof EqualsAndHashCodeNestedShadow.Baz.Foo); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") int hashCode() { + int result = 1; + return result; + } + } + Baz() { + super(); + } + } +} \ No newline at end of file diff --git a/test/transform/resource/before/EqualsAndHashCodeNestedShadow.java b/test/transform/resource/before/EqualsAndHashCodeNestedShadow.java new file mode 100644 index 00000000..2b0c4fa3 --- /dev/null +++ b/test/transform/resource/before/EqualsAndHashCodeNestedShadow.java @@ -0,0 +1,15 @@ +interface EqualsAndHashCodeNestedShadow { + interface Foo { + } + class Bar { + @lombok.EqualsAndHashCode(callSuper=false) + public static class Foo extends Bar implements EqualsAndHashCodeNestedShadow.Foo { + } + } + + class Baz { + @lombok.EqualsAndHashCode(callSuper=false) + public static class Foo extends Bar implements EqualsAndHashCodeNestedShadow.Foo { + } + } +} \ No newline at end of file -- cgit From 1d32894ca316dd83c873d1e46746ee6ca37f8059 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Tue, 14 Feb 2017 00:19:14 +0100 Subject: Fixes issue #1287 - if a field gets marked as static via `@UtilityClass`, don’t make it final via `@FieldDefaults`. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/lombok/eclipse/handlers/HandleUtilityClass.java | 2 ++ src/core/lombok/javac/handlers/HandleUtilityClass.java | 2 ++ 2 files changed, 4 insertions(+) (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 199ce102..959c1d20 100644 --- a/src/core/lombok/eclipse/handlers/HandleUtilityClass.java +++ b/src/core/lombok/eclipse/handlers/HandleUtilityClass.java @@ -49,6 +49,7 @@ import org.mangosdk.spi.ProviderFor; import lombok.ConfigurationKeys; import lombok.core.AnnotationValues; +import lombok.core.HandlerPriority; import lombok.core.AST.Kind; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseNode; @@ -57,6 +58,7 @@ import lombok.experimental.UtilityClass; /** * Handles the {@code lombok.experimental.UtilityClass} annotation for eclipse. */ +@HandlerPriority(-4096) //-2^12; to ensure @FieldDefaults picks up on the 'static' we set here. @ProviderFor(EclipseAnnotationHandler.class) public class HandleUtilityClass extends EclipseAnnotationHandler { @Override public void handle(AnnotationValues annotation, Annotation ast, EclipseNode annotationNode) { diff --git a/src/core/lombok/javac/handlers/HandleUtilityClass.java b/src/core/lombok/javac/handlers/HandleUtilityClass.java index 6d3ec63b..ee8081d6 100644 --- a/src/core/lombok/javac/handlers/HandleUtilityClass.java +++ b/src/core/lombok/javac/handlers/HandleUtilityClass.java @@ -44,6 +44,7 @@ import com.sun.tools.javac.util.Name; import lombok.ConfigurationKeys; import lombok.core.AST.Kind; import lombok.core.AnnotationValues; +import lombok.core.HandlerPriority; import lombok.experimental.UtilityClass; import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; @@ -53,6 +54,7 @@ import lombok.javac.JavacTreeMaker; /** * Handles the {@code @UtilityClass} annotation for javac. */ +@HandlerPriority(-4096) //-2^12; to ensure @FieldDefaults picks up on the 'static' we set here. @ProviderFor(JavacAnnotationHandler.class) public class HandleUtilityClass extends JavacAnnotationHandler { @Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { -- cgit From d05d03743316e45abfd0d00397999d7eb959eb64 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Mon, 6 Mar 2017 23:34:23 +0100 Subject: Fixed issue #778: problems with onX if the annotation to be added has named args. --- doc/changelog.markdown | 1 + src/core/lombok/AllArgsConstructor.java | 7 +- src/core/lombok/EqualsAndHashCode.java | 9 +- src/core/lombok/Getter.java | 9 +- src/core/lombok/NoArgsConstructor.java | 7 +- src/core/lombok/RequiredArgsConstructor.java | 7 +- src/core/lombok/Setter.java | 14 +++- .../eclipse/handlers/EclipseHandlerUtil.java | 91 +++++++++++++------- .../lombok/eclipse/handlers/HandleConstructor.java | 6 +- .../eclipse/handlers/HandleEqualsAndHashCode.java | 2 +- src/core/lombok/eclipse/handlers/HandleGetter.java | 2 +- src/core/lombok/eclipse/handlers/HandleSetter.java | 4 +- src/core/lombok/eclipse/handlers/HandleWither.java | 4 +- src/core/lombok/experimental/Wither.java | 14 +++- .../lombok/javac/handlers/HandleConstructor.java | 6 +- .../javac/handlers/HandleEqualsAndHashCode.java | 2 +- src/core/lombok/javac/handlers/HandleGetter.java | 2 +- src/core/lombok/javac/handlers/HandleSetter.java | 4 +- src/core/lombok/javac/handlers/HandleWither.java | 4 +- .../lombok/javac/handlers/JavacHandlerUtil.java | 97 +++++++++++++--------- .../resource/after-delombok/OnXJava7Style.java | 43 ++++++++++ .../resource/after-delombok/OnXJava8Style.java | 43 ++++++++++ .../resource/after-ecj/OnXJava7Style.java | 31 +++++++ .../resource/after-ecj/OnXJava7StyleOn8.java | 31 +++++++ .../resource/after-ecj/OnXJava8Style.java | 31 +++++++ .../resource/after-ecj/OnXJava8StyleOn7.java | 31 +++++++ .../resource/before/GetterOnMethodErrors2.java | 1 + test/transform/resource/before/OnXJava7Style.java | 16 ++++ .../resource/before/OnXJava7StyleOn8.java | 18 ++++ test/transform/resource/before/OnXJava8Style.java | 16 ++++ .../resource/before/OnXJava8StyleOn7.java | 18 ++++ .../GetterOnMethodErrors2.java.messages | 8 +- .../GetterOnMethodErrors2.java.messages | 8 +- usage_examples/experimental/onXExample_pre.jpage | 6 +- website/features/experimental/onX.html | 6 +- 35 files changed, 488 insertions(+), 111 deletions(-) create mode 100644 test/transform/resource/after-delombok/OnXJava7Style.java create mode 100644 test/transform/resource/after-delombok/OnXJava8Style.java create mode 100644 test/transform/resource/after-ecj/OnXJava7Style.java create mode 100644 test/transform/resource/after-ecj/OnXJava7StyleOn8.java create mode 100644 test/transform/resource/after-ecj/OnXJava8Style.java create mode 100644 test/transform/resource/after-ecj/OnXJava8StyleOn7.java create mode 100644 test/transform/resource/before/OnXJava7Style.java create mode 100644 test/transform/resource/before/OnXJava7StyleOn8.java create mode 100644 test/transform/resource/before/OnXJava8Style.java create mode 100644 test/transform/resource/before/OnXJava8StyleOn7.java (limited to 'src/core/lombok/eclipse') diff --git a/doc/changelog.markdown b/doc/changelog.markdown index eba0c595..6fc3af38 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -4,6 +4,7 @@ Lombok Changelog ### v1.16.15 "Edgy Guinea Pig" * v1.16.14 is the latest stable release of Project Lombok. * PLATFORM: Improved jdk9 support, work in progress. +* BUGFIX: The `onX` feature (which lets you add annotations to generated methods) did not work if the annotation you added contained named parameters, and you are compiling with JDK8's javac. We can't fix this (it's a bug in javac), but we have provided an alternate, prettier way to do `onX` on javac8+. [Issue #778](https://github.com/rzwitserloot/lombok/issues/778) [onX documentation](https://projectlombok.org/features/experimental/onX.html) ### v1.16.14 (February 10th, 2017) * FEATURE: Generated classes, methods and fields can now also annotated with `@lombok.Generated` [Issue #1014](https://github.com/rzwitserloot/lombok/issues/1014)
diff --git a/src/core/lombok/AllArgsConstructor.java b/src/core/lombok/AllArgsConstructor.java index 3037c9db..45ae897c 100644 --- a/src/core/lombok/AllArgsConstructor.java +++ b/src/core/lombok/AllArgsConstructor.java @@ -49,7 +49,12 @@ public @interface AllArgsConstructor { String staticName() default ""; /** - * Any annotations listed here are put on the generated constructor. The syntax for this feature is: {@code @AllArgsConstructor(onConstructor=@__({@AnnotationsGoHere}))} + * Any annotations listed here are put on the generated constructor. + * The syntax for this feature depends on JDK version (nothing we can do about that; it's to work around javac bugs).
+ * up to JDK7:
+ * {@code @AllArgsConstructor(onConstructor=@__({@AnnotationsGoHere}))}
+ * from JDK8:
+ * {@code @AllArgsConstructor(onConstructor_={@AnnotationsGohere})} // note the underscore after {@code onConstructor}. */ AnyAnnotation[] onConstructor() default {}; diff --git a/src/core/lombok/EqualsAndHashCode.java b/src/core/lombok/EqualsAndHashCode.java index 605815ed..34f4ffc6 100644 --- a/src/core/lombok/EqualsAndHashCode.java +++ b/src/core/lombok/EqualsAndHashCode.java @@ -63,8 +63,13 @@ public @interface EqualsAndHashCode { boolean doNotUseGetters() default false; /** - * Any annotations listed here are put on the generated parameter of {@code equals} and {@code canEqual}. The syntax for this feature is: {@code @EqualsAndHashCode(onParam=@__({@AnnotationsGoHere}))} - * This is useful to add for example a {@code Nullable} annotation. + * Any annotations listed here are put on the generated parameter of {@code equals} and {@code canEqual}. + * This is useful to add for example a {@code Nullable} annotation.
+ * The syntax for this feature depends on JDK version (nothing we can do about that; it's to work around javac bugs).
+ * up to JDK7:
+ * {@code @EqualsAndHashCode(onParam=@__({@AnnotationsGoHere}))}
+ * from JDK8:
+ * {@code @EqualsAndHashCode(onParam_={@AnnotationsGohere})} // note the underscore after {@code onParam}. */ AnyAnnotation[] onParam() default {}; diff --git a/src/core/lombok/Getter.java b/src/core/lombok/Getter.java index 906ae60f..5a4056fa 100644 --- a/src/core/lombok/Getter.java +++ b/src/core/lombok/Getter.java @@ -58,9 +58,14 @@ public @interface Getter { lombok.AccessLevel value() default lombok.AccessLevel.PUBLIC; /** - * Any annotations listed here are put on the generated method. The syntax for this feature is: {@code @Getter(onMethod=@__({@AnnotationsGoHere}))} + * Any annotations listed here are put on the generated method. + * The syntax for this feature depends on JDK version (nothing we can do about that; it's to work around javac bugs).
+ * up to JDK7:
+ * {@code @Getter(onMethod=@__({@AnnotationsGoHere}))}
+ * from JDK8:
+ * {@code @Getter(onMethod_={@AnnotationsGohere})} // note the underscore after {@code onMethod}. */ - AnyAnnotation[] onMethod() default @AnyAnnotation; + AnyAnnotation[] onMethod() default {}; boolean lazy() default false; diff --git a/src/core/lombok/NoArgsConstructor.java b/src/core/lombok/NoArgsConstructor.java index ff437bba..5f2268a8 100644 --- a/src/core/lombok/NoArgsConstructor.java +++ b/src/core/lombok/NoArgsConstructor.java @@ -51,7 +51,12 @@ public @interface NoArgsConstructor { String staticName() default ""; /** - * Any annotations listed here are put on the generated constructor. The syntax for this feature is: {@code @NoArgsConstructor(onConstructor=@__({@AnnotationsGoHere}))} + * Any annotations listed here are put on the generated constructor. + * The syntax for this feature depends on JDK version (nothing we can do about that; it's to work around javac bugs).
+ * up to JDK7:
+ * {@code @NoArgsConstructor(onConstructor=@__({@AnnotationsGoHere}))}
+ * from JDK8:
+ * {@code @NoArgsConstructor(onConstructor_={@AnnotationsGohere})} // note the underscore after {@code onConstructor}. */ AnyAnnotation[] onConstructor() default {}; diff --git a/src/core/lombok/RequiredArgsConstructor.java b/src/core/lombok/RequiredArgsConstructor.java index 7a9da3f9..abfdd55c 100644 --- a/src/core/lombok/RequiredArgsConstructor.java +++ b/src/core/lombok/RequiredArgsConstructor.java @@ -49,7 +49,12 @@ public @interface RequiredArgsConstructor { String staticName() default ""; /** - * Any annotations listed here are put on the generated constructor. The syntax for this feature is: {@code @RequiredArgsConstructor(onConstructor=@__({@AnnotationsGoHere}))} + * Any annotations listed here are put on the generated constructor. + * The syntax for this feature depends on JDK version (nothing we can do about that; it's to work around javac bugs).
+ * up to JDK7:
+ * {@code @RequiredArgsConstructor(onConstructor=@__({@AnnotationsGoHere}))}
+ * from JDK8:
+ * {@code @RequiredArgsConstructor(onConstructor_={@AnnotationsGohere})} // note the underscore after {@code onConstructor}. */ AnyAnnotation[] onConstructor() default {}; diff --git a/src/core/lombok/Setter.java b/src/core/lombok/Setter.java index ba9e9759..f2ebe5b3 100644 --- a/src/core/lombok/Setter.java +++ b/src/core/lombok/Setter.java @@ -59,12 +59,22 @@ public @interface Setter { lombok.AccessLevel value() default lombok.AccessLevel.PUBLIC; /** - * Any annotations listed here are put on the generated method. The syntax for this feature is: {@code @Setter(onMethod=@__({@AnnotationsGoHere}))} + * Any annotations listed here are put on the generated method. + * The syntax for this feature depends on JDK version (nothing we can do about that; it's to work around javac bugs).
+ * up to JDK7:
+ * {@code @Setter(onMethod=@__({@AnnotationsGoHere}))}
+ * from JDK8:
+ * {@code @Setter(onMethod_={@AnnotationsGohere})} // note the underscore after {@code onMethod}. */ AnyAnnotation[] onMethod() default {}; /** - * Any annotations listed here are put on the generated method's parameter. The syntax for this feature is: {@code @Setter(onParam=@__({@AnnotationsGoHere}))} + * Any annotations listed here are put on the generated method's parameter. + * The syntax for this feature depends on JDK version (nothing we can do about that; it's to work around javac bugs).
+ * up to JDK7:
+ * {@code @Setter(onParam=@__({@AnnotationsGoHere}))}
+ * from JDK8:
+ * {@code @Setter(onParam_={@AnnotationsGohere})} // note the underscore after {@code onParam}. */ AnyAnnotation[] onParam() default {}; diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index ab4ca27b..4726b17e 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -1616,6 +1616,14 @@ public class EclipseHandlerUtil { return true; } + public static void addError(String errorName, EclipseNode node) { + if (node.getLatestJavaSpecSupported() < 8) { + node.addError("The correct format is " + errorName + "_={@SomeAnnotation, @SomeOtherAnnotation})"); + } else { + node.addError("The correct format is " + errorName + "=@__({@SomeAnnotation, @SomeOtherAnnotation}))"); + } + } + public static List unboxAndRemoveAnnotationParameter(Annotation annotation, String annotationName, String errorName, EclipseNode errorNode) { if ("value".equals(annotationName)) { // We can't unbox this, because SingleMemberAnnotation REQUIRES a value, and this method @@ -1638,51 +1646,70 @@ public class EclipseHandlerUtil { char[] nameAsCharArray = annotationName.toCharArray(); + top: for (int i = 0; i < pairs.length; i++) { - if (pairs[i].name == null || !Arrays.equals(nameAsCharArray, pairs[i].name)) continue; + boolean allowRaw; + char[] name = pairs[i].name; + if (name == null) continue; + if (name.length < nameAsCharArray.length) continue; + for (int j = 0; j < nameAsCharArray.length; j++) { + if (name[j] != nameAsCharArray[j]) continue top; + } + allowRaw = name.length > nameAsCharArray.length; + for (int j = nameAsCharArray.length; j < name.length; j++) { + if (name[j] != '_') continue top; + } + // If we're still here it's the targeted annotation param. Expression value = pairs[i].value; MemberValuePair[] newPairs = new MemberValuePair[pairs.length - 1]; if (i > 0) System.arraycopy(pairs, 0, newPairs, 0, i); if (i < pairs.length - 1) System.arraycopy(pairs, i + 1, newPairs, i, pairs.length - i - 1); normalAnnotation.memberValuePairs = newPairs; - // We have now removed the annotation parameter and stored '@__({... annotations ...})', - // which we must now unbox. - if (!(value instanceof Annotation)) { - errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); - return Collections.emptyList(); - } - - Annotation atDummyIdentifier = (Annotation) value; - if (!(atDummyIdentifier.type instanceof SingleTypeReference) || - !isAllValidOnXCharacters(((SingleTypeReference) atDummyIdentifier.type).token)) { - errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); - return Collections.emptyList(); - } - - if (atDummyIdentifier instanceof MarkerAnnotation) { - // It's @Getter(onMethod=@__). This is weird, but fine. - return Collections.emptyList(); - } + // We have now removed the annotation parameter and stored the value, + // which we must now unbox. It's either annotations, or @__(annotations). Expression content = null; - if (atDummyIdentifier instanceof NormalAnnotation) { - MemberValuePair[] mvps = ((NormalAnnotation) atDummyIdentifier).memberValuePairs; - if (mvps == null || mvps.length == 0) { - // It's @Getter(onMethod=@__()). This is weird, but fine. + if (value instanceof ArrayInitializer) { + if (!allowRaw) { + addError(errorName, errorNode); return Collections.emptyList(); } - if (mvps.length == 1 && Arrays.equals("value".toCharArray(), mvps[0].name)) { - content = mvps[0].value; + content = value; + } else if (!(value instanceof Annotation)) { + addError(errorName, errorNode); + return Collections.emptyList(); + } else { + Annotation atDummyIdentifier = (Annotation) value; + if (atDummyIdentifier.type instanceof SingleTypeReference && isAllValidOnXCharacters(((SingleTypeReference) atDummyIdentifier.type).token)) { + if (atDummyIdentifier instanceof MarkerAnnotation) { + return Collections.emptyList(); + } else if (atDummyIdentifier instanceof NormalAnnotation) { + MemberValuePair[] mvps = ((NormalAnnotation) atDummyIdentifier).memberValuePairs; + if (mvps == null || mvps.length == 0) { + return Collections.emptyList(); + } + if (mvps.length == 1 && Arrays.equals("value".toCharArray(), mvps[0].name)) { + content = mvps[0].value; + } + } else if (atDummyIdentifier instanceof SingleMemberAnnotation) { + content = ((SingleMemberAnnotation) atDummyIdentifier).memberValue; + } else { + addError(errorName, errorNode); + return Collections.emptyList(); + } + } else { + if (allowRaw) { + content = atDummyIdentifier; + } else { + addError(errorName, errorNode); + return Collections.emptyList(); + } } } - if (atDummyIdentifier instanceof SingleMemberAnnotation) { - content = ((SingleMemberAnnotation) atDummyIdentifier).memberValue; - } - if (content == null) { - errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); + addError(errorName, errorNode); return Collections.emptyList(); } @@ -1694,13 +1721,13 @@ public class EclipseHandlerUtil { if (expressions != null) for (Expression ex : expressions) { if (ex instanceof Annotation) result.add((Annotation) ex); else { - errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); + addError(errorName, errorNode); return Collections.emptyList(); } } return result; } else { - errorNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); + addError(errorName, errorNode); return Collections.emptyList(); } } diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java index a3b0585d..2aed4a4e 100644 --- a/src/core/lombok/eclipse/handlers/HandleConstructor.java +++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java @@ -93,7 +93,7 @@ public class HandleConstructor { boolean force = ann.force(); List fields = force ? findFinalFields(typeNode) : Collections.emptyList(); - List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@NoArgsConstructor(onConstructor=", annotationNode); + List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@NoArgsConstructor(onConstructor", annotationNode); new HandleConstructor().generateConstructor(typeNode, level, fields, force, staticName, SkipIfConstructorExists.NO, null, onConstructor, annotationNode); } @@ -117,7 +117,7 @@ public class HandleConstructor { suppressConstructorProperties = suppress; } - List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@RequiredArgsConstructor(onConstructor=", annotationNode); + List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@RequiredArgsConstructor(onConstructor", annotationNode); new HandleConstructor().generateConstructor( typeNode, level, findRequiredFields(typeNode), false, staticName, SkipIfConstructorExists.NO, @@ -179,7 +179,7 @@ public class HandleConstructor { suppressConstructorProperties = suppress; } - List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@AllArgsConstructor(onConstructor=", annotationNode); + List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@AllArgsConstructor(onConstructor", annotationNode); new HandleConstructor().generateConstructor( typeNode, level, findAllFields(typeNode), false, staticName, SkipIfConstructorExists.NO, diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java index bc25ae2a..ceef3d3c 100644 --- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java @@ -129,7 +129,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler includes = Arrays.asList(ann.of()); EclipseNode typeNode = annotationNode.up(); - List onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@EqualsAndHashCode(onParam=", annotationNode); + List onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@EqualsAndHashCode(onParam", annotationNode); checkForBogusFieldNames(typeNode, annotation); Boolean callSuper = ann.callSuper(); diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java index 77d678f2..c11303f3 100644 --- a/src/core/lombok/eclipse/handlers/HandleGetter.java +++ b/src/core/lombok/eclipse/handlers/HandleGetter.java @@ -148,7 +148,7 @@ public class HandleGetter extends EclipseAnnotationHandler { if (node == null) return; - List onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Getter(onMethod=", annotationNode); + List onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Getter(onMethod", annotationNode); switch (node.getKind()) { case FIELD: diff --git a/src/core/lombok/eclipse/handlers/HandleSetter.java b/src/core/lombok/eclipse/handlers/HandleSetter.java index 1fcf751d..7e7ea121 100644 --- a/src/core/lombok/eclipse/handlers/HandleSetter.java +++ b/src/core/lombok/eclipse/handlers/HandleSetter.java @@ -125,8 +125,8 @@ public class HandleSetter extends EclipseAnnotationHandler { AccessLevel level = annotation.getInstance().value(); if (level == AccessLevel.NONE || node == null) return; - List onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Setter(onMethod=", annotationNode); - List onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Setter(onParam=", annotationNode); + List onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Setter(onMethod", annotationNode); + List onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Setter(onParam", annotationNode); switch (node.getKind()) { case FIELD: diff --git a/src/core/lombok/eclipse/handlers/HandleWither.java b/src/core/lombok/eclipse/handlers/HandleWither.java index d8ac8df6..200ebde7 100644 --- a/src/core/lombok/eclipse/handlers/HandleWither.java +++ b/src/core/lombok/eclipse/handlers/HandleWither.java @@ -127,8 +127,8 @@ public class HandleWither extends EclipseAnnotationHandler { AccessLevel level = annotation.getInstance().value(); if (level == AccessLevel.NONE || node == null) return; - List onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Wither(onMethod=", annotationNode); - List onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Wither(onParam=", annotationNode); + List onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Wither(onMethod", annotationNode); + List onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Wither(onParam", annotationNode); switch (node.getKind()) { case FIELD: diff --git a/src/core/lombok/experimental/Wither.java b/src/core/lombok/experimental/Wither.java index b4131187..3fb767d1 100644 --- a/src/core/lombok/experimental/Wither.java +++ b/src/core/lombok/experimental/Wither.java @@ -60,12 +60,22 @@ public @interface Wither { AccessLevel value() default AccessLevel.PUBLIC; /** - * Any annotations listed here are put on the generated method. The syntax for this feature is: {@code @Setter(onMethod=@__({@AnnotationsGoHere}))} + * Any annotations listed here are put on the generated method. + * The syntax for this feature depends on JDK version (nothing we can do about that; it's to work around javac bugs).
+ * up to JDK7:
+ * {@code @Wither(onMethod=@__({@AnnotationsGoHere}))}
+ * from JDK8:
+ * {@code @Wither(onMethod_={@AnnotationsGohere})} // note the underscore after {@code onMethod}. */ AnyAnnotation[] onMethod() default {}; /** - * Any annotations listed here are put on the generated method's parameter. The syntax for this feature is: {@code @Setter(onParam=@__({@AnnotationsGoHere}))} + * Any annotations listed here are put on the generated method's parameter. + * The syntax for this feature depends on JDK version (nothing we can do about that; it's to work around javac bugs).
+ * up to JDK7:
+ * {@code @Wither(onParam=@__({@AnnotationsGoHere}))}
+ * from JDK8:
+ * {@code @Wither(onParam_={@AnnotationsGohere})} // note the underscore after {@code onParam}. */ AnyAnnotation[] onParam() default {}; diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index ef4ba088..617ec0d1 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -71,7 +71,7 @@ public class HandleConstructor { deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); JavacNode typeNode = annotationNode.up(); if (!checkLegality(typeNode, annotationNode, NoArgsConstructor.class.getSimpleName())) return; - List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@NoArgsConstructor(onConstructor=", annotationNode); + List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@NoArgsConstructor(onConstructor", annotationNode); NoArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); if (level == AccessLevel.NONE) return; @@ -91,7 +91,7 @@ public class HandleConstructor { deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); JavacNode typeNode = annotationNode.up(); if (!checkLegality(typeNode, annotationNode, RequiredArgsConstructor.class.getSimpleName())) return; - List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@RequiredArgsConstructor(onConstructor=", annotationNode); + List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@RequiredArgsConstructor(onConstructor", annotationNode); RequiredArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); if (level == AccessLevel.NONE) return; @@ -141,7 +141,7 @@ public class HandleConstructor { deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); JavacNode typeNode = annotationNode.up(); if (!checkLegality(typeNode, annotationNode, AllArgsConstructor.class.getSimpleName())) return; - List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@AllArgsConstructor(onConstructor=", annotationNode); + List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@AllArgsConstructor(onConstructor", annotationNode); AllArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); if (level == AccessLevel.NONE) return; diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index 8e868bca..6df56ed6 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -95,7 +95,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler excludes = List.from(ann.exclude()); List includes = List.from(ann.of()); JavacNode typeNode = annotationNode.up(); - List onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@EqualsAndHashCode(onParam=", annotationNode); + List onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@EqualsAndHashCode(onParam", annotationNode); checkForBogusFieldNames(typeNode, annotation); Boolean callSuper = ann.callSuper(); diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index 60dbe8ee..5a2e1993 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -147,7 +147,7 @@ public class HandleGetter extends JavacAnnotationHandler { if (node == null) return; - List onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Getter(onMethod=", annotationNode); + List onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Getter(onMethod", annotationNode); switch (node.getKind()) { case FIELD: diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index 02cc3775..e766127a 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -129,8 +129,8 @@ public class HandleSetter extends JavacAnnotationHandler { if (level == AccessLevel.NONE || node == null) return; - List onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Setter(onMethod=", annotationNode); - List onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Setter(onParam=", annotationNode); + List onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Setter(onMethod", annotationNode); + List onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Setter(onParam", annotationNode); switch (node.getKind()) { case FIELD: diff --git a/src/core/lombok/javac/handlers/HandleWither.java b/src/core/lombok/javac/handlers/HandleWither.java index 8aec0240..987a3d34 100644 --- a/src/core/lombok/javac/handlers/HandleWither.java +++ b/src/core/lombok/javac/handlers/HandleWither.java @@ -131,8 +131,8 @@ public class HandleWither extends JavacAnnotationHandler { if (level == AccessLevel.NONE || node == null) return; - List onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Wither(onMethod=", annotationNode); - List onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Wither(onParam=", annotationNode); + List onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Wither(onMethod", annotationNode); + List onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Wither(onParam", annotationNode); switch (node.getKind()) { case FIELD: diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 27289108..56e666f7 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1240,19 +1240,9 @@ public class JavacHandlerUtil { ListBuffer params = new ListBuffer(); ListBuffer result = new ListBuffer(); - try { - for (JCExpression arg : ast.args) { - String argName = "value"; - if (arg instanceof JCAssign) { - JCAssign as = (JCAssign) arg; - argName = as.lhs.toString(); - } - if (!argName.equals(parameterName)) continue; - } - } catch (Exception ignore) {} - outer: for (JCExpression param : ast.args) { + boolean allowRaw; String nameOfParam = "value"; JCExpression valueOfParam = null; if (param instanceof JCAssign) { @@ -1264,6 +1254,15 @@ public class JavacHandlerUtil { valueOfParam = assign.rhs; } + /* strip trailing underscores */ { + int lastIdx; + for (lastIdx = nameOfParam.length() ; lastIdx > 0; lastIdx--) { + if (nameOfParam.charAt(lastIdx - 1) != '_') break; + } + allowRaw = lastIdx < nameOfParam.length(); + nameOfParam = nameOfParam.substring(0, lastIdx); + } + if (!parameterName.equals(nameOfParam)) { params.append(param); continue outer; @@ -1276,48 +1275,68 @@ public class JavacHandlerUtil { String dummyAnnotationName = ((JCAnnotation) valueOfParam).annotationType.toString(); dummyAnnotationName = dummyAnnotationName.replace("_", "").replace("$", "").replace("x", "").replace("X", ""); if (dummyAnnotationName.length() > 0) { - annotationNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); - continue outer; - } - for (JCExpression expr : ((JCAnnotation) valueOfParam).args) { - if (expr instanceof JCAssign && ((JCAssign) expr).lhs instanceof JCIdent) { - JCIdent id = (JCIdent) ((JCAssign) expr).lhs; - if ("value".equals(id.name.toString())) { - expr = ((JCAssign) expr).rhs; - } else { - annotationNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); - continue outer; - } + if (allowRaw) { + result.append((JCAnnotation) valueOfParam); + } else { + addError(errorName, annotationNode); + continue outer; } - - if (expr instanceof JCAnnotation) { - result.append((JCAnnotation) expr); - } else if (expr instanceof JCNewArray) { - for (JCExpression expr2 : ((JCNewArray) expr).elems) { - if (expr2 instanceof JCAnnotation) { - result.append((JCAnnotation) expr2); + } else { + for (JCExpression expr : ((JCAnnotation) valueOfParam).args) { + if (expr instanceof JCAssign && ((JCAssign) expr).lhs instanceof JCIdent) { + JCIdent id = (JCIdent) ((JCAssign) expr).lhs; + if ("value".equals(id.name.toString())) { + expr = ((JCAssign) expr).rhs; } else { - annotationNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); - continue outer; + addError(errorName, annotationNode); } } - } else { - annotationNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); - continue outer; + + if (expr instanceof JCAnnotation) { + result.append((JCAnnotation) expr); + } else if (expr instanceof JCNewArray) { + for (JCExpression expr2 : ((JCNewArray) expr).elems) { + if (expr2 instanceof JCAnnotation) { + result.append((JCAnnotation) expr2); + } else { + addError(errorName, annotationNode); + continue outer; + } + } + } else { + addError(errorName, annotationNode); + continue outer; + } } } - } else { - if (valueOfParam instanceof JCNewArray && ((JCNewArray) valueOfParam).elems.isEmpty()) { - // Then we just remove it and move on (it's onMethod={} for example). + } else if (valueOfParam instanceof JCNewArray) { + JCNewArray arr = (JCNewArray) valueOfParam; + if (arr.elems.isEmpty()) { + // Just remove it, this is always fine. + } else if (allowRaw) { + for (JCExpression jce : arr.elems) { + if (jce instanceof JCAnnotation) result.append((JCAnnotation) jce); + else addError(errorName, annotationNode); + } } else { - annotationNode.addError("The correct format is " + errorName + "@__({@SomeAnnotation, @SomeOtherAnnotation}))"); + addError(errorName, annotationNode); } + } else { + addError(errorName, annotationNode); } } ast.args = params.toList(); return result.toList(); } + private static void addError(String errorName, JavacNode node) { + if (node.getLatestJavaSpecSupported() < 8) { + node.addError("The correct format up to JDK7 is " + errorName + "=@__({@SomeAnnotation, @SomeOtherAnnotation}))"); + } else { + node.addError("The correct format for JDK8+ is " + errorName + "_={@SomeAnnotation, @SomeOtherAnnotation})"); + } + } + public static List copyTypeParams(JavacNode source, List params) { if (params == null || params.isEmpty()) return params; ListBuffer out = new ListBuffer(); diff --git a/test/transform/resource/after-delombok/OnXJava7Style.java b/test/transform/resource/after-delombok/OnXJava7Style.java new file mode 100644 index 00000000..f3a58d79 --- /dev/null +++ b/test/transform/resource/after-delombok/OnXJava7Style.java @@ -0,0 +1,43 @@ +//version :7 +public class OnXJava7Style { + @interface Foo { + String value() default ""; + } + @interface Bar { + String stuff() default ""; + } + String a; + String b; + String c; + String d; + String e; + @Foo + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public String getA() { + return this.a; + } + @Foo + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public void setB(final String b) { + this.b = b; + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public void setC(@Foo("a") final String c) { + this.c = c; + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public void setD(@Bar(stuff = "b") final String d) { + this.d = d; + } + @Foo("c") + @Bar(stuff = "d") + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public String getE() { + return this.e; + } +} diff --git a/test/transform/resource/after-delombok/OnXJava8Style.java b/test/transform/resource/after-delombok/OnXJava8Style.java new file mode 100644 index 00000000..b0ea96d6 --- /dev/null +++ b/test/transform/resource/after-delombok/OnXJava8Style.java @@ -0,0 +1,43 @@ +//version 8: +public class OnXJava8Style { + @interface Foo { + String value() default ""; + } + @interface Bar { + String stuff() default ""; + } + String a; + String b; + String c; + String d; + String e; + @Foo + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public String getA() { + return this.a; + } + @Foo + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public void setB(final String b) { + this.b = b; + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public void setC(@Foo("a") final String c) { + this.c = c; + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public void setD(@Bar(stuff = "b") final String d) { + this.d = d; + } + @Foo("c") + @Bar(stuff = "d") + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public String getE() { + return this.e; + } +} diff --git a/test/transform/resource/after-ecj/OnXJava7Style.java b/test/transform/resource/after-ecj/OnXJava7Style.java new file mode 100644 index 00000000..415234d8 --- /dev/null +++ b/test/transform/resource/after-ecj/OnXJava7Style.java @@ -0,0 +1,31 @@ +public class OnXJava7Style { + @interface Foo { + String value() default ""; + } + @interface Bar { + String stuff() default ""; + } + @lombok.Getter() String a; + @lombok.Setter() String b; + @lombok.Setter() String c; + @lombok.Setter() String d; + @lombok.Getter() String e; + public OnXJava7Style() { + super(); + } + public @Foo @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") String getA() { + return this.a; + } + public @Foo() @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") void setB(final String b) { + this.b = b; + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") void setC(final @Foo("a") String c) { + this.c = c; + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") void setD(final @Bar(stuff = "b") String d) { + this.d = d; + } + public @Foo(value = "c") @Bar(stuff = "d") @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") String getE() { + return this.e; + } +} diff --git a/test/transform/resource/after-ecj/OnXJava7StyleOn8.java b/test/transform/resource/after-ecj/OnXJava7StyleOn8.java new file mode 100644 index 00000000..da51a5f0 --- /dev/null +++ b/test/transform/resource/after-ecj/OnXJava7StyleOn8.java @@ -0,0 +1,31 @@ +public class OnXJava7StyleOn8 { + @interface Foo { + String value() default ""; + } + @interface Bar { + String stuff() default ""; + } + @lombok.Getter() String a; + @lombok.Setter() String b; + @lombok.Setter() String c; + @lombok.Setter() String d; + @lombok.Getter() String e; + public OnXJava7StyleOn8() { + super(); + } + public @Foo @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") String getA() { + return this.a; + } + public @Foo() @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") void setB(final String b) { + this.b = b; + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") void setC(final @Foo("a") String c) { + this.c = c; + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") void setD(final @Bar(stuff = "b") String d) { + this.d = d; + } + public @Foo(value = "c") @Bar(stuff = "d") @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") String getE() { + return this.e; + } +} diff --git a/test/transform/resource/after-ecj/OnXJava8Style.java b/test/transform/resource/after-ecj/OnXJava8Style.java new file mode 100644 index 00000000..0e95a20b --- /dev/null +++ b/test/transform/resource/after-ecj/OnXJava8Style.java @@ -0,0 +1,31 @@ +public class OnXJava8Style { + @interface Foo { + String value() default ""; + } + @interface Bar { + String stuff() default ""; + } + @lombok.Getter() String a; + @lombok.Setter() String b; + @lombok.Setter() String c; + @lombok.Setter() String d; + @lombok.Getter() String e; + public OnXJava8Style() { + super(); + } + public @Foo @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") String getA() { + return this.a; + } + public @Foo() @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") void setB(final String b) { + this.b = b; + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") void setC(final @Foo("a") String c) { + this.c = c; + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") void setD(final @Bar(stuff = "b") String d) { + this.d = d; + } + public @Foo(value = "c") @Bar(stuff = "d") @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") String getE() { + return this.e; + } +} diff --git a/test/transform/resource/after-ecj/OnXJava8StyleOn7.java b/test/transform/resource/after-ecj/OnXJava8StyleOn7.java new file mode 100644 index 00000000..28afb5a7 --- /dev/null +++ b/test/transform/resource/after-ecj/OnXJava8StyleOn7.java @@ -0,0 +1,31 @@ +public class OnXJava8StyleOn7 { + @interface Foo { + String value() default ""; + } + @interface Bar { + String stuff() default ""; + } + @lombok.Getter() String a; + @lombok.Setter() String b; + @lombok.Setter() String c; + @lombok.Setter() String d; + @lombok.Getter() String e; + public OnXJava8StyleOn7() { + super(); + } + public @Foo @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") String getA() { + return this.a; + } + public @Foo() @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") void setB(final String b) { + this.b = b; + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") void setC(final @Foo("a") String c) { + this.c = c; + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") void setD(final @Bar(stuff = "b") String d) { + this.d = d; + } + public @Foo(value = "c") @Bar(stuff = "d") @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") String getE() { + return this.e; + } +} diff --git a/test/transform/resource/before/GetterOnMethodErrors2.java b/test/transform/resource/before/GetterOnMethodErrors2.java index 2fd98c83..08ef13c6 100644 --- a/test/transform/resource/before/GetterOnMethodErrors2.java +++ b/test/transform/resource/before/GetterOnMethodErrors2.java @@ -1,3 +1,4 @@ +//version 8: class GetterOnMethodErrors2 { @lombok.Getter(onMethod=@_A_(@Deprecated)) private int bad1; @lombok.Getter(onMethod=@__(5)) private int bad2; diff --git a/test/transform/resource/before/OnXJava7Style.java b/test/transform/resource/before/OnXJava7Style.java new file mode 100644 index 00000000..6a3c35ff --- /dev/null +++ b/test/transform/resource/before/OnXJava7Style.java @@ -0,0 +1,16 @@ +//version :7 +public class OnXJava7Style { + @interface Foo { + String value() default ""; + } + + @interface Bar { + String stuff() default ""; + } + + @lombok.Getter(onMethod=@__(@Foo)) String a; + @lombok.Setter(onMethod=@__(@Foo())) String b; + @lombok.Setter(onParam=@__(@Foo("a"))) String c; + @lombok.Setter(onParam=@__(@Bar(stuff="b"))) String d; + @lombok.Getter(onMethod=@__({@Foo(value="c"), @Bar(stuff="d")})) String e; +} diff --git a/test/transform/resource/before/OnXJava7StyleOn8.java b/test/transform/resource/before/OnXJava7StyleOn8.java new file mode 100644 index 00000000..582fe6ce --- /dev/null +++ b/test/transform/resource/before/OnXJava7StyleOn8.java @@ -0,0 +1,18 @@ +//platform ecj +//version 8: + +public class OnXJava7StyleOn8 { + @interface Foo { + String value() default ""; + } + + @interface Bar { + String stuff() default ""; + } + + @lombok.Getter(onMethod=@__(@Foo)) String a; + @lombok.Setter(onMethod=@__(@Foo())) String b; + @lombok.Setter(onParam=@__(@Foo("a"))) String c; + @lombok.Setter(onParam=@__(@Bar(stuff="b"))) String d; + @lombok.Getter(onMethod=@__({@Foo(value="c"), @Bar(stuff="d")})) String e; +} diff --git a/test/transform/resource/before/OnXJava8Style.java b/test/transform/resource/before/OnXJava8Style.java new file mode 100644 index 00000000..ffb91727 --- /dev/null +++ b/test/transform/resource/before/OnXJava8Style.java @@ -0,0 +1,16 @@ +//version 8: +public class OnXJava8Style { + @interface Foo { + String value() default ""; + } + + @interface Bar { + String stuff() default ""; + } + + @lombok.Getter(onMethod_=@Foo) String a; + @lombok.Setter(onMethod_=@Foo()) String b; + @lombok.Setter(onParam_=@Foo("a")) String c; + @lombok.Setter(onParam_=@Bar(stuff="b")) String d; + @lombok.Getter(onMethod_={@Foo(value="c"), @Bar(stuff="d")}) String e; +} diff --git a/test/transform/resource/before/OnXJava8StyleOn7.java b/test/transform/resource/before/OnXJava8StyleOn7.java new file mode 100644 index 00000000..c006e468 --- /dev/null +++ b/test/transform/resource/before/OnXJava8StyleOn7.java @@ -0,0 +1,18 @@ +//platform ecj +//version :7 + +public class OnXJava8StyleOn7 { + @interface Foo { + String value() default ""; + } + + @interface Bar { + String stuff() default ""; + } + + @lombok.Getter(onMethod_=@Foo) String a; + @lombok.Setter(onMethod_=@Foo()) String b; + @lombok.Setter(onParam_=@Foo("a")) String c; + @lombok.Setter(onParam_=@Bar(stuff="b")) String d; + @lombok.Getter(onMethod_={@Foo(value="c"), @Bar(stuff="d")}) String e; +} diff --git a/test/transform/resource/messages-delombok/GetterOnMethodErrors2.java.messages b/test/transform/resource/messages-delombok/GetterOnMethodErrors2.java.messages index 53a9b9ad..6a181265 100644 --- a/test/transform/resource/messages-delombok/GetterOnMethodErrors2.java.messages +++ b/test/transform/resource/messages-delombok/GetterOnMethodErrors2.java.messages @@ -1,4 +1,4 @@ -2 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) -3 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) -4 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) -5 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) +2 The correct format is @Getter(onMethod_={@SomeAnnotation, @SomeOtherAnnotation}) +3 The correct format is @Getter(onMethod_={@SomeAnnotation, @SomeOtherAnnotation}) +4 The correct format is @Getter(onMethod_={@SomeAnnotation, @SomeOtherAnnotation}) +5 The correct format is @Getter(onMethod_={@SomeAnnotation, @SomeOtherAnnotation}) diff --git a/test/transform/resource/messages-ecj/GetterOnMethodErrors2.java.messages b/test/transform/resource/messages-ecj/GetterOnMethodErrors2.java.messages index 53a9b9ad..6a181265 100644 --- a/test/transform/resource/messages-ecj/GetterOnMethodErrors2.java.messages +++ b/test/transform/resource/messages-ecj/GetterOnMethodErrors2.java.messages @@ -1,4 +1,4 @@ -2 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) -3 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) -4 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) -5 The correct format is @Getter(onMethod=@__({@SomeAnnotation, @SomeOtherAnnotation})) +2 The correct format is @Getter(onMethod_={@SomeAnnotation, @SomeOtherAnnotation}) +3 The correct format is @Getter(onMethod_={@SomeAnnotation, @SomeOtherAnnotation}) +4 The correct format is @Getter(onMethod_={@SomeAnnotation, @SomeOtherAnnotation}) +5 The correct format is @Getter(onMethod_={@SomeAnnotation, @SomeOtherAnnotation}) diff --git a/usage_examples/experimental/onXExample_pre.jpage b/usage_examples/experimental/onXExample_pre.jpage index f8fcb435..e54371ae 100644 --- a/usage_examples/experimental/onXExample_pre.jpage +++ b/usage_examples/experimental/onXExample_pre.jpage @@ -9,7 +9,9 @@ import javax.validation.constraints.Max; @AllArgsConstructor(onConstructor=@__(@Inject)) public class OnXExample { - @Getter(onMethod=@__({@Id, @Column(name="unique-id")})) - @Setter(onParam=@__(@Max(10000))) +// @Getter(onMethod=@__({@Id, @Column(name="unique-id")})) //JDK7 +// @Setter(onParam=@__(@Max(10000))) //JDK7 + @Getter(onMethod_={@Id, @Column(name="unique-id")}) //JDK8 + @Setter(onParam_=@Max(10000)) //JDK8 private long unid; } diff --git a/website/features/experimental/onX.html b/website/features/experimental/onX.html index d4260dd5..39faa1bf 100644 --- a/website/features/experimental/onX.html +++ b/website/features/experimental/onX.html @@ -42,7 +42,9 @@

@Setter and @Wither support onParam in addition to onMethod; annotations listed will be put on the only parameter that the generated method has. @EqualsAndHashCode also supports onParam; the listed annotation(s) will be placed on the single parameter of the generated equals method, as well as any generated canEqual method.

- The syntax is a little strange; to use any of the 3 onX features, you must wrap the annotations to be applied to the constructor / method / parameter in @__(@AnnotationGoesHere). To apply multiple annotations, use @__({@Annotation1, @Annotation2}). The annotations can themselves obviously have parameters as well. + The syntax is a little strange and depends on the javac you are using.
+ On javac7, to use any of the 3 onX features, you must wrap the annotations to be applied to the constructor / method / parameter in @__(@AnnotationGoesHere). To apply multiple annotations, use @__({@Annotation1, @Annotation2}). The annotations can themselves obviously have parameters as well.
+ On javac8 and up, you add an underscore after onMethod, onParam, or onConstructor.

@@ -62,6 +64,8 @@

The reason of the weird syntax is to make this feature work in javac 7 compilers; the @__ type is an annotation reference to the annotation type __ (double underscore) which doesn't actually exist; this makes javac 7 delay aborting the compilation process due to an error because it is possible an annotation processor will later create the __ type. Instead, lombok applies the annotations and removes the references so that the error will never actually occur. The point is: The __ type must not exist, otherwise the feature does not work. In the rare case that the __ type does exist (and is imported or in the package), you can simply add more underscores. Technically any non-existent type would work, but to maintain consistency and readability and catch erroneous use, lombok considers it an error if the 'wrapper' annotation is anything but a series of underscores.

+ In javac8, the above feature should work but due to a bug in javac8 it does not. However, starting in javac8, if the parameter name does not exist in the annotation type, compilation proceeds to a phase where lombok can fix it. +

To reiterate: This feature can disappear at any time; if you use this feature, be prepared to adjust your code when we find a nicer way of implementing this feature, or, if a future version of javac forces us to remove this feature entirely with no alternative.

The onX parameter is not legal on any type-wide variant. For example, a @Getter annotation on a class does not support onMethod. -- cgit From a2c10c70fa8e2c8736464a5c3d445e2ca6e8a296 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Tue, 7 Mar 2017 01:10:18 +0100 Subject: removed the suppressConstructorProperties param. --- src/core/lombok/AllArgsConstructor.java | 10 ------ src/core/lombok/RequiredArgsConstructor.java | 10 ------ .../lombok/eclipse/handlers/HandleBuilder.java | 4 +-- .../lombok/eclipse/handlers/HandleConstructor.java | 37 +++++++++------------ src/core/lombok/javac/handlers/HandleBuilder.java | 4 +-- .../lombok/javac/handlers/HandleConstructor.java | 38 +++++++++------------- .../after-delombok/ConstructorsConfiguration.java | 9 ----- .../after-ecj/ConstructorsConfiguration.java | 7 ---- .../resource/before/ConstructorsConfiguration.java | 4 --- 9 files changed, 35 insertions(+), 88 deletions(-) (limited to 'src/core/lombok/eclipse') diff --git a/src/core/lombok/AllArgsConstructor.java b/src/core/lombok/AllArgsConstructor.java index 45ae897c..75f87211 100644 --- a/src/core/lombok/AllArgsConstructor.java +++ b/src/core/lombok/AllArgsConstructor.java @@ -63,16 +63,6 @@ public @interface AllArgsConstructor { */ AccessLevel access() default lombok.AccessLevel.PUBLIC; - /** - * Constructors are generated with the {@link java.beans.ConstructorProperties} annotation. - * However, this annotation is new in 1.6 which means those compiling for 1.5 will need - * to set this value to true. - * - * @deprecated THIS FEATURE WILL BE REMOVED after March 31st 2015. Use configuration key {@link ConfigurationKeys#ANY_CONSTRUCTOR_SUPPRESS_CONSTRUCTOR_PROPERTIES} instead. - */ - @Deprecated - boolean suppressConstructorProperties() default false; - /** * Placeholder annotation to enable the placement of annotations on the generated code. * @deprecated Don't use this annotation, ever - Read the documentation. diff --git a/src/core/lombok/RequiredArgsConstructor.java b/src/core/lombok/RequiredArgsConstructor.java index abfdd55c..2f4d0aaf 100644 --- a/src/core/lombok/RequiredArgsConstructor.java +++ b/src/core/lombok/RequiredArgsConstructor.java @@ -63,16 +63,6 @@ public @interface RequiredArgsConstructor { */ AccessLevel access() default lombok.AccessLevel.PUBLIC; - /** - * Constructors are generated with the {@link java.beans.ConstructorProperties} annotation. - * However, this annotation is new in 1.6 which means those compiling for 1.5 will need - * to set this value to true. - * - * @deprecated THIS FEATURE WILL BE REMOVED after March 31st 2015. Use configuration key {@link ConfigurationKeys#ANY_CONSTRUCTOR_SUPPRESS_CONSTRUCTOR_PROPERTIES} instead. - */ - @Deprecated - boolean suppressConstructorProperties() default false; - /** * Placeholder annotation to enable the placement of annotations on the generated code. * @deprecated Don't use this annotation, ever - Read the documentation. diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java index afa03538..8c200a94 100644 --- a/src/core/lombok/eclipse/handlers/HandleBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java @@ -189,7 +189,7 @@ public class HandleBuilder extends EclipseAnnotationHandler { allFields.add(fieldNode); } - new HandleConstructor().generateConstructor(tdParent, AccessLevel.PACKAGE, allFields, false, null, SkipIfConstructorExists.I_AM_BUILDER, null, + new HandleConstructor().generateConstructor(tdParent, AccessLevel.PACKAGE, allFields, false, null, SkipIfConstructorExists.I_AM_BUILDER, Collections.emptyList(), annotationNode); returnType = namePlusTypeParamsToTypeReference(td.name, td.typeParameters, p); @@ -395,7 +395,7 @@ public class HandleBuilder extends EclipseAnnotationHandler { if (constructorExists(builderType) == MemberExistsResult.NOT_EXISTS) { ConstructorDeclaration cd = HandleConstructor.createConstructor( - AccessLevel.PACKAGE, builderType, Collections.emptyList(), false, null, + AccessLevel.PACKAGE, builderType, Collections.emptyList(), false, annotationNode, Collections.emptyList()); if (cd != null) injectMethod(builderType, cd); } diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java index 2aed4a4e..49b09231 100644 --- a/src/core/lombok/eclipse/handlers/HandleConstructor.java +++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java @@ -95,7 +95,7 @@ public class HandleConstructor { List fields = force ? findFinalFields(typeNode) : Collections.emptyList(); List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@NoArgsConstructor(onConstructor", annotationNode); - new HandleConstructor().generateConstructor(typeNode, level, fields, force, staticName, SkipIfConstructorExists.NO, null, onConstructor, annotationNode); + new HandleConstructor().generateConstructor(typeNode, level, fields, force, staticName, SkipIfConstructorExists.NO, onConstructor, annotationNode); } } @@ -110,18 +110,15 @@ public class HandleConstructor { AccessLevel level = ann.access(); if (level == AccessLevel.NONE) return; String staticName = ann.staticName(); - Boolean suppressConstructorProperties = null; if (annotation.isExplicit("suppressConstructorProperties")) { - @SuppressWarnings("deprecation") - boolean suppress = ann.suppressConstructorProperties(); - suppressConstructorProperties = suppress; + annotationNode.addError("This deprecated feature is no longer supported. Remove it; you can create a lombok.config file with 'lombok.anyConstructor.suppressConstructorProperties = true'."); } List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@RequiredArgsConstructor(onConstructor", annotationNode); new HandleConstructor().generateConstructor( typeNode, level, findRequiredFields(typeNode), false, staticName, SkipIfConstructorExists.NO, - suppressConstructorProperties, onConstructor, annotationNode); + onConstructor, annotationNode); } } @@ -172,18 +169,15 @@ public class HandleConstructor { AccessLevel level = ann.access(); if (level == AccessLevel.NONE) return; String staticName = ann.staticName(); - Boolean suppressConstructorProperties = null; if (annotation.isExplicit("suppressConstructorProperties")) { - @SuppressWarnings("deprecation") - boolean suppress = ann.suppressConstructorProperties(); - suppressConstructorProperties = suppress; + annotationNode.addError("This deprecated feature is no longer supported. Remove it; you can create a lombok.config file with 'lombok.anyConstructor.suppressConstructorProperties = true'."); } List onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@AllArgsConstructor(onConstructor", annotationNode); new HandleConstructor().generateConstructor( typeNode, level, findAllFields(typeNode), false, staticName, SkipIfConstructorExists.NO, - suppressConstructorProperties, onConstructor, annotationNode); + onConstructor, annotationNode); } } @@ -205,14 +199,14 @@ public class HandleConstructor { EclipseNode typeNode, AccessLevel level, String staticName, SkipIfConstructorExists skipIfConstructorExists, List onConstructor, EclipseNode sourceNode) { - generateConstructor(typeNode, level, findRequiredFields(typeNode), false, staticName, skipIfConstructorExists, null, onConstructor, sourceNode); + generateConstructor(typeNode, level, findRequiredFields(typeNode), false, staticName, skipIfConstructorExists, onConstructor, sourceNode); } public void generateAllArgsConstructor( EclipseNode typeNode, AccessLevel level, String staticName, SkipIfConstructorExists skipIfConstructorExists, List onConstructor, EclipseNode sourceNode) { - generateConstructor(typeNode, level, findAllFields(typeNode), false, staticName, skipIfConstructorExists, null, onConstructor, sourceNode); + generateConstructor(typeNode, level, findAllFields(typeNode), false, staticName, skipIfConstructorExists, onConstructor, sourceNode); } public enum SkipIfConstructorExists { @@ -221,7 +215,7 @@ public class HandleConstructor { public void generateConstructor( EclipseNode typeNode, AccessLevel level, List fields, boolean allToDefault, String staticName, SkipIfConstructorExists skipIfConstructorExists, - Boolean suppressConstructorProperties, List onConstructor, EclipseNode sourceNode) { + List onConstructor, EclipseNode sourceNode) { ASTNode source = sourceNode.get(); boolean staticConstrRequired = staticName != null && !staticName.equals(""); @@ -256,7 +250,7 @@ public class HandleConstructor { ConstructorDeclaration constr = createConstructor( staticConstrRequired ? AccessLevel.PRIVATE : level, typeNode, fields, allToDefault, - suppressConstructorProperties, sourceNode, onConstructor); + sourceNode, onConstructor); injectMethod(typeNode, constr); if (staticConstrRequired) { MethodDeclaration staticConstr = createStaticConstructor(level, staticName, typeNode, allToDefault ? Collections.emptyList() : fields, source); @@ -298,7 +292,7 @@ public class HandleConstructor { public static ConstructorDeclaration createConstructor( AccessLevel level, EclipseNode type, Collection fields, boolean allToDefault, - Boolean suppressConstructorProperties, EclipseNode sourceNode, List onConstructor) { + EclipseNode sourceNode, List onConstructor) { ASTNode source = sourceNode.get(); TypeDeclaration typeDeclaration = ((TypeDeclaration) type.get()); @@ -308,12 +302,11 @@ public class HandleConstructor { if (isEnum) level = AccessLevel.PRIVATE; - if (suppressConstructorProperties == null) { - if (fields.isEmpty()) { - suppressConstructorProperties = false; - } else { - suppressConstructorProperties = Boolean.TRUE.equals(type.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_SUPPRESS_CONSTRUCTOR_PROPERTIES)); - } + boolean suppressConstructorProperties; + if (fields.isEmpty()) { + suppressConstructorProperties = false; + } else { + suppressConstructorProperties = Boolean.TRUE.equals(type.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_SUPPRESS_CONSTRUCTOR_PROPERTIES)); } ConstructorDeclaration constructor = new ConstructorDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult); diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index 2704981b..4c670433 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -155,7 +155,7 @@ public class HandleBuilder extends JavacAnnotationHandler { allFields.append(fieldNode); } - new HandleConstructor().generateConstructor(tdParent, AccessLevel.PACKAGE, List.nil(), allFields.toList(), false, null, SkipIfConstructorExists.I_AM_BUILDER, null, annotationNode); + new HandleConstructor().generateConstructor(tdParent, AccessLevel.PACKAGE, List.nil(), allFields.toList(), false, null, SkipIfConstructorExists.I_AM_BUILDER, annotationNode); returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), td.name, td.typarams); typeParams = td.typarams; @@ -348,7 +348,7 @@ public class HandleBuilder extends JavacAnnotationHandler { } if (constructorExists(builderType) == MemberExistsResult.NOT_EXISTS) { - JCMethodDecl cd = HandleConstructor.createConstructor(AccessLevel.PACKAGE, List.nil(), builderType, List.nil(), false, null, annotationNode); + JCMethodDecl cd = HandleConstructor.createConstructor(AccessLevel.PACKAGE, List.nil(), builderType, List.nil(), false, annotationNode); if (cd != null) injectMethod(builderType, cd); } diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index 617ec0d1..4e90b639 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -78,7 +78,7 @@ public class HandleConstructor { String staticName = ann.staticName(); boolean force = ann.force(); List fields = force ? findFinalFields(typeNode) : List.nil(); - new HandleConstructor().generateConstructor(typeNode, level, onConstructor, fields, force, staticName, SkipIfConstructorExists.NO, null, annotationNode); + new HandleConstructor().generateConstructor(typeNode, level, onConstructor, fields, force, staticName, SkipIfConstructorExists.NO, annotationNode); } } @@ -96,14 +96,11 @@ public class HandleConstructor { AccessLevel level = ann.access(); if (level == AccessLevel.NONE) return; String staticName = ann.staticName(); - Boolean suppressConstructorProperties = null; if (annotation.isExplicit("suppressConstructorProperties")) { - @SuppressWarnings("deprecation") - boolean suppress = ann.suppressConstructorProperties(); - suppressConstructorProperties = suppress; + annotationNode.addError("This deprecated feature is no longer supported. Remove it; you can create a lombok.config file with 'lombok.anyConstructor.suppressConstructorProperties = true'."); } - new HandleConstructor().generateConstructor(typeNode, level, onConstructor, findRequiredFields(typeNode), false, staticName, SkipIfConstructorExists.NO, suppressConstructorProperties, annotationNode); + new HandleConstructor().generateConstructor(typeNode, level, onConstructor, findRequiredFields(typeNode), false, staticName, SkipIfConstructorExists.NO, annotationNode); } } @@ -146,13 +143,10 @@ public class HandleConstructor { AccessLevel level = ann.access(); if (level == AccessLevel.NONE) return; String staticName = ann.staticName(); - Boolean suppressConstructorProperties = null; if (annotation.isExplicit("suppressConstructorProperties")) { - @SuppressWarnings("deprecation") - boolean suppress = ann.suppressConstructorProperties(); - suppressConstructorProperties = suppress; + annotationNode.addError("This deprecated feature is no longer supported. Remove it; you can create a lombok.config file with 'lombok.anyConstructor.suppressConstructorProperties = true'."); } - new HandleConstructor().generateConstructor(typeNode, level, onConstructor, findAllFields(typeNode), false, staticName, SkipIfConstructorExists.NO, suppressConstructorProperties, annotationNode); + new HandleConstructor().generateConstructor(typeNode, level, onConstructor, findAllFields(typeNode), false, staticName, SkipIfConstructorExists.NO, annotationNode); } } @@ -188,7 +182,7 @@ public class HandleConstructor { } public void generateRequiredArgsConstructor(JavacNode typeNode, AccessLevel level, String staticName, SkipIfConstructorExists skipIfConstructorExists, JavacNode source) { - generateConstructor(typeNode, level, List.nil(), findRequiredFields(typeNode), false, staticName, skipIfConstructorExists, null, source); + generateConstructor(typeNode, level, List.nil(), findRequiredFields(typeNode), false, staticName, skipIfConstructorExists, source); } public enum SkipIfConstructorExists { @@ -196,10 +190,10 @@ public class HandleConstructor { } public void generateAllArgsConstructor(JavacNode typeNode, AccessLevel level, String staticName, SkipIfConstructorExists skipIfConstructorExists, JavacNode source) { - generateConstructor(typeNode, level, List.nil(), findAllFields(typeNode), false, staticName, skipIfConstructorExists, null, source); + generateConstructor(typeNode, level, List.nil(), findAllFields(typeNode), false, staticName, skipIfConstructorExists, source); } - public void generateConstructor(JavacNode typeNode, AccessLevel level, List onConstructor, List fields, boolean allToDefault, String staticName, SkipIfConstructorExists skipIfConstructorExists, Boolean suppressConstructorProperties, JavacNode source) { + public void generateConstructor(JavacNode typeNode, AccessLevel level, List onConstructor, List fields, boolean allToDefault, String staticName, SkipIfConstructorExists skipIfConstructorExists, JavacNode source) { boolean staticConstrRequired = staticName != null && !staticName.equals(""); if (skipIfConstructorExists != SkipIfConstructorExists.NO && constructorExists(typeNode) != MemberExistsResult.NOT_EXISTS) return; @@ -228,7 +222,7 @@ public class HandleConstructor { } } - JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, onConstructor, typeNode, fields, allToDefault, suppressConstructorProperties, source); + JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, onConstructor, typeNode, fields, allToDefault, source); ListBuffer argTypes = new ListBuffer(); for (JavacNode fieldNode : fields) { Type mirror = getMirrorForFieldType(fieldNode); @@ -262,18 +256,18 @@ public class HandleConstructor { mods.annotations = mods.annotations.append(annotation); } - public static JCMethodDecl createConstructor(AccessLevel level, List onConstructor, JavacNode typeNode, List fields, boolean allToDefault, Boolean suppressConstructorProperties, JavacNode source) { + public static JCMethodDecl createConstructor(AccessLevel level, List onConstructor, JavacNode typeNode, List fields, boolean allToDefault, JavacNode source) { JavacTreeMaker maker = typeNode.getTreeMaker(); boolean isEnum = (((JCClassDecl) typeNode.get()).mods.flags & Flags.ENUM) != 0; if (isEnum) level = AccessLevel.PRIVATE; - if (suppressConstructorProperties == null) { - if (fields.isEmpty()) { - suppressConstructorProperties = false; - } else { - suppressConstructorProperties = Boolean.TRUE.equals(typeNode.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_SUPPRESS_CONSTRUCTOR_PROPERTIES)); - } + boolean suppressConstructorProperties; + + if (fields.isEmpty()) { + suppressConstructorProperties = false; + } else { + suppressConstructorProperties = Boolean.TRUE.equals(typeNode.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_SUPPRESS_CONSTRUCTOR_PROPERTIES)); } ListBuffer nullChecks = new ListBuffer(); diff --git a/test/transform/resource/after-delombok/ConstructorsConfiguration.java b/test/transform/resource/after-delombok/ConstructorsConfiguration.java index effc51b8..40189911 100644 --- a/test/transform/resource/after-delombok/ConstructorsConfiguration.java +++ b/test/transform/resource/after-delombok/ConstructorsConfiguration.java @@ -6,12 +6,3 @@ class ConstructorsConfiguration { this.x = x; } } -class ConstructorsConfigurationExplicit { - int x; - @java.beans.ConstructorProperties({"x"}) - @java.lang.SuppressWarnings("all") - @javax.annotation.Generated("lombok") - public ConstructorsConfigurationExplicit(final int x) { - this.x = x; - } -} diff --git a/test/transform/resource/after-ecj/ConstructorsConfiguration.java b/test/transform/resource/after-ecj/ConstructorsConfiguration.java index 33a95181..3ca13844 100644 --- a/test/transform/resource/after-ecj/ConstructorsConfiguration.java +++ b/test/transform/resource/after-ecj/ConstructorsConfiguration.java @@ -5,10 +5,3 @@ this.x = x; } } -@lombok.AllArgsConstructor(suppressConstructorProperties = false) class ConstructorsConfigurationExplicit { - int x; - public @java.beans.ConstructorProperties({"x"}) @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") ConstructorsConfigurationExplicit(final int x) { - super(); - this.x = x; - } -} diff --git a/test/transform/resource/before/ConstructorsConfiguration.java b/test/transform/resource/before/ConstructorsConfiguration.java index 8fae10fc..4d0e8bd9 100644 --- a/test/transform/resource/before/ConstructorsConfiguration.java +++ b/test/transform/resource/before/ConstructorsConfiguration.java @@ -3,7 +3,3 @@ class ConstructorsConfiguration { int x; } -@lombok.AllArgsConstructor(suppressConstructorProperties=false) -class ConstructorsConfigurationExplicit { - int x; -} -- cgit