[java] Promote "JEP 409: Sealed Classes" for Java 17

"JEP 409: Sealed Classes" is now a permanent language
feature with Java 17.
This commit is contained in:
Andreas Dangel
2021-07-01 10:39:49 +02:00
parent d0683b7903
commit 5209a1280d
17 changed files with 205 additions and 7 deletions

View File

@ -1,4 +1,7 @@
/**
* Promote "JEP 409: Sealed Classes" as permanent language feature with Java 17.
* Andreas Dangel 07/2021
*====================================================================
* Fix #3117 - infinite loop when parsing invalid code nested in lambdas
* Andreas Dangel 03/2021
*====================================================================
@ -446,11 +449,11 @@ public class JavaParser {
if ((jdkVersion == 15 && preview || jdkVersion >= 16) && "record".equals(image)) {
throwParseException("With JDK 15 Preview and Java >= 16, 'record' is a contextual keyword and cannot be used for type declarations!");
}
if ((jdkVersion == 15 && preview || jdkVersion == 16 && preview) && "sealed".equals(image)) {
throwParseException("With JDK 15 Preview and JDK 16 Preview, 'sealed' is a contextual keyword and cannot be used for type declarations!");
if ((jdkVersion == 15 && preview || jdkVersion == 16 && preview || jdkVersion >= 17) && "sealed".equals(image)) {
throwParseException("With JDK 15 Preview and JDK 16 Preview and JDK >= 17, 'sealed' is a contextual keyword and cannot be used for type declarations!");
}
if ((jdkVersion == 15 && preview || jdkVersion == 16 && preview) && "permits".equals(image)) {
throwParseException("With JDK 15 Preview and JDK 16 Preview, 'permits' is a contextual keyword and cannot be used for type declarations!");
if ((jdkVersion == 15 && preview || jdkVersion == 16 && preview || jdkVersion >= 17) && "permits".equals(image)) {
throwParseException("With JDK 15 Preview and JDK 16 Preview and JDK >= 17, 'permits' is a contextual keyword and cannot be used for type declarations!");
}
}
private void checkForMultipleCaseLabels() {
@ -514,12 +517,12 @@ public class JavaParser {
}
private boolean isSealedClassSupported() {
return jdkVersion == 15 && preview || jdkVersion == 16 && preview;
return jdkVersion == 15 && preview || jdkVersion == 16 && preview || jdkVersion >= 17;
}
private void checkForSealedClassUsage() {
if (!isSealedClassSupported()) {
throwParseException("Sealed Classes are only supported with Java 15 Preview");
throwParseException("Sealed Classes are only supported with JDK 15 Preview, JDK 16 Preview and JDK >= 17.");
}
}

View File

@ -18,7 +18,7 @@ import net.sourceforge.pmd.lang.java.JavaParsingHelper;
public class Java16TreeDumpTest extends BaseTreeDumpTest {
private final JavaParsingHelper java16 =
JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("16")
.withResourceContext(Java15TreeDumpTest.class, "jdkversiontests/java16/");
.withResourceContext(Java16TreeDumpTest.class, "jdkversiontests/java16/");
private final JavaParsingHelper java16p = java16.withDefaultVersion("16-preview");
private final JavaParsingHelper java15 = java16.withDefaultVersion("15");

View File

@ -0,0 +1,59 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.ast;
import org.junit.Test;
import net.sourceforge.pmd.lang.ast.ParseException;
import net.sourceforge.pmd.lang.ast.test.BaseParsingHelper;
import net.sourceforge.pmd.lang.ast.test.BaseTreeDumpTest;
import net.sourceforge.pmd.lang.ast.test.RelevantAttributePrinter;
import net.sourceforge.pmd.lang.java.JavaParsingHelper;
public class Java17TreeDumpTest extends BaseTreeDumpTest {
private final JavaParsingHelper java17 =
JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("17")
.withResourceContext(Java17TreeDumpTest.class, "jdkversiontests/java17/");
private final JavaParsingHelper java17p = java17.withDefaultVersion("17-preview");
private final JavaParsingHelper java16 = java17.withDefaultVersion("16");
public Java17TreeDumpTest() {
super(new RelevantAttributePrinter(), ".java");
}
@Override
public BaseParsingHelper<?, ?> getParser() {
return java17;
}
@Test(expected = ParseException.class)
public void sealedClassBeforeJava17() {
java16.parseResource("geometry/Shape.java");
}
@Test
public void sealedClass() {
doTest("geometry/Shape");
java17p.parseResource("geometry/Shape.java"); // make sure we can parse it with preview as well
}
@Test
public void nonSealedClass() {
doTest("geometry/Square");
java17p.parseResource("geometry/Square.java"); // make sure we can parse it with preview as well
}
@Test(expected = ParseException.class)
public void sealedInterfaceBeforeJava17() {
java16.parseResource("expression/Expr.java");
}
@Test
public void sealedInterface() {
doTest("expression/Expr");
java17p.parseResource("expression/Expr.java"); // make sure we can parse it with preview as well
}
}

View File

@ -0,0 +1,9 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package com.example.expression;
/**
* @see <a href="https://openjdk.java.net/jeps/409">JEP 409: Sealed Classes</a>
*/
public final class ConstantExpr implements Expr { }

