Merge branch 'pr-2272' into java-grammar
[java] Make enum body track trailing comma/semi
This commit is contained in:
@ -912,9 +912,9 @@ void EnumBody():
|
||||
{}
|
||||
{
|
||||
"{"
|
||||
[ EnumConstant() ( LOOKAHEAD(2) "," EnumConstant() )* ]
|
||||
[ "," ]
|
||||
[ ";" ( ClassOrInterfaceBodyDeclaration() )* ]
|
||||
[ EnumConstant() ( LOOKAHEAD(2) "," EnumConstant() )* ]
|
||||
[ "," { jjtThis.setTrailingComma(); } ]
|
||||
[ ";" { jjtThis.setSeparatorSemi(); } ( ClassOrInterfaceBodyDeclaration() )* ]
|
||||
"}"
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* EnumBody ::= "{"
|
||||
* [( {@link ASTAnnotation Annotation} )* {@link ASTEnumConstant EnumConstant} ( "," ( {@link ASTAnnotation Annotation} )* {@link ASTEnumConstant EnumConstant} )* ]
|
||||
* [ {@link ASTEnumConstant EnumConstant} ( "," ( {@link ASTEnumConstant EnumConstant} )* ]
|
||||
* [ "," ]
|
||||
* [ ";" ( {@link ASTClassOrInterfaceBodyDeclaration ClassOrInterfaceBodyDeclaration} )* ]
|
||||
* "}"
|
||||
@ -21,6 +21,9 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
*/
|
||||
public final class ASTEnumBody extends AbstractJavaNode implements ASTTypeBody {
|
||||
|
||||
private boolean trailingComma;
|
||||
private boolean separatorSemi;
|
||||
|
||||
ASTEnumBody(int id) {
|
||||
super(id);
|
||||
}
|
||||
@ -35,4 +38,43 @@ public final class ASTEnumBody extends AbstractJavaNode implements ASTTypeBody {
|
||||
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
|
||||
visitor.visit(this, data);
|
||||
}
|
||||
|
||||
void setTrailingComma() {
|
||||
this.trailingComma = true;
|
||||
}
|
||||
|
||||
void setSeparatorSemi() {
|
||||
this.separatorSemi = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the last enum constant has a trailing comma.
|
||||
* For example:
|
||||
* <pre>{@code
|
||||
* enum Foo { A, B, C, }
|
||||
* enum Bar { , }
|
||||
* }</pre>
|
||||
*/
|
||||
public boolean hasTrailingComma() {
|
||||
return trailingComma;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the last enum constant has a trailing semi-colon.
|
||||
* This semi is not optional when the enum has other members.
|
||||
* For example:
|
||||
* <pre>{@code
|
||||
* enum Foo {
|
||||
* A(2);
|
||||
*
|
||||
* Foo(int i) {...}
|
||||
* }
|
||||
*
|
||||
* enum Bar { A; }
|
||||
* enum Baz { ; }
|
||||
* }</pre>
|
||||
*/
|
||||
public boolean hasSeparatorSemi() {
|
||||
return separatorSemi;
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,75 @@ class ASTEnumConstantTest : ParserTestSpec({
|
||||
}
|
||||
|
||||
|
||||
parserTest("Corner cases with separators") {
|
||||
|
||||
inContext(TopLevelTypeDeclarationParsingCtx) {
|
||||
|
||||
|
||||
"enum Foo { A, }" should parseAs {
|
||||
|
||||
enumDecl("Foo") {
|
||||
modifiers { }
|
||||
enumBody {
|
||||
it::hasTrailingComma shouldBe true
|
||||
enumConstant("A")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"enum Foo { , }" should parseAs {
|
||||
|
||||
enumDecl("Foo") {
|
||||
modifiers { }
|
||||
|
||||
enumBody {
|
||||
it::hasTrailingComma shouldBe true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"enum Foo { ,; }" should parseAs {
|
||||
|
||||
enumDecl("Foo") {
|
||||
modifiers { }
|
||||
enumBody {
|
||||
it::hasTrailingComma shouldBe true
|
||||
it::hasSeparatorSemi shouldBe true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"enum Foo { ,, }" shouldNot parse()
|
||||
|
||||
"enum Foo { ; }" should parseAs {
|
||||
|
||||
enumDecl("Foo") {
|
||||
modifiers { }
|
||||
enumBody {
|
||||
it::hasTrailingComma shouldBe false
|
||||
it::hasSeparatorSemi shouldBe true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"enum Foo { ;; }" should parseAs {
|
||||
|
||||
enumDecl("Foo") {
|
||||
modifiers { }
|
||||
|
||||
enumBody {
|
||||
it::hasTrailingComma shouldBe false
|
||||
it::hasSeparatorSemi shouldBe true
|
||||
child<ASTClassOrInterfaceBodyDeclaration> {
|
||||
child<ASTEmptyDeclaration> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
parserTest("Enum constants should have an anonymous class node") {
|
||||
|
||||
inContext(TopLevelTypeDeclarationParsingCtx) {
|
||||
@ -96,7 +165,6 @@ class ASTEnumConstantTest : ParserTestSpec({
|
||||
it::getModifiers shouldBe modifiers {}
|
||||
|
||||
enumBody {
|
||||
|
||||
enumConstant("B") {
|
||||
|
||||
val c = it
|
||||
@ -160,6 +228,7 @@ class ASTEnumConstantTest : ParserTestSpec({
|
||||
}
|
||||
|
||||
it::getAnonymousClass shouldBe null
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,6 @@ fun TreeNodeWrapper<Node, *>.enumDecl(name: String, spec: NodeSpec<ASTEnumDeclar
|
||||
spec()
|
||||
}
|
||||
|
||||
|
||||
fun TreeNodeWrapper<Node, *>.enumBody(contents: NodeSpec<ASTEnumBody> = EmptyAssertions) =
|
||||
child<ASTEnumBody> {
|
||||
contents()
|
||||
|
Reference in New Issue
Block a user