diff --git a/.all-contributorsrc b/.all-contributorsrc
index 908c5cc8cb..93ab44ab69 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -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,
diff --git a/Gemfile.lock b/Gemfile.lock
index 0a16d16858..f47c7c5067 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -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
diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock
index f85828b039..37ab0dfb1e 100644
--- a/docs/Gemfile.lock
+++ b/docs/Gemfile.lock
@@ -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)
diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml
index f7ab16ddb0..e0e3854f86 100644
--- a/docs/_data/sidebars/pmd_sidebar.yml
+++ b/docs/_data/sidebars/pmd_sidebar.yml
@@ -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:
diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md
index 536ffc76a9..3f57f4b9f6 100644
--- a/docs/pages/pmd/projectdocs/credits.md
+++ b/docs/pages/pmd/projectdocs/credits.md
@@ -419,555 +419,560 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
 Lucas Soncini 💻 🐛 |
+  Luis Alcantar 💻 |
 Lukasz Slonina 🐛 |
 Lukebray 🐛 |
 Lyor Goldstein 🐛 |
 MCMicS 🐛 |
 Macarse 🐛 |
 Machine account for PMD 💻 |
-  Maciek Siemczyk 🐛 |
+  Maciek Siemczyk 🐛 |
 Maikel Steneker 💻 🐛 |
 Maksim Moiseikin 🐛 |
 Manfred Koch 🐛 |
 Manuel Moya Ferrer 💻 🐛 |
 Manuel Ryan 🐛 |
 Marat Vyshegorodtsev 🐛 |
-  Marcel Härle 🐛 |
+  Marcel Härle 🐛 |
 Marcello Fialho 🐛 |
 Marcin Rataj 🐛 |
 Mark Adamcin 🐛 |
 Mark Hall 💻 🐛 |
 Mark Kolich 🐛 |
 Mark Pritchard 🐛 |
-  Markus Rathgeb 🐛 |
+  Markus Rathgeb 🐛 |
 Marquis Wang 🐛 |
 Martin Feldsztejn 🐛 |
 Martin Lehmann 🐛 |
 Martin Spamer 🐛 |
 Martin Tarjányi 🐛 |
 MatFl 🐛 |
-  Mateusz Stefanski 🐛 |
+  Mateusz Stefanski 🐛 |
 Mathieu Gouin 🐛 |
 MatiasComercio 💻 🐛 |
 Matt Benson 🐛 |
 Matt De Poorter 🐛 |
 Matt Hargett 💻 💵 |
 Matt Harrah 🐛 |
-  Matt Nelson 🐛 |
+  Matt Nelson 🐛 |
 Matthew Amos 🐛 |
 Matthew Duggan 🐛 |
 Matthew Hall 🐛 |
 Matías Fraga 💻 🐛 |
 Maxime Robert 💻 🐛 |
 MetaBF 🐛 |
-  Michael 🐛 |
+  Michael 🐛 |
 Michael Bell 🐛 |
 Michael Bernstein 🐛 |
 Michael Clay 🐛 |
 Michael Dombrowski 🐛 |
 Michael Hausegger 🐛 |
 Michael Hoefer 🐛 |
-  Michael Möbius 🐛 |
+  Michael Möbius 🐛 |
 Michael N. Lipp 🐛 |
 Michael Pellegrini 🐛 |
 Michal Kordas 🐛 |
 Michał Borek 🐛 |
 Michał Kuliński 🐛 |
 Miguel Núñez Díaz-Montes 🐛 |
-  Mihai Ionut 🐛 |
+  Mihai Ionut 🐛 |
 Mirek Hankus 🐛 |
 Mladjan Gadzic 🐛 |
 MrAngry52 🐛 |
 Muminur Choudhury 🐛 |
 Mykhailo Palahuta 💻 🐛 |
 Nagendra Kumar Singh 🐛 |
-  Nahuel Barrios 🐛 |
+  Nahuel Barrios 🐛 |
 Nathan Braun 🐛 |
 Nathan Reynolds 🐛 |
 Nathan Reynolds 🐛 |
 Nathanaël 🐛 |
 Naveen 💻 |
 Nazdravi 🐛 |
-  Neha-Dhonde 🐛 |
+  Neha-Dhonde 🐛 |
 Nicholas Doyle 🐛 |
 Nick Butcher 🐛 |
 Nico Gallinal 🐛 |
 Nicola Dal Maso 🐛 |
 Nicolas Filotto 💻 |
 Nicolas Vuillamy 📖 |
-  Nikita Chursin 🐛 |
+  Nikita Chursin 🐛 |
 Niklas Baudy 🐛 |
 Nikolas Havrikov 🐛 |
 Nilesh Virkar 🐛 |
 Nimit Patel 🐛 |
 Niranjan Harpale 🐛 |
 Noah Sussman 🐛 |
-  Noah0120 🐛 |
+  Noah0120 🐛 |
 Noam Tamim 🐛 |
 Noel Grandin 🐛 |
 Olaf Haalstra 🐛 |
+  Oleg Andreych 💻 |
 Oleg Pavlenko 🐛 |
 Oleksii Dykov 💻 |
-  Oliver Eikemeier 🐛 |
-  Olivier Parent 💻 🐛 |
+  Oliver Eikemeier 🐛 |
+  Oliver Siegmar 💵 |
+  Olivier Parent 💻 🐛 |
 Ollie Abbey 💻 🐛 |
 OverDrone 🐛 |
 Ozan Gulle 💻 🐛 |
 PUNEET JAIN 🐛 |
+
+
 Parbati Bose 🐛 |
 Paul Berg 🐛 |
 Pavel Bludov 🐛 |
-
-
 Pavel Mička 🐛 |
 Pedro Nuno Santos 🐛 |
 Pedro Rijo 🐛 |
 Pelisse Romain 💻 📖 🐛 |
+
+
 Per Abich 💻 |
 Pete Davids 🐛 |
 Peter Bruin 🐛 |
-
-
 Peter Chittum 💻 🐛 |
 Peter Cudmore 🐛 |
 Peter Kasson 🐛 |
 Peter Kofler 🐛 |
+
+
 Peter Paul Bakker 💻 |
 Pham Hai Trung 🐛 |
 Philip Graf 💻 🐛 |
-
-
 Philip Hachey 🐛 |
 Philippe Ozil 🐛 |
 Phinehas Artemix 🐛 |
 Phokham Nonava 🐛 |
