diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt index cb8559352b..062d5dc597 100644 --- a/pmd-java/etc/grammar/Java.jjt +++ b/pmd-java/etc/grammar/Java.jjt @@ -1,6 +1,7 @@ /** * Remove support for Java 13 preview language features. * Promote text blocks as a permanent language features with Java 15. + * Support Pattern Matching for instanceof with Java 15 Preview. * Andreas Dangel 08/2020 *==================================================================== * Add support for record types introduced as a preview language @@ -372,8 +373,8 @@ public class JavaParser { } private void checkforBadInstanceOfPattern() { - if (jdkVersion != 14 || !preview) { - throwParseException("Cannot use type test patterns in instanceof when running in JDK other than 14-preview"); + if (jdkVersion != 14 && jdkVersion != 15 || !preview) { + throwParseException("Pattern Matching for instanceof is only supported with Java 14 Preview and Java 15 Preview"); } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java15PreviewTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java15PreviewTest.java new file mode 100644 index 0000000000..9b6086c187 --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java15PreviewTest.java @@ -0,0 +1,45 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import net.sourceforge.pmd.lang.ast.ParseException; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; + +public class Java15PreviewTest { + private final JavaParsingHelper java15p = + JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("15-preview") + .withResourceContext(Java15PreviewTest.class, "jdkversiontests/java15p/"); + + private final JavaParsingHelper java15 = java15p.withDefaultVersion("15"); + + @Test + public void patternMatchingInstanceof() { + ASTCompilationUnit compilationUnit = java15p.parseResource("PatternMatchingInstanceof.java"); + List instanceOfExpressions = compilationUnit.findDescendantsOfType(ASTInstanceOfExpression.class); + Assert.assertEquals(4, instanceOfExpressions.size()); + for (ASTInstanceOfExpression expr : instanceOfExpressions) { + Assert.assertTrue(expr.getChild(1) instanceof ASTTypeTestPattern); + ASTVariableDeclaratorId variable = expr.getChild(1).getFirstChildOfType(ASTVariableDeclaratorId.class); + Assert.assertEquals(String.class, variable.getType()); + Assert.assertEquals("s", variable.getVariableName()); + Assert.assertTrue(variable.isPatternBinding()); + Assert.assertTrue(variable.isFinal()); + // Note: these variables are not part of the symbol table + // See ScopeAndDeclarationFinder#visit(ASTVariableDeclaratorId, Object) + Assert.assertNull(variable.getNameDeclaration()); + } + } + + @Test(expected = ParseException.class) + public void patternMatchingInstanceofBeforeJava15PreviewShouldFail() { + java15.parseResource("PatternMatchingInstanceof.java"); + } + +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/PatternMatchingInstanceof.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/PatternMatchingInstanceof.java new file mode 100644 index 0000000000..c541b5c8c0 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/PatternMatchingInstanceof.java @@ -0,0 +1,34 @@ +/** + * + * @see JEP 375: Pattern Matching for instanceof (Second Preview) + */ +public class PatternMatchingInstanceof { + private String s = "other string"; + + public void test() { + Object obj = "abc"; + //obj = 1; + if (obj instanceof String s) { + System.out.println("a) obj == s: " + (obj == s)); // true + } else { + System.out.println("b) obj == s: " + (obj == s)); // false + } + + if (!(obj instanceof String s)) { + System.out.println("c) obj == s: " + (obj == s)); // false + } else { + System.out.println("d) obj == s: " + (obj == s)); // true + } + + if (obj instanceof String s && s.length() > 2) { + System.out.println("e) obj == s: " + (obj == s)); // true + } + if (obj instanceof String s || s.length() > 5) { + System.out.println("f) obj == s: " + (obj == s)); // false + } + } + + public static void main(String[] args) { + new PatternMatchingInstanceof().test(); + } +} \ No newline at end of file