Merge branch 'master' into pr-4100
This commit is contained in:
33 files changed
+1468
-252
No files matched your search
+49
-2
@@ -492,7 +492,8 @@
|
||||
"profile": "https://github.com/pzygielo",
|
||||
"contributions": [
|
||||
"code",
|
||||
"bug"
|
||||
"bug",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -6798,7 +6799,8 @@
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},{
|
||||
},
|
||||
{
|
||||
"login": "pacvz",
|
||||
"name": "pacvz",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/35453365?v=4",
|
||||
@@ -6806,6 +6808,51 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "mohan-chinnappan-n",
|
||||
"name": "mohan-chinnappan-n",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/5963194?v=4",
|
||||
"profile": "https://mohan-chinnappan-n.github.io/about/cv.html",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Suvashri",
|
||||
"name": "Suvashri",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/112872981?v=4",
|
||||
"profile": "https://github.com/Suvashri",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "osiegmar",
|
||||
"name": "Oliver Siegmar",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1918869?v=4",
|
||||
"profile": "https://github.com/osiegmar",
|
||||
"contributions": [
|
||||
"financial"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "OlegAndreych",
|
||||
"name": "Oleg Andreych",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/2041351?v=4",
|
||||
"profile": "https://github.com/OlegAndreych",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "lfalcantar",
|
||||
"name": "Luis Alcantar",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/13026131?v=4",
|
||||
"profile": "https://github.com/lfalcantar",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
||||
+15
-14
@@ -1,8 +1,8 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
addressable (2.8.1)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
claide (1.1.0)
|
||||
claide-plugins (0.9.2)
|
||||
cork
|
||||
@@ -12,7 +12,7 @@ GEM
|
||||
concurrent-ruby (1.1.10)
|
||||
cork (0.3.0)
|
||||
colored2 (~> 3.1)
|
||||
danger (8.6.1)
|
||||
danger (9.0.0)
|
||||
claide (~> 1.0)
|
||||
claide-plugins (>= 0.9.2)
|
||||
colored2 (~> 3.1)
|
||||
@@ -23,12 +23,12 @@ GEM
|
||||
kramdown (~> 2.3)
|
||||
kramdown-parser-gfm (~> 1.0)
|
||||
no_proxy_fix
|
||||
octokit (~> 4.7)
|
||||
octokit (~> 5.0)
|
||||
terminal-table (>= 1, < 4)
|
||||
differ (0.1.2)
|
||||
et-orbi (1.2.7)
|
||||
tzinfo
|
||||
faraday (1.10.0)
|
||||
faraday (1.10.2)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
faraday-excon (~> 1.1)
|
||||
@@ -43,7 +43,7 @@ GEM
|
||||
faraday-em_http (1.0.0)
|
||||
faraday-em_synchrony (1.0.0)
|
||||
faraday-excon (1.1.0)
|
||||
faraday-http-cache (2.4.0)
|
||||
faraday-http-cache (2.4.1)
|
||||
faraday (>= 0.8)
|
||||
faraday-httpclient (1.0.1)
|
||||
faraday-multipart (1.0.4)
|
||||
@@ -53,25 +53,26 @@ GEM
|
||||
faraday-patron (1.0.0)
|
||||
faraday-rack (1.0.0)
|
||||
faraday-retry (1.0.3)
|
||||
fugit (1.5.3)
|
||||
fugit (1.7.1)
|
||||
et-orbi (~> 1, >= 1.2.7)
|
||||
raabro (~> 1.4)
|
||||
git (1.11.0)
|
||||
git (1.12.0)
|
||||
addressable (~> 2.8)
|
||||
rchardet (~> 1.8)
|
||||
kramdown (2.4.0)
|
||||
rexml
|
||||
kramdown-parser-gfm (1.1.0)
|
||||
kramdown (~> 2.0)
|
||||
liquid (5.3.0)
|
||||
liquid (5.4.0)
|
||||
logger-colors (1.0.0)
|
||||
mini_portile2 (2.8.0)
|
||||
multipart-post (2.2.3)
|
||||
nap (1.1.0)
|
||||
no_proxy_fix (0.1.2)
|
||||
nokogiri (1.13.7)
|
||||
nokogiri (1.13.8)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
octokit (4.25.1)
|
||||
octokit (5.6.1)
|
||||
faraday (>= 1, < 3)
|
||||
sawyer (~> 0.9)
|
||||
open4 (1.3.4)
|
||||
@@ -82,12 +83,12 @@ GEM
|
||||
nokogiri (~> 1.13)
|
||||
rufus-scheduler (~> 3.8)
|
||||
slop (~> 4.6)
|
||||
public_suffix (4.0.7)
|
||||
public_suffix (5.0.0)
|
||||
raabro (1.4.0)
|
||||
racc (1.6.0)
|
||||
rchardet (1.8.0)
|
||||
rexml (3.2.5)
|
||||
rouge (3.29.0)
|
||||
rouge (4.0.0)
|
||||
ruby2_keywords (0.0.5)
|
||||
rufus-scheduler (3.8.2)
|
||||
fugit (~> 1.1, >= 1.1.6)
|
||||
@@ -100,7 +101,7 @@ GEM
|
||||
unicode-display_width (>= 1.1.1, < 3)
|
||||
tzinfo (2.0.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
unicode-display_width (2.2.0)
|
||||
unicode-display_width (2.3.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
+10
-10
@@ -1,20 +1,20 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activesupport (6.0.5.1)
|
||||
activesupport (6.0.6)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
zeitwerk (~> 2.2, >= 2.2.2)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
addressable (2.8.1)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.11.1)
|
||||
colorator (1.1.0)
|
||||
commonmarker (0.23.5)
|
||||
commonmarker (0.23.6)
|
||||
concurrent-ruby (1.1.10)
|
||||
dnsruby (1.61.9)
|
||||
simpleidn (~> 0.1)
|
||||
@@ -25,10 +25,10 @@ GEM
|
||||
ffi (>= 1.15.0)
|
||||
eventmachine (1.2.7)
|
||||
execjs (2.8.1)
|
||||
faraday (2.3.0)
|
||||
faraday-net_http (~> 2.0)
|
||||
faraday (2.5.2)
|
||||
faraday-net_http (>= 2.0, < 3.1)
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-net_http (2.0.3)
|
||||
faraday-net_http (3.0.0)
|
||||
ffi (1.15.5)
|
||||
forwardable-extended (2.6.0)
|
||||
gemoji (3.0.1)
|
||||
@@ -211,8 +211,8 @@ GEM
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
jekyll-feed (~> 0.9)
|
||||
jekyll-seo-tag (~> 2.1)
|
||||
minitest (5.16.2)
|
||||
nokogiri (1.13.7)
|
||||
minitest (5.16.3)
|
||||
nokogiri (1.13.8)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
octokit (4.25.1)
|
||||
@@ -222,7 +222,7 @@ GEM
|
||||
forwardable-extended (~> 2.6)
|
||||
public_suffix (4.0.7)
|
||||
racc (1.6.0)
|
||||
rb-fsevent (0.11.1)
|
||||
rb-fsevent (0.11.2)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
rexml (3.2.5)
|
||||
|
||||
@@ -58,6 +58,9 @@ entries:
|
||||
- title: PMD Report formats
|
||||
url: /pmd_userdocs_report_formats.html
|
||||
output: web, pdf
|
||||
- title: 3rd party rulesets
|
||||
output: web, pdf
|
||||
url: /pmd_userdocs_3rdpartyrulesets.html
|
||||
- title: null
|
||||
output: web, pdf
|
||||
subfolders:
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -9,26 +9,43 @@ author: Tom Copeland <tom@infoether.org>
|
||||
|
||||
### Salesforce / Apex Language Module
|
||||
|
||||
* October 2020 - [Salesforce CLI Scanner Custom XPath Rules - Part 1](https://bobbuzzard.blogspot.com/2020/10/salesforce-cli-scanner-custom-xpath.html),
|
||||
[Salesforce CLI Scanner Custom XPath Rules - Part 2](http://bobbuzzard.blogspot.com/2020/10/salesforce-cli-scanner-custom-xpath_11.html)
|
||||
by [Keir Bowden](https://twitter.com/bob_buzzard)
|
||||
|
||||
* March 2020 - [Helping Salesforce developers create readable and maintainable Apex code](https://gearset.com/blog/helping-sf-developers-create-readable-and-maintainable-apex-code)
|
||||
|
||||
* July 2019 - [Apex PMD \| Static code analysis - Apex Hours](https://youtu.be/34PxAHtAavU)
|
||||
|
||||
* June 2019 - [Pluralsight](https://www.pluralsight.com/authors/don-robins) Course about leveraging PMD usage for Salesforce by [Robert Sösemann](https://github.com/rsoesemann) (Apex Language Module Contributor) [Play by Play: Automated Code Analysis in Salesforce - a Tools Deep-Dive](https://www.pluralsight.com/courses/play-by-play-automated-code-analysis-in-salesforce)
|
||||
* June 2019 - [Pluralsight](https://www.pluralsight.com/authors/don-robins) Course about leveraging PMD usage for
|
||||
Salesforce by [Robert Sösemann](https://github.com/rsoesemann) (Apex Language Module Contributor)
|
||||
[Play by Play: Automated Code Analysis in Salesforce - a Tools Deep-Dive](https://www.pluralsight.com/courses/play-by-play-automated-code-analysis-in-salesforce)
|
||||
|
||||
* June 2018 - [Salesforce Way Podcast](https://salesforceway.com/podcast/podcast/) with [Robert Sösemann](https://github.com/rsoesemann) [Static Code Analysis with PMD for Apex](https://salesforceway.com/podcast/podcast/static-code-analysis-with-pmd-for-apex/)
|
||||
* June 2018 - [Salesforce Way Podcast](https://salesforceway.com/podcast/podcast/) with
|
||||
[Robert Sösemann](https://github.com/rsoesemann) [Static Code Analysis with PMD for Apex](https://salesforceway.com/podcast/podcast/static-code-analysis-with-pmd-for-apex/)
|
||||
|
||||
* January 2018 - [Webinar: How to contribute Apex rules to PMD with Robert Sösemann](https://www.youtube.com/watch?v=7_Ex9WWS_3Q)
|
||||
* January 2018 - [Webinar: How to contribute Apex rules to PMD with Robert Sösemann](https://www.youtube.com/watch?v=7_Ex9WWS_3Q)
|
||||
|
||||
* August 2017 - Webinar about how to use PMD with The Welkin Suite Salesforce IDE - Author [Robert Sösemann](https://github.com/rsoesemann) - [Improving your Apex Code Quality with PMD in The Welkin Suite](https://www.youtube.com/watch?v=Ypyiy5b6huc)
|
||||
* August 2017 - Webinar about how to use PMD with The Welkin Suite Salesforce IDE - Author
|
||||
[Robert Sösemann](https://github.com/rsoesemann) - [Improving your Apex Code Quality with PMD in The Welkin Suite](https://www.youtube.com/watch?v=Ypyiy5b6huc)
|
||||
|
||||
* November 2016 - Recording of [Robert Sösemann](https://github.com/rsoesemann)'s Session at Salesforce Dreamforce Conference about enforcing Clean Code in the Salesforce world using PMD and other tools [Clean Apex Code with Automatic Code Metrics](https://www.youtube.com/watch?v=bW7m6y6bEug)
|
||||
* November 2016 - Recording of [Robert Sösemann](https://github.com/rsoesemann)'s Session at Salesforce Dreamforce
|
||||
Conference about enforcing Clean Code in the Salesforce world using PMD and other tools
|
||||
[Clean Apex Code with Automatic Code Metrics](https://www.youtube.com/watch?v=bW7m6y6bEug)
|
||||
|
||||
|
||||
### PMD in general and other Language Modules
|
||||
|
||||
* February 2021 - Artem Krosheninnikov's talk about Quality Assurance Automation: [Artem Krosheninnikov, Wrike - How static analysis can help in QAA processes](https://www.youtube.com/watch?v=L42zH5ne074)
|
||||
* February 2021 - Artem Krosheninnikov's talk about Quality Assurance Automation:
|
||||
[Artem Krosheninnikov, Wrike - How static analysis can help in QAA processes](
|
||||
https://www.youtube.com/watch?v=L42zH5ne074)
|
||||
|
||||
* May 2019 - [Code quality assurance with PMD – An extensible static code analyser for Java and other languages](https://www.datarespons.com/code-quality-assurance-with-pmd/)
|
||||
* December 2020 - Jeroen Borgers' talk about finding performance bugs with PMD:
|
||||
[J-Fall Virtual 2020: Jeroen Borgers - Fixing your performance and concurrency bugs before they bite you](
|
||||
https://www.youtube.com/watch?v=Z_sT38KTRNk)
|
||||
|
||||
* May 2019 - [Code quality assurance with PMD – An extensible static code analyser for Java and other languages](
|
||||
https://www.datarespons.com/code-quality-assurance-with-pmd/)
|
||||
|
||||
* February 2012 - Romain Pelisse's lightning talk at FOSDEM 2012 about "PMD5: What can it do for you?".
|
||||
[Video recording is available](http://video.fosdem.org/2012/lightningtalks/PMD5.webm).
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: 3rd party rulesets
|
||||
tags: [rule_references, userdocs]
|
||||
summary: Lists rulesets and rules from the community
|
||||
permalink: pmd_userdocs_3rdpartyrulesets.html
|
||||
last_updated: September 2022
|
||||
---
|
||||
|
||||
## For Java
|
||||
|
||||
* **jPinpoint rules:** PMD rule set for performance aware Java and Kotlin coding.
|
||||
* <https://github.com/jborgers/PMD-jPinpoint-rules>
|
||||
* **arch4u-pmd** is a library with pmd rules that bring new regulations related to known problems in REST API, logging,
|
||||
monitoring, etc., including reconfigured default pmd rules to decrease false-positive violations during usage of
|
||||
well-known frameworks like Spring, Quarkus, etc.
|
||||
* <https://github.com/dgroup/arch4u-pmd>
|
||||
* Sample ruleset from **maxdocs**, a multi markup wiki engine.
|
||||
* <https://github.com/bohni/maxdocs/blob/master/src/main/config/pmd/pmd-ruleset.xml>
|
||||
* Sample ruleset from **geotools**, an open source Java library that provides tools for geospatial data.
|
||||
* <https://github.com/geotools/geotools/blob/main/build/qa/pmd-ruleset.xml>
|
||||
* <https://github.com/geotools/geotools/blob/main/build/qa/pmd-junit-ruleset.xml>
|
||||
|
||||
|
||||
## For Apex
|
||||
* **unhappy-soup**, a repository with problematic Salesforce code to showcase PMD, the SFDX Scanner CLI
|
||||
* <https://github.com/rsoesemann/unhappy-soup/blob/master/ruleset.xml>
|
||||
|
||||
@@ -122,7 +122,7 @@ Novice as much as advanced readers may want to [read on on Refactoring Guru](htt
|
||||
{% include custom/cli_option_row.html options="--ignore-literal-sequences"
|
||||
description="Ignore sequences of literals (common e.g. in list initializers)"
|
||||
default="false"
|
||||
languages="C#, C++"
|
||||
languages="C#, C++, Lua"
|
||||
%}
|
||||
{% include custom/cli_option_row.html options="--ignore-usings"
|
||||
description="Ignore `using` directives in C# when comparing text"
|
||||
|
||||
@@ -14,11 +14,49 @@ This is a {{ site.pmd.release_type }} release.
|
||||
|
||||
### New and noteworthy
|
||||
|
||||
#### Lua now supports additionally Luau
|
||||
|
||||
This release of PMD adds support for [Luau](https://github.com/Roblox/luau), a gradually typed language derived
|
||||
from Lua. This means, that the Lua language in PMD can now parse both Lua and Luau.
|
||||
|
||||
#### Modified rules
|
||||
|
||||
* The Java rule {% rule java/codestyle/CommentDefaultAccessModifier %} now by default ignores JUnit5 annotated
|
||||
methods. This behavior can be customized using the property `ignoredAnnotations`.
|
||||
|
||||
### Fixed Issues
|
||||
* cli
|
||||
* [#4118](https://github.com/pmd/pmd/issues/4118): \[cli] run.sh designer reports "integer expression expected"
|
||||
* core
|
||||
* [#4116](https://github.com/pmd/pmd/pull/4116): \[core] Missing --file arg in TreeExport CLI example
|
||||
* doc
|
||||
* [#4109](https://github.com/pmd/pmd/pull/4109): \[doc] Add page for 3rd party rulesets
|
||||
* [#4124](https://github.com/pmd/pmd/pull/4124): \[doc] Fix typos in Java rule docs
|
||||
* java-codestyle
|
||||
* [#3859](https://github.com/pmd/pmd/issues/3859): \[java] CommentDefaultAccessModifier is triggered in JUnit5 test class
|
||||
* [#4085](https://github.com/pmd/pmd/issues/4085): \[java] UnnecessaryFullyQualifiedName false positive when nested and non-nested classes with the same name and in the same package are used together
|
||||
* java-design
|
||||
* [#4090](https://github.com/pmd/pmd/issues/4090): \[java] FinalFieldCouldBeStatic false positive with non-static synchronized block (regression in 6.48, worked with 6.47)
|
||||
|
||||
### API Changes
|
||||
|
||||
#### CPD CLI
|
||||
|
||||
* CPD now supports the `--ignore-literal-sequences` argument when analyzing Lua code.
|
||||
|
||||
### Financial Contributions
|
||||
|
||||
Many thanks to our sponsors:
|
||||
|
||||
* [Oliver Siegmar](https://github.com/osiegmar) (@osiegmar)
|
||||
|
||||
### External Contributions
|
||||
* [#4066](https://github.com/pmd/pmd/pull/4066): \[lua] Add support for Luau syntax and skipping literal sequences in CPD - [Matt Hargett](https://github.com/matthargett) (@matthargett)
|
||||
* [#4116](https://github.com/pmd/pmd/pull/4116): \[core] Fix missing --file arg in TreeExport CLI example - [mohan-chinnappan-n](https://github.com/mohan-chinnappan-n) (@mohan-chinnappan-n)
|
||||
* [#4124](https://github.com/pmd/pmd/pull/4124): \[doc] Fix typos in Java rule docs - [Piotrek Żygieło](https://github.com/pzygielo) (@pzygielo)
|
||||
* [#4128](https://github.com/pmd/pmd/pull/4128): \[java] Fix False-positive UnnecessaryFullyQualifiedName when nested and non-nest… #4103 - [Oleg Andreych](https://github.com/OlegAndreych) (@OlegAndreych)
|
||||
* [#4131](https://github.com/pmd/pmd/pull/4131): \[doc] TooFewBranchesForASwitchStatement - Use "if-else" instead of "if-then" - [Suvashri](https://github.com/Suvashri) (@Suvashri)
|
||||
* [#4137](https://github.com/pmd/pmd/pull/4137): \[java] Fixes 3859: Exclude junit5 test methods from the commentDefaultAccessModifierRule - [Luis Alcantar](https://github.com/lfalcantar) (@lfalcantar)
|
||||
|
||||
{% endtocmaker %}
|
||||
|
||||
@@ -139,7 +139,7 @@ public class TreeExportCli {
|
||||
sb.append(System.lineSeparator())
|
||||
.append(System.lineSeparator());
|
||||
|
||||
sb.append("Example: ast-dump --format xml --language java MyFile.java")
|
||||
sb.append("Example: ast-dump --format xml --language java --file MyFile.java")
|
||||
.append(System.lineSeparator());
|
||||
|
||||
System.err.print(sb);
|
||||
|
||||
@@ -4,35 +4,41 @@ set OPTS=
|
||||
set MAIN_CLASS=net.sourceforge.pmd.util.fxdesigner.DesignerStarter
|
||||
|
||||
|
||||
:: sets the jver variable to the java version, eg 901 for 9.0.1+x or 180 for 1.8.0_171-b11
|
||||
:: sets the jver variable to the java version, eg 90 for 9.0.1+x or 80 for 1.8.0_171-b11 or 110 for 11.0.6.1
|
||||
:: sets the jvendor variable to either java (oracle) or openjdk
|
||||
for /f tokens^=1^,3^,4^,5^ delims^=.-_+^"^ %%j in ('java -version 2^>^&1 ^| find "version"') do (
|
||||
set jvendor=%%j
|
||||
if %%l EQU ea (
|
||||
set /A "jver=%%k00"
|
||||
set /A "jver=%%k0"
|
||||
) else (
|
||||
set /A jver=%%k%%l%%m
|
||||
if %%k EQU 1 (
|
||||
:: for java version 1.7.x, 1.8.x, ignore the first 1.
|
||||
set /A "jver=%%l%%m"
|
||||
) else (
|
||||
set /A "jver=%%k%%l"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
Set "jreopts="
|
||||
:: oracle java 9 and 10 has javafx included as a module
|
||||
if /I "%jvendor%" EQU "java" (
|
||||
if %jver% GEQ 900 (
|
||||
if %jver% LSS 1100 (
|
||||
if /I %jvendor% == java (
|
||||
if %jver% GEQ 90 (
|
||||
if %jver% LSS 110 (
|
||||
:: enable reflection
|
||||
Set jreopts=--add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED
|
||||
set jreopts=--add-opens javafx.controls/javafx.scene.control.skin=ALL-UNNAMED
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
set "_needjfxlib=0"
|
||||
if /I "%jvendor%" EQU "openjdk" set _needjfxlib=1
|
||||
if /I "%jvendor%" EQU "java" (
|
||||
if %jver% GEQ 1100 set _needjfxlib=1
|
||||
if /I %jvendor% == openjdk set _needjfxlib=1
|
||||
if /I %jvendor% == java (
|
||||
if %jver% GEQ 110 set _needjfxlib=1
|
||||
)
|
||||
if %_needjfxlib% EQU 1 (
|
||||
if %jver% LSS 1000 (
|
||||
if %jver% LSS 100 (
|
||||
echo For openjfx at least java 10 is required.
|
||||
pause
|
||||
exit
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
usage() {
|
||||
echo "Usage:"
|
||||
echo " $(basename $0) <application-name> [-h|-v] ..."
|
||||
echo " $(basename "$0") <application-name> [-h|-v] ..."
|
||||
echo ""
|
||||
echo "application-name: valid options are: $(valid_app_options)"
|
||||
echo "-h print this help"
|
||||
@@ -60,9 +60,9 @@ java_heapsize_settings() {
|
||||
|
||||
|
||||
set_lib_dir() {
|
||||
if [ -z ${LIB_DIR} ]; then
|
||||
if [ -z "${LIB_DIR}" ]; then
|
||||
# Allow for symlinks to this script
|
||||
if [ -L $0 ]; then
|
||||
if [ -L "$0" ]; then
|
||||
local script_real_loc=$(readlink "$0")
|
||||
else
|
||||
local script_real_loc=$0
|
||||
@@ -83,23 +83,25 @@ check_lib_dir() {
|
||||
}
|
||||
|
||||
function script_exit() {
|
||||
echo $1 >&2
|
||||
echo "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
determine_java_version() {
|
||||
local full_ver=$(java -version 2>&1)
|
||||
# java_ver is eg "18" for java 1.8, "90" for java 9.0, "100" for java 10.0.x
|
||||
readonly java_ver=$(echo $full_ver | sed -n '{
|
||||
# java_ver is eg "80" for java 1.8, "90" for java 9.0, "100" for java 10.0.x
|
||||
readonly java_ver=$(echo "$full_ver" | sed -n '{
|
||||
# replace early access versions, e.g. 11-ea with 11.0.0
|
||||
s/-ea/.0.0/
|
||||
# replace versions such as 10 with 10.0.0
|
||||
s/version "\([0-9]\{1,\}\)"/version "\1.0.0"/
|
||||
# replace old java versions 1.x.* (java 1.7, java 1.8) with x.*
|
||||
s/version "1\.\(.*\)"/version "\1"/
|
||||
# extract the major and minor parts of the version
|
||||
s/^.* version "\(.*\)\.\(.*\)\..*".*$/\1\2/p
|
||||
s/^.* version "\([0-9]\{1,\}\)\.\([0-9]\{1,\}\).*".*$/\1\2/p
|
||||
}')
|
||||
# java_vendor is either java (oracle) or openjdk
|
||||
readonly java_vendor=$(echo $full_ver | sed -n -e 's/^\(.*\) version .*$/\1/p')
|
||||
readonly java_vendor=$(echo "$full_ver" | sed -n -e 's/^\(.*\) version .*$/\1/p')
|
||||
}
|
||||
|
||||
jre_specific_vm_options() {
|
||||
@@ -197,7 +199,7 @@ case "${APPNAME}" in
|
||||
readonly CLASSNAME="net.sourceforge.pmd.util.treeexport.TreeExportCli"
|
||||
;;
|
||||
*)
|
||||
echo "${APPNAME} is NOT a valid application name, valid options are:$(valid_app_options)"
|
||||
echo "${APPNAME} is NOT a valid application name, valid options are: $(valid_app_options)"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
@echo off
|
||||
|
||||
:: BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
|
||||
::
|
||||
:: Simple manual test script
|
||||
:: - code is copied from designer.bat to be tested here (so please check, it might be out of sync)
|
||||
:: - mostly the function "determine_java_version" is tested here
|
||||
:: - just run it with "designertest.bat" and look at the output
|
||||
:: - test cases are at the end of this script
|
||||
::
|
||||
|
||||
GOTO :main
|
||||
|
||||
:determine_java_version
|
||||
:: sets the jver variable to the java version, eg 90 for 9.0.1+x or 80 for 1.8.0_171-b11 or 110 for 11.0.6.1
|
||||
:: sets the jvendor variable to either java (oracle) or openjdk
|
||||
for /f tokens^=1^,3^,4^,5^ delims^=.-_+^"^ %%j in (%full_version%) do (
|
||||
set jvendor=%%j
|
||||
if %%l EQU ea (
|
||||
set /A "jver=%%k0"
|
||||
) else (
|
||||
if %%k EQU 1 (
|
||||
:: for java version 1.7.x, 1.8.x, ignore the first 1.
|
||||
set /A "jver=%%l%%m"
|
||||
) else (
|
||||
set /A "jver=%%k%%l"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
set detection=
|
||||
if %jver% GEQ 70 (
|
||||
if %jver% LSS 80 (
|
||||
set detection="detected java 7"
|
||||
)
|
||||
)
|
||||
if [%detection%] == [] (
|
||||
if %jver% GEQ 80 (
|
||||
if %jver% LSS 90 (
|
||||
set detection="detected java 8"
|
||||
)
|
||||
)
|
||||
)
|
||||
if [%detection%] == [] (
|
||||
if %jver% GEQ 90 (
|
||||
if %jver% LSS 110 (
|
||||
if %jvendor% == java (
|
||||
set detection="detected java 9 or 10 from oracle"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
if [%detection%] == [] (
|
||||
if %jvendor% == openjdk (
|
||||
set detection="detected java 11 from oracle or any openjdk"
|
||||
)
|
||||
)
|
||||
if [%detection%] == [] (
|
||||
if %jvendor% == java (
|
||||
if %jver% GEQ 110 (
|
||||
set detection="detected java 11 from oracle or any openjdk"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
EXIT /B
|
||||
|
||||
|
||||
|
||||
:run_test
|
||||
set full_version=%1
|
||||
set expected_vendor=%2
|
||||
set expected_version=%3
|
||||
set expected_detection=%4
|
||||
|
||||
CALL :determine_java_version
|
||||
|
||||
echo full_version: %full_version%
|
||||
if %jver% == %expected_version% ( echo jver: %jver% [32mOK[0m ) ELSE ( echo jver: %jver% [31mEXPECTED: %expected_version% [0m )
|
||||
if %jvendor% == %expected_vendor% ( echo jvendor: %jvendor% [32mOK[0m ) ELSE ( echo jvendor: %jvendor% [31mEXPECTED: %expected_vendor% [0m )
|
||||
if [%detection%] == [%expected_detection%] ( echo detection: %detection% [32mOK[0m ) ELSE ( echo detection: %detection% [31mEXPECTED: %expected_detection% [0m )
|
||||
echo.
|
||||
|
||||
EXIT /B
|
||||
|
||||
:main
|
||||
|
||||
CALL :run_test "java version ""1.7.0_80""" java 70 "detected java 7"
|
||||
CALL :run_test "openjdk version ""1.7.0_352""" openjdk 70 "detected java 7"
|
||||
CALL :run_test "java version ""1.8.0_271""" java 80 "detected java 8"
|
||||
CALL :run_test "openjdk version ""1.8.0_345""" openjdk 80 "detected java 8"
|
||||
CALL :run_test "java version ""9.0.4""" java 90 "detected java 9 or 10 from oracle"
|
||||
CALL :run_test "openjdk version ""9.0.4""" openjdk 90 "detected java 11 from oracle or any openjdk"
|
||||
CALL :run_test "java version ""10.0.2"" 2018-07-17" java 100 "detected java 9 or 10 from oracle"
|
||||
CALL :run_test "openjdk version ""11.0.6"" 2022-08-12" openjdk 110 "detected java 11 from oracle or any openjdk"
|
||||
CALL :run_test "openjdk version ""11.0.6.1"" 2022-08-12" openjdk 110 "detected java 11 from oracle or any openjdk"
|
||||
CALL :run_test "java version ""11.0.13"" 2021-10-19 LTS" java 110 "detected java 11 from oracle or any openjdk"
|
||||
CALL :run_test "openjdk version ""17.0.4"" 2022-08-12" openjdk 170 "detected java 11 from oracle or any openjdk"
|
||||
CALL :run_test "openjdk version ""17.1.4"" 2022-08-12" openjdk 171 "detected java 11 from oracle or any openjdk"
|
||||
CALL :run_test "openjdk version ""17.0.4.1"" 2022-08-12" openjdk 170 "detected java 11 from oracle or any openjdk"
|
||||
CALL :run_test "openjdk version ""18.0.2.1"" 2022-08-18" openjdk 180 "detected java 11 from oracle or any openjdk"
|
||||
CALL :run_test "openjdk version ""19-ea"" 2022-09-20" openjdk 190 "detected java 11 from oracle or any openjdk"
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
#!/bin/bash
|
||||
# BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
|
||||
#
|
||||
# Simple manual test script
|
||||
# - code is copied from run.sh to be tested here (so please check, it might be out of sync)
|
||||
# - mostly the function "determine_java_version" is tested here
|
||||
# - just run it with "./runtest.sh" and look at the output
|
||||
# - test cases are at the end of this script
|
||||
#
|
||||
|
||||
export LANG=en_US.UTF-8
|
||||
|
||||
FULL_JAVA_VERSION=""
|
||||
|
||||
get_full_java_version() {
|
||||
#java -version 2>&1
|
||||
#echo "openjdk version \"11.0.6\" 2022-08-12"
|
||||
echo "$FULL_JAVA_VERSION"
|
||||
}
|
||||
|
||||
determine_java_version() {
|
||||
local full_ver=$(get_full_java_version)
|
||||
# java_ver is eg "80" for java 1.8, "90" for java 9.0, "100" for java 10.0.x
|
||||
java_ver=$(echo "$full_ver" | sed -n '{
|
||||
# replace early access versions, e.g. 11-ea with 11.0.0
|
||||
s/-ea/.0.0/
|
||||
# replace versions such as 10 with 10.0.0
|
||||
s/version "\([0-9]\{1,\}\)"/version "\1.0.0"/
|
||||
# replace old java versions 1.x.* (java 1.7, java 1.8) with x.*
|
||||
s/version "1\.\(.*\)"/version "\1"/
|
||||
# extract the major and minor parts of the version
|
||||
s/^.* version "\([0-9]\{1,\}\)\.\([0-9]\{1,\}\).*".*$/\1\2/p
|
||||
}')
|
||||
# java_vendor is either java (oracle) or openjdk
|
||||
java_vendor=$(echo "$full_ver" | sed -n -e 's/^\(.*\) version .*$/\1/p')
|
||||
}
|
||||
|
||||
jre_specific_vm_options() {
|
||||
options=""
|
||||
if [ "$java_ver" -ge 70 ] && [ "$java_ver" -lt 80 ]
|
||||
then
|
||||
options="detected java 7"
|
||||
elif [ "$java_ver" -ge 80 ] && [ "$java_ver" -lt 90 ]
|
||||
then
|
||||
options="detected java 8"
|
||||
elif [ "$java_ver" -ge 90 ] && [ "$java_ver" -lt 110 ] && [ "$java_vendor" = "java" ]
|
||||
then
|
||||
options="detected java 9 or 10 from oracle"
|
||||
elif [ "$java_vendor" = "openjdk" ] || ( [ "$java_vendor" = "java" ] && [ "$java_ver" -ge 110 ] )
|
||||
then
|
||||
options="detected java 11 from oracle or any openjdk"
|
||||
fi
|
||||
echo $options
|
||||
}
|
||||
|
||||
run_test() {
|
||||
FULL_JAVA_VERSION="$1"
|
||||
EXPECTED_VENDOR="$2"
|
||||
EXPECTED_VER="$3"
|
||||
EXPECTED="$4"
|
||||
echo "Testing: '${FULL_JAVA_VERSION}'"
|
||||
determine_java_version
|
||||
java_opts="$(jre_specific_vm_options)"
|
||||
echo -n "java_ver: $java_ver "
|
||||
if [ "$EXPECTED_VER" = "$java_ver" ]; then echo -e "\e[32mOK\e[0m"; else echo -e "\e[31mFAILED\e[0m"; fi
|
||||
echo -n "java_vendor: $java_vendor "
|
||||
if [ "$EXPECTED_VENDOR" = "$java_vendor" ]; then echo -e "\e[32mOK\e[0m"; else echo -e "\e[31mFAILED\e[0m"; fi
|
||||
echo -n "java_opts: $java_opts "
|
||||
if [ "$EXPECTED" = "$java_opts" ]; then echo -e "\e[32mOK\e[0m"; else echo -e "\e[31mFAILED\e[0m - expected: ${EXPECTED}"; fi
|
||||
echo
|
||||
}
|
||||
|
||||
run_test "java version \"1.7.0_80\"" "java" "70" "detected java 7"
|
||||
run_test "openjdk version \"1.7.0_352\"" "openjdk" "70" "detected java 7"
|
||||
run_test "java version \"1.8.0_271\"" "java" "80" "detected java 8"
|
||||
run_test "openjdk version \"1.8.0_345\"" "openjdk" "80" "detected java 8"
|
||||
run_test "java version \"9.0.4\"" "java" "90" "detected java 9 or 10 from oracle"
|
||||
run_test "openjdk version \"9.0.4\"" "openjdk" "90" "detected java 11 from oracle or any openjdk"
|
||||
run_test "java version \"10.0.2\" 2018-07-17" "java" "100" "detected java 9 or 10 from oracle"
|
||||
run_test "openjdk version \"11.0.6\" 2022-08-12" "openjdk" "110" "detected java 11 from oracle or any openjdk"
|
||||
run_test "openjdk version \"11.0.6.1\" 2022-08-12" "openjdk" "110" "detected java 11 from oracle or any openjdk"
|
||||
run_test "java version \"11.0.13\" 2021-10-19 LTS" "java" "110" "detected java 11 from oracle or any openjdk"
|
||||
run_test "openjdk version \"17.0.4\" 2022-08-12" "openjdk" "170" "detected java 11 from oracle or any openjdk"
|
||||
run_test "openjdk version \"17.1.4\" 2022-08-12" "openjdk" "171" "detected java 11 from oracle or any openjdk"
|
||||
run_test "openjdk version \"17.0.4.1\" 2022-08-12" "openjdk" "170" "detected java 11 from oracle or any openjdk"
|
||||
run_test "openjdk version \"18.0.2.1\" 2022-08-18" "openjdk" "180" "detected java 11 from oracle or any openjdk"
|
||||
run_test "openjdk version \"19-ea\" 2022-09-20" "openjdk" "190" "detected java 11 from oracle or any openjdk"
|
||||
+1
-1
@@ -31,7 +31,7 @@
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<version>1.14.3</version>
|
||||
<version>1.15.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
+9
@@ -57,6 +57,15 @@ public class CommentDefaultAccessModifierRule extends AbstractIgnoredAnnotationR
|
||||
Collection<String> ignoredStrings = new ArrayList<>();
|
||||
ignoredStrings.add("com.google.common.annotations.VisibleForTesting");
|
||||
ignoredStrings.add("android.support.annotation.VisibleForTesting");
|
||||
ignoredStrings.add("org.junit.jupiter.api.Test");
|
||||
ignoredStrings.add("org.junit.jupiter.api.ParameterizedTest");
|
||||
ignoredStrings.add("org.junit.jupiter.api.RepeatedTest");
|
||||
ignoredStrings.add("org.junit.jupiter.api.TestFactory");
|
||||
ignoredStrings.add("org.junit.jupiter.api.TestTemplate");
|
||||
ignoredStrings.add("org.junit.jupiter.api.BeforeEach");
|
||||
ignoredStrings.add("org.junit.jupiter.api.BeforeAll");
|
||||
ignoredStrings.add("org.junit.jupiter.api.AfterEach");
|
||||
ignoredStrings.add("org.junit.jupiter.api.AfterAll");
|
||||
return ignoredStrings;
|
||||
}
|
||||
|
||||
|
||||
+27
-4
@@ -17,7 +17,9 @@ import java.util.logging.Logger;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import net.sourceforge.pmd.RuleContext;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTName;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTNameList;
|
||||
@@ -186,9 +188,12 @@ public class UnnecessaryFullyQualifiedNameRule extends AbstractJavaRule {
|
||||
|
||||
if (matches.isEmpty()) {
|
||||
if (isJavaLangImplicit(node)) {
|
||||
addViolation(data, node, new Object[] { node.getImage(), "java.lang.*", "implicit "});
|
||||
asCtx(data).addViolation(node,
|
||||
node.getImage(), "java.lang.*", "implicit ");
|
||||
} else if (isSamePackage(node, name)) {
|
||||
addViolation(data, node, new Object[] { node.getImage(), currentPackage + ".*", "same package "});
|
||||
if (!hasSameSimpleNameInScope(node)) {
|
||||
asCtx(data).addViolation(node, node.getImage(), currentPackage + ".*", "same package ");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ASTImportDeclaration firstMatch = findFirstMatch(matches);
|
||||
@@ -199,11 +204,29 @@ public class UnnecessaryFullyQualifiedNameRule extends AbstractJavaRule {
|
||||
String importStr = firstMatch.getImportedName() + (firstMatch.isImportOnDemand() ? ".*" : "");
|
||||
String type = firstMatch.isStatic() ? "static " : "";
|
||||
|
||||
addViolation(data, node, new Object[] { node.getImage(), importStr, type });
|
||||
asCtx(data).addViolation(node, node.getImage(), importStr, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasSameSimpleNameInScope(TypeNode node) {
|
||||
final ASTCompilationUnit root = node.getRoot();
|
||||
final List<ASTClassOrInterfaceDeclaration> declarationDescendants = root.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class);
|
||||
final Class<?> nodeType = node.getType();
|
||||
|
||||
if (nodeType == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ASTClassOrInterfaceDeclaration declarationDescendant : declarationDescendants) {
|
||||
if (nodeType.getSimpleName().equals(declarationDescendant.getSimpleName())
|
||||
&& !nodeType.getName().equals(declarationDescendant.getQualifiedName().toString())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private ASTImportDeclaration findFirstMatch(List<ASTImportDeclaration> imports) {
|
||||
// first search only static imports
|
||||
ASTImportDeclaration result = null;
|
||||
@@ -404,7 +427,7 @@ public class UnnecessaryFullyQualifiedNameRule extends AbstractJavaRule {
|
||||
|
||||
// Is it a conflict with a class in the same file?
|
||||
final Set<String> qualifiedTypes = node.getScope().getEnclosingScope(SourceFileScope.class)
|
||||
.getQualifiedTypeNames().keySet();
|
||||
.getQualifiedTypeNames().keySet();
|
||||
for (final String qualified : qualifiedTypes) {
|
||||
int fullLength = qualified.length();
|
||||
if (qualified.endsWith(unqualifiedName)
|
||||
|
||||
@@ -19,7 +19,7 @@ Rules which enforce generally accepted best practices.
|
||||
The abstract class does not contain any abstract methods. An abstract class suggests
|
||||
an incomplete implementation, which is to be completed by subclasses implementing the
|
||||
abstract methods. If the class is intended to be used as a base class only (not to be instantiated
|
||||
directly) a protected constructor can be provided prevent direct instantiation.
|
||||
directly) a protected constructor can be provided to prevent direct instantiation.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<example>
|
||||
|
||||
@@ -436,9 +436,10 @@ public class Éléphant {}
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#commentdefaultaccessmodifier">
|
||||
<description>
|
||||
To avoid mistakes if we want that an Annotation, Class, Enum, Method, Constructor or Field have a default access modifier
|
||||
we must add a comment at the beginning of it's declaration.
|
||||
By default the comment must be `/* default */` or `/* package */`, if you want another, you have to provide a regular expression.
|
||||
This rule ignores by default all cases that have a @VisibleForTesting annotation. Use the
|
||||
we must add a comment at the beginning of its declaration.
|
||||
By default, the comment must be `/* default */` or `/* package */`, if you want another, you have to provide a regular expression.
|
||||
|
||||
This rule ignores by default all cases that have a `@VisibleForTesting` annotation or any JUnit5 annotation. Use the
|
||||
property "ignoredAnnotations" to customize the recognized annotations.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
|
||||
@@ -17,7 +17,7 @@ Rules that help you discover design issues.
|
||||
message="No abstract method which means that the keyword is most likely used to prevent instantiation. Use a private or protected constructor instead."
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#abstractclasswithoutanymethod">
|
||||
<description>
|
||||
If an abstract class does not provides any methods, it may be acting as a simple data container
|
||||
If an abstract class does not provide any methods, it may be acting as a simple data container
|
||||
that is not meant to be instantiated. In this case, it is probably better to use a private or
|
||||
protected constructor in order to prevent instantiation than make the class misleadingly abstract.
|
||||
</description>
|
||||
@@ -53,7 +53,7 @@ public abstract class Example {
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#avoidcatchinggenericexception">
|
||||
<description>
|
||||
Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block
|
||||
Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
@@ -836,6 +836,8 @@ in each object at runtime.
|
||||
]
|
||||
]
|
||||
/VariableDeclaratorId
|
||||
[not(@Image = //MethodDeclaration[@Static = false()]//SynchronizedStatement/Expression/PrimaryExpression/
|
||||
(PrimaryPrefix/Name|PrimarySuffix[preceding-sibling::PrimaryPrefix[@ThisModifier = true()]])/@Image)]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
|
||||
@@ -844,8 +844,8 @@ private String baz() {
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#toofewbranchesforaswitchstatement">
|
||||
<description>
|
||||
Switch statements are intended to be used to support complex branching behaviour. Using a switch for only a few
|
||||
cases is ill-advised, since switches are not as easy to understand as if-then statements. In these cases use the
|
||||
if-then statement to increase code readability.
|
||||
cases is ill-advised, since switches are not as easy to understand as if-else statements. In these cases use the
|
||||
if-else statement to increase code readability.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
|
||||
+14
@@ -381,6 +381,20 @@ public interface MyInterface {
|
||||
public enum MyEnum {
|
||||
FOO;
|
||||
class MyNestedClass {}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>#3859 [java] CommentDefaultAccessModifier is triggered in JUnit5 method and it was conflicting with rule JUnit5TestShouldBePackagePrivate</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class SomeTest {
|
||||
|
||||
@Test
|
||||
void test() {}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
+34
@@ -622,6 +622,40 @@ public class UnnecessaryFullyQualifiedName {
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>False positive when same package inner class is referenced (not enum) #4085</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
package net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname;
|
||||
|
||||
public class OuterTestClass {
|
||||
public static class TestClass{
|
||||
private final net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname.TestClass test;
|
||||
|
||||
public TestClass(net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname.TestClass test){
|
||||
|
||||
this.test = test;
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Should report fully-qualified name usage of a class in itself #4085</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>4</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
package net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname;
|
||||
|
||||
public class TestClass {
|
||||
public static net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname.TestClass INSTANCE(){
|
||||
return new TestClass();
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>#2098 false positive with annotated package</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
|
||||
+30
@@ -231,4 +231,34 @@ public class Foo {
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>[java] FinalFieldCouldBeStatic false positive with non-static synchronized block (regression in 6.48, worked with 6.47) #4090</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>4</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
class foo {
|
||||
private final Object[] lock = new Object[0];
|
||||
private final Object[] lock2 = new Object[0];
|
||||
private final Object[] o = new Object[0];
|
||||
|
||||
|
||||
void init() {
|
||||
synchronized (lock) {
|
||||
// do init stuff
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
synchronized (this.lock2) {
|
||||
// do close stuff
|
||||
}
|
||||
}
|
||||
|
||||
void foo() {
|
||||
System.out.println(o);
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
</test-data>
|
||||
File diff suppressed because it is too large.
Load diff
@@ -4,15 +4,28 @@
|
||||
|
||||
package net.sourceforge.pmd.cpd;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Language implementation for Lua
|
||||
*/
|
||||
public class LuaLanguage extends AbstractLanguage {
|
||||
|
||||
public LuaLanguage() {
|
||||
this(System.getProperties());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Lua Language instance.
|
||||
*/
|
||||
public LuaLanguage() {
|
||||
public LuaLanguage(Properties properties) {
|
||||
super("Lua", "lua", new LuaTokenizer(), ".lua");
|
||||
setProperties(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setProperties(Properties properties) {
|
||||
LuaTokenizer tokenizer = (LuaTokenizer) getTokenizer();
|
||||
tokenizer.setProperties(properties);
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,11 @@
|
||||
|
||||
package net.sourceforge.pmd.cpd;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
|
||||
import net.sourceforge.pmd.cpd.token.AntlrToken;
|
||||
import net.sourceforge.pmd.cpd.token.AntlrTokenFilter;
|
||||
import net.sourceforge.pmd.lang.antlr.AntlrTokenManager;
|
||||
import net.sourceforge.pmd.lang.lua.antlr4.LuaLexer;
|
||||
@@ -15,6 +18,22 @@ import net.sourceforge.pmd.lang.lua.antlr4.LuaLexer;
|
||||
*/
|
||||
public class LuaTokenizer extends AntlrTokenizer {
|
||||
|
||||
private boolean ignoreLiteralSequences = false;
|
||||
|
||||
/**
|
||||
* Sets the possible options for the Lua tokenizer.
|
||||
*
|
||||
* @param properties the properties
|
||||
* @see #OPTION_IGNORE_LITERAL_SEQUENCES
|
||||
*/
|
||||
public void setProperties(Properties properties) {
|
||||
ignoreLiteralSequences = getBooleanProperty(properties, OPTION_IGNORE_LITERAL_SEQUENCES);
|
||||
}
|
||||
|
||||
private boolean getBooleanProperty(final Properties properties, final String property) {
|
||||
return Boolean.parseBoolean(properties.getProperty(property, Boolean.FALSE.toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AntlrTokenManager getLexerForSource(SourceCode sourceCode) {
|
||||
CharStream charStream = AntlrTokenizer.getCharStreamFromSourceCode(sourceCode);
|
||||
@@ -23,6 +42,151 @@ public class LuaTokenizer extends AntlrTokenizer {
|
||||
|
||||
@Override
|
||||
protected AntlrTokenFilter getTokenFilter(final AntlrTokenManager tokenManager) {
|
||||
return new AntlrTokenFilter(tokenManager);
|
||||
return new LuaTokenFilter(tokenManager, ignoreLiteralSequences);
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link LuaTokenFilter} extends the {@link AntlrTokenFilter} to discard
|
||||
* Lua-specific tokens.
|
||||
* <p>
|
||||
* By default, it discards semicolons, require statements, and
|
||||
* enables annotation-based CPD suppression.
|
||||
* </p>
|
||||
*/
|
||||
private static class LuaTokenFilter extends AntlrTokenFilter {
|
||||
|
||||
private final boolean ignoreLiteralSequences;
|
||||
private boolean discardingRequires = false;
|
||||
private boolean discardingNL = false;
|
||||
private AntlrToken discardingLiteralsUntil = null;
|
||||
private boolean discardCurrent = false;
|
||||
|
||||
|
||||
LuaTokenFilter(final AntlrTokenManager tokenManager, boolean ignoreLiteralSequences) {
|
||||
super(tokenManager);
|
||||
this.ignoreLiteralSequences = ignoreLiteralSequences;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void analyzeToken(final AntlrToken currentToken) {
|
||||
skipNewLines(currentToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void analyzeTokens(final AntlrToken currentToken, final Iterable<AntlrToken> remainingTokens) {
|
||||
discardCurrent = false;
|
||||
skipRequires(currentToken);
|
||||
skipLiteralSequences(currentToken, remainingTokens);
|
||||
}
|
||||
|
||||
private void skipRequires(final AntlrToken currentToken) {
|
||||
final int type = currentToken.getKind();
|
||||
if (type == LuaLexer.REQUIRE) {
|
||||
discardingRequires = true;
|
||||
} else if (type == LuaLexer.CLOSE_PARENS && discardingRequires) {
|
||||
discardingRequires = false;
|
||||
discardCurrent = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void skipNewLines(final AntlrToken currentToken) {
|
||||
discardingNL = currentToken.getKind() == LuaLexer.NL;
|
||||
}
|
||||
|
||||
private void skipLiteralSequences(final AntlrToken currentToken, final Iterable<AntlrToken> remainingTokens) {
|
||||
if (ignoreLiteralSequences) {
|
||||
final int type = currentToken.getKind();
|
||||
if (isDiscardingLiterals()) {
|
||||
if (currentToken == discardingLiteralsUntil) { // NOPMD - intentional check for reference equality
|
||||
discardingLiteralsUntil = null;
|
||||
discardCurrent = true;
|
||||
}
|
||||
} else if (type == LuaLexer.OPEN_BRACE
|
||||
|| type == LuaLexer.OPEN_BRACKET
|
||||
|| type == LuaLexer.OPEN_PARENS) {
|
||||
final AntlrToken finalToken = findEndOfSequenceOfLiterals(remainingTokens);
|
||||
discardingLiteralsUntil = finalToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AntlrToken findEndOfSequenceOfLiterals(final Iterable<AntlrToken> remainingTokens) {
|
||||
boolean seenLiteral = false;
|
||||
int braceCount = 0;
|
||||
int bracketCount = 0;
|
||||
int parenCount = 0;
|
||||
for (final AntlrToken token : remainingTokens) {
|
||||
switch (token.getKind()) {
|
||||
case LuaLexer.INT:
|
||||
case LuaLexer.NORMAL_STRING:
|
||||
case LuaLexer.INTERPOLATED_STRING:
|
||||
case LuaLexer.LONG_STRING:
|
||||
case LuaLexer.HEX_FLOAT:
|
||||
case LuaLexer.HEX:
|
||||
case LuaLexer.FLOAT:
|
||||
case LuaLexer.NIL:
|
||||
case LuaLexer.BOOLEAN:
|
||||
seenLiteral = true;
|
||||
break; // can be skipped; continue to the next token
|
||||
case LuaLexer.COMMA:
|
||||
break; // can be skipped; continue to the next token
|
||||
case LuaLexer.NL:
|
||||
// this helps skip large multi-line data table sequences in Lua
|
||||
break; // can be skipped; continue to the next token
|
||||
case LuaLexer.ASSIGNMENT:
|
||||
// this helps skip large data table sequences in Lua: { ["bob"] = "uncle", ["alice"] = "enby" }
|
||||
break; // can be skipped; continue to the next token
|
||||
case LuaLexer.OPEN_BRACE:
|
||||
braceCount++;
|
||||
break; // curly braces are allowed, as long as they're balanced
|
||||
case LuaLexer.CLOSE_BRACE:
|
||||
braceCount--;
|
||||
if (braceCount < 0) {
|
||||
// end of the list in the braces; skip all contents
|
||||
return seenLiteral ? token : null;
|
||||
} else {
|
||||
// curly braces are not yet balanced; continue to the next token
|
||||
break;
|
||||
}
|
||||
case LuaLexer.OPEN_BRACKET:
|
||||
bracketCount++;
|
||||
break; // brackets are allowed, as long as they're balanced
|
||||
case LuaLexer.CLOSE_BRACKET:
|
||||
bracketCount--;
|
||||
if (bracketCount < 0) {
|
||||
// end of the list in the brackets; skip all contents
|
||||
return seenLiteral ? token : null;
|
||||
} else {
|
||||
// brackets are not yet balanced; continue to the next token
|
||||
break;
|
||||
}
|
||||
case LuaLexer.OPEN_PARENS:
|
||||
parenCount++;
|
||||
break; // parens are allowed, as long as they're balanced
|
||||
case LuaLexer.CLOSE_PARENS:
|
||||
parenCount--;
|
||||
if (parenCount < 0) {
|
||||
// end of the list in the parens; skip all contents
|
||||
return seenLiteral ? token : null;
|
||||
} else {
|
||||
// parens are not yet balanced; continue to the next token
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// some other token than the expected ones; this is not a sequence of literals
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isDiscardingLiterals() {
|
||||
return discardingLiteralsUntil != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isLanguageSpecificDiscarding() {
|
||||
return discardingRequires || discardingNL || isDiscardingLiterals() || discardCurrent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,4 +39,14 @@ public class LuaTokenizerTest extends CpdTextComparisonTest {
|
||||
public void testTabWidth() {
|
||||
doTest("tabWidth");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLuauTypes() {
|
||||
doTest("luauTypes");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComment() {
|
||||
doTest("comment");
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
|
||||
-- inline comment ("long comment")
|
||||
print(1 --[[, 2]])
|
||||
|
||||
-- line comment ("short comment")
|
||||
print(1) -- comment
|
||||
|
||||
-- inline comment with multiple lines ("long comment")
|
||||
print(1 --[[comment line 1
|
||||
comment line 2]])
|
||||
|
||||
-- line comment without any content
|
||||
print(1) --
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
[Image] or [Truncated image[ Bcol Ecol
|
||||
L3
|
||||
[print] 1 5
|
||||
[(] 6 6
|
||||
[1] 7 7
|
||||
[)] 18 18
|
||||
L6
|
||||
[print] 1 5
|
||||
[(] 6 6
|
||||
[1] 7 7
|
||||
[)] 8 8
|
||||
L9
|
||||
[print] 1 5
|
||||
[(] 6 6
|
||||
[1] 7 7
|
||||
L10
|
||||
[)] 17 17
|
||||
L13
|
||||
[print] 1 5
|
||||
[(] 6 6
|
||||
[1] 7 7
|
||||
[)] 8 8
|
||||
EOF
|
||||
Loaded 30 of 33 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user