diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | doc/changelog.markdown | 4 | ||||
-rw-r--r-- | src/core/lombok/core/AST.java | 32 | ||||
-rw-r--r-- | src/core/lombok/eclipse/EclipseAST.java | 6 | ||||
-rw-r--r-- | src/core/lombok/javac/JavacAST.java | 42 | ||||
-rw-r--r-- | src/installer/lombok/installer/eclipse/RhdsFinder.java | 70 | ||||
-rw-r--r-- | src/installer/lombok/installer/eclipse/RhdsLocation.java | 45 | ||||
-rw-r--r-- | src/installer/lombok/installer/eclipse/RhdsLocationProvider.java | 69 | ||||
-rw-r--r-- | src/installer/lombok/installer/eclipse/rhds.png | bin | 0 -> 3470 bytes | |||
-rw-r--r-- | test/transform/resource/after-delombok/ValFinal.java | 5 | ||||
-rw-r--r-- | test/transform/resource/after-delombok/ValInLambda.java | 18 | ||||
-rw-r--r-- | test/transform/resource/after-ecj/ValFinal.java | 9 | ||||
-rw-r--r-- | test/transform/resource/after-ecj/ValInLambda.java | 21 | ||||
-rw-r--r-- | test/transform/resource/before/ValFinal.java | 6 | ||||
-rw-r--r-- | test/transform/resource/before/ValInLambda.java | 21 |
15 files changed, 323 insertions, 26 deletions
@@ -1,5 +1,6 @@ Lombok contributors in alphabetical order: +Bulgakov Alexander <buls@yandex.ru> Christian Sterzl <christian.sterzl@gmail.com> DaveLaw <project.lombok@apconsult.de> Dawid Rusin <dawidrusin90@gmail.com> diff --git a/doc/changelog.markdown b/doc/changelog.markdown index bdd1c818..89df8709 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -3,7 +3,9 @@ Lombok Changelog ### v1.16.11 "Edgy Guinea Pig" * v1.16.10 is the latest release -* BUGFIX: delombok: for-loops with initializers that are not local variables would be generated incorrectly [Issue 1076](https://github.com/rzwitserloot/lombok/issues/1076) +* BUGFIX: `val` in lambda expressions now work as expected [Issue #911](https://github.com/rzwitserloot/lombok/issues/911) +* PLATFORM: Red Hat JBoss Developer Studio is now correctly identified by the installer [Issue #1164](https://github.com/rzwitserloot/lombok/issues/1164) +* BUGFIX: delombok: for-loops with initializers that are not local variables would be generated incorrectly [Issue #1076](https://github.com/rzwitserloot/lombok/issues/1076) ### v1.16.10 (July 15th, 2016) * FEATURE: Added support for JBoss logger [Issue #1103](https://github.com/rzwitserloot/lombok/issues/1103) diff --git a/src/core/lombok/core/AST.java b/src/core/lombok/core/AST.java index e6efe058..1142018f 100644 --- a/src/core/lombok/core/AST.java +++ b/src/core/lombok/core/AST.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2013 The Project Lombok Authors. + * Copyright (C) 2009-2016 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 @@ -21,7 +21,7 @@ */ package lombok.core; -import static lombok.Lombok.*; +import static lombok.Lombok.sneakyThrow; import java.lang.reflect.Array; import java.lang.reflect.Field; @@ -31,10 +31,11 @@ import java.lang.reflect.Type; import java.net.URI; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import lombok.core.configuration.ConfigurationKey; import lombok.core.debug.HistogramTracker; @@ -61,12 +62,18 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>, Map<N, N> identityDetector = new IdentityHashMap<N, N>(); private Map<N, L> nodeMap = new IdentityHashMap<N, L>(); private boolean changed = false; + + // The supertypes which are considered AST Node children. Usually, the Statement, and the Expression, + // though some platforms (such as Eclipse) group these under one common supertype. + private final Collection<Class<? extends N>> statementTypes; + private static final HistogramTracker configTracker = System.getProperty("lombok.timeConfig") == null ? null : new HistogramTracker("lombok.config"); - protected AST(String fileName, String packageDeclaration, ImportList imports) { + protected AST(String fileName, String packageDeclaration, ImportList imports, Collection<Class<? extends N>> statementTypes) { this.fileName = fileName == null ? "(unknown).java" : fileName; this.packageDeclaration = packageDeclaration; this.imports = imports; + this.statementTypes = statementTypes; } /** @@ -209,11 +216,11 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>, } } - private static Map<Class<?>, Collection<FieldAccess>> fieldsOfASTClasses = new HashMap<Class<?>, Collection<FieldAccess>>(); + private static final ConcurrentMap<Class<?>, Collection<FieldAccess>> fieldsOfASTClasses = new ConcurrentHashMap<Class<?>, Collection<FieldAccess>>(); /** Returns FieldAccess objects for the stated class. Each field that contains objects of the kind returned by * {@link #getStatementTypes()}, either directly or inside of an array or java.util.collection (or array-of-arrays, - * or collection-of-collections, etcetera), is returned. + * or collection-of-collections, et cetera), is returned. */ protected Collection<FieldAccess> fieldsOf(Class<?> c) { Collection<FieldAccess> fields = fieldsOfASTClasses.get(c); @@ -221,8 +228,8 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>, fields = new ArrayList<FieldAccess>(); getFields(c, fields); - fieldsOfASTClasses.put(c, fields); - return fields; + fieldsOfASTClasses.putIfAbsent(c, fields); + return fieldsOfASTClasses.get(c); } private void getFields(Class<?> c, Collection<FieldAccess> fields) { @@ -261,13 +268,8 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>, return Object.class; } - /** - * The supertypes which are considered AST Node children. Usually, the Statement, and the Expression, - * though some platforms (such as Eclipse) group these under one common supertype. */ - protected abstract Collection<Class<? extends N>> getStatementTypes(); - - protected boolean shouldDrill(Class<?> parentType, Class<?> childType, String fieldName) { - for (Class<?> statementType : getStatementTypes()) { + private boolean shouldDrill(Class<?> parentType, Class<?> childType, String fieldName) { + for (Class<?> statementType : statementTypes) { if (statementType.isAssignableFrom(childType)) return true; } diff --git a/src/core/lombok/eclipse/EclipseAST.java b/src/core/lombok/eclipse/EclipseAST.java index 6741b33a..dc2c9843 100644 --- a/src/core/lombok/eclipse/EclipseAST.java +++ b/src/core/lombok/eclipse/EclipseAST.java @@ -62,7 +62,7 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> { * @param ast The compilation unit, which serves as the top level node in the tree to be built. */ public EclipseAST(CompilationUnitDeclaration ast) { - super(toFileName(ast), packageDeclaration(ast), new EclipseImportList(ast)); + super(toFileName(ast), packageDeclaration(ast), new EclipseImportList(ast), statementTypes()); this.compilationUnitDeclaration = ast; setTop(buildCompilationUnit(ast)); this.completeParse = isComplete(ast); @@ -477,9 +477,9 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> { return putInMap(new EclipseNode(this, statement, childNodes, Kind.STATEMENT)); } - /** For Eclipse, only Statement counts, as Expression is a subclass of it, even though this isn't + /* For Eclipse, only Statement counts, as Expression is a subclass of it, even though this isn't * entirely correct according to the JLS spec (only some expressions can be used as statements, not all of them). */ - @Override protected Collection<Class<? extends ASTNode>> getStatementTypes() { + private static Collection<Class<? extends ASTNode>> statementTypes() { return Collections.<Class<? extends ASTNode>>singleton(Statement.class); } diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index da61361d..106a29ae 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2015 The Project Lombok Authors. + * Copyright (C) 2009-2016 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 @@ -28,6 +28,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import javax.annotation.processing.Messager; import javax.tools.Diagnostic; @@ -79,7 +81,7 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> { * @param top The compilation unit, which serves as the top level node in the tree to be built. */ public JavacAST(Messager messager, Context context, JCCompilationUnit top) { - super(sourceName(top), PackageName.getPackageName(top), new JavacImportList(top)); + super(sourceName(top), PackageName.getPackageName(top), new JavacImportList(top), statementTypes()); setTop(buildCompilationUnit(top)); this.context = context; this.messager = messager; @@ -315,7 +317,6 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> { // @Foo int x, y; is handled in javac by putting the same annotation node on 2 JCVariableDecls. return null; } - return putInMap(new JavacNode(this, annotation, null, Kind.ANNOTATION)); } @@ -333,12 +334,40 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> { if (statement instanceof JCClassDecl) return buildType((JCClassDecl)statement); if (statement instanceof JCVariableDecl) return buildLocalVar((JCVariableDecl)statement, Kind.LOCAL); if (statement instanceof JCTry) return buildTry((JCTry) statement); - + if (statement.getClass().getSimpleName().equals("JCLambda")) return buildLambda(statement); if (setAndGetAsHandled(statement)) return null; return drill(statement); } + private JavacNode buildLambda(JCTree jcTree) { + return buildStatementOrExpression(getBody(jcTree)); + } + + private JCTree getBody(JCTree jcTree) { + try { + return (JCTree) getBodyMethod(jcTree.getClass()).invoke(jcTree); + } catch (Exception e) { + throw Javac.sneakyThrow(e); + } + } + + private final static ConcurrentMap<Class<?>, Method> getBodyMethods = new ConcurrentHashMap<Class<?>, Method>(); + + private Method getBodyMethod(Class<?> c) { + Method m = getBodyMethods.get(c); + if (m != null) { + return m; + } + try { + m = c.getMethod("getBody"); + } catch (NoSuchMethodException e) { + throw Javac.sneakyThrow(e); + } + getBodyMethods.putIfAbsent(c, m); + return getBodyMethods.get(c); + } + private JavacNode drill(JCTree statement) { try { List<JavacNode> childNodes = new ArrayList<JavacNode>(); @@ -354,9 +383,8 @@ public class JavacAST extends AST<JavacAST, JavacNode, JCTree> { } } - /** For javac, both JCExpression and JCStatement are considered as valid children types. */ - @Override - protected Collection<Class<? extends JCTree>> getStatementTypes() { + /* For javac, both JCExpression and JCStatement are considered as valid children types. */ + private static Collection<Class<? extends JCTree>> statementTypes() { Collection<Class<? extends JCTree>> collection = new ArrayList<Class<? extends JCTree>>(3); collection.add(JCStatement.class); collection.add(JCExpression.class); diff --git a/src/installer/lombok/installer/eclipse/RhdsFinder.java b/src/installer/lombok/installer/eclipse/RhdsFinder.java new file mode 100644 index 00000000..5e639fa5 --- /dev/null +++ b/src/installer/lombok/installer/eclipse/RhdsFinder.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2013 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.installer.eclipse; + +import java.util.Arrays; +import java.util.List; + +import lombok.installer.CorruptedIdeLocationException; +import lombok.installer.IdeFinder; +import lombok.installer.IdeLocation; + +import org.mangosdk.spi.ProviderFor; + +/** + * RHDS (Red Hat JBoss Developer Studio) is an eclipse variant. + * Other than different executable names, it's the same as eclipse, as far as lombok support goes. + */ +@ProviderFor(IdeFinder.class) +public class RhdsFinder extends EclipseFinder { + @Override protected IdeLocation createLocation(String guess) throws CorruptedIdeLocationException { + return new RhdsLocationProvider().create0(guess); + } + + @Override protected String getDirName() { + return "studio"; + } + + @Override protected String getMacExecutableName() { + return "devstudio.app"; + } + + @Override protected String getUnixExecutableName() { + return "devstudio"; + } + + @Override protected String getWindowsExecutableName() { + return "devstudio.exe"; + } + + @Override protected List<String> getSourceDirsOnWindows() { + return Arrays.asList("\\", "\\Program Files", "\\Program Files (x86)", System.getProperty("user.home", ".")); + } + + @Override protected List<String> getSourceDirsOnMac() { + return Arrays.asList("/Applications", System.getProperty("user.home", ".")); + } + + @Override protected List<String> getSourceDirsOnUnix() { + return Arrays.asList(System.getProperty("user.home", ".")); + } +} diff --git a/src/installer/lombok/installer/eclipse/RhdsLocation.java b/src/installer/lombok/installer/eclipse/RhdsLocation.java new file mode 100644 index 00000000..dbe1812c --- /dev/null +++ b/src/installer/lombok/installer/eclipse/RhdsLocation.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2013 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.installer.eclipse; + +import java.io.File; +import java.net.URL; + +import lombok.installer.CorruptedIdeLocationException; + +public class RhdsLocation extends EclipseLocation { + public RhdsLocation(String nameOfLocation, File pathToEclipseIni) throws CorruptedIdeLocationException { + super(nameOfLocation, pathToEclipseIni); + } + + @Override public URL getIdeIcon() { + return RhdsLocation.class.getResource("rhds.png"); + } + + @Override protected String getIniFileName() { + return "devstudio.ini"; + } + + @Override protected String getTypeName() { + return "Red Hat JBoss Developer Studio"; + } +} diff --git a/src/installer/lombok/installer/eclipse/RhdsLocationProvider.java b/src/installer/lombok/installer/eclipse/RhdsLocationProvider.java new file mode 100644 index 00000000..fabddba2 --- /dev/null +++ b/src/installer/lombok/installer/eclipse/RhdsLocationProvider.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2013 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.installer.eclipse; + +import java.io.File; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; + +import lombok.installer.CorruptedIdeLocationException; +import lombok.installer.IdeLocation; +import lombok.installer.IdeLocationProvider; +import lombok.installer.IdeFinder.OS; + +import org.mangosdk.spi.ProviderFor; + +@ProviderFor(IdeLocationProvider.class) +public class RhdsLocationProvider extends EclipseLocationProvider { + @Override protected List<String> getEclipseExecutableNames() { + return Arrays.asList("devstudio.app", "devstudio.exe", "devstudioc.exe", "devstudio"); + } + + @Override protected String getIniName() { + return "devstudio.ini"; + } + + @Override protected IdeLocation makeLocation(String name, File ini) throws CorruptedIdeLocationException { + return new RhdsLocation(name, ini); + } + + @Override protected String getMacAppName() { + return "devstudio.app"; + } + + @Override protected String getUnixAppName() { + return "devstudio"; + } + + @Override public Pattern getLocationSelectors(OS os) { + switch (os) { + case MAC_OS_X: + return Pattern.compile("^(devstudio|devstudio\\.ini|devstudio\\.app)$", Pattern.CASE_INSENSITIVE); + case WINDOWS: + return Pattern.compile("^(devstudioc?\\.exe|devstudio\\.ini)$", Pattern.CASE_INSENSITIVE); + default: + case UNIX: + return Pattern.compile("^(devstudio|devstudio\\.ini)$", Pattern.CASE_INSENSITIVE); + } + } +} diff --git a/src/installer/lombok/installer/eclipse/rhds.png b/src/installer/lombok/installer/eclipse/rhds.png Binary files differnew file mode 100644 index 00000000..ca7738e6 --- /dev/null +++ b/src/installer/lombok/installer/eclipse/rhds.png diff --git a/test/transform/resource/after-delombok/ValFinal.java b/test/transform/resource/after-delombok/ValFinal.java new file mode 100644 index 00000000..d35ca713 --- /dev/null +++ b/test/transform/resource/after-delombok/ValFinal.java @@ -0,0 +1,5 @@ +public class ValFinal { + public void test() { + final int x = 10; + } +}
\ No newline at end of file diff --git a/test/transform/resource/after-delombok/ValInLambda.java b/test/transform/resource/after-delombok/ValInLambda.java new file mode 100644 index 00000000..7ce1e1b4 --- /dev/null +++ b/test/transform/resource/after-delombok/ValInLambda.java @@ -0,0 +1,18 @@ +// version 8: +class ValInLambda { + Runnable foo = (Runnable) () -> { + final int i = 1; + }; + + public void easyLambda() { + Runnable foo = (Runnable) () -> { + final int i = 1; + }; + } + + public void easyIntersectionLambda() { + Runnable foo = (Runnable) () -> { + final int i = 1; + }; + } +} diff --git a/test/transform/resource/after-ecj/ValFinal.java b/test/transform/resource/after-ecj/ValFinal.java new file mode 100644 index 00000000..d7cf9cb7 --- /dev/null +++ b/test/transform/resource/after-ecj/ValFinal.java @@ -0,0 +1,9 @@ +import lombok.val; +public class ValFinal { + public ValFinal() { + super(); + } + public void test() { + final @val int x = 10; + } +} diff --git a/test/transform/resource/after-ecj/ValInLambda.java b/test/transform/resource/after-ecj/ValInLambda.java new file mode 100644 index 00000000..7669789b --- /dev/null +++ b/test/transform/resource/after-ecj/ValInLambda.java @@ -0,0 +1,21 @@ +// version 8: + +import lombok.val; +class ValInLambda { + Runnable foo = (Runnable) () -> { + final @val int i = 1; +}; + ValInLambda() { + super(); + } + public void easyLambda() { + Runnable foo = (Runnable) () -> { + final @val int i = 1; +}; + } + public void easyIntersectionLambda() { + Runnable foo = (Runnable) () -> { + final @val int i = 1; +}; + } +} diff --git a/test/transform/resource/before/ValFinal.java b/test/transform/resource/before/ValFinal.java new file mode 100644 index 00000000..3c5af366 --- /dev/null +++ b/test/transform/resource/before/ValFinal.java @@ -0,0 +1,6 @@ +import lombok.val; +public class ValFinal { + public void test() { + final val x = 10; + } +}
\ No newline at end of file diff --git a/test/transform/resource/before/ValInLambda.java b/test/transform/resource/before/ValInLambda.java new file mode 100644 index 00000000..2c2a5942 --- /dev/null +++ b/test/transform/resource/before/ValInLambda.java @@ -0,0 +1,21 @@ +// version 8: + +import lombok.val; + +class ValInLambda { + Runnable foo = (Runnable) () -> { + val i = 1; + }; + + public void easyLambda() { + Runnable foo = (Runnable) () -> { + val i = 1; + }; + } + + public void easyIntersectionLambda() { + Runnable foo = (Runnable) () -> { + val i = 1; + }; + } +} |