diff --git a/docs/pages/pmd/userdocs/cli_reference.md b/docs/pages/pmd/userdocs/cli_reference.md index 743f5c3a15..2e6350ebc8 100644 --- a/docs/pages/pmd/userdocs/cli_reference.md +++ b/docs/pages/pmd/userdocs/cli_reference.md @@ -185,7 +185,7 @@ Example: * [apex](pmd_rules_apex.html) (Salesforce Apex) * [java](pmd_rules_java.html) * Supported Versions: 1.3, 1.4, 1.5, 5, 1.6, 6, 1.7, 7, 1.8, 8, 9, 1.9, 10, 1.10, 11, 12, - 13, 13-preview, 14 (default), 14-preview + 13, 14, 14-preview, 15 (default), 15-preview * [ecmascript](pmd_rules_ecmascript.html) (JavaScript) * [jsp](pmd_rules_jsp.html) * [modelica](pmd_rules_modelica.html) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index be11faf83e..c1c706dc1d 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -19,6 +19,24 @@ This is a {{ site.pmd.release_type }} release. ### New and noteworthy +#### Java 15 Support + +This release of PMD brings support for Java 15. PMD can parse [Text Blocks](https://openjdk.java.net/jeps/378) +which have been promoted to be a standard language feature of Java. + +PMD also supports [Pattern Matching for instanceof](https://openjdk.java.net/jeps/375), +[Records](https://openjdk.java.net/jeps/384), and [Sealed Classes](https://openjdk.java.net/jeps/360). + +Note: The Pattern Matching for instanceof, Records, and Sealed Classes are all preview language features of OpenJDK 15 +and are not enabled by default. In order to +analyze a project with PMD that uses these language features, you'll need to enable it via the environment +variable `PMD_JAVA_OPTS` and select the new language version `15-preview`: + + export PMD_JAVA_OPTS=--enable-preview + ./run.sh pmd -language java -version 15-preview ... + +Note: Support for Java 13 preview language features have been removed. The version "13-preview" is no longer available. + #### Changes in how tab characters are handled In the past, tab characters in source files has been handled differently in different languages by PMD. @@ -65,6 +83,8 @@ See also [[all] Ensure PMD/CPD uses tab width of 1 for tabs consistently #2656]( * [#2653](https://github.com/pmd/pmd/issues/2653): \[lang-test] Upgrade kotlintest to Kotest * [#2656](https://github.com/pmd/pmd/pull/2656): \[all] Ensure PMD/CPD uses tab width of 1 for tabs consistently * [#2690](https://github.com/pmd/pmd/pull/2690): \[core] Fix java7 compatibility +* java + * [#2646](https://github.com/pmd/pmd/issues/2646): \[java] Support JDK 15 * java-bestpractices * [#2471](https://github.com/pmd/pmd/issues/2471): \[java] New Rule: AvoidReassigningCatchVariables * [#2663](https://github.com/pmd/pmd/issues/2663): \[java] NoClassDefFoundError on upgrade from 6.25.0 to 6.26.0 diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt index 25bbe28f41..6c63fd9ca2 100644 --- a/pmd-java/etc/grammar/Java.jjt +++ b/pmd-java/etc/grammar/Java.jjt @@ -1,4 +1,12 @@ /** + * 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. + * Support Records with Java 15 Preview. + * Support Local Records with Java 15 Preview. + * Support Sealed Classes with Java 15 Preview. + * Andreas Dangel 08/2020 + *==================================================================== * Add support for record types introduced as a preview language * feature with Java 14. See JEP 359. * Andreas Dangel 02/2020 @@ -227,6 +235,7 @@ PARSER_BEGIN(JavaParserImpl) package net.sourceforge.pmd.lang.java.ast; import java.util.ArrayList; import java.util.Collections; +import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Set; @@ -234,6 +243,7 @@ import java.util.Map; import net.sourceforge.pmd.lang.ast.CharStream; import net.sourceforge.pmd.lang.ast.GenericToken; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; +import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.ast.TokenMgrError; import net.sourceforge.pmd.lang.ast.Node; @@ -260,6 +270,16 @@ class JavaParserImpl { throw new ParseException("Line " + line + ", Column " + col + ": " + message); } + + private boolean isRecordTypeSupported() { + return (jdkVersion == 14 || jdkVersion == 15) && preview; + } + + private boolean isSealedClassSupported() { + return jdkVersion == 15 && preview; + } + + /** * Keeps track during tree construction, whether we are currently building a switch label. * A switch label must not contain a LambdaExpression. @@ -285,9 +305,65 @@ class JavaParserImpl { /** * Semantic lookahead to check if the next identifier is a * specific restricted keyword. + * + *

Restricted keywords are: + * var, yield, record, sealed, permits, "non" + "-" + "sealed" + * + *

