Make enum body track trailing comma/semi
This commit is contained in:
@ -924,8 +924,8 @@ void EnumBody():
|
|||||||
{
|
{
|
||||||
"{"
|
"{"
|
||||||
[ EnumConstant() ( LOOKAHEAD(2) "," EnumConstant() )* ]
|
[ EnumConstant() ( LOOKAHEAD(2) "," EnumConstant() )* ]
|
||||||
[ "," ]
|
[ "," { jjtThis.setTrailingComma(); } ]
|
||||||
[ ";" ( ClassOrInterfaceBodyDeclaration() )* ]
|
[ ";" { jjtThis.setSeparatorSemi(); } ( ClassOrInterfaceBodyDeclaration() )* ]
|
||||||
"}"
|
"}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ package net.sourceforge.pmd.lang.java.ast;
|
|||||||
* <pre class="grammar">
|
* <pre class="grammar">
|
||||||
*
|
*
|
||||||
* EnumBody ::= "{"
|
* EnumBody ::= "{"
|
||||||
* [( {@link ASTAnnotation Annotation} )* {@link ASTEnumConstant EnumConstant} ( "," ( {@link ASTAnnotation Annotation} )* {@link ASTEnumConstant EnumConstant} )* ]
|
* [ {@link ASTEnumConstant EnumConstant} ( "," ( {@link ASTEnumConstant EnumConstant} )* ]
|
||||||
* [ "," ]
|
* [ "," ]
|
||||||
* [ ";" ( {@link ASTClassOrInterfaceBodyDeclaration ClassOrInterfaceBodyDeclaration} )* ]
|
* [ ";" ( {@link ASTClassOrInterfaceBodyDeclaration ClassOrInterfaceBodyDeclaration} )* ]
|
||||||
* "}"
|
* "}"
|
||||||
@ -21,6 +21,9 @@ package net.sourceforge.pmd.lang.java.ast;
|
|||||||
*/
|
*/
|
||||||
public final class ASTEnumBody extends AbstractJavaNode implements ASTTypeBody {
|
public final class ASTEnumBody extends AbstractJavaNode implements ASTTypeBody {
|
||||||
|
|
||||||
|
private boolean trailingComma;
|
||||||
|
private boolean separatorSemi;
|
||||||
|
|
||||||
ASTEnumBody(int id) {
|
ASTEnumBody(int id) {
|
||||||
super(id);
|
super(id);
|
||||||
}
|
}
|
||||||
@ -35,4 +38,43 @@ public final class ASTEnumBody extends AbstractJavaNode implements ASTTypeBody {
|
|||||||
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
|
public <T> void jjtAccept(SideEffectingVisitor<T> visitor, T data) {
|
||||||
visitor.visit(this, 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,7 @@ public class JavaParser extends JjtreeParserAdapter<ASTCompilationUnit> {
|
|||||||
parser.setPreview(checker.isPreviewEnabled());
|
parser.setPreview(checker.isPreviewEnabled());
|
||||||
|
|
||||||
ASTCompilationUnit acu = parser.CompilationUnit();
|
ASTCompilationUnit acu = parser.CompilationUnit();
|
||||||
|
acu.setTokenDocument(cs.getTokenDocument());
|
||||||
acu.setNoPmdComments(parser.getSuppressMap());
|
acu.setNoPmdComments(parser.getSuppressMap());
|
||||||
checker.check(acu);
|
checker.check(acu);
|
||||||
return acu;
|
return acu;
|
||||||
|
@ -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") {
|
parserTest("Enum constants should have an anonymous class node") {
|
||||||
|
|
||||||
inContext(TopLevelTypeDeclarationParsingCtx) {
|
inContext(TopLevelTypeDeclarationParsingCtx) {
|
||||||
@ -97,6 +166,7 @@ class ASTEnumConstantTest : ParserTestSpec({
|
|||||||
|
|
||||||
enumBody {
|
enumBody {
|
||||||
|
|
||||||
|
|
||||||
enumConstant("B") {
|
enumConstant("B") {
|
||||||
|
|
||||||
val c = it
|
val c = it
|
||||||
@ -160,7 +230,7 @@ class ASTEnumConstantTest : ParserTestSpec({
|
|||||||
}
|
}
|
||||||
|
|
||||||
it::getAnonymousClass shouldBe null
|
it::getAnonymousClass shouldBe null
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,6 @@ fun TreeNodeWrapper<Node, *>.enumDecl(name: String, spec: NodeSpec<ASTEnumDeclar
|
|||||||
spec()
|
spec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun TreeNodeWrapper<Node, *>.enumBody(contents: NodeSpec<ASTEnumBody> = EmptyAssertions) =
|
fun TreeNodeWrapper<Node, *>.enumBody(contents: NodeSpec<ASTEnumBody> = EmptyAssertions) =
|
||||||
child<ASTEnumBody> {
|
child<ASTEnumBody> {
|
||||||
contents()
|
contents()
|
||||||
|
Reference in New Issue
Block a user