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/ConfigurationKeys.java | 14 ++++++-------- src/core/lombok/core/handlers/HandlerUtil.java | 4 ++-- src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java | 4 ++-- src/core/lombok/javac/handlers/JavacHandlerUtil.java | 4 ++-- 4 files changed, 12 insertions(+), 14 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java index ff17ca09..f0e070e2 100644 --- a/src/core/lombok/ConfigurationKeys.java +++ b/src/core/lombok/ConfigurationKeys.java @@ -41,30 +41,28 @@ public class ConfigurationKeys { /** * lombok configuration: {@code lombok.addGeneratedAnnotation} = {@code true} | {@code false}. * - * If unset or {@code true}, lombok generates various annotations to mark generated code like {@code @javax.annotation.Generated("lombok")} and {@code @lombok.Generated}. + * If unset or {@code true}, lombok generates {@code @javax.annotation.Generated("lombok")} on all fields, methods, and types that are generated, unless {@code lombok.addJavaxGeneratedAnnotation} is set. * * @see ConfigurationKeys#ADD_JAVAX_GENERATED_ANNOTATIONS * @see ConfigurationKeys#ADD_LOMBOK_GENERATED_ANNOTATIONS + * @deprecated Since version 1.16.14, use {@link #ADD_JAVAX_GENERATED_ANNOTATIONS} instead. */ - public static final ConfigurationKey ADD_GENERATED_ANNOTATIONS = new ConfigurationKey("lombok.addGeneratedAnnotation", "Generate @javax.annotation.Generated on all generated code (default: true).") {}; + @Deprecated + public static final ConfigurationKey ADD_GENERATED_ANNOTATIONS = new ConfigurationKey("lombok.addGeneratedAnnotation", "Generate @javax.annotation.Generated on all generated code (default: true). Deprecated, use 'lombok.addJavaxGeneratedAnnotation' instead.") {}; /** * lombok configuration: {@code lombok.addJavaxGeneratedAnnotation} = {@code true} | {@code false}. * * If unset or {@code true}, lombok generates {@code @javax.annotation.Generated("lombok")} on all fields, methods, and types that are generated, unless {@code lombok.addGeneratedAnnotation} is set to {@code false}. - * - * @see ConfigurationKeys#ADD_GENERATED_ANNOTATIONS */ public static final ConfigurationKey ADD_JAVAX_GENERATED_ANNOTATIONS = new ConfigurationKey("lombok.addJavaxGeneratedAnnotation", "Generate @javax.annotation.Generated on all generated code (default: follow lombok.addGeneratedAnnotation).") {}; /** * lombok configuration: {@code lombok.addLombokGeneratedAnnotation} = {@code true} | {@code false}. * - * If unset or {@code true}, lombok generates {@code @lombok.Generated} on all fields, methods, and types that are generated, unless {@code lombok.addGeneratedAnnotation} is set to {@code false}. - * - * @see ConfigurationKeys#ADD_GENERATED_ANNOTATIONS + * If {@code true}, lombok generates {@code @lombok.Generated} on all fields, methods, and types that are generated. */ - public static final ConfigurationKey ADD_LOMBOK_GENERATED_ANNOTATIONS = new ConfigurationKey("lombok.addLombokGeneratedAnnotation", "Generate @lombok.Generated on all generated code (default: follow lombok.addGeneratedAnnotation).") {}; + public static final ConfigurationKey ADD_LOMBOK_GENERATED_ANNOTATIONS = new ConfigurationKey("lombok.addLombokGeneratedAnnotation", "Generate @lombok.Generated on all generated code (default: false).") {}; /** * lombok configuration: {@code lombok.extern.findbugs.addSuppressFBWarnings} = {@code true} | {@code false}. diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java index a05578d4..7e6d6d66 100644 --- a/src/core/lombok/core/handlers/HandlerUtil.java +++ b/src/core/lombok/core/handlers/HandlerUtil.java @@ -109,8 +109,8 @@ public class HandlerUtil { } } - public static boolean shouldAddGenerated(LombokNode node, ConfigurationKey key) { - Boolean add = node.getAst().readConfiguration(key); + public static boolean shouldAddGenerated(LombokNode node) { + Boolean add = node.getAst().readConfiguration(ConfigurationKeys.ADD_JAVAX_GENERATED_ANNOTATIONS); if (add != null) return add; return !Boolean.FALSE.equals(node.getAst().readConfiguration(ConfigurationKeys.ADD_GENERATED_ANNOTATIONS)); } 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; diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 0b4e839d..af8289a3 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1025,10 +1025,10 @@ public class JavacHandlerUtil { public static void addGenerated(JCModifiers mods, JavacNode node, int pos, JCTree source, Context context) { if (!LombokOptionsFactory.getDelombokOptions(context).getFormatPreferences().generateGenerated()) return; - if (HandlerUtil.shouldAddGenerated(node, ConfigurationKeys.ADD_JAVAX_GENERATED_ANNOTATIONS)) { + if (HandlerUtil.shouldAddGenerated(node)) { addAnnotation(mods, node, pos, source, context, "javax.annotation.Generated", node.getTreeMaker().Literal("lombok")); } - if (HandlerUtil.shouldAddGenerated(node, ConfigurationKeys.ADD_LOMBOK_GENERATED_ANNOTATIONS)) { + if (Boolean.TRUE.equals(node.getAst().readConfiguration(ConfigurationKeys.ADD_LOMBOK_GENERATED_ANNOTATIONS))) { addAnnotation(mods, node, pos, source, context, "lombok.Generated", null); } } -- 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') 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 87822a7142e9f91da8557467d27b5854e0ebe2ec Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 10 Feb 2017 03:20:27 +0100 Subject: pre-release version bump. --- doc/changelog.markdown | 2 +- src/core/lombok/core/Version.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/core') diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 1f5218d9..2656a1ef 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -1,7 +1,7 @@ Lombok Changelog ---------------- -### v1.16.13 "Edgy Guinea Pig" +### v1.16.14 (February 10th, 2017) * v1.16.12 is the latest stable release of Project Lombok. * 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) diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java index 4fdb7216..c6dc83fa 100644 --- a/src/core/lombok/core/Version.java +++ b/src/core/lombok/core/Version.java @@ -30,9 +30,9 @@ public class Version { // ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries). // Note: In 'X.Y.Z', if Z is odd, its a snapshot build built from the repository, so many different 0.10.3 versions can exist, for example. // Official builds always end in an even number. (Since 0.10.2). - private static final String VERSION = "1.16.13"; - private static final String RELEASE_NAME = "Edgy Guinea Pig"; -// private static final String RELEASE_NAME = "Candid Duck"; + private static final String VERSION = "1.16.14"; +// private static final String RELEASE_NAME = "Edgy Guinea Pig"; + private static final String RELEASE_NAME = "Candid Duck"; private Version() { //Prevent instantiation -- cgit From 5eaf74ec22879e8fabc3f9d86a520fc04a097dc3 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 10 Feb 2017 04:06:01 +0100 Subject: Post-release version bump. --- doc/changelog.markdown | 4 +++- src/core/lombok/core/Version.java | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src/core') diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 2656a1ef..d218639d 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -1,8 +1,10 @@ Lombok Changelog ---------------- +### v1.16.15 "Edgy Guinea Pig" +* v1.16.14 is the latest stable release of Project Lombok. + ### v1.16.14 (February 10th, 2017) -* v1.16.12 is the latest stable release of Project Lombok. * 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) diff --git a/src/core/lombok/core/Version.java b/src/core/lombok/core/Version.java index c6dc83fa..a50b72d5 100644 --- a/src/core/lombok/core/Version.java +++ b/src/core/lombok/core/Version.java @@ -30,9 +30,9 @@ public class Version { // ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries). // Note: In 'X.Y.Z', if Z is odd, its a snapshot build built from the repository, so many different 0.10.3 versions can exist, for example. // Official builds always end in an even number. (Since 0.10.2). - private static final String VERSION = "1.16.14"; -// private static final String RELEASE_NAME = "Edgy Guinea Pig"; - private static final String RELEASE_NAME = "Candid Duck"; + private static final String VERSION = "1.16.15"; + private static final String RELEASE_NAME = "Edgy Guinea Pig"; +// private static final String RELEASE_NAME = "Candid Duck"; private Version() { //Prevent instantiation -- cgit From 9491bce6021d22c98dd615821d5dbb9fdf5e3fc5 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Mon, 13 Feb 2017 20:40:03 +0100 Subject: [trivial] Added a suppress warnings (to suppress an expected and in this case analysed to be harmless, intentional use of our own deprecated API) --- src/core/lombok/core/handlers/HandlerUtil.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core') diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java index 7e6d6d66..6c3a0b79 100644 --- a/src/core/lombok/core/handlers/HandlerUtil.java +++ b/src/core/lombok/core/handlers/HandlerUtil.java @@ -109,6 +109,7 @@ public class HandlerUtil { } } + @SuppressWarnings("deprecation") public static boolean shouldAddGenerated(LombokNode node) { Boolean add = node.getAst().readConfiguration(ConfigurationKeys.ADD_JAVAX_GENERATED_ANNOTATIONS); if (add != null) return add; -- 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') 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 05f93771e9aeb6ad0c884f22df4b9fa8c1f6cc2f Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Tue, 14 Feb 2017 00:36:00 +0100 Subject: [jdk9] Create FileObjects for jdk9 --- .../javac/apt/Javac9BaseFileObjectWrapper.java | 113 +++++++++++++++++++++ src/core/lombok/javac/apt/LombokFileObjects.java | 78 ++++++++++---- .../com/sun/tools/javac/file/BaseFileManager.java | 8 ++ .../com/sun/tools/javac/file/PathFileObject.java | 12 +++ 4 files changed, 189 insertions(+), 22 deletions(-) create mode 100644 src/core/lombok/javac/apt/Javac9BaseFileObjectWrapper.java create mode 100644 src/stubs/com/sun/tools/javac/file/BaseFileManager.java create mode 100644 src/stubs/com/sun/tools/javac/file/PathFileObject.java (limited to 'src/core') diff --git a/src/core/lombok/javac/apt/Javac9BaseFileObjectWrapper.java b/src/core/lombok/javac/apt/Javac9BaseFileObjectWrapper.java new file mode 100644 index 00000000..f9fe2a7d --- /dev/null +++ b/src/core/lombok/javac/apt/Javac9BaseFileObjectWrapper.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2010-2017 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 + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package lombok.javac.apt; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.net.URI; +import java.nio.file.Path; + +import javax.lang.model.element.Modifier; +import javax.lang.model.element.NestingKind; + +import com.sun.tools.javac.file.BaseFileManager; + +class Javac9BaseFileObjectWrapper extends com.sun.tools.javac.file.PathFileObject { + private final LombokFileObject delegate; + + public Javac9BaseFileObjectWrapper(BaseFileManager fileManager, Path path, LombokFileObject delegate) { + super(fileManager, path); + this.delegate = delegate; + } + + @Override public boolean isNameCompatible(String simpleName, Kind kind) { + return delegate.isNameCompatible(simpleName, kind); + } + + @Override public URI toUri() { + return delegate.toUri(); + } + + @SuppressWarnings("all") + @Override public String getName() { + return delegate.getName(); + } + + @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + return delegate.getCharContent(ignoreEncodingErrors); + } + + @Override public InputStream openInputStream() throws IOException { + return delegate.openInputStream(); + } + + @Override public Reader openReader(boolean ignoreEncodingErrors) throws IOException { + return delegate.openReader(ignoreEncodingErrors); + } + + @Override public Writer openWriter() throws IOException { + return delegate.openWriter(); + } + + @Override public OutputStream openOutputStream() throws IOException { + return delegate.openOutputStream(); + } + + @Override public long getLastModified() { + return delegate.getLastModified(); + } + + @Override public boolean delete() { + return delegate.delete(); + } + + @Override public Kind getKind() { + return delegate.getKind(); + } + + @Override public NestingKind getNestingKind() { + return delegate.getNestingKind(); + } + + @Override public Modifier getAccessLevel() { + return delegate.getAccessLevel(); + } + + @Override public boolean equals(Object obj) { + if (!(obj instanceof Javac9BaseFileObjectWrapper)) { + return false; + } + return delegate.equals(((Javac9BaseFileObjectWrapper)obj).delegate); + } + + @Override public int hashCode() { + return delegate.hashCode(); + } + + @Override public String toString() { + return delegate.toString(); + } +} \ No newline at end of file diff --git a/src/core/lombok/javac/apt/LombokFileObjects.java b/src/core/lombok/javac/apt/LombokFileObjects.java index 412e449b..7e818cab 100644 --- a/src/core/lombok/javac/apt/LombokFileObjects.java +++ b/src/core/lombok/javac/apt/LombokFileObjects.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 The Project Lombok Authors. + * Copyright (C) 2010-2017 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 @@ -23,19 +23,24 @@ package lombok.javac.apt; import java.lang.reflect.Method; +import java.net.URI; +import java.nio.file.Paths; import java.util.concurrent.atomic.AtomicBoolean; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; import javax.tools.JavaFileObject.Kind; +import com.sun.tools.javac.file.BaseFileManager; + import lombok.core.DiagnosticsReceiver; //Can't use SimpleJavaFileObject so we copy/paste most of its content here, because javac doesn't follow the interface, //and casts to its own BaseFileObject type. D'oh! final class LombokFileObjects { - enum Compiler { - JAVAC6 { + + interface Compiler { + Compiler JAVAC6 = new Compiler() { private Method decoderMethod = null; private final AtomicBoolean decoderIsSet = new AtomicBoolean(); @@ -46,13 +51,13 @@ final class LombokFileObjects { @Override public Method getDecoderMethod() { synchronized (decoderIsSet) { if (decoderIsSet.get()) return decoderMethod; - decoderMethod = getDecoderMethod("com.sun.tools.javac.util.BaseFileObject"); + decoderMethod = LombokFileObjects.getDecoderMethod("com.sun.tools.javac.util.BaseFileObject"); decoderIsSet.set(true); return decoderMethod; } } - }, - JAVAC7 { + }; + Compiler JAVAC7 = new Compiler() { private Method decoderMethod = null; private final AtomicBoolean decoderIsSet = new AtomicBoolean(); @@ -63,28 +68,28 @@ final class LombokFileObjects { @Override public Method getDecoderMethod() { synchronized (decoderIsSet) { if (decoderIsSet.get()) return decoderMethod; - decoderMethod = getDecoderMethod("com.sun.tools.javac.file.BaseFileObject"); + decoderMethod = LombokFileObjects.getDecoderMethod("com.sun.tools.javac.file.BaseFileObject"); decoderIsSet.set(true); return decoderMethod; } } }; - static Method getDecoderMethod(String className) { - Method m = null; - try { - m = Class.forName(className).getDeclaredMethod("getDecoder", boolean.class); - m.setAccessible(true); - } catch (NoSuchMethodException e) { - // Intentional fallthrough - getDecoder(boolean) is not always present. - } catch (ClassNotFoundException e) { - // Intentional fallthrough - getDecoder(boolean) is not always present. - } - return m; - } + JavaFileObject wrap(LombokFileObject fileObject); + Method getDecoderMethod(); + } - abstract JavaFileObject wrap(LombokFileObject fileObject); - abstract Method getDecoderMethod(); + static Method getDecoderMethod(String className) { + Method m = null; + try { + m = Class.forName(className).getDeclaredMethod("getDecoder", boolean.class); + m.setAccessible(true); + } catch (NoSuchMethodException e) { + // Intentional fallthrough - getDecoder(boolean) is not always present. + } catch (ClassNotFoundException e) { + // Intentional fallthrough - getDecoder(boolean) is not always present. + } + return m; } private LombokFileObjects() {} @@ -93,7 +98,16 @@ final class LombokFileObjects { String jfmClassName = jfm != null ? jfm.getClass().getName() : "null"; if (jfmClassName.equals("com.sun.tools.javac.util.DefaultFileManager")) return Compiler.JAVAC6; if (jfmClassName.equals("com.sun.tools.javac.util.JavacFileManager")) return Compiler.JAVAC6; - if (jfmClassName.equals("com.sun.tools.javac.file.JavacFileManager")) return Compiler.JAVAC7; + if (jfmClassName.equals("com.sun.tools.javac.file.JavacFileManager")) { + try { + Class superType = Class.forName("com.sun.tools.javac.file.BaseFileManager"); + if (superType.isInstance(jfm)) { + return new Java9Compiler(jfm); + } + } + catch (Exception e) {} + return Compiler.JAVAC7; + } try { if (Class.forName("com.sun.tools.javac.file.BaseFileObject") == null) throw new NullPointerException(); return Compiler.JAVAC7; @@ -112,4 +126,24 @@ final class LombokFileObjects { static JavaFileObject createIntercepting(Compiler compiler, JavaFileObject delegate, String fileName, DiagnosticsReceiver diagnostics) { return compiler.wrap(new InterceptingJavaFileObject(delegate, fileName, diagnostics, compiler.getDecoderMethod())); } + + static class Java9Compiler implements Compiler { + private final BaseFileManager fileManager; + + public Java9Compiler(JavaFileManager jfm) { + fileManager = (BaseFileManager) jfm; + } + + @Override public JavaFileObject wrap(LombokFileObject fileObject) { + URI uri = fileObject.toUri(); + if (uri.getScheme() == null) { + uri = URI.create("file://" + uri); + } + return new Javac9BaseFileObjectWrapper(fileManager, Paths.get(uri), fileObject); + } + + @Override public Method getDecoderMethod() { + throw new UnsupportedOperationException(); + } + } } diff --git a/src/stubs/com/sun/tools/javac/file/BaseFileManager.java b/src/stubs/com/sun/tools/javac/file/BaseFileManager.java new file mode 100644 index 00000000..7a2293d5 --- /dev/null +++ b/src/stubs/com/sun/tools/javac/file/BaseFileManager.java @@ -0,0 +1,8 @@ +/* + * These are stub versions of various bits of javac-internal API (for various different versions of javac). Lombok is compiled against these. + */ +package com.sun.tools.javac.file; + +import javax.tools.JavaFileManager; + +public abstract class BaseFileManager implements JavaFileManager{} diff --git a/src/stubs/com/sun/tools/javac/file/PathFileObject.java b/src/stubs/com/sun/tools/javac/file/PathFileObject.java new file mode 100644 index 00000000..c1ee6074 --- /dev/null +++ b/src/stubs/com/sun/tools/javac/file/PathFileObject.java @@ -0,0 +1,12 @@ +/* + * These are stub versions of various bits of javac-internal API (for various different versions of javac). Lombok is compiled against these. + */ +package com.sun.tools.javac.file; + +import java.nio.file.Path; + +import javax.tools.JavaFileObject; + +public abstract class PathFileObject implements JavaFileObject { + protected PathFileObject(BaseFileManager fileManager, Path path) {} +} -- cgit From e3a86782e590e11291e1f208417d5ca61aac4fac Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Tue, 14 Feb 2017 01:21:27 +0100 Subject: [jdk9] Fix members_field error --- .../lombok/javac/handlers/JavacHandlerUtil.java | 23 +++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index af8289a3..918d23f1 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -894,16 +894,20 @@ public class JavacHandlerUtil { static class ClassSymbolMembersField { private static final Field membersField; private static final Method removeMethod; + private static final Method enterMethod; static { Field f = null; - Method m = null; + Method r = null; + Method e = null; try { f = ClassSymbol.class.getField("members_field"); - m = f.getType().getMethod("remove", Symbol.class); - } catch (Exception e) {} + r = f.getType().getMethod("remove", Symbol.class); + e = f.getType().getMethod("enter", Symbol.class); + } catch (Exception ex) {} membersField = f; - removeMethod = m; + removeMethod = r; + enterMethod = r; } static void remove(ClassSymbol from, Symbol toRemove) { @@ -914,6 +918,15 @@ public class JavacHandlerUtil { removeMethod.invoke(scope, toRemove); } catch (Exception e) {} } + + static void enter(ClassSymbol from, Symbol toEnter) { + if (from == null) return; + try { + Scope scope = (Scope) membersField.get(from); + if (scope == null) return; + enterMethod.invoke(scope, toEnter); + } catch (Exception e) {} + } } public static void injectMethod(JavacNode typeNode, JCMethodDecl method) { @@ -959,7 +972,7 @@ public class JavacHandlerUtil { if (typeMirror == null || paramTypes == null || returnType == null) return; ClassSymbol cs = (ClassSymbol) typeMirror; MethodSymbol methodSymbol = new MethodSymbol(access, methodName, new MethodType(paramTypes, returnType, List.nil(), Symtab.instance(context).methodClass), cs); - cs.members_field.enter(methodSymbol); + ClassSymbolMembersField.enter(cs, methodSymbol); } /** -- cgit From 06ddfd4e656255dadaf4a47c9070e3765ea57d8e Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Thu, 16 Feb 2017 23:32:39 +0100 Subject: A stray debug variant of an error message left in the source. --- src/core/lombok/javac/handlers/HandleBuilder.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/core') diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index 8588fc16..d37e1f79 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -270,8 +270,7 @@ public class HandleBuilder extends JavacAnnotationHandler { } if (pos == -1 || tpOnType.size() <= pos) { - annotationNode.addError("**" + returnType.getClass().toString()); -// annotationNode.addError("@Builder(toBuilder=true) requires that each type parameter on the static method is part of the typeargs of the return value. Type parameter " + tp.name + " is not part of the return type."); + annotationNode.addError("@Builder(toBuilder=true) requires that each type parameter on the static method is part of the typeargs of the return value. Type parameter " + tp.name + " is not part of the return type."); return; } typeArgsForToBuilder.add(tpOnType.get(pos).name); -- cgit From 272b33a6ffb7c8697148b4e3de405dbaf59fedfa Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Thu, 16 Feb 2017 23:32:58 +0100 Subject: bugfix for JDK9: The enterMethod was erroneously hooked up to the remove method. whoops. --- src/core/lombok/javac/handlers/JavacHandlerUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core') diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 918d23f1..2b67118e 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -907,7 +907,7 @@ public class JavacHandlerUtil { } catch (Exception ex) {} membersField = f; removeMethod = r; - enterMethod = r; + enterMethod = e; } static void remove(ClassSymbol from, Symbol toRemove) { -- cgit From 74603cd9d355353f5373deb167988c5eaf015346 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Thu, 16 Feb 2017 23:32:17 +0100 Subject: Fixing issue #1298: `@Builder` with recursive generics didn’t work in javac/delombok. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/lombok/javac/handlers/HandleBuilder.java | 13 ++- .../lombok/javac/handlers/JavacHandlerUtil.java | 17 +++- .../before/I1298BuilderWithGenerics.java | 15 ---- .../BuilderWithRecursiveGenerics.java | 100 +++++++++++++++++++++ .../after-ecj/BuilderWithRecursiveGenerics.java | 78 ++++++++++++++++ .../before/BuilderWithRecursiveGenerics.java | 13 +++ 6 files changed, 212 insertions(+), 24 deletions(-) delete mode 100644 test/transform/knownBroken/before/I1298BuilderWithGenerics.java create mode 100644 test/transform/resource/after-delombok/BuilderWithRecursiveGenerics.java create mode 100644 test/transform/resource/after-ecj/BuilderWithRecursiveGenerics.java create mode 100644 test/transform/resource/before/BuilderWithRecursiveGenerics.java (limited to 'src/core') diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index d37e1f79..2704981b 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -297,7 +297,7 @@ public class HandleBuilder extends JavacAnnotationHandler { JavacNode builderType = findInnerClass(tdParent, builderClassName); if (builderType == null) { - builderType = makeBuilderClass(isStatic, tdParent, builderClassName, typeParams, ast); + builderType = makeBuilderClass(isStatic, annotationNode, tdParent, builderClassName, typeParams, ast); } else { JCClassDecl builderTypeDeclaration = (JCClassDecl) builderType.get(); if (isStatic && !builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)) { @@ -319,7 +319,6 @@ public class HandleBuilder extends JavacAnnotationHandler { } } } - } for (BuilderFieldData bfd : builderFields) { @@ -374,7 +373,7 @@ public class HandleBuilder extends JavacAnnotationHandler { if (addCleaning) injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast)); if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) { - JCMethodDecl md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, tdParent, typeParams); + JCMethodDecl md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, annotationNode, tdParent, typeParams); recursiveSetGeneratedBy(md, ast, annotationNode.getContext()); if (md != null) injectMethod(tdParent, md); } @@ -549,7 +548,7 @@ public class HandleBuilder extends JavacAnnotationHandler { return maker.MethodDef(maker.Modifiers(Flags.PUBLIC), type.toName(buildName), returnType, List.nil(), List.nil(), thrownExceptions, body, null); } - public JCMethodDecl generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, JavacNode type, List typeParams) { + public JCMethodDecl generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, JavacNode source, JavacNode type, List typeParams) { JavacTreeMaker maker = type.getTreeMaker(); ListBuffer typeArgs = new ListBuffer(); @@ -563,7 +562,7 @@ public class HandleBuilder extends JavacAnnotationHandler { JCBlock body = maker.Block(0, List.of(statement)); int modifiers = Flags.PUBLIC; if (isStatic) modifiers |= Flags.STATIC; - return maker.MethodDef(maker.Modifiers(modifiers), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), copyTypeParams(maker, typeParams), List.nil(), List.nil(), body, null); + return maker.MethodDef(maker.Modifiers(modifiers), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type.toName(builderClassName), typeParams), copyTypeParams(source, typeParams), List.nil(), List.nil(), body, null); } public void generateBuilderFields(JavacNode builderType, java.util.List builderFields, JCTree source) { @@ -628,12 +627,12 @@ public class HandleBuilder extends JavacAnnotationHandler { return null; } - public JavacNode makeBuilderClass(boolean isStatic, JavacNode tdParent, String builderClassName, List typeParams, JCAnnotation ast) { + public JavacNode makeBuilderClass(boolean isStatic, JavacNode source, JavacNode tdParent, String builderClassName, List typeParams, JCAnnotation ast) { JavacTreeMaker maker = tdParent.getTreeMaker(); int modifiers = Flags.PUBLIC; if (isStatic) modifiers |= Flags.STATIC; JCModifiers mods = maker.Modifiers(modifiers); - JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderClassName), copyTypeParams(maker, typeParams), null, List.nil(), List.nil()); + JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderClassName), copyTypeParams(source, typeParams), null, List.nil(), List.nil()); return injectType(tdParent, builder); } diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 2b67118e..27289108 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -92,6 +92,7 @@ import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.JCTree.JCWildcard; import com.sun.tools.javac.tree.JCTree.TypeBoundKind; +import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; @@ -1317,10 +1318,22 @@ public class JavacHandlerUtil { return result.toList(); } - public static List copyTypeParams(JavacTreeMaker maker, List params) { + public static List copyTypeParams(JavacNode source, List params) { if (params == null || params.isEmpty()) return params; ListBuffer out = new ListBuffer(); - for (JCTypeParameter tp : params) out.append(maker.TypeParameter(tp.name, tp.bounds)); + JavacTreeMaker maker = source.getTreeMaker(); + Context context = source.getContext(); + for (JCTypeParameter tp : params) { + List bounds = tp.bounds; + if (bounds != null && !bounds.isEmpty()) { + ListBuffer boundsCopy = new ListBuffer(); + for (JCExpression expr : tp.bounds) { + boundsCopy.append(cloneType(maker, expr, source.get(), context)); + } + bounds = boundsCopy.toList(); + } + out.append(maker.TypeParameter(tp.name, bounds)); + } return out.toList(); } diff --git a/test/transform/knownBroken/before/I1298BuilderWithGenerics.java b/test/transform/knownBroken/before/I1298BuilderWithGenerics.java deleted file mode 100644 index af154d42..00000000 --- a/test/transform/knownBroken/before/I1298BuilderWithGenerics.java +++ /dev/null @@ -1,15 +0,0 @@ -import java.util.Set; -import lombok.Builder; -import lombok.Value; - -public class I1298BuilderWithGenerics { - interface Inter> {} - - @Builder @Value public static class Test< - Foo, - Bar extends Set, - Quz extends Inter> { - Foo foo; - Bar bar; - } -} diff --git a/test/transform/resource/after-delombok/BuilderWithRecursiveGenerics.java b/test/transform/resource/after-delombok/BuilderWithRecursiveGenerics.java new file mode 100644 index 00000000..edc1e3c6 --- /dev/null +++ b/test/transform/resource/after-delombok/BuilderWithRecursiveGenerics.java @@ -0,0 +1,100 @@ +import java.util.Set; +public class BuilderWithRecursiveGenerics { + interface Inter> { + } + public static final class Test, Quz extends Inter> { + private final Foo foo; + private final Bar bar; + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + Test(final Foo foo, final Bar bar) { + this.foo = foo; + this.bar = bar; + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public static class TestBuilder, Quz extends Inter> { + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + private Foo foo; + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + private Bar bar; + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + TestBuilder() { + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public TestBuilder foo(final Foo foo) { + this.foo = foo; + return this; + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public TestBuilder bar(final Bar bar) { + this.bar = bar; + return this; + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public Test build() { + return new Test(foo, bar); + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public java.lang.String toString() { + return "BuilderWithRecursiveGenerics.Test.TestBuilder(foo=" + this.foo + ", bar=" + this.bar + ")"; + } + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public static , Quz extends Inter> TestBuilder builder() { + return new TestBuilder(); + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public Foo getFoo() { + return this.foo; + } + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public Bar getBar() { + return this.bar; + } + @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 BuilderWithRecursiveGenerics.Test)) return false; + final BuilderWithRecursiveGenerics.Test other = (BuilderWithRecursiveGenerics.Test) o; + final java.lang.Object this$foo = this.getFoo(); + final java.lang.Object other$foo = other.getFoo(); + if (this$foo == null ? other$foo != null : !this$foo.equals(other$foo)) return false; + final java.lang.Object this$bar = this.getBar(); + final java.lang.Object other$bar = other.getBar(); + if (this$bar == null ? other$bar != null : !this$bar.equals(other$bar)) return false; + return true; + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public int hashCode() { + final int PRIME = 59; + int result = 1; + final java.lang.Object $foo = this.getFoo(); + result = result * PRIME + ($foo == null ? 43 : $foo.hashCode()); + final java.lang.Object $bar = this.getBar(); + result = result * PRIME + ($bar == null ? 43 : $bar.hashCode()); + return result; + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + @javax.annotation.Generated("lombok") + public java.lang.String toString() { + return "BuilderWithRecursiveGenerics.Test(foo=" + this.getFoo() + ", bar=" + this.getBar() + ")"; + } + } +} diff --git a/test/transform/resource/after-ecj/BuilderWithRecursiveGenerics.java b/test/transform/resource/after-ecj/BuilderWithRecursiveGenerics.java new file mode 100644 index 00000000..f13b8b9b --- /dev/null +++ b/test/transform/resource/after-ecj/BuilderWithRecursiveGenerics.java @@ -0,0 +1,78 @@ +import java.util.Set; +import lombok.Builder; +import lombok.Value; +public class BuilderWithRecursiveGenerics { + interface Inter> { + } + public static final @Builder @Value class Test, Quz extends Inter> { + public static @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") class TestBuilder, Quz extends Inter> { + private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") Foo foo; + private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") Bar bar; + @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") TestBuilder() { + super(); + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") TestBuilder foo(final Foo foo) { + this.foo = foo; + return this; + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") TestBuilder bar(final Bar bar) { + this.bar = bar; + return this; + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") Test build() { + return new Test(foo, bar); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() { + return (((("BuilderWithRecursiveGenerics.Test.TestBuilder(foo=" + this.foo) + ", bar=") + this.bar) + ")"); + } + } + private final Foo foo; + private final Bar bar; + @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") Test(final Foo foo, final Bar bar) { + super(); + this.foo = foo; + this.bar = bar; + } + public static @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") , Quz extends Inter>TestBuilder builder() { + return new TestBuilder(); + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") Foo getFoo() { + return this.foo; + } + public @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") Bar getBar() { + return this.bar; + } + 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 BuilderWithRecursiveGenerics.Test))) + return false; + final BuilderWithRecursiveGenerics.Test other = (BuilderWithRecursiveGenerics.Test) o; + final java.lang.Object this$foo = this.getFoo(); + final java.lang.Object other$foo = other.getFoo(); + if (((this$foo == null) ? (other$foo != null) : (! this$foo.equals(other$foo)))) + return false; + final java.lang.Object this$bar = this.getBar(); + final java.lang.Object other$bar = other.getBar(); + if (((this$bar == null) ? (other$bar != null) : (! this$bar.equals(other$bar)))) + return false; + return true; + } + public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") int hashCode() { + final int PRIME = 59; + int result = 1; + final java.lang.Object $foo = this.getFoo(); + result = ((result * PRIME) + (($foo == null) ? 43 : $foo.hashCode())); + final java.lang.Object $bar = this.getBar(); + result = ((result * PRIME) + (($bar == null) ? 43 : $bar.hashCode())); + return result; + } + public @java.lang.Override @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") java.lang.String toString() { + return (((("BuilderWithRecursiveGenerics.Test(foo=" + this.getFoo()) + ", bar=") + this.getBar()) + ")"); + } + } + public BuilderWithRecursiveGenerics() { + super(); + } +} + diff --git a/test/transform/resource/before/BuilderWithRecursiveGenerics.java b/test/transform/resource/before/BuilderWithRecursiveGenerics.java new file mode 100644 index 00000000..041da414 --- /dev/null +++ b/test/transform/resource/before/BuilderWithRecursiveGenerics.java @@ -0,0 +1,13 @@ +//issue #1298 +import java.util.Set; +import lombok.Builder; +import lombok.Value; + +public class BuilderWithRecursiveGenerics { + interface Inter> {} + + @Builder @Value public static class Test, Quz extends Inter> { + Foo foo; + Bar bar; + } +} -- 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') 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') 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