From 0939d4e1fc4d2aabb3b83e54fddc5bdccd0a2ad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sat, 25 May 2019 03:09:23 +0200 Subject: [PATCH] Fix some corner cases found in jdk12 sources --- pmd-java/etc/grammar/Java.jjt | 9 ++++----- .../pmd/lang/java/ast/BinaryOp.java | 2 ++ .../ASTExplicitConstructorInvocationTest.kt | 18 ++++++++++++++++++ .../pmd/lang/java/ast/ASTMethodCallTest.kt | 2 +- .../lang/java/ast/ASTMethodReferenceTest.kt | 17 +++++++++++++++++ .../lang/java/ast/ASTShiftExpressionTest.kt | 13 +++++++++++++ 6 files changed, 55 insertions(+), 6 deletions(-) diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt index 6ff9549cee..3cc1fb5df9 100644 --- a/pmd-java/etc/grammar/Java.jjt +++ b/pmd-java/etc/grammar/Java.jjt @@ -2521,14 +2521,13 @@ void PrimaryPrefix() #void : // This describes the cases where the PrimaryPrefix may fall // into PrimaryStep2. Notice that type arguments is still possible, // as well as annotations ("@") before an annotated array type. -// If we are in an explicit constructor invocation, then super or -// this are disallowed. +// If we are in an explicit constructor invocation, then super is disallowed. private void Step2Lahead() #void: {} { "::" | "(" | "@" | "[" | TypeArguments() | LOOKAHEAD({!inExplicitConstructorInvoc}) "." - | LOOKAHEAD({inExplicitConstructorInvoc}) "." ("class" | | TypeArguments() | "new") // not super or this in this case + | LOOKAHEAD({inExplicitConstructorInvoc}) "." ("class" | | TypeArguments() | "new" | "this") // not super in this case } private void SuffixLAhead() #void: @@ -2548,8 +2547,8 @@ private void SuffixLAhead() #void: void PrimaryStep2() #void: {} { - // Can't be followed by array dims, because it would raise an error for generic array creation - {forceTypeContext();} TypeArguments() {injectTop();} ( "." ClassTypeSegment() )* MethodReference() + // If the class is a parameterised type, then we can only expect a method reference + {forceTypeContext();} TypeArguments() {injectTop();} ( "." ClassTypeSegment() )* [ Dims() #ArrayType(2) ] MethodReference() | MethodReference() | ArgumentList() #MethodCall(2) | "." ( diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/BinaryOp.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/BinaryOp.java index 810edf121c..761ccbecc7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/BinaryOp.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/BinaryOp.java @@ -41,7 +41,9 @@ public enum BinaryOp { // shift LEFT_SHIFT("<<"), + /** Token {@code >> } */ RIGHT_SHIFT(">>"), + /** Token {@code >>>} */ UNSIGNED_RIGHT_SHIFT(">>>"), // additive diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTExplicitConstructorInvocationTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTExplicitConstructorInvocationTest.kt index b2e505f51d..35855f846b 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTExplicitConstructorInvocationTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTExplicitConstructorInvocationTest.kt @@ -147,6 +147,24 @@ class ASTExplicitConstructorInvocationTest : ParserTestSpec({ } } + "public TabbedPaneLayout() { MetalTabbedPaneUI.this.super(); }" should matchDeclaration { + + child { } + + child { + it::isThis shouldBe false + it::isSuper shouldBe true + it::isQualified shouldBe true + it::getExplicitTypeArguments shouldBe null + it::getArgumentCount shouldBe 0 + + it::getLhsExpression shouldBe child(ignoreChildren = true) { } + + + it::getArgumentsList shouldBe child { } + } + } + // An explicit constructor invocation statement in a constructor body may not refer to any instance // variables or instance methods or inner classes declared in this class or any superclass, or use // this or super in any expression; otherwise, a compile-time error occurs. diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodCallTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodCallTest.kt index 8067613a59..a017bb06fa 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodCallTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodCallTest.kt @@ -78,7 +78,7 @@ class ASTMethodCallTest : ParserTestSpec({ child(ignoreChildren = true) {} } } - + "foo.bar(foo::bar).foreach(System.out::println)" should matchExpr { it::getMethodName shouldBe "foreach" diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodReferenceTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodReferenceTest.kt index 246878b0ea..152f4d069b 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodReferenceTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTMethodReferenceTest.kt @@ -165,6 +165,23 @@ class ASTMethodReferenceTest : ParserTestSpec({ } } + "Class[]::new" should parseAs { + constructorRef { + it::getTypeArguments shouldBe null + + arrayType { + classType("Class") { + typeArgList { + child { } + } + } + it::getDimensions shouldBe child { + arrayDim() + } + } + } + } + "ArrayList::new" should parseAs { constructorRef { val lhs = classType("ArrayList") diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTShiftExpressionTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTShiftExpressionTest.kt index 186c72b087..5b0d392835 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTShiftExpressionTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTShiftExpressionTest.kt @@ -36,6 +36,19 @@ class ASTShiftExpressionTest : ParserTestSpec({ child {} } + "i < width >> 1" should matchExpr { + it::getOp shouldBe BinaryOp.LE + + variableRef("i") + + child { + it::getOp shouldBe BinaryOp.RIGHT_SHIFT + + variableRef("width") + int(1) + } + } + } parserTest("Changing operators should push a new node") {