-  Piotr Szymański 🐛 |
-  Piotrek Żygieło 💻 🐛 |
-  Pranay Jaiswal 🐛 |
+  Piotr Szymański 🐛 |
+  Piotrek Żygieło 💻 🐛 📖 |
+  Pranay Jaiswal 🐛 |
 Prasad Kamath 🐛 |
 Prasanna 🐛 |
 Presh-AR 🐛 |
 Puneet1726 🐛 |
+
+
 Rafael Cortês 🐛 |
 RaheemShaik999 🐛 |
 RajeshR 💻 🐛 |
-
-
 Ramachandra Mohan 🐛 |
 Ramel0921 🐛 |
 Raquel Pau 🐛 |
 Ravikiran Janardhana 🐛 |
+
+
 Reda Benhemmouche 🐛 |
 Renato Oliveira 💻 🐛 |
 Rich DiCroce 🐛 |
-
-
 Riot R1cket 🐛 |
 Rishabh Jain 🐛 |
 RishabhDeep Singh 🐛 |
 Robbie Martinus 💻 🐛 |
+
+
 Robert Henry 🐛 |
 Robert Painsi 🐛 |
 Robert Russell 🐛 |
-
-
 Robert Sösemann 💻 📖 📢 🐛 |
 Robert Whitebit 🐛 |
 Robin Richtsfeld 🐛 |
 Robin Stocker 💻 🐛 |
+
+
 Robin Wils 🐛 |
 RochusOest 🐛 |
 Rodolfo Noviski 🐛 |
-
-
 Rodrigo Casara 🐛 |
 Rodrigo Fernandes 🐛 |
 Roman Salvador 💻 🐛 |
 Ronald Blaschke 🐛 |
+
+
 Róbert Papp 🐛 |
 Saikat Sengupta 🐛 |
 Saksham Handu 🐛 |
-
-
 Saladoc 🐛 |
 Salesforce Bob Lightning 🐛 |
 Sam Carlberg 🐛 |
 Satoshi Kubo 🐛 |
+
+
 Scott Kennedy 🐛 |
 Scott Wells 🐛 💻 |
 Scrsloota 💻 |
-
-
 Sebastian Bögl 🐛 |
 Sebastian Schuberth 🐛 |
 Sebastian Schwarz 🐛 |
 Sergey Gorbaty 🐛 |
+
+
 Sergey Kozlov 🐛 |
 Sergey Yanzin 💻 🐛 |
 Seth Wilcox 💻 |
-
-
 Shubham 💻 🐛 |
 Simon Abykov 💻 |
 Simon Xiao 🐛 |
 Srinivasan Venkatachalam 🐛 |
+
+
 Stanislav Gromov 🐛 |
 Stanislav Myachenkov 💻 |
 Stefan Birkner 🐛 |
-
-
 Stefan Bohn 🐛 |
 Stefan Endrullis 🐛 |
 Stefan Klöss-Schuster 🐛 |
 Stefan Wolf 🐛 |
+
+
 Stephan H. Wissel 🐛 |
 Stephen 🐛 |
 Stephen Friedrich 🐛 |
-
-
 Steve Babula 💻 |
 Stexxe 🐛 |
 Stian Lågstad 🐛 |
 StuartClayton5 🐛 |
-  Supun Arunoda 🐛 |
-  Suren Abrahamyan 🐛 |
-  SwatiBGupta1110 🐛 |
+  Supun Arunoda 🐛 |
+  Suren Abrahamyan 🐛 |
+  Suvashri 📖 |
+  SwatiBGupta1110 🐛 |
 SyedThoufich 🐛 |
 Szymon Sasin 🐛 |
 T-chuangxin 🐛 |
+
+
 TERAI Atsuhiro 🐛 |
 TIOBE Software 💻 🐛 |
 Taylor Smock 🐛 |
 Techeira Damián 💻 🐛 |
-
-
 Ted Husted 🐛 |
 TehBakker 🐛 |
 The Gitter Badger 🐛 |
+
+
 Theodoor 🐛 |
 Thiago Henrique Hüpner 🐛 |
 Thibault Meyer 🐛 |
 Thomas Güttler 🐛 |
-
-
 Thomas Jones-Low 🐛 |
 Thomas Smith 💻 🐛 |
 ThrawnCA 🐛 |
+
+
 Thunderforge 💻 🐛 |
 Tim van der Lippe 🐛 |
 Tobias Weimer 💻 🐛 |
 Tom Daly 🐛 |
-
-
 Tomer Figenblat 🐛 |
 Tomi De Lucca 💻 🐛 |
 Torsten Kleiber 🐛 |
+
+
 TrackerSB 🐛 |
 Ullrich Hafner 🐛 |
 Utku Cuhadaroglu 💻 🐛 |
 Valentin Brandl 🐛 |
-
-
 Valeria 🐛 |
 Vasily Anisimov 🐛 |
 Vibhor Goyal 🐛 |
+
+
 Vickenty Fesunov 🐛 |
 Victor Noël 🐛 |
 Vincent Galloy 💻 |
 Vincent HUYNH 🐛 |
-
-
 Vincent Maurin 🐛 |
 Vincent Privat 🐛 |
 Vishhwas 🐛 |
+
+
 Vitaly 🐛 |
 Vitaly Polonetsky 🐛 |
 Vojtech Polivka 🐛 |
 Vsevolod Zholobov 🐛 |
-
-
 Vyom Yadav 💻 |
 Wang Shidong 🐛 |
 Waqas Ahmed 🐛 |
+
+
 Wayne J. Earl 🐛 |
 Wchenghui 🐛 |
 Will Winder 🐛 |
 William Brockhus 💻 🐛 |
-
-
 Wilson Kurniawan 🐛 |
 Wim Deblauwe 🐛 |
 Woongsik Choi 🐛 |
+
+
 XenoAmess 💻 🐛 |
 Yang 💻 |
 YaroslavTER 🐛 |
 Young Chan 💻 🐛 |
-
-
 YuJin Kim 🐛 |
 Yuri Dolzhenko 🐛 |
 Yurii Dubinka 🐛 |
+
+
 Zoltan Farkas 🐛 |
 Zustin 🐛 |
 aaronhurst-google 🐛 💻 |
 alexmodis 🐛 |
-
-
 andreoss 🐛 |
 andrey81inmd 💻 🐛 |
 anicoara 🐛 |
