[java] Add experimental ASTGuardedPattern

Now we can parse guarded patterns in switch labels.
This commit is contained in:
Andreas Dangel
2021-07-01 17:01:48 +02:00
parent ea802f90ba
commit e2b1f0f3b9
8 changed files with 287 additions and 4 deletions

View File

@ -550,6 +550,12 @@ public class JavaParser {
}
}
private void checkForGuardedPatterns() {
if (!isJEP406Supported()) {
throwParseException("Guarded patterns are only supported with JDK 17 Preview.");
}
}
// This is a semantic LOOKAHEAD to determine if we're dealing with an assert
// Note that this can't be replaced with a syntactic lookahead
// since "assert" isn't a string literal token
@ -1748,6 +1754,25 @@ void EqualityExpression() #EqualityExpression(>1):
InstanceOfExpression() ( LOOKAHEAD(2) ( "==" {jjtThis.setImage("==");} | "!=" {jjtThis.setImage("!=");} ) InstanceOfExpression() )*
}
void Pattern() #void:
{}
{
PrimaryPattern() [ GuardedPatternCondition() #GuardedPattern(2) {checkForGuardedPatterns();} ]
}
void GuardedPatternCondition() #void:
{}
{
"&&" ConditionalAndExpression()
}
void PrimaryPattern() #void:
{}
{
TypePattern()
| "(" Pattern() ")"
}
void TypePattern():
{}
{
@ -2242,11 +2267,12 @@ void SwitchLabel() :
void CaseLabelElement() #void:
{}
{
NullLiteral() {checkForNullCaseLabel();}
LOOKAHEAD(1) NullLiteral() {checkForNullCaseLabel();}
|
"default" {checkForDefaultCaseLabel();}
|
LOOKAHEAD(Type() <IDENTIFIER>) Type() VariableDeclaratorId() #TypePattern(2) {checkForPatternMatchingInSwitch();}
// LOOKAHEAD(Type() <IDENTIFIER>) Type() VariableDeclaratorId() #TypePattern(2) {checkForPatternMatchingInSwitch();}
LOOKAHEAD(Pattern()) Pattern() {checkForPatternMatchingInSwitch();}
|
ConditionalExpression() #Expression
}

View File

@ -0,0 +1,38 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.ast;
import net.sourceforge.pmd.annotation.Experimental;
/**
* A guarded pattern (JDK17 Preview). This can be found
* in {@link ASTSwitchLabel}s.
*
* <pre class="grammar">
*
* GuardedPattern ::= {@linkplain ASTPattern} "&&" {@linkplain ASTConditionalAndExpression}
*
* </pre>
*
* @see <a href="https://openjdk.java.net/jeps/406">JEP 406: Pattern Matching for switch (Preview)</a>
*/
@Experimental
public final class ASTGuardedPattern extends AbstractJavaNode implements ASTPattern {
ASTGuardedPattern(int id) {
super(id);
}
ASTGuardedPattern(JavaParser p, int id) {
super(p, id);
}
@Override
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
}

View File

@ -4,6 +4,8 @@
package net.sourceforge.pmd.lang.java.ast;
import net.sourceforge.pmd.annotation.Experimental;
/**
* External wrapper for a visitor decorator. This one drives the AST visit, delegating to the base controlless visitor
* given in the constructor. Add decorators using the {@link #decorateWith(JavaParserVisitorDecorator)}.
@ -940,4 +942,11 @@ public class JavaParserDecoratedVisitor implements JavaParserVisitor {
visitor.visit(node, data);
return visit((JavaNode) node, data);
}
@Experimental
@Override
public Object visit(ASTGuardedPattern node, Object data) {
visitor.visit(node, data);
return visit((JavaNode) node, data);
}
}

View File

@ -4,6 +4,8 @@
package net.sourceforge.pmd.lang.java.ast;
import net.sourceforge.pmd.annotation.Experimental;
public class JavaParserVisitorAdapter implements JavaParserVisitor {
@Override
@ -660,4 +662,10 @@ public class JavaParserVisitorAdapter implements JavaParserVisitor {
public Object visit(ASTPermitsList node, Object data) {
return visit((JavaNode) node, data);
}
@Experimental
@Override
public Object visit(ASTGuardedPattern node, Object data) {
return visit((JavaNode) node, data);
}
}

View File

@ -4,6 +4,7 @@
package net.sourceforge.pmd.lang.java.ast;
import net.sourceforge.pmd.annotation.Experimental;
import net.sourceforge.pmd.annotation.InternalApi;
/**
@ -793,4 +794,10 @@ public class JavaParserVisitorDecorator implements JavaParserControllessVisitor
public Object visit(ASTPermitsList node, Object data) {
return visitor.visit(node, data);
}
@Experimental
@Override
public Object visit(ASTGuardedPattern node, Object data) {
return visitor.visit(node, data);
}
}

View File

@ -7,6 +7,7 @@ package net.sourceforge.pmd.lang.java.rule;
import java.util.List;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.annotation.Experimental;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.JavaLanguageModule;
@ -59,6 +60,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTForStatement;
import net.sourceforge.pmd.lang.java.ast.ASTForUpdate;
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameters;
import net.sourceforge.pmd.lang.java.ast.ASTGuardedPattern;
import net.sourceforge.pmd.lang.java.ast.ASTIfStatement;
import net.sourceforge.pmd.lang.java.ast.ASTImplementsList;
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
@ -870,4 +872,10 @@ public abstract class AbstractJavaRule extends AbstractRule implements JavaParse
public Object visit(ASTPermitsList node, Object data) {
return visit((JavaNode) node, data);
}
@Experimental
@Override
public Object visit(ASTGuardedPattern node, Object data) {
return visit((JavaNode) node, data);
}
}

View File

@ -4,7 +4,6 @@
package net.sourceforge.pmd.lang.java.ast;
import org.junit.Ignore;
import org.junit.Test;
import net.sourceforge.pmd.lang.ast.ParseException;
@ -59,7 +58,6 @@ public class Java17PreviewTreeDumpTest extends BaseTreeDumpTest {
}
@Test
@Ignore("not finished yet")
public void guardedAndParenthesizedPatterns() {
doTest("GuardedAndParenthesizedPatterns");
}

View File

@ -0,0 +1,189 @@
+- CompilationUnit[@PackageName = "", @declarationsAreInDefaultPackage = true]
+- TypeDeclaration[]
+- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "GuardedAndParenthesizedPatterns", @Default = false, @Final = false, @Image = "GuardedAndParenthesizedPatterns", @Interface = false, @Local = false, @Modifiers = 1, @Native = false, @Nested = false, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = false, @SimpleName = "GuardedAndParenthesizedPatterns", @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 = 1, @Default = false, @Final = false, @InterfaceMember = false, @Kind = MethodLikeKind.METHOD, @MethodName = "test", @Modifiers = 16, @Name = "test", @Native = false, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @Static = true, @Strictfp = false, @Synchronized = false, @SyntacticallyAbstract = false, @SyntacticallyPublic = false, @Transient = false, @Void = true, @Volatile = false]
| +- ResultType[@Void = true, @returnsArray = false]
| +- MethodDeclarator[@Image = "test", @ParameterCount = 1]
| | +- FormalParameters[@ParameterCount = 1, @Size = 1]
| | +- FormalParameter[@Abstract = false, @Array = false, @ArrayDepth = 0, @Default = false, @ExplicitReceiverParameter = 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, @Varargs = false, @Volatile = false]
| | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "Object"]
| | | +- ReferenceType[@Array = false, @ArrayDepth = 0]
| | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Object", @ReferenceToClassSameCompilationUnit = false]
| | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @ForeachVariable = false, @FormalParameter = true, @Image = "o", @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "o"]
| +- Block[@containsComment = false]
| +- BlockStatement[@Allocation = false]
| +- Statement[]
| +- SwitchStatement[@DefaultCase = false, @ExhaustiveEnumSwitch = false]
| +- Expression[@StandAlonePrimitive = false]
| | +- PrimaryExpression[]
| | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | +- Name[@Image = "o"]
| +- SwitchLabeledExpression[]
| | +- SwitchLabel[@Default = false]
| | | +- GuardedPattern[]
| | | +- TypePattern[]
| | | | +- 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]
| | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @ForeachVariable = false, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"]
| | | +- PrimaryExpression[]
| | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | | +- Expression[@StandAlonePrimitive = false]
| | | +- EqualityExpression[@Image = "==", @Operator = "=="]
| | | +- PrimaryExpression[]
| | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | | | | +- Name[@Image = "s.length"]
| | | | +- PrimarySuffix[@ArgumentCount = 0, @Arguments = true, @ArrayDereference = false]
| | | | +- Arguments[@ArgumentCount = 0, @Size = 0]
| | | +- PrimaryExpression[]
| | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = "1", @FloatLiteral = false, @Image = "1", @IntLiteral = true, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = false, @TextBlock = false, @TextBlockContent = "1", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 1, @ValueAsLong = 1]
| | +- Expression[@StandAlonePrimitive = false]
| | +- PrimaryExpression[]
| | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | | +- Name[@Image = "System.out.println"]
| | +- PrimarySuffix[@ArgumentCount = 1, @Arguments = true, @ArrayDereference = false]
| | +- Arguments[@ArgumentCount = 1, @Size = 1]
| | +- ArgumentList[@Size = 1]
| | +- Expression[@StandAlonePrimitive = false]
| | +- PrimaryExpression[]
| | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""single char string"", @FloatLiteral = false, @Image = ""single char string"", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""single char string"", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0]
| +- SwitchLabeledExpression[]
| | +- SwitchLabel[@Default = false]
| | | +- TypePattern[]
| | | +- 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]
| | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @ForeachVariable = false, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"]
| | +- Expression[@StandAlonePrimitive = false]
| | +- PrimaryExpression[]
| | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | | +- Name[@Image = "System.out.println"]
| | +- PrimarySuffix[@ArgumentCount = 1, @Arguments = true, @ArrayDereference = false]
| | +- Arguments[@ArgumentCount = 1, @Size = 1]
| | +- ArgumentList[@Size = 1]
| | +- Expression[@StandAlonePrimitive = false]
| | +- PrimaryExpression[]
| | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""string"", @FloatLiteral = false, @Image = ""string"", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""string"", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0]
| +- SwitchLabeledExpression[]
| | +- SwitchLabel[@Default = false]
| | | +- GuardedPattern[]
| | | +- TypePattern[]
| | | | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "Integer"]
| | | | | +- ReferenceType[@Array = false, @ArrayDepth = 0]
| | | | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Integer", @ReferenceToClassSameCompilationUnit = false]
| | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @ForeachVariable = false, @FormalParameter = false, @Image = "i", @LambdaParameter = false, @LocalVariable = false, @Name = "i", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "i"]
| | | +- EqualityExpression[@Image = "==", @Operator = "=="]
| | | +- PrimaryExpression[]
| | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | | | | +- Name[@Image = "i.intValue"]
| | | | +- PrimarySuffix[@ArgumentCount = 0, @Arguments = true, @ArrayDereference = false]
| | | | +- Arguments[@ArgumentCount = 0, @Size = 0]
| | | +- PrimaryExpression[]
| | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = "1", @FloatLiteral = false, @Image = "1", @IntLiteral = true, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = false, @TextBlock = false, @TextBlockContent = "1", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 1, @ValueAsLong = 1]
| | +- Expression[@StandAlonePrimitive = false]
| | +- PrimaryExpression[]
| | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | | +- Name[@Image = "System.out.println"]
| | +- PrimarySuffix[@ArgumentCount = 1, @Arguments = true, @ArrayDereference = false]
| | +- Arguments[@ArgumentCount = 1, @Size = 1]
| | +- ArgumentList[@Size = 1]
| | +- Expression[@StandAlonePrimitive = false]
| | +- PrimaryExpression[]
| | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""integer 1"", @FloatLiteral = false, @Image = ""integer 1"", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""integer 1"", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0]
| +- SwitchLabeledExpression[]
| +- SwitchLabel[@Default = true]
| +- Expression[@StandAlonePrimitive = false]
| +- PrimaryExpression[]
| +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | +- Name[@Image = "System.out.println"]
| +- PrimarySuffix[@ArgumentCount = 1, @Arguments = true, @ArrayDereference = false]
| +- Arguments[@ArgumentCount = 1, @Size = 1]
| +- ArgumentList[@Size = 1]
| +- Expression[@StandAlonePrimitive = false]
| +- PrimaryExpression[]
| +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""default case"", @FloatLiteral = false, @Image = ""default case"", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""default case"", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0]
+- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.METHOD]
+- MethodDeclaration[@Abstract = false, @Arity = 1, @Default = false, @Final = false, @InterfaceMember = false, @Kind = MethodLikeKind.METHOD, @MethodName = "main", @Modifiers = 17, @Name = "main", @Native = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Static = true, @Strictfp = false, @Synchronized = false, @SyntacticallyAbstract = false, @SyntacticallyPublic = true, @Transient = false, @Void = true, @Volatile = false]
+- ResultType[@Void = true, @returnsArray = false]
+- MethodDeclarator[@Image = "main", @ParameterCount = 1]
| +- FormalParameters[@ParameterCount = 1, @Size = 1]
| +- FormalParameter[@Abstract = false, @Array = true, @ArrayDepth = 1, @Default = false, @ExplicitReceiverParameter = 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, @Varargs = false, @Volatile = false]
| +- Type[@Array = true, @ArrayDepth = 1, @ArrayType = true, @TypeImage = "String"]
| | +- ReferenceType[@Array = true, @ArrayDepth = 1]
| | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = true, @ArrayDepth = 1, @Image = "String", @ReferenceToClassSameCompilationUnit = false]
| +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = true, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @ForeachVariable = false, @FormalParameter = true, @Image = "args", @LambdaParameter = false, @LocalVariable = false, @Name = "args", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "args"]
+- Block[@containsComment = false]
+- BlockStatement[@Allocation = false]
| +- Statement[]
| +- StatementExpression[]
| +- PrimaryExpression[]
| +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | +- Name[@Image = "test"]
| +- PrimarySuffix[@ArgumentCount = 1, @Arguments = true, @ArrayDereference = false]
| +- Arguments[@ArgumentCount = 1, @Size = 1]
| +- ArgumentList[@Size = 1]
| +- Expression[@StandAlonePrimitive = false]
| +- PrimaryExpression[]
| +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""a"", @FloatLiteral = false, @Image = ""a"", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = true, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""a"", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0]
+- BlockStatement[@Allocation = false]
| +- Statement[]
| +- StatementExpression[]
| +- PrimaryExpression[]
| +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | +- Name[@Image = "test"]
| +- PrimarySuffix[@ArgumentCount = 1, @Arguments = true, @ArrayDereference = false]
| +- Arguments[@ArgumentCount = 1, @Size = 1]
| +- ArgumentList[@Size = 1]
| +- Expression[@StandAlonePrimitive = false]
| +- PrimaryExpression[]
| +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""fooo"", @FloatLiteral = false, @Image = ""fooo"", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""fooo"", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0]
+- BlockStatement[@Allocation = false]
| +- Statement[]
| +- StatementExpression[]
| +- PrimaryExpression[]
| +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | +- Name[@Image = "test"]
| +- PrimarySuffix[@ArgumentCount = 1, @Arguments = true, @ArrayDereference = false]
| +- Arguments[@ArgumentCount = 1, @Size = 1]
| +- ArgumentList[@Size = 1]
| +- Expression[@StandAlonePrimitive = true]
| +- PrimaryExpression[]
| +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = "1", @FloatLiteral = false, @Image = "1", @IntLiteral = true, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = false, @TextBlock = false, @TextBlockContent = "1", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 1, @ValueAsLong = 1]
+- BlockStatement[@Allocation = false]
| +- Statement[]
| +- StatementExpression[]
| +- PrimaryExpression[]
| +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| | +- Name[@Image = "test"]
| +- PrimarySuffix[@ArgumentCount = 1, @Arguments = true, @ArrayDereference = false]
| +- Arguments[@ArgumentCount = 1, @Size = 1]
| +- ArgumentList[@Size = 1]
| +- Expression[@StandAlonePrimitive = true]
| +- PrimaryExpression[]
| +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = "1L", @FloatLiteral = false, @Image = "1L", @IntLiteral = false, @LongLiteral = true, @SingleCharacterStringLiteral = false, @StringLiteral = false, @TextBlock = false, @TextBlockContent = "1L", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 1, @ValueAsLong = 1]
+- BlockStatement[@Allocation = false]
+- Statement[]
+- StatementExpression[]
+- PrimaryExpression[]
+- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false]
| +- Name[@Image = "test"]
+- PrimarySuffix[@ArgumentCount = 1, @Arguments = true, @ArrayDereference = false]
+- Arguments[@ArgumentCount = 1, @Size = 1]
+- ArgumentList[@Size = 1]
+- 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[]