View File

@ -0,0 +1,10 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package com.example.expression;
/**
* @see <a href="https://openjdk.java.net/jeps/409">JEP 409: Sealed Classes</a>
*/
public sealed interface Expr
permits ConstantExpr, PlusExpr, TimesExpr, NegExpr { }

View File

@ -0,0 +1,11 @@
+- CompilationUnit[@PackageName = "com.example.expression", @declarationsAreInDefaultPackage = false]
+- PackageDeclaration[@Name = "com.example.expression", @PackageNameImage = "com.example.expression"]
| +- Name[@Image = "com.example.expression"]
+- TypeDeclaration[]
+- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "com.example.expression.Expr", @Default = false, @Final = false, @Image = "Expr", @Interface = true, @Local = false, @Modifiers = 16385, @Native = false, @Nested = false, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = true, @SimpleName = "Expr", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.INTERFACE, @Volatile = false]
+- PermitsList[]
| +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "ConstantExpr", @ReferenceToClassSameCompilationUnit = false]
| +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "PlusExpr", @ReferenceToClassSameCompilationUnit = false]
| +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "TimesExpr", @ReferenceToClassSameCompilationUnit = false]
| +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "NegExpr", @ReferenceToClassSameCompilationUnit = false]
+- ClassOrInterfaceBody[@AnonymousInnerClass = false, @EnumChild = false]

View File

@ -0,0 +1,9 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package com.example.expression;
/**
* @see <a href="https://openjdk.java.net/jeps/409">JEP 409: Sealed Classes</a>
*/
public final class NegExpr implements Expr { }

View File

@ -0,0 +1,9 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package com.example.expression;
/**
* @see <a href="https://openjdk.java.net/jeps/409">JEP 409: Sealed Classes</a>
*/
public final class PlusExpr implements Expr { }

View File

@ -0,0 +1,9 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package com.example.expression;
/**
* @see <a href="https://openjdk.java.net/jeps/409">JEP 409: Sealed Classes</a>
*/
public final class TimesExpr implements Expr { }

View File

@ -0,0 +1,9 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package com.example.geometry;
/**
* @see <a href="https://openjdk.java.net/jeps/409">JEP 409: Sealed Classes</a>
*/
public final class Circle extends Shape { }

View File

@ -0,0 +1,10 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package com.example.geometry;
/**
* @see <a href="https://openjdk.java.net/jeps/409">JEP 409: Sealed Classes</a>
*/
public final class FilledRectangle extends Rectangle { }

View File

@ -0,0 +1,11 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package com.example.geometry;
/**
* @see <a href="https://openjdk.java.net/jeps/409">JEP 409: Sealed Classes</a>
*/
public sealed class Rectangle extends Shape
permits TransparentRectangle, FilledRectangle { }

View File

@ -0,0 +1,11 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package com.example.geometry;
/**
* @see <a href="https://openjdk.java.net/jeps/409">JEP 409: Sealed Classes</a>
*/
public sealed class Shape
permits Circle, Rectangle, Square { }

View File

@ -0,0 +1,10 @@
+- CompilationUnit[@PackageName = "com.example.geometry", @declarationsAreInDefaultPackage = false]
+- PackageDeclaration[@Name = "com.example.geometry", @PackageNameImage = "com.example.geometry"]
| +- Name[@Image = "com.example.geometry"]
+- TypeDeclaration[]
+- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "com.example.geometry.Shape", @Default = false, @Final = false, @Image = "Shape", @Interface = false, @Local = false, @Modifiers = 16385, @Native = false, @Nested = false, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = true, @SimpleName = "Shape", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.CLASS, @Volatile = false]
+- PermitsList[]
| +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Circle", @ReferenceToClassSameCompilationUnit = false]
| +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Rectangle", @ReferenceToClassSameCompilationUnit = false]
| +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Square", @ReferenceToClassSameCompilationUnit = false]
+- ClassOrInterfaceBody[@AnonymousInnerClass = false, @EnumChild = false]

View File

@ -0,0 +1,10 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package com.example.geometry;
/**
* @see <a href="https://openjdk.java.net/jeps/409">JEP 409: Sealed Classes</a>
*/
public non-sealed class Square extends Shape { }

View File

@ -0,0 +1,8 @@
+- CompilationUnit[@PackageName = "com.example.geometry", @declarationsAreInDefaultPackage = false]
+- PackageDeclaration[@Name = "com.example.geometry", @PackageNameImage = "com.example.geometry"]
| +- Name[@Image = "com.example.geometry"]
+- TypeDeclaration[]
+- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "com.example.geometry.Square", @Default = false, @Final = false, @Image = "Square", @Interface = false, @Local = false, @Modifiers = 32769, @Native = false, @Nested = false, @NonSealed = true, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = false, @SimpleName = "Square", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.CLASS, @Volatile = false]
+- ExtendsList[]
| +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Shape", @ReferenceToClassSameCompilationUnit = false]
+- ClassOrInterfaceBody[@AnonymousInnerClass = false, @EnumChild = false]

View File

@ -0,0 +1,10 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package com.example.geometry;
/**
* @see <a href="https://openjdk.java.net/jeps/409">JEP 409: Sealed Classes</a>
*/
public final class TransparentRectangle extends Rectangle { }