[java] Support vararg/array in RecordComponent and empty components

This commit is contained in:
Andreas Dangel
2020-02-28 17:35:44 +01:00
parent 5f43e198d5
commit e017def280
7 changed files with 63 additions and 9 deletions

View File

@ -1139,13 +1139,16 @@ void RecordDeclaration(int modifiers):
void RecordComponentList() :
{}
{
"(" RecordComponent() ("," RecordComponent())* ")"
"(" [ RecordComponent() ("," RecordComponent())* ] ")"
}
void RecordComponent():
{}
{
(TypeAnnotation())* Type() <IDENTIFIER> { jjtThis.setImage(token.image); }
(Annotation())*
Type()
[ (Annotation())* "..." {jjtThis.setVarargs();} ]
VariableDeclaratorId()
}
void RecordBody():

View File

@ -12,14 +12,17 @@ import net.sourceforge.pmd.annotation.Experimental;
*
* <pre class="grammar">
*
* RecordComponent ::= ({@linkplain ASTTypeAnnotation TypeAnnotation})*
* RecordComponent ::= ({@linkplain ASTAnnotation Annotation})*
* {@linkplain ASTType Type}
* &lt;IDENTIFIER&gt;
* ( ({@linkplain ASTAnnotation Annotation})* "..." )?
* {@linkplain ASTVariableDeclaratorId VariableDeclaratorId}
*
* </pre>
*/
@Experimental
public class ASTRecordComponent extends AbstractJavaNode {
private boolean varargs;
ASTRecordComponent(int id) {
super(id);
}
@ -32,4 +35,20 @@ public class ASTRecordComponent extends AbstractJavaNode {
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
public boolean isVarargs() {
return varargs;
}
void setVarargs() {
varargs = true;
}
public ASTType getTypeNode() {
return getFirstChildOfType(ASTType.class);
}
public ASTVariableDeclaratorId getVariableDeclaratorId() {
return getFirstChildOfType(ASTVariableDeclaratorId.class);
}
}

View File

@ -12,8 +12,7 @@ import net.sourceforge.pmd.annotation.Experimental;
*
* <pre class="grammar">
*
* RecordComponentList ::= "(" {@linkplain ASTRecordComponent RecordComponent}
* ( "," {@linkplain ASTRecordComponent RecordComponent} )* ")"
* RecordComponentList ::= "(" ( {@linkplain ASTRecordComponent RecordComponent} ( "," {@linkplain ASTRecordComponent RecordComponent} )* )? ")"
*
* </pre>
*/

View File

@ -57,4 +57,8 @@ public class ASTRecordDeclaration extends AbstractAnyTypeDeclaration {
public boolean isFindBoundary() {
return isNested();
}
public List<ASTRecordComponent> getRecordComponents() {
return getFirstChildOfType(ASTRecordComponentList.class).findChildrenOfType(ASTRecordComponent.class);
}
}

View File

@ -303,6 +303,8 @@ public class ASTVariableDeclaratorId extends AbstractJavaTypeNode implements Dim
return null;
} else if (getParent() instanceof ASTTypeTestPattern) {
return ((ASTTypeTestPattern) getParent()).getTypeNode();
} else if (getParent() instanceof ASTRecordComponent) {
return ((ASTRecordComponent) getParent()).getTypeNode();
} else {
Node n = getParent().getParent();
if (n instanceof ASTLocalVariableDeclaration || n instanceof ASTFieldDeclaration) {

View File

@ -99,8 +99,8 @@ public class Java14PreviewTest {
List<ASTRecordComponent> components = recordDecl.getFirstChildOfType(ASTRecordComponentList.class)
.findChildrenOfType(ASTRecordComponent.class);
Assert.assertEquals(2, components.size());
Assert.assertEquals("x", components.get(0).getImage());
Assert.assertEquals("y", components.get(1).getImage());
Assert.assertEquals("x", components.get(0).getVariableDeclaratorId().getImage());
Assert.assertEquals("y", components.get(1).getVariableDeclaratorId().getImage());
}
@Test(expected = ParseException.class)
@ -112,7 +112,28 @@ public class Java14PreviewTest {
public void innerRecords() {
ASTCompilationUnit compilationUnit = java14p.parseResource("Records.java");
List<ASTRecordDeclaration> recordDecls = compilationUnit.findDescendantsOfType(ASTRecordDeclaration.class);
Assert.assertEquals(2, recordDecls.size());
Assert.assertEquals(5, recordDecls.size());
ASTRecordDeclaration range = recordDecls.get(1);
Assert.assertEquals("Range", range.getImage());
Assert.assertEquals(2, range.getRecordComponents().size());
List<ASTRecordConstructorDeclaration> rangeConstructors = range.findDescendantsOfType(ASTRecordConstructorDeclaration.class);
Assert.assertEquals(1, rangeConstructors.size());
Assert.assertEquals("Range", rangeConstructors.get(0).getImage());
ASTRecordDeclaration varRec = recordDecls.get(2);
Assert.assertEquals("VarRec", varRec.getImage());
Assert.assertEquals("x", varRec.getRecordComponents().get(0).getVariableDeclaratorId().getImage());
Assert.assertTrue(varRec.getRecordComponents().get(0).isVarargs());
ASTRecordDeclaration arrayRec = recordDecls.get(3);
Assert.assertEquals("ArrayRec", arrayRec.getImage());
Assert.assertEquals("x", arrayRec.getRecordComponents().get(0).getVariableDeclaratorId().getImage());
Assert.assertTrue(arrayRec.getRecordComponents().get(0).getVariableDeclaratorId().hasArrayType());
ASTRecordDeclaration emptyRec = recordDecls.get(4);
Assert.assertEquals("EmptyRec", emptyRec.getImage());
Assert.assertEquals(0, emptyRec.getRecordComponents().size());
}
@Test(expected = ParseException.class)

View File

@ -15,4 +15,10 @@ public class Records {
throw new IllegalArgumentException(String.format("(%d,%d)", lo, hi));
}
}
public record VarRec(int ... x) {};
public record ArrayRec(int x[]) {};
public record EmptyRec() {};
}