Simplify some jjtree aspects
This commit is contained in:
@ -57,24 +57,6 @@ public final class JjtreeBuilder<N extends AbstractJjtreeNode<?>> {
|
||||
return nodes.get(0);
|
||||
}
|
||||
|
||||
/***
|
||||
* Extend the number of children of the current node of one to the left.
|
||||
* If the node is closed, one additional node from the stack will be popped
|
||||
* and added to its children. This allows mimicking "left-recursive" nodes,
|
||||
* while keeping the parsing iterative.
|
||||
*
|
||||
* <p>Note that when the total number of children is definitely known, you
|
||||
* can use "definite nodes", ie write the expected number of children (including
|
||||
* the ones to the left) in the JJTree annotation (eg {@code #AdditiveExpression(2)}).
|
||||
* So this is only useful when the number of children of the current node is not certain.
|
||||
*
|
||||
* <p>This method does not affect the stack unless the current jjtThis is
|
||||
* closed in the future.
|
||||
*/
|
||||
public void extendLeft() {
|
||||
mk--;
|
||||
}
|
||||
|
||||
/***
|
||||
* Peek the nth node from the top of the stack.
|
||||
* peekNode(0) == peekNode()
|
||||
|
@ -1285,13 +1285,13 @@ void ClassOrInterfaceType() #void:
|
||||
{ forceTypeContext(); }
|
||||
}
|
||||
|
||||
private void ClassTypeSegment() #ClassOrInterfaceType:
|
||||
private void ClassTypeSegment() #ClassOrInterfaceType(jjtree.nodeArity() + 1):
|
||||
{}
|
||||
{
|
||||
TypeAnnotListNoInject()
|
||||
<IDENTIFIER>
|
||||
// We'll enclose the previous segment
|
||||
{ setLastTokenImage(jjtThis); jjtree.extendLeft();}
|
||||
{ setLastTokenImage(jjtThis); }
|
||||
[ TypeArguments() ]
|
||||
}
|
||||
|
||||
@ -1345,7 +1345,7 @@ void PrimitiveType() :
|
||||
| "float"
|
||||
| "double"
|
||||
)
|
||||
{jjtThis.setImage(getToken(0).getImage());}
|
||||
{setLastTokenImage(jjtThis);}
|
||||
}
|
||||
|
||||
|
||||
@ -1628,7 +1628,8 @@ void PrimaryPrefix() #void :
|
||||
("." MemberSelector() | MethodReference())
|
||||
| UnqualifiedAllocationExpr()
|
||||
| ("void" "." "class") #ClassLiteral
|
||||
| (PrimitiveType() [ Dims() ] ) #ArrayType(>1)
|
||||
| LOOKAHEAD(1) // suppress the warning here.
|
||||
(PrimitiveType() [ Dims() ] ) #ArrayType(>1)
|
||||
(
|
||||
MethodReference()
|
||||
| "." "class" #ClassLiteral(1)
|
||||
@ -1636,7 +1637,7 @@ void PrimaryPrefix() #void :
|
||||
|
||||
// If annotations start the expression, it's necessarily a method or ctor reference
|
||||
// This is because types in class literals or in qualified super/this may not be annotated
|
||||
| LOOKAHEAD({getToken(1).kind == AT}) AnnotatedRefType() MethodReference()
|
||||
| LOOKAHEAD("@") AnnotatedRefType() MethodReference()
|
||||
|
||||
| LOOKAHEAD(LambdaLahead()) LambdaExpression()
|
||||
|
||||
@ -1738,10 +1739,10 @@ void MemberSelector() #void :
|
||||
| (<IDENTIFIER> {setLastTokenImage(jjtThis);}) #FieldAccess(1)
|
||||
}
|
||||
|
||||
void MethodReference(): // LHS is injected
|
||||
void MethodReference() #MethodReference(jjtree.nodeArity() + 1): // LHS is injected
|
||||
{}
|
||||
{
|
||||
"::" {jjtree.extendLeft();}
|
||||
"::"
|
||||
[TypeArguments()]
|
||||
( "new" | <IDENTIFIER> ) {setLastTokenImage(jjtThis);}
|
||||
{/* empty, to set the image before jjtClose */}
|
||||
@ -1847,11 +1848,10 @@ void ArgumentList() :
|
||||
|
||||
|
||||
// more straightforward because can't be an array creation expr
|
||||
void QualifiedAllocationExpr() #ConstructorCall:
|
||||
void QualifiedAllocationExpr() #ConstructorCall(jjtree.nodeArity() + 1):
|
||||
{}
|
||||
{
|
||||
"new"
|
||||
{jjtree.extendLeft();}
|
||||
[ TypeArguments() ]
|
||||
AnnotatedClassOrInterfaceType()
|
||||
ArgumentList()
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.sourceforge.pmd.lang.java.ast
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.test.shouldBe
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType.BOOLEAN
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType.PrimitiveType.INT
|
||||
|
||||
/**
|
||||
@ -157,6 +158,23 @@ class ASTMethodReferenceTest : ParserTestSpec({
|
||||
}
|
||||
}
|
||||
|
||||
"boolean @A []::new" should parseAs {
|
||||
constructorRef {
|
||||
it::getTypeArguments shouldBe null
|
||||
|
||||
typeExpr {
|
||||
arrayType {
|
||||
primitiveType(BOOLEAN)
|
||||
it::getDimensions shouldBe child {
|
||||
arrayDim {
|
||||
annotation("A")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"Class<?>[]::new" should parseAs {
|
||||
constructorRef {
|
||||
it::getTypeArguments shouldBe null
|
||||
|
Reference in New Issue
Block a user