From 3c1b0afcf6eb71ffd543d95cedead3acdedc9e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Wed, 16 Sep 2020 15:40:45 +0200 Subject: [PATCH 1/2] Fix #2783 --- pmd-java/etc/grammar/Java.jjt | 16 ++++++++-- .../pmd/lang/java/ast/ParserCornersTest.java | 5 +++ .../pmd/lang/java/ast/LambdaBug2783.java | 31 +++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug2783.java diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt index 0962322888..7fc17b1edf 100644 --- a/pmd-java/etc/grammar/Java.jjt +++ b/pmd-java/etc/grammar/Java.jjt @@ -1754,11 +1754,23 @@ void UnaryExpressionNotPlusMinus() #UnaryExpressionNotPlusMinus((jjtn000.getImag * meaning we can't be explicit as to what can be casted depending on the cast type (primitive or otherwise) */ | LOOKAHEAD("(" (Annotation())* PrimitiveType() ")") CastExpression() -| LOOKAHEAD("(" (Annotation())* Type() ( "&" ReferenceType() )* ")" UnaryExpressionNotPlusMinus()) CastExpression() -| PostfixExpression() +| LOOKAHEAD("(" (Annotation())* Type() ( "&" ReferenceType() )* ")" UnaryExprNotPmStart()) CastExpression() +| PostfixExpression() // this may be a parenthesized expr, which is why we have lookaheads | SwitchExpression() } + +private void UnaryExprNotPmStart() #void: +{} +{ + // Condensed FIRST set of UnaryExpressionNotPlusMinus + // Avoid looking ahead for a whole UnaryExpressionNotPlusMinus, but just for a token + + "~" | "!" | "(" | "switch" | "new" | "this" | "super" | Literal() | "@" + | + | "void" | PrimitiveType() +} + void PostfixExpression() #PostfixExpression((jjtn000.getImage() != null)): {} { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java index 4af25e38db..eab5faaaf4 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/ParserCornersTest.java @@ -177,6 +177,11 @@ public class ParserCornersTest { java8.parseResource("GitHubBug207.java"); } + @Test + public void testLambda2783() { + java8.parseResource("LambdaBug2783.java"); + } + @Test public void testGitHubBug2767() { // PMD fails to parse an initializer block. diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug2783.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug2783.java new file mode 100644 index 0000000000..425e262c28 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/LambdaBug2783.java @@ -0,0 +1,31 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +import java.util.List; + +public class LambdaBug2783 { + // https://github.com/pmd/pmd/issues/2783 + + public Spec test() { + // cast, block body (the failing case) + Spec result = (Spec) (a, b) -> { + return a.toArray(String[]::new); + }; + // no cast, block body + result = (a, b) -> { + return a.toArray(String[]::new); + }; + // cast, expression body + result = (Spec) (a, b) -> a.toArray(String[]::new); + + // return position? + return (Spec) (a, b) -> { + return a.toArray(String[]::new); + }; + } + + interface Spec { + String[] process(List var1, List var2); + } +} From d81731ed6c97ab3912a9f8f57d2b1291a1ed6b05 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 17 Sep 2020 14:57:55 +0200 Subject: [PATCH 2/2] [doc] Update release notes, refs #2784, fixes #2783 --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 5d8124da48..2fa8a74515 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -35,6 +35,7 @@ AbstractTokenizer and the custom tokenizers of Fortran, Perl and Ruby are deprec * [#2756](https://github.com/pmd/pmd/issues/2756): \[java] TypeTestUtil fails with NPE for anonymous class * [#2759](https://github.com/pmd/pmd/issues/2759): \[java] False positive in UnusedAssignment * [#2767](https://github.com/pmd/pmd/issues/2767): \[java] IndexOutOfBoundsException when parsing an initializer BlockStatement + * [#2783](https://github.com/pmd/pmd/issues/2783): \[java] Error while parsing with lambda of custom interface ### API Changes