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. --- .../eclipse/handlers/HandleEqualsAndHashCode.java | 70 +++++++++++++--------- .../javac/handlers/HandleEqualsAndHashCode.java | 36 +++++------ 2 files changed, 58 insertions(+), 48 deletions(-) (limited to 'src/core') 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()); } -- 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. --- src/core/lombok/core/Version.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core') 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. --- src/core/lombok/core/Version.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core') 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 ++++++++++---- 2 files changed, 169 insertions(+), 22 deletions(-) create mode 100644 src/core/lombok/javac/apt/Javac9BaseFileObjectWrapper.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(); + } + } } -- 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 ++++++------- src/core/lombok/javac/handlers/JavacHandlerUtil.java | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 9 deletions(-) (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(); } -- 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. --- 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 +++++++++++++--------- 19 files changed, 191 insertions(+), 100 deletions(-) (limited to 'src/core') 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/