From 8c755fabe22986f3e66aca447a4906c262a97ac8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 12 Feb 2021 12:44:08 +0100 Subject: [PATCH] [java] JEP 394: Pattern Matching for instanceof for Java16 The TypePattern now allows the final keyword and Annotations. Pattern variables are now only effectively final. --- pmd-java/etc/grammar/Java.jjt | 25 +- .../pmd/lang/java/ast/ASTPattern.java | 11 +- .../pmd/lang/java/ast/ASTTypeTestPattern.java | 30 +- .../java/ast/ASTVariableDeclaratorId.java | 7 +- .../pmd/lang/java/ast/Java14PreviewTest.java | 2 +- .../pmd/lang/java/ast/Java16TreeDumpTest.java | 55 ++ .../pmd/lang/java/ast/ASTPatternTest.kt | 49 +- .../java15p/PatternMatchingInstanceof.txt | 8 +- .../java16/PatternMatchingInstanceof.java | 55 ++ .../java16/PatternMatchingInstanceof.txt | 530 ++++++++++++++++++ 10 files changed, 741 insertions(+), 31 deletions(-) create mode 100644 pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java16TreeDumpTest.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/PatternMatchingInstanceof.java create mode 100644 pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/PatternMatchingInstanceof.txt diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt index 7fc17b1edf..132280c698 100644 --- a/pmd-java/etc/grammar/Java.jjt +++ b/pmd-java/etc/grammar/Java.jjt @@ -1,4 +1,7 @@ /** + * JEP 394: Pattern Matching for instanceof for Java16 + * Andreas Dangel 02/2021 + *==================================================================== * Remove support for Java 13 preview language features. * Promote text blocks as a permanent language features with Java 15. * Support Pattern Matching for instanceof with Java 15 Preview. @@ -378,8 +381,8 @@ public class JavaParser { } private void checkforBadInstanceOfPattern() { - if (jdkVersion != 14 && jdkVersion != 15 || !preview) { - throwParseException("Pattern Matching for instanceof is only supported with Java 14 Preview and Java 15 Preview"); + if (!(jdkVersion == 14 && preview || jdkVersion == 15 && preview || jdkVersion == 16)) { + throwParseException("Pattern Matching for instanceof is only supported with Java 14 Preview and Java 15 Preview and Java 16"); } } @@ -1682,10 +1685,26 @@ void EqualityExpression() #EqualityExpression(>1): InstanceOfExpression() ( LOOKAHEAD(2) ( "==" {jjtThis.setImage("==");} | "!=" {jjtThis.setImage("!=");} ) InstanceOfExpression() )* } +void TypePattern() #TypeTestPattern: +{} +{ + ( "final" {jjtThis.setFinal(true);} | Annotation() )* + Type() + VariableDeclaratorId() +} + void InstanceOfExpression() #InstanceOfExpression(>1): {} { - RelationalExpression() [ LOOKAHEAD(2) "instanceof" Type() [ {checkforBadInstanceOfPattern();} VariableDeclaratorId() #TypeTestPattern(2) ] ] + RelationalExpression() + [ "instanceof" + ( + LOOKAHEAD("final" | "@") {checkforBadInstanceOfPattern();} TypePattern() + | + Type() + [ {checkforBadInstanceOfPattern();} VariableDeclaratorId() #TypeTestPattern(2) ] + ) + ] } void RelationalExpression() #RelationalExpression(>1): diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPattern.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPattern.java index 707be4e0cd..ef957a26c5 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPattern.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPattern.java @@ -1,4 +1,4 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ @@ -8,22 +8,21 @@ import net.sourceforge.pmd.annotation.Experimental; /** * A pattern (for pattern matching constructs like {@link ASTInstanceOfExpression InstanceOfExpression}). - * This is a JDK 14 and JDK 15 preview feature and is subject to change. + * This is a JDK 16 feature. * *

This interface will be implemented by all forms of patterns. For * now, only type test patterns are supported. Record deconstruction - * patterns are in the works for JDK 15 preview. - * - *

See https://openjdk.java.net/jeps/305, https://openjdk.java.net/jeps/8235186 + * patterns is planned for a future JDK version. * *

  *
  * Pattern ::= {@link ASTTypeTestPattern TypeTestPattern}
  *
  * 
+ * + * @see JEP 394: Pattern Matching for instanceof */ @Experimental public interface ASTPattern extends JavaNode { - } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeTestPattern.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeTestPattern.java index c126b89198..40c59ff9b4 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeTestPattern.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTTypeTestPattern.java @@ -1,24 +1,29 @@ -/** +/* * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ package net.sourceforge.pmd.lang.java.ast; +import java.util.List; + import net.sourceforge.pmd.annotation.Experimental; /** - * A type test pattern (JDK 14 preview feature). This can be found on + * A type pattern (JDK16). This can be found on * the right-hand side of an {@link ASTInstanceOfExpression InstanceOfExpression}. * *
  *
- * TypeTestPattern ::= {@linkplain ASTType Type} {@link ASTVariableDeclaratorId VariableDeclaratorId}
+ * TypeTestPattern ::= ( "final" | {@linkplain ASTAnnotation Annotation} )* {@linkplain ASTType Type} {@link ASTVariableDeclaratorId VariableDeclaratorId}
  *
  * 
- */ + * + * @see JEP 394: Pattern Matching for instanceof +*/ @Experimental -public final class ASTTypeTestPattern extends AbstractJavaNode implements ASTPattern { +public final class ASTTypeTestPattern extends AbstractJavaAnnotatableNode implements ASTPattern { + private boolean isFinal; ASTTypeTestPattern(int id) { super(id); @@ -34,17 +39,28 @@ public final class ASTTypeTestPattern extends AbstractJavaNode implements ASTPat return visitor.visit(this, data); } + @Override + public List getDeclaredAnnotations() { + return this.findChildrenOfType(ASTAnnotation.class); + } /** * Gets the type against which the expression is tested. */ public ASTType getTypeNode() { - return (ASTType) getChild(0); + return getFirstChildOfType(ASTType.class); } /** Returns the declared variable. */ public ASTVariableDeclaratorId getVarId() { - return (ASTVariableDeclaratorId) getChild(1); + return getFirstChildOfType(ASTVariableDeclaratorId.class); } + void setFinal(boolean isFinal) { + this.isFinal = isFinal; + } + + boolean isFinal() { + return isFinal; + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorId.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorId.java index a8703fa98d..c1c213f000 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorId.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTVariableDeclaratorId.java @@ -199,9 +199,10 @@ public class ASTVariableDeclaratorId extends AbstractJavaTypeNode implements Dim return true; } else if (isLambdaParamWithNoType()) { return false; - } else if (isPatternBinding()) { - // implicitly like final, assignment of a pattern binding is not allowed - return true; + } + + if (getParent() instanceof ASTTypeTestPattern) { + return ((ASTTypeTestPattern) getParent()).isFinal(); } if (getParent() instanceof ASTRecordComponent) { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java14PreviewTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java14PreviewTest.java index b487c35267..ac22623748 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java14PreviewTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java14PreviewTest.java @@ -83,7 +83,7 @@ public class Java14PreviewTest { Assert.assertEquals(String.class, variable.getType()); Assert.assertEquals("s", variable.getVariableName()); Assert.assertTrue(variable.isPatternBinding()); - Assert.assertTrue(variable.isFinal()); + Assert.assertFalse(variable.isFinal()); // Note: these variables are not part of the symbol table // See ScopeAndDeclarationFinder#visit(ASTVariableDeclaratorId, Object) Assert.assertNull(variable.getNameDeclaration()); diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java16TreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java16TreeDumpTest.java new file mode 100644 index 0000000000..8afcc25eee --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java16TreeDumpTest.java @@ -0,0 +1,55 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import net.sourceforge.pmd.lang.ast.ParseException; +import net.sourceforge.pmd.lang.ast.test.BaseParsingHelper; +import net.sourceforge.pmd.lang.ast.test.BaseTreeDumpTest; +import net.sourceforge.pmd.lang.ast.test.RelevantAttributePrinter; +import net.sourceforge.pmd.lang.java.JavaParsingHelper; + +public class Java16TreeDumpTest extends BaseTreeDumpTest { + private final JavaParsingHelper java16 = + JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("16") + .withResourceContext(Java15TreeDumpTest.class, "jdkversiontests/java16/"); + private final JavaParsingHelper java16p = java16.withDefaultVersion("16-preview"); + private final JavaParsingHelper java15 = java16.withDefaultVersion("15"); + + public Java16TreeDumpTest() { + super(new RelevantAttributePrinter(), ".java"); + } + + @Override + public BaseParsingHelper getParser() { + return java16; + } + + @Test + public void patternMatchingInstanceof() { + doTest("PatternMatchingInstanceof"); + + // extended tests for type resolution etc. + ASTCompilationUnit compilationUnit = java16.parseResource("PatternMatchingInstanceof.java"); + List instanceOfExpressions = compilationUnit.findDescendantsOfType(ASTInstanceOfExpression.class); + for (ASTInstanceOfExpression expr : instanceOfExpressions) { + ASTVariableDeclaratorId variable = expr.getChild(1).getFirstChildOfType(ASTVariableDeclaratorId.class); + Assert.assertEquals(String.class, variable.getType()); + // Note: these variables are not part of the symbol table + // See ScopeAndDeclarationFinder#visit(ASTVariableDeclaratorId, Object) + Assert.assertNull(variable.getNameDeclaration()); + } + } + + @Test(expected = ParseException.class) + public void patternMatchingInstanceofBeforeJava16ShouldFail() { + java15.parseResource("PatternMatchingInstanceof.java"); + } + +} diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTPatternTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTPatternTest.kt index f513429d89..806588b2eb 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTPatternTest.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/ASTPatternTest.kt @@ -4,32 +4,67 @@ package net.sourceforge.pmd.lang.java.ast -import net.sourceforge.pmd.lang.ast.test.shouldBe +import io.kotest.matchers.shouldBe +import net.sourceforge.pmd.lang.ast.test.shouldBe as typeShouldBe import net.sourceforge.pmd.lang.java.ast.JavaVersion import net.sourceforge.pmd.lang.java.ast.JavaVersion.* import java.io.IOException class ASTPatternTest : ParserTestSpec({ - parserTest("Test patterns only available on JDK 14+15 (preview)", javaVersions = JavaVersion.values().asList().minus(J14__PREVIEW).minus(J15__PREVIEW)) { + parserTest("Test patterns only available on JDK 14+15 (preview) and JDK16 and JDK16 (preview)", + javaVersions = JavaVersion.values().asList().minus(J14__PREVIEW).minus(J15__PREVIEW).minus(J16).minus(J16__PREVIEW)) { - expectParseException("Pattern Matching for instanceof is only supported with Java 14 Preview and Java 15 Preview") { + expectParseException("Pattern Matching for instanceof is only supported with Java 14 Preview and Java 15 Preview and Java 16") { parseAstExpression("obj instanceof Class c") } } - parserTest("Test simple patterns", javaVersions = listOf(J14__PREVIEW, J15__PREVIEW)) { + parserTest("Test simple patterns", javaVersions = listOf(J14__PREVIEW, J15__PREVIEW, J16)) { importedTypes += IOException::class.java "obj instanceof Class c" should matchExpr { unspecifiedChild() child { - it::getTypeNode shouldBe child(ignoreChildren = true) {} + it.isAnnotationPresent("java.lang.Deprecated") shouldBe false + it::getTypeNode typeShouldBe child(ignoreChildren = true) {} - it::getVarId shouldBe child { - it::getVariableName shouldBe "c" + it::getVarId typeShouldBe child { + it.name shouldBe "c" + it.isFinal shouldBe false + } + } + } + + "obj instanceof final Class c" should matchExpr { + unspecifiedChild() + child { + it.isAnnotationPresent("java.lang.Deprecated") shouldBe false + it::getTypeNode typeShouldBe child(ignoreChildren = true) {} + + it::getVarId typeShouldBe child { + it.name shouldBe "c" + it.isFinal shouldBe true + } + } + } + + "obj instanceof @Deprecated Class c" should matchExpr { + unspecifiedChild() + child { + child(ignoreChildren = true) { + it.annotationName shouldBe "Deprecated" + } + + it.isAnnotationPresent("java.lang.Deprecated") shouldBe true + + it::getTypeNode typeShouldBe child(ignoreChildren = true) {} + + it::getVarId typeShouldBe child { + it.name shouldBe "c" + it.isFinal shouldBe false } } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/PatternMatchingInstanceof.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/PatternMatchingInstanceof.txt index e69073e1e7..00481b37e4 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/PatternMatchingInstanceof.txt +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/PatternMatchingInstanceof.txt @@ -44,7 +44,7 @@ | | | +- 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 = true, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] + | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] | | +- Statement[] | | | +- Block[@containsComment = true] | | | +- BlockStatement[@Allocation = false] @@ -113,7 +113,7 @@ | | | +- 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 = true, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] + | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] | | +- Statement[] | | | +- Block[@containsComment = true] | | | +- BlockStatement[@Allocation = false] @@ -179,7 +179,7 @@ | | | | +- 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 = true, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] + | | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] | | | +- RelationalExpression[@Image = ">"] | | | +- PrimaryExpression[] | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] @@ -228,7 +228,7 @@ | | | +- 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 = true, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] + | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] | | +- RelationalExpression[@Image = ">"] | | +- PrimaryExpression[] | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/PatternMatchingInstanceof.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/PatternMatchingInstanceof.java new file mode 100644 index 0000000000..c4e6e46e5a --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/PatternMatchingInstanceof.java @@ -0,0 +1,55 @@ +/** + * + * @see JEP 394: Pattern Matching for instanceof + */ +public class PatternMatchingInstanceof { + private String s = "other string"; + + public void test() { + Object obj = "abc"; + //obj = 1; + if (obj instanceof String s) { + System.out.println("a) obj == s: " + (obj == s)); // true + s = "other value"; // not a compile error - s is only effectively final + System.out.println("changed s to " + s + ": obj == s: " + (obj == s)); + } else { + System.out.println("b) obj == s: " + (obj == s)); // false + } + + if (!(obj instanceof String s)) { + System.out.println("c) obj == s: " + (obj == s)); // false + } else { + System.out.println("d) obj == s: " + (obj == s)); // true + } + + if (obj instanceof String s && s.length() > 2) { + System.out.println("e) obj == s: " + (obj == s)); // true + } + if (obj instanceof String s || s.length() > 5) { + System.out.println("f) obj == s: " + (obj == s)); // false + } + + // With Java16 there can be final and annotations + if (obj instanceof final String s) { + System.out.println("g) obj == s: " + (obj == s)); // true + //s = "another value"; // compile error: error: cannot assign a value to final variable s + } else { + System.out.println("h) obj == s: " + (obj == s)); // false + } + if (obj instanceof @Deprecated String s) { + System.out.println("i) obj == s: " + (obj == s)); // true + } else { + System.out.println("j) obj == s: " + (obj == s)); // false + } + if (obj instanceof final @Deprecated String s) { + System.out.println("k) obj == s: " + (obj == s)); // true + //s = "another value"; // compile error: error: cannot assign a value to final variable s + } else { + System.out.println("l) obj == s: " + (obj == s)); // false + } + } + + public static void main(String[] args) { + new PatternMatchingInstanceof().test(); + } +} \ No newline at end of file diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/PatternMatchingInstanceof.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/PatternMatchingInstanceof.txt new file mode 100644 index 0000000000..dca5fe68c6 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java16/PatternMatchingInstanceof.txt @@ -0,0 +1,530 @@ ++- CompilationUnit[@PackageName = "", @declarationsAreInDefaultPackage = true] + +- TypeDeclaration[] + +- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "PatternMatchingInstanceof", @Default = false, @Final = false, @Image = "PatternMatchingInstanceof", @Interface = false, @Local = false, @Modifiers = 1, @Native = false, @Nested = false, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = false, @SimpleName = "PatternMatchingInstanceof", @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.FIELD] + | +- FieldDeclaration[@Abstract = false, @AnnotationMember = false, @Array = false, @ArrayDepth = 0, @Default = false, @Final = false, @InterfaceMember = false, @Modifiers = 4, @Native = false, @PackagePrivate = false, @Private = true, @Protected = false, @Public = false, @Static = false, @Strictfp = false, @Synchronized = false, @SyntacticallyFinal = false, @SyntacticallyPublic = false, @SyntacticallyStatic = false, @Transient = false, @VariableName = "s", @Volatile = false] + | +- 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] + | +- VariableDeclarator[@Initializer = true, @Name = "s"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = true, @Final = false, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""other string"", @FloatLiteral = false, @Image = ""other string"", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""other string"", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.METHOD] + | +- MethodDeclaration[@Abstract = false, @Arity = 0, @Default = false, @Final = false, @InterfaceMember = false, @Kind = MethodLikeKind.METHOD, @MethodName = "test", @Modifiers = 1, @Name = "test", @Native = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Static = false, @Strictfp = false, @Synchronized = false, @SyntacticallyAbstract = false, @SyntacticallyPublic = true, @Transient = false, @Void = true, @Volatile = false] + | +- ResultType[@Void = true, @returnsArray = false] + | +- MethodDeclarator[@Image = "test", @ParameterCount = 0] + | | +- FormalParameters[@ParameterCount = 0, @Size = 0] + | +- Block[@containsComment = false] + | +- BlockStatement[@Allocation = false] + | | +- LocalVariableDeclaration[@Abstract = false, @Array = false, @ArrayDepth = 0, @Default = 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, @VariableName = "obj", @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] + | | +- VariableDeclarator[@Initializer = true, @Name = "obj"] + | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "obj", @LambdaParameter = false, @LocalVariable = true, @Name = "obj", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "obj"] + | | +- VariableInitializer[] + | | +- Expression[@StandAlonePrimitive = false] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""abc"", @FloatLiteral = false, @Image = ""abc"", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""abc"", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | +- BlockStatement[@Allocation = false] + | | +- Statement[] + | | +- IfStatement[@Else = true] + | | +- Expression[@StandAlonePrimitive = false] + | | | +- InstanceOfExpression[] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Name[@Image = "obj"] + | | | +- TypeTestPattern[] + | | | +- 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, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] + | | +- Statement[] + | | | +- Block[@containsComment = false] + | | | +- BlockStatement[@Allocation = false] + | | | | +- Statement[] + | | | | +- StatementExpression[] + | | | | +- 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] + | | | | +- AdditiveExpression[@Image = "+", @Operator = "+"] + | | | | +- PrimaryExpression[] + | | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""a) obj == s: "", @FloatLiteral = false, @Image = ""a) obj == s: "", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""a) obj == s: "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Expression[@StandAlonePrimitive = false] + | | | | +- EqualityExpression[@Image = "==", @Operator = "=="] + | | | | +- PrimaryExpression[] + | | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | | +- Name[@Image = "obj"] + | | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Name[@Image = "s"] + | | | +- BlockStatement[@Allocation = false] + | | | | +- Statement[] + | | | | +- StatementExpression[] + | | | | +- PrimaryExpression[] + | | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | | +- Name[@Image = "s"] + | | | | +- AssignmentOperator[@Compound = false, @Image = "="] + | | | | +- Expression[@StandAlonePrimitive = false] + | | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""other value"", @FloatLiteral = false, @Image = ""other value"", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""other value"", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | | +- BlockStatement[@Allocation = false] + | | | +- Statement[] + | | | +- StatementExpression[] + | | | +- 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] + | | | +- AdditiveExpression[@Image = "+", @Operator = "+"] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""changed s to "", @FloatLiteral = false, @Image = ""changed s to "", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""changed s to "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Name[@Image = "s"] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = "": obj == s: "", @FloatLiteral = false, @Image = "": obj == s: "", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = "": obj == s: "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Expression[@StandAlonePrimitive = false] + | | | +- EqualityExpression[@Image = "==", @Operator = "=="] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Name[@Image = "obj"] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "s"] + | | +- Statement[] + | | +- Block[@containsComment = true] + | | +- BlockStatement[@Allocation = false] + | | +- Statement[] + | | +- StatementExpression[] + | | +- 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] + | | +- AdditiveExpression[@Image = "+", @Operator = "+"] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""b) obj == s: "", @FloatLiteral = false, @Image = ""b) obj == s: "", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""b) obj == s: "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Expression[@StandAlonePrimitive = false] + | | +- EqualityExpression[@Image = "==", @Operator = "=="] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "obj"] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "s"] + | +- BlockStatement[@Allocation = false] + | | +- Statement[] + | | +- IfStatement[@Else = true] + | | +- Expression[@StandAlonePrimitive = false] + | | | +- UnaryExpressionNotPlusMinus[@Image = "!", @Operator = "!"] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Expression[@StandAlonePrimitive = false] + | | | +- InstanceOfExpression[] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Name[@Image = "obj"] + | | | +- TypeTestPattern[] + | | | +- 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, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] + | | +- Statement[] + | | | +- Block[@containsComment = true] + | | | +- BlockStatement[@Allocation = false] + | | | +- Statement[] + | | | +- StatementExpression[] + | | | +- 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] + | | | +- AdditiveExpression[@Image = "+", @Operator = "+"] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""c) obj == s: "", @FloatLiteral = false, @Image = ""c) obj == s: "", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""c) obj == s: "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Expression[@StandAlonePrimitive = false] + | | | +- EqualityExpression[@Image = "==", @Operator = "=="] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Name[@Image = "obj"] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "s"] + | | +- Statement[] + | | +- Block[@containsComment = true] + | | +- BlockStatement[@Allocation = false] + | | +- Statement[] + | | +- StatementExpression[] + | | +- 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] + | | +- AdditiveExpression[@Image = "+", @Operator = "+"] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""d) obj == s: "", @FloatLiteral = false, @Image = ""d) obj == s: "", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""d) obj == s: "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Expression[@StandAlonePrimitive = false] + | | +- EqualityExpression[@Image = "==", @Operator = "=="] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "obj"] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "s"] + | +- BlockStatement[@Allocation = false] + | | +- Statement[] + | | +- IfStatement[@Else = false] + | | +- Expression[@StandAlonePrimitive = false] + | | | +- ConditionalAndExpression[] + | | | +- InstanceOfExpression[] + | | | | +- PrimaryExpression[] + | | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | | +- Name[@Image = "obj"] + | | | | +- TypeTestPattern[] + | | | | +- 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, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] + | | | +- RelationalExpression[@Image = ">"] + | | | +- 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 = "2", @FloatLiteral = false, @Image = "2", @IntLiteral = true, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = false, @TextBlock = false, @TextBlockContent = "2", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 2, @ValueAsLong = 2] + | | +- Statement[] + | | +- Block[@containsComment = true] + | | +- BlockStatement[@Allocation = false] + | | +- Statement[] + | | +- StatementExpression[] + | | +- 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] + | | +- AdditiveExpression[@Image = "+", @Operator = "+"] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""e) obj == s: "", @FloatLiteral = false, @Image = ""e) obj == s: "", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""e) obj == s: "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Expression[@StandAlonePrimitive = false] + | | +- EqualityExpression[@Image = "==", @Operator = "=="] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "obj"] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "s"] + | +- BlockStatement[@Allocation = false] + | | +- Statement[] + | | +- IfStatement[@Else = false] + | | +- Expression[@StandAlonePrimitive = false] + | | | +- ConditionalOrExpression[] + | | | +- InstanceOfExpression[] + | | | | +- PrimaryExpression[] + | | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | | +- Name[@Image = "obj"] + | | | | +- TypeTestPattern[] + | | | | +- 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, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] + | | | +- RelationalExpression[@Image = ">"] + | | | +- 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 = "5", @FloatLiteral = false, @Image = "5", @IntLiteral = true, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = false, @TextBlock = false, @TextBlockContent = "5", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 5, @ValueAsLong = 5] + | | +- Statement[] + | | +- Block[@containsComment = true] + | | +- BlockStatement[@Allocation = false] + | | +- Statement[] + | | +- StatementExpression[] + | | +- 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] + | | +- AdditiveExpression[@Image = "+", @Operator = "+"] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""f) obj == s: "", @FloatLiteral = false, @Image = ""f) obj == s: "", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""f) obj == s: "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Expression[@StandAlonePrimitive = false] + | | +- EqualityExpression[@Image = "==", @Operator = "=="] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "obj"] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "s"] + | +- BlockStatement[@Allocation = false] + | | +- Statement[] + | | +- IfStatement[@Else = true] + | | +- Expression[@StandAlonePrimitive = false] + | | | +- InstanceOfExpression[] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Name[@Image = "obj"] + | | | +- TypeTestPattern[] + | | | +- 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 = true, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] + | | +- Statement[] + | | | +- Block[@containsComment = true] + | | | +- BlockStatement[@Allocation = false] + | | | +- Statement[] + | | | +- StatementExpression[] + | | | +- 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] + | | | +- AdditiveExpression[@Image = "+", @Operator = "+"] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""g) obj == s: "", @FloatLiteral = false, @Image = ""g) obj == s: "", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""g) obj == s: "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Expression[@StandAlonePrimitive = false] + | | | +- EqualityExpression[@Image = "==", @Operator = "=="] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Name[@Image = "obj"] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "s"] + | | +- Statement[] + | | +- Block[@containsComment = true] + | | +- BlockStatement[@Allocation = false] + | | +- Statement[] + | | +- StatementExpression[] + | | +- 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] + | | +- AdditiveExpression[@Image = "+", @Operator = "+"] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""h) obj == s: "", @FloatLiteral = false, @Image = ""h) obj == s: "", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""h) obj == s: "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Expression[@StandAlonePrimitive = false] + | | +- EqualityExpression[@Image = "==", @Operator = "=="] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "obj"] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "s"] + | +- BlockStatement[@Allocation = false] + | | +- Statement[] + | | +- IfStatement[@Else = true] + | | +- Expression[@StandAlonePrimitive = false] + | | | +- InstanceOfExpression[] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Name[@Image = "obj"] + | | | +- TypeTestPattern[] + | | | +- Annotation[@AnnotationName = "Deprecated"] + | | | | +- MarkerAnnotation[@AnnotationName = "Deprecated"] + | | | | +- Name[@Image = "Deprecated"] + | | | +- 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, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] + | | +- Statement[] + | | | +- Block[@containsComment = true] + | | | +- BlockStatement[@Allocation = false] + | | | +- Statement[] + | | | +- StatementExpression[] + | | | +- 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] + | | | +- AdditiveExpression[@Image = "+", @Operator = "+"] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""i) obj == s: "", @FloatLiteral = false, @Image = ""i) obj == s: "", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""i) obj == s: "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Expression[@StandAlonePrimitive = false] + | | | +- EqualityExpression[@Image = "==", @Operator = "=="] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Name[@Image = "obj"] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "s"] + | | +- Statement[] + | | +- Block[@containsComment = true] + | | +- BlockStatement[@Allocation = false] + | | +- Statement[] + | | +- StatementExpression[] + | | +- 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] + | | +- AdditiveExpression[@Image = "+", @Operator = "+"] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""j) obj == s: "", @FloatLiteral = false, @Image = ""j) obj == s: "", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""j) obj == s: "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Expression[@StandAlonePrimitive = false] + | | +- EqualityExpression[@Image = "==", @Operator = "=="] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "obj"] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "s"] + | +- BlockStatement[@Allocation = false] + | +- Statement[] + | +- IfStatement[@Else = true] + | +- Expression[@StandAlonePrimitive = false] + | | +- InstanceOfExpression[] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "obj"] + | | +- TypeTestPattern[] + | | +- Annotation[@AnnotationName = "Deprecated"] + | | | +- MarkerAnnotation[@AnnotationName = "Deprecated"] + | | | +- Name[@Image = "Deprecated"] + | | +- 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 = true, @FormalParameter = false, @Image = "s", @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "s"] + | +- Statement[] + | | +- Block[@containsComment = true] + | | +- BlockStatement[@Allocation = false] + | | +- Statement[] + | | +- StatementExpression[] + | | +- 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] + | | +- AdditiveExpression[@Image = "+", @Operator = "+"] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""k) obj == s: "", @FloatLiteral = false, @Image = ""k) obj == s: "", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""k) obj == s: "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Expression[@StandAlonePrimitive = false] + | | +- EqualityExpression[@Image = "==", @Operator = "=="] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "obj"] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "s"] + | +- Statement[] + | +- Block[@containsComment = true] + | +- BlockStatement[@Allocation = false] + | +- Statement[] + | +- StatementExpression[] + | +- 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] + | +- AdditiveExpression[@Image = "+", @Operator = "+"] + | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""l) obj == s: "", @FloatLiteral = false, @Image = ""l) obj == s: "", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""l) obj == s: "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Expression[@StandAlonePrimitive = false] + | +- EqualityExpression[@Image = "==", @Operator = "=="] + | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "obj"] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Name[@Image = "s"] + +- 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, @FormalParameter = true, @Image = "args", @LambdaParameter = false, @LocalVariable = false, @Name = "args", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "args"] + +- Block[@containsComment = false] + +- BlockStatement[@Allocation = true] + +- Statement[] + +- StatementExpression[] + +- PrimaryExpression[] + +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- AllocationExpression[@AnonymousClass = false] + | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "PatternMatchingInstanceof", @ReferenceToClassSameCompilationUnit = true] + | +- Arguments[@ArgumentCount = 0, @Size = 0] + +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @Image = "test"] + +- PrimarySuffix[@ArgumentCount = 0, @Arguments = true, @ArrayDereference = false] + +- Arguments[@ArgumentCount = 0, @Size = 0]