+
+
 arunprasathav 🐛 |
 asiercamara 🐛 |
 astillich-igniti 💻 |
 avesolovksyy 🐛 |
-
-
 avishvat 🐛 |
 avivmu 🐛 |
 axelbarfod1 🐛 |
+
+
 b-3-n 🐛 |
 balbhadra9 🐛 |
 base23de 🐛 |
 bergander 🐛 |
-
-
 berkam 💻 🐛 |
 breizh31 🐛 |
 caesarkim 🐛 |
+
+
 carolyujing 🐛 |
 cesares-basilico 🐛 |
 chrite 🐛 |
 cobratbq 🐛 |
-
-
 coladict 🐛 |
 cosmoJFH 🐛 |
 cristalp 🐛 |
+
+
 crunsk 🐛 |
 cwholmes 🐛 |
 cyberjj999 🐛 |
 cyw3 🐛 |
-
-
 d1ss0nanz 🐛 |
 dalizi007 💻 |
 danbrycefairsailcom 🐛 |
+
+
 dariansanity 🐛 |
 darrenmiliband 🐛 |
 davidburstrom 🐛 |
 dbirkman-paloalto 🐛 |
-
-
 deepak-patra 🐛 |
 dependabot[bot] 💻 🐛 |
 dinesh150 🐛 |
+
+
 diziaq 🐛 |
 dreaminpast123 🐛 |
 duanyanan 🐛 |
 dutt-sanjay 🐛 |
-
-
 dylanleung 🐛 |
 dzeigler 🐛 |
 ekkirala 🐛 |
+
+
 emersonmoura 🐛 |
 fairy 🐛 |
 filiprafalowicz 💻 |
 foxmason 🐛 |
-
-
 frankegabor 🐛 |
 frankl 🐛 |
 freafrea 🐛 |
+
+
 fsapatin 🐛 |
 gracia19 🐛 |
 guo fei 🐛 |
 gurmsc5 🐛 |
-
-
 gwilymatgearset 💻 🐛 |
 haigsn 🐛 |
 hemanshu070 🐛 |
+
+
 henrik242 🐛 |
 hongpuwu 🐛 |
 hvbtup 💻 🐛 |
 igniti GmbH 🐛 |
-
-
 ilovezfs 🐛 |
 itaigilo 🐛 |
 jakivey32 🐛 |
+
+
 jbennett2091 🐛 |
 jcamerin 🐛 |
 jkeener1 🐛 |
 jmetertea 🐛 |
-
-
 johnra2 💻 |
 josemanuelrolon 💻 🐛 |
 kabroxiko 💻 🐛 |
+
+
 karwer 🐛 |
 kaulonline 🐛 |
 kdaemonv 🐛 |
 kenji21 💻 🐛 |
-
-
 kfranic 🐛 |
 khalidkh 🐛 |
 krzyk 🐛 |
+
+
 lasselindqvist 🐛 |
 lgemeinhardt 🐛 |
 lihuaib 🐛 |
 lonelyma1021 🐛 |
-
-
 lpeddy 🐛 |
 lujiefsi 💻 |
 lukelukes 💻 |
+
+
 lyriccoder 🐛 |
 marcelmore 🐛 |
 matchbox 🐛 |
 matthiaskraaz 🐛 |
-
-
 meandonlyme 🐛 |
 mikesive 🐛 |
 milossesic 🐛 |
+
+
+  mohan-chinnappan-n 💻 |
 mriddell95 🐛 |
 mrlzh 🐛 |
 msloan 🐛 |
 mucharlaravalika 🐛 |
-
-
 mvenneman 🐛 |
 nareshl119 🐛 |
+
+
 nicolas-harraudeau-sonarsource 🐛 |
 noerremark 🐛 |
 novsirion 🐛 |
 oggboy 🐛 |
 oinume 🐛 |
-
-
 orimarko 💻 🐛 |
 pacvz 💻 |
+
+
 pallavi agarwal 🐛 |
 parksungrin 🐛 |
 patpatpat123 🐛 |
 patriksevallius 🐛 |
 pbrajesh1 🐛 |
-
-
 phoenix384 🐛 |
 piotrszymanski-sc 💻 |
+
+
 plan3d 🐛 |
 poojasix 🐛 |
 prabhushrikant 🐛 |
 pujitha8783 🐛 |
 r-r-a-j 🐛 |
-
-
 raghujayjunk 🐛 |
 rajeshveera 🐛 |
+
+
 rajeswarreddy88 🐛 |
 recdevs 🐛 |
 reudismam 💻 🐛 |
 rijkt 🐛 |
 rillig-tk 🐛 |
-
-
 rmohan20 💻 🐛 |
 rxmicro 🐛 |
+
+
 ryan-gustafson 💻 🐛 |
 sabi0 🐛 |
 scais 🐛 |
 sebbASF 🐛 |
 sergeygorbaty 💻 |
-
-
 shilko2013 🐛 |
 shiomiyan 📖 |
+
+
 simeonKondr 🐛 |
 snajberk 🐛 |
 sniperrifle2004 🐛 |
 snuyanzin 🐛 💻 |
 sratz 🐛 |
-
-
 stonio 🐛 |
 sturton 💻 🐛 |
+
+
 sudharmohan 🐛 |
 suruchidawar 🐛 |
 svenfinitiv 🐛 |
 tashiscool 🐛 |
 test-git-hook 🐛 |
-
-
 testation21 💻 🐛 |
 thanosa 🐛 |
+
+
 tiandiyixian 🐛 |
 tobwoerk 🐛 |
 tprouvot 🐛 💻 |
 trentchilders 🐛 |
 triandicAnt 🐛 |
-
-
 trishul14 🐛 |
 tsui 🐛 |
+
+
 winhkey 🐛 |
 witherspore 🐛 |
 wjljack 🐛 |
 wuchiuwong 🐛 |
 xingsong 🐛 |
-
-
 xioayuge 🐛 |
 xnYi9wRezm 💻 🐛 |
+
+
 xuanuy 🐛 |
 xyf0921 🐛 |
 yalechen-cyw3 🐛 |
 yasuharu-sato 🐛 |
 zenglian 🐛 |
-
-
 zgrzyt93 💻 🐛 |
 zh3ng 🐛 |
+
+
 zt_soft 🐛 |
 ztt79 🐛 |
 zzzzfeng 🐛 |
 Árpád Magosányi 🐛 |
 任贵杰 🐛 |
-
-
 茅延安 💻 |
