[java] Disallow local sealed/non-sealed classes

This is apparently not valid.
This commit is contained in:
Andreas Dangel
2021-07-30 11:06:51 +02:00
parent d641b3a506
commit 30124628f7
4 changed files with 61 additions and 5 deletions

View File

@ -619,7 +619,7 @@ public class JavaParser {
return false;
}
private boolean classModifierLookahead() {
private boolean classModifierForLocalTypesLookahead() {
Token next = getToken(1);
return next.kind == AT
|| next.kind == PUBLIC
@ -628,9 +628,7 @@ public class JavaParser {
|| next.kind == ABSTRACT
|| next.kind == STATIC
|| next.kind == FINAL
|| next.kind == STRICTFP
|| isSealedClassSupported() && isKeyword("sealed")
|| isSealedClassSupported() && isNonSealedModifier();
|| next.kind == STRICTFP;
}
private boolean localTypeDeclLookahead() {
@ -2144,7 +2142,7 @@ void BlockStatement():
}
";"
)
| LOOKAHEAD({classModifierLookahead() || localTypeDeclLookahead()})
| LOOKAHEAD({classModifierForLocalTypesLookahead() || localTypeDeclLookahead()})
mods=Modifiers()
LocalTypeDecl(mods)
| LOOKAHEAD(Type() <IDENTIFIER>)

View File

@ -72,4 +72,8 @@ public class Java17TreeDumpTest extends BaseTreeDumpTest {
java17p.parseResource("expression/Expr.java"); // make sure we can parse it with preview as well
}
@Test
public void localVars() {
doTest("LocalVars");
}
}

View File

@ -0,0 +1,15 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
public class LocalVars {
public void aMethod() {
String sealed = null;
sealed = this.getClass().getName();
// error: sealed or non-sealed local classes are not allowed
// sealed class LocalSealedClass {}
}
}

View File

@ -0,0 +1,39 @@
+- CompilationUnit[@PackageName = "", @declarationsAreInDefaultPackage = true]
+- TypeDeclaration[]
+- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "LocalVars", @Default = false, @Final = false, @Image = "LocalVars", @Interface = false, @Local = false, @Modifiers = 1, @Native = false, @Nested = false, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = false, @SimpleName = "LocalVars", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.CLASS, @Volatile = false]
+- ClassOrInterfaceBody[@AnonymousInnerClass = false, @EnumChild = false]
+- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.METHOD]
+- MethodDeclaration[@Abstract = false, @Arity = 0, @Default = false, @Final = false, @InterfaceMember = false, @Kind = MethodLikeKind.METHOD, @MethodName = "aMethod", @Modifiers = 1, @Name = "aMethod", @Native = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Static = false, @Strictfp = false, @Synchronized = false, @SyntacticallyAbstract = false, @SyntacticallyPublic = true, @Transient = false, @Void = true, @Volatile = false]
+- ResultType[@Void = true, @returnsArray = false]
+- MethodDeclarator[@Image = "aMethod", @ParameterCount = 0]
| +- FormalParameters[@ParameterCount = 0, @Size = 0]
+- Block[@containsComment = true]
+- BlockStatement[@Allocation = false]
| +- LocalVariableDeclaration[@Abstract = false, @Array = false, @ArrayDepth = 0, @Default = false, @Final = false, @Modifiers = 0, @Native = false, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeInferred = false, @VariableName = "sealed", @Volatile = false]
| +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "String"]
| | +- ReferenceType[@Array = false, @ArrayDepth = 0]
| | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "String", @ReferenceToClassSameCompilationUnit = false]
| +- VariableDeclarator[@Initializer = true, @Name = "sealed"]
| +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @ForeachVariable = false, @FormalParameter = false, @Image = "sealed", @LambdaParameter = false, @LocalVariable = true, @Name = "sealed", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "sealed"]
| +- VariableInitializer[]
| +- Expression[@StandAlonePrimitive = false]
| +- PrimaryExpression[]
| +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = null, @FloatLiteral = false, @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = false, @TextBlock = false, @TextBlockContent = null, @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0]
| +- NullLiteral[]
+- BlockStatement[@Allocation = false]
+- Statement[]
+- StatementExpression[]
+- PrimaryExpression[]
| +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| +- Name[@Image = "sealed"]
+- AssignmentOperator[@Compound = false, @Image = "="]
+- Expression[@StandAlonePrimitive = false]
+- PrimaryExpression[]
+- PrimaryPrefix[@SuperModifier = false, @ThisModifier = true]
+- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @Image = "getClass"]
+- PrimarySuffix[@ArgumentCount = 0, @Arguments = true, @ArrayDereference = false]
| +- Arguments[@ArgumentCount = 0, @Size = 0]
+- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @Image = "getName"]
+- PrimarySuffix[@ArgumentCount = 0, @Arguments = true, @ArrayDereference = false]
+- Arguments[@ArgumentCount = 0, @Size = 0]