enum and assert is used like restricted keywords, as they were not keywords + * in the early java versions. */ - private boolean isKeyword(String keyword) { - return getToken(1).kind == IDENTIFIER && getToken(1).getImage().equals(keyword); + private boolean isKeyword(String image) { + return isKeyword(1, image); + } + + private boolean isKeyword(int index, String image) { + Token token = getToken(index); + return token.kind == IDENTIFIER && token.image.equals(image); + } + + private boolean isToken(int index, int kind) { + return getToken(index).kind == kind; + } + + /** + * Semantic lookahead which matches "non-sealed". + * + *

"non-sealed" cannot be a token, for several reasons: + * It is only a keyword with java15 preview+, it consists actually + * of several separate tokens, which are valid on their own. + */ + private boolean isNonSealedModifier() { + if (isKeyword(1, "non") && isToken(2, MINUS) && isKeyword(3, "sealed")) { + JavaccToken nonToken = getToken(1); + JavaccToken minusToken = getToken(2); + JavaccToken sealedToken = getToken(3); + return nonToken.getEndColumn() == minusToken.getBeginColumn() + && minusToken.getEndColumn() == sealedToken.getBeginColumn(); + } + return false; + } + + private boolean classModifierLookahead() { + Token next = getToken(1); + return next.kind == AT + || next.kind == PUBLIC + || next.kind == PROTECTED + || next.kind == PRIVATE + || next.kind == ABSTRACT + || next.kind == STATIC + || next.kind == FINAL + || next.kind == STRICTFP + || isSealedClassSupported() && isKeyword("sealed") + || isSealedClassSupported() && isNonSealedModifier(); + } + + private boolean localTypeDeclLookahead() { + Token next = getToken(1); + return next.kind == CLASS + || isRecordTypeSupported() && next.kind == INTERFACE + || isRecordTypeSupported() && next.kind == AT && isToken(2, INTERFACE) + || isRecordTypeSupported() && next.kind == IDENTIFIER && next.getImage().equals("enum") + || isRecordTypeSupported() && next.kind == IDENTIFIER && next.image.equals("record"); } /** @@ -875,6 +951,8 @@ void ModifierList(): | "volatile" { modifiers.add(JModifier.VOLATILE); } | "strictfp" { modifiers.add(JModifier.STRICTFP); } | "default" { modifiers.add(JModifier.DEFAULT); } + | LOOKAHEAD({isKeyword("sealed")}) { modifiers |= AccessNode.SEALED; } + | LOOKAHEAD({isNonSealedModifier()}) { modifiers |= AccessNode.NON_SEALED; } | Annotation() ) )* @@ -906,6 +984,7 @@ void ClassOrInterfaceDeclaration(): [ TypeParameters() ] [ ExtendsList() ] [ ImplementsList() ] + [ LOOKAHEAD({isKeyword("permits")}) PermittedSubclasses() ] ClassOrInterfaceBody() } @@ -923,6 +1002,20 @@ void ImplementsList(): ( "," AnnotatedClassOrInterfaceType() )* } +void PermittedSubclasses() #PermitsList: +{ + Token t; +} +{ + t = { + if (!"permits".equals(t.image)) { + throw new ParseException("ERROR: expecting permits"); + } + } + (TypeAnnotation())* ClassOrInterfaceType() + ( "," (TypeAnnotation())* ClassOrInterfaceType() )* +} + void EnumDeclaration(): { JavaccToken t; @@ -2069,13 +2162,45 @@ void Block() : } void BlockStatement() #void: -{} +{int mods = 0;} { LOOKAHEAD( { isNextTokenAnAssert() } ) AssertStatement() | LOOKAHEAD( { isYieldStart() } ) YieldStatement() -| - LOOKAHEAD(( "final" | Annotation() )* Type() ) - LocalVariableDeclaration() ";" { +| LOOKAHEAD( "@" | "final" ) + // this eagerly parses all modifiers and annotations. After that, either a local type declaration + // or a local variable declaration follows. + // This allows more modifiers for local variables than actually allowed + // and the annotations for local variables need to be moved in the AST down again. + mods=Modifiers() + ( + LOOKAHEAD({localTypeDeclLookahead()}) LocalTypeDecl(mods) + | + { + List annotations = new ArrayList(); + while (jjtree.peekNode() instanceof ASTAnnotation) { + annotations.add((ASTAnnotation) jjtree.popNode()); + } + } + LocalVariableDeclaration() + { + ASTLocalVariableDeclaration localVarDecl = (ASTLocalVariableDeclaration) jjtree.peekNode(); + if ((mods & AccessNode.FINAL) == AccessNode.FINAL) { + localVarDecl.setFinal(true); + } + if (!annotations.isEmpty()) { + Collections.reverse(annotations); + for (ASTAnnotation a : annotations) { + localVarDecl.insertChild(a, 0); + } + } + } + ";" + ) +| LOOKAHEAD({classModifierLookahead() || localTypeDeclLookahead()}) + mods=Modifiers() + LocalTypeDecl(mods) +| LOOKAHEAD(Type() ) + LocalVariableDeclaration() ";" { // make it so that the LocalVariableDeclaration's last token is the semicolon AbstractJavaNode top = (AbstractJavaNode) jjtree.peekNode(); top.setLastToken(getToken(0)); @@ -2084,25 +2209,21 @@ void BlockStatement() #void: // we need to lookahead until the "class" token, // because a method ref may be annotated // -> so Expression, and hence Statement, may start with "@" - LOOKAHEAD(ModifierList() "class") LocalClassDecl() + LOOKAHEAD(ModifierList() "class") LocalTypeDecl() | Statement() } -void LocalClassDecl() #LocalClassStatement: +void LocalTypeDecl(int mods) #LocalClassStatement: {} { - // this preserves the modifiers of the local class. - // it allows for modifiers that are forbidden for local classes, - // but anyway we are *not* checking modifiers for incompatibilities - // anywhere else in this grammar (and indeed the production Modifiers - // accepts any modifier explicitly for the purpose of forgiving modifier errors, - // and reporting them later if needed --see its documentation). - - // In particular, it unfortunately allows local class declarations to start - // with a "default" modifier, which introduces an ambiguity with default - // switch labels. This is guarded by a custom lookahead around SwitchLabel - ModifierList() ClassOrInterfaceDeclaration() + ( + LOOKAHEAD() ClassOrInterfaceDeclaration(mods) + | LOOKAHEAD() ClassOrInterfaceDeclaration(mods) + | LOOKAHEAD({isKeyword("record")}) RecordDeclaration(mods) + | LOOKAHEAD({isKeyword("enum")}) EnumDeclaration(mods) + | AnnotationTypeDeclaration(mods) + ) } /* diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java index 1da8afecd5..8bab973c6b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/JavaLanguageModule.java @@ -28,9 +28,10 @@ public class JavaLanguageModule extends BaseLanguageModule { addVersion("11", new JavaLanguageHandler(11)); addVersion("12", new JavaLanguageHandler(12)); addVersion("13", new JavaLanguageHandler(13)); - addVersion("13-preview", new JavaLanguageHandler(13, true)); - addDefaultVersion("14", new JavaLanguageHandler(14)); // 14 is the default + addVersion("14", new JavaLanguageHandler(14)); addVersion("14-preview", new JavaLanguageHandler(14, true)); + addDefaultVersion("15", new JavaLanguageHandler(15)); // 15 is the default + addVersion("15-preview", new JavaLanguageHandler(15, true)); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclaration.java index c69197d8d1..6d7d3c0b6c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclaration.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceDeclaration.java @@ -4,7 +4,12 @@ package net.sourceforge.pmd.lang.java.ast; +import java.util.Collections; +import java.util.List; + +import net.sourceforge.pmd.annotation.Experimental; import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.util.CollectionUtil; /** @@ -67,4 +72,10 @@ public final class ASTClassOrInterfaceDeclaration extends AbstractAnyTypeDeclara return extendsList == null ? null : extendsList.iterator().next(); } + + @Experimental + public List getPermittedSubclasses() { + return ASTList.orEmpty(children(ASTPermitsList.class)); + } + } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLiteral.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLiteral.java index 71ba58d3a1..ee21bb1167 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLiteral.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTLiteral.java @@ -27,7 +27,6 @@ public interface ASTLiteral extends ASTPrimaryExpression { return this instanceof ASTStringLiteral; } - /** * Returns true if this is a {@linkplain ASTCharLiteral character literal}. */ 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 7df29d5c58..707be4e0cd 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 @@ -8,7 +8,7 @@ import net.sourceforge.pmd.annotation.Experimental; /** * A pattern (for pattern matching constructs like {@link ASTInstanceOfExpression InstanceOfExpression}). - * This is a JDK 14 preview feature and is subject to change. + * This is a JDK 14 and JDK 15 preview feature and is subject to change. * *

This interface will be implemented by all forms of patterns. For * now, only type test patterns are supported. Record deconstruction diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPermitsList.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPermitsList.java new file mode 100644 index 0000000000..890e4293d8 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTPermitsList.java @@ -0,0 +1,41 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast; + +import java.util.Iterator; + +import net.sourceforge.pmd.annotation.Experimental; + + +/** + * Represents the {@code permits} clause of a (sealed) class declaration. + * + *

This is a Java 15 Preview feature. + * + *

See https://openjdk.java.net/jeps/360 + * + *

+ *
+ *  PermittedSubclasses ::= "permits" (TypeAnnotation)* ClassOrInterfaceType
+ *                ( "," (TypeAnnotation)* ClassOrInterfaceType )*
+ * 
+ */ +@Experimental +public final class ASTPermitsList extends AbstractJavaNode implements Iterable { + + ASTPermitsList(int id) { + super(id); + } + + @Override + protected R acceptVisitor(JavaVisitor visitor, P data) { + return visitor.visit(this, data); + } + + @Override + public Iterator iterator() { + return children(ASTClassOrInterfaceType.class).iterator(); + } +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordBody.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordBody.java index e34163411f..63b2da1d0f 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordBody.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordBody.java @@ -8,7 +8,7 @@ package net.sourceforge.pmd.lang.java.ast; import net.sourceforge.pmd.annotation.Experimental; /** - * Defines the body of a {@linkplain ASTRecordDeclaration RecordDeclaration} (JDK 14 preview feature). + * Defines the body of a {@linkplain ASTRecordDeclaration RecordDeclaration} (JDK 14 and JDK 15 preview feature). * This can contain additional methods and or constructors. * *
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordComponent.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordComponent.java
index a296ecb8ef..59f60996b5 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordComponent.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordComponent.java
@@ -11,7 +11,7 @@ import net.sourceforge.pmd.lang.java.symbols.JClassSymbol;
 import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol;
 
 /**
- * Defines a single component of a {@linkplain ASTRecordDeclaration RecordDeclaration} (JDK 14 preview feature).
+ * Defines a single component of a {@linkplain ASTRecordDeclaration RecordDeclaration} (JDK 14 and JDK 15 preview feature).
  *
  * 

The varargs ellipsis {@code "..."} is parsed as an {@linkplain ASTArrayTypeDim array dimension} * in the type node. diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordComponentList.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordComponentList.java index 82cf139908..06b0ed909d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordComponentList.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordComponentList.java @@ -11,7 +11,7 @@ import net.sourceforge.pmd.lang.java.ast.InternalInterfaces.AllChildrenAreOfType import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol; /** - * Defines the state description of a {@linkplain ASTRecordDeclaration RecordDeclaration} (JDK 14 preview feature). + * Defines the state description of a {@linkplain ASTRecordDeclaration RecordDeclaration} (JDK 14 and JDK 15 preview feature). * *

  *
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordConstructorDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordConstructorDeclaration.java
index 3bffa597f2..d8039119ea 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordConstructorDeclaration.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordConstructorDeclaration.java
@@ -10,7 +10,7 @@ import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol;
 
 /**
  * This defines a compact constructor for a {@link ASTRecordDeclaration RecordDeclaration}
- * (JDK 14 preview feature). Compact constructors implicitly declares formal
+ * (JDK 14 and JDK 15 preview feature). Compact constructors implicitly declares formal
  * parameters corresponding to the record component list. These can be
  * fetched from {@link #getSymbol()}.
  *
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordDeclaration.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordDeclaration.java
index 71c421b23b..66f2eb700d 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordDeclaration.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTRecordDeclaration.java
@@ -12,7 +12,7 @@ import net.sourceforge.pmd.lang.ast.Node;
 import net.sourceforge.pmd.lang.ast.NodeStream;
 
 /**
- * A record declaration is a special data class type (JDK 14 preview feature).
+ * A record declaration is a special data class type (JDK 14 and JDK 15 preview feature).
  * This is a {@linkplain Node#isFindBoundary() find boundary} for tree traversal methods.
  *
  * 
@@ -27,7 +27,7 @@ import net.sourceforge.pmd.lang.ast.NodeStream;
  *
  * 
* - * @see JEP 359: Records (Preview) + * @see JEP 384: Records (Second Preview) */ @Experimental public final class ASTRecordDeclaration extends AbstractAnyTypeDeclaration { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java index 33fb67dc53..57534f8674 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/AbstractJavaNode.java @@ -50,6 +50,11 @@ abstract class AbstractJavaNode extends AbstractJjtreeNode { SWITCH_EXPRESSIONS(12, 13, true), SWITCH_RULES(12, 13, true), - TEXT_BLOCK_LITERALS(13, 14, false), + TEXT_BLOCK_LITERALS(13, 14, true), YIELD_STATEMENTS(13, 13, true), /** \s */ - SPACE_STRING_ESCAPES(14, 14, false), - RECORD_DECLARATIONS(14, 14, false), - TYPE_TEST_PATTERNS_IN_INSTANCEOF(14, 14, false); + SPACE_STRING_ESCAPES(14, 14, true), + RECORD_DECLARATIONS(14, 15, false), + TYPE_TEST_PATTERNS_IN_INSTANCEOF(14, 15, false), + SEALED_CLASSES(15, 15, false), + + ; // SUPPRESS CHECKSTYLE enum trailing semi is awesome private final int minPreviewVersion; @@ -473,6 +478,12 @@ public class LanguageLevelChecker { @Override public Void visit(ASTAnyTypeDeclaration node, T data) { + if ((node.getModifiers() & (AccessNode.SEALED | AccessNode.NON_SEALED)) != 0) { + check(node, PreviewFeature.SEALED_CLASSES, data); + } else if (node.isLocal() && node.getTypeKind() != TypeKind.CLASS) { + check(node, PreviewFeature.SEALED_CLASSES, data); + } + String simpleName = node.getSimpleName(); if ("var".equals(simpleName)) { check(node, ReservedIdentifiers.VAR_AS_A_TYPE_NAME, data); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/visitors/PMDASMVisitor.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/visitors/PMDASMVisitor.java index 3597ab88ca..e3fe30b2ac 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/visitors/PMDASMVisitor.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/typeresolution/visitors/PMDASMVisitor.java @@ -40,7 +40,7 @@ public class PMDASMVisitor extends ClassVisitor { public List innerClasses; public PMDASMVisitor(String outerName) { - super(Opcodes.ASM7); + super(Opcodes.ASM9); this.outerName = outerName; } @@ -181,7 +181,7 @@ public class PMDASMVisitor extends ClassVisitor { private PMDASMVisitor parent; PMDFieldVisitor(PMDASMVisitor visitor) { - super(Opcodes.ASM5); + super(Opcodes.ASM9); parent = visitor; } @@ -196,7 +196,7 @@ public class PMDASMVisitor extends ClassVisitor { private PMDASMVisitor parent; PMDAnnotationVisitor(PMDASMVisitor visitor) { - super(Opcodes.ASM5); + super(Opcodes.ASM9); parent = visitor; } @@ -228,7 +228,7 @@ public class PMDASMVisitor extends ClassVisitor { private PMDASMVisitor parent; PMDSignatureVisitor(PMDASMVisitor visitor) { - super(Opcodes.ASM5); + super(Opcodes.ASM9); this.parent = visitor; } @@ -292,7 +292,7 @@ public class PMDASMVisitor extends ClassVisitor { private PMDASMVisitor parent; PMDMethodVisitor(PMDASMVisitor visitor) { - super(Opcodes.ASM5); + super(Opcodes.ASM9); parent = visitor; } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/LanguageVersionDiscovererTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/LanguageVersionDiscovererTest.java index 98c660c09e..1961e37dfd 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/LanguageVersionDiscovererTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/LanguageVersionDiscovererTest.java @@ -26,8 +26,8 @@ public class LanguageVersionDiscovererTest { File javaFile = new File("/path/to/MyClass.java"); LanguageVersion languageVersion = discoverer.getDefaultLanguageVersionForFile(javaFile); - assertEquals("LanguageVersion must be Java 14 !", - LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("14"), languageVersion); + assertEquals("LanguageVersion must be Java 15 !", + LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("15"), languageVersion); } /** @@ -48,7 +48,7 @@ public class LanguageVersionDiscovererTest { public void testLanguageVersionDiscoverer() { PMDConfiguration configuration = new PMDConfiguration(); LanguageVersionDiscoverer languageVersionDiscoverer = configuration.getLanguageVersionDiscoverer(); - assertEquals("Default Java version", LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("14"), + assertEquals("Default Java version", LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("15"), languageVersionDiscoverer .getDefaultLanguageVersion(LanguageRegistry.getLanguage(JavaLanguageModule.NAME))); configuration diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/LanguageVersionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/LanguageVersionTest.java index e8a2bb5506..9197fe2f7c 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/LanguageVersionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/LanguageVersionTest.java @@ -52,6 +52,10 @@ public class LanguageVersionTest extends AbstractLanguageVersionTest { LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("14"), }, { JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "14-preview", LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("14-preview"), }, + { JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "15", + LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("15"), }, + { JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "15-preview", + LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("15-preview"), }, // this one won't be found: case sensitive! { "JAVA", "JAVA", "1.7", null, }, diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java13Test.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java13Test.java deleted file mode 100644 index fec0c374a4..0000000000 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java13Test.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.Ignore; -import org.junit.Test; - -import net.sourceforge.pmd.lang.ast.ParseException; -import net.sourceforge.pmd.lang.java.JavaParsingHelper; - -@Ignore("those tests depend on type resolution") -public class Java13Test { - - - private final JavaParsingHelper java12 = - JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("12") - .withResourceContext(getClass(), "jdkversiontests/java13/"); - - private final JavaParsingHelper java13p = java12.withDefaultVersion("13-preview"); - - @Test - public void testTextBlocks() { - ASTCompilationUnit compilationUnit = java13p.parseResource("TextBlocks.java"); - List literals = compilationUnit.findDescendantsOfType(ASTStringLiteral.class); - Assert.assertEquals(10, literals.size()); - for (int i = 0; i < 8; i++) { - ASTStringLiteral literal = literals.get(i); - Assert.assertTrue(literal.isTextBlock()); - } - Assert.assertEquals("\"\"\"\n" - + " \n" - + " \n" - + "

Hello, world

\n" - + " \n" - + " \n" - + " \"\"\"", - literals.get(0).getImage()); - Assert.assertFalse(literals.get(8).isTextBlock()); - Assert.assertTrue(literals.get(9).isTextBlock()); - } - - @Test(expected = ParseException.class) - public void testTextBlocksBeforeJava13() { - java12.parseResource("TextBlocks.java"); - } - -} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java14Test.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java14Test.java index dd08f3011c..4d171feed2 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java14Test.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java14Test.java @@ -29,15 +29,12 @@ public class Java14Test { private final JavaParsingHelper java14p = java14.withDefaultVersion("14-preview"); private final JavaParsingHelper java13 = java14.withDefaultVersion("13"); - private final JavaParsingHelper java13p = java14.withDefaultVersion("13-preview"); /** * Tests switch expressions with yield. - * The switch expressions have no changed between java 13-preview and 14, so behave exactly the same. */ @Test public void switchExpressions() { - parseAndCheckSwitchExpression(java13p); parseAndCheckSwitchExpression(java14); parseAndCheckSwitchExpression(java14p); } @@ -87,11 +84,6 @@ public class Java14Test { @Test public void checkYieldConditionalBehaviour() { - checkYieldStatements(java13p); - } - - @Test - public void checkYieldConditionalBehaviourJ14() { checkYieldStatements(java14); } @@ -142,7 +134,6 @@ public class Java14Test { @Test public void multipleCaseLabels() { - multipleCaseLabels(java13p); multipleCaseLabels(java14); multipleCaseLabels(java14p); } @@ -158,7 +149,6 @@ public class Java14Test { @Test public void switchRules() { - switchRules(java13p); switchRules(java14); switchRules(java14p); } @@ -186,7 +176,6 @@ public class Java14Test { @Test public void simpleSwitchExpressions() { - simpleSwitchExpressions(java13p); simpleSwitchExpressions(java14); simpleSwitchExpressions(java14p); } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java15PreviewTreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java15PreviewTreeDumpTest.java new file mode 100644 index 0000000000..739aedf86e --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java15PreviewTreeDumpTest.java @@ -0,0 +1,134 @@ +/* + * 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 Java15PreviewTreeDumpTest extends BaseTreeDumpTest { + private final JavaParsingHelper java15p = + JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("15-preview") + .withResourceContext(Java15PreviewTreeDumpTest.class, "jdkversiontests/java15p/"); + private final JavaParsingHelper java15 = java15p.withDefaultVersion("15"); + + public Java15PreviewTreeDumpTest() { + super(new RelevantAttributePrinter(), ".java"); + } + + @Override + public BaseParsingHelper getParser() { + return java15p; + } + + @Test + public void patternMatchingInstanceof() { + doTest("PatternMatchingInstanceof"); + + // extended tests for type resolution etc. + ASTCompilationUnit compilationUnit = java15p.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 patternMatchingInstanceofBeforeJava15PreviewShouldFail() { + java15.parseResource("PatternMatchingInstanceof.java"); + } + + @Test + public void recordPoint() { + doTest("Point"); + + // extended tests for type resolution etc. + ASTCompilationUnit compilationUnit = java15p.parseResource("Point.java"); + ASTRecordDeclaration recordDecl = compilationUnit.getFirstDescendantOfType(ASTRecordDeclaration.class); + List components = recordDecl.getFirstChildOfType(ASTRecordComponentList.class) + .findChildrenOfType(ASTRecordComponent.class); + Assert.assertNull(components.get(0).getVarId().getNameDeclaration().getAccessNodeParent()); + Assert.assertEquals(Integer.TYPE, components.get(0).getVarId().getNameDeclaration().getType()); + Assert.assertEquals("int", components.get(0).getVarId().getNameDeclaration().getTypeImage()); + } + + @Test(expected = ParseException.class) + public void recordPointBeforeJava15PreviewShouldFail() { + java15.parseResource("Point.java"); + } + + @Test(expected = ParseException.class) + public void recordCtorWithThrowsShouldFail() { + java15p.parse(" record R {" + + " R throws IOException {}" + + " }"); + } + + @Test(expected = ParseException.class) + public void recordMustNotExtend() { + java15p.parse("record RecordEx(int x) extends Number { }"); + } + + @Test + public void innerRecords() { + doTest("Records"); + } + + @Test(expected = ParseException.class) + public void recordIsARestrictedIdentifier() { + java15p.parse("public class record {}"); + } + + @Test + public void localRecords() { + doTest("LocalRecords"); + } + + @Test(expected = ParseException.class) + public void sealedClassBeforeJava15Preview() { + java15.parseResource("geometry/Shape.java"); + } + + @Test + public void sealedClass() { + doTest("geometry/Shape"); + } + + @Test + public void nonSealedClass() { + doTest("geometry/Square"); + } + + @Test(expected = ParseException.class) + public void sealedInterfaceBeforeJava15Preview() { + java15.parseResource("expression/Expr.java"); + } + + @Test + public void sealedInterface() { + doTest("expression/Expr"); + } + + @Test + public void localInterfaceAndEnums() { + doTest("LocalInterfacesAndEnums"); + } + + @Test(expected = ParseException.class) + public void localInterfacesAndEnumsBeforeJava15PreviewShouldFail() { + java15.parseResource("LocalInterfacesAndEnums.java"); + } +} diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java15TreeDumpTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java15TreeDumpTest.java new file mode 100644 index 0000000000..bed127076d --- /dev/null +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/Java15TreeDumpTest.java @@ -0,0 +1,52 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast; + +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 Java15TreeDumpTest extends BaseTreeDumpTest { + private final JavaParsingHelper java15 = + JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("15") + .withResourceContext(Java15TreeDumpTest.class, "jdkversiontests/java15/"); + private final JavaParsingHelper java15p = java15.withDefaultVersion("15-preview"); + private final JavaParsingHelper java14 = java15.withDefaultVersion("14"); + + public Java15TreeDumpTest() { + super(new RelevantAttributePrinter(), ".java"); + } + + @Override + public BaseParsingHelper getParser() { + return java15; + } + + @Test + public void textBlocks() { + doTest("TextBlocks"); + java15p.parseResource("TextBlocks.java"); // make sure we can parse it with preview as well + } + + @Test(expected = net.sourceforge.pmd.lang.ast.ParseException.class) + public void textBlocksBeforeJava15ShouldFail() { + java14.parseResource("TextBlocks.java"); + } + + @Test(expected = ParseException.class) + public void stringEscapeSequenceShouldFail() { + java14.parse("class Foo { String s =\"a\\sb\"; }"); + } + + @Test + public void sealedAndNonSealedIdentifiers() { + doTest("NonSealedIdentifier"); + java15p.parseResource("NonSealedIdentifier.java"); // make sure we can parse it with preview as well + } +} 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 91f570b0d6..71c359541a 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 @@ -7,22 +7,24 @@ package net.sourceforge.pmd.lang.java.ast import io.kotest.matchers.string.shouldContain import io.kotest.matchers.shouldBe import net.sourceforge.pmd.lang.ast.test.shouldBe +import net.sourceforge.pmd.lang.java.ast.JavaVersion import net.sourceforge.pmd.lang.java.ast.JavaVersion.J14__PREVIEW +import net.sourceforge.pmd.lang.java.ast.JavaVersion.J15__PREVIEW import java.io.IOException class ASTPatternTest : ParserTestSpec({ - parserTest("Test patterns only available on JDK 14 (preview)", javaVersions = !J14__PREVIEW) { + parserTest("Test patterns only available on JDK 14+15 (preview)", javaVersions = JavaVersion.except(J14__PREVIEW, J15__PREVIEW)) { + inContext(ExpressionParsingCtx) { "obj instanceof Class c" should throwParseException { - it.message.shouldContain("Type test patterns in instanceof is a preview feature of JDK 14, you should select your language version accordingly") + it.message.shouldContain("Type test patterns in instanceof is a preview feature of JDK") } } - } - parserTest("Test simple patterns", javaVersion = J14__PREVIEW) { + parserTest("Test simple patterns", javaVersions = listOf(J14__PREVIEW, J15__PREVIEW)) { importedTypes += IOException::class.java inContext(ExpressionParsingCtx) { diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/Java15KotlinTest.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/Java15KotlinTest.kt new file mode 100644 index 0000000000..6bc3facde9 --- /dev/null +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/Java15KotlinTest.kt @@ -0,0 +1,44 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.lang.java.ast + +import net.sourceforge.pmd.lang.ast.test.shouldBe + +class Java15KotlinTest: ParserTestSpec( { + + // Note: More tests are in ASTLiteralTest. + parserTest("textBlocks", javaVersions = JavaVersion.J15..JavaVersion.Latest) { + ("\"\"\"\n" + + " \n" + + " \n" + + "

Hello, world

\n" + + " \n" + + " \n" + + " \"\"\"") should matchExpr { + child { + child { + child { + it::isTextBlock shouldBe true + it::getEscapedStringLiteral shouldBe + "\"\"\"\n" + + " \n" + + " \n" + + "

Hello, world

\n" + + " \n" + + " \n" + + " \"\"\"" + it::getTextBlockContent shouldBe + "\n" + + " \n" + + "

Hello, world

\n" + + " \n" + + "\n" + } + } + } + } + } + +}) diff --git a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt index 43e53a893b..0c889e864b 100644 --- a/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt +++ b/pmd-java/src/test/kotlin/net/sourceforge/pmd/lang/java/ast/KotlinTestingDsl.kt @@ -28,8 +28,9 @@ import java.beans.PropertyDescriptor enum class JavaVersion : Comparable { J1_3, J1_4, J1_5, J1_6, J1_7, J1_8, J9, J10, J11, J12, - J13, J13__PREVIEW, - J14, J14__PREVIEW; + J13, + J14, J14__PREVIEW, + J15, J15__PREVIEW; /** Name suitable for use with e.g. [JavaParsingHelper.parse] */ val pmdName: String = name.removePrefix("J").replaceFirst("__", "-").replace('_', '.').toLowerCase() @@ -55,9 +56,10 @@ enum class JavaVersion : Comparable { val Latest = values().last() val Earliest = values().first() - fun except(vararg versions: JavaVersion) = values().toList() - versions - fun except(versions: List) = values().toList() - versions + fun except(v1: JavaVersion, vararg versions: JavaVersion) = + values().toList() - v1 - versions + fun except(versions: List) = values().toList() - versions } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java13/TextBlocks.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java13/TextBlocks.java deleted file mode 100644 index 78a6d111c3..0000000000 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java13/TextBlocks.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @see JEP 355: Text Blocks (Preview) - */ -public class TextBlocks { - - public static void main(String[] args) { - String html = """ - - -

Hello, world

- - - """; - - System.out.println(html); - - String season = """ - winter"""; // the six characters w i n t e r - - String period = """ - winter - """; // the seven characters w i n t e r LF - - String greeting = - """ - Hi, "Bob" - """; // the ten characters H i , SP " B o b " LF - - String salutation = - """ - Hi, - "Bob" - """; // the eleven characters H i , LF SP " B o b " LF - - String empty = """ - """; // the empty string (zero length) - - String quote = """ - " - """; // the two characters " LF - - String backslash = """ - \\ - """; // the two characters \ LF - - String normalStringLiteral = "test"; - - String code = - """ - String text = \""" - A text block inside a text block - \"""; - """; - } -} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/NonSealedIdentifier.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/NonSealedIdentifier.java new file mode 100644 index 0000000000..dbeebe9403 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/NonSealedIdentifier.java @@ -0,0 +1,15 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +public class NonSealedIdentifier { + public static void main(String[] args) { + int result = 0; + int non = 1; + // sealed is a valid identifier name in both Java15 and Java15 Preview + int sealed = 2; + // non-sealed is a valid subtraction expression in both Java15 and Java15 Preview + result = non-sealed; + System.out.println(result); + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/NonSealedIdentifier.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/NonSealedIdentifier.txt new file mode 100644 index 0000000000..bcd2128440 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/NonSealedIdentifier.txt @@ -0,0 +1,76 @@ ++- CompilationUnit[@PackageName = "", @declarationsAreInDefaultPackage = true] + +- TypeDeclaration[] + +- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "NonSealedIdentifier", @Default = false, @Final = false, @Image = "NonSealedIdentifier", @Interface = false, @Local = false, @Modifiers = 1, @Native = false, @Nested = false, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = false, @SimpleName = "NonSealedIdentifier", @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 = "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 = 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 = "result", @Volatile = false] + | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "int"] + | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | +- VariableDeclarator[@Initializer = true, @Name = "result"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "result", @LambdaParameter = false, @LocalVariable = true, @Name = "result", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "result"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = true] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = "0", @FloatLiteral = false, @Image = "0", @IntLiteral = true, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = false, @TextBlock = false, @TextBlockContent = "0", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- 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 = "non", @Volatile = false] + | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "int"] + | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | +- VariableDeclarator[@Initializer = true, @Name = "non"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "non", @LambdaParameter = false, @LocalVariable = true, @Name = "non", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "non"] + | +- VariableInitializer[] + | +- 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] + | +- 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 = "sealed", @Volatile = false] + | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "int"] + | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | +- VariableDeclarator[@Initializer = true, @Name = "sealed"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "sealed", @LambdaParameter = false, @LocalVariable = true, @Name = "sealed", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "sealed"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = true] + | +- 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] + +- BlockStatement[@Allocation = false] + | +- Statement[] + | +- StatementExpression[] + | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "result"] + | +- AssignmentOperator[@Compound = false, @Image = "="] + | +- Expression[@StandAlonePrimitive = false] + | +- AdditiveExpression[@Image = "-", @Operator = "-"] + | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "non"] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Name[@Image = "sealed"] + +- 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] + +- PrimaryExpression[] + +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + +- Name[@Image = "result"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/TextBlocks.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/TextBlocks.java new file mode 100644 index 0000000000..0876748bb0 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/TextBlocks.java @@ -0,0 +1,119 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; + +/** + * Text Blocks are a permanent language feature with JDK 15. + * + * @see + +

Hello, world

+ + + """; + System.out.println(html); + + String query = """ + SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB` + WHERE `CITY` = 'INDIANAPOLIS' + ORDER BY `EMP_ID`, `LAST_NAME`; + """; + System.out.println(query); + + ScriptEngine engine = new ScriptEngineManager().getEngineByName("js"); + Object obj = engine.eval(""" + function hello() { + print('"Hello, world"'); + } + + hello(); + """); + + // Escape sequences + String htmlWithEscapes = """ + \r + \r +

Hello, world

\r + \r + \r + """; + System.out.println(htmlWithEscapes); + + String season = """ + winter"""; // the six characters w i n t e r + + String period = """ + winter + """; // the seven characters w i n t e r LF + + String greeting = + """ + Hi, "Bob" + """; // the ten characters H i , SP " B o b " LF + + String salutation = + """ + Hi, + "Bob" + """; // the eleven characters H i , LF SP " B o b " LF + + String empty = """ + """; // the empty string (zero length) + + String quote = """ + " + """; // the two characters " LF + + String backslash = """ + \\ + """; // the two characters \ LF + + String normalStringLiteral = "test"; + + String code = + """ + String text = \""" + A text block inside a text block + \"""; + """; + + // new escape sequences + String text = """ + Lorem ipsum dolor sit amet, consectetur adipiscing \ + elit, sed do eiusmod tempor incididunt ut labore \ + et dolore magna aliqua.\ + """; + System.out.println(text); + + String colors = """ + red \s + green\s + blue \s + """; + System.out.println(colors); + + // empty new line as first content + String emptyLine = """ + +test +"""; + System.out.println(emptyLine.replaceAll("\n", "")); + + // backslash escapes + String bs = """ + \\test + """; + System.out.println(bs.replaceAll("\n", "")); + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/TextBlocks.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/TextBlocks.txt new file mode 100644 index 0000000000..6a14ab0115 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15/TextBlocks.txt @@ -0,0 +1,510 @@ ++- CompilationUnit[@PackageName = "", @declarationsAreInDefaultPackage = true] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "javax.script.ScriptEngine", @ImportedSimpleName = "ScriptEngine", @PackageName = "javax.script", @Static = false] + | +- Name[@Image = "javax.script.ScriptEngine"] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "javax.script.ScriptEngineManager", @ImportedSimpleName = "ScriptEngineManager", @PackageName = "javax.script", @Static = false] + | +- Name[@Image = "javax.script.ScriptEngineManager"] + +- TypeDeclaration[] + +- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "TextBlocks", @Default = false, @Final = false, @Image = "TextBlocks", @Interface = false, @Local = false, @Modifiers = 1, @Native = false, @Nested = false, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = false, @SimpleName = "TextBlocks", @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 = "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"] + +- NameList[] + | +- Name[@Image = "Exception"] + +- 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 = "html", @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 = "html"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "html", @LambdaParameter = false, @LocalVariable = true, @Name = "html", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "html"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """" + + +

Hello, world

+ + + """", @FloatLiteral = false, @Image = """" + + +

Hello, world

+ + + """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = " + +

Hello, world

+ + +", @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] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Name[@Image = "html"] + +- 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 = "query", @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 = "query"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "query", @LambdaParameter = false, @LocalVariable = true, @Name = "query", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "query"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """" + SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB` + WHERE `CITY` = 'INDIANAPOLIS' + ORDER BY `EMP_ID`, `LAST_NAME`; + """", @FloatLiteral = false, @Image = """" + SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB` + WHERE `CITY` = 'INDIANAPOLIS' + ORDER BY `EMP_ID`, `LAST_NAME`; + """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = "SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB` +WHERE `CITY` = 'INDIANAPOLIS' +ORDER BY `EMP_ID`, `LAST_NAME`; +", @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] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Name[@Image = "query"] + +- BlockStatement[@Allocation = true] + | +- 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 = "engine", @Volatile = false] + | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "ScriptEngine"] + | | +- ReferenceType[@Array = false, @ArrayDepth = 0] + | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "ScriptEngine", @ReferenceToClassSameCompilationUnit = false] + | +- VariableDeclarator[@Initializer = true, @Name = "engine"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "engine", @LambdaParameter = false, @LocalVariable = true, @Name = "engine", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "engine"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- AllocationExpression[@AnonymousClass = false] + | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "ScriptEngineManager", @ReferenceToClassSameCompilationUnit = false] + | | +- Arguments[@ArgumentCount = 0, @Size = 0] + | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @Image = "getEngineByName"] + | +- 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 = ""js"", @FloatLiteral = false, @Image = ""js"", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""js"", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- 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] + | | +- Name[@Image = "engine.eval"] + | +- 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 = """" + function hello() { + print('"Hello, world"'); + } + + hello(); + """", @FloatLiteral = false, @Image = """" + function hello() { + print('"Hello, world"'); + } + + hello(); + """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = "function hello() { + print('"Hello, world"'); +} + +hello(); +", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- 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 = "htmlWithEscapes", @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 = "htmlWithEscapes"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "htmlWithEscapes", @LambdaParameter = false, @LocalVariable = true, @Name = "htmlWithEscapes", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "htmlWithEscapes"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """" + + +

Hello, world

+ + + """", @FloatLiteral = false, @Image = """" + + +

Hello, world

+ + + """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = " + +

Hello, world

+ + +", @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] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Name[@Image = "htmlWithEscapes"] + +- 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 = "season", @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 = "season"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "season", @LambdaParameter = false, @LocalVariable = true, @Name = "season", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "season"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """" + winter"""", @FloatLiteral = false, @Image = """" + winter"""", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = "winter", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- 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 = "period", @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 = "period"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "period", @LambdaParameter = false, @LocalVariable = true, @Name = "period", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "period"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """" + winter + """", @FloatLiteral = false, @Image = """" + winter + """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = "winter +", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- 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 = "greeting", @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 = "greeting"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "greeting", @LambdaParameter = false, @LocalVariable = true, @Name = "greeting", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "greeting"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """" + Hi, "Bob" + """", @FloatLiteral = false, @Image = """" + Hi, "Bob" + """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = "Hi, "Bob" +", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- 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 = "salutation", @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 = "salutation"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "salutation", @LambdaParameter = false, @LocalVariable = true, @Name = "salutation", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "salutation"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """" + Hi, + "Bob" + """", @FloatLiteral = false, @Image = """" + Hi, + "Bob" + """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = "Hi, + "Bob" +", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- 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 = "empty", @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 = "empty"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "empty", @LambdaParameter = false, @LocalVariable = true, @Name = "empty", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "empty"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """" + """", @FloatLiteral = false, @Image = """" + """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- 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 = "quote", @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 = "quote"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "quote", @LambdaParameter = false, @LocalVariable = true, @Name = "quote", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "quote"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """" + " + """", @FloatLiteral = false, @Image = """" + " + """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = "" +", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- 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 = "backslash", @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 = "backslash"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "backslash", @LambdaParameter = false, @LocalVariable = true, @Name = "backslash", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "backslash"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """" + \ + """", @FloatLiteral = false, @Image = """" + \ + """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = " +", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- 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 = "normalStringLiteral", @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 = "normalStringLiteral"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "normalStringLiteral", @LambdaParameter = false, @LocalVariable = true, @Name = "normalStringLiteral", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "normalStringLiteral"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""test"", @FloatLiteral = false, @Image = ""test"", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""test"", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- 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 = "code", @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 = "code"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "code", @LambdaParameter = false, @LocalVariable = true, @Name = "code", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "code"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """" + String text = """ + A text block inside a text block + """; + """", @FloatLiteral = false, @Image = """" + String text = """ + A text block inside a text block + """; + """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = "String text = """ + A text block inside a text block +"""; +", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- 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 = "text", @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 = "text"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "text", @LambdaParameter = false, @LocalVariable = true, @Name = "text", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "text"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """" + Lorem ipsum dolor sit amet, consectetur adipiscing + elit, sed do eiusmod tempor incididunt ut labore + et dolore magna aliqua. + """", @FloatLiteral = false, @Image = """" + Lorem ipsum dolor sit amet, consectetur adipiscing + elit, sed do eiusmod tempor incididunt ut labore + et dolore magna aliqua. + """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", @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] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Name[@Image = "text"] + +- 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 = "colors", @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 = "colors"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "colors", @LambdaParameter = false, @LocalVariable = true, @Name = "colors", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "colors"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """" + red s + greens + blue s + """", @FloatLiteral = false, @Image = """" + red s + greens + blue s + """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = "red +green +blue +", @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] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Name[@Image = "colors"] + +- 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 = "emptyLine", @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 = "emptyLine"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "emptyLine", @LambdaParameter = false, @LocalVariable = true, @Name = "emptyLine", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "emptyLine"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """" + +test +"""", @FloatLiteral = false, @Image = """" + +test +"""", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = " +test +", @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] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "emptyLine.replaceAll"] + | +- PrimarySuffix[@ArgumentCount = 2, @Arguments = true, @ArrayDereference = false] + | +- Arguments[@ArgumentCount = 2, @Size = 2] + | +- ArgumentList[@Size = 2] + | +- Expression[@StandAlonePrimitive = false] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = "" +"", @FloatLiteral = false, @Image = "" +"", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = true, @StringLiteral = true, @TextBlock = false, @TextBlockContent = "" +"", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """", @FloatLiteral = false, @Image = """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = """", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- 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 = "bs", @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 = "bs"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "bs", @LambdaParameter = false, @LocalVariable = true, @Name = "bs", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "bs"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """" + \test + """", @FloatLiteral = false, @Image = """" + \test + """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = true, @TextBlockContent = " est +", @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] + +- PrimaryExpression[] + +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Name[@Image = "bs.replaceAll"] + +- PrimarySuffix[@ArgumentCount = 2, @Arguments = true, @ArrayDereference = false] + +- Arguments[@ArgumentCount = 2, @Size = 2] + +- ArgumentList[@Size = 2] + +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = "" +"", @FloatLiteral = false, @Image = "" +"", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = true, @StringLiteral = true, @TextBlock = false, @TextBlockContent = "" +"", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- Expression[@StandAlonePrimitive = false] + +- PrimaryExpression[] + +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = """", @FloatLiteral = false, @Image = """", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = """", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/LocalInterfacesAndEnums.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/LocalInterfacesAndEnums.java new file mode 100644 index 0000000000..0897eb27a4 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/LocalInterfacesAndEnums.java @@ -0,0 +1,19 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +public class LocalInterfacesAndEnums { + + { + class MyLocalClass {} + + // static local classes are not allowed (neither Java15 nor Java15 Preview) + //static class MyLocalStaticClass {} + + interface MyLocalInterface {} + + enum MyLocalEnum { A } + + @interface MyLocalAnnotation {} + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/LocalInterfacesAndEnums.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/LocalInterfacesAndEnums.txt new file mode 100644 index 0000000000..d2fcaa476a --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/LocalInterfacesAndEnums.txt @@ -0,0 +1,20 @@ ++- CompilationUnit[@PackageName = "", @declarationsAreInDefaultPackage = true] + +- TypeDeclaration[] + +- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "LocalInterfacesAndEnums", @Default = false, @Final = false, @Image = "LocalInterfacesAndEnums", @Interface = false, @Local = false, @Modifiers = 1, @Native = false, @Nested = false, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = false, @SimpleName = "LocalInterfacesAndEnums", @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.INITIALIZER] + +- Initializer[@Static = false] + +- Block[@containsComment = false] + +- BlockStatement[@Allocation = false] + | +- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "LocalInterfacesAndEnums$1MyLocalClass", @Default = false, @Final = false, @Image = "MyLocalClass", @Interface = false, @Local = true, @Modifiers = 0, @Native = false, @Nested = false, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = false, @Sealed = false, @SimpleName = "MyLocalClass", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.CLASS, @Volatile = false] + | +- ClassOrInterfaceBody[@AnonymousInnerClass = false, @EnumChild = false] + +- BlockStatement[@Allocation = false] + | +- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "LocalInterfacesAndEnums$1MyLocalInterface", @Default = false, @Final = false, @Image = "MyLocalInterface", @Interface = true, @Local = true, @Modifiers = 0, @Native = false, @Nested = false, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = false, @Sealed = false, @SimpleName = "MyLocalInterface", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.INTERFACE, @Volatile = false] + | +- ClassOrInterfaceBody[@AnonymousInnerClass = false, @EnumChild = false] + +- BlockStatement[@Allocation = false] + | +- EnumDeclaration[@Abstract = false, @BinaryName = "LocalInterfacesAndEnums$MyLocalEnum", @Default = false, @Final = false, @Image = "MyLocalEnum", @Local = true, @Modifiers = 0, @Native = false, @Nested = false, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @SimpleName = "MyLocalEnum", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.ENUM, @Volatile = false] + | +- EnumBody[] + | +- EnumConstant[@AnonymousClass = false, @Image = "A"] + +- BlockStatement[@Allocation = false] + +- AnnotationTypeDeclaration[@Abstract = false, @BinaryName = "LocalInterfacesAndEnums$MyLocalAnnotation", @Default = false, @Final = false, @Image = "MyLocalAnnotation", @Local = true, @Modifiers = 0, @Native = false, @Nested = false, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @SimpleName = "MyLocalAnnotation", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.ANNOTATION, @Volatile = false] + +- AnnotationTypeBody[] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/LocalRecords.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/LocalRecords.java new file mode 100644 index 0000000000..c359b99419 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/LocalRecords.java @@ -0,0 +1,45 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +import java.util.stream.Collectors; +import java.util.List; + +/** + * @see
JEP 384: Records (Second Preview) + */ +public class LocalRecords { + public interface Merchant {} + public static double computeSales(Merchant merchant, int month) { + return month; + } + List findTopMerchants(List merchants, int month) { + // Local record + record MerchantSales(Merchant merchant, double sales) {} + + return merchants.stream() + .map(merchant -> new MerchantSales(merchant, computeSales(merchant, month))) + .sorted((m1, m2) -> Double.compare(m2.sales(), m1.sales())) + .map(MerchantSales::merchant) + .collect(Collectors.toList()); + } + + void methodWithLocalRecordAndModifiers() { + final record MyRecord1(String a) {} + final static record MyRecord2(String a) {} + @Deprecated record MyRecord3(String a) {} + final @Deprecated static record MyRecord4(String a) {} + } + + void methodWithLocalClass() { + class MyLocalClass {} + } + + void methodWithLocalVarsNamedSealed() { + int result = 0; + int non = 1; + int sealed = 2; + result = non-sealed; + System.out.println(result); + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/LocalRecords.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/LocalRecords.txt new file mode 100644 index 0000000000..c274834840 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/LocalRecords.txt @@ -0,0 +1,292 @@ ++- CompilationUnit[@PackageName = "", @declarationsAreInDefaultPackage = true] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.stream.Collectors", @ImportedSimpleName = "Collectors", @PackageName = "java.util.stream", @Static = false] + | +- Name[@Image = "java.util.stream.Collectors"] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.util.List", @ImportedSimpleName = "List", @PackageName = "java.util", @Static = false] + | +- Name[@Image = "java.util.List"] + +- TypeDeclaration[] + +- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "LocalRecords", @Default = false, @Final = false, @Image = "LocalRecords", @Interface = false, @Local = false, @Modifiers = 1, @Native = false, @Nested = false, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = false, @SimpleName = "LocalRecords", @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.INTERFACE] + | +- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "LocalRecords$Merchant", @Default = false, @Final = false, @Image = "Merchant", @Interface = true, @Local = false, @Modifiers = 1, @Native = false, @Nested = true, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = false, @SimpleName = "Merchant", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.INTERFACE, @Volatile = false] + | +- ClassOrInterfaceBody[@AnonymousInnerClass = false, @EnumChild = false] + +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.METHOD] + | +- MethodDeclaration[@Abstract = false, @Arity = 2, @Default = false, @Final = false, @InterfaceMember = false, @Kind = MethodLikeKind.METHOD, @MethodName = "computeSales", @Modifiers = 17, @Name = "computeSales", @Native = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Static = true, @Strictfp = false, @Synchronized = false, @SyntacticallyAbstract = false, @SyntacticallyPublic = true, @Transient = false, @Void = false, @Volatile = false] + | +- ResultType[@Void = false, @returnsArray = false] + | | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "double"] + | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "double"] + | +- MethodDeclarator[@Image = "computeSales", @ParameterCount = 2] + | | +- FormalParameters[@ParameterCount = 2, @Size = 2] + | | +- 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 = "Merchant"] + | | | | +- ReferenceType[@Array = false, @ArrayDepth = 0] + | | | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Merchant", @ReferenceToClassSameCompilationUnit = true] + | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = true, @Image = "merchant", @LambdaParameter = false, @LocalVariable = false, @Name = "merchant", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "merchant"] + | | +- 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 = "int"] + | | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = true, @Image = "month", @LambdaParameter = false, @LocalVariable = false, @Name = "month", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "month"] + | +- Block[@containsComment = false] + | +- BlockStatement[@Allocation = false] + | +- Statement[] + | +- ReturnStatement[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Name[@Image = "month"] + +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.METHOD] + | +- MethodDeclaration[@Abstract = false, @Arity = 2, @Default = false, @Final = false, @InterfaceMember = false, @Kind = MethodLikeKind.METHOD, @MethodName = "findTopMerchants", @Modifiers = 0, @Name = "findTopMerchants", @Native = false, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @Static = false, @Strictfp = false, @Synchronized = false, @SyntacticallyAbstract = false, @SyntacticallyPublic = false, @Transient = false, @Void = false, @Volatile = false] + | +- ResultType[@Void = false, @returnsArray = false] + | | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "List"] + | | +- ReferenceType[@Array = false, @ArrayDepth = 0] + | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "List", @ReferenceToClassSameCompilationUnit = false] + | | +- TypeArguments[@Diamond = false] + | | +- TypeArgument[@Wildcard = false] + | | +- ReferenceType[@Array = false, @ArrayDepth = 0] + | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Merchant", @ReferenceToClassSameCompilationUnit = true] + | +- MethodDeclarator[@Image = "findTopMerchants", @ParameterCount = 2] + | | +- FormalParameters[@ParameterCount = 2, @Size = 2] + | | +- 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 = "List"] + | | | | +- ReferenceType[@Array = false, @ArrayDepth = 0] + | | | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "List", @ReferenceToClassSameCompilationUnit = false] + | | | | +- TypeArguments[@Diamond = false] + | | | | +- TypeArgument[@Wildcard = false] + | | | | +- ReferenceType[@Array = false, @ArrayDepth = 0] + | | | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Merchant", @ReferenceToClassSameCompilationUnit = true] + | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = true, @Image = "merchants", @LambdaParameter = false, @LocalVariable = false, @Name = "merchants", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "merchants"] + | | +- 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 = "int"] + | | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = true, @Image = "month", @LambdaParameter = false, @LocalVariable = false, @Name = "month", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "month"] + | +- Block[@containsComment = false] + | +- BlockStatement[@Allocation = false] + | | +- RecordDeclaration[@Abstract = false, @BinaryName = "LocalRecords$MerchantSales", @Default = false, @Final = true, @Image = "MerchantSales", @Local = true, @Modifiers = 0, @Native = false, @Nested = false, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @SimpleName = "MerchantSales", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.RECORD, @Volatile = false] + | | +- RecordComponentList[@Size = 2] + | | | +- RecordComponent[@Varargs = false] + | | | | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "Merchant"] + | | | | | +- ReferenceType[@Array = false, @ArrayDepth = 0] + | | | | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Merchant", @ReferenceToClassSameCompilationUnit = true] + | | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "merchant", @LambdaParameter = false, @LocalVariable = false, @Name = "merchant", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "merchant"] + | | | +- RecordComponent[@Varargs = false] + | | | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "double"] + | | | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "double"] + | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "sales", @LambdaParameter = false, @LocalVariable = false, @Name = "sales", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "sales"] + | | +- RecordBody[] + | +- BlockStatement[@Allocation = false] + | +- Statement[] + | +- ReturnStatement[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "merchants.stream"] + | +- PrimarySuffix[@ArgumentCount = 0, @Arguments = true, @ArrayDereference = false] + | | +- Arguments[@ArgumentCount = 0, @Size = 0] + | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @Image = "map"] + | +- PrimarySuffix[@ArgumentCount = 1, @Arguments = true, @ArrayDereference = false] + | | +- Arguments[@ArgumentCount = 1, @Size = 1] + | | +- ArgumentList[@Size = 1] + | | +- Expression[@StandAlonePrimitive = false] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- LambdaExpression[@Abstract = false, @Default = false, @Final = false, @Kind = MethodLikeKind.LAMBDA, @Modifiers = 0, @Native = false, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @Volatile = false] + | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = true, @Image = "merchant", @LambdaParameter = true, @LocalVariable = false, @Name = "merchant", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = true, @VariableName = "merchant"] + | | +- Expression[@StandAlonePrimitive = false] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- AllocationExpression[@AnonymousClass = false] + | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "MerchantSales", @ReferenceToClassSameCompilationUnit = false] + | | +- Arguments[@ArgumentCount = 2, @Size = 2] + | | +- ArgumentList[@Size = 2] + | | +- Expression[@StandAlonePrimitive = false] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "merchant"] + | | +- Expression[@StandAlonePrimitive = false] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "computeSales"] + | | +- PrimarySuffix[@ArgumentCount = 2, @Arguments = true, @ArrayDereference = false] + | | +- Arguments[@ArgumentCount = 2, @Size = 2] + | | +- ArgumentList[@Size = 2] + | | +- Expression[@StandAlonePrimitive = false] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "merchant"] + | | +- Expression[@StandAlonePrimitive = false] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "month"] + | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @Image = "sorted"] + | +- PrimarySuffix[@ArgumentCount = 1, @Arguments = true, @ArrayDereference = false] + | | +- Arguments[@ArgumentCount = 1, @Size = 1] + | | +- ArgumentList[@Size = 1] + | | +- Expression[@StandAlonePrimitive = false] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- LambdaExpression[@Abstract = false, @Default = false, @Final = false, @Kind = MethodLikeKind.LAMBDA, @Modifiers = 0, @Native = false, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @Volatile = false] + | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = true, @Image = "m1", @LambdaParameter = true, @LocalVariable = false, @Name = "m1", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = true, @VariableName = "m1"] + | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = true, @Image = "m2", @LambdaParameter = true, @LocalVariable = false, @Name = "m2", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = true, @VariableName = "m2"] + | | +- Expression[@StandAlonePrimitive = false] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "Double.compare"] + | | +- PrimarySuffix[@ArgumentCount = 2, @Arguments = true, @ArrayDereference = false] + | | +- Arguments[@ArgumentCount = 2, @Size = 2] + | | +- ArgumentList[@Size = 2] + | | +- Expression[@StandAlonePrimitive = false] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Name[@Image = "m2.sales"] + | | | +- PrimarySuffix[@ArgumentCount = 0, @Arguments = true, @ArrayDereference = false] + | | | +- Arguments[@ArgumentCount = 0, @Size = 0] + | | +- Expression[@StandAlonePrimitive = false] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "m1.sales"] + | | +- PrimarySuffix[@ArgumentCount = 0, @Arguments = true, @ArrayDereference = false] + | | +- Arguments[@ArgumentCount = 0, @Size = 0] + | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @Image = "map"] + | +- PrimarySuffix[@ArgumentCount = 1, @Arguments = true, @ArrayDereference = false] + | | +- Arguments[@ArgumentCount = 1, @Size = 1] + | | +- ArgumentList[@Size = 1] + | | +- Expression[@StandAlonePrimitive = false] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "MerchantSales"] + | | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false] + | | +- MemberSelector[] + | | +- MethodReference[@Image = "merchant"] + | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @Image = "collect"] + | +- PrimarySuffix[@ArgumentCount = 1, @Arguments = true, @ArrayDereference = false] + | +- Arguments[@ArgumentCount = 1, @Size = 1] + | +- ArgumentList[@Size = 1] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "Collectors.toList"] + | +- PrimarySuffix[@ArgumentCount = 0, @Arguments = true, @ArrayDereference = false] + | +- Arguments[@ArgumentCount = 0, @Size = 0] + +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.METHOD] + | +- MethodDeclaration[@Abstract = false, @Arity = 0, @Default = false, @Final = false, @InterfaceMember = false, @Kind = MethodLikeKind.METHOD, @MethodName = "methodWithLocalRecordAndModifiers", @Modifiers = 0, @Name = "methodWithLocalRecordAndModifiers", @Native = false, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @Static = false, @Strictfp = false, @Synchronized = false, @SyntacticallyAbstract = false, @SyntacticallyPublic = false, @Transient = false, @Void = true, @Volatile = false] + | +- ResultType[@Void = true, @returnsArray = false] + | +- MethodDeclarator[@Image = "methodWithLocalRecordAndModifiers", @ParameterCount = 0] + | | +- FormalParameters[@ParameterCount = 0, @Size = 0] + | +- Block[@containsComment = false] + | +- BlockStatement[@Allocation = false] + | | +- RecordDeclaration[@Abstract = false, @BinaryName = "LocalRecords$MyRecord1", @Default = false, @Final = true, @Image = "MyRecord1", @Local = true, @Modifiers = 32, @Native = false, @Nested = false, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @SimpleName = "MyRecord1", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.RECORD, @Volatile = false] + | | +- RecordComponentList[@Size = 1] + | | | +- RecordComponent[@Varargs = 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] + | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "a", @LambdaParameter = false, @LocalVariable = false, @Name = "a", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "a"] + | | +- RecordBody[] + | +- BlockStatement[@Allocation = false] + | | +- RecordDeclaration[@Abstract = false, @BinaryName = "LocalRecords$MyRecord2", @Default = false, @Final = true, @Image = "MyRecord2", @Local = true, @Modifiers = 48, @Native = false, @Nested = false, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @SimpleName = "MyRecord2", @Static = true, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.RECORD, @Volatile = false] + | | +- RecordComponentList[@Size = 1] + | | | +- RecordComponent[@Varargs = 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] + | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "a", @LambdaParameter = false, @LocalVariable = false, @Name = "a", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "a"] + | | +- RecordBody[] + | +- BlockStatement[@Allocation = false] + | | +- Annotation[@AnnotationName = "Deprecated"] + | | | +- MarkerAnnotation[@AnnotationName = "Deprecated"] + | | | +- Name[@Image = "Deprecated"] + | | +- RecordDeclaration[@Abstract = false, @BinaryName = "LocalRecords$MyRecord3", @Default = false, @Final = true, @Image = "MyRecord3", @Local = true, @Modifiers = 0, @Native = false, @Nested = false, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @SimpleName = "MyRecord3", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.RECORD, @Volatile = false] + | | +- RecordComponentList[@Size = 1] + | | | +- RecordComponent[@Varargs = 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] + | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "a", @LambdaParameter = false, @LocalVariable = false, @Name = "a", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "a"] + | | +- RecordBody[] + | +- BlockStatement[@Allocation = false] + | +- Annotation[@AnnotationName = "Deprecated"] + | | +- MarkerAnnotation[@AnnotationName = "Deprecated"] + | | +- Name[@Image = "Deprecated"] + | +- RecordDeclaration[@Abstract = false, @BinaryName = "LocalRecords$MyRecord4", @Default = false, @Final = true, @Image = "MyRecord4", @Local = true, @Modifiers = 48, @Native = false, @Nested = false, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @SimpleName = "MyRecord4", @Static = true, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.RECORD, @Volatile = false] + | +- RecordComponentList[@Size = 1] + | | +- RecordComponent[@Varargs = 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] + | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "a", @LambdaParameter = false, @LocalVariable = false, @Name = "a", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "a"] + | +- RecordBody[] + +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.METHOD] + | +- MethodDeclaration[@Abstract = false, @Arity = 0, @Default = false, @Final = false, @InterfaceMember = false, @Kind = MethodLikeKind.METHOD, @MethodName = "methodWithLocalClass", @Modifiers = 0, @Name = "methodWithLocalClass", @Native = false, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @Static = false, @Strictfp = false, @Synchronized = false, @SyntacticallyAbstract = false, @SyntacticallyPublic = false, @Transient = false, @Void = true, @Volatile = false] + | +- ResultType[@Void = true, @returnsArray = false] + | +- MethodDeclarator[@Image = "methodWithLocalClass", @ParameterCount = 0] + | | +- FormalParameters[@ParameterCount = 0, @Size = 0] + | +- Block[@containsComment = false] + | +- BlockStatement[@Allocation = false] + | +- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "LocalRecords$1MyLocalClass", @Default = false, @Final = false, @Image = "MyLocalClass", @Interface = false, @Local = true, @Modifiers = 0, @Native = false, @Nested = false, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = false, @Sealed = false, @SimpleName = "MyLocalClass", @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 = 0, @Default = false, @Final = false, @InterfaceMember = false, @Kind = MethodLikeKind.METHOD, @MethodName = "methodWithLocalVarsNamedSealed", @Modifiers = 0, @Name = "methodWithLocalVarsNamedSealed", @Native = false, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @Static = false, @Strictfp = false, @Synchronized = false, @SyntacticallyAbstract = false, @SyntacticallyPublic = false, @Transient = false, @Void = true, @Volatile = false] + +- ResultType[@Void = true, @returnsArray = false] + +- MethodDeclarator[@Image = "methodWithLocalVarsNamedSealed", @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 = "result", @Volatile = false] + | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "int"] + | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | +- VariableDeclarator[@Initializer = true, @Name = "result"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "result", @LambdaParameter = false, @LocalVariable = true, @Name = "result", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "result"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = true] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = "0", @FloatLiteral = false, @Image = "0", @IntLiteral = true, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = false, @TextBlock = false, @TextBlockContent = "0", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- 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 = "non", @Volatile = false] + | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "int"] + | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | +- VariableDeclarator[@Initializer = true, @Name = "non"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "non", @LambdaParameter = false, @LocalVariable = true, @Name = "non", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "non"] + | +- VariableInitializer[] + | +- 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] + | +- 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 = "sealed", @Volatile = false] + | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "int"] + | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | +- VariableDeclarator[@Initializer = true, @Name = "sealed"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "sealed", @LambdaParameter = false, @LocalVariable = true, @Name = "sealed", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "sealed"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = true] + | +- 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] + +- BlockStatement[@Allocation = false] + | +- Statement[] + | +- StatementExpression[] + | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "result"] + | +- AssignmentOperator[@Compound = false, @Image = "="] + | +- Expression[@StandAlonePrimitive = false] + | +- AdditiveExpression[@Image = "-", @Operator = "-"] + | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "non"] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Name[@Image = "sealed"] + +- 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] + +- PrimaryExpression[] + +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + +- Name[@Image = "result"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/PatternMatchingInstanceof.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/PatternMatchingInstanceof.java new file mode 100644 index 0000000000..c541b5c8c0 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/PatternMatchingInstanceof.java @@ -0,0 +1,34 @@ +/** + * + * @see JEP 375: Pattern Matching for instanceof (Second Preview) + */ +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 + } 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 + } + } + + 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/java15p/PatternMatchingInstanceof.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/PatternMatchingInstanceof.txt new file mode 100644 index 0000000000..e69073e1e7 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/PatternMatchingInstanceof.txt @@ -0,0 +1,288 @@ ++- 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 = 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 = ""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"] + | | +- 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 = 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 = ""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 = true, @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 = true, @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"] + +- 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] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/Point.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/Point.java new file mode 100644 index 0000000000..bef547a6c6 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/Point.java @@ -0,0 +1,14 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +/** + * @see JEP 384: Records (Second Preview) + */ +public record Point(int x, int y) { + + public static void main(String[] args) { + Point p = new Point(1, 2); + System.out.println("p = " + p); + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/Point.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/Point.txt new file mode 100644 index 0000000000..088f830cb6 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/Point.txt @@ -0,0 +1,64 @@ ++- CompilationUnit[@PackageName = "", @declarationsAreInDefaultPackage = true] + +- TypeDeclaration[] + +- RecordDeclaration[@Abstract = false, @BinaryName = "Point", @Default = false, @Final = true, @Image = "Point", @Local = false, @Modifiers = 1, @Native = false, @Nested = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @SimpleName = "Point", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.RECORD, @Volatile = false] + +- RecordComponentList[@Size = 2] + | +- RecordComponent[@Varargs = false] + | | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "int"] + | | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "x", @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "x"] + | +- RecordComponent[@Varargs = false] + | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "int"] + | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "y", @LambdaParameter = false, @LocalVariable = false, @Name = "y", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "y"] + +- RecordBody[] + +- 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] + | +- 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 = "p", @Volatile = false] + | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "Point"] + | | +- ReferenceType[@Array = false, @ArrayDepth = 0] + | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Point", @ReferenceToClassSameCompilationUnit = false] + | +- VariableDeclarator[@Initializer = true, @Name = "p"] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "p", @LambdaParameter = false, @LocalVariable = true, @Name = "p", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "p"] + | +- VariableInitializer[] + | +- Expression[@StandAlonePrimitive = false] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- AllocationExpression[@AnonymousClass = false] + | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Point", @ReferenceToClassSameCompilationUnit = false] + | +- Arguments[@ArgumentCount = 2, @Size = 2] + | +- ArgumentList[@Size = 2] + | +- 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] + | +- Expression[@StandAlonePrimitive = true] + | +- 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] + +- 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 = ""p = "", @FloatLiteral = false, @Image = ""p = "", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""p = "", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + +- PrimaryExpression[] + +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + +- Name[@Image = "p"] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/Records.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/Records.java new file mode 100644 index 0000000000..9a756d70c1 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/Records.java @@ -0,0 +1,68 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +import java.io.IOException; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +/** + * @see JEP 384: Records (Second Preview) + */ +public class Records { + + @Target(ElementType.TYPE_USE) + @interface Nullable { } + + @Target({ElementType.CONSTRUCTOR, ElementType.PARAMETER}) + @interface MyAnnotation { } + + public record MyComplex(int real, @Deprecated int imaginary) { + // explicit declaration of a canonical constructor + @MyAnnotation + public MyComplex(@MyAnnotation int real, int imaginary) { + if (real > 100) throw new IllegalArgumentException("too big"); + this.real = real; + this.imaginary = imaginary; + } + + public record Nested(int a) {} + + public static class NestedClass { } + } + + + public record Range(int lo, int hi) { + // compact record constructor + @MyAnnotation + public Range { + if (lo > hi) /* referring here to the implicit constructor parameters */ + throw new IllegalArgumentException(String.format("(%d,%d)", lo, hi)); + } + + public void foo() { } + } + + public record VarRec(@Nullable @Deprecated String @Nullable ... x) {} + + public record ArrayRec(int x[]) {} + + public record EmptyRec() { + public void foo() { } + public Type bar() { return null; } + public static void baz() { + EmptyRec r = new EmptyRec<>(); + System.out.println(r); + } + } + + // see https://www.javaspecialists.eu/archive/Issue276.html + public interface Person { + String firstName(); + String lastName(); + } + public record PersonRecord(String firstName, String lastName) + implements Person, java.io.Serializable { + + } +} diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/Records.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/Records.txt new file mode 100644 index 0000000000..860315363f --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/Records.txt @@ -0,0 +1,316 @@ ++- CompilationUnit[@PackageName = "", @declarationsAreInDefaultPackage = true] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.io.IOException", @ImportedSimpleName = "IOException", @PackageName = "java.io", @Static = false] + | +- Name[@Image = "java.io.IOException"] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.lang.annotation.Target", @ImportedSimpleName = "Target", @PackageName = "java.lang.annotation", @Static = false] + | +- Name[@Image = "java.lang.annotation.Target"] + +- ImportDeclaration[@ImportOnDemand = false, @ImportedName = "java.lang.annotation.ElementType", @ImportedSimpleName = "ElementType", @PackageName = "java.lang.annotation", @Static = false] + | +- Name[@Image = "java.lang.annotation.ElementType"] + +- TypeDeclaration[] + +- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "Records", @Default = false, @Final = false, @Image = "Records", @Interface = false, @Local = false, @Modifiers = 1, @Native = false, @Nested = false, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = false, @SimpleName = "Records", @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.ANNOTATION] + | +- Annotation[@AnnotationName = "Target"] + | | +- SingleMemberAnnotation[@AnnotationName = "Target"] + | | +- Name[@Image = "Target"] + | | +- MemberValue[] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "ElementType.TYPE_USE"] + | +- AnnotationTypeDeclaration[@Abstract = false, @BinaryName = "Records$Nullable", @Default = false, @Final = false, @Image = "Nullable", @Local = false, @Modifiers = 0, @Native = false, @Nested = true, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @SimpleName = "Nullable", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.ANNOTATION, @Volatile = false] + | +- AnnotationTypeBody[] + +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.ANNOTATION] + | +- Annotation[@AnnotationName = "Target"] + | | +- SingleMemberAnnotation[@AnnotationName = "Target"] + | | +- Name[@Image = "Target"] + | | +- MemberValue[] + | | +- MemberValueArrayInitializer[] + | | +- MemberValue[] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "ElementType.CONSTRUCTOR"] + | | +- MemberValue[] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "ElementType.PARAMETER"] + | +- AnnotationTypeDeclaration[@Abstract = false, @BinaryName = "Records$MyAnnotation", @Default = false, @Final = false, @Image = "MyAnnotation", @Local = false, @Modifiers = 0, @Native = false, @Nested = true, @PackagePrivate = true, @Private = false, @Protected = false, @Public = false, @SimpleName = "MyAnnotation", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.ANNOTATION, @Volatile = false] + | +- AnnotationTypeBody[] + +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.RECORD] + | +- RecordDeclaration[@Abstract = false, @BinaryName = "Records$MyComplex", @Default = false, @Final = true, @Image = "MyComplex", @Local = false, @Modifiers = 1, @Native = false, @Nested = true, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @SimpleName = "MyComplex", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.RECORD, @Volatile = false] + | +- RecordComponentList[@Size = 2] + | | +- RecordComponent[@Varargs = false] + | | | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "int"] + | | | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "real", @LambdaParameter = false, @LocalVariable = false, @Name = "real", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "real"] + | | +- RecordComponent[@Varargs = false] + | | +- Annotation[@AnnotationName = "Deprecated"] + | | | +- MarkerAnnotation[@AnnotationName = "Deprecated"] + | | | +- Name[@Image = "Deprecated"] + | | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "int"] + | | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "imaginary", @LambdaParameter = false, @LocalVariable = false, @Name = "imaginary", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "imaginary"] + | +- RecordBody[] + | +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.CONSTRUCTOR] + | | +- Annotation[@AnnotationName = "MyAnnotation"] + | | | +- MarkerAnnotation[@AnnotationName = "MyAnnotation"] + | | | +- Name[@Image = "MyAnnotation"] + | | +- ConstructorDeclaration[@Abstract = false, @Arity = 2, @Default = false, @Final = false, @Image = "MyComplex", @Kind = MethodLikeKind.CONSTRUCTOR, @Modifiers = 1, @Native = false, @PackagePrivate = false, @ParameterCount = 2, @Private = false, @Protected = false, @Public = true, @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @Volatile = false, @containsComment = false] + | | +- FormalParameters[@ParameterCount = 2, @Size = 2] + | | | +- 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] + | | | | +- Annotation[@AnnotationName = "MyAnnotation"] + | | | | | +- MarkerAnnotation[@AnnotationName = "MyAnnotation"] + | | | | | +- Name[@Image = "MyAnnotation"] + | | | | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "int"] + | | | | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = true, @Image = "real", @LambdaParameter = false, @LocalVariable = false, @Name = "real", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "real"] + | | | +- 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 = "int"] + | | | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = true, @Image = "imaginary", @LambdaParameter = false, @LocalVariable = false, @Name = "imaginary", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "imaginary"] + | | +- BlockStatement[@Allocation = true] + | | | +- Statement[] + | | | +- IfStatement[@Else = false] + | | | +- Expression[@StandAlonePrimitive = false] + | | | | +- RelationalExpression[@Image = ">"] + | | | | +- PrimaryExpression[] + | | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | | +- Name[@Image = "real"] + | | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = "100", @FloatLiteral = false, @Image = "100", @IntLiteral = true, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = false, @TextBlock = false, @TextBlockContent = "100", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 100, @ValueAsLong = 100] + | | | +- Statement[] + | | | +- ThrowStatement[@FirstClassOrInterfaceTypeImage = "IllegalArgumentException"] + | | | +- Expression[@StandAlonePrimitive = false] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- AllocationExpression[@AnonymousClass = false] + | | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "IllegalArgumentException", @ReferenceToClassSameCompilationUnit = false] + | | | +- Arguments[@ArgumentCount = 1, @Size = 1] + | | | +- ArgumentList[@Size = 1] + | | | +- Expression[@StandAlonePrimitive = false] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""too big"", @FloatLiteral = false, @Image = ""too big"", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""too big"", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | +- BlockStatement[@Allocation = false] + | | | +- Statement[] + | | | +- StatementExpression[] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = true] + | | | | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @Image = "real"] + | | | +- AssignmentOperator[@Compound = false, @Image = "="] + | | | +- Expression[@StandAlonePrimitive = false] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "real"] + | | +- BlockStatement[@Allocation = false] + | | +- Statement[] + | | +- StatementExpression[] + | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = true] + | | | +- PrimarySuffix[@ArgumentCount = -1, @Arguments = false, @ArrayDereference = false, @Image = "imaginary"] + | | +- AssignmentOperator[@Compound = false, @Image = "="] + | | +- Expression[@StandAlonePrimitive = false] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "imaginary"] + | +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.RECORD] + | | +- RecordDeclaration[@Abstract = false, @BinaryName = "Records$MyComplex$Nested", @Default = false, @Final = true, @Image = "Nested", @Local = false, @Modifiers = 1, @Native = false, @Nested = true, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @SimpleName = "Nested", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.RECORD, @Volatile = false] + | | +- RecordComponentList[@Size = 1] + | | | +- RecordComponent[@Varargs = false] + | | | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "int"] + | | | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "a", @LambdaParameter = false, @LocalVariable = false, @Name = "a", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "a"] + | | +- RecordBody[] + | +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.CLASS] + | +- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "Records$MyComplex$NestedClass", @Default = false, @Final = false, @Image = "NestedClass", @Interface = false, @Local = false, @Modifiers = 17, @Native = false, @Nested = true, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = false, @SimpleName = "NestedClass", @Static = true, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.CLASS, @Volatile = false] + | +- ClassOrInterfaceBody[@AnonymousInnerClass = false, @EnumChild = false] + +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.RECORD] + | +- RecordDeclaration[@Abstract = false, @BinaryName = "Records$Range", @Default = false, @Final = true, @Image = "Range", @Local = false, @Modifiers = 1, @Native = false, @Nested = true, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @SimpleName = "Range", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.RECORD, @Volatile = false] + | +- RecordComponentList[@Size = 2] + | | +- RecordComponent[@Varargs = false] + | | | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "int"] + | | | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "lo", @LambdaParameter = false, @LocalVariable = false, @Name = "lo", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "lo"] + | | +- RecordComponent[@Varargs = false] + | | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "int"] + | | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "hi", @LambdaParameter = false, @LocalVariable = false, @Name = "hi", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "hi"] + | +- RecordBody[] + | +- RecordConstructorDeclaration[@Abstract = false, @Default = false, @Final = false, @Image = "Range", @Kind = DeclarationKind.RECORD_CONSTRUCTOR, @Modifiers = 1, @Native = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @Volatile = false] + | | +- Annotation[@AnnotationName = "MyAnnotation"] + | | | +- MarkerAnnotation[@AnnotationName = "MyAnnotation"] + | | | +- Name[@Image = "MyAnnotation"] + | | +- Block[@containsComment = false] + | | +- BlockStatement[@Allocation = true] + | | +- Statement[] + | | +- IfStatement[@Else = false] + | | +- Expression[@StandAlonePrimitive = false] + | | | +- RelationalExpression[@Image = ">"] + | | | +- PrimaryExpression[] + | | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | | +- Name[@Image = "lo"] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "hi"] + | | +- Statement[] + | | +- ThrowStatement[@FirstClassOrInterfaceTypeImage = "IllegalArgumentException"] + | | +- Expression[@StandAlonePrimitive = false] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- AllocationExpression[@AnonymousClass = false] + | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "IllegalArgumentException", @ReferenceToClassSameCompilationUnit = false] + | | +- Arguments[@ArgumentCount = 1, @Size = 1] + | | +- ArgumentList[@Size = 1] + | | +- Expression[@StandAlonePrimitive = false] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "String.format"] + | | +- PrimarySuffix[@ArgumentCount = 3, @Arguments = true, @ArrayDereference = false] + | | +- Arguments[@ArgumentCount = 3, @Size = 3] + | | +- ArgumentList[@Size = 3] + | | +- Expression[@StandAlonePrimitive = false] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Literal[@CharLiteral = false, @DoubleLiteral = false, @EscapedStringLiteral = ""(%d,%d)"", @FloatLiteral = false, @Image = ""(%d,%d)"", @IntLiteral = false, @LongLiteral = false, @SingleCharacterStringLiteral = false, @StringLiteral = true, @TextBlock = false, @TextBlockContent = ""(%d,%d)"", @ValueAsDouble = NaN, @ValueAsFloat = NaN, @ValueAsInt = 0, @ValueAsLong = 0] + | | +- Expression[@StandAlonePrimitive = false] + | | | +- PrimaryExpression[] + | | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | | +- Name[@Image = "lo"] + | | +- Expression[@StandAlonePrimitive = false] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- Name[@Image = "hi"] + | +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.METHOD] + | +- MethodDeclaration[@Abstract = false, @Arity = 0, @Default = false, @Final = false, @InterfaceMember = false, @Kind = MethodLikeKind.METHOD, @MethodName = "foo", @Modifiers = 1, @Name = "foo", @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 = "foo", @ParameterCount = 0] + | | +- FormalParameters[@ParameterCount = 0, @Size = 0] + | +- Block[@containsComment = false] + +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.RECORD] + | +- RecordDeclaration[@Abstract = false, @BinaryName = "Records$VarRec", @Default = false, @Final = true, @Image = "VarRec", @Local = false, @Modifiers = 1, @Native = false, @Nested = true, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @SimpleName = "VarRec", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.RECORD, @Volatile = false] + | +- RecordComponentList[@Size = 1] + | | +- RecordComponent[@Varargs = true] + | | +- Annotation[@AnnotationName = "Nullable"] + | | | +- MarkerAnnotation[@AnnotationName = "Nullable"] + | | | +- Name[@Image = "Nullable"] + | | +- 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] + | | | +- Annotation[@AnnotationName = "Nullable"] + | | | +- MarkerAnnotation[@AnnotationName = "Nullable"] + | | | +- Name[@Image = "Nullable"] + | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "x", @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "x"] + | +- RecordBody[] + +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.RECORD] + | +- RecordDeclaration[@Abstract = false, @BinaryName = "Records$ArrayRec", @Default = false, @Final = true, @Image = "ArrayRec", @Local = false, @Modifiers = 1, @Native = false, @Nested = true, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @SimpleName = "ArrayRec", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.RECORD, @Volatile = false] + | +- RecordComponentList[@Size = 1] + | | +- RecordComponent[@Varargs = false] + | | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "int"] + | | | +- PrimitiveType[@Array = false, @ArrayDepth = 0, @Boolean = false, @Image = "int"] + | | +- VariableDeclaratorId[@Array = true, @ArrayDepth = 1, @ArrayType = true, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "x", @LambdaParameter = false, @LocalVariable = false, @Name = "x", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "x"] + | +- RecordBody[] + +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.RECORD] + | +- RecordDeclaration[@Abstract = false, @BinaryName = "Records$EmptyRec", @Default = false, @Final = true, @Image = "EmptyRec", @Local = false, @Modifiers = 1, @Native = false, @Nested = true, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @SimpleName = "EmptyRec", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.RECORD, @Volatile = false] + | +- TypeParameters[] + | | +- TypeParameter[@Image = "Type", @ParameterName = "Type", @TypeBound = false] + | +- RecordComponentList[@Size = 0] + | +- RecordBody[] + | +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.METHOD] + | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @Default = false, @Final = false, @InterfaceMember = false, @Kind = MethodLikeKind.METHOD, @MethodName = "foo", @Modifiers = 1, @Name = "foo", @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 = "foo", @ParameterCount = 0] + | | | +- FormalParameters[@ParameterCount = 0, @Size = 0] + | | +- Block[@containsComment = false] + | +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.METHOD] + | | +- MethodDeclaration[@Abstract = false, @Arity = 0, @Default = false, @Final = false, @InterfaceMember = false, @Kind = MethodLikeKind.METHOD, @MethodName = "bar", @Modifiers = 1, @Name = "bar", @Native = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Static = false, @Strictfp = false, @Synchronized = false, @SyntacticallyAbstract = false, @SyntacticallyPublic = true, @Transient = false, @Void = false, @Volatile = false] + | | +- ResultType[@Void = false, @returnsArray = false] + | | | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "Type"] + | | | +- ReferenceType[@Array = false, @ArrayDepth = 0] + | | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Type", @ReferenceToClassSameCompilationUnit = false] + | | +- MethodDeclarator[@Image = "bar", @ParameterCount = 0] + | | | +- FormalParameters[@ParameterCount = 0, @Size = 0] + | | +- Block[@containsComment = false] + | | +- BlockStatement[@Allocation = false] + | | +- Statement[] + | | +- ReturnStatement[] + | | +- 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[] + | +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.METHOD] + | +- MethodDeclaration[@Abstract = false, @Arity = 0, @Default = false, @Final = false, @InterfaceMember = false, @Kind = MethodLikeKind.METHOD, @MethodName = "baz", @Modifiers = 17, @Name = "baz", @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 = "baz", @ParameterCount = 0] + | | +- FormalParameters[@ParameterCount = 0, @Size = 0] + | +- Block[@containsComment = false] + | +- BlockStatement[@Allocation = true] + | | +- 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 = "r", @Volatile = false] + | | +- Type[@Array = false, @ArrayDepth = 0, @ArrayType = false, @TypeImage = "EmptyRec"] + | | | +- ReferenceType[@Array = false, @ArrayDepth = 0] + | | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "EmptyRec", @ReferenceToClassSameCompilationUnit = false] + | | | +- TypeArguments[@Diamond = false] + | | | +- TypeArgument[@Wildcard = false] + | | | +- ReferenceType[@Array = false, @ArrayDepth = 0] + | | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "String", @ReferenceToClassSameCompilationUnit = false] + | | +- VariableDeclarator[@Initializer = true, @Name = "r"] + | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = false, @FormalParameter = false, @Image = "r", @LambdaParameter = false, @LocalVariable = true, @Name = "r", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "r"] + | | +- VariableInitializer[] + | | +- Expression[@StandAlonePrimitive = false] + | | +- PrimaryExpression[] + | | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | | +- AllocationExpression[@AnonymousClass = false] + | | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "EmptyRec", @ReferenceToClassSameCompilationUnit = false] + | | | +- TypeArguments[@Diamond = true] + | | +- Arguments[@ArgumentCount = 0, @Size = 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] + | +- PrimaryExpression[] + | +- PrimaryPrefix[@SuperModifier = false, @ThisModifier = false] + | +- Name[@Image = "r"] + +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.INTERFACE] + | +- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "Records$Person", @Default = false, @Final = false, @Image = "Person", @Interface = true, @Local = false, @Modifiers = 1, @Native = false, @Nested = true, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = false, @SimpleName = "Person", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.INTERFACE, @Volatile = false] + | +- ClassOrInterfaceBody[@AnonymousInnerClass = false, @EnumChild = false] + | +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.METHOD] + | | +- MethodDeclaration[@Abstract = true, @Arity = 0, @Default = false, @Final = false, @InterfaceMember = true, @Kind = MethodLikeKind.METHOD, @MethodName = "firstName", @Modifiers = 0, @Name = "firstName", @Native = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Static = false, @Strictfp = false, @Synchronized = false, @SyntacticallyAbstract = false, @SyntacticallyPublic = false, @Transient = false, @Void = false, @Volatile = false] + | | +- ResultType[@Void = false, @returnsArray = 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] + | | +- MethodDeclarator[@Image = "firstName", @ParameterCount = 0] + | | +- FormalParameters[@ParameterCount = 0, @Size = 0] + | +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.METHOD] + | +- MethodDeclaration[@Abstract = true, @Arity = 0, @Default = false, @Final = false, @InterfaceMember = true, @Kind = MethodLikeKind.METHOD, @MethodName = "lastName", @Modifiers = 0, @Name = "lastName", @Native = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Static = false, @Strictfp = false, @Synchronized = false, @SyntacticallyAbstract = false, @SyntacticallyPublic = false, @Transient = false, @Void = false, @Volatile = false] + | +- ResultType[@Void = false, @returnsArray = 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] + | +- MethodDeclarator[@Image = "lastName", @ParameterCount = 0] + | +- FormalParameters[@ParameterCount = 0, @Size = 0] + +- ClassOrInterfaceBodyDeclaration[@AnonymousInnerClass = false, @EnumChild = false, @Kind = DeclarationKind.RECORD] + +- RecordDeclaration[@Abstract = false, @BinaryName = "Records$PersonRecord", @Default = false, @Final = true, @Image = "PersonRecord", @Local = false, @Modifiers = 1, @Native = false, @Nested = true, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @SimpleName = "PersonRecord", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.RECORD, @Volatile = false] + +- RecordComponentList[@Size = 2] + | +- RecordComponent[@Varargs = 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] + | | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "firstName", @LambdaParameter = false, @LocalVariable = false, @Name = "firstName", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "firstName"] + | +- RecordComponent[@Varargs = 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] + | +- VariableDeclaratorId[@Array = false, @ArrayDepth = 0, @ArrayType = false, @ExceptionBlockParameter = false, @ExplicitReceiverParameter = false, @Field = false, @Final = true, @FormalParameter = false, @Image = "lastName", @LambdaParameter = false, @LocalVariable = false, @Name = "lastName", @PatternBinding = false, @ResourceDeclaration = false, @TypeInferred = false, @VariableName = "lastName"] + +- ImplementsList[] + | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Person", @ReferenceToClassSameCompilationUnit = true] + | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "java.io.Serializable", @ReferenceToClassSameCompilationUnit = false] + +- RecordBody[] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/ConstantExpr.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/ConstantExpr.java new file mode 100644 index 0000000000..800fc3d2d1 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/ConstantExpr.java @@ -0,0 +1,9 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package com.example.expression; + +/** + * @see JEP 360: Sealed Classes (Preview) + */ +public final class ConstantExpr implements Expr { } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/Expr.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/Expr.java new file mode 100644 index 0000000000..7218bd477f --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/Expr.java @@ -0,0 +1,10 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package com.example.expression; + +/** + * @see JEP 360: Sealed Classes (Preview) + */ +public sealed interface Expr + permits ConstantExpr, PlusExpr, TimesExpr, NegExpr { } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/Expr.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/Expr.txt new file mode 100644 index 0000000000..5a2d23b1cc --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/Expr.txt @@ -0,0 +1,11 @@ ++- CompilationUnit[@PackageName = "com.example.expression", @declarationsAreInDefaultPackage = false] + +- PackageDeclaration[@PackageNameImage = "com.example.expression"] + | +- Name[@Image = "com.example.expression"] + +- TypeDeclaration[] + +- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "com.example.expression.Expr", @Default = false, @Final = false, @Image = "Expr", @Interface = true, @Local = false, @Modifiers = 16385, @Native = false, @Nested = false, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = true, @SimpleName = "Expr", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.INTERFACE, @Volatile = false] + +- PermitsList[] + | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "ConstantExpr", @ReferenceToClassSameCompilationUnit = false] + | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "PlusExpr", @ReferenceToClassSameCompilationUnit = false] + | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "TimesExpr", @ReferenceToClassSameCompilationUnit = false] + | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "NegExpr", @ReferenceToClassSameCompilationUnit = false] + +- ClassOrInterfaceBody[@AnonymousInnerClass = false, @EnumChild = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/NegExpr.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/NegExpr.java new file mode 100644 index 0000000000..35194d1cb9 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/NegExpr.java @@ -0,0 +1,9 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package com.example.expression; + +/** + * @see JEP 360: Sealed Classes (Preview) + */ +public final class NegExpr implements Expr { } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/PlusExpr.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/PlusExpr.java new file mode 100644 index 0000000000..ac652798e2 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/PlusExpr.java @@ -0,0 +1,9 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package com.example.expression; + +/** + * @see JEP 360: Sealed Classes (Preview) + */ +public final class PlusExpr implements Expr { } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/TimesExpr.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/TimesExpr.java new file mode 100644 index 0000000000..a5cf1ccc74 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/expression/TimesExpr.java @@ -0,0 +1,9 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package com.example.expression; + +/** + * @see JEP 360: Sealed Classes (Preview) + */ +public final class TimesExpr implements Expr { } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Circle.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Circle.java new file mode 100644 index 0000000000..c4baabda9b --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Circle.java @@ -0,0 +1,9 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package com.example.geometry; + +/** + * @see JEP 360: Sealed Classes (Preview) + */ +public final class Circle extends Shape { } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/FilledRectangle.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/FilledRectangle.java new file mode 100644 index 0000000000..92eb290b6b --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/FilledRectangle.java @@ -0,0 +1,10 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package com.example.geometry; + +/** + * @see JEP 360: Sealed Classes (Preview) + */ +public final class FilledRectangle extends Rectangle { } + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Rectangle.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Rectangle.java new file mode 100644 index 0000000000..fd66cdd014 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Rectangle.java @@ -0,0 +1,11 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package com.example.geometry; + +/** + * @see JEP 360: Sealed Classes (Preview) + */ +public sealed class Rectangle extends Shape + permits TransparentRectangle, FilledRectangle { } + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Shape.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Shape.java new file mode 100644 index 0000000000..cdec22ef4c --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Shape.java @@ -0,0 +1,11 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package com.example.geometry; + +/** + * @see JEP 360: Sealed Classes (Preview) + */ +public sealed class Shape + permits Circle, Rectangle, Square { } + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Shape.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Shape.txt new file mode 100644 index 0000000000..aab21fafd9 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Shape.txt @@ -0,0 +1,10 @@ ++- CompilationUnit[@PackageName = "com.example.geometry", @declarationsAreInDefaultPackage = false] + +- PackageDeclaration[@PackageNameImage = "com.example.geometry"] + | +- Name[@Image = "com.example.geometry"] + +- TypeDeclaration[] + +- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "com.example.geometry.Shape", @Default = false, @Final = false, @Image = "Shape", @Interface = false, @Local = false, @Modifiers = 16385, @Native = false, @Nested = false, @NonSealed = false, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = true, @SimpleName = "Shape", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.CLASS, @Volatile = false] + +- PermitsList[] + | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Circle", @ReferenceToClassSameCompilationUnit = false] + | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Rectangle", @ReferenceToClassSameCompilationUnit = false] + | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Square", @ReferenceToClassSameCompilationUnit = false] + +- ClassOrInterfaceBody[@AnonymousInnerClass = false, @EnumChild = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Square.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Square.java new file mode 100644 index 0000000000..75dafdbc92 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Square.java @@ -0,0 +1,10 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package com.example.geometry; + +/** + * @see JEP 360: Sealed Classes (Preview) + */ +public non-sealed class Square extends Shape { } + diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Square.txt b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Square.txt new file mode 100644 index 0000000000..6adad58fea --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/Square.txt @@ -0,0 +1,8 @@ ++- CompilationUnit[@PackageName = "com.example.geometry", @declarationsAreInDefaultPackage = false] + +- PackageDeclaration[@PackageNameImage = "com.example.geometry"] + | +- Name[@Image = "com.example.geometry"] + +- TypeDeclaration[] + +- ClassOrInterfaceDeclaration[@Abstract = false, @BinaryName = "com.example.geometry.Square", @Default = false, @Final = false, @Image = "Square", @Interface = false, @Local = false, @Modifiers = 32769, @Native = false, @Nested = false, @NonSealed = true, @PackagePrivate = false, @Private = false, @Protected = false, @Public = true, @Sealed = false, @SimpleName = "Square", @Static = false, @Strictfp = false, @Synchronized = false, @Transient = false, @TypeKind = TypeKind.CLASS, @Volatile = false] + +- ExtendsList[] + | +- ClassOrInterfaceType[@AnonymousClass = false, @Array = false, @ArrayDepth = 0, @Image = "Shape", @ReferenceToClassSameCompilationUnit = false] + +- ClassOrInterfaceBody[@AnonymousInnerClass = false, @EnumChild = false] diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/TransparentRectangle.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/TransparentRectangle.java new file mode 100644 index 0000000000..a5c656157f --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/java15p/geometry/TransparentRectangle.java @@ -0,0 +1,10 @@ +/* + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package com.example.geometry; + +/** + * @see JEP 360: Sealed Classes (Preview) + */ +public final class TransparentRectangle extends Rectangle { } + diff --git a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/NodePrinters.kt b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/NodePrinters.kt index 7e476c62c3..c2b76c3a23 100644 --- a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/NodePrinters.kt +++ b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/NodePrinters.kt @@ -51,6 +51,8 @@ open class BaseNodeAttributePrinter : TextTreeRenderer(true, -1) { .joinTo(buffer = out, prefix = "[", postfix = "]") { "@${it.name} = ${valueToString(it.value)}" } + + out.append("\n") } protected open fun valueToString(value: Any?): String? { diff --git a/pom.xml b/pom.xml index d6f1fd8708..c283ddbbd9 100644 --- a/pom.xml +++ b/pom.xml @@ -682,7 +682,7 @@ org.ow2.asm asm - 7.3.1 + 9.0-beta org.pcollections