Merge branch 'master' into pr-2597

This commit is contained in:
Andreas Dangel
2020-07-16 18:25:21 +02:00
334 changed files with 24194 additions and 2212 deletions

View File

@ -49,7 +49,7 @@ jobs:
env: BUILD=publish
before_install:
- bash .travis/before_install.sh "11.0.7+10"
- bash .travis/before_install.sh "11.0.8+10"
- source ${HOME}/java.env
install: true
before_script: true

View File

@ -1,9 +1,9 @@
repository: pmd/pmd
pmd:
version: 6.25.0-SNAPSHOT
previous_version: 6.24.0
date: ??-June-2020
version: 6.26.0-SNAPSHOT
previous_version: 6.25.0
date: ??-??-2020
release_type: minor
# release types: major, minor, bugfix

View File

@ -125,6 +125,57 @@ the breaking API changes will be performed in 7.0.0.
an API is tagged as `@Deprecated` or not in the latest minor release. During the development of 7.0.0,
we may decide to remove some APIs that were not tagged as deprecated, though we'll try to avoid it." %}
#### 6.25.0
* The maven module `net.sourceforge.pmd:pmd-scala` is deprecated. Use `net.sourceforge.pmd:pmd-scala_2.13`
or `net.sourceforge.pmd:pmd-scala_2.12` instead.
* Rule implementation classes are internal API and should not be used by clients directly.
The rules should only be referenced via their entry in the corresponding category ruleset
(e.g. `<rule ref="category/java/bestpractices.xml/AbstractClassWithoutAbstractMethod" />`).
While we definitely won't move or rename the rule classes in PMD 6.x, we might consider changes
in PMD 7.0.0 and onwards.
##### Deprecated APIs
###### Internal API
Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0.
You can identify them with the `@InternalApi` annotation. You'll also get a deprecation warning.
* {% jdoc java::lang.java.rule.AbstractIgnoredAnnotationRule %} (Java)
* {% jdoc java::lang.java.rule.AbstractInefficientZeroCheck %} (Java)
* {% jdoc java::lang.java.rule.AbstractJUnitRule %} (Java)
* {% jdoc java::lang.java.rule.AbstractJavaMetricsRule %} (Java)
* {% jdoc java::lang.java.rule.AbstractLombokAwareRule %} (Java)
* {% jdoc java::lang.java.rule.AbstractPoorMethodCall %} (Java)
* {% jdoc java::lang.java.rule.bestpractices.AbstractSunSecureRule %} (Java)
* {% jdoc java::lang.java.rule.design.AbstractNcssCountRule %} (Java)
* {% jdoc java::lang.java.rule.documentation.AbstractCommentRule %} (Java)
* {% jdoc java::lang.java.rule.performance.AbstractOptimizationRule %} (Java)
* {% jdoc java::lang.java.rule.regex.RegexHelper %} (Java)
* {% jdoc apex::lang.apex.rule.AbstractApexUnitTestRule %} (Apex)
* {% jdoc apex::lang.apex.rule.design.AbstractNcssCountRule %} (Apex)
* {% jdoc plsql::lang.plsql.rule.design.AbstractNcssCountRule %} (PLSQL)
* {% jdoc apex::lang.apex.ApexParser %}
* {% jdoc apex::lang.apex.ApexHandler %}
* {% jdoc core::RuleChain %}
* {% jdoc core::RuleSets %}
* {% jdoc !!core::RulesetsFactoryUtils#getRuleSets(java.lang.String, net.sourceforge.pmd.RuleSetFactory) %}
###### For removal
* {% jdoc !!core::cpd.TokenEntry#TokenEntry(java.lang.String, java.lang.String, int) %}
* {% jdoc test::testframework.AbstractTokenizerTest %}. Use CpdTextComparisonTest in module pmd-lang-test instead.
For details see
[Testing your implementation](pmd_devdocs_major_adding_new_cpd_language.html#testing-your-implementation)
in the developer documentation.
* {% jdoc !!apex::lang.apex.ast.ASTAnnotation#suppresses(core::Rule) %} (Apex)
* {% jdoc apex::lang.apex.rule.ApexXPathRule %} (Apex)
* {% jdoc java::lang.java.rule.SymbolTableTestRule %} (Java)
* {% jdoc !!java::lang.java.rule.performance.InefficientStringBufferingRule#isInStringBufferOperation(net.sourceforge.pmd.lang.ast.Node, int, java.lang.String) %}
#### 6.24.0
##### Deprecated APIs

View File

@ -74,3 +74,62 @@ All you need to do is follow this few steps:
You should take a look to [Kotlin token filter implementation](https://github.com/pmd/pmd/blob/master/pmd-kotlin/src/main/java/net/sourceforge/pmd/cpd/KotlinTokenizer.java)
- For non-Antlr grammars you can use [BaseTokenFilter](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/internal/BaseTokenFilter.java) directly or take a peek to [Java's token filter](https://github.com/pmd/pmd/blob/master/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java)
### Testing your implementation
Add a Maven dependency on `pmd-lang-test` (scope `test`) in your `pom.xml`.
This contains utilities to test your Tokenizer.
For simple tests, create a test class extending from `CpdTextComparisonTest`.
That class is written in Kotlin, but you can extend it in Java as well.
To add tests, you need to write regular JUnit `@Test`-annotated methods, and
call the method `doTest` with the name of the test file.
For example, for the Dart language:
```java
public class DartTokenizerTest extends CpdTextComparisonTest {
/**********************************
Implementation of the superclass
***********************************/
public DartTokenizerTest() {
super(".dart"); // the file extension for the dart language
}
@Override
protected String getResourcePrefix() {
// If your class is in src/test/java /some/package
// you need to place the test files in src/test/resources/some/package/cpdData
return "cpdData";
}
@Override
public Tokenizer newTokenizer() {
// Override this abstract method to return the correct tokenizer
return new DartTokenizer();
}
/**************
Test methods
***************/
@Test // don't forget the JUnit annotation
public void testLiterals() {
// This will look for a file named literals.dart
// in the directory identified by getResourcePrefix,
// tokenize it, then compare the result against a baseline
// literals.txt file in the same directory
// If the baseline file does not exist, it is created automatically
doTest("literals");
}
}
```

View File

@ -40,7 +40,9 @@ The tool comes with a rather extensive help text, simply running with `-help`!
{% include custom/cli_option_row.html options="-auxclasspath"
option_arg="cp"
description="Specifies the classpath for libraries used by the source code.
This is used to resolve types in source files. Alternatively, a `file://` URL
This is used to resolve types in source files. The platform specific path delimiter
(\":\" on Linux, \";\" on Windows) is used to separate the entries.
Alternatively, a single `file:` URL
to a text file containing path elements on consecutive lines can be specified."
languages="Java"
%}

View File

@ -80,11 +80,19 @@ function from Java types to XDM types.
|`String` | `xs:string`
|`Character` | `xs:string`
|`Enum<E>` | `xs:string` (uses `Object::toString`)
|`List<E>` | `conv(E)*` (a sequence type)
|`List<E>` | `conv(E)*` (a sequence type) <br> ⚠️ List support is deprecated with 6.25.0. See below.
The same `conv` function is used to translate rule property values to XDM values.
{% include warning.html content="Support for attributes of type `List<E>` has been deprecated
with PMD 6.25.0 and will be removed completely with PMD 7. The reason is that newer Saxon
versions don't support sequences as attributes anymore. Lists are still possible in Java-based
rules but not with XPath.
[Multivalued rule properties](pmd_userdocs_extending_defining_properties.html#multivalued-properties)
are still supported." %}
## Migrating from 1.0 to 2.0

View File

@ -14,83 +14,26 @@ This is a {{ site.pmd.release_type }} release.
### New and noteworthy
#### Scala cross compilation
Up until now the PMD Scala module has been compiled against scala 2.13 only by default.
However, this makes it impossible to use pmd as a library in scala projects,
that use scala 2.12, e.g. in sbt plugins. Therefore PMD now provides cross compiled pmd-scala
modules for both versions: **scala 2.12** and **scala 2.13**.
The new modules have new maven artifactIds. The old artifactId `net.sourceforge.pmd:pmd-scala:{{ site.pmd.version }}`
is still available, but is deprecated from now on. It has been demoted to be just a delegation to the new
`pmd-scala_2.13` module and will be removed eventually.
The coordinates for the new modules are:
```
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-scala_2.12</artifactId>
<version>{{ site.pmd.version }}</version>
</dependency>
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-scala_2.13</artifactId>
<version>{{ site.pmd.version }}</version>
</dependency>
```
The command line version of PMD continues to use **scala 2.13**.
#### New Rules
* The new Java Rule {% rule "java/codestyle/UnnecessaryCast" %} (`java-codestyle`)
finds casts that are unnecessary while accessing collection elements.
#### Modified rules
* The Java rule {% rule "java/codestyle/UseDiamondOperator" %} (`java-codestyle`) now by default
finds unnecessary usages of type parameters, which are nested, involve wildcards and are used
within a ternary operator. These usages are usually only unnecessary with Java8 and later, when
the type inference in Java has been improved.
In order to avoid false positives when checking Java7 only code, the rule has the new property
`java7Compatibility`, which is disabled by default. Settings this to "true" retains
the old rule behaviour.
### Fixed Issues
* apex
* [#2610](https://github.com/pmd/pmd/pull/2610): \[apex] Support top-level enums in rules
* apex-bestpractices
* [#2626](https://github.com/pmd/pmd/issues/2626): \[apex] UnusedLocalVariable - false positive on case insensitivity allowed in Apex
* core
* [#2594](https://github.com/pmd/pmd/issues/2594): \[core] Update exec-maven-plugin and align it in all project
* c#
* [#2551](https://github.com/pmd/pmd/issues/2551): \[c#] CPD suppression with comments doesn't work
* java-codestyle
* [#2545](https://github.com/pmd/pmd/issues/2545): \[java] UseDiamondOperator false negatives
* [#2573](https://github.com/pmd/pmd/pull/2573): \[java] DefaultPackage: Allow package default JUnit 5 Test methods
* java-design
* [#2563](https://github.com/pmd/pmd/pull/2563): \[java] UselessOverridingMethod false negative with already public methods
* scala
* [#2547](https://github.com/pmd/pmd/pull/2547): \[scala] Add cross compilation for scala 2.12 and 2.13
* [#2174](https://github.com/pmd/pmd/issues/2174): \[java] LawOfDemeter: False positive with 'this' pointer
* [#2189](https://github.com/pmd/pmd/issues/2189): \[java] LawOfDemeter: False positive when casting to derived class
* java-performance
* [#1736](https://github.com/pmd/pmd/issues/1736): \[java] UseStringBufferForStringAppends: False positive if only one concatenation
* [#2207](https://github.com/pmd/pmd/issues/2207): \[java] AvoidInstantiatingObjectsInLoops: False positive - should not flag objects when assigned to lists/arrays
### API Changes
* The maven module `net.sourceforge.pmd:pmd-scala` is deprecated. Use `net.sourceforge.pmd:pmd-scala_2.13`
or `net.sourceforge.pmd:pmd-scala_2.12` instead.
#### Deprecated APIs
* {%jdoc apex::lang.apex.ast.ASTAnnotation#suppresses(core::Rule) %}
### External Contributions
* [#2349](https://github.com/pmd/pmd/pull/2349): \[java] Optimize UnusedPrivateMethodRule - [shilko2013](https://github.com/shilko2013)
* [#2547](https://github.com/pmd/pmd/pull/2547): \[scala] Add cross compilation for scala 2.12 and 2.13 - [João Ferreira](https://github.com/jtjeferreira)
* [#2567](https://github.com/pmd/pmd/pull/2567): \[c#] Fix CPD suppression with comments doesn't work - [Lixon Lookose](https://github.com/LixonLookose)
* [#2573](https://github.com/pmd/pmd/pull/2573): \[java] DefaultPackage: Allow package default JUnit 5 Test methods - [Craig Andrews](https://github.com/candrews)
* [#2558](https://github.com/pmd/pmd/pull/2558): \[java] Fix issue #1736 and issue #2207 - [Young Chan](https://github.com/YYoungC)
* [#2560](https://github.com/pmd/pmd/pull/2560): \[java] Fix false positives of LawOfDemeter: this and cast expressions - [xioayuge](https://github.com/xioayuge)
* [#2590](https://github.com/pmd/pmd/pull/2590): Update libraries snyk is referring to as `unsafe` - [Artem Krosheninnikov](https://github.com/KroArtem)
* [#2597](https://github.com/pmd/pmd/pull/2597): \[dependencies] Fix issue #2594, update exec-maven-plugin everywhere - [Artem Krosheninnikov](https://github.com/KroArtem)
{% endtocmaker %}

View File

@ -5,6 +5,179 @@ permalink: pmd_release_notes_old.html
Previous versions of PMD can be downloaded here: https://github.com/pmd/pmd/releases
## 27-June-2020 - 6.25.0
The PMD team is pleased to announce PMD 6.25.0.
This is a minor release.
### Table Of Contents
* [New and noteworthy](#new-and-noteworthy)
* [Scala cross compilation](#scala-cross-compilation)
* [New Rules](#new-rules)
* [Modified rules](#modified-rules)
* [Fixed Issues](#fixed-issues)
* [API Changes](#api-changes)
* [Deprecated APIs](#deprecated-apis)
* [Internal API](#internal-api)
* [For removal](#for-removal)
* [External Contributions](#external-contributions)
* [Stats](#stats)
### New and noteworthy
#### Scala cross compilation
Up until now the PMD Scala module has been compiled against scala 2.13 only by default.
However, this makes it impossible to use pmd as a library in scala projects,
that use scala 2.12, e.g. in sbt plugins. Therefore PMD now provides cross compiled pmd-scala
modules for both versions: **scala 2.12** and **scala 2.13**.
The new modules have new maven artifactIds. The old artifactId `net.sourceforge.pmd:pmd-scala:6.25.0`
is still available, but is deprecated from now on. It has been demoted to be just a delegation to the new
`pmd-scala_2.13` module and will be removed eventually.
The coordinates for the new modules are:
```
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-scala_2.12</artifactId>
<version>6.25.0</version>
</dependency>
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-scala_2.13</artifactId>
<version>6.25.0</version>
</dependency>
```
The command line version of PMD continues to use **scala 2.13**.
#### New Rules
* The new Java Rule [`UnnecessaryCast`](https://pmd.github.io/pmd-6.25.0/pmd_rules_java_codestyle.html#unnecessarycast) (`java-codestyle`)
finds casts that are unnecessary while accessing collection elements.
* The new Java Rule [`AvoidCalendarDateCreation`](https://pmd.github.io/pmd-6.25.0/pmd_rules_java_performance.html#avoidcalendardatecreation) (`java-performance`)
finds usages of `java.util.Calendar` whose purpose is just to get the current date. This
can be done in a more lightweight way.
* The new Java Rule [`UseIOStreamsWithApacheCommonsFileItem`](https://pmd.github.io/pmd-6.25.0/pmd_rules_java_performance.html#useiostreamswithapachecommonsfileitem) (`java-performance`)
finds usage of `FileItem.get()` and `FileItem.getString()`. These two methods are problematic since
they load the whole uploaded file into memory.
#### Modified rules
* The Java rule [`UseDiamondOperator`](https://pmd.github.io/pmd-6.25.0/pmd_rules_java_codestyle.html#usediamondoperator) (`java-codestyle`) now by default
finds unnecessary usages of type parameters, which are nested, involve wildcards and are used
within a ternary operator. These usages are usually only unnecessary with Java8 and later, when
the type inference in Java has been improved.
In order to avoid false positives when checking Java7 only code, the rule has the new property
`java7Compatibility`, which is disabled by default. Settings this to "true" retains
the old rule behaviour.
### Fixed Issues
* apex-bestpractices
* [#2554](https://github.com/pmd/pmd/issues/2554): \[apex] Exception applying rule UnusedLocalVariable on trigger
* core
* [#971](https://github.com/pmd/pmd/issues/971): \[apex]\[plsql]\[java] Deprecate overly specific base rule classes
* [#2451](https://github.com/pmd/pmd/issues/2451): \[core] Deprecate support for List attributes with XPath 2.0
* [#2599](https://github.com/pmd/pmd/pull/2599): \[core] Fix XPath 2.0 Rule Chain Analyzer with Unions
* [#2483](https://github.com/pmd/pmd/issues/2483): \[lang-test] Support cpd tests based on text comparison.
For details see
[Testing your implementation](pmd_devdocs_major_adding_new_cpd_language.html#testing-your-implementation)
in the developer documentation.
* c#
* [#2551](https://github.com/pmd/pmd/issues/2551): \[c#] CPD suppression with comments doesn't work
* cpp
* [#1757](https://github.com/pmd/pmd/issues/1757): \[cpp] Support unicode characters
* java
* [#2549](https://github.com/pmd/pmd/issues/2549): \[java] Auxclasspath in PMD CLI does not support relative file path
* java-codestyle
* [#2545](https://github.com/pmd/pmd/issues/2545): \[java] UseDiamondOperator false negatives
* [#2573](https://github.com/pmd/pmd/pull/2573): \[java] DefaultPackage: Allow package default JUnit 5 Test methods
* java-design
* [#2563](https://github.com/pmd/pmd/pull/2563): \[java] UselessOverridingMethod false negative with already public methods
* [#2570](https://github.com/pmd/pmd/issues/2570): \[java] NPathComplexity should mention the expected NPath complexity
* java-errorprone
* [#2544](https://github.com/pmd/pmd/issues/2544): \[java] UseProperClassLoader can not detect the case with method call on intermediate variable
* java-performance
* [#2591](https://github.com/pmd/pmd/pull/2591): \[java] InefficientStringBuffering/AppendCharacterWithChar: Fix false negatives with concats in appends
* [#2600](https://github.com/pmd/pmd/pull/2600): \[java] UseStringBufferForStringAppends: fix false negative with fields
* scala
* [#2547](https://github.com/pmd/pmd/pull/2547): \[scala] Add cross compilation for scala 2.12 and 2.13
### API Changes
* The maven module `net.sourceforge.pmd:pmd-scala` is deprecated. Use `net.sourceforge.pmd:pmd-scala_2.13`
or `net.sourceforge.pmd:pmd-scala_2.12` instead.
* Rule implementation classes are internal API and should not be used by clients directly.
The rules should only be referenced via their entry in the corresponding category ruleset
(e.g. `<rule ref="category/java/bestpractices.xml/AbstractClassWithoutAbstractMethod" />`).
While we definitely won't move or rename the rule classes in PMD 6.x, we might consider changes
in PMD 7.0.0 and onwards.
#### Deprecated APIs
##### Internal API
Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0.
You can identify them with the `@InternalApi` annotation. You'll also get a deprecation warning.
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.25.0/net/sourceforge/pmd/lang/java/rule/AbstractIgnoredAnnotationRule.html#"><code>AbstractIgnoredAnnotationRule</code></a> (Java)
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.25.0/net/sourceforge/pmd/lang/java/rule/AbstractInefficientZeroCheck.html#"><code>AbstractInefficientZeroCheck</code></a> (Java)
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.25.0/net/sourceforge/pmd/lang/java/rule/AbstractJUnitRule.html#"><code>AbstractJUnitRule</code></a> (Java)
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.25.0/net/sourceforge/pmd/lang/java/rule/AbstractJavaMetricsRule.html#"><code>AbstractJavaMetricsRule</code></a> (Java)
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.25.0/net/sourceforge/pmd/lang/java/rule/AbstractLombokAwareRule.html#"><code>AbstractLombokAwareRule</code></a> (Java)
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.25.0/net/sourceforge/pmd/lang/java/rule/AbstractPoorMethodCall.html#"><code>AbstractPoorMethodCall</code></a> (Java)
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.25.0/net/sourceforge/pmd/lang/java/rule/bestpractices/AbstractSunSecureRule.html#"><code>AbstractSunSecureRule</code></a> (Java)
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.25.0/net/sourceforge/pmd/lang/java/rule/design/AbstractNcssCountRule.html#"><code>AbstractNcssCountRule</code></a> (Java)
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.25.0/net/sourceforge/pmd/lang/java/rule/documentation/AbstractCommentRule.html#"><code>AbstractCommentRule</code></a> (Java)
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.25.0/net/sourceforge/pmd/lang/java/rule/performance/AbstractOptimizationRule.html#"><code>AbstractOptimizationRule</code></a> (Java)
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.25.0/net/sourceforge/pmd/lang/java/rule/regex/RegexHelper.html#"><code>RegexHelper</code></a> (Java)
* <a href="https://docs.pmd-code.org/apidocs/pmd-apex/6.25.0/net/sourceforge/pmd/lang/apex/rule/AbstractApexUnitTestRule.html#"><code>AbstractApexUnitTestRule</code></a> (Apex)
* <a href="https://docs.pmd-code.org/apidocs/pmd-apex/6.25.0/net/sourceforge/pmd/lang/apex/rule/design/AbstractNcssCountRule.html#"><code>AbstractNcssCountRule</code></a> (Apex)
* <a href="https://docs.pmd-code.org/apidocs/pmd-plsql/6.25.0/net/sourceforge/pmd/lang/plsql/rule/design/AbstractNcssCountRule.html#"><code>AbstractNcssCountRule</code></a> (PLSQL)
* <a href="https://docs.pmd-code.org/apidocs/pmd-apex/6.25.0/net/sourceforge/pmd/lang/apex/ApexParser.html#"><code>ApexParser</code></a>
* <a href="https://docs.pmd-code.org/apidocs/pmd-apex/6.25.0/net/sourceforge/pmd/lang/apex/ApexHandler.html#"><code>ApexHandler</code></a>
* <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.25.0/net/sourceforge/pmd/RuleChain.html#"><code>RuleChain</code></a>
* <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.25.0/net/sourceforge/pmd/RuleSets.html#"><code>RuleSets</code></a>
* <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.25.0/net/sourceforge/pmd/RulesetsFactoryUtils.html#getRuleSets(java.lang.String,net.sourceforge.pmd.RuleSetFactory)"><code>RulesetsFactoryUtils#getRuleSets</code></a>
##### For removal
* <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.25.0/net/sourceforge/pmd/cpd/TokenEntry.html#TokenEntry(java.lang.String,java.lang.String,int)"><code>TokenEntry#TokenEntry</code></a>
* <a href="https://docs.pmd-code.org/apidocs/pmd-test/6.25.0/net/sourceforge/pmd/testframework/AbstractTokenizerTest.html#"><code>AbstractTokenizerTest</code></a>. Use CpdTextComparisonTest in module pmd-lang-test instead.
For details see
[Testing your implementation](pmd_devdocs_major_adding_new_cpd_language.html#testing-your-implementation)
in the developer documentation.
* <a href="https://docs.pmd-code.org/apidocs/pmd-apex/6.25.0/net/sourceforge/pmd/lang/apex/ast/ASTAnnotation.html#suppresses(net.sourceforge.pmd.Rule)"><code>ASTAnnotation#suppresses</code></a> (Apex)
* <a href="https://docs.pmd-code.org/apidocs/pmd-apex/6.25.0/net/sourceforge/pmd/lang/apex/rule/ApexXPathRule.html#"><code>ApexXPathRule</code></a> (Apex)
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.25.0/net/sourceforge/pmd/lang/java/rule/SymbolTableTestRule.html#"><code>SymbolTableTestRule</code></a> (Java)
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.25.0/net/sourceforge/pmd/lang/java/rule/performance/InefficientStringBufferingRule.html#isInStringBufferOperation(net.sourceforge.pmd.lang.ast.Node,int,java.lang.String)"><code>InefficientStringBufferingRule#isInStringBufferOperation</code></a>
### External Contributions
* [#1932](https://github.com/pmd/pmd/pull/1932): \[java] Added 4 performance rules originating from PMD-jPinpoint-rules - [Jeroen Borgers](https://github.com/jborgers)
* [#2349](https://github.com/pmd/pmd/pull/2349): \[java] Optimize UnusedPrivateMethodRule - [shilko2013](https://github.com/shilko2013)
* [#2547](https://github.com/pmd/pmd/pull/2547): \[scala] Add cross compilation for scala 2.12 and 2.13 - [João Ferreira](https://github.com/jtjeferreira)
* [#2567](https://github.com/pmd/pmd/pull/2567): \[c#] Fix CPD suppression with comments doesn't work - [Lixon Lookose](https://github.com/LixonLookose)
* [#2573](https://github.com/pmd/pmd/pull/2573): \[java] DefaultPackage: Allow package default JUnit 5 Test methods - [Craig Andrews](https://github.com/candrews)
* [#2593](https://github.com/pmd/pmd/pull/2593): \[java] NPathComplexity should mention the expected NPath complexity - [Artem Krosheninnikov](https://github.com/KroArtem)
### Stats
* 135 commits
* 31 closed tickets & PRs
* Days since last release: 33
## 24-May-2020 - 6.24.0
The PMD team is pleased to announce PMD 6.24.0.

View File

@ -8,7 +8,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<version>6.26.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
@ -54,12 +54,12 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.7</version>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
@ -119,7 +119,7 @@
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.17</version>
<version>1.26</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<version>6.26.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>

View File

@ -56,7 +56,8 @@ public class ApexTokenizer implements Tokenizer {
tokenText = tokenText.toLowerCase(Locale.ROOT);
}
TokenEntry tokenEntry = new TokenEntry(tokenText, sourceCode.getFileName(), token.getLine(),
token.getCharPositionInLine(), token.getCharPositionInLine() + tokenText.length());
token.getCharPositionInLine() + 1,
token.getCharPositionInLine() + tokenText.length());
tokenEntries.add(tokenEntry);
}
token = lexer.nextToken();

View File

@ -8,6 +8,7 @@ import java.io.Writer;
import java.util.Arrays;
import java.util.List;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
import net.sourceforge.pmd.lang.Parser;
import net.sourceforge.pmd.lang.ParserOptions;
@ -26,6 +27,11 @@ import net.sourceforge.pmd.lang.metrics.internal.AbstractLanguageMetricsProvider
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
/**
* @deprecated Internal API
*/
@Deprecated
@InternalApi
public class ApexHandler extends AbstractLanguageVersionHandler {
private final ApexMetricsProvider myMetricsProvider = new ApexMetricsProvider();

View File

@ -7,7 +7,9 @@ package net.sourceforge.pmd.lang.apex;
import java.io.Reader;
import java.util.Map;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.AbstractParser;
import net.sourceforge.pmd.lang.LanguageVersionHandler;
import net.sourceforge.pmd.lang.ParserOptions;
import net.sourceforge.pmd.lang.TokenManager;
import net.sourceforge.pmd.lang.ast.Node;
@ -15,7 +17,11 @@ import net.sourceforge.pmd.lang.ast.ParseException;
/**
* Adapter for the Apex jorje parser
*
* @deprecated This is internal API, use {@link LanguageVersionHandler#getParser(ParserOptions)}.
*/
@InternalApi
@Deprecated
public class ApexParser extends AbstractParser {
private net.sourceforge.pmd.lang.apex.ast.ApexParser apexParser;

View File

@ -10,6 +10,7 @@ import java.util.Map;
import org.apache.commons.io.IOUtils;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.apex.ApexJorjeLogging;
import net.sourceforge.pmd.lang.apex.ApexParserOptions;
import net.sourceforge.pmd.lang.ast.ParseException;
@ -23,6 +24,11 @@ import apex.jorje.semantic.ast.compilation.UserTrigger;
import apex.jorje.semantic.ast.visitor.AdditionalPassScope;
import apex.jorje.semantic.ast.visitor.AstVisitor;
/**
* @deprecated Internal API
*/
@InternalApi
@Deprecated
public class ApexParser {
protected final ApexParserOptions parserOptions;

View File

@ -8,6 +8,7 @@ import java.util.Stack;
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClassOrInterface;
import net.sourceforge.pmd.lang.apex.ast.ASTUserEnum;
import net.sourceforge.pmd.lang.apex.ast.ASTUserTrigger;
import net.sourceforge.pmd.lang.apex.ast.ApexParserVisitorReducedAdapter;
@ -41,6 +42,12 @@ public class ApexMultifileVisitor extends ApexParserVisitorReducedAdapter {
}
@Override
public Object visit(ASTUserEnum node, Object data) {
return data; // ignore
}
@Override
public Object visit(ASTMethod node, Object data) {
stack.peek().addOperation(node.getQualifiedName().getOperation(), node.getSignature());

View File

@ -137,12 +137,17 @@ public abstract class AbstractApexRule extends AbstractRule
protected void visitAll(List<? extends Node> nodes, RuleContext ctx) {
for (Object element : nodes) {
// all nodes of type ApexRootNode...
if (element instanceof ASTUserClass) {
visit((ASTUserClass) element, ctx);
} else if (element instanceof ASTUserInterface) {
visit((ASTUserInterface) element, ctx);
} else if (element instanceof ASTUserTrigger) {
visit((ASTUserTrigger) element, ctx);
} else if (element instanceof ASTUserEnum) {
visit((ASTUserEnum) element, ctx);
} else if (element instanceof ASTAnonymousClass) {
visit((ASTAnonymousClass) element, ctx);
}
}
}

View File

@ -1,9 +1,10 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.rule;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.apex.ast.ASTModifierNode;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
@ -14,7 +15,10 @@ import apex.jorje.services.Version;
* Do special checks for apex unit test classes and methods
*
* @author a.subramanian
* @deprecated Internal API
*/
@Deprecated
@InternalApi
public abstract class AbstractApexUnitTestRule extends AbstractApexRule {
public AbstractApexUnitTestRule() {

View File

@ -1,4 +1,4 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
@ -11,6 +11,11 @@ import net.sourceforge.pmd.lang.apex.ApexParserOptions;
import net.sourceforge.pmd.lang.rule.XPathRule;
import net.sourceforge.pmd.renderers.CodeClimateRule;
/**
* @deprecated Will be removed with PMD 7. The only reason for this class were the code climate properties,
* which are already deprecated.
*/
@Deprecated
public class ApexXPathRule extends XPathRule implements CodeClimateRule {
public ApexXPathRule() {

View File

@ -1,4 +1,4 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
@ -7,6 +7,8 @@ package net.sourceforge.pmd.lang.apex.rule.bestpractices;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.lang.apex.ast.ASTBlockStatement;
import net.sourceforge.pmd.lang.apex.ast.ASTReferenceExpression;
import net.sourceforge.pmd.lang.apex.ast.ASTVariableDeclaration;
@ -24,6 +26,10 @@ public class UnusedLocalVariableRule extends AbstractApexRule {
String variableName = node.getImage();
ASTBlockStatement variableContext = node.getFirstParentOfType(ASTBlockStatement.class);
if (variableContext == null) {
// if there is no parent BlockStatement, e.g. in triggers
return data;
}
List<ApexNode<?>> potentialUsages = new ArrayList<>();
@ -37,7 +43,7 @@ public class UnusedLocalVariableRule extends AbstractApexRule {
continue;
}
if (usage.hasImageEqualTo(variableName)) {
if (StringUtils.equalsIgnoreCase(variableName, usage.getImage())) {
return data;
}
}

View File

@ -1,9 +1,10 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.rule.design;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.apex.ast.ASTBreakStatement;
import net.sourceforge.pmd.lang.apex.ast.ASTContinueStatement;
import net.sourceforge.pmd.lang.apex.ast.ASTDoLoopStatement;
@ -27,7 +28,10 @@ import net.sourceforge.pmd.util.NumericConstants;
* <a href="http://www.kclee.de/clemens/java/javancss/">JavaNCSS rules</a>.
*
* @author ported from Java original of Jason Bennett
* @deprecated Internal API
*/
@Deprecated
@InternalApi
public abstract class AbstractNcssCountRule extends AbstractStatisticalApexRule {
private Class<?> nodeClass;

View File

@ -129,13 +129,6 @@ public class StdCyclomaticComplexityRule extends AbstractApexRule {
@Override
public Object visit(ASTUserEnum node, Object data) {
entryStack.push(new Entry());
super.visit(node, data);
Entry classEntry = entryStack.pop();
if (classEntry.getComplexityAverage() >= reportLevel || classEntry.highestDecisionPoints >= reportLevel) {
addViolation(data, node, new String[] { "class", node.getImage(),
classEntry.getComplexityAverage() + "(Highest = " + classEntry.highestDecisionPoints + ')', });
}
return data;
}

View File

@ -4,89 +4,57 @@
package net.sourceforge.pmd.cpd;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import net.sourceforge.pmd.PMD;
import net.sourceforge.pmd.cpd.SourceCode.StringCodeLoader;
import net.sourceforge.pmd.cpd.test.CpdTextComparisonTest;
public class ApexTokenizerTest extends CpdTextComparisonTest {
public ApexTokenizerTest() {
super(".cls");
}
@Override
protected String getResourcePrefix() {
return "../lang/apex/cpd/testdata";
}
@Override
public Tokenizer newTokenizer(Properties properties) {
ApexTokenizer tokenizer = new ApexTokenizer();
tokenizer.setProperties(properties);
return tokenizer;
}
public class ApexTokenizerTest {
@Test
public void testTokenize() throws IOException {
Tokens tokens = tokenize(load("Simple.cls"));
if (tokens.size() != 28) {
printTokens(tokens);
}
assertEquals(28, tokens.size());
assertEquals("someparam", findTokensByLine(8, tokens).get(0).toString());
public void testTokenize() {
doTest("Simple");
}
@Test
public void testTokenizeCaseSensitive() throws IOException {
Tokens tokens = tokenize(load("Simple.cls"), true);
if (tokens.size() != 28) {
printTokens(tokens);
}
assertEquals(28, tokens.size());
assertEquals("someParam", findTokensByLine(8, tokens).get(0).toString());
public void testTokenizeCaseSensitive() {
doTest("Simple", "_caseSensitive", caseSensitive());
}
/**
* Comments are ignored since using ApexLexer.
*/
@Test
public void testTokenizeWithComments() throws IOException {
Tokens tokens = tokenize(load("issue427/SFDCEncoder.cls"));
assertEquals(17, tokens.size());
Tokens tokens2 = tokenize(load("issue427/SFDCEncoderConstants.cls"));
assertEquals(17, tokens2.size());
public void testTokenizeWithComments() {
doTest("comments");
}
private List<TokenEntry> findTokensByLine(int line, Tokens tokens) {
List<TokenEntry> result = new ArrayList<>();
for (TokenEntry entry : tokens.getTokens()) {
if (entry.getBeginLine() == line) {
result.add(entry);
}
}
if (result.isEmpty()) {
fail("Not tokens found at line " + line);
}
return result;
private Properties caseSensitive() {
return properties(true);
}
private Tokens tokenize(String code) {
return tokenize(code, false);
}
private Tokens tokenize(String code, boolean caseSensitive) {
ApexTokenizer tokenizer = new ApexTokenizer();
private Properties properties(boolean caseSensitive) {
Properties properties = new Properties();
properties.setProperty(ApexTokenizer.CASE_SENSITIVE, Boolean.toString(caseSensitive));
tokenizer.setProperties(properties);
Tokens tokens = new Tokens();
tokenizer.tokenize(new SourceCode(new StringCodeLoader(code)), tokens);
return tokens;
return properties;
}
private void printTokens(Tokens tokens) {
for (TokenEntry entry : tokens.getTokens()) {
System.out.printf("%02d: %s%s", entry.getBeginLine(), entry.toString(), PMD.EOL);
}
}
private String load(String name) throws IOException {
return IOUtils.toString(ApexTokenizerTest.class.getResourceAsStream(name), StandardCharsets.UTF_8);
}
}

View File

@ -0,0 +1,86 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.rule;
import static org.junit.Assert.assertEquals;
import java.util.Collections;
import org.junit.Test;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.apex.ast.ASTAnonymousClass;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
import net.sourceforge.pmd.lang.apex.ast.ASTUserEnum;
import net.sourceforge.pmd.lang.apex.ast.ASTUserInterface;
import net.sourceforge.pmd.lang.apex.ast.ASTUserTrigger;
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
import net.sourceforge.pmd.lang.apex.ast.ApexParserTestBase;
import apex.jorje.semantic.ast.compilation.Compilation;
public class AbstractApexRuleTest extends ApexParserTestBase {
@Test
public void shouldVisitTopLevelClass() {
run("class Foo { }");
}
@Test
public void shouldVisitTopLevelInterface() {
run("interface Foo { }");
}
@Test
public void shouldVisitTopLevelTrigger() {
run("trigger Foo on Account (before insert, before update) { }");
}
@Test
public void shouldVisitTopLevelEnum() {
run("enum Foo { }");
}
private void run(String code) {
ApexNode<Compilation> node = parse(code);
RuleContext ctx = new RuleContext();
ctx.setLanguageVersion(apex.getDefaultVersion());
TopLevelRule rule = new TopLevelRule();
rule.apply(Collections.singletonList(node), ctx);
assertEquals(1, ctx.getReport().size());
}
private static class TopLevelRule extends AbstractApexRule {
@Override
public Object visit(ASTUserClass node, Object data) {
addViolation(data, node);
return data;
}
@Override
public Object visit(ASTUserInterface node, Object data) {
addViolation(data, node);
return data;
}
@Override
public Object visit(ASTUserTrigger node, Object data) {
addViolation(data, node);
return data;
}
@Override
public Object visit(ASTUserEnum node, Object data) {
addViolation(data, node);
return data;
}
@Override
public Object visit(ASTAnonymousClass node, Object data) {
addViolation(data, node);
return data;
}
}
}

View File

@ -0,0 +1,35 @@
[Image] or [Truncated image[ Bcol Ecol
L4
[public] 1 6
[with] 8 11
[sharing] 13 19
[class] 21 25
[simple] 27 32
[{] 34 34
L5
[public] 5 10
[string] 12 17
[someparam] 19 27
[{] 29 29
[get] 31 33
[;] 34 34
[set] 36 38
[;] 39 39
[}] 41 41
L7
[public] 5 10
[void] 12 15
[getinit] 17 23
[(] 24 24
[)] 25 25
[{] 27 27
L8
[someparam] 9 17
[=] 19 19
[test] 22 25
[;] 27 27
L9
[}] 5 5
L10
[}] 1 1
EOF

View File

@ -0,0 +1,35 @@
[Image] or [Truncated image[ Bcol Ecol
L4
[public] 1 6
[with] 8 11
[sharing] 13 19
[class] 21 25
[Simple] 27 32
[{] 34 34
L5
[public] 5 10
[String] 12 17
[someParam] 19 27
[{] 29 29
[get] 31 33
[;] 34 34
[set] 36 38
[;] 39 39
[}] 41 41
L7
[public] 5 10
[void] 12 15
[getInit] 17 23
[(] 24 24
[)] 25 25
[{] 27 27
L8
[someParam] 9 17
[=] 19 19
[test] 22 25
[;] 27 27
L9
[}] 5 5
L10
[}] 1 1
EOF

View File

@ -0,0 +1,14 @@
/**
* OWO
*/
/**
* Common character classes used for input validation, output encoding, verifying password strength
*/
public with sharing class SFDCEncoderConstants {
// a single-line comment
/************ CLASS CODE HERE *************/
public String someParam { get; set; }
}

View File

@ -0,0 +1,21 @@
[Image] or [Truncated image[ Bcol Ecol
L8
[public] 1 6
[with] 8 11
[sharing] 13 19
[class] 21 25
[sfdcencoderconstants] 27 46
[{] 48 48
L12
[public] 2 7
[string] 9 14
[someparam] 16 24
[{] 26 26
[get] 28 30
[;] 31 31
[set] 33 35
[;] 36 36
[}] 38 38
L13
[}] 1 1
EOF

View File

@ -83,6 +83,31 @@ public class Foo {
public String fieldUsage() {
return myfield;
}
}
]]></code>
</test-code>
<test-code>
<description>NPE with triggers (#2554)</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
trigger leadOwnerUpdate on Lead (after update) {
for(Lead Id : Trigger.new) {
}
}
]]></code>
</test-code>
<test-code>
<description>[apex] UnusedLocalVariable - false positive on case insensitivity allowed in Apex #2626</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
class Foo {
private String foo() {
String Bar;
bar = 'bar';
return bar;
}
}
]]></code>
</test-code>

View File

@ -63,6 +63,14 @@ public class Foo {
]]></code>
</test-code>
<test-code>
<description>top-level enum all is well</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public enum FooEnum { }
]]></code>
</test-code>
<test-code>
<description>test class default is title case</description>
<expected-problems>1</expected-problems>
@ -121,6 +129,17 @@ public class Foo {
]]></code>
</test-code>
<test-code>
<description>top-level enum default is title case</description>
<expected-problems>1</expected-problems>
<expected-messages>
<message>The enum name 'fooEnum' doesn't match '[A-Z][a-zA-Z0-9_]*'</message>
</expected-messages>
<code><![CDATA[
public enum fooEnum { }
]]></code>
</test-code>
<test-code>
<description>custom test class pattern</description>
<rule-property name="testClassPattern">[a-zA-Z0-9_]+</rule-property>
@ -157,4 +176,22 @@ public class FOO_CLASS { }
public interface FOO_INTERFACE { }
]]></code>
</test-code>
<test-code>
<description>custom enum pattern</description>
<rule-property name="enumPattern">E[a-zA-Z0-9_]+</rule-property>
<expected-problems>0</expected-problems>
<code><![CDATA[
public enum EFOO_ENUM { }
]]></code>
</test-code>
<test-code>
<description>custom enum pattern</description>
<rule-property name="enumPattern">E[a-zA-Z0-9_]+</rule-property>
<expected-problems>1</expected-problems>
<code><![CDATA[
public enum FooEnum { }
]]></code>
</test-code>
</test-data>

Some files were not shown because too many files have changed in this diff Show More