forked from phoedos/pmd
Merge branch 'master' into experimental-apex-parser
This commit is contained in:
commit
3290815fff
@ -133,6 +133,7 @@ function build() {
|
||||
pmd_ci_log_group_end
|
||||
|
||||
pmd_ci_log_group_start "Executing build with sonar"
|
||||
pmd_ci_openjdk_setdefault 17
|
||||
# Note: Sonar also needs GITHUB_TOKEN (!)
|
||||
./mvnw \
|
||||
-Dmaven.javadoc.skip=true \
|
||||
@ -146,6 +147,7 @@ function build() {
|
||||
pmd_ci_log_group_end
|
||||
|
||||
pmd_ci_log_group_start "Executing build with coveralls"
|
||||
pmd_ci_openjdk_setdefault 11
|
||||
export CI_NAME="github actions"
|
||||
export CI_BUILD_URL="${PMD_CI_JOB_URL}"
|
||||
export CI_BRANCH="${PMD_CI_BRANCH}"
|
||||
|
@ -111,8 +111,8 @@ langs:
|
||||
examples:
|
||||
- code: '//*[pmd-java:nodeIs("Expression")]'
|
||||
outcome: "Matches all nodes that implement {% jdoc jast::ASTExpression %}"
|
||||
- code: '//*[pmd-java:nodeIs("AnyTypeDeclaration")]'
|
||||
outcome: "Matches all nodes that implement {% jdoc jast::ASTAnyTypeDeclaration %}"
|
||||
- code: '//*[pmd-java:nodeIs("TypeDeclaration")]'
|
||||
outcome: "Matches all nodes that implement {% jdoc jast::ASTTypeDeclaration %}"
|
||||
- code: '//*[pmd-java:nodeIs("Foo")]'
|
||||
outcome: "Runtime error, there's no class ASTFoo in the package"
|
||||
|
||||
@ -129,7 +129,7 @@ langs:
|
||||
examples:
|
||||
- code: '//FormalParameter[pmd-java:typeIs("java.lang.String[]")]'
|
||||
outcome: "Matches formal parameters of type `String[]` (including vararg parameters)"
|
||||
- code: '//VariableDeclaratorId[pmd-java:typeIs("java.lang.List")]'
|
||||
- code: '//VariableId[pmd-java:typeIs("java.lang.List")]'
|
||||
outcome: "Matches variable declarators of type `List` or any of its subtypes (including e.g. `ArrayList`)"
|
||||
|
||||
- name: typeIsExactly
|
||||
@ -142,7 +142,7 @@ langs:
|
||||
parameters:
|
||||
- *qname_param
|
||||
examples:
|
||||
- code: '//VariableDeclaratorId[pmd-java:typeIsExactly("java.lang.List")]'
|
||||
- code: '//VariableId[pmd-java:typeIsExactly("java.lang.List")]'
|
||||
outcome: "Matches variable declarators of type `List` (but not e.g. `ArrayList`)"
|
||||
|
||||
|
||||
@ -159,7 +159,7 @@ langs:
|
||||
type: "xs:string"
|
||||
description: "The name of a metric in {% jdoc jmx::JavaMetrics %} (or an alias thereof)."
|
||||
examples:
|
||||
- code: "//ClassOrInterfaceDeclaration[metric('NCSS') > 200]"
|
||||
- code: "//ClassDeclaration[metric('NCSS') > 200]"
|
||||
outcome: ""
|
||||
- code: "//MethodDeclaration[metric('CYCLO') > 10 and metric('NCSS') > 20]"
|
||||
outcome: ""
|
||||
@ -186,7 +186,7 @@ langs:
|
||||
Returns a sequence of the effective modifiers of a node as strings.
|
||||
This is documented on {% jdoc jast::ASTModifierList#getEffectiveModifiers() %}.
|
||||
|
||||
notes: "The context node must be an {% jdoc jast::AccessNode %}, otherwise this returns an empty sequence"
|
||||
notes: "The context node must be an {% jdoc jast::ModifierOwner %}, otherwise this returns an empty sequence"
|
||||
parameters:
|
||||
examples:
|
||||
- code: '//MethodDeclaration[pmd-java:modifiers() = "native"]'
|
||||
@ -210,7 +210,7 @@ langs:
|
||||
Returns a sequence of the explicit modifiers of a node as strings.
|
||||
This is documented on {% jdoc jast::ASTModifierList#getExplicitModifiers() %}.
|
||||
|
||||
notes: "The context node must be an {% jdoc jast::AccessNode %}, otherwise this returns an empty sequence"
|
||||
notes: "The context node must be an {% jdoc jast::ModifierOwner %}, otherwise this returns an empty sequence"
|
||||
parameters:
|
||||
examples:
|
||||
- code: '//MethodDeclaration[pmd-java:explicitModifiers() = "public"]'
|
||||
|
@ -68,25 +68,23 @@ $ cat Foo.xml
|
||||
<?xml version='1.0' encoding='UTF-8' ?>
|
||||
<CompilationUnit Image='' PackageName='' declarationsAreInDefaultPackage='true'>
|
||||
<TypeDeclaration Image=''>
|
||||
<ClassOrInterfaceDeclaration Abstract='false' BinaryName='Foo' Default='false' Final='false' Image='Foo' Interface='false' Local='false' Modifiers='1' Native='false' Nested='false' PackagePrivate='false' Private='false' Protected='false' Public='true' SimpleName='Foo' Static='false' Strictfp='false' Synchronized='false' Transient='false' TypeKind='CLASS' Volatile='false'>
|
||||
<ClassOrInterfaceBody AnonymousInnerClass='false' EnumChild='false' Image=''>
|
||||
<ClassOrInterfaceBodyDeclaration AnonymousInnerClass='false' EnumChild='false' Image='' Kind='FIELD'>
|
||||
<FieldDeclaration Abstract='false' AnnotationMember='false' Array='false' ArrayDepth='0' Default='false' Final='false' Image='' InterfaceMember='false' Modifiers='0' Native='false' PackagePrivate='true' Private='false' Protected='false' Public='false' Static='false' Strictfp='false' Synchronized='false' SyntacticallyFinal='false' SyntacticallyPublic='false' SyntacticallyStatic='false' Transient='false' VariableName='a' Volatile='false'>
|
||||
<Type Array='false' ArrayDepth='0' ArrayType='false' Image='' TypeImage='int'>
|
||||
<PrimitiveType Array='false' ArrayDepth='0' Boolean='false' Image='int' />
|
||||
</Type>
|
||||
<VariableDeclarator Image='' Initializer='false' Name='a'>
|
||||
<VariableDeclaratorId Array='false' ArrayDepth='0' ArrayType='false' ExceptionBlockParameter='false' ExplicitReceiverParameter='false' Field='true' Final='false' FormalParameter='false' Image='a' LambdaParameter='false' LocalVariable='false' ResourceDeclaration='false' TypeInferred='false' VariableName='a' />
|
||||
</VariableDeclarator>
|
||||
</FieldDeclaration>
|
||||
</ClassOrInterfaceBodyDeclaration>
|
||||
</ClassOrInterfaceBody>
|
||||
</ClassOrInterfaceDeclaration>
|
||||
<ClassDeclaration Abstract='false' BinaryName='Foo' Default='false' Final='false' Image='Foo' Interface='false' Local='false' Modifiers='1' Native='false' Nested='false' PackagePrivate='false' Private='false' Protected='false' Public='true' SimpleName='Foo' Static='false' Strictfp='false' Synchronized='false' Transient='false' TypeKind='CLASS' Volatile='false'>
|
||||
<ClassBody AnonymousInnerClass='false' EnumChild='false' Image=''>
|
||||
<FieldDeclaration Abstract='false' AnnotationMember='false' Array='false' ArrayDepth='0' Default='false' Final='false' Image='' InterfaceMember='false' Modifiers='0' Native='false' PackagePrivate='true' Private='false' Protected='false' Public='false' Static='false' Strictfp='false' Synchronized='false' SyntacticallyFinal='false' SyntacticallyPublic='false' SyntacticallyStatic='false' Transient='false' VariableName='a' Volatile='false'>
|
||||
<Type Array='false' ArrayDepth='0' ArrayType='false' Image='' TypeImage='int'>
|
||||
<PrimitiveType Array='false' ArrayDepth='0' Boolean='false' Image='int' />
|
||||
</Type>
|
||||
<VariableDeclarator Image='' Initializer='false' Name='a'>
|
||||
<VariableId Array='false' ArrayDepth='0' ArrayType='false' ExceptionBlockParameter='false' ExplicitReceiverParameter='false' Field='true' Final='false' FormalParameter='false' Image='a' LambdaParameter='false' LocalVariable='false' ResourceDeclaration='false' TypeInferred='false' VariableName='a' />
|
||||
</VariableDeclarator>
|
||||
</FieldDeclaration>
|
||||
</ClassBody>
|
||||
</ClassDeclaration>
|
||||
</TypeDeclaration>
|
||||
</CompilationUnit>
|
||||
|
||||
$ xmlstarlet select -t -c "//VariableDeclaratorId[@VariableName='a']" Foo.xml
|
||||
<VariableDeclaratorId Array="false" ArrayDepth="0" ArrayType="false" ExceptionBlockParameter="false" ExplicitReceiverParameter="false" Field="true" Final="false" FormalParameter="false" Image="a" LambdaParameter="false" LocalVariable="false" ResourceDeclaration="false" TypeInferred="false" VariableName="a"/>
|
||||
$ xmlstarlet select -t -c "//VariableId[@VariableName='a']" Foo.xml
|
||||
<VariableId Array="false" ArrayDepth="0" ArrayType="false" ExceptionBlockParameter="false" ExplicitReceiverParameter="false" Field="true" Final="false" FormalParameter="false" Image="a" LambdaParameter="false" LocalVariable="false" ResourceDeclaration="false" TypeInferred="false" VariableName="a"/>
|
||||
```
|
||||
|
||||
This example uses [xmlstarlet](http://xmlstar.sourceforge.net/) to query the xml document for any variables/fields
|
||||
|
@ -76,7 +76,7 @@ Here's a short overview:
|
||||
| `{% raw %}{% jdoc !a!core::Rule#setName(java.lang.String) %}{% endraw %}` | {% jdoc !a!core::Rule#setName(java.lang.String) %} |
|
||||
| `{% raw %}{% jdoc !ac!core::Rule#setName(java.lang.String) %}{% endraw %}` | {% jdoc !ac!core::Rule#setName(java.lang.String) %} |
|
||||
| `{% raw %}{% jdoc core::properties.PropertyDescriptor %}{% endraw %}` | {% jdoc core::properties.PropertyDescriptor %} |
|
||||
| `{% raw %}{% jdoc_nspace :jast java::lang.java.ast %}{% jdoc jast::ASTAnyTypeDeclaration %}{% endraw %}` | {% jdoc_nspace :jast java::lang.java.ast %}{% jdoc jast::ASTAnyTypeDeclaration %} |
|
||||
| `{% raw %}{% jdoc_nspace :jast java::lang.java.ast %}{% jdoc jast::ASTTypeDeclaration %}{% endraw %}` | {% jdoc_nspace :jast java::lang.java.ast %}{% jdoc jast::ASTTypeDeclaration %} |
|
||||
| `{% raw %}{% jdoc_nspace :jast java::lang.java.ast %}{% jdoc_package :jast %}{% endraw %}` | {% jdoc_nspace :jast java::lang.java.ast %}{% jdoc_package :jast %} |
|
||||
| `{% raw %}{% jdoc_nspace :PrD core::properties.PropertyDescriptor %}{% jdoc !ac!:PrD#uiOrder() %}{% endraw %}` | {% jdoc_nspace :PrD core::properties.PropertyDescriptor %}{% jdoc !ac!:PrD#uiOrder() %} |
|
||||
| `{% raw %}{% jdoc_old core::Rule %}{% endraw %}` | {% jdoc_old core::Rule %}
|
||||
|
@ -120,11 +120,6 @@ The tool comes with a rather extensive help text, simply running with `--help`!
|
||||
Language detection is only influenced by file extensions and the `--force-language` option.</p>
|
||||
<p>See also [Supported Languages](#supported-languages).</p>"
|
||||
%}
|
||||
{% include custom/cli_option_row.html options="-language,-l"
|
||||
option_arg="lang"
|
||||
description="Specify the language PMD should use. Used together with `-version`. See also [Supported Languages](#supported-languages).
|
||||
<p><span class=\"label label-default\">Deprecated</span> since PMD 6.52.0. Use `--use-version` instead.</p>"
|
||||
%}
|
||||
{% include custom/cli_option_row.html options="--minimum-priority"
|
||||
option_arg="priority"
|
||||
description="Rule priority threshold; rules with lower priority than configured here won't be used.
|
||||
@ -303,6 +298,6 @@ Alternatively, you can create a filelist to only analyze files with a given exte
|
||||
id="file-list"
|
||||
linux="find src/ -name \"*.ext\" > filelist.txt
|
||||
pmd check --file-list filelist.txt -f text -R ruleset.xml --force-language xml"
|
||||
windows="for /r src/ %i in (*.ext) do echo %i >> filelist.txt
|
||||
windows="for /r src\ %i in (*.ext) do echo %i >> filelist.txt
|
||||
pmd.bat check --file-list filelist.txt -f text -R ruleset.xml --force-language xml" %}
|
||||
|
||||
|
@ -171,7 +171,7 @@ with a backslash when needed.
|
||||
description="A StringMultiProperty." />
|
||||
<property name="xpath">
|
||||
<value><![CDATA[
|
||||
//VariableDeclaratorId[@Name = $reportedIdentifiers]
|
||||
//VariableId[@Image = $reportedIdentifiers]
|
||||
]]></value>
|
||||
</property>
|
||||
</properties>
|
||||
|
@ -61,8 +61,8 @@ public class MyRule extends AbstractJavaRule {
|
||||
|
||||
Generally, a rule wants to check for only some node types. In our XPath example
|
||||
in [Your First Rule](pmd_userdocs_extending_your_first_rule.html),
|
||||
we wanted to check for some `VariableDeclaratorId` nodes. That's the XPath name,
|
||||
but in Java, you'll get access to the {% jdoc jast::ASTVariableDeclaratorId %}
|
||||
we wanted to check for some `VariableId` nodes. That's the XPath name,
|
||||
but in Java, you'll get access to the {% jdoc jast::ASTVariableId %}
|
||||
full API.
|
||||
|
||||
If you want to check for some specific node types, you can override the
|
||||
@ -72,8 +72,8 @@ corresponding `visit` method:
|
||||
public class MyRule extends AbstractJavaRule {
|
||||
|
||||
@Override
|
||||
public Object visit(ASTVariableDeclaratorId node, Object data) {
|
||||
// This method is called on each node of type ASTVariableDeclaratorId
|
||||
public Object visit(ASTVariableId node, Object data) {
|
||||
// This method is called on each node of type ASTVariableId
|
||||
// in the AST
|
||||
|
||||
if (node.getType() == short.class) {
|
||||
|
@ -45,11 +45,12 @@ class Foo extends Object {
|
||||
|
||||
```java
|
||||
└─ CompilationUnit
|
||||
└─ ClassOrInterfaceDeclaration "Foo"
|
||||
├─ ModifierList
|
||||
├─ ExtendsList
|
||||
│ └─ ClassOrInterfaceType "Object"
|
||||
└─ ClassOrInterfaceBody
|
||||
└─ TypeDeclaration
|
||||
└─ ClassDeclaration "Foo"
|
||||
├─ ModifierList
|
||||
├─ ExtendsList
|
||||
│ └─ ClassType "Object"
|
||||
└─ ClassBody
|
||||
```
|
||||
|
||||
</td>
|
||||
|
@ -40,7 +40,7 @@ defined on. Concretely, this means:
|
||||
* Some Java getters are exposed as XML attributes on those elements
|
||||
* This means, that documentation for attributes can be found in our Javadocs. For
|
||||
example, the attribute `@SimpleName` of the Java node `EnumDeclaration` is backed
|
||||
by the Java getter {% jdoc java::lang.java.ast.AbstractAnyTypeDeclaration#getSimpleName() %}.
|
||||
by the Java getter {% jdoc java::lang.java.ast.ASTTypeDeclaration#getSimpleName() %}.
|
||||
|
||||
### Value conversion
|
||||
|
||||
|
@ -83,11 +83,11 @@ public class KeepingItSerious {
|
||||
|
||||
```
|
||||
|
||||
Examining the AST, you find out that the LocalVariableDeclaration has a VariableDeclaratorId
|
||||
Examining the AST, you find out that the LocalVariableDeclaration has a VariableId
|
||||
descendant, whose `Name` XPath attribute is exactly `bill`. You thus write your first attempt
|
||||
in the XPath editor:
|
||||
```xpath
|
||||
//VariableDeclaratorId[@Name = "bill"]
|
||||
//VariableId[@Name = "bill"]
|
||||
```
|
||||
|
||||
You can see the XPath result list is updated with the variable declarator.
|
||||
@ -112,7 +112,7 @@ based on your examination of the Type node of the field and local variable
|
||||
declaration nodes.
|
||||
|
||||
```xpath
|
||||
//VariableDeclaratorId[@Image = "bill"][../../PrimitiveType[@Kind = "short"]]
|
||||
//VariableId[@Name = "bill" and ../../Type[@TypeImage = "short"]]
|
||||
```
|
||||
|
||||
### Exporting to XML
|
||||
@ -135,8 +135,8 @@ copy-paste into your ruleset XML. The resulting element looks like so:
|
||||
<properties>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//VariableDeclaratorId[@Image = "bill"][../../PrimitiveType[@Kind = "short"]]
|
||||
<![CDATA[
|
||||
//VariableId[@Name = "bill"][../../Type[@TypeImage="short"]]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
|
@ -99,11 +99,11 @@ Additionally, the following options, are specified most of the time even though
|
||||
.../src/main/java/com/me/RuleSetWriter.java:66 Avoid empty catch blocks"
|
||||
windows="pmd.bat check -f text -R rulesets/java/quickstart.xml ..\..\src\main\java
|
||||
|
||||
.../src/main/java/com/me/RuleSet.java:123 These nested if statements could be combined
|
||||
.../src/main/java/com/me/RuleSet.java:231 Useless parentheses.
|
||||
.../src/main/java/com/me/RuleSet.java:232 Useless parentheses.
|
||||
.../src/main/java/com/me/RuleSet.java:357 These nested if statements could be combined
|
||||
.../src/main/java/com/me/RuleSetWriter.java:66 Avoid empty catch blocks" %}
|
||||
...\src\main\java\com\me\RuleSet.java:123 These nested if statements could be combined
|
||||
...\src\main\java\com\me\RuleSet.java:231 Useless parentheses.
|
||||
...\src\main\java\com\me\RuleSet.java:232 Useless parentheses.
|
||||
...\src\main\java\com\me\RuleSet.java:357 These nested if statements could be combined
|
||||
...\src\main\java\com\me\RuleSetWriter.java:66 Avoid empty catch blocks" %}
|
||||
|
||||
## Running CPD via command line
|
||||
|
||||
@ -140,7 +140,7 @@ sources. Alternatively You can use the `-d` or `--dir` flag, which is equivalent
|
||||
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
|
||||
assertEquals(Boolean.TYPE, expressions.get(index++).getType());
|
||||
assertEquals(Boolean.TYPE, expressions.get(index++).getType());"
|
||||
windows="pmd.bat cpd --minimum-tokens 100 /home/me/src
|
||||
windows="pmd.bat cpd --minimum-tokens 100 c:\temp\src
|
||||
|
||||
Found a 7 line (110 tokens) duplication in the following files:
|
||||
Starting at line 579 of c:\temp\src\test\java\foo\FooTypeTest.java
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -210,17 +210,17 @@ more violations than expected.
|
||||
|
||||
Another example, to suppress violations occurring in classes whose name contains `Bean`:
|
||||
```xml
|
||||
<property name="violationSuppressXPath" value="./ancestor::ClassOrInterfaceDeclaration[contains(@Image, 'Bean')]"/>
|
||||
<property name="violationSuppressXPath" value="./ancestor::ClassDeclaration[contains(@Image, 'Bean')]"/>
|
||||
```
|
||||
|
||||
You can also use regex for string comparison. The next example suppresses violations in classes ending with `Bean`:
|
||||
```xml
|
||||
<property name="violationSuppressXPath" value="./ancestor::ClassOrInterfaceDeclaration[matches(@Image, '^.*Bean$')]"/>
|
||||
<property name="violationSuppressXPath" value="./ancestor::ClassDeclaration[matches(@Image, '^.*Bean$')]"/>
|
||||
```
|
||||
|
||||
|
||||
Note here the usage of the `./ancestor::` axis instead of `//`. The latter would match
|
||||
any ClassOrInterfaceDeclaration in the file, while the former matches only class
|
||||
any ClassDeclaration in the file, while the former matches only class
|
||||
declaration nodes that *enclose the violation node*, which is usually what you'd want.
|
||||
|
||||
Note for XPath based suppression to work, you must know how to write
|
||||
|
@ -37,4 +37,4 @@ The programmatic API for PMD is centered around {% jdoc core::PmdAnalysis %}, pl
|
||||
|
||||
## Running CPD programmatically
|
||||
|
||||
The programmatic API for CPD is centered around {% jdoc core::CpdAnalysis %}, please see the javadocs for usage information.
|
||||
The programmatic API for CPD is centered around {% jdoc core::cpd.CpdAnalysis %}, please see the javadocs for usage information.
|
||||
|
@ -130,6 +130,8 @@ in the Migration Guide.
|
||||
* groovy
|
||||
* [#4726](https://github.com/pmd/pmd/pull/4726): \[groovy] Support Groovy to 3 and 4 and CPD suppressions
|
||||
* java
|
||||
* [#1307](https://github.com/pmd/pmd/issues/1307): \[java] AccessNode API changes
|
||||
* [#3751](https://github.com/pmd/pmd/issues/3751): \[java] Rename some node types
|
||||
* [#4628](https://github.com/pmd/pmd/pull/4628): \[java] Support loading classes from java runtime images
|
||||
* [#4753](https://github.com/pmd/pmd/issues/4753): \[java] PMD crashes while using generics and wildcards
|
||||
* java-codestyle
|
||||
@ -140,6 +142,7 @@ in the Migration Guide.
|
||||
* java-design
|
||||
* [#174](https://github.com/pmd/pmd/issues/174): \[java] SingularField false positive with switch in method that both assigns and reads field
|
||||
* java-errorprone
|
||||
* [#718](https://github.com/pmd/pmd/issues/718): \[java] BrokenNullCheck false positive with parameter/field confusion
|
||||
* [#1831](https://github.com/pmd/pmd/issues/1831): \[java] DetachedTestCase reports abstract methods
|
||||
* [#4719](https://github.com/pmd/pmd/pull/4719): \[java] UnnecessaryCaseChange: example doc toUpperCase() should compare to a capitalized string
|
||||
* javascript
|
||||
@ -151,7 +154,7 @@ in the Migration Guide.
|
||||
|
||||
#### API Changes
|
||||
|
||||
**Removed classes and methods**
|
||||
**Removed classes and methods (previously deprecated)**
|
||||
|
||||
The following previously deprecated classes have been removed:
|
||||
|
||||
@ -165,6 +168,38 @@ The following previously deprecated classes have been removed:
|
||||
If the current version is needed, then `Node.getTextDocument().getLanguageVersion()` can be used. This
|
||||
is the version that has been selected via CLI `--use-version` parameter.
|
||||
|
||||
**Removed classes, interfaces and methods (not previously deprecated)**
|
||||
|
||||
* pmd-java
|
||||
* The interface `FinalizableNode` (introduced in 7.0.0-rc1) has been removed.
|
||||
Its method `isFinal()` has been moved down to the
|
||||
nodes where needed, e.g. {% jdoc !!java::lang.java.ast.ASTLocalVariableDeclaration#isFinal() %}.
|
||||
* The method `isPackagePrivate()` in {% jdoc java::lang.java.ast.ASTClassDeclaration %} (formerly ASTClassOrInterfaceDeclaration)
|
||||
has been removed.
|
||||
Use {% jdoc java::lang.java.ast.ModifierOwner#hasVisibility(java::lang.java.ast.ModifierOwner.Visibility) %} instead,
|
||||
which can correctly differentiate between local and package private classes.
|
||||
|
||||
**Renamed classes, interfaces**
|
||||
|
||||
* pmd-java
|
||||
* The interface `AccessNode` has been renamed to {% jdoc java::lang.ast.ModifierOwner %}. This is only relevant
|
||||
for Java rules, which use that type directly e.g. through downcasting.
|
||||
Or when using the XPath function `pmd-java:nodeIs()`.
|
||||
* The node `ASTClassOrInterfaceType` has been renamed to {% jdoc java::lang.ast.ASTClassType %}. XPath rules
|
||||
need to be adjusted.
|
||||
* The node `ASTClassOrInterfaceDeclaration` has been renamed to {% jdoc java::lang.ast.ASTClassDeclaration %}.
|
||||
XPath rules need to be adjusted.
|
||||
* The interface `ASTAnyTypeDeclaration` has been renamed to {% jdoc java::lang.ast.ASTTypeDeclaration %}.
|
||||
This is only relevant for Java rules, which use that type directly, e.g. through downcasting.
|
||||
Or when using the XPath function `pmd-java:nodeIs()`.
|
||||
* The interface `ASTMethodOrConstructorDeclaration` has been renamed to
|
||||
{% jdoc java::lang.ast.ASTExecutableDeclaration %}. This is only relevant for Java rules, which sue that type
|
||||
directly, e.g. through downcasting. Or when using the XPath function `pmd-java:nodeIs()`.
|
||||
* The node `ASTVariableDeclaratorId` has been renamed to {% jdoc java::lang.ast.ASTVariableId %}. XPath rules
|
||||
need to be adjusted.
|
||||
* The node `ASTClassOrInterfaceBody` has been renamed to {% jdoc java::lang.ast.ASTClassBody %}. XPath rules
|
||||
need to be adjusted.
|
||||
|
||||
#### External Contributions
|
||||
* [#4640](https://github.com/pmd/pmd/pull/4640): \[cli] Launch script fails if run via "bash pmd" - [Shai Bennathan](https://github.com/shai-bennathan) (@shai-bennathan)
|
||||
* [#4673](https://github.com/pmd/pmd/pull/4673): \[javascript] CPD: Added support for decorator notation - [Wener](https://github.com/wener-tiobe) (@wener-tiobe)
|
||||
@ -645,6 +680,7 @@ Language specific fixes:
|
||||
* [#1128](https://github.com/pmd/pmd/issues/1128): \[java] Improve ASTLocalVariableDeclaration
|
||||
* [#1150](https://github.com/pmd/pmd/issues/1150): \[java] ClassOrInterfaceType AST improvements
|
||||
* [#1207](https://github.com/pmd/pmd/issues/1207): \[java] Resolve explicit types using FQCNs, without hitting the classloader
|
||||
* [#1307](https://github.com/pmd/pmd/issues/1307): \[java] AccessNode API changes
|
||||
* [#1367](https://github.com/pmd/pmd/issues/1367): \[java] Parsing error on annotated inner class
|
||||
* [#1661](https://github.com/pmd/pmd/issues/1661): \[java] About operator nodes
|
||||
* [#2366](https://github.com/pmd/pmd/pull/2366): \[java] Remove qualified names
|
||||
@ -653,6 +689,7 @@ Language specific fixes:
|
||||
* [#3763](https://github.com/pmd/pmd/issues/3763): \[java] Ambiguous reference error in valid code
|
||||
* [#3749](https://github.com/pmd/pmd/issues/3749): \[java] Improve `isOverridden` in ASTMethodDeclaration
|
||||
* [#3750](https://github.com/pmd/pmd/issues/3750): \[java] Make symbol table support instanceof pattern bindings
|
||||
* [#3751](https://github.com/pmd/pmd/issues/3751): \[java] Rename some node types
|
||||
* [#3752](https://github.com/pmd/pmd/issues/3752): \[java] Expose annotations in symbol API
|
||||
* [#4237](https://github.com/pmd/pmd/pull/4237): \[java] Cleanup handling of Java comments
|
||||
* [#4317](https://github.com/pmd/pmd/issues/4317): \[java] Some AST nodes should not be TypeNodes
|
||||
@ -763,6 +800,7 @@ Language specific fixes:
|
||||
* [#4416](https://github.com/pmd/pmd/pull/4416): \[java] Fix reported line number in CommentContentRule
|
||||
* java-errorprone
|
||||
* [#659](https://github.com/pmd/pmd/issues/659): \[java] MissingBreakInSwitch - last default case does not contain a break
|
||||
* [#718](https://github.com/pmd/pmd/issues/718): \[java] BrokenNullCheck false positive with parameter/field confusion
|
||||
* [#1005](https://github.com/pmd/pmd/issues/1005): \[java] CloneMethodMustImplementCloneable triggers for interfaces
|
||||
* [#1669](https://github.com/pmd/pmd/issues/1669): \[java] NullAssignment - FP with ternay and null as constructor argument
|
||||
* [#1831](https://github.com/pmd/pmd/issues/1831): \[java] DetachedTestCase reports abstract methods
|
||||
|
@ -22,7 +22,7 @@ public class SourceLanguage {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
/** This actually corresponds to a {@link Language#getTerseName()}. */
|
||||
/** This actually corresponds to {@link Language#getId()}. */
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ final class ApexViolationSuppressors {
|
||||
private static boolean suppresses(ASTAnnotation annot, Rule rule) {
|
||||
final String ruleAnno = "PMD." + rule.getName();
|
||||
|
||||
if ("SuppressWarnings".equals(annot.getName())) {
|
||||
if ("SuppressWarnings".equalsIgnoreCase(annot.getName())) {
|
||||
for (ASTAnnotationParameter param : annot.children(ASTAnnotationParameter.class)) {
|
||||
String image = param.getValue();
|
||||
|
||||
|
@ -59,7 +59,7 @@ public final class ASTField extends AbstractApexNode.Many<Node> {
|
||||
}
|
||||
|
||||
public ASTModifierNode getModifiers() {
|
||||
return getFirstChildOfType(ASTModifierNode.class);
|
||||
return firstChild(ASTModifierNode.class);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
@ -24,7 +24,7 @@ public final class ASTFieldDeclarationStatements extends AbstractApexNode.Single
|
||||
|
||||
|
||||
public ASTModifierNode getModifiers() {
|
||||
return getFirstChildOfType(ASTModifierNode.class);
|
||||
return firstChild(ASTModifierNode.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -151,7 +151,7 @@ public final class ASTMethod extends AbstractApexNode implements ApexQualifiable
|
||||
}
|
||||
|
||||
public ASTModifierNode getModifiers() {
|
||||
return getFirstChildOfType(ASTModifierNode.class);
|
||||
return firstChild(ASTModifierNode.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,7 +24,7 @@ public final class ASTParameter extends AbstractApexNode.Single<ParameterDeclara
|
||||
}
|
||||
|
||||
public ASTModifierNode getModifiers() {
|
||||
return getFirstChildOfType(ASTModifierNode.class);
|
||||
return firstChild(ASTModifierNode.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,7 +34,7 @@ public final class ASTProperty extends AbstractApexNode.Single<PropertyDeclarati
|
||||
}
|
||||
|
||||
public ASTModifierNode getModifiers() {
|
||||
return getFirstChildOfType(ASTModifierNode.class);
|
||||
return firstChild(ASTModifierNode.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,7 @@ public final class ASTTryCatchFinallyBlockStatement extends AbstractApexNode.Sin
|
||||
}
|
||||
|
||||
public List<ASTCatchBlockStatement> getCatchClauses() {
|
||||
return findChildrenOfType(ASTCatchBlockStatement.class);
|
||||
return children(ASTCatchBlockStatement.class).toList();
|
||||
}
|
||||
|
||||
public ASTBlockStatement getFinallyBlock() {
|
||||
|
@ -22,7 +22,7 @@ public final class ASTUserEnum extends BaseApexClass<EnumDeclaration> {
|
||||
public ApexQualifiedName getQualifiedName() {
|
||||
if (qname == null) {
|
||||
|
||||
ASTUserClass parent = this.getFirstParentOfType(ASTUserClass.class);
|
||||
ASTUserClass parent = ancestors(ASTUserClass.class).first();
|
||||
|
||||
if (parent != null) {
|
||||
qname = ApexQualifiedName.ofNestedEnum(parent.getQualifiedName(), this);
|
||||
|
@ -19,6 +19,6 @@ public final class ASTVariableDeclarationStatements extends AbstractApexNode.Sin
|
||||
}
|
||||
|
||||
public ASTModifierNode getModifiers() {
|
||||
return getFirstChildOfType(ASTModifierNode.class);
|
||||
return firstChild(ASTModifierNode.class);
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ public final class ApexQualifiedName {
|
||||
|
||||
static ApexQualifiedName ofOuterClass(ASTUserClassOrInterface<?> astUserClass) {
|
||||
String ns = astUserClass.getNamespace();
|
||||
String[] classes = {astUserClass.getImage()};
|
||||
String[] classes = {astUserClass.getSimpleName()};
|
||||
return new ApexQualifiedName(StringUtils.isEmpty(ns) ? "c" : ns, classes, null);
|
||||
}
|
||||
|
||||
@ -153,21 +153,21 @@ public final class ApexQualifiedName {
|
||||
static ApexQualifiedName ofNestedClass(ApexQualifiedName parent, ASTUserClassOrInterface<?> astUserClass) {
|
||||
|
||||
String[] classes = Arrays.copyOf(parent.classes, parent.classes.length + 1);
|
||||
classes[classes.length - 1] = astUserClass.getImage();
|
||||
classes[classes.length - 1] = astUserClass.getSimpleName();
|
||||
return new ApexQualifiedName(parent.nameSpace, classes, null);
|
||||
}
|
||||
|
||||
|
||||
static ApexQualifiedName ofOuterEnum(ASTUserEnum astUserEnum) {
|
||||
String ns = astUserEnum.getNamespace();
|
||||
String[] classes = {astUserEnum.getImage()};
|
||||
String[] classes = {astUserEnum.getSimpleName()};
|
||||
return new ApexQualifiedName(StringUtils.isEmpty(ns) ? "c" : ns, classes, null);
|
||||
}
|
||||
|
||||
|
||||
static ApexQualifiedName ofNestedEnum(ApexQualifiedName parent, ASTUserEnum astUserEnum) {
|
||||
String[] classes = Arrays.copyOf(parent.classes, parent.classes.length + 1);
|
||||
classes[classes.length - 1] = astUserEnum.getImage();
|
||||
classes[classes.length - 1] = astUserEnum.getSimpleName();
|
||||
return new ApexQualifiedName(parent.nameSpace, classes, null);
|
||||
}
|
||||
|
||||
@ -213,7 +213,7 @@ public final class ApexQualifiedName {
|
||||
String ns = trigger.getNamespace();
|
||||
String targetObj = trigger.getTargetName();
|
||||
|
||||
return new ApexQualifiedName(StringUtils.isEmpty(ns) ? "c" : ns, new String[]{"trigger", targetObj}, trigger.getImage()); // uses a reserved word as a class name to prevent clashes
|
||||
return new ApexQualifiedName(StringUtils.isEmpty(ns) ? "c" : ns, new String[]{"trigger", targetObj}, trigger.getSimpleName()); // uses a reserved word as a class name to prevent clashes
|
||||
|
||||
} else {
|
||||
ApexQualifiedName baseName = parent.getQualifiedName();
|
||||
|
@ -40,7 +40,7 @@ abstract class BaseApexClass<T extends TypeDeclaration> extends AbstractApexNode
|
||||
public ApexQualifiedName getQualifiedName() {
|
||||
if (qname == null) {
|
||||
|
||||
ASTUserClass parent = this.getFirstParentOfType(ASTUserClass.class);
|
||||
ASTUserClass parent = ancestors(ASTUserClass.class).first();
|
||||
|
||||
if (parent != null) {
|
||||
qname = ApexQualifiedName.ofNestedClass(parent.getQualifiedName(), this);
|
||||
|
@ -22,7 +22,7 @@ public class ApexDesignerBindings extends DefaultDesignerBindings {
|
||||
@Override
|
||||
public Attribute getMainAttribute(Node node) {
|
||||
if (node instanceof ApexNode) {
|
||||
Attribute attr = (Attribute) ((ApexNode<?>) node).jjtAccept(MainAttrVisitor.INSTANCE, null);
|
||||
Attribute attr = (Attribute) node.acceptVisitor(MainAttrVisitor.INSTANCE, null);
|
||||
if (attr != null) {
|
||||
return attr;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public final class ApexMetricsHelper {
|
||||
* @return The complexity of the expression
|
||||
*/
|
||||
static int booleanExpressionComplexity(ASTStandardCondition expression) {
|
||||
Set<ASTBooleanExpression> subs = new HashSet<>(expression.findDescendantsOfType(ASTBooleanExpression.class));
|
||||
Set<ASTBooleanExpression> subs = new HashSet<>(expression.descendants(ASTBooleanExpression.class).toList());
|
||||
int complexity = 0;
|
||||
|
||||
for (ASTBooleanExpression sub : subs) {
|
||||
|
@ -24,7 +24,7 @@ public class StandardCycloVisitor extends ApexVisitorBase<MutableInt, Void> {
|
||||
|
||||
@Override
|
||||
public Void visit(ASTIfBlockStatement node, MutableInt data) {
|
||||
data.add(1 + ApexMetricsHelper.booleanExpressionComplexity(node.getFirstDescendantOfType(ASTStandardCondition.class)));
|
||||
data.add(1 + ApexMetricsHelper.booleanExpressionComplexity(node.descendants(ASTStandardCondition.class).first()));
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ public class StandardCycloVisitor extends ApexVisitorBase<MutableInt, Void> {
|
||||
@Override
|
||||
public Void visit(ASTForLoopStatement node, MutableInt data) {
|
||||
data.add(
|
||||
1 + ApexMetricsHelper.booleanExpressionComplexity(node.getFirstDescendantOfType(ASTStandardCondition.class)));
|
||||
1 + ApexMetricsHelper.booleanExpressionComplexity(node.descendants(ASTStandardCondition.class).first()));
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ public class StandardCycloVisitor extends ApexVisitorBase<MutableInt, Void> {
|
||||
@Override
|
||||
public Void visit(ASTWhileLoopStatement node, MutableInt data) {
|
||||
data.add(
|
||||
1 + ApexMetricsHelper.booleanExpressionComplexity(node.getFirstDescendantOfType(ASTStandardCondition.class)));
|
||||
1 + ApexMetricsHelper.booleanExpressionComplexity(node.descendants(ASTStandardCondition.class).first()));
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ public class StandardCycloVisitor extends ApexVisitorBase<MutableInt, Void> {
|
||||
@Override
|
||||
public Void visit(ASTDoLoopStatement node, MutableInt data) {
|
||||
data.add(
|
||||
1 + ApexMetricsHelper.booleanExpressionComplexity(node.getFirstDescendantOfType(ASTStandardCondition.class)));
|
||||
1 + ApexMetricsHelper.booleanExpressionComplexity(node.descendants(ASTStandardCondition.class).first()));
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ public class StandardCycloVisitor extends ApexVisitorBase<MutableInt, Void> {
|
||||
@Override
|
||||
public Void visit(ASTTernaryExpression node, MutableInt data) {
|
||||
data.add(
|
||||
1 + ApexMetricsHelper.booleanExpressionComplexity(node.getFirstDescendantOfType(ASTStandardCondition.class)));
|
||||
1 + ApexMetricsHelper.booleanExpressionComplexity(node.descendants(ASTStandardCondition.class).first()));
|
||||
return super.visit(node, data);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user