Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Clément Fournier
2021-01-08 21:41:29 +01:00
17 changed files with 174 additions and 63 deletions

View File

@ -45,7 +45,7 @@ There are various channels, on which you can ask questions:
* On [StackOverflow](https://stackoverflow.com/questions/tagged/pmd): Make sure, to tag your question with "pmd".
* Create a issue for your question at <https://github.com/pmd/pmd/issues>.
* Create a new discussion for your question at <https://github.com/pmd/pmd/discussions>.
* Ask your question on Gitter <https://gitter.im/pmd/pmd>.

View File

@ -34,18 +34,19 @@ GEM
fugit (1.4.1)
et-orbi (~> 1.1, >= 1.1.8)
raabro (~> 1.4)
git (1.7.0)
git (1.8.1)
rchardet (~> 1.8)
kramdown (1.17.0)
liquid (4.0.3)
liquid (5.0.0)
logger-colors (1.0.0)
mini_portile2 (2.4.0)
mini_portile2 (2.5.0)
multipart-post (2.1.1)
nap (1.1.0)
no_proxy_fix (0.1.2)
nokogiri (1.10.10)
mini_portile2 (~> 2.4.0)
octokit (4.19.0)
nokogiri (1.11.1)
mini_portile2 (~> 2.5.0)
racc (~> 1.4)
octokit (4.20.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
open4 (1.3.4)
@ -58,9 +59,10 @@ GEM
slop (~> 4.6)
public_suffix (4.0.6)
raabro (1.4.0)
racc (1.5.2)
rchardet (1.8.0)
rouge (3.25.0)
rufus-scheduler (3.6.0)
rouge (3.26.0)
rufus-scheduler (3.7.0)
fugit (~> 1.1, >= 1.1.6)
safe_yaml (1.0.5)
sawyer (0.8.2)
@ -69,7 +71,7 @@ GEM
slop (4.8.2)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
tzinfo (2.0.3)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
unicode-display_width (1.7.0)

View File

@ -20,10 +20,12 @@ Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex, Scala, Swift,
## Support
* How do I? -- Ask a question on [StackOverflow](https://stackoverflow.com/questions/tagged/pmd).
* I got this error, why? -- Ask a question on [StackOverflow](https://stackoverflow.com/questions/tagged/pmd).
* How do I? -- Ask a question on [StackOverflow](https://stackoverflow.com/questions/tagged/pmd)
or on [discussions](https://github.com/pmd/pmd/discussions).
* I got this error, why? -- Ask a question on [StackOverflow](https://stackoverflow.com/questions/tagged/pmd)
or on [discussions](https://github.com/pmd/pmd/discussions).
* I got this error and I'm sure it's a bug -- file an [issue](https://github.com/pmd/pmd/issues).
* I have an idea/request/question -- file an [issue](https://github.com/pmd/pmd/issues).
* I have an idea/request/question -- create a new [discussion](https://github.com/pmd/pmd/discussions).
* I have a quick question -- ask on our [Gitter chat](https://gitter.im/pmd/pmd).
* Where's your documentation? -- <https://pmd.github.io/latest/>

View File

@ -1,7 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (6.0.3.2)
activesupport (6.0.3.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
@ -17,37 +17,40 @@ GEM
commonmarker (0.17.13)
ruby-enum (~> 0.5)
concurrent-ruby (1.1.7)
dnsruby (1.61.4)
dnsruby (1.61.5)
simpleidn (~> 0.1)
em-websocket (0.5.1)
em-websocket (0.5.2)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0)
ethon (0.12.0)
ffi (>= 1.3.0)
eventmachine (1.2.7)
execjs (2.7.0)
faraday (1.0.1)
faraday (1.3.0)
faraday-net_http (~> 1.0)
multipart-post (>= 1.2, < 3)
ffi (1.13.1)
ruby2_keywords
faraday-net_http (1.0.0)
ffi (1.14.2)
forwardable-extended (2.6.0)
gemoji (3.0.1)
github-pages (207)
github-pages (209)
github-pages-health-check (= 1.16.1)
jekyll (= 3.9.0)
jekyll-avatar (= 0.7.0)
jekyll-coffeescript (= 1.1.1)
jekyll-commonmark-ghpages (= 0.1.6)
jekyll-default-layout (= 0.1.4)
jekyll-feed (= 0.13.0)
jekyll-feed (= 0.15.1)
jekyll-gist (= 1.5.0)
jekyll-github-metadata (= 2.13.0)
jekyll-mentions (= 1.5.1)
jekyll-mentions (= 1.6.0)
jekyll-optional-front-matter (= 0.3.2)
jekyll-paginate (= 1.1.0)
jekyll-readme-index (= 0.3.0)
jekyll-redirect-from (= 0.15.0)
jekyll-redirect-from (= 0.16.0)
jekyll-relative-links (= 0.6.1)
jekyll-remote-theme (= 0.4.1)
jekyll-remote-theme (= 0.4.2)
jekyll-sass-converter (= 1.5.2)
jekyll-seo-tag (= 2.6.1)
jekyll-sitemap (= 1.4.0)
@ -55,7 +58,7 @@ GEM
jekyll-theme-architect (= 0.1.1)
jekyll-theme-cayman (= 0.1.1)
jekyll-theme-dinky (= 0.1.1)
jekyll-theme-hacker (= 0.1.1)
jekyll-theme-hacker (= 0.1.2)
jekyll-theme-leap-day (= 0.1.1)
jekyll-theme-merlot (= 0.1.1)
jekyll-theme-midnight (= 0.1.1)
@ -66,14 +69,14 @@ GEM
jekyll-theme-tactile (= 0.1.1)
jekyll-theme-time-machine (= 0.1.1)
jekyll-titles-from-headings (= 0.5.3)
jemoji (= 0.11.1)
jemoji (= 0.12.0)
kramdown (= 2.3.0)
kramdown-parser-gfm (= 1.1.0)
liquid (= 4.0.3)
mercenary (~> 0.3)
minima (= 2.5.1)
nokogiri (>= 1.10.4, < 2.0)
rouge (= 3.19.0)
rouge (= 3.23.0)
terminal-table (~> 1.4)
github-pages-health-check (1.16.1)
addressable (~> 2.3)
@ -114,14 +117,14 @@ GEM
rouge (>= 2.0, < 4.0)
jekyll-default-layout (0.1.4)
jekyll (~> 3.0)
jekyll-feed (0.13.0)
jekyll-feed (0.15.1)
jekyll (>= 3.7, < 5.0)
jekyll-gist (1.5.0)
octokit (~> 4.2)
jekyll-github-metadata (2.13.0)
jekyll (>= 3.4, < 5.0)
octokit (~> 4.0, != 4.4.0)
jekyll-mentions (1.5.1)
jekyll-mentions (1.6.0)
html-pipeline (~> 2.3)
jekyll (>= 3.7, < 5.0)
jekyll-optional-front-matter (0.3.2)
@ -129,14 +132,15 @@ GEM
jekyll-paginate (1.1.0)
jekyll-readme-index (0.3.0)
jekyll (>= 3.0, < 5.0)
jekyll-redirect-from (0.15.0)
jekyll-redirect-from (0.16.0)
jekyll (>= 3.3, < 5.0)
jekyll-relative-links (0.6.1)
jekyll (>= 3.3, < 5.0)
jekyll-remote-theme (0.4.1)
jekyll-remote-theme (0.4.2)
addressable (~> 2.0)
jekyll (>= 3.5, < 5.0)
rubyzip (>= 1.3.0)
jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
rubyzip (>= 1.3.0, < 3.0)
jekyll-sass-converter (1.5.2)
sass (~> 3.4)
jekyll-seo-tag (2.6.1)
@ -153,8 +157,8 @@ GEM
jekyll-theme-dinky (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-hacker (0.1.1)
jekyll (~> 3.5)
jekyll-theme-hacker (0.1.2)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-leap-day (0.1.1)
jekyll (~> 3.5)
@ -188,7 +192,7 @@ GEM
jekyll (>= 3.3, < 5.0)
jekyll-watch (2.2.1)
listen (~> 3.0)
jemoji (0.11.1)
jemoji (0.12.0)
gemoji (~> 3.0)
html-pipeline (~> 2.2)
jekyll (>= 3.0, < 5.0)
@ -197,32 +201,35 @@ GEM
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (4.0.3)
listen (3.2.1)
listen (3.4.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
mini_portile2 (2.4.0)
mini_portile2 (2.5.0)
minima (2.5.1)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.14.1)
minitest (5.14.3)
multipart-post (2.1.1)
nokogiri (1.10.10)
mini_portile2 (~> 2.4.0)
octokit (4.18.0)
nokogiri (1.11.1)
mini_portile2 (~> 2.5.0)
racc (~> 1.4)
octokit (4.20.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (3.1.1)
racc (1.5.2)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
rexml (3.2.4)
rouge (3.19.0)
rouge (3.23.0)
ruby-enum (0.8.0)
i18n
ruby2_keywords (0.0.2)
rubyzip (2.3.0)
safe_yaml (1.0.5)
sass (3.7.4)
@ -240,13 +247,13 @@ GEM
thread_safe (0.3.6)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (1.2.7)
tzinfo (1.2.9)
thread_safe (~> 0.1)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
unicode-display_width (1.7.0)
zeitwerk (2.4.0)
zeitwerk (2.4.2)
PLATFORMS
ruby

View File

@ -131,7 +131,7 @@ we may decide to remove some APIs that were not tagged as deprecated, though we'
###### Around RuleSet parsing
* {% jdoc core::RuleSetFactory %} and {% jdoc core::RuleSetFactoryUtils %} have been deprecated in favor of {% jdoc core::RuleSetLoader %}. This is easier to configure, and more maintainable than the multiple overloads of `RuleSetFactoryUtils`.
* {% jdoc core::RuleSetFactory %} and {% jdoc core::RulesetsFactoryUtils %} have been deprecated in favor of {% jdoc core::RuleSetLoader %}. This is easier to configure, and more maintainable than the multiple overloads of `RulesetsFactoryUtils`.
* Some static creation methods have been added to {% jdoc core::RuleSet %} for simple cases, eg {% jdoc core::RuleSet#forSingleRule(core::Rule) %}. These replace some counterparts in {% jdoc core::RuleSetFactory %}
* Since {% jdoc core::RuleSets %} is also deprecated, many APIs that require a RuleSets instance now are deprecated, and have a counterpart that expects a `List<RuleSet>`.
* {% jdoc core::RuleSetReferenceId %}, {% jdoc core::RuleSetReference %}, {% jdoc core::RuleSetFactoryCompatibility %} are deprecated. They are most likely not relevant outside of the implementation of pmd-core.

View File

@ -1,8 +1,8 @@
---
title: Getting Help
permalink: pmd_about_help.html
author: Andreas Dangel <andreas.dangel@adangel.org>
last_updated: September 2017
author: Andreas Dangel <andreas.dangel@pmd-code.org>
last_updated: January 2021
---
There are numerous ways of getting help:
@ -13,7 +13,7 @@ There are numerous ways of getting help:
* If you found a bug, please create a new [github issue](https://github.com/pmd/pmd/issues).
* You can also ask questions in our [sourceforge forum](https://sourceforge.net/p/pmd/discussion/).
* You can also ask questions on [github discussions](https://github.com/pmd/pmd/discussions).
* Or you can join the [Mailing List](https://lists.sourceforge.net/lists/listinfo/pmd-devel) or browse
through the archives ([archive1](http://java-pmd.30631.n5.nabble.com/), [archive2](http://web.archive.org/web/20160715035623/http://blog.gmane.org:80/gmane.comp.java.audit.pmd.devel)).

View File

@ -16,11 +16,18 @@ This is a {{ site.pmd.release_type }} release.
### Fixed Issues
* core
* [#2994](https://github.com/pmd/pmd/pull/2994): \[core] Fix code climate severity strings
* java-bestpractices
* [#575](https://github.com/pmd/pmd/issues/575): \[java] LiteralsFirstInComparisons should consider constant fields
### API Changes
### External Contributions
- [#2964](https://github.com/pmd/pmd/pull/2964) \[cs] Update C# grammar for additional C# 7 and C# 8 features -- [Maikel Steneker](https://github.com/maikelsteneker)
* [#2964](https://github.com/pmd/pmd/pull/2964): \[cs] Update C# grammar for additional C# 7 and C# 8 features - [Maikel Steneker](https://github.com/maikelsteneker)
* [#2983](https://github.com/pmd/pmd/pull/2983): \[java] LiteralsFirstInComparisons should consider constant fields - [Ozan Gulle](https://github.com/ozangulle)
* [#2994](https://github.com/pmd/pmd/pull/2994): \[core] Fix code climate severity strings - [Vincent Maurin](https://github.com/vmaurin)
{% endtocmaker %}

View File

@ -70,7 +70,7 @@ Thanks to Jeff Bartolotta and Roopa Mohan for contributing this!
##### Around RuleSet parsing
* <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetFactory.html#"><code>RuleSetFactory</code></a> and <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RulesetsFactoryUtils.html#"><code>RulesetsFactoryUtils</code></a> have been deprecated in favor of <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetLoader.html#"><code>RuleSetLoader</code></a>. This is easier to configure, and more maintainable than the multiple overloads of `RuleSetFactoryUtils`.
* <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetFactory.html#"><code>RuleSetFactory</code></a> and <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RulesetsFactoryUtils.html#"><code>RulesetsFactoryUtils</code></a> have been deprecated in favor of <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetLoader.html#"><code>RuleSetLoader</code></a>. This is easier to configure, and more maintainable than the multiple overloads of `RulesetsFactoryUtils`.
* Some static creation methods have been added to <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSet.html#"><code>RuleSet</code></a> for simple cases, eg <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSet.html#forSingleRule(net.sourceforge.pmd.Rule)"><code>forSingleRule</code></a>. These replace some counterparts in <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetFactory.html#"><code>RuleSetFactory</code></a>
* Since <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSets.html#"><code>RuleSets</code></a> is also deprecated, many APIs that require a RuleSets instance now are deprecated, and have a counterpart that expects a `List<RuleSet>`.
* <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetReferenceId.html#"><code>RuleSetReferenceId</code></a>, <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetReference.html#"><code>RuleSetReference</code></a>, <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetFactoryCompatibility.html#"><code>RuleSetFactoryCompatibility</code></a> are deprecated. They are most likely not relevant outside of the implementation of pmd-core.

View File

@ -84,12 +84,16 @@ public class CodeClimateRenderer extends AbstractIncrementingRenderer {
switch (rule.getPriority()) {
case HIGH:
issue.severity = "critical";
issue.severity = "blocker";
break;
case MEDIUM_HIGH:
issue.severity = "critical";
break;
case MEDIUM:
issue.severity = "major";
break;
case MEDIUM_LOW:
issue.severity = "normal";
issue.severity = "minor";
break;
case LOW:
default:

View File

@ -16,6 +16,7 @@ import net.sourceforge.pmd.Report.ConfigurationError;
import net.sourceforge.pmd.Report.ProcessingError;
import net.sourceforge.pmd.ReportTest;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RulePriority;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.RuleWithProperties;
import net.sourceforge.pmd.lang.ast.DummyNode;
@ -69,8 +70,12 @@ public abstract class AbstractRendererTest {
private Report reportTwoViolations() {
Report report = new Report();
report.addRuleViolation(newRuleViolation(1));
report.addRuleViolation(newRuleViolation(2));
RuleViolation informationalRuleViolation = newRuleViolation(1);
informationalRuleViolation.getRule().setPriority(RulePriority.LOW);
report.addRuleViolation(informationalRuleViolation);
RuleViolation severeRuleViolation = newRuleViolation(2);
severeRuleViolation.getRule().setPriority(RulePriority.HIGH);
report.addRuleViolation(severeRuleViolation);
return report;
}

View File

@ -30,7 +30,7 @@ public class CSVRendererTest extends AbstractRendererTest {
public String getExpectedMultiple() {
return getHeader()
+ "\"1\",\"\",\"" + getSourceCodeFilename() + "\",\"5\",\"1\",\"blah\",\"RuleSet\",\"Foo\"" + PMD.EOL
+ "\"2\",\"\",\"" + getSourceCodeFilename() + "\",\"5\",\"1\",\"blah\",\"RuleSet\",\"Foo\"" + PMD.EOL;
+ "\"2\",\"\",\"" + getSourceCodeFilename() + "\",\"1\",\"1\",\"blah\",\"RuleSet\",\"Foo\"" + PMD.EOL;
}
@Override

View File

@ -76,7 +76,7 @@ public class CodeClimateRendererTest extends AbstractRendererTest {
+ "violationSuppressXPath | | Suppress violations on nodes which match a given relative XPath expression.\\n"
+ "\"},\"categories\":[\"Style\"],\"location\":{\"path\":\"" + getSourceCodeFilename() + "\",\"lines\":{\"begin\":1,\"end\":1}},\"severity\":\"info\",\"remediation_points\":50000}"
+ "\u0000" + PMD.EOL + "{\"type\":\"issue\",\"check_name\":\"Foo\",\"description\":\"blah\","
+ "\"content\":{\"body\":\"## Foo\\n\\nSince: PMD null\\n\\nPriority: Low\\n\\n"
+ "\"content\":{\"body\":\"## Foo\\n\\nSince: PMD null\\n\\nPriority: High\\n\\n"
+ "[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): Style\\n\\n"
+ "[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): 50000\\n\\n"
+ "desc\\n\\n"
@ -84,7 +84,7 @@ public class CodeClimateRendererTest extends AbstractRendererTest {
+ "Name | Value | Description\\n" + "--- | --- | ---\\n"
+ "violationSuppressRegex | | Suppress violations with messages matching a regular expression\\n"
+ "violationSuppressXPath | | Suppress violations on nodes which match a given relative XPath expression.\\n"
+ "\"},\"categories\":[\"Style\"],\"location\":{\"path\":\"" + getSourceCodeFilename() + "\",\"lines\":{\"begin\":1,\"end\":1}},\"severity\":\"info\",\"remediation_points\":50000}"
+ "\"},\"categories\":[\"Style\"],\"location\":{\"path\":\"" + getSourceCodeFilename() + "\",\"lines\":{\"begin\":1,\"end\":1}},\"severity\":\"blocker\",\"remediation_points\":50000}"
+ "\u0000" + PMD.EOL;
}

View File

@ -79,6 +79,7 @@ public class JsonRendererTest extends AbstractRendererTest {
public String filter(String expected) {
String result = expected
.replaceAll("\"timestamp\":\\s*\"[^\"]+\"", "\"timestamp\": \"--replaced--\"")
.replaceAll("\"pmdVersion\":\\s*\"[^\"]+\"", "\"pmdVersion\": \"unknown\"")
.replaceAll("\r\n", "\n"); // make the test run on Windows, too
return result;
}

View File

@ -63,7 +63,7 @@ public class XMLRendererTest extends AbstractRendererTest {
return getHeader() + "<file name=\"" + getSourceCodeFilename() + "\">" + PMD.EOL
+ "<violation beginline=\"1\" endline=\"1\" begincolumn=\"1\" endcolumn=\"1\" rule=\"Foo\" ruleset=\"RuleSet\" priority=\"5\">"
+ PMD.EOL + "blah" + PMD.EOL + "</violation>" + PMD.EOL
+ "<violation beginline=\"1\" endline=\"1\" begincolumn=\"1\" endcolumn=\"2\" rule=\"Foo\" ruleset=\"RuleSet\" priority=\"5\">"
+ "<violation beginline=\"1\" endline=\"1\" begincolumn=\"1\" endcolumn=\"2\" rule=\"Foo\" ruleset=\"RuleSet\" priority=\"1\">"
+ PMD.EOL + "blah" + PMD.EOL + "</violation>" + PMD.EOL + "</file>" + PMD.EOL + "</pmd>" + PMD.EOL;
}

View File

@ -24,7 +24,7 @@
"description": "blah",
"rule": "Foo",
"ruleset": "RuleSet",
"priority": 5
"priority": 1
}
]
}

View File

@ -8,16 +8,20 @@ import java.util.List;
import net.sourceforge.pmd.lang.java.ast.ASTArgumentList;
import net.sourceforge.pmd.lang.java.ast.ASTArguments;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBody;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBodyDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTConditionalAndExpression;
import net.sourceforge.pmd.lang.java.ast.ASTConditionalOrExpression;
import net.sourceforge.pmd.lang.java.ast.ASTEqualityExpression;
import net.sourceforge.pmd.lang.java.ast.ASTExpression;
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
import net.sourceforge.pmd.lang.java.ast.ASTName;
import net.sourceforge.pmd.lang.java.ast.ASTNullLiteral;
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator;
import net.sourceforge.pmd.lang.java.ast.JavaNode;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
@ -123,20 +127,28 @@ public class LiteralsFirstInComparisonsRule extends AbstractJavaRule {
private boolean isStringLiteralFirstArgumentOfSuffix(ASTPrimarySuffix primarySuffix) {
try {
JavaNode firstArg = getFirstArgument(primarySuffix);
return isStringLiteral(firstArg);
JavaNode firstLiteralArg = getFirstLiteralArgument(primarySuffix);
JavaNode firstNameArg = getFirstNameArgument(primarySuffix);
return isStringLiteral(firstLiteralArg) || isConstantString(firstNameArg);
} catch (NullPointerException e) {
return false;
}
}
private JavaNode getFirstArgument(ASTPrimarySuffix primarySuffix) {
private JavaNode getFirstLiteralArgument(ASTPrimarySuffix primarySuffix) {
return getArgumentPrimaryPrefix(primarySuffix).getFirstChildOfType(ASTLiteral.class);
}
private JavaNode getFirstNameArgument(ASTPrimarySuffix primarySuffix) {
return getArgumentPrimaryPrefix(primarySuffix).getFirstChildOfType(ASTName.class);
}
private JavaNode getArgumentPrimaryPrefix(ASTPrimarySuffix primarySuffix) {
ASTArguments arguments = primarySuffix.getFirstChildOfType(ASTArguments.class);
ASTArgumentList argumentList = arguments.getFirstChildOfType(ASTArgumentList.class);
ASTExpression expression = argumentList.getFirstChildOfType(ASTExpression.class);
ASTPrimaryExpression primaryExpression = expression.getFirstChildOfType(ASTPrimaryExpression.class);
ASTPrimaryPrefix primaryPrefix = primaryExpression.getFirstChildOfType(ASTPrimaryPrefix.class);
return primaryPrefix.getFirstChildOfType(ASTLiteral.class);
return primaryExpression.getFirstChildOfType(ASTPrimaryPrefix.class);
}
private boolean isStringLiteral(JavaNode node) {
@ -147,6 +159,25 @@ public class LiteralsFirstInComparisonsRule extends AbstractJavaRule {
return false;
}
private boolean isConstantString(JavaNode node) {
if (node instanceof ASTName) {
ASTName name = (ASTName) node;
ASTClassOrInterfaceBody classBody = name.getFirstParentOfType(ASTClassOrInterfaceBody.class);
ASTClassOrInterfaceBodyDeclaration classOrInterfaceBodyDeclaration = classBody.getFirstChildOfType(ASTClassOrInterfaceBodyDeclaration.class);
List<ASTFieldDeclaration> fieldDeclarations = classOrInterfaceBodyDeclaration.findChildrenOfType(ASTFieldDeclaration.class);
for (ASTFieldDeclaration fieldDeclaration : fieldDeclarations) {
ASTVariableDeclarator declaration = fieldDeclaration.getFirstChildOfType(ASTVariableDeclarator.class);
if (declaration.getName().equals(name.getImage())
&& String.class.equals(declaration.getType())
&& fieldDeclaration.isFinal()
&& fieldDeclaration.isStatic()) {
return true;
}
}
}
return false;
}
private boolean isNotWithinNullComparison(ASTPrimaryExpression node) {
return !isWithinNullComparison(node);
}

View File

@ -315,6 +315,58 @@ public class Foo {
if (getStr("b").equals("ab")) { } // nok
if ("ab".equals(getStr("b"))) { } // ok
}
}
]]></code>
</test-code>
<test-code>
<description>#575 LiteralsFirstInComparisons to consider constant fields, i.e. static final Strings</description>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class Foo {
private static final String TEST_CONSTANT = "Test-Constant";
public boolean test(String someString) {
return someString.equals(TEST_CONSTANT);
}
}
]]></code>
</test-code>
<test-code>
<description>#575 LiteralsFirstInComparisons must not trigger if the field is not final</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
private static String TEST_CONSTANT = "Test-Constant";
public boolean test(String someString) {
return someString.equals(TEST_CONSTANT);
}
}
]]></code>
</test-code>
<test-code>
<description>#575 LiteralsFirstInComparisons must not trigger if the field is not static</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
private final String TEST_CONSTANT = "Test-Constant";
public boolean test(String someString) {
return someString.equals(TEST_CONSTANT);
}
}
]]></code>
</test-code>
<test-code>
<description>#575 LiteralsFirstInComparisons must not trigger if the constant field is not a String</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
private final Integer TEST_CONSTANT = 5;
public boolean test(String someString) {
return someString.equals(TEST_CONSTANT);
}
}
]]></code>
</test-code>