Merge branch 'issue-3366-support-jdk-17' into
pmd7-issue-3366-support-jdk-17
This commit is contained in:
@ -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, 14, 14-preview, 15 (default), 15-preview
|
||||
13, 14, 15, 16, 16-preview, 17 (default), 17-preview
|
||||
* [ecmascript](pmd_rules_ecmascript.html) (JavaScript)
|
||||
* [jsp](pmd_rules_jsp.html)
|
||||
* [modelica](pmd_rules_modelica.html)
|
||||
|
@ -19,6 +19,20 @@ This is a {{ site.pmd.release_type }} release.
|
||||
|
||||
### New and noteworthy
|
||||
|
||||
#### Java 17 Support
|
||||
|
||||
This release of PMD brings support for Java 17. PMD supports [JEP 409: Sealed Classes](https://openjdk.java.net/jeps/409)
|
||||
which has been promoted to be a standard language feature of Java 17.
|
||||
|
||||
PMD also supports [JEP 406: Pattern Matching for switch (Preview)](https://openjdk.java.net/jeps/406) as a preview
|
||||
language feature. 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 `17-preview`:
|
||||
|
||||
export PMD_JAVA_OPTS=--enable-preview
|
||||
./run.sh pmd -language java -version 17-preview ...
|
||||
|
||||
Note: Support for Java 15 preview language features have been removed. The version "15-preview" is no longer available.
|
||||
|
||||
#### New rules
|
||||
|
||||
This release ships with 1 new Java rule.
|
||||
@ -61,6 +75,14 @@ supersedes it.
|
||||
|
||||
### API Changes
|
||||
|
||||
#### Experimental APIs
|
||||
|
||||
* The AST types and APIs around Sealed Classes are not experimental anymore:
|
||||
* {% jdoc !!java::lang.java.ast.ASTClassOrInterfaceDeclaration#isSealed() %},
|
||||
{% jdoc !!java::lang.java.ast.ASTClassOrInterfaceDeclaration#isNonSealed() %},
|
||||
{% jdoc !!java::lang.java.ast.ASTClassOrInterfaceDeclaration#getPermittedSubclasses() %}
|
||||
* {% jdoc java::lang.java.ast.ASTPermitsList %}
|
||||
|
||||
### External Contributions
|
||||
|
||||
* [#3367](https://github.com/pmd/pmd/pull/3367): \[apex] Check SOQL CRUD on for loops - [Jonathan Wiesel](https://github.com/jonathanwiesel)
|
||||
|
@ -1,4 +1,9 @@
|
||||
/**
|
||||
* Promote "JEP 409: Sealed Classes" as permanent language feature with Java 17.
|
||||
* Support "JEP 406: Pattern Matching for switch (Preview)" for Java 17 Preview.
|
||||
* Remove support for Java 15 preview language features
|
||||
* Andreas Dangel 07/2021
|
||||
*====================================================================
|
||||
* Fix #3117 - infinite loop when parsing invalid code nested in lambdas
|
||||
* Andreas Dangel 03/2021
|
||||
*====================================================================
|
||||
@ -297,10 +302,6 @@ class JavaParserImpl {
|
||||
return isRecordTypeSupported();
|
||||
}
|
||||
|
||||
private boolean isSealedClassSupported() {
|
||||
return jdkVersion == 15 && preview || jdkVersion == 16 && preview;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps track during tree construction, whether we are currently building a switch label.
|
||||
* A switch label must not contain a LambdaExpression.
|
||||
@ -311,6 +312,7 @@ class JavaParserImpl {
|
||||
*/
|
||||
private boolean inSwitchLabel = false;
|
||||
|
||||
|
||||
// This is a semantic LOOKAHEAD to determine if we're dealing with an assert
|
||||
// Note that this can't be replaced with a syntactic lookahead
|
||||
// since "assert" isn't a string literal token
|
||||
@ -1714,6 +1716,33 @@ void EqualityExpression() #void:
|
||||
)*
|
||||
}
|
||||
|
||||
void Pattern() #void:
|
||||
{}
|
||||
{
|
||||
PrimaryPattern() [ GuardedPatternCondition() #GuardedPattern(2) ]
|
||||
}
|
||||
|
||||
void GuardedPatternCondition() #void:
|
||||
{}
|
||||
{
|
||||
"&&" ConditionalAndExpression()
|
||||
}
|
||||
|
||||
void PrimaryPattern() #void:
|
||||
{}
|
||||
{
|
||||
TypePattern()
|
||||
| "(" Pattern() ")" { AstImplUtil.bumpParenDepth((ASTPattern) jjtree.peekNode()); }
|
||||
}
|
||||
|
||||
void TypePattern():
|
||||
{}
|
||||
{
|
||||
AnnotatedRefType() VariableDeclaratorId()
|
||||
|
|
||||
LocalVarModifierList() ReferenceType() VariableDeclaratorId()
|
||||
}
|
||||
|
||||
void InstanceOfExpression() #void:
|
||||
{}
|
||||
{
|
||||
@ -1721,9 +1750,11 @@ void InstanceOfExpression() #void:
|
||||
LOOKAHEAD(1)
|
||||
("instanceof"
|
||||
(
|
||||
AnnotatedRefType() [ VariableDeclaratorId() #TypePattern(2) ]
|
||||
LOOKAHEAD("final" | "@") PrimaryPattern()
|
||||
|
|
||||
( LocalVarModifierList() ReferenceType() VariableDeclaratorId() ) #TypePattern(3)
|
||||
LOOKAHEAD("(") Pattern()
|
||||
|
|
||||
AnnotatedRefType() [ VariableDeclaratorId() #TypePattern(2) ]
|
||||
)
|
||||
{
|
||||
jjtThis.setOp(BinaryOp.INSTANCEOF);
|
||||
@ -2405,13 +2436,28 @@ void SwitchLabel() :
|
||||
{
|
||||
{ inSwitchLabel = true; }
|
||||
(
|
||||
"case" ConditionalExpression() ( "," ConditionalExpression() )*
|
||||
"case" CaseLabelElement(jjtThis) ( "," CaseLabelElement(jjtThis) )*
|
||||
|
|
||||
"default" {jjtThis.setDefault();}
|
||||
)
|
||||
{ inSwitchLabel = false; }
|
||||
}
|
||||
|
||||
void CaseLabelElement(ASTSwitchLabel label) #void:
|
||||
{}
|
||||
{
|
||||
"default" {label.setDefault(); checkForDefaultCaseLabel();}
|
||||
|
|
||||
LOOKAHEAD(Pattern()) Pattern() {checkForPatternMatchingInSwitch();}
|
||||
|
|
||||
ConditionalExpression() #Expression
|
||||
{
|
||||
if ("null".equals(((ASTExpression) jjtree.peekNode()).jjtGetFirstToken().getImage())) {
|
||||
checkForNullCaseLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void YieldStatement() :
|
||||
{ }
|
||||
{
|
||||
|
@ -30,9 +30,10 @@ public class JavaLanguageModule extends BaseLanguageModule {
|
||||
addVersion("13", new JavaLanguageHandler(13));
|
||||
addVersion("14", new JavaLanguageHandler(14));
|
||||
addVersion("15", new JavaLanguageHandler(15));
|
||||
addVersion("15-preview", new JavaLanguageHandler(15, true));
|
||||
addDefaultVersion("16", new JavaLanguageHandler(16)); // 16 is the default
|
||||
addVersion("16", new JavaLanguageHandler(16));
|
||||
addVersion("16-preview", new JavaLanguageHandler(16, true));
|
||||
addDefaultVersion("17", new JavaLanguageHandler(17)); // 17 is the default
|
||||
addVersion("17-preview", new JavaLanguageHandler(17, true));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.annotation.Experimental;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
|
||||
|
||||
@ -81,9 +80,7 @@ public final class ASTClassOrInterfaceDeclaration extends AbstractAnyTypeDeclara
|
||||
}
|
||||
|
||||
|
||||
@Experimental
|
||||
public List<ASTClassOrInterfaceType> getPermittedSubclasses() {
|
||||
return ASTList.orEmpty(children(ASTPermitsList.class).first());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 net.sourceforge.pmd.annotation.Experimental;
|
||||
|
||||
/**
|
||||
* A guarded pattern (JDK17 Preview). This can be found
|
||||
* in {@link ASTSwitchLabel}s.
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* GuardedPattern ::= {@linkplain ASTPattern Pattern} "&&" {@linkplain ASTConditionalAndExpression ConditionalAndExpression}
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @see <a href="https://openjdk.java.net/jeps/406">JEP 406: Pattern Matching for switch (Preview)</a>
|
||||
*/
|
||||
@Experimental
|
||||
public final class ASTGuardedPattern extends AbstractJavaNode implements ASTPattern {
|
||||
|
||||
private int parenDepth;
|
||||
|
||||
ASTGuardedPattern(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <P, R> R acceptVisitor(JavaVisitor<? super P, ? extends R> visitor, P data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
public ASTPattern getPattern() {
|
||||
return (ASTPattern) getChild(0);
|
||||
}
|
||||
|
||||
public JavaNode getGuard() {
|
||||
return getChild(1);
|
||||
}
|
||||
|
||||
void bumpParenDepth() {
|
||||
parenDepth++;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Experimental
|
||||
public int getParenthesisDepth() {
|
||||
return parenDepth;
|
||||
}
|
||||
}
|
@ -4,9 +4,11 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import net.sourceforge.pmd.annotation.Experimental;
|
||||
|
||||
/**
|
||||
* A pattern (for pattern matching constructs like {@link ASTInstanceOfExpression InstanceOfExpression}).
|
||||
* This is a JDK 16 feature.
|
||||
* A pattern (for pattern matching constructs like {@link ASTInstanceOfExpression InstanceOfExpression}
|
||||
* or within a {@link ASTSwitchLabel}). This is a JDK 16 feature.
|
||||
*
|
||||
* <p>This interface will be implemented by all forms of patterns. For
|
||||
* now, only type test patterns are supported. Record deconstruction
|
||||
@ -14,7 +16,8 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
* Pattern ::= {@link ASTTypePattern TypePattern}
|
||||
* Pattern ::= {@link ASTTypePattern TypePattern}
|
||||
* | {@link ASTGuardedPattern GuardedPattern}
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
@ -22,4 +25,10 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
*/
|
||||
public interface ASTPattern extends JavaNode {
|
||||
|
||||
/**
|
||||
* Returns the number of parenthesis levels around this pattern.
|
||||
* If this method returns 0, then no parentheses are present.
|
||||
*/
|
||||
@Experimental
|
||||
int getParenthesisDepth();
|
||||
}
|
||||
|
@ -4,16 +4,15 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import net.sourceforge.pmd.annotation.Experimental;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTList.ASTNonEmptyList;
|
||||
|
||||
|
||||
/**
|
||||
* Represents the {@code permits} clause of a (sealed) class declaration.
|
||||
*
|
||||
* <p>This is a Java 15 Preview and Java 16 Preview feature.
|
||||
* <p>This is a Java 17 Feature.
|
||||
*
|
||||
* <p>See https://openjdk.java.net/jeps/397
|
||||
* <p>See https://openjdk.java.net/jeps/409
|
||||
*
|
||||
* <pre class="grammar">
|
||||
*
|
||||
@ -21,7 +20,6 @@ import net.sourceforge.pmd.lang.java.ast.ASTList.ASTNonEmptyList;
|
||||
* ( "," ClassOrInterfaceType )*
|
||||
* </pre>
|
||||
*/
|
||||
@Experimental
|
||||
public final class ASTPermitsList extends ASTNonEmptyList<ASTClassOrInterfaceType> {
|
||||
|
||||
ASTPermitsList(int id) {
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import net.sourceforge.pmd.annotation.Experimental;
|
||||
|
||||
/**
|
||||
* A type pattern (JDK16). This can be found on
|
||||
* the right-hand side of an {@link ASTInfixExpression InstanceOfExpression},
|
||||
@ -19,6 +21,8 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
*/
|
||||
public final class ASTTypePattern extends AbstractJavaNode implements ASTPattern, AccessNode {
|
||||
|
||||
private int parenDepth;
|
||||
|
||||
ASTTypePattern(int id) {
|
||||
super(id);
|
||||
}
|
||||
@ -39,4 +43,14 @@ public final class ASTTypePattern extends AbstractJavaNode implements ASTPattern
|
||||
public ASTVariableDeclaratorId getVarId() {
|
||||
return getFirstChildOfType(ASTVariableDeclaratorId.class);
|
||||
}
|
||||
|
||||
void bumpParenDepth() {
|
||||
parenDepth++;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Experimental
|
||||
public int getParenthesisDepth() {
|
||||
return parenDepth;
|
||||
}
|
||||
}
|
||||
|
@ -48,4 +48,14 @@ final class AstImplUtil {
|
||||
((AbstractJavaExpr) expression).bumpParenDepth();
|
||||
}
|
||||
|
||||
static void bumpParenDepth(ASTPattern pattern) {
|
||||
assert pattern instanceof ASTTypePattern || pattern instanceof ASTGuardedPattern
|
||||
: pattern.getClass() + " doesn't have parenDepth attribute!";
|
||||
|
||||
if (pattern instanceof ASTTypePattern) {
|
||||
((ASTTypePattern) pattern).bumpParenDepth();
|
||||
} else if (pattern instanceof ASTGuardedPattern) {
|
||||
((ASTGuardedPattern) pattern).bumpParenDepth();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTEnumDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTForeachStatement;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTGuardedPattern;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTIntersectionType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression;
|
||||
@ -137,8 +138,14 @@ public class LanguageLevelChecker<T> {
|
||||
/**
|
||||
* @see <a href="https://openjdk.java.net/jeps/360">JEP 360: Sealed Classes (Preview)</a>
|
||||
* @see <a href="https://openjdk.java.net/jeps/397">JEP 397: Sealed Classes (Second Preview)</a>
|
||||
* @see <a href="https://openjdk.java.net/jeps/409">JEP 409: Sealed Classes</a>
|
||||
*/
|
||||
SEALED_CLASSES(15, 16, false),
|
||||
SEALED_CLASSES(15, 16, true),
|
||||
|
||||
/**
|
||||
* @see <a href="https://openjdk.java.net/jeps/406">JEP 406: Pattern Matching for switch (Preview)</a>
|
||||
*/
|
||||
PATTERN_MATCHING_FOR_SWITCH(17, 17, false),
|
||||
|
||||
; // SUPPRESS CHECKSTYLE enum trailing semi is awesome
|
||||
|
||||
@ -491,6 +498,12 @@ public class LanguageLevelChecker<T> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(ASTGuardedPattern node, T data) {
|
||||
check(node, PreviewFeature.PATTERN_MATCHING_FOR_SWITCH, data);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(ASTTryStatement node, T data) {
|
||||
if (node.isTryWithResources()) {
|
||||
|
@ -52,7 +52,6 @@ public abstract class AbstractJavaRule extends AbstractRule implements JavaParse
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean dependsOn(AstProcessingStage<?> stage) {
|
||||
if (!(stage instanceof JavaProcessingStage)) {
|
||||
|
@ -42,24 +42,20 @@ public class LanguageVersionTest extends AbstractLanguageVersionTest {
|
||||
LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("11"), },
|
||||
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "12",
|
||||
LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("12"), },
|
||||
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "12-preview",
|
||||
LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("12-preview"), },
|
||||
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "13",
|
||||
LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("13"), },
|
||||
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "13-preview",
|
||||
LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("13-preview"), },
|
||||
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "14",
|
||||
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"), },
|
||||
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "16",
|
||||
LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("16"), },
|
||||
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "16-preview",
|
||||
LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("16-preview"), },
|
||||
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "17",
|
||||
LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("17"), },
|
||||
{ JavaLanguageModule.NAME, JavaLanguageModule.TERSE_NAME, "17-preview",
|
||||
LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("17-preview"), },
|
||||
|
||||
// this one won't be found: case sensitive!
|
||||
{ "JAVA", "JAVA", "1.7", null, },
|
||||
|
@ -1,131 +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.ast.test.BaseParsingHelper;
|
||||
import net.sourceforge.pmd.lang.java.BaseJavaTreeDumpTest;
|
||||
import net.sourceforge.pmd.lang.java.JavaParsingHelper;
|
||||
|
||||
public class Java15PreviewTreeDumpTest extends BaseJavaTreeDumpTest {
|
||||
private final JavaParsingHelper java15p =
|
||||
JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("15-preview")
|
||||
.withResourceContext(Java15PreviewTreeDumpTest.class, "jdkversiontests/java15p/");
|
||||
private final JavaParsingHelper java15 = java15p.withDefaultVersion("15");
|
||||
|
||||
|
||||
@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<ASTInstanceOfExpression> 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
|
||||
@Ignore("Ignored, this will be reactivated on the typeresolution branch")
|
||||
public void recordPoint() {
|
||||
doTest("Point");
|
||||
|
||||
// extended tests for type resolution etc.
|
||||
ASTCompilationUnit compilationUnit = java15p.parseResource("Point.java");
|
||||
ASTRecordDeclaration recordDecl = compilationUnit.getFirstDescendantOfType(ASTRecordDeclaration.class);
|
||||
List<ASTRecordComponent> components = recordDecl.getRecordComponents().toList();
|
||||
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");
|
||||
}
|
||||
}
|
@ -15,7 +15,6 @@ public class Java15TreeDumpTest extends BaseJavaTreeDumpTest {
|
||||
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");
|
||||
|
||||
@Override
|
||||
@ -26,7 +25,6 @@ public class Java15TreeDumpTest extends BaseJavaTreeDumpTest {
|
||||
@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)
|
||||
@ -42,6 +40,5 @@ public class Java15TreeDumpTest extends BaseJavaTreeDumpTest {
|
||||
@Test
|
||||
public void sealedAndNonSealedIdentifiers() {
|
||||
doTest("NonSealedIdentifier");
|
||||
java15p.parseResource("NonSealedIdentifier.java"); // make sure we can parse it with preview as well
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import net.sourceforge.pmd.lang.java.types.JPrimitiveType;
|
||||
public class Java16TreeDumpTest extends BaseJavaTreeDumpTest {
|
||||
private final JavaParsingHelper java16 =
|
||||
JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("16")
|
||||
.withResourceContext(Java15TreeDumpTest.class, "jdkversiontests/java16/");
|
||||
.withResourceContext(Java16TreeDumpTest.class, "jdkversiontests/java16/");
|
||||
private final JavaParsingHelper java16p = java16.withDefaultVersion("16-preview");
|
||||
private final JavaParsingHelper java15 = java16.withDefaultVersion("15");
|
||||
|
||||
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.function.ThrowingRunnable;
|
||||
|
||||
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 Java17PreviewTreeDumpTest extends BaseTreeDumpTest {
|
||||
private final JavaParsingHelper java17p =
|
||||
JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("17-preview")
|
||||
.withResourceContext(Java17PreviewTreeDumpTest.class, "jdkversiontests/java17p/");
|
||||
private final JavaParsingHelper java17 = java17p.withDefaultVersion("17");
|
||||
|
||||
public Java17PreviewTreeDumpTest() {
|
||||
super(new RelevantAttributePrinter(), ".java");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseParsingHelper<?, ?> getParser() {
|
||||
return java17p;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patternMatchingForSwitchBeforeJava17Preview() {
|
||||
ParseException thrown = Assert.assertThrows(ParseException.class, new ThrowingRunnable() {
|
||||
@Override
|
||||
public void run() throws Throwable {
|
||||
java17.parseResource("PatternsInSwitchLabels.java");
|
||||
}
|
||||
});
|
||||
Assert.assertTrue("Unexpected message: " + thrown.getMessage(),
|
||||
thrown.getMessage().contains("Pattern Matching in Switch is only supported with JDK 17 Preview."));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patternMatchingForSwitch() {
|
||||
doTest("PatternsInSwitchLabels");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enhancedTypeCheckingSwitch() {
|
||||
doTest("EnhancedTypeCheckingSwitch");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void scopeOfPatternVariableDeclarations() {
|
||||
doTest("ScopeOfPatternVariableDeclarations");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dealingWithNullBeforeJava17Preview() {
|
||||
ParseException thrown = Assert.assertThrows(ParseException.class, new ThrowingRunnable() {
|
||||
@Override
|
||||
public void run() throws Throwable {
|
||||
java17.parseResource("DealingWithNull.java");
|
||||
}
|
||||
});
|
||||
Assert.assertTrue("Unexpected message: " + thrown.getMessage(),
|
||||
thrown.getMessage().contains("Null case labels in switch are only supported with JDK 17 Preview."));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dealingWithNull() {
|
||||
doTest("DealingWithNull");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void guardedAndParenthesizedPatternsBeforeJava17Preview() {
|
||||
ParseException thrown = Assert.assertThrows(ParseException.class, new ThrowingRunnable() {
|
||||
@Override
|
||||
public void run() throws Throwable {
|
||||
java17.parseResource("GuardedAndParenthesizedPatterns.java");
|
||||
}
|
||||
});
|
||||
Assert.assertTrue("Unexpected message: " + thrown.getMessage(),
|
||||
thrown.getMessage().contains("Guarded patterns are only supported with JDK 17 Preview."));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void guardedAndParenthesizedPatterns() {
|
||||
doTest("GuardedAndParenthesizedPatterns");
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.function.ThrowingRunnable;
|
||||
|
||||
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 Java17TreeDumpTest extends BaseTreeDumpTest {
|
||||
private final JavaParsingHelper java17 =
|
||||
JavaParsingHelper.WITH_PROCESSING.withDefaultVersion("17")
|
||||
.withResourceContext(Java17TreeDumpTest.class, "jdkversiontests/java17/");
|
||||
private final JavaParsingHelper java17p = java17.withDefaultVersion("17-preview");
|
||||
private final JavaParsingHelper java16 = java17.withDefaultVersion("16");
|
||||
|
||||
public Java17TreeDumpTest() {
|
||||
super(new RelevantAttributePrinter(), ".java");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseParsingHelper<?, ?> getParser() {
|
||||
return java17;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sealedClassBeforeJava17() {
|
||||
ParseException thrown = Assert.assertThrows(ParseException.class, new ThrowingRunnable() {
|
||||
@Override
|
||||
public void run() throws Throwable {
|
||||
java16.parseResource("geometry/Shape.java");
|
||||
}
|
||||
});
|
||||
Assert.assertTrue("Unexpected message: " + thrown.getMessage(),
|
||||
thrown.getMessage().contains("Sealed Classes are only supported with JDK 16 Preview and JDK >= 17."));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sealedClass() {
|
||||
doTest("geometry/Shape");
|
||||
java17p.parseResource("geometry/Shape.java"); // make sure we can parse it with preview as well
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nonSealedClass() {
|
||||
doTest("geometry/Square");
|
||||
java17p.parseResource("geometry/Square.java"); // make sure we can parse it with preview as well
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sealedInterfaceBeforeJava17() {
|
||||
ParseException thrown = Assert.assertThrows(ParseException.class, new ThrowingRunnable() {
|
||||
@Override
|
||||
public void run() throws Throwable {
|
||||
java16.parseResource("expression/Expr.java");
|
||||
}
|
||||
});
|
||||
Assert.assertTrue("Unexpected message: " + thrown.getMessage(),
|
||||
thrown.getMessage().contains("Sealed Classes are only supported with JDK 16 Preview and JDK >= 17."));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sealedInterface() {
|
||||
doTest("expression/Expr");
|
||||
java17p.parseResource("expression/Expr.java"); // make sure we can parse it with preview as well
|
||||
}
|
||||
|
||||
}
|
@ -165,7 +165,7 @@ public class ParserCornersTest extends BaseJavaTreeDumpTest {
|
||||
public void testGitHubBug2767() {
|
||||
// PMD fails to parse an initializer block.
|
||||
// PMD 6.26.0 parses this code just fine.
|
||||
java.withDefaultVersion("15-preview")
|
||||
java.withDefaultVersion("16")
|
||||
.parse("class Foo {\n"
|
||||
+ " {final int I;}\n"
|
||||
+ "}\n");
|
||||
|
@ -12,9 +12,9 @@ import java.io.IOException
|
||||
|
||||
class ASTPatternTest : ProcessorTestSpec({
|
||||
|
||||
val typePatternsVersions = JavaVersion.since(J16).plus(J15__PREVIEW)
|
||||
val typePatternsVersions = JavaVersion.since(J16)
|
||||
|
||||
parserTest("Test patterns only available on JDK 15 (preview) and JDK16 and JDK16 (preview)",
|
||||
parserTest("Test patterns only available on JDK16 and JDK16 (preview) and JDK17 and JDK 17 (preview)",
|
||||
javaVersions = JavaVersion.except(typePatternsVersions)) {
|
||||
|
||||
inContext(ExpressionParsingCtx) {
|
||||
|
@ -34,8 +34,9 @@ enum class JavaVersion : Comparable<JavaVersion> {
|
||||
J12,
|
||||
J13,
|
||||
J14,
|
||||
J15, J15__PREVIEW,
|
||||
J16, J16__PREVIEW;
|
||||
J15,
|
||||
J16, J16__PREVIEW,
|
||||
J17, J17__PREVIEW;
|
||||
|
||||
/** Name suitable for use with e.g. [JavaParsingHelper.parse] */
|
||||
val pmdName: String = name.removePrefix("J").replaceFirst("__", "-").replace('_', '.').toLowerCase()
|
||||
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* 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 }
|
||||
|
||||
// not supported anymore with Java16
|
||||
//@interface MyLocalAnnotation {}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
+- CompilationUnit[@PackageName = ""]
|
||||
+- ClassOrInterfaceDeclaration[@Abstract = "false", @Annotation = "false", @Anonymous = "false", @BinaryName = "LocalInterfacesAndEnums", @CanonicalName = "LocalInterfacesAndEnums", @EffectiveVisibility = "public", @Enum = "false", @Final = "false", @Interface = "false", @Local = "false", @Nested = "false", @PackageName = "", @PackagePrivate = "false", @Record = "false", @RegularClass = "true", @RegularInterface = "false", @SimpleName = "LocalInterfacesAndEnums", @TopLevel = "true", @Visibility = "public"]
|
||||
+- ModifierList[@EffectiveModifiers = "{public}", @ExplicitModifiers = "{public}"]
|
||||
+- ClassOrInterfaceBody[@Size = "1"]
|
||||
+- Initializer[@Static = "false"]
|
||||
+- Block[@Size = "3", @containsComment = "true"]
|
||||
+- LocalClassStatement[]
|
||||
| +- ClassOrInterfaceDeclaration[@Abstract = "false", @Annotation = "false", @Anonymous = "false", @BinaryName = "LocalInterfacesAndEnums$1MyLocalClass", @CanonicalName = null, @EffectiveVisibility = "local", @Enum = "false", @Final = "false", @Interface = "false", @Local = "true", @Nested = "false", @PackageName = "", @PackagePrivate = "false", @Record = "false", @RegularClass = "true", @RegularInterface = "false", @SimpleName = "MyLocalClass", @TopLevel = "false", @Visibility = "local"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| +- ClassOrInterfaceBody[@Size = "0"]
|
||||
+- LocalClassStatement[]
|
||||
| +- ClassOrInterfaceDeclaration[@Abstract = "true", @Annotation = "false", @Anonymous = "false", @BinaryName = "LocalInterfacesAndEnums$1MyLocalInterface", @CanonicalName = null, @EffectiveVisibility = "local", @Enum = "false", @Final = "false", @Interface = "true", @Local = "true", @Nested = "false", @PackageName = "", @PackagePrivate = "false", @Record = "false", @RegularClass = "false", @RegularInterface = "true", @SimpleName = "MyLocalInterface", @TopLevel = "false", @Visibility = "local"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{abstract, static}", @ExplicitModifiers = "{}"]
|
||||
| +- ClassOrInterfaceBody[@Size = "0"]
|
||||
+- LocalClassStatement[]
|
||||
+- EnumDeclaration[@Abstract = "false", @Annotation = "false", @Anonymous = "false", @BinaryName = "LocalInterfacesAndEnums$1MyLocalEnum", @CanonicalName = null, @EffectiveVisibility = "local", @Enum = "true", @Final = "true", @Interface = "false", @Local = "true", @Nested = "false", @PackageName = "", @Record = "false", @RegularClass = "false", @RegularInterface = "false", @SimpleName = "MyLocalEnum", @TopLevel = "false", @Visibility = "local"]
|
||||
+- ModifierList[@EffectiveModifiers = "{static, final}", @ExplicitModifiers = "{}"]
|
||||
+- EnumBody[@SeparatorSemi = "false", @Size = "1", @TrailingComma = "false"]
|
||||
+- EnumConstant[@AnonymousClass = "false", @EffectiveVisibility = "local", @Image = "A", @MethodName = "new", @Name = "A", @Visibility = "public"]
|
||||
+- ModifierList[@EffectiveModifiers = "{public, static, final}", @ExplicitModifiers = "{}"]
|
||||
+- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "true", @ExceptionBlockParameter = "false", @Field = "false", @Final = "true", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "false", @Name = "A", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "true", @Visibility = "public"]
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @see <a href="https://openjdk.java.net/jeps/384">JEP 384: Records (Second Preview)</a>
|
||||
*/
|
||||
public class LocalRecords {
|
||||
public interface Merchant {}
|
||||
public static double computeSales(Merchant merchant, int month) {
|
||||
return month;
|
||||
}
|
||||
List<Merchant> findTopMerchants(List<Merchant> 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 statementThatStartsWithRecordAsRegularIdent() {
|
||||
// https://github.com/pmd/pmd/issues/3145
|
||||
final Map<String, String> record = new HashMap<>();
|
||||
record.put("key", "value");
|
||||
}
|
||||
|
||||
void methodWithLocalClass() {
|
||||
class MyLocalClass {}
|
||||
}
|
||||
|
||||
void methodWithLocalVarsNamedSealed() {
|
||||
int result = 0;
|
||||
int non = 1;
|
||||
int sealed = 2;
|
||||
result = non-sealed;
|
||||
System.out.println(result);
|
||||
}
|
||||
}
|
@ -1,217 +0,0 @@
|
||||
+- CompilationUnit[@PackageName = ""]
|
||||
+- ImportDeclaration[@ImportOnDemand = "false", @ImportedName = "java.util.stream.Collectors", @ImportedSimpleName = "Collectors", @PackageName = "java.util.stream", @Static = "false"]
|
||||
+- ImportDeclaration[@ImportOnDemand = "false", @ImportedName = "java.util.List", @ImportedSimpleName = "List", @PackageName = "java.util", @Static = "false"]
|
||||
+- ClassOrInterfaceDeclaration[@Abstract = "false", @Annotation = "false", @Anonymous = "false", @BinaryName = "LocalRecords", @CanonicalName = "LocalRecords", @EffectiveVisibility = "public", @Enum = "false", @Final = "false", @Interface = "false", @Local = "false", @Nested = "false", @PackageName = "", @PackagePrivate = "false", @Record = "false", @RegularClass = "true", @RegularInterface = "false", @SimpleName = "LocalRecords", @TopLevel = "true", @Visibility = "public"]
|
||||
+- ModifierList[@EffectiveModifiers = "{public}", @ExplicitModifiers = "{public}"]
|
||||
+- ClassOrInterfaceBody[@Size = "7"]
|
||||
+- ClassOrInterfaceDeclaration[@Abstract = "true", @Annotation = "false", @Anonymous = "false", @BinaryName = "LocalRecords$Merchant", @CanonicalName = "LocalRecords.Merchant", @EffectiveVisibility = "public", @Enum = "false", @Final = "false", @Interface = "true", @Local = "false", @Nested = "true", @PackageName = "", @PackagePrivate = "false", @Record = "false", @RegularClass = "false", @RegularInterface = "true", @SimpleName = "Merchant", @TopLevel = "false", @Visibility = "public"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{public, abstract, static}", @ExplicitModifiers = "{public}"]
|
||||
| +- ClassOrInterfaceBody[@Size = "0"]
|
||||
+- MethodDeclaration[@Abstract = "false", @Arity = "2", @EffectiveVisibility = "public", @Image = "computeSales", @Name = "computeSales", @Overridden = "false", @Varargs = "false", @Visibility = "public", @Void = "false"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{public, static}", @ExplicitModifiers = "{public, static}"]
|
||||
| +- PrimitiveType[@Kind = "double"]
|
||||
| +- FormalParameters[@Size = "2"]
|
||||
| | +- FormalParameter[@EffectiveVisibility = "local", @Final = "false", @Varargs = "false", @Visibility = "local"]
|
||||
| | | +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "Merchant"]
|
||||
| | | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "true", @LambdaParameter = "false", @LocalVariable = "false", @Name = "merchant", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| | +- FormalParameter[@EffectiveVisibility = "local", @Final = "false", @Varargs = "false", @Visibility = "local"]
|
||||
| | +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| | +- PrimitiveType[@Kind = "int"]
|
||||
| | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "true", @LambdaParameter = "false", @LocalVariable = "false", @Name = "month", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| +- Block[@Size = "1", @containsComment = "false"]
|
||||
| +- ReturnStatement[]
|
||||
| +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "month", @Name = "month", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
+- MethodDeclaration[@Abstract = "false", @Arity = "2", @EffectiveVisibility = "package", @Image = "findTopMerchants", @Name = "findTopMerchants", @Overridden = "false", @Varargs = "false", @Visibility = "package", @Void = "false"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "List"]
|
||||
| | +- TypeArguments[@Diamond = "false", @Size = "1"]
|
||||
| | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "Merchant"]
|
||||
| +- FormalParameters[@Size = "2"]
|
||||
| | +- FormalParameter[@EffectiveVisibility = "local", @Final = "false", @Varargs = "false", @Visibility = "local"]
|
||||
| | | +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "List"]
|
||||
| | | | +- TypeArguments[@Diamond = "false", @Size = "1"]
|
||||
| | | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "Merchant"]
|
||||
| | | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "true", @LambdaParameter = "false", @LocalVariable = "false", @Name = "merchants", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| | +- FormalParameter[@EffectiveVisibility = "local", @Final = "false", @Varargs = "false", @Visibility = "local"]
|
||||
| | +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| | +- PrimitiveType[@Kind = "int"]
|
||||
| | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "true", @LambdaParameter = "false", @LocalVariable = "false", @Name = "month", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| +- Block[@Size = "2", @containsComment = "false"]
|
||||
| +- LocalClassStatement[]
|
||||
| | +- RecordDeclaration[@Abstract = "false", @Annotation = "false", @Anonymous = "false", @BinaryName = "LocalRecords$1MerchantSales", @CanonicalName = null, @EffectiveVisibility = "local", @Enum = "false", @Final = "true", @Interface = "false", @Local = "true", @Nested = "false", @PackageName = "", @Record = "true", @RegularClass = "false", @RegularInterface = "false", @SimpleName = "MerchantSales", @TopLevel = "false", @Visibility = "local"]
|
||||
| | +- ModifierList[@EffectiveModifiers = "{static, final}", @ExplicitModifiers = "{}"]
|
||||
| | +- RecordComponentList[@Size = "2", @Varargs = "false"]
|
||||
| | | +- RecordComponent[@EffectiveVisibility = "local", @Varargs = "false", @Visibility = "private"]
|
||||
| | | | +- ModifierList[@EffectiveModifiers = "{private, final}", @ExplicitModifiers = "{}"]
|
||||
| | | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "Merchant"]
|
||||
| | | | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "true", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "false", @Name = "merchant", @PatternBinding = "false", @RecordComponent = "true", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "private"]
|
||||
| | | +- RecordComponent[@EffectiveVisibility = "local", @Varargs = "false", @Visibility = "private"]
|
||||
| | | +- ModifierList[@EffectiveModifiers = "{private, final}", @ExplicitModifiers = "{}"]
|
||||
| | | +- PrimitiveType[@Kind = "double"]
|
||||
| | | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "true", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "false", @Name = "sales", @PatternBinding = "false", @RecordComponent = "true", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "private"]
|
||||
| | +- RecordBody[@Size = "0"]
|
||||
| +- ReturnStatement[]
|
||||
| +- MethodCall[@CompileTimeConstant = "false", @Image = "collect", @MethodName = "collect", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- MethodCall[@CompileTimeConstant = "false", @Image = "map", @MethodName = "map", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- MethodCall[@CompileTimeConstant = "false", @Image = "sorted", @MethodName = "sorted", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- MethodCall[@CompileTimeConstant = "false", @Image = "map", @MethodName = "map", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- MethodCall[@CompileTimeConstant = "false", @Image = "stream", @MethodName = "stream", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "merchants", @Name = "merchants", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | | +- ArgumentList[@Size = "0"]
|
||||
| | | | +- ArgumentList[@Size = "1"]
|
||||
| | | | +- LambdaExpression[@BlockBody = "false", @CompileTimeConstant = "false", @ExpressionBody = "true", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- LambdaParameterList[@Size = "1"]
|
||||
| | | | | +- LambdaParameter[@EffectiveVisibility = "package", @Final = "false", @TypeInferred = "true", @Visibility = "package"]
|
||||
| | | | | +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| | | | | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "package", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "true", @LambdaParameter = "true", @LocalVariable = "false", @Name = "merchant", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "true", @Visibility = "package"]
|
||||
| | | | +- ConstructorCall[@AnonymousClass = "false", @CompileTimeConstant = "false", @DiamondTypeArgs = "false", @MethodName = "new", @ParenthesisDepth = "0", @Parenthesized = "false", @QualifiedInstanceCreation = "false"]
|
||||
| | | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "MerchantSales"]
|
||||
| | | | +- ArgumentList[@Size = "2"]
|
||||
| | | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "merchant", @Name = "merchant", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- MethodCall[@CompileTimeConstant = "false", @Image = "computeSales", @MethodName = "computeSales", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- ArgumentList[@Size = "2"]
|
||||
| | | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "merchant", @Name = "merchant", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "month", @Name = "month", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- ArgumentList[@Size = "1"]
|
||||
| | | +- LambdaExpression[@BlockBody = "false", @CompileTimeConstant = "false", @ExpressionBody = "true", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- LambdaParameterList[@Size = "2"]
|
||||
| | | | +- LambdaParameter[@EffectiveVisibility = "package", @Final = "false", @TypeInferred = "true", @Visibility = "package"]
|
||||
| | | | | +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| | | | | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "package", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "true", @LambdaParameter = "true", @LocalVariable = "false", @Name = "m1", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "true", @Visibility = "package"]
|
||||
| | | | +- LambdaParameter[@EffectiveVisibility = "package", @Final = "false", @TypeInferred = "true", @Visibility = "package"]
|
||||
| | | | +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| | | | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "package", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "true", @LambdaParameter = "true", @LocalVariable = "false", @Name = "m2", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "true", @Visibility = "package"]
|
||||
| | | +- MethodCall[@CompileTimeConstant = "false", @Image = "compare", @MethodName = "compare", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- TypeExpression[@CompileTimeConstant = "false", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "Double"]
|
||||
| | | +- ArgumentList[@Size = "2"]
|
||||
| | | +- MethodCall[@CompileTimeConstant = "false", @Image = "sales", @MethodName = "sales", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "m2", @Name = "m2", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- ArgumentList[@Size = "0"]
|
||||
| | | +- MethodCall[@CompileTimeConstant = "false", @Image = "sales", @MethodName = "sales", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "m1", @Name = "m1", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- ArgumentList[@Size = "0"]
|
||||
| | +- ArgumentList[@Size = "1"]
|
||||
| | +- MethodReference[@CompileTimeConstant = "false", @ConstructorReference = "false", @MethodName = "merchant", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- TypeExpression[@CompileTimeConstant = "false", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "MerchantSales"]
|
||||
| +- ArgumentList[@Size = "1"]
|
||||
| +- MethodCall[@CompileTimeConstant = "false", @Image = "toList", @MethodName = "toList", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- TypeExpression[@CompileTimeConstant = "false", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "Collectors"]
|
||||
| +- ArgumentList[@Size = "0"]
|
||||
+- MethodDeclaration[@Abstract = "false", @Arity = "0", @EffectiveVisibility = "package", @Image = "methodWithLocalRecordAndModifiers", @Name = "methodWithLocalRecordAndModifiers", @Overridden = "false", @Varargs = "false", @Visibility = "package", @Void = "true"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| +- VoidType[]
|
||||
| +- FormalParameters[@Size = "0"]
|
||||
| +- Block[@Size = "4", @containsComment = "false"]
|
||||
| +- LocalClassStatement[]
|
||||
| | +- RecordDeclaration[@Abstract = "false", @Annotation = "false", @Anonymous = "false", @BinaryName = "LocalRecords$1MyRecord1", @CanonicalName = null, @EffectiveVisibility = "local", @Enum = "false", @Final = "true", @Interface = "false", @Local = "true", @Nested = "false", @PackageName = "", @Record = "true", @RegularClass = "false", @RegularInterface = "false", @SimpleName = "MyRecord1", @TopLevel = "false", @Visibility = "local"]
|
||||
| | +- ModifierList[@EffectiveModifiers = "{static, final}", @ExplicitModifiers = "{final}"]
|
||||
| | +- RecordComponentList[@Size = "1", @Varargs = "false"]
|
||||
| | | +- RecordComponent[@EffectiveVisibility = "local", @Varargs = "false", @Visibility = "private"]
|
||||
| | | +- ModifierList[@EffectiveModifiers = "{private, final}", @ExplicitModifiers = "{}"]
|
||||
| | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "String"]
|
||||
| | | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "true", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "false", @Name = "a", @PatternBinding = "false", @RecordComponent = "true", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "private"]
|
||||
| | +- RecordBody[@Size = "0"]
|
||||
| +- LocalClassStatement[]
|
||||
| | +- RecordDeclaration[@Abstract = "false", @Annotation = "false", @Anonymous = "false", @BinaryName = "LocalRecords$1MyRecord2", @CanonicalName = null, @EffectiveVisibility = "local", @Enum = "false", @Final = "true", @Interface = "false", @Local = "true", @Nested = "false", @PackageName = "", @Record = "true", @RegularClass = "false", @RegularInterface = "false", @SimpleName = "MyRecord2", @TopLevel = "false", @Visibility = "local"]
|
||||
| | +- ModifierList[@EffectiveModifiers = "{static, final}", @ExplicitModifiers = "{static, final}"]
|
||||
| | +- RecordComponentList[@Size = "1", @Varargs = "false"]
|
||||
| | | +- RecordComponent[@EffectiveVisibility = "local", @Varargs = "false", @Visibility = "private"]
|
||||
| | | +- ModifierList[@EffectiveModifiers = "{private, final}", @ExplicitModifiers = "{}"]
|
||||
| | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "String"]
|
||||
| | | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "true", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "false", @Name = "a", @PatternBinding = "false", @RecordComponent = "true", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "private"]
|
||||
| | +- RecordBody[@Size = "0"]
|
||||
| +- LocalClassStatement[]
|
||||
| | +- RecordDeclaration[@Abstract = "false", @Annotation = "false", @Anonymous = "false", @BinaryName = "LocalRecords$1MyRecord3", @CanonicalName = null, @EffectiveVisibility = "local", @Enum = "false", @Final = "true", @Interface = "false", @Local = "true", @Nested = "false", @PackageName = "", @Record = "true", @RegularClass = "false", @RegularInterface = "false", @SimpleName = "MyRecord3", @TopLevel = "false", @Visibility = "local"]
|
||||
| | +- ModifierList[@EffectiveModifiers = "{static, final}", @ExplicitModifiers = "{}"]
|
||||
| | | +- Annotation[@SimpleName = "Deprecated"]
|
||||
| | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "Deprecated"]
|
||||
| | +- RecordComponentList[@Size = "1", @Varargs = "false"]
|
||||
| | | +- RecordComponent[@EffectiveVisibility = "local", @Varargs = "false", @Visibility = "private"]
|
||||
| | | +- ModifierList[@EffectiveModifiers = "{private, final}", @ExplicitModifiers = "{}"]
|
||||
| | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "String"]
|
||||
| | | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "true", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "false", @Name = "a", @PatternBinding = "false", @RecordComponent = "true", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "private"]
|
||||
| | +- RecordBody[@Size = "0"]
|
||||
| +- LocalClassStatement[]
|
||||
| +- RecordDeclaration[@Abstract = "false", @Annotation = "false", @Anonymous = "false", @BinaryName = "LocalRecords$1MyRecord4", @CanonicalName = null, @EffectiveVisibility = "local", @Enum = "false", @Final = "true", @Interface = "false", @Local = "true", @Nested = "false", @PackageName = "", @Record = "true", @RegularClass = "false", @RegularInterface = "false", @SimpleName = "MyRecord4", @TopLevel = "false", @Visibility = "local"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{static, final}", @ExplicitModifiers = "{static, final}"]
|
||||
| | +- Annotation[@SimpleName = "Deprecated"]
|
||||
| | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "Deprecated"]
|
||||
| +- RecordComponentList[@Size = "1", @Varargs = "false"]
|
||||
| | +- RecordComponent[@EffectiveVisibility = "local", @Varargs = "false", @Visibility = "private"]
|
||||
| | +- ModifierList[@EffectiveModifiers = "{private, final}", @ExplicitModifiers = "{}"]
|
||||
| | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "String"]
|
||||
| | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "true", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "false", @Name = "a", @PatternBinding = "false", @RecordComponent = "true", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "private"]
|
||||
| +- RecordBody[@Size = "0"]
|
||||
+- MethodDeclaration[@Abstract = "false", @Arity = "0", @EffectiveVisibility = "package", @Image = "statementThatStartsWithRecordAsRegularIdent", @Name = "statementThatStartsWithRecordAsRegularIdent", @Overridden = "false", @Varargs = "false", @Visibility = "package", @Void = "true"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| +- VoidType[]
|
||||
| +- FormalParameters[@Size = "0"]
|
||||
| +- Block[@Size = "2", @containsComment = "false"]
|
||||
| +- LocalVariableDeclaration[@EffectiveVisibility = "local", @Final = "true", @TypeInferred = "false", @Visibility = "local"]
|
||||
| | +- ModifierList[@EffectiveModifiers = "{final}", @ExplicitModifiers = "{final}"]
|
||||
| | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "Map"]
|
||||
| | | +- TypeArguments[@Diamond = "false", @Size = "2"]
|
||||
| | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "String"]
|
||||
| | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "String"]
|
||||
| | +- VariableDeclarator[@Initializer = "true", @Name = "record"]
|
||||
| | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "true", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "true", @Name = "record", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| | +- ConstructorCall[@AnonymousClass = "false", @CompileTimeConstant = "false", @DiamondTypeArgs = "true", @MethodName = "new", @ParenthesisDepth = "0", @Parenthesized = "false", @QualifiedInstanceCreation = "false"]
|
||||
| | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "HashMap"]
|
||||
| | | +- TypeArguments[@Diamond = "true", @Size = "0"]
|
||||
| | +- ArgumentList[@Size = "0"]
|
||||
| +- ExpressionStatement[]
|
||||
| +- MethodCall[@CompileTimeConstant = "false", @Image = "put", @MethodName = "put", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "record", @Name = "record", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- ArgumentList[@Size = "2"]
|
||||
| +- StringLiteral[@CompileTimeConstant = "true", @ConstValue = "key", @Empty = "false", @Image = "\"key\"", @Length = "3", @ParenthesisDepth = "0", @Parenthesized = "false", @TextBlock = "false"]
|
||||
| +- StringLiteral[@CompileTimeConstant = "true", @ConstValue = "value", @Empty = "false", @Image = "\"value\"", @Length = "5", @ParenthesisDepth = "0", @Parenthesized = "false", @TextBlock = "false"]
|
||||
+- MethodDeclaration[@Abstract = "false", @Arity = "0", @EffectiveVisibility = "package", @Image = "methodWithLocalClass", @Name = "methodWithLocalClass", @Overridden = "false", @Varargs = "false", @Visibility = "package", @Void = "true"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| +- VoidType[]
|
||||
| +- FormalParameters[@Size = "0"]
|
||||
| +- Block[@Size = "1", @containsComment = "false"]
|
||||
| +- LocalClassStatement[]
|
||||
| +- ClassOrInterfaceDeclaration[@Abstract = "false", @Annotation = "false", @Anonymous = "false", @BinaryName = "LocalRecords$1MyLocalClass", @CanonicalName = null, @EffectiveVisibility = "local", @Enum = "false", @Final = "false", @Interface = "false", @Local = "true", @Nested = "false", @PackageName = "", @PackagePrivate = "false", @Record = "false", @RegularClass = "true", @RegularInterface = "false", @SimpleName = "MyLocalClass", @TopLevel = "false", @Visibility = "local"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| +- ClassOrInterfaceBody[@Size = "0"]
|
||||
+- MethodDeclaration[@Abstract = "false", @Arity = "0", @EffectiveVisibility = "package", @Image = "methodWithLocalVarsNamedSealed", @Name = "methodWithLocalVarsNamedSealed", @Overridden = "false", @Varargs = "false", @Visibility = "package", @Void = "true"]
|
||||
+- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
+- VoidType[]
|
||||
+- FormalParameters[@Size = "0"]
|
||||
+- Block[@Size = "5", @containsComment = "false"]
|
||||
+- LocalVariableDeclaration[@EffectiveVisibility = "local", @Final = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| +- PrimitiveType[@Kind = "int"]
|
||||
| +- VariableDeclarator[@Initializer = "true", @Name = "result"]
|
||||
| +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "true", @Name = "result", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| +- NumericLiteral[@Base = "10", @CompileTimeConstant = "true", @DoubleLiteral = "false", @FloatLiteral = "false", @Image = "0", @IntLiteral = "true", @Integral = "true", @LongLiteral = "false", @ParenthesisDepth = "0", @Parenthesized = "false", @ValueAsDouble = "0.0", @ValueAsFloat = "0.0", @ValueAsInt = "0", @ValueAsLong = "0"]
|
||||
+- LocalVariableDeclaration[@EffectiveVisibility = "local", @Final = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| +- PrimitiveType[@Kind = "int"]
|
||||
| +- VariableDeclarator[@Initializer = "true", @Name = "non"]
|
||||
| +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "true", @Name = "non", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| +- NumericLiteral[@Base = "10", @CompileTimeConstant = "true", @DoubleLiteral = "false", @FloatLiteral = "false", @Image = "1", @IntLiteral = "true", @Integral = "true", @LongLiteral = "false", @ParenthesisDepth = "0", @Parenthesized = "false", @ValueAsDouble = "1.0", @ValueAsFloat = "1.0", @ValueAsInt = "1", @ValueAsLong = "1"]
|
||||
+- LocalVariableDeclaration[@EffectiveVisibility = "local", @Final = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| +- PrimitiveType[@Kind = "int"]
|
||||
| +- VariableDeclarator[@Initializer = "true", @Name = "sealed"]
|
||||
| +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "true", @Name = "sealed", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| +- NumericLiteral[@Base = "10", @CompileTimeConstant = "true", @DoubleLiteral = "false", @FloatLiteral = "false", @Image = "2", @IntLiteral = "true", @Integral = "true", @LongLiteral = "false", @ParenthesisDepth = "0", @Parenthesized = "false", @ValueAsDouble = "2.0", @ValueAsFloat = "2.0", @ValueAsInt = "2", @ValueAsLong = "2"]
|
||||
+- ExpressionStatement[]
|
||||
| +- AssignmentExpression[@CompileTimeConstant = "false", @Compound = "false", @Operator = "=", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- VariableAccess[@AccessType = "WRITE", @CompileTimeConstant = "false", @Image = "result", @Name = "result", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- InfixExpression[@CompileTimeConstant = "false", @Operator = "-", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "non", @Name = "non", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "sealed", @Name = "sealed", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
+- ExpressionStatement[]
|
||||
+- MethodCall[@CompileTimeConstant = "false", @Image = "println", @MethodName = "println", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
+- FieldAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "out", @Name = "out", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- TypeExpression[@CompileTimeConstant = "false", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "System"]
|
||||
+- ArgumentList[@Size = "1"]
|
||||
+- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "result", @Name = "result", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
@ -1,34 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* @see <a href="https://openjdk.java.net/jeps/375">JEP 375: Pattern Matching for instanceof (Second Preview)</a>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
+- CompilationUnit[@PackageName = ""]
|
||||
+- ClassOrInterfaceDeclaration[@Abstract = "false", @Annotation = "false", @Anonymous = "false", @BinaryName = "PatternMatchingInstanceof", @CanonicalName = "PatternMatchingInstanceof", @EffectiveVisibility = "public", @Enum = "false", @Final = "false", @Interface = "false", @Local = "false", @Nested = "false", @PackageName = "", @PackagePrivate = "false", @Record = "false", @RegularClass = "true", @RegularInterface = "false", @SimpleName = "PatternMatchingInstanceof", @TopLevel = "true", @Visibility = "public"]
|
||||
+- ModifierList[@EffectiveModifiers = "{public}", @ExplicitModifiers = "{public}"]
|
||||
+- ClassOrInterfaceBody[@Size = "3"]
|
||||
+- FieldDeclaration[@EffectiveVisibility = "private", @Visibility = "private"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{private}", @ExplicitModifiers = "{private}"]
|
||||
| +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "String"]
|
||||
| +- VariableDeclarator[@Initializer = "true", @Name = "s"]
|
||||
| +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "private", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "true", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "false", @Name = "s", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "private"]
|
||||
| +- StringLiteral[@CompileTimeConstant = "true", @ConstValue = "other string", @Empty = "false", @Image = "\"other string\"", @Length = "12", @ParenthesisDepth = "0", @Parenthesized = "false", @TextBlock = "false"]
|
||||
+- MethodDeclaration[@Abstract = "false", @Arity = "0", @EffectiveVisibility = "public", @Image = "test", @Name = "test", @Overridden = "false", @Varargs = "false", @Visibility = "public", @Void = "true"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{public}", @ExplicitModifiers = "{public}"]
|
||||
| +- VoidType[]
|
||||
| +- FormalParameters[@Size = "0"]
|
||||
| +- Block[@Size = "5", @containsComment = "false"]
|
||||
| +- LocalVariableDeclaration[@EffectiveVisibility = "local", @Final = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| | +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "Object"]
|
||||
| | +- VariableDeclarator[@Initializer = "true", @Name = "obj"]
|
||||
| | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "true", @Name = "obj", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| | +- StringLiteral[@CompileTimeConstant = "true", @ConstValue = "abc", @Empty = "false", @Image = "\"abc\"", @Length = "3", @ParenthesisDepth = "0", @Parenthesized = "false", @TextBlock = "false"]
|
||||
| +- IfStatement[@Else = "true"]
|
||||
| | +- InfixExpression[@CompileTimeConstant = "false", @Operator = "instanceof", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "obj", @Name = "obj", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- PatternExpression[@CompileTimeConstant = "false", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- TypePattern[@EffectiveVisibility = "package", @Visibility = "package"]
|
||||
| | | +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "String"]
|
||||
| | | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "false", @Name = "s", @PatternBinding = "true", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| | +- Block[@Size = "1", @containsComment = "true"]
|
||||
| | | +- ExpressionStatement[]
|
||||
| | | +- MethodCall[@CompileTimeConstant = "false", @Image = "println", @MethodName = "println", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- FieldAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "out", @Name = "out", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- TypeExpression[@CompileTimeConstant = "false", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "System"]
|
||||
| | | +- ArgumentList[@Size = "1"]
|
||||
| | | +- InfixExpression[@CompileTimeConstant = "false", @Operator = "+", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- StringLiteral[@CompileTimeConstant = "true", @ConstValue = "a) obj == s: ", @Empty = "false", @Image = "\"a) obj == s: \"", @Length = "13", @ParenthesisDepth = "0", @Parenthesized = "false", @TextBlock = "false"]
|
||||
| | | +- InfixExpression[@CompileTimeConstant = "false", @Operator = "==", @ParenthesisDepth = "1", @Parenthesized = "true"]
|
||||
| | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "obj", @Name = "obj", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "s", @Name = "s", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- Block[@Size = "1", @containsComment = "true"]
|
||||
| | +- ExpressionStatement[]
|
||||
| | +- MethodCall[@CompileTimeConstant = "false", @Image = "println", @MethodName = "println", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- FieldAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "out", @Name = "out", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- TypeExpression[@CompileTimeConstant = "false", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "System"]
|
||||
| | +- ArgumentList[@Size = "1"]
|
||||
| | +- InfixExpression[@CompileTimeConstant = "false", @Operator = "+", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- StringLiteral[@CompileTimeConstant = "true", @ConstValue = "b) obj == s: ", @Empty = "false", @Image = "\"b) obj == s: \"", @Length = "13", @ParenthesisDepth = "0", @Parenthesized = "false", @TextBlock = "false"]
|
||||
| | +- InfixExpression[@CompileTimeConstant = "false", @Operator = "==", @ParenthesisDepth = "1", @Parenthesized = "true"]
|
||||
| | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "obj", @Name = "obj", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "s", @Name = "s", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- IfStatement[@Else = "true"]
|
||||
| | +- UnaryExpression[@CompileTimeConstant = "false", @Operator = "!", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- InfixExpression[@CompileTimeConstant = "false", @Operator = "instanceof", @ParenthesisDepth = "1", @Parenthesized = "true"]
|
||||
| | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "obj", @Name = "obj", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- PatternExpression[@CompileTimeConstant = "false", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- TypePattern[@EffectiveVisibility = "package", @Visibility = "package"]
|
||||
| | | +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "String"]
|
||||
| | | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "false", @Name = "s", @PatternBinding = "true", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| | +- Block[@Size = "1", @containsComment = "true"]
|
||||
| | | +- ExpressionStatement[]
|
||||
| | | +- MethodCall[@CompileTimeConstant = "false", @Image = "println", @MethodName = "println", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- FieldAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "out", @Name = "out", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- TypeExpression[@CompileTimeConstant = "false", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "System"]
|
||||
| | | +- ArgumentList[@Size = "1"]
|
||||
| | | +- InfixExpression[@CompileTimeConstant = "false", @Operator = "+", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- StringLiteral[@CompileTimeConstant = "true", @ConstValue = "c) obj == s: ", @Empty = "false", @Image = "\"c) obj == s: \"", @Length = "13", @ParenthesisDepth = "0", @Parenthesized = "false", @TextBlock = "false"]
|
||||
| | | +- InfixExpression[@CompileTimeConstant = "false", @Operator = "==", @ParenthesisDepth = "1", @Parenthesized = "true"]
|
||||
| | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "obj", @Name = "obj", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "s", @Name = "s", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- Block[@Size = "1", @containsComment = "true"]
|
||||
| | +- ExpressionStatement[]
|
||||
| | +- MethodCall[@CompileTimeConstant = "false", @Image = "println", @MethodName = "println", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- FieldAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "out", @Name = "out", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- TypeExpression[@CompileTimeConstant = "false", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "System"]
|
||||
| | +- ArgumentList[@Size = "1"]
|
||||
| | +- InfixExpression[@CompileTimeConstant = "false", @Operator = "+", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- StringLiteral[@CompileTimeConstant = "true", @ConstValue = "d) obj == s: ", @Empty = "false", @Image = "\"d) obj == s: \"", @Length = "13", @ParenthesisDepth = "0", @Parenthesized = "false", @TextBlock = "false"]
|
||||
| | +- InfixExpression[@CompileTimeConstant = "false", @Operator = "==", @ParenthesisDepth = "1", @Parenthesized = "true"]
|
||||
| | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "obj", @Name = "obj", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "s", @Name = "s", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- IfStatement[@Else = "false"]
|
||||
| | +- InfixExpression[@CompileTimeConstant = "false", @Operator = "&&", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- InfixExpression[@CompileTimeConstant = "false", @Operator = "instanceof", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "obj", @Name = "obj", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- PatternExpression[@CompileTimeConstant = "false", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- TypePattern[@EffectiveVisibility = "package", @Visibility = "package"]
|
||||
| | | | +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| | | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "String"]
|
||||
| | | | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "false", @Name = "s", @PatternBinding = "true", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| | | +- InfixExpression[@CompileTimeConstant = "false", @Operator = ">", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- MethodCall[@CompileTimeConstant = "false", @Image = "length", @MethodName = "length", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "s", @Name = "s", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | | +- ArgumentList[@Size = "0"]
|
||||
| | | +- NumericLiteral[@Base = "10", @CompileTimeConstant = "true", @DoubleLiteral = "false", @FloatLiteral = "false", @Image = "2", @IntLiteral = "true", @Integral = "true", @LongLiteral = "false", @ParenthesisDepth = "0", @Parenthesized = "false", @ValueAsDouble = "2.0", @ValueAsFloat = "2.0", @ValueAsInt = "2", @ValueAsLong = "2"]
|
||||
| | +- Block[@Size = "1", @containsComment = "true"]
|
||||
| | +- ExpressionStatement[]
|
||||
| | +- MethodCall[@CompileTimeConstant = "false", @Image = "println", @MethodName = "println", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- FieldAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "out", @Name = "out", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- TypeExpression[@CompileTimeConstant = "false", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "System"]
|
||||
| | +- ArgumentList[@Size = "1"]
|
||||
| | +- InfixExpression[@CompileTimeConstant = "false", @Operator = "+", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- StringLiteral[@CompileTimeConstant = "true", @ConstValue = "e) obj == s: ", @Empty = "false", @Image = "\"e) obj == s: \"", @Length = "13", @ParenthesisDepth = "0", @Parenthesized = "false", @TextBlock = "false"]
|
||||
| | +- InfixExpression[@CompileTimeConstant = "false", @Operator = "==", @ParenthesisDepth = "1", @Parenthesized = "true"]
|
||||
| | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "obj", @Name = "obj", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "s", @Name = "s", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- IfStatement[@Else = "false"]
|
||||
| +- InfixExpression[@CompileTimeConstant = "false", @Operator = "||", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- InfixExpression[@CompileTimeConstant = "false", @Operator = "instanceof", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "obj", @Name = "obj", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- PatternExpression[@CompileTimeConstant = "false", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- TypePattern[@EffectiveVisibility = "package", @Visibility = "package"]
|
||||
| | | +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| | | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "String"]
|
||||
| | | +- VariableDeclaratorId[@ArrayType = "false", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "false", @LambdaParameter = "false", @LocalVariable = "false", @Name = "s", @PatternBinding = "true", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
| | +- InfixExpression[@CompileTimeConstant = "false", @Operator = ">", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- MethodCall[@CompileTimeConstant = "false", @Image = "length", @MethodName = "length", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "s", @Name = "s", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | | +- ArgumentList[@Size = "0"]
|
||||
| | +- NumericLiteral[@Base = "10", @CompileTimeConstant = "true", @DoubleLiteral = "false", @FloatLiteral = "false", @Image = "5", @IntLiteral = "true", @Integral = "true", @LongLiteral = "false", @ParenthesisDepth = "0", @Parenthesized = "false", @ValueAsDouble = "5.0", @ValueAsFloat = "5.0", @ValueAsInt = "5", @ValueAsLong = "5"]
|
||||
| +- Block[@Size = "1", @containsComment = "true"]
|
||||
| +- ExpressionStatement[]
|
||||
| +- MethodCall[@CompileTimeConstant = "false", @Image = "println", @MethodName = "println", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- FieldAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "out", @Name = "out", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- TypeExpression[@CompileTimeConstant = "false", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "System"]
|
||||
| +- ArgumentList[@Size = "1"]
|
||||
| +- InfixExpression[@CompileTimeConstant = "false", @Operator = "+", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- StringLiteral[@CompileTimeConstant = "true", @ConstValue = "f) obj == s: ", @Empty = "false", @Image = "\"f) obj == s: \"", @Length = "13", @ParenthesisDepth = "0", @Parenthesized = "false", @TextBlock = "false"]
|
||||
| +- InfixExpression[@CompileTimeConstant = "false", @Operator = "==", @ParenthesisDepth = "1", @Parenthesized = "true"]
|
||||
| +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "obj", @Name = "obj", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Image = "s", @Name = "s", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
+- MethodDeclaration[@Abstract = "false", @Arity = "1", @EffectiveVisibility = "public", @Image = "main", @MainMethod = "true", @Name = "main", @Overridden = "false", @Varargs = "false", @Visibility = "public", @Void = "true"]
|
||||
+- ModifierList[@EffectiveModifiers = "{public, static}", @ExplicitModifiers = "{public, static}"]
|
||||
+- VoidType[]
|
||||
+- FormalParameters[@Size = "1"]
|
||||
| +- FormalParameter[@EffectiveVisibility = "local", @Final = "false", @Varargs = "false", @Visibility = "local"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| +- ArrayType[@ArrayDepth = "1"]
|
||||
| | +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "String"]
|
||||
| | +- ArrayDimensions[@Size = "1"]
|
||||
| | +- ArrayTypeDim[@Varargs = "false"]
|
||||
| +- VariableDeclaratorId[@ArrayType = "true", @EffectiveVisibility = "local", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @Final = "false", @ForLoopVariable = "false", @ForeachVariable = "false", @FormalParameter = "true", @LambdaParameter = "false", @LocalVariable = "false", @Name = "args", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @Visibility = "local"]
|
||||
+- Block[@Size = "1", @containsComment = "false"]
|
||||
+- ExpressionStatement[]
|
||||
+- MethodCall[@CompileTimeConstant = "false", @Image = "test", @MethodName = "test", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
+- ConstructorCall[@AnonymousClass = "false", @CompileTimeConstant = "false", @DiamondTypeArgs = "false", @MethodName = "new", @ParenthesisDepth = "0", @Parenthesized = "false", @QualifiedInstanceCreation = "false"]
|
||||
| +- ClassOrInterfaceType[@FullyQualified = "false", @SimpleName = "PatternMatchingInstanceof"]
|
||||
| +- ArgumentList[@Size = "0"]
|
||||
+- ArgumentList[@Size = "0"]
|
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see <a href="https://openjdk.java.net/jeps/384">JEP 384: Records (Second Preview)</a>
|
||||
*/
|
||||
public record Point(int x, int y) {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Point p = new Point(1, 2);
|
||||
System.out.println("p = " + p);
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
+- CompilationUnit[@PackageName = "", @declarationsAreInDefaultPackage = "true"]
|
||||
+- RecordDeclaration[@Abstract = "false", @Annotation = "false", @Anonymous = "false", @BinaryName = "Point", @CanonicalName = "Point", @Enum = "false", @Image = "Point", @Interface = "false", @Local = "false", @Nested = "false", @PackageName = "", @Record = "true", @RegularClass = "false", @SimpleName = "Point", @TopLevel = "true", @Visibility = "public"]
|
||||
+- ModifierList[@EffectiveModifiers = "{public, final}", @ExplicitModifiers = "{public}"]
|
||||
+- RecordComponentList[@Size = "2", @Varargs = "false"]
|
||||
| +- RecordComponent[@Varargs = "false", @Visibility = "private"]
|
||||
| | +- ModifierList[@EffectiveModifiers = "{private, final}", @ExplicitModifiers = "{}"]
|
||||
| | +- PrimitiveType[@ArrayDepth = "0", @ArrayType = "false", @Boolean = "false", @ClassOrInterfaceType = "false", @Image = "int", @ModelConstant = "int", @PrimitiveType = "true", @ReferenceType = "false", @TypeImage = "int"]
|
||||
| | +- VariableDeclaratorId[@ArrayType = "false", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @FormalParameter = "false", @Image = "x", @LambdaParameter = "false", @LocalVariable = "false", @Name = "x", @PatternBinding = "false", @RecordComponent = "true", @ResourceDeclaration = "false", @TypeInferred = "false", @VariableName = "x", @Visibility = "private"]
|
||||
| +- RecordComponent[@Varargs = "false", @Visibility = "private"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{private, final}", @ExplicitModifiers = "{}"]
|
||||
| +- PrimitiveType[@ArrayDepth = "0", @ArrayType = "false", @Boolean = "false", @ClassOrInterfaceType = "false", @Image = "int", @ModelConstant = "int", @PrimitiveType = "true", @ReferenceType = "false", @TypeImage = "int"]
|
||||
| +- VariableDeclaratorId[@ArrayType = "false", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @FormalParameter = "false", @Image = "y", @LambdaParameter = "false", @LocalVariable = "false", @Name = "y", @PatternBinding = "false", @RecordComponent = "true", @ResourceDeclaration = "false", @TypeInferred = "false", @VariableName = "y", @Visibility = "private"]
|
||||
+- RecordBody[@Size = "1"]
|
||||
+- MethodDeclaration[@Abstract = "false", @Arity = "1", @Image = "main", @MethodName = "main", @Name = "main", @Varargs = "false", @Visibility = "public", @Void = "true"]
|
||||
+- ModifierList[@EffectiveModifiers = "{public, static}", @ExplicitModifiers = "{public, static}"]
|
||||
+- ResultType[@Void = "true", @returnsArray = "false"]
|
||||
+- FormalParameters[@Size = "1"]
|
||||
| +- FormalParameter[@Varargs = "false", @Visibility = "local"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| +- ArrayType[@ArrayDepth = "1", @ArrayType = "true", @ClassOrInterfaceType = "false", @PrimitiveType = "false", @ReferenceType = "true", @TypeImage = "String"]
|
||||
| | +- ClassOrInterfaceType[@ArrayDepth = "0", @ArrayType = "false", @ClassOrInterfaceType = "true", @FullyQualified = "false", @PrimitiveType = "false", @ReferenceToClassSameCompilationUnit = "false", @ReferenceType = "true", @SimpleName = "String", @TypeImage = "String"]
|
||||
| | +- ArrayDimensions[@Size = "1"]
|
||||
| | +- ArrayTypeDim[@Varargs = "false"]
|
||||
| +- VariableDeclaratorId[@ArrayType = "true", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @FormalParameter = "true", @Image = "args", @LambdaParameter = "false", @LocalVariable = "false", @Name = "args", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @VariableName = "args", @Visibility = "package"]
|
||||
+- Block[@Size = "2", @containsComment = "false"]
|
||||
+- LocalVariableDeclaration[@TypeInferred = "false", @Visibility = "local"]
|
||||
| +- ModifierList[@EffectiveModifiers = "{}", @ExplicitModifiers = "{}"]
|
||||
| +- ClassOrInterfaceType[@ArrayDepth = "0", @ArrayType = "false", @ClassOrInterfaceType = "true", @FullyQualified = "false", @PrimitiveType = "false", @ReferenceToClassSameCompilationUnit = "false", @ReferenceType = "true", @SimpleName = "Point", @TypeImage = "Point"]
|
||||
| +- VariableDeclarator[@Initializer = "true", @Name = "p"]
|
||||
| +- VariableDeclaratorId[@ArrayType = "false", @EnumConstant = "false", @ExceptionBlockParameter = "false", @Field = "false", @FormalParameter = "false", @Image = "p", @LambdaParameter = "false", @LocalVariable = "true", @Name = "p", @PatternBinding = "false", @RecordComponent = "false", @ResourceDeclaration = "false", @TypeInferred = "false", @VariableName = "p", @Visibility = "package"]
|
||||
| +- ConstructorCall[@AnonymousClass = "false", @CompileTimeConstant = "false", @Diamond = "false", @DiamondTypeArgs = "false", @Expression = "true", @ParenthesisDepth = "0", @Parenthesized = "false", @QualifiedInstanceCreation = "false"]
|
||||
| +- ClassOrInterfaceType[@ArrayDepth = "0", @ArrayType = "false", @ClassOrInterfaceType = "true", @FullyQualified = "false", @PrimitiveType = "false", @ReferenceToClassSameCompilationUnit = "false", @ReferenceType = "true", @SimpleName = "Point", @TypeImage = "Point"]
|
||||
| +- ArgumentList[@Size = "2"]
|
||||
| +- NumericLiteral[@Base = "10", @BooleanLiteral = "false", @CharLiteral = "false", @CompileTimeConstant = "true", @DoubleLiteral = "false", @Expression = "true", @FloatLiteral = "false", @Image = "1", @IntLiteral = "true", @Integral = "true", @LongLiteral = "false", @NullLiteral = "false", @NumericLiteral = "true", @ParenthesisDepth = "0", @Parenthesized = "false", @PrimitiveType = "int", @StringLiteral = "false", @ValueAsDouble = "1.0", @ValueAsFloat = "1.0", @ValueAsInt = "1", @ValueAsLong = "1"]
|
||||
| +- NumericLiteral[@Base = "10", @BooleanLiteral = "false", @CharLiteral = "false", @CompileTimeConstant = "true", @DoubleLiteral = "false", @Expression = "true", @FloatLiteral = "false", @Image = "2", @IntLiteral = "true", @Integral = "true", @LongLiteral = "false", @NullLiteral = "false", @NumericLiteral = "true", @ParenthesisDepth = "0", @Parenthesized = "false", @PrimitiveType = "int", @StringLiteral = "false", @ValueAsDouble = "2.0", @ValueAsFloat = "2.0", @ValueAsInt = "2", @ValueAsLong = "2"]
|
||||
+- ExpressionStatement[]
|
||||
+- MethodCall[@CompileTimeConstant = "false", @Expression = "true", @Image = "println", @MethodName = "println", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
+- FieldAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Expression = "true", @Image = "out", @Name = "out", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- TypeExpression[@CompileTimeConstant = "false", @Expression = "true", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
| +- ClassOrInterfaceType[@ArrayDepth = "0", @ArrayType = "false", @ClassOrInterfaceType = "true", @FullyQualified = "false", @PrimitiveType = "false", @ReferenceToClassSameCompilationUnit = "false", @ReferenceType = "true", @SimpleName = "System", @TypeImage = "System"]
|
||||
+- ArgumentList[@Size = "1"]
|
||||
+- InfixExpression[@CompileTimeConstant = "false", @Expression = "true", @Operator = "+", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
||||
+- StringLiteral[@BooleanLiteral = "false", @CharLiteral = "false", @CompileTimeConstant = "true", @ConstValue = "p = ", @DoubleLiteral = "false", @Expression = "true", @FloatLiteral = "false", @Image = ""p = "", @IntLiteral = "false", @LongLiteral = "false", @NullLiteral = "false", @NumericLiteral = "false", @ParenthesisDepth = "0", @Parenthesized = "false", @StringLiteral = "true", @TextBlock = "false"]
|
||||
+- VariableAccess[@AccessType = "READ", @CompileTimeConstant = "false", @Expression = "true", @Image = "p", @Name = "p", @ParenthesisDepth = "0", @Parenthesized = "false"]
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* 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 <a href="https://openjdk.java.net/jeps/384">JEP 384: Records (Second Preview)</a>
|
||||
*/
|
||||
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) {}
|
||||
|
||||
// note: Java 15 Preview allowed c-style arrays "public record ArrayRec(int x[]) {}"
|
||||
// but PMD doesn't
|
||||
public record ArrayRec(int[] x) {}
|
||||
|
||||
public record EmptyRec<Type>() {
|
||||
public void foo() { }
|
||||
public Type bar() { return null; }
|
||||
public static void baz() {
|
||||
EmptyRec<String> 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 {
|
||||
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user