diff --git a/docs/pages/pmd/projectdocs/trivia/news.md b/docs/pages/pmd/projectdocs/trivia/news.md
index 8fb06bbd4c..2cf8db566d 100644
--- a/docs/pages/pmd/projectdocs/trivia/news.md
+++ b/docs/pages/pmd/projectdocs/trivia/news.md
@@ -9,26 +9,43 @@ author: Tom Copeland
### 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).
diff --git a/docs/pages/pmd/userdocs/3rdpartyrulesets.md b/docs/pages/pmd/userdocs/3rdpartyrulesets.md
new file mode 100644
index 0000000000..ecbfee2818
--- /dev/null
+++ b/docs/pages/pmd/userdocs/3rdpartyrulesets.md
@@ -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.
+ *
+* **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.
+ *
+* Sample ruleset from **maxdocs**, a multi markup wiki engine.
+ *
+* Sample ruleset from **geotools**, an open source Java library that provides tools for geospatial data.
+ *
+ *
+
+
+## For Apex
+* **unhappy-soup**, a repository with problematic Salesforce code to showcase PMD, the SFDX Scanner CLI
+ *
+
diff --git a/docs/pages/pmd/userdocs/cpd/cpd.md b/docs/pages/pmd/userdocs/cpd/cpd.md
index 67b81492be..22d594259b 100644
--- a/docs/pages/pmd/userdocs/cpd/cpd.md
+++ b/docs/pages/pmd/userdocs/cpd/cpd.md
@@ -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"
diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md
index b8f8783555..2da44b2235 100644
--- a/docs/pages/release_notes.md
+++ b/docs/pages/release_notes.md
@@ -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 %}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/treeexport/TreeExportCli.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/treeexport/TreeExportCli.java
index cd7c7c7e99..5ad05cb9da 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/util/treeexport/TreeExportCli.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/treeexport/TreeExportCli.java
@@ -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);
diff --git a/pmd-dist/src/main/resources/scripts/designer.bat b/pmd-dist/src/main/resources/scripts/designer.bat
index bc3cbb9188..a53623c28c 100644
--- a/pmd-dist/src/main/resources/scripts/designer.bat
+++ b/pmd-dist/src/main/resources/scripts/designer.bat
@@ -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
diff --git a/pmd-dist/src/main/resources/scripts/run.sh b/pmd-dist/src/main/resources/scripts/run.sh
index 1501db12bc..ece76fc949 100755
--- a/pmd-dist/src/main/resources/scripts/run.sh
+++ b/pmd-dist/src/main/resources/scripts/run.sh
@@ -2,7 +2,7 @@
usage() {
echo "Usage:"
- echo " $(basename $0) [-h|-v] ..."
+ echo " $(basename "$0") [-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
diff --git a/pmd-dist/src/test/resources/scripts/designertest.bat b/pmd-dist/src/test/resources/scripts/designertest.bat
new file mode 100644
index 0000000000..d43a5ff146
--- /dev/null
+++ b/pmd-dist/src/test/resources/scripts/designertest.bat
@@ -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"
diff --git a/pmd-dist/src/test/resources/scripts/runtest.sh b/pmd-dist/src/test/resources/scripts/runtest.sh
new file mode 100755
index 0000000000..34185ddb1c
--- /dev/null
+++ b/pmd-dist/src/test/resources/scripts/runtest.sh
@@ -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"
diff --git a/pmd-html/pom.xml b/pmd-html/pom.xml
index bbd5c0a746..cab9828d2d 100644
--- a/pmd-html/pom.xml
+++ b/pmd-html/pom.xml
@@ -31,7 +31,7 @@
org.jsoup
jsoup
- 1.14.3
+ 1.15.3
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierRule.java
index 2891b13843..f6f9fb0fbc 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierRule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/CommentDefaultAccessModifierRule.java
@@ -57,6 +57,15 @@ public class CommentDefaultAccessModifierRule extends AbstractIgnoredAnnotationR
Collection 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;
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java
index 32bf8fa21c..8091d944e3 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java
@@ -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 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 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 qualifiedTypes = node.getScope().getEnclosingScope(SourceFileScope.class)
- .getQualifiedTypeNames().keySet();
+ .getQualifiedTypeNames().keySet();
for (final String qualified : qualifiedTypes) {
int fullLength = qualified.length();
if (qualified.endsWith(unqualifiedName)
diff --git a/pmd-java/src/main/resources/category/java/bestpractices.xml b/pmd-java/src/main/resources/category/java/bestpractices.xml
index e865f684e4..122b0e4dc7 100644
--- a/pmd-java/src/main/resources/category/java/bestpractices.xml
+++ b/pmd-java/src/main/resources/category/java/bestpractices.xml
@@ -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.
3
diff --git a/pmd-java/src/main/resources/category/java/codestyle.xml b/pmd-java/src/main/resources/category/java/codestyle.xml
index f9770a891b..ec8f37cc46 100644
--- a/pmd-java/src/main/resources/category/java/codestyle.xml
+++ b/pmd-java/src/main/resources/category/java/codestyle.xml
@@ -436,9 +436,10 @@ public class Éléphant {}
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#commentdefaultaccessmodifier">
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.
3
diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml
index edeecae3fd..0146f66ff0 100644
--- a/pmd-java/src/main/resources/category/java/design.xml
+++ b/pmd-java/src/main/resources/category/java/design.xml
@@ -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">
-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.
@@ -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">
-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.
3
@@ -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)]
]]>
diff --git a/pmd-java/src/main/resources/category/java/performance.xml b/pmd-java/src/main/resources/category/java/performance.xml
index d211ac31b4..84a7da762d 100644
--- a/pmd-java/src/main/resources/category/java/performance.xml
+++ b/pmd-java/src/main/resources/category/java/performance.xml
@@ -844,8 +844,8 @@ private String baz() {
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#toofewbranchesforaswitchstatement">
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.
3
diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml
index 00d81cfa78..3b3c76f2d8 100755
--- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml
+++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/CommentDefaultAccessModifier.xml
@@ -381,6 +381,20 @@ public interface MyInterface {
public enum MyEnum {
FOO;
class MyNestedClass {}
+}
+ ]]>
+
+
+
+ #3859 [java] CommentDefaultAccessModifier is triggered in JUnit5 method and it was conflicting with rule JUnit5TestShouldBePackagePrivate
+ 0
+
diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml
index f95d7bc81e..097e096767 100644
--- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml
+++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml
@@ -622,6 +622,40 @@ public class UnnecessaryFullyQualifiedName {
]]>
+
+ False positive when same package inner class is referenced (not enum) #4085
+ 0
+
+
+
+
+ Should report fully-qualified name usage of a class in itself #4085
+ 1
+ 4
+
+
+
#2098 false positive with annotated package
0
diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/FinalFieldCouldBeStatic.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/FinalFieldCouldBeStatic.xml
index e5f41598a0..4ed2aed5c1 100644
--- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/FinalFieldCouldBeStatic.xml
+++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/FinalFieldCouldBeStatic.xml
@@ -231,4 +231,34 @@ public class Foo {
}
]]>
+
+
+ [java] FinalFieldCouldBeStatic false positive with non-static synchronized block (regression in 6.48, worked with 6.47) #4090
+ 1
+ 4
+
+
diff --git a/pmd-lua/src/main/antlr4/net/sourceforge/pmd/lang/lua/antlr4/Lua.g4 b/pmd-lua/src/main/antlr4/net/sourceforge/pmd/lang/lua/antlr4/Lua.g4
index 59c0b86a60..fde74727ac 100644
--- a/pmd-lua/src/main/antlr4/net/sourceforge/pmd/lang/lua/antlr4/Lua.g4
+++ b/pmd-lua/src/main/antlr4/net/sourceforge/pmd/lang/lua/antlr4/Lua.g4
@@ -62,6 +62,7 @@ Tested by Matt Hargett with:
- Entire codebase and test suite for neovim v0.7.2: https://github.com/neovim/neovim/tree/v0.7.2
- Entire codebase for World of Warcraft Interface: https://github.com/tomrus88/BlizzardInterfaceCode
- Benchmarks and conformance test suite for Luau 0.537: https://github.com/Roblox/luau/tree/0.537
+ - Entire Lua codebase for nmap 7.92 : https://github.com/nmap/nmap
*/
grammar Lua;
@@ -71,12 +72,13 @@ chunk
;
block
- : stat* laststat?
+ : (stat ';'?)* (laststat ';'?)?
;
stat
: ';'
- | varlist '=' explist
+ | varlist ASSIGNMENT explist
+ | var compoundop exp
| functioncall
| label
| 'break'
@@ -85,11 +87,12 @@ stat
| 'while' exp 'do' block 'end'
| 'repeat' block 'until' exp
| 'if' exp 'then' block ('elseif' exp 'then' block)* ('else' block)? 'end'
- | 'for' NAME '=' exp ',' exp (',' exp)? 'do' block 'end'
- | 'for' namelist 'in' explist 'do' block 'end'
+ | 'for' binding ASSIGNMENT exp ',' exp (',' exp)? 'do' block 'end'
+ | 'for' bindinglist 'in' explist 'do' block 'end'
| 'function' funcname funcbody
- | 'local' 'function' NAME funcbody
- | 'local' attnamelist ('=' explist)?
+ | LOCAL 'function' NAME funcbody
+ | LOCAL bindinglist (ASSIGNMENT explist)?
+ | ('export')? 'type' NAME ('<' genericTypeParameterList '>')? '=' type
;
attnamelist
@@ -100,47 +103,50 @@ attrib
: ('<' NAME '>')?
;
-laststat
- : 'return' explist? | 'break' | 'continue' ';'?
- ;
-
label
: '::' NAME '::'
;
+laststat
+ // "continue" is a luau addition and actually not a reserved keyword
+ : 'return' explist? | 'break' | 'continue'
+ ;
+
funcname
: NAME ('.' NAME)* (':' NAME)?
;
-varlist
- : var (',' var)*
+funcbody
+ : ('<' genericTypeParameterList '>')? OPEN_PARENS parlist? CLOSE_PARENS (':' '...'? returnType ) block 'end'
;
-namelist
- : NAME (',' NAME)*
+parlist
+ : bindinglist (',' '...')?
+ | '...'
;
explist
: (exp ',')* exp
;
-exp
- : 'nil' | 'false' | 'true'
- | number
- | string
- | '...'
- | functiondef
- | prefixexp
- | tableconstructor
- | exp operatorPower exp
- | operatorUnary exp
- | exp operatorMulDivMod exp
- | exp operatorAddSub exp
- | exp operatorStrcat exp
- | exp operatorComparison exp
- | exp operatorAnd exp
- | exp operatorOr exp
- | exp operatorBitwise exp
+namelist
+ : NAME (',' NAME)*
+ ;
+
+binding
+ : NAME (':' type ('?')?)?
+ ;
+
+bindinglist
+ : binding (',' bindinglist)?
+ ;
+
+var
+ : (NAME | OPEN_PARENS exp CLOSE_PARENS varSuffix) varSuffix*
+ ;
+
+varlist
+ : var (',' var)*
;
prefixexp
@@ -151,16 +157,35 @@ functioncall
: varOrExp nameAndArgs+
;
-varOrExp
- : var | '(' exp ')'
+exp
+ : (asexp | operatorUnary exp) ( binop exp )*
;
-var
- : (NAME | '(' exp ')' varSuffix) varSuffix*
+ifelseexp
+ : 'if' exp 'then' exp ('elseif' exp 'then' exp)* 'else' exp
+ ;
+
+asexp
+ : simpleexp ('::' type)?
+ ;
+
+simpleexp
+ : NIL | BOOLEAN
+ | number
+ | string
+ | '...'
+ | 'function' funcbody
+ | prefixexp
+ | ifelseexp
+ | tableconstructor;
+
+varOrExp
+ : var
+ | OPEN_PARENS exp CLOSE_PARENS
;
varSuffix
- : nameAndArgs* ('[' exp ']' | '.' NAME)
+ : nameAndArgs* (OPEN_BRACKET exp CLOSE_BRACKET | '.' NAME)
;
nameAndArgs
@@ -168,23 +193,17 @@ nameAndArgs
;
args
- : '(' explist? ')' | tableconstructor | string
+ : OPEN_PARENS explist? CLOSE_PARENS
+ | tableconstructor
+ | string
;
functiondef
: 'function' funcbody
;
-funcbody
- : '(' parlist? ')' block 'end'
- ;
-
-parlist
- : namelist (',' '...')? | '...'
- ;
-
tableconstructor
- : '{' fieldlist? '}'
+ : OPEN_BRACE fieldlist? CLOSE_BRACE
;
fieldlist
@@ -192,13 +211,35 @@ fieldlist
;
field
- : '[' exp ']' '=' exp | NAME '=' exp | exp
+ : OPEN_BRACKET exp CLOSE_BRACKET ASSIGNMENT exp
+ | NAME ASSIGNMENT exp
+ | exp
;
fieldsep
- : ',' | ';'
+ : ','
+ | ';'
;
+compoundop
+ : '+='
+ | '-='
+
+ | '*='
+ | '/='
+ | '%='
+ | '^='
+ | '..=';
+
+binop: operatorAddSub
+ | operatorMulDivMod
+ | operatorPower
+ | operatorStrcat
+ | operatorComparison
+ | operatorAnd
+ | operatorOr
+ | operatorBitwise;
+
operatorOr
: 'or';
@@ -206,56 +247,183 @@ operatorAnd
: 'and';
operatorComparison
- : '<' | '>' | '<=' | '>=' | '~=' | '==';
+ : '<'
+ | '>'
+ | '<='
+ | '>='
+ | '~='
+ | '=='
+ ;
+
+ASSIGNMENT
+ : '='
+ ;
operatorStrcat
: '..';
operatorAddSub
- : '+' | '-';
+ : '+'
+ | '-'
+ ;
operatorMulDivMod
- : '*' | '/' | '%' | '//';
+ : '*'
+ | '/'
+ | '%'
+ | '//'
+ ;
operatorBitwise
- : '&' | '|' | '~' | '<<' | '>>';
+ : '&'
+ | '|'
+ | '~'
+ | '<<'
+ | '>>'
+ ;
operatorUnary
- : 'not' | '#' | '-' | '~';
+ : 'not'
+ | '#'
+ | '-'
+ | '~'
+ ;
operatorPower
: '^';
number
- : INT | HEX | FLOAT | HEX_FLOAT
+ : INT
+ | HEX
+ | FLOAT
+ | HEX_FLOAT
;
string
- : NORMALSTRING | CHARSTRING | LONGSTRING
+ : NORMAL_STRING
+ | LONG_STRING
+ | INTERPOLATED_STRING
+ ;
+
+simpleType
+ : NIL
+ | singletonType
+ | NAME ('.' NAME)? ('<' typeParams '>')?
+ | 'typeof' OPEN_PARENS exp CLOSE_PARENS
+ | tableType
+ | functionType
+ ;
+
+singletonType
+ : NORMAL_STRING
+ | BOOLEAN
+ ;
+
+type
+ : simpleType ('?')?
+ | type ('|' type)
+ | type ('&' type)
+ ;
+
+genericTypePackParameter
+ : NAME '...' ('=' (typePack | variadicTypePack | genericTypePack))?
+ ;
+
+genericTypeParameterList
+ : NAME ('=' type)? (',' genericTypeParameterList)?
+ | genericTypePackParameter (',' genericTypePackParameter)*
+ ;
+
+typeList
+ : type (',' typeList)? | variadicTypePack
+ ;
+
+typeParams
+ : (type | typePack | variadicTypePack | genericTypePack) (',' typeParams)?
+ ;
+
+typePack
+ : OPEN_PARENS (typeList)? CLOSE_PARENS
+ ;
+
+genericTypePack
+ : NAME '...'
+ ;
+
+variadicTypePack
+ : '...' type
+ ;
+
+returnType
+ : type
+ | typePack
+ ;
+
+tableIndexer
+ : OPEN_BRACKET type CLOSE_BRACKET ':' type
+ ;
+
+tableProp
+ : NAME ':' type
+ ;
+
+tablePropOrIndexer
+ : tableProp
+ | tableIndexer
+ ;
+
+propList
+ : tablePropOrIndexer (fieldsep tablePropOrIndexer)* fieldsep?
+ ;
+
+tableType
+ : OPEN_BRACE propList CLOSE_BRACE
+ ;
+
+functionType
+ : ('<' genericTypeParameterList '>')? OPEN_PARENS (typeList)? CLOSE_PARENS '->' returnType
;
// LEXER
+LOCAL
+ : 'local'
+ ;
+
+REQUIRE
+ : 'require'
+ ;
+
+NIL
+ : 'nil'
+ ;
+
+BOOLEAN
+ : 'true'
+ | 'false'
+ ;
+
NAME
: [a-zA-Z_][a-zA-Z_0-9]*
;
-NORMALSTRING
- : '"' ( EscapeSequence | ~('\\'|'"') )* '"'
+NORMAL_STRING
+ : '"' (~["\\\r\n\u0085\u2028\u2029] | EscapeSequence | '\\\n')* '"'
+ | '\'' (~['\\\r\n\u0085\u2028\u2029] | EscapeSequence | '\\\n')* '\''
;
-CHARSTRING
- : '\'' ( EscapeSequence | ~('\''|'\\') )* '\''
+INTERPOLATED_STRING
+ : '`' (~[`\\\r\n\u0085\u2028\u2029] | EscapeSequence | '\\\n')* '`'
;
-LONGSTRING
- : '[' NESTED_STR ']'
+LONG_STRING
+ : OPEN_BRACKET NESTED_STR CLOSE_BRACKET
;
fragment
NESTED_STR
: '=' NESTED_STR '='
- | '[' .*? ']'
+ | OPEN_BRACKET .*? CLOSE_BRACKET
;
INT
@@ -278,6 +446,40 @@ HEX_FLOAT
| '0' [xX] HexDigit+ HexExponentPart
;
+OPEN_BRACE
+ : '{'
+ ;
+
+CLOSE_BRACE
+ : '}'
+ ;
+
+OPEN_BRACKET
+ : '['
+ ;
+CLOSE_BRACKET
+ : ']'
+ ;
+
+OPEN_PARENS:
+ '('
+ ;
+
+CLOSE_PARENS
+ : ')'
+ ;
+
+NL
+ : '\r\n' | '\r' | '\n'
+ | '\u0085' // '
+ | '\u2028' //''
+ | '\u2029' //''
+ ;
+
+COMMA
+ : ','
+ ;
+
fragment
ExponentPart
: [eE] [+-]? Digit+
@@ -290,8 +492,8 @@ HexExponentPart
fragment
EscapeSequence
- : '\\' [abfnrtvz"'|$#\\] // World of Warcraft Lua additionally escapes |$#
- | '\\' '\r'? '\n'
+ : '\\' [abfnrtvz"'`|$#\\] // World of Warcraft Lua additionally escapes |$#
+ | NL
| DecimalEscape
| HexEscape
| UtfEscape
@@ -324,6 +526,11 @@ HexDigit
: [0-9a-fA-F]
;
+fragment
+StartingSingleCommentLineInputCharacter
+ : ~[[\r\n\u0085\u2028\u2029]
+ ;
+
fragment
SingleLineInputCharacter
: ~[\r\n\u0085\u2028\u2029]
@@ -334,11 +541,11 @@ COMMENT
;
LINE_COMMENT
- : '--' SingleLineInputCharacter* -> channel(HIDDEN)
+ : '--' (NL | StartingSingleCommentLineInputCharacter SingleLineInputCharacter*) -> channel(HIDDEN)
;
WS
- : [ \t\u000C\r\n]+ -> skip
+ : [ \n\r\t\u000B\u000C\u0000]+ -> channel(HIDDEN)
;
SHEBANG
diff --git a/pmd-lua/src/main/java/net/sourceforge/pmd/cpd/LuaLanguage.java b/pmd-lua/src/main/java/net/sourceforge/pmd/cpd/LuaLanguage.java
index e2a87ec878..2e485e13b8 100644
--- a/pmd-lua/src/main/java/net/sourceforge/pmd/cpd/LuaLanguage.java
+++ b/pmd-lua/src/main/java/net/sourceforge/pmd/cpd/LuaLanguage.java
@@ -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);
}
}
diff --git a/pmd-lua/src/main/java/net/sourceforge/pmd/cpd/LuaTokenizer.java b/pmd-lua/src/main/java/net/sourceforge/pmd/cpd/LuaTokenizer.java
index 23c292dbe7..328c5e8ab0 100644
--- a/pmd-lua/src/main/java/net/sourceforge/pmd/cpd/LuaTokenizer.java
+++ b/pmd-lua/src/main/java/net/sourceforge/pmd/cpd/LuaTokenizer.java
@@ -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.
+ *
+ * By default, it discards semicolons, require statements, and
+ * enables annotation-based CPD suppression.
+ *
+ */
+ 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 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 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 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;
+ }
}
}
diff --git a/pmd-lua/src/test/java/net/sourceforge/pmd/cpd/LuaTokenizerTest.java b/pmd-lua/src/test/java/net/sourceforge/pmd/cpd/LuaTokenizerTest.java
index 76d18a3ffa..9c8705d4b4 100644
--- a/pmd-lua/src/test/java/net/sourceforge/pmd/cpd/LuaTokenizerTest.java
+++ b/pmd-lua/src/test/java/net/sourceforge/pmd/cpd/LuaTokenizerTest.java
@@ -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");
+ }
}
diff --git a/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/comment.lua b/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/comment.lua
new file mode 100644
index 0000000000..d79dc5db81
--- /dev/null
+++ b/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/comment.lua
@@ -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) --
diff --git a/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/comment.txt b/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/comment.txt
new file mode 100644
index 0000000000..f6f1fd25fd
--- /dev/null
+++ b/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/comment.txt
@@ -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
diff --git a/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/luauTypes.lua b/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/luauTypes.lua
new file mode 100644
index 0000000000..da4e9ddf80
--- /dev/null
+++ b/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/luauTypes.lua
@@ -0,0 +1,34 @@
+--!strict
+type Array = { T }
+local x = 31337
+local _negativeLiteral = -3
+local _negativeVariable = -x
+local _notLiteral = not true
+local _notVariable = not x
+local _length = #{x}
+export type Function = (...any) -> T...
+local _PlatformService = nil
+local game = require(script.Parent.game).default :: any
+pcall(function() _PlatformService = game:GetService('PlatformService') end)
+
+return function (req, ...: boolean): ({[string|number]: T}, string, Function<...any>)
+ local body = string.format("%s %s\n", req.method, req.path)
+ local res = {
+ code = 200,
+ { "Content-Type", "text/plain" },
+ {
+ "Content-Length",
+ #body,
+ ["Auth.Confirm"] = [[至:%s。]],
+
+ } :: Array,
+ } :: { [any]: number | Array }
+ if (req :: any).keepAlive then
+ local socketType: "Connection" | "Pingback" | "" = "" :: ""
+ socketType = "Connection" :: "Connection"
+ res[#res + 1] = { socketType :: string, `\`${req.keepAlive}\`` }
+ res[#res - 2] = { ... }
+ end
+
+ return (res :: any) :: { T }, (if req then body else "") :: string, function(...): ...any return ... end
+end
\ No newline at end of file
diff --git a/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/luauTypes.txt b/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/luauTypes.txt
new file mode 100644
index 0000000000..f1a3934c53
--- /dev/null
+++ b/pmd-lua/src/test/resources/net/sourceforge/pmd/lang/lua/cpd/testdata/luauTypes.txt
@@ -0,0 +1,302 @@
+ [Image] or [Truncated image[ Bcol Ecol
+L2
+ [type] 1 4
+ [Array] 6 10
+ [<] 11 11
+ [T] 12 12
+ [=] 14 14
+ [any] 16 18
+ [>] 19 19
+ [=] 21 21
+ [{] 23 23
+ [T] 25 25
+ [}] 27 27
+L3
+ [local] 1 5
+ [x] 7 7
+ [=] 9 9
+ [31337] 11 15
+L4
+ [local] 1 5
+ [_negativeLiteral] 7 22
+ [=] 24 24
+ [-] 26 26
+ [3] 27 27
+L5
+ [local] 1 5
+ [_negativeVariable] 7 23
+ [=] 25 25
+ [-] 27 27
+ [x] 28 28
+L6
+ [local] 1 5
+ [_notLiteral] 7 17
+ [=] 19 19
+ [not] 21 23
+ [true] 25 28
+L7
+ [local] 1 5
+ [_notVariable] 7 18
+ [=] 20 20
+ [not] 22 24
+ [x] 26 26
+L8
+ [local] 1 5
+ [_length] 7 13
+ [=] 15 15
+ [#] 17 17
+ [{] 18 18
+ [x] 19 19
+ [}] 20 20
+L9
+ [export] 1 6
+ [type] 8 11
+ [Function] 13 20
+ [<] 21 21
+ [T] 22 22
+ [...] 23 25
+ [=] 27 27
+ [...] 29 31
+ [any] 32 34
+ [>] 35 35
+ [=] 37 37
+ [(] 39 39
+ [...] 40 42
+ [any] 43 45
+ [)] 46 46
+ [->] 48 49
+ [T] 51 51
+ [...] 52 54
+L10
+ [local] 1 5
+ [_PlatformService] 7 22
+ [=] 24 24
+ [nil] 26 28
+L11
+ [local] 1 5
+ [game] 7 10
+ [=] 12 12
+ [.] 41 41
+ [default] 42 48
+ [::] 50 51
+ [any] 53 55
+L12
+ [pcall] 1 5
+ [(] 6 6
+ [function] 7 14
+ [(] 15 15
+ [)] 16 16
+ [_PlatformService] 18 33
+ [=] 35 35
+ [game] 37 40
+ [:] 41 41
+ [GetService] 42 51
+ [(] 52 52
+ ['PlatformService'] 53 69
+ [)] 70 70
+ [end] 72 74
+ [)] 75 75
+L14
+ [return] 1 6
+ [function] 8 15
+ [<] 17 17
+ [T] 18 18
+ [>] 19 19
+ [(] 20 20
+ [req] 21 23
+ [,] 24 24
+ [...] 26 28
+ [:] 29 29
+ [boolean] 31 37
+ [)] 38 38
+ [:] 39 39
+ [(] 41 41
+ [{] 42 42
+ [\[] 43 43
+ [string] 44 49
+ [|] 50 50
+ [number] 51 56
+ [\]] 57 57
+ [:] 58 58
+ [T] 60 60
+ [}] 61 61
+ [,] 62 62
+ [string] 64 69
+ [,] 70 70
+ [Function] 72 79
+ [<] 80 80
+ [...] 81 83
+ [any] 84 86
+ [>] 87 87
+ [)] 88 88
+L15
+ [local] 3 7
+ [body] 9 12
+ [=] 14 14
+ [string] 16 21
+ [.] 22 22
+ [format] 23 28
+ [(] 29 29
+ ["%s %s\\n"] 30 38
+ [,] 39 39
+ [req] 41 43
+ [.] 44 44
+ [method] 45 50
+ [,] 51 51
+ [req] 53 55
+ [.] 56 56
+ [path] 57 60
+ [)] 61 61
+L16
+ [local] 3 7
+ [res] 9 11
+ [=] 13 13
+ [{] 15 15
+L17
+ [code] 5 8
+ [=] 10 10
+ [200] 12 14
+ [,] 15 15
+L18
+ [{] 5 5
+ ["Content-Type"] 7 20
+ [,] 21 21
+ ["text/plain"] 23 34
+ [}] 36 36
+ [,] 37 37
+L19
+ [{] 5 5
+L20
+ ["Content-Length"] 7 22
+ [,] 23 23
+L21
+ [#] 7 7
+ [body] 8 11
+ [,] 12 12
+L22
+ [\[] 7 7
+ ["Auth.Confirm"] 8 21
+ [\]] 22 22
+ [=] 24 24
+ [\[\[至:%s。\]\]] 26 34
+ [,] 35 35
+L24
+ [}] 5 5
+ [::] 7 8
+ [Array] 10 14
+ [<] 15 15
+ [any] 16 18
+ [>] 19 19
+ [,] 20 20
+L25
+ [}] 3 3
+ [::] 5 6
+ [{] 8 8
+ [\[] 10 10
+ [any] 11 13
+ [\]] 14 14
+ [:] 15 15
+ [number] 17 22
+ [|] 24 24
+ [Array] 26 30
+ [<] 31 31
+ [string] 32 37
+ [|] 39 39
+ [boolean] 41 47
+ [>] 48 48
+ [}] 50 50
+L26
+ [if] 3 4
+ [(] 6 6
+ [req] 7 9
+ [::] 11 12
+ [any] 14 16
+ [)] 17 17
+ [.] 18 18
+ [keepAlive] 19 27
+ [then] 29 32
+L27
+ [local] 5 9
+ [socketType] 11 20
+ [:] 21 21
+ ["Connection"] 23 34
+ [|] 36 36
+ ["Pingback"] 38 47
+ [|] 49 49
+ [""] 51 52
+ [=] 54 54
+ [""] 56 57
+ [::] 59 60
+ [""] 62 63
+L28
+ [socketType] 5 14
+ [=] 16 16
+ ["Connection"] 18 29
+ [::] 31 32
+ ["Connection"] 34 45
+L29
+ [res] 5 7
+ [\[] 8 8
+ [#] 9 9
+ [res] 10 12
+ [+] 14 14
+ [1] 16 16
+ [\]] 17 17
+ [=] 19 19
+ [{] 21 21
+ [socketType] 23 32
+ [::] 34 35
+ [string] 37 42
+ [,] 43 43
+ [`\\`${req.keepAlive}\\``] 45 66
+ [}] 68 68
+L30
+ [res] 5 7
+ [\[] 8 8
+ [#] 9 9
+ [res] 10 12
+ [-] 14 14
+ [2] 16 16
+ [\]] 17 17
+ [=] 19 19
+ [{] 21 21
+ [...] 23 25
+ [}] 27 27
+L31
+ [end] 3 5
+L33
+ [return] 3 8
+ [(] 10 10
+ [res] 11 13
+ [::] 15 16
+ [any] 18 20
+ [)] 21 21
+ [::] 23 24
+ [{] 26 26
+ [T] 28 28
+ [}] 30 30
+ [,] 31 31
+ [(] 33 33
+ [if] 34 35
+ [req] 37 39
+ [then] 41 44
+ [body] 46 49
+ [else] 51 54
+ [""] 56 57
+ [)] 58 58
+ [::] 60 61
+ [string] 63 68
+ [,] 69 69
+ [function] 71 78
+ [(] 79 79
+ [...] 80 82
+ [)] 83 83
+ [:] 84 84
+ [...] 86 88
+ [any] 89 91
+ [return] 93 98
+ [...] 100 102
+ [end] 104 106
+L34
+ [end] 1 3
+EOF
diff --git a/pom.xml b/pom.xml
index 9036d17f18..569c34bfd1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -92,9 +92,9 @@
5.0
3.0.0-M5
- 9.3
- 3.1.2
- 3.18.0
+ 10.3.3
+ 3.2.0
+ 3.19.0
1.10.12
3.2.0
4.7.2
@@ -770,7 +770,7 @@
org.yaml
snakeyaml
- 1.30
+ 1.32