Merge branch 'master' into apex-deprecate-ast

This commit is contained in:
Clément Fournier committed 2020-04-20 10:56:40 +02:00
commit f7fc5c5687
97 files changed
+2741 -679

No files matched your search

+16 -7
View File
@@ -1,10 +1,19 @@
<!--
Please, prefix the PR title with the language it applies to within brackets, such as *[java]* or *[apex]*. If not specific to a language, you can use *[core]*
-->
## Describe the PR
Before submitting a PR, please check that:
- [ ] The PR is submitted against `master`. The PMD team will merge back to support branches as needed.
- [ ] `./mvnw clean verify` passes. This will [build](https://github.com/pmd/pmd/blob/master/BUILDING.md) and test PMD, execute PMD and checkstyle rules. [Check this for more info](https://github.com/pmd/pmd/blob/master/CONTRIBUTING.md#code-style)
<!-- A clear and concise description of the bug the PR fixes or the feature the PR introduces. -->
**PR Description:**
## Related issues
<!-- PR relates to issues in the `pmd` repo: -->
- Fixes #
## Ready?
<!-- If you feel like you can help to check off the following tasks, that'd be great. If not, don't worry - we will take care of it. -->
- [ ] Added unit tests for fixed bug/feature
- [ ] Passing all unit tests
- [ ] Complete build `./mvnw clean verify` passes (checked automatically by travis)
- [ ] Added (in-code) documentation (if needed)
+4
View File
@@ -2,6 +2,10 @@
First off, thanks for taking the time to contribute!
Please note that this project is released with a Contributor Code of Conduct.
By participating in this project you agree to abide by its terms.
You can find the code of conduct in the file [code_of_conduct.md](code_of_conduct.md).
| NB: the rule designer is developed over at [pmd/pmd-designer](https://github.com/pmd/pmd-designer). Please refer to the specific [contributor documentation](https://github.com/pmd/pmd-designer#contributing) if your issue, feature request or PR touches the designer. |
| --- |
+2
View File
@@ -5,6 +5,8 @@
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd)
[![Coverage Status](https://coveralls.io/repos/github/pmd/pmd/badge.svg)](https://coveralls.io/github/pmd/pmd)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/a674ee8642ed44c6ba7633626ee95967)](https://www.codacy.com/app/pmd/pmd?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=pmd/pmd&amp;utm_campaign=Badge_Grade)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](code_of_conduct.md)
## About
**PMD** is a source code analyzer. It finds common programming flaws like unused variables, empty catch blocks,
+129
View File
@@ -0,0 +1,129 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
<moderators@pmd-code.org>.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
+32 -6
View File
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
# Make sure, everything is English...
@@ -15,7 +15,7 @@ if [ ! -f pom.xml -o ! -d ../pmd.github.io ]; then
exit 1
fi
LAST_VERSION=
RELEASE_VERSION=
DEVELOPMENT_VERSION=
CURRENT_BRANCH=
@@ -33,11 +33,16 @@ PATCH=$(echo $RELEASE_VERSION | cut -d . -f 3)
if [ "$PATCH" == "0" ]; then
NEXT_MINOR=$(expr ${MINOR} + 1)
NEXT_PATCH="0"
LAST_MINOR=$(expr ${MINOR} - 1)
LAST_PATCH="0"
else
# this is a bugfixing release
NEXT_MINOR="${MINOR}"
NEXT_PATCH=$(expr ${PATCH} + 1)
LAST_MINOR="${MINOR}"
LAST_PATCH=$(expr ${PATCH} - 1)
fi
LAST_VERSION="$MAJOR.$LAST_MINOR.$LAST_PATCH"
DEVELOPMENT_VERSION="$MAJOR.$NEXT_MINOR.$NEXT_PATCH"
DEVELOPMENT_VERSION="${DEVELOPMENT_VERSION}-SNAPSHOT"
@@ -52,17 +57,18 @@ CURRENT_BRANCH=$(git symbolic-ref -q HEAD)
CURRENT_BRANCH=${CURRENT_BRANCH##refs/heads/}
CURRENT_BRANCH=${CURRENT_BRANCH:-HEAD}
echo "RELEASE_VERSION: ${RELEASE_VERSION}"
echo "DEVELOPMENT_VERSION: ${DEVELOPMENT_VERSION}"
echo "LAST_VERSION: ${LAST_VERSION}"
echo "RELEASE_VERSION: ${RELEASE_VERSION} (this release)"
echo "DEVELOPMENT_VERSION: ${DEVELOPMENT_VERSION} (the next version after the release)"
echo "CURRENT_BRANCH: ${CURRENT_BRANCH}"
echo
echo "Is this correct?"
echo
echo "Press enter to continue..."
echo "Press enter to continue... (or CTRL+C to cancel)"
read
export LAST_VERSION
export RELEASE_VERSION
export DEVELOPMENT_VERSION
export CURRENT_BRANCH
@@ -89,6 +95,26 @@ echo
echo "Press enter to continue..."
read
# calculating stats for release notes
STATS=$(
echo "### Stats"
echo "* $(git log pmd_releases/${LAST_VERSION}..HEAD --oneline --no-merges |wc -l) commits"
echo "* $(curl -s https://api.github.com/repos/pmd/pmd/milestones|jq ".[] | select(.title == \"$RELEASE_VERSION\") | .closed_issues") closed tickets & PRs"
echo "* Days since last release: $(( ( $(date +%s) - $(git log --max-count=1 --format="%at" pmd_releases/${LAST_VERSION}) ) / 86400))"
)
TEMP_RELEASE_NOTES=$(cat docs/pages/release_notes.md)
TEMP_RELEASE_NOTES=${TEMP_RELEASE_NOTES/\{\% endtocmaker \%\}/$STATS$'\n'$'\n'\{\% endtocmaker \%\}$'\n'}
echo "${TEMP_RELEASE_NOTES}" > docs/pages/release_notes.md
echo
echo "Updated stats in release notes:"
echo "$STATS"
echo
echo
# install bundles needed for rendering release notes
bundle install --with=release_notes_preprocessing --path vendor/bundle
+15 -3
View File
@@ -55,6 +55,21 @@ entries:
- title: PMD CLI reference
url: /pmd_userdocs_cli_reference.html
output: web, pdf
- title: PMD Report formats
url: /pmd_userdocs_report_formats.html
output: web, pdf
- title: null
output: web, pdf
subfolders:
- title: CPD reference
output: web, pdf
subfolderitems:
- title: Copy-paste detection
url: /pmd_userdocs_cpd.html
output: web, pdf
- title: CPD Report formats
url: /pmd_userdocs_cpd_report_formats.html
output: web, pdf
- title: null
output: web, pdf
subfolders:
@@ -88,9 +103,6 @@ entries:
- title: Testing your rules
url: /pmd_userdocs_extending_testing.html
output: web, pdf
- title: Copy-paste detection
url: /pmd_userdocs_cpd.html
output: web, pdf
- title: null
output: web, pdf
subfolders:
@@ -53,6 +53,25 @@ The designer lives at [pmd/pmd-designer](https://github.com/pmd/pmd-designer).
Update property `pmd-designer.version` in **pom.xml** to reference the latest pmd-designer release.
See <https://search.maven.org/search?q=g:net.sourceforge.pmd%20AND%20a:pmd-ui&core=gav> for the available releases.
Starting with PMD 6.23.0 we'll provide small statistics for every release. This needs to be added
to the release notes as the last section. To count the closed issues and pull requests, the milestone
on github with the title of the new release is searched. Make sure, there is a milestone
on <https://github.com/pmd/pmd/milestones>. The following snippet will
create the numbers, that can be attached to the release notes as a last section:
```shell
LAST_VERSION=6.22.0
NEW_VERSION=6.23.0
NEW_VERSION_COMMITISH=HEAD
echo "### Stats"
echo "* $(git log pmd_releases/${LAST_VERSION}..${NEW_VERSION_COMMITISH} --oneline --no-merges |wc -l) commits"
echo "* $(curl -s https://api.github.com/repos/pmd/pmd/milestones|jq ".[] | select(.title == \"$NEW_VERSION\") | .closed_issues") closed tickets & PRs"
echo "* Days since last release: $(( ( $(date +%s) - $(git log --max-count=1 --format="%at" pmd_releases/${LAST_VERSION}) ) / 86400))"
```
Note: this part is also integrated into `do-release.sh`.
Check in all (version) changes to branch master or any other branch, from which the release takes place:
$ git commit -a -m "Prepare pmd release <version>"
+1 -72
View File
@@ -198,76 +198,5 @@ Example:
## Available Report Formats
PMD comes with many different renderers.
The mnemonics in bold are used to select them on the command line, as
arguments to the `-format` option. Some formats accept *properties*,
which can be specified with the `-property` option on the command-line.
All formats are described at [PMD Report formats](pmd_userdocs_report_formats.html)
* **codeclimate**: Renderer for Code Climate JSON format.
* **csv**: Comma-separated values tabular format.
Properties:
* problem: Include problem column. Default: true.
* package: Include package column. Default: true.
* file: Include file column. Default: true.
* priority: Include priority column. Default: true.
* line: Include line column. Default: true.
* desc: Include description column. Default: true.
* ruleSet: Include Rule set column. Default: true.
* rule: Include Rule column. Default: true.
* **emacs**: GNU Emacs integration.
* **html**: HTML format.
Properties:
* linePrefix: Prefix for line number anchor in the source file.
* linkPrefix: Path to HTML source.
* **ideaj**: IntelliJ IDEA integration.
Properties:
* classAndMethodName: Class and method name, pass `.method` when processing a directory.
* sourcePath:
* fileName:
* **summaryhtml**: Summary HTML format.
Properties:
* linePrefix: Prefix for line number anchor in the source file.
* linkPrefix: Path to HTML source.
* **text**: Text format.
* **textcolor**: Text format, with color support (requires ANSI console support, e.g. xterm, rxvt, etc.).
Properties:
* color: Enables colors with anything other than `false` or `0`. Default: yes.
* **textpad**: TextPad integration.
* **vbhtml**: Vladimir Bossicard HTML format.
* **xml**: XML format.
Properties:
* encoding: XML encoding format, defaults to UTF-8.
* **xslt**: XML with a XSL transformation applied.
Properties:
* encoding: XML encoding format, defaults to UTF-8.
* xsltFilename: The XSLT file name.
* **yahtml**: Yet Another HTML format.
Properties:
* outputDir: Output directory.
@@ -239,6 +239,7 @@ This behavior has been introduced to ease CPD integration into scripts or hooks,
* csv_with_linecount_per_file
* vs
For details, see [CPD Report Formats](pmd_userdocs_cpd_report_formats.html).
## Ant task
@@ -0,0 +1,220 @@
---
title: Report formats for CPD
tags: [cpd, userdocs]
keywords: [formats, renderers]
summary: "Overview of the built-in report formats for CPD"
permalink: pmd_userdocs_cpd_report_formats.html
author: Andreas Dangel <andreas.dangel@pmd-code.org>
---
## Overview
CPD collects occurrences of found duplications and provides them to the selected report format.
Each found code duplication appears in one or more other files, so that each code duplication can
have multiple locations. Not all report formats display all locations.
The following examples always describe the same duplications:
1. a code block of 239 tokens spanning 33 lines in RuleReferenceTest. This is a duplication within the same file.
2. a code block of 110 tokens spanning 16 lines in JaxenXPathRuleQueryTest. This is a duplication that appears
3 times within the same file.
## text
This is the default format.
All duplications are reported one after another. For each duplication, the complete code snippet is output.
Each duplication is separated by `======`.
Example:
```
Found a 33 line (239 tokens) duplication in the following files:
Starting at line 32 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java
Starting at line 68 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java
public void testOverride() {
final StringProperty PROPERTY1_DESCRIPTOR = new StringProperty("property1", "Test property", null, 0f);
MockRule rule = new MockRule();
rule.definePropertyDescriptor(PROPERTY1_DESCRIPTOR);
rule.setLanguage(LanguageRegistry.getLanguage(Dummy2LanguageModule.NAME));
rule.setName("name1");
rule.setProperty(PROPERTY1_DESCRIPTOR, "value1");
rule.setMessage("message1");
rule.setDescription("description1");
rule.addExample("example1");
rule.setExternalInfoUrl("externalInfoUrl1");
rule.setPriority(RulePriority.HIGH);
final StringProperty PROPERTY2_DESCRIPTOR = new StringProperty("property2", "Test property", null, 0f);
RuleReference ruleReference = new RuleReference();
ruleReference.setRule(rule);
ruleReference.definePropertyDescriptor(PROPERTY2_DESCRIPTOR);
ruleReference.setLanguage(LanguageRegistry.getLanguage(DummyLanguageModule.NAME));
ruleReference
.setMinimumLanguageVersion(LanguageRegistry.getLanguage(DummyLanguageModule.NAME).getVersion("1.3"));
ruleReference
.setMaximumLanguageVersion(LanguageRegistry.getLanguage(DummyLanguageModule.NAME).getVersion("1.7"));
ruleReference.setDeprecated(true);
ruleReference.setName("name2");
ruleReference.setProperty(PROPERTY1_DESCRIPTOR, "value2");
ruleReference.setProperty(PROPERTY2_DESCRIPTOR, "value3");
ruleReference.setMessage("message2");
ruleReference.setDescription("description2");
ruleReference.addExample("example2");
ruleReference.setExternalInfoUrl("externalInfoUrl2");
ruleReference.setPriority(RulePriority.MEDIUM_HIGH);
validateOverridenValues(PROPERTY1_DESCRIPTOR, PROPERTY2_DESCRIPTOR, ruleReference);
=====================================================================
Found a 16 line (110 tokens) duplication in the following files:
Starting at line 66 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java
Starting at line 88 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java
Starting at line 110 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java
JaxenXPathRuleQuery query = createQuery(xpath);
List<String> ruleChainVisits = query.getRuleChainVisits();
Assert.assertEquals(2, ruleChainVisits.size());
Assert.assertTrue(ruleChainVisits.contains("dummyNode"));
// Note: Having AST_ROOT in the rule chain visits is probably a mistake. But it doesn't hurt, it shouldn't
// match a real node name.
Assert.assertTrue(ruleChainVisits.contains(JaxenXPathRuleQuery.AST_ROOT));
DummyNodeWithListAndEnum dummy = new DummyNodeWithListAndEnum(1);
RuleContext data = new RuleContext();
data.setLanguageVersion(LanguageRegistry.findLanguageByTerseName("dummy").getDefaultVersion());
query.evaluate(dummy, data);
// note: the actual xpath queries are only available after evaluating
Assert.assertEquals(2, query.nodeNameToXPaths.size());
Assert.assertEquals("self::node()[(attribute::Test1 = \"false\")][(attribute::Test2 = \"true\")]", query.nodeNameToXPaths.get("dummyNode").get(0).toString());
```
## xml
This format uses XML to output the duplications in a more structured format.
Example:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<pmd-cpd>
<duplication lines="33" tokens="239">
<file column="29" endcolumn="75" endline="64" line="32"
path="/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java"/>
<file column="37" endcolumn="75" endline="100" line="68"
path="/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java"/>
<codefragment><![CDATA[ public void testOverride() {
final StringProperty PROPERTY1_DESCRIPTOR = new StringProperty("property1", "Test property", null, 0f);
MockRule rule = new MockRule();
rule.definePropertyDescriptor(PROPERTY1_DESCRIPTOR);
rule.setLanguage(LanguageRegistry.getLanguage(Dummy2LanguageModule.NAME));
rule.setName("name1");
rule.setProperty(PROPERTY1_DESCRIPTOR, "value1");
rule.setMessage("message1");
rule.setDescription("description1");
rule.addExample("example1");
rule.setExternalInfoUrl("externalInfoUrl1");
rule.setPriority(RulePriority.HIGH);
final StringProperty PROPERTY2_DESCRIPTOR = new StringProperty("property2", "Test property", null, 0f);
RuleReference ruleReference = new RuleReference();
ruleReference.setRule(rule);
ruleReference.definePropertyDescriptor(PROPERTY2_DESCRIPTOR);
ruleReference.setLanguage(LanguageRegistry.getLanguage(DummyLanguageModule.NAME));
ruleReference
.setMinimumLanguageVersion(LanguageRegistry.getLanguage(DummyLanguageModule.NAME).getVersion("1.3"));
ruleReference
.setMaximumLanguageVersion(LanguageRegistry.getLanguage(DummyLanguageModule.NAME).getVersion("1.7"));
ruleReference.setDeprecated(true);
ruleReference.setName("name2");
ruleReference.setProperty(PROPERTY1_DESCRIPTOR, "value2");
ruleReference.setProperty(PROPERTY2_DESCRIPTOR, "value3");
ruleReference.setMessage("message2");
ruleReference.setDescription("description2");
ruleReference.addExample("example2");
ruleReference.setExternalInfoUrl("externalInfoUrl2");
ruleReference.setPriority(RulePriority.MEDIUM_HIGH);
validateOverridenValues(PROPERTY1_DESCRIPTOR, PROPERTY2_DESCRIPTOR, ruleReference);]]></codefragment>
</duplication>
<duplication lines="16" tokens="110">
<file column="9" endcolumn="28" endline="81" line="66"
path="/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java"/>
<file column="9" endcolumn="28" endline="103" line="88"
path="/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java"/>
<file column="9" endcolumn="28" endline="125" line="110"
path="/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java"/>
<codefragment><![CDATA[ JaxenXPathRuleQuery query = createQuery(xpath);
List<String> ruleChainVisits = query.getRuleChainVisits();
Assert.assertEquals(2, ruleChainVisits.size());
Assert.assertTrue(ruleChainVisits.contains("dummyNode"));
// Note: Having AST_ROOT in the rule chain visits is probably a mistake. But it doesn't hurt, it shouldn't
// match a real node name.
Assert.assertTrue(ruleChainVisits.contains(JaxenXPathRuleQuery.AST_ROOT));
DummyNodeWithListAndEnum dummy = new DummyNodeWithListAndEnum(1);
RuleContext data = new RuleContext();
data.setLanguageVersion(LanguageRegistry.findLanguageByTerseName("dummy").getDefaultVersion());
query.evaluate(dummy, data);
// note: the actual xpath queries are only available after evaluating
Assert.assertEquals(2, query.nodeNameToXPaths.size());
Assert.assertEquals("self::node()[(attribute::Test1 = \"false\")][(attribute::Test2 = \"true\")]", query.nodeNameToXPaths.get("dummyNode").get(0).toString());]]></codefragment>
</duplication>
</pmd-cpd>
```
## csv
This outputs the duplication as comma separated values. It only reports the duplication size (number
of lines and tokens) and the number of occurrences. After that, the begin lines and filenames are reported on
after another.
Example:
```
lines,tokens,occurrences
33,239,2,32,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java,68,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java
16,110,3,66,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java,88,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java,110,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java
```
## csv_with_linecount_per_file
This format is similar to "csv", but it has one difference: The duplication size in number of lines is reported
for each occurrence separately. While the tokens are the same, due to formatting or comments, the code blocks might be
different. Whitespace and comments are usually ignored when finding duplicated code.
In each line, the duplication size in tokens is reported, then the number of occurrences. And after that, for each
file, the begin line, the number of duplicated lines and the filename.
Example:
```
tokens,occurrences
239,2,32,33,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java,68,33,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenc
eTest.java
110,3,66,16,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java,88,16,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java,110,16,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java
```
## vs
This outputs the duplication in a format, that Visual Studio. CPD can be added as a external tool and the output
is shown in the console. You can then click on the filenames to jump to the source where the duplication is located.
Each occurrence of a duplication is reported in a separate line, that's why in this example, we have 5 lines.
Example:
```
/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java(32): Between lines 32 and 65
/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java(68): Between lines 68 and 101
/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java(66): Between lines 66 and 82
/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java(88): Between lines 88 and 104
/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java(110): Between lines 110 and 126
```
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -243,11 +243,11 @@ Here's how to set it up as an "External Tool":
* Name: PMD
* Description: PMD, good for what ails you.
* Menu: Select the "Main menu", "Project views", "Editor menu", and "Search results" checkboxes.
* Program: $JDKPath$\bin\java.exe
* Program: `c:\pmd\bin\pmd.bat`
* For the next parameter you'll need to plug in the location of your PMD installation
and the rulesets you want to use
* Parameters:
`-cp %CLASSPATH%;c:\pmd\lib\pmd-{{pmd.site.version}}.jar;c:\pmd\lib\asm-3.2.jar;c:\pmd\lib\jaxen-1.1.1.jar net.sourceforge.pmd.PMD "$FilePath$" ideaj unusedcode,imports "$Sourcepath$" $FileClass$.method $FileName$`
`-d "$FilePath$" -f ideaj -R rulesets/java/quickstart.xml -P sourcePath="$Sourcepath$" -P classAndMethodName=$FileClass$.method -P fileName=$FileName$`
That's pretty much it. Now you can right click on a source directory and select PMD,
it'll run recursively on the source files, and the results should
+25
View File
@@ -14,6 +14,18 @@ This is a {{ site.pmd.release_type }} release.
### New and noteworthy
#### PMD adopts Contributor Code of Conduct
To facilitate healthy and constructive community behavior PMD adopts
[Contributor Convenant](https://www.contributor-covenant.org/) as its code of
conduct.
Please note that this project is released with a Contributor Code of Conduct.
By participating in this project you agree to abide by its terms.
You can find the code of conduct in the file [code_of_conduct.md](https://github.com/pmd/pmd/blob/master/code_of_conduct.md)
in our repository.
#### Performance improvements for XPath 2.0 rules
XPath rules written with XPath 2.0 now support conversion to a rulechain rule, which
@@ -46,10 +58,16 @@ Note that XPath 1.0 support, the default XPath version, is deprecated since PMD
* [#2210](https://github.com/pmd/pmd/issues/2210): \[apex] ApexCRUDViolation: Support WITH SECURITY_ENFORCED
* [#2399](https://github.com/pmd/pmd/issues/2399): \[apex] ApexCRUDViolation: false positive with security enforced with line break
* core
* [#2019](https://github.com/pmd/pmd/issues/2019): \[core] Insufficient deprecation warnings for XPath attributes
* [#2357](https://github.com/pmd/pmd/issues/2357): Add code of conduct: Contributor Covenant
* doc
* [#2355](https://github.com/pmd/pmd/issues/2355): \[doc] Improve documentation about incremental analysis
* [#2356](https://github.com/pmd/pmd/issues/2356): \[doc] Add missing doc about pmd.github.io
* [#2413](https://github.com/pmd/pmd/issues/2413): \[doc] Improve documentation about the available renderers (PMD/CPD)
* java
* [#2378](https://github.com/pmd/pmd/issues/2378): \[java] AbstractJUnitRule has bad performance on large code bases
* java-bestpractices
* [#2398](https://github.com/pmd/pmd/issues/2398): \[java] AbstractClassWithoutAbstractMethod false negative with inner abstract classes
* java-codestyle
* [#1164](https://github.com/pmd/pmd/issues/1164): \[java] ClassNamingConventions suggests to add Util for class containing only static constants
* [#1723](https://github.com/pmd/pmd/issues/1723): \[java] UseDiamondOperator false-positive inside lambda
@@ -127,6 +145,12 @@ implementations, and their corresponding Parser if it exists (in the same packag
* {% jdoc vm::lang.vm.VmTokenManager %}
In the **Java AST** the following attributes are deprecated and will issue a warning when used in XPath rules:
* {% jdoc !!java::lang.java.ast.ASTAdditiveExpression#getImage() %} - use `getOperator()` instead
* {% jdoc !!java::lang.java.ast.ASTVariableDeclaratorId#getImage() %} - use `getName()` instead
* {% jdoc !!java::lang.java.ast.ASTVariableDeclaratorId#getVariableName() %} - use `getName()` instead
##### For removal
* {% jdoc !!core::lang.Parser#getTokenManager(java.lang.String,java.io.Reader) %}
@@ -152,6 +176,7 @@ implementations, and their corresponding Parser if it exists (in the same packag
* [#2403](https://github.com/pmd/pmd/pull/2403): \[java] #2402 fix false-positives on Primitive Streams - [Bernd Farka](https://github.com/BerndFarkaDyna)
* [#2409](https://github.com/pmd/pmd/pull/2409): \[java] ClassNamingConventions suggests to add Util for class containing only static constants, fixes #1164 - [Binu R J](https://github.com/binu-r)
* [#2411](https://github.com/pmd/pmd/pull/2411): \[java] Fix UseAssertEqualsInsteadOfAssertTrue Example - [Moritz Scheve](https://github.com/Blightbuster)
* [#2423](https://github.com/pmd/pmd/pull/2423): \[core] Fix Checkstyle OperatorWrap in AbstractTokenizer - [Harsh Kukreja](https://github.com/harsh-kukreja)
{% endtocmaker %}
+67
View File
@@ -0,0 +1,67 @@
<html><head><title>PMD</title></head><body>
<center><h3>PMD report</h3></center><center><h3>Problems found</h3></center><table align="center" cellspacing="0" cellpadding="3"><tr>
<th>#</th><th>File</th><th>Line</th><th>Problem</th></tr>
<tr bgcolor="lightgrey">
<td align="center">1</td>
<td width="*%"><a href="https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java#L124">pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java</a></td>
<td align="center" width="5%">124</td>
<td width="*"><a href="https://pmd.github.io/pmd-6.22.0/pmd_rules_java_bestpractices.html#guardlogstatement">Logger calls should be surrounded by log level guards.</a></td>
</tr>
<tr>
<td align="center">2</td>
<td width="*%"><a href="https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java#L58">pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java</a></td>
<td align="center" width="5%">58</td>
<td width="*"><a href="https://pmd.github.io/pmd-6.22.0/pmd_rules_java_bestpractices.html#forloopcanbeforeach">This for loop can be replaced by a foreach loop</a></td>
</tr>
</table><hr/><center><h3>Processing errors</h3></center><table align="center" cellspacing="0" cellpadding="3"><tr>
<th>File</th><th>Problem</th></tr>
<tr bgcolor="lightgrey">
<td><a href="https://github.com/pmd/pmd/blob/master/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java#">pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java</a></td>
<td><pre>net.sourceforge.pmd.PMDException: Error while parsing pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:110)
at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:89)
at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:51)
at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:78)
at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:24)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: net.sourceforge.pmd.lang.java.ast.ParseException: Encountered " "-" "- "" at line 6, column 30.
Was expecting one of:
"extends" ...
"implements" ...
"{" ...
"<" ...
at net.sourceforge.pmd.lang.java.ast.JavaParser.generateParseException(JavaParser.java:12713)
at net.sourceforge.pmd.lang.java.ast.JavaParser.jj_consume_token(JavaParser.java:12597)
at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceBody(JavaParser.java:1554)
at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceDeclaration(JavaParser.java:732)
at net.sourceforge.pmd.lang.java.ast.JavaParser.TypeDeclaration(JavaParser.java:639)
at net.sourceforge.pmd.lang.java.ast.JavaParser.CompilationUnit(JavaParser.java:373)
at net.sourceforge.pmd.lang.java.AbstractJavaParser.parse(AbstractJavaParser.java:62)
at net.sourceforge.pmd.SourceCodeProcessor.parse(SourceCodeProcessor.java:121)
at net.sourceforge.pmd.SourceCodeProcessor.processSource(SourceCodeProcessor.java:185)
at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:107)
... 10 more
</pre></td>
</tr>
</table><hr/><center><h3>Suppressed warnings</h3></center><table align="center" cellspacing="0" cellpadding="3"><tr>
<th>File</th><th>Line</th><th>Rule</th><th>NOPMD or Annotation</th><th>Reason</th></tr>
<tr bgcolor="lightgrey">
<td align="left"><a href="https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java#L505">pmd-core/src/main/java/net/sourceforge/pmd/PMD.java</a></td>
<td align="center">505</td>
<td align="center"><a href="https://pmd.github.io/pmd-6.22.0/pmd_rules_java_errorprone.html#closeresource">CloseResource</a></td>
<td align="center">Annotation</td>
<td align="center"></td>
</tr>
</table><hr/><center><h3>Configuration errors</h3></center><table align="center" cellspacing="0" cellpadding="3"><tr>
<th>Rule</th><th>Problem</th></tr>
<tr bgcolor="lightgrey">
<td><a href="https://pmd.github.io/pmd-6.22.0/pmd_rules_java_design.html#loosepackagecoupling">LoosePackageCoupling</a></td>
<td>No packages or classes specified</td>
</tr>
</table></body></html>
@@ -0,0 +1,223 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns:pmd="http://pmd.sourceforge.net/report/2.0.0">
<head>
<title>PMD 6.22.0 Report</title>
<style type="text/css">
.bannercell {
border: 0px;
padding: 0px;
}
body {
margin-left: 10px;
margin-right: 10px;
font:normal 80% arial,helvetica,sanserif;
background-color:#FFFFFF;
color:#000000;
}
.a td {
background: #efefef;
}
.b td {
background: #fff;
}
th, td {
text-align: left;
vertical-align: top;
}
th {
font-weight:bold;
background: #ccc;
color: black;
}
table, th, td {
font-size:100%;
border: none
}
table.log tr td, tr th {
}
h2 {
font-weight:bold;
font-size:140%;
margin-bottom: 5;
}
h3 {
font-size:100%;
font-weight:bold;
background: #525D76;
color: white;
text-decoration: none;
padding: 5px;
margin-right: 2px;
margin-left: 2px;
margin-bottom: 0px;
}
.p1 { background:#FF9999; }
.p2 { background:#FFCC66; }
.p3 { background:#FFFF99; }
.p4 { background:#99FF99; }
.p5 { background:#a6caf0; }
</style>
</head>
<body>
<a name="top"/>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td class="bannercell" rowspan="2"/>
<td class="text-align:right">
<h2>PMD 6.22.0 Report. Generated on 2020-04-11 - 19:23:45</h2>
</td>
</tr>
</table>
<hr size="1"/>
<h3>Summary</h3>
<table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
<tr>
<th style="width:25%">Files</th>
<th>Total</th>
<th>
<div class="p1">Priority 1</div>
</th>
<th>
<div class="p2">Priority 2</div>
</th>
<th>
<div class="p3">Priority 3</div>
</th>
<th>
<div class="p4">Priority 4</div>
</th>
<th>
<div class="p5">Priority 5</div>
</th>
</tr>
<tr class="a">
<td>2</td>
<td>2</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>0</td>
</tr>
</table>
<hr size="1" width="100%" align="left"/>
<h3>Rules</h3>
<table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
<tr>
<th style="width:84%">Rule</th>
<th style="width:8%">Violations</th>
<th style="width:8%">Severity</th>
</tr>
<tr class="a">
<td>
[Best Practices] GuardLogStatement</td>
<td>1</td>
<td>
<div class="p2"> 2</div>
</td>
</tr>
<tr class="b">
<td>
[Best Practices] ForLoopCanBeForeach</td>
<td>1</td>
<td>
<div class="p3"> 3</div>
</td>
</tr>
</table>
<hr size="1" width="100%" align="left"/>
<h3>Files</h3>
<table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
<tr>
<th>File</th>
<th style="width:40px">
<div class="p5">5</div>
</th>
<th style="width:40px">
<div class="p4">4</div>
</th>
<th style="width:40px">
<div class="p3">3</div>
</th>
<th style="width:40px">
<div class="p2">2</div>
</th>
<th style="width:40px">
<div class="p1">1</div>
</th>
</tr>
<tr class="a">
<td>
<a href="#f-pmd-core_src_main_java_net_sourceforge_pmd_RuleContext.java">/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java</a>
</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
</tr>
<tr class="b">
<td>
<a href="#f-pmd-core_src_main_java_net_sourceforge_pmd_benchmark_Benchmarker.java">/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java</a>
</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
</tr>
</table>
<hr size="1" width="100%" align="left"/>
<a name="f-pmd-core_src_main_java_net_sourceforge_pmd_RuleContext.java"/>
<h3>File /home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java</h3>
<table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
<tr>
<th style="width:60px;">Violation</th>
<th>Error Description</th>
<th style="width:40px;">Line</th>
</tr>
<tr class="a">
<td>
<div class="p2">2</div>
</td>
<td>
[Best Practices.GuardLogStatement]
-
<a href="https://pmd.github.io/pmd-6.22.0/pmd_rules_java_bestpractices.html#guardlogstatement">
Logger calls should be surrounded by log level guards.
</a>
</td>
<td>124 - 125</td>
</tr>
</table>
<a href="#top">Back to top</a>
<a name="f-pmd-core_src_main_java_net_sourceforge_pmd_benchmark_Benchmarker.java"/>
<h3>File /home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java</h3>
<table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
<tr>
<th style="width:60px;">Violation</th>
<th>Error Description</th>
<th style="width:40px;">Line</th>
</tr>
<tr class="a">
<td>
<div class="p3">3</div>
</td>
<td>
[Best Practices.ForLoopCanBeForeach]
-
<a href="https://pmd.github.io/pmd-6.22.0/pmd_rules_java_bestpractices.html#forloopcanbeforeach">
This for loop can be replaced by a foreach loop
</a>
</td>
<td>58 - 62</td>
</tr>
</table>
<a href="#top">Back to top</a>
<hr size="1" width="100%" align="left"/>
</body>
</html>
@@ -0,0 +1,74 @@
<html><head><title>PMD</title></head><body>
<center><h2>Summary</h2></center>
<table align="center" cellspacing="0" cellpadding="3">
<tr><th>Rule name</th><th>Number of violations</th></tr>
<tr><td>GuardLogStatement</td><td align=center>1</td></tr>
<tr><td>ForLoopCanBeForeach</td><td align=center>1</td></tr>
</table>
<center><h2>Detail</h2></center><table align="center" cellspacing="0" cellpadding="3"><tr>
<center><h3>PMD report</h3></center><center><h3>Problems found</h3></center><table align="center" cellspacing="0" cellpadding="3"><tr>
<th>#</th><th>File</th><th>Line</th><th>Problem</th></tr>
<tr bgcolor="lightgrey">
<td align="center">1</td>
<td width="*%"><a href="https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java#L124">pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java</a></td>
<td align="center" width="5%">124</td>
<td width="*"><a href="https://pmd.github.io/pmd-6.22.0/pmd_rules_java_bestpractices.html#guardlogstatement">Logger calls should be surrounded by log level guards.</a></td>
</tr>
<tr>
<td align="center">2</td>
<td width="*%"><a href="https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java#L58">pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java</a></td>
<td align="center" width="5%">58</td>
<td width="*"><a href="https://pmd.github.io/pmd-6.22.0/pmd_rules_java_bestpractices.html#forloopcanbeforeach">This for loop can be replaced by a foreach loop</a></td>
</tr>
</table><hr/><center><h3>Processing errors</h3></center><table align="center" cellspacing="0" cellpadding="3"><tr>
<th>File</th><th>Problem</th></tr>
<tr bgcolor="lightgrey">
<td><a href="https://github.com/pmd/pmd/blob/master/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java#">pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java</a></td>
<td><pre>net.sourceforge.pmd.PMDException: Error while parsing pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:110)
at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:89)
at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:51)
at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:78)
at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:1)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: net.sourceforge.pmd.lang.java.ast.ParseException: Encountered " "-" "- "" at line 6, column 30.
Was expecting one of:
"extends" ...
"implements" ...
"{" ...
"<" ...
at net.sourceforge.pmd.lang.java.ast.JavaParser.generateParseException(JavaParser.java:12731)
at net.sourceforge.pmd.lang.java.ast.JavaParser.jj_consume_token(JavaParser.java:12615)
at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceBody(JavaParser.java:1574)
at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceDeclaration(JavaParser.java:779)
at net.sourceforge.pmd.lang.java.ast.JavaParser.TypeDeclaration(JavaParser.java:686)
at net.sourceforge.pmd.lang.java.ast.JavaParser.CompilationUnit(JavaParser.java:420)
at net.sourceforge.pmd.lang.java.AbstractJavaParser.parse(AbstractJavaParser.java:62)
at net.sourceforge.pmd.SourceCodeProcessor.parse(SourceCodeProcessor.java:121)
at net.sourceforge.pmd.SourceCodeProcessor.processSource(SourceCodeProcessor.java:185)
at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:107)
... 10 more
</pre></td>
</tr>
</table><hr/><center><h3>Suppressed warnings</h3></center><table align="center" cellspacing="0" cellpadding="3"><tr>
<th>File</th><th>Line</th><th>Rule</th><th>NOPMD or Annotation</th><th>Reason</th></tr>
<tr bgcolor="lightgrey">
<td align="left"><a href="https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java#L505">pmd-core/src/main/java/net/sourceforge/pmd/PMD.java</a></td>
<td align="center">505</td>
<td align="center"><a href="https://pmd.github.io/pmd-6.22.0/pmd_rules_java_errorprone.html#closeresource">CloseResource</a></td>
<td align="center">Annotation</td>
<td align="center"></td>
</tr>
</table><hr/><center><h3>Configuration errors</h3></center><table align="center" cellspacing="0" cellpadding="3"><tr>
<th>Rule</th><th>Problem</th></tr>
<tr bgcolor="lightgrey">
<td><a href="https://pmd.github.io/pmd-6.22.0/pmd_rules_java_design.html#loosepackagecoupling">LoosePackageCoupling</a></td>
<td>No packages or classes specified</td>
</tr>
</table></tr></table></body></html>
@@ -0,0 +1,42 @@
<html><head><title>PMD</title></head><style type="text/css"><!--
body { background-color: white; font-family:verdana, arial, helvetica, geneva; font-size: 16px; font-style: italic; color: black; }
.title { font-family: verdana, arial, helvetica,geneva; font-size: 12px; font-weight:bold; color: white; }
.body { font-family: verdana, arial, helvetica, geneva; font-size: 12px; font-weight:plain; color: black; }
#TableHeader { background-color: #003366; }
#RowColor1 { background-color: #eeeeee; }
#RowColor2 { background-color: white; }
--></style><body><center><table border="0" width="80%"><tr id=TableHeader><td colspan="2"><font class=title>&nbsp;/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java</font></tr>
<tr id=RowColor2><td width="50" align="right"><font class=body>124&nbsp;&nbsp;&nbsp;</font></td><td><font class=body>Logger calls should be surrounded by log level guards.</font></td></tr>
</table><table border="0" width="80%"><tr id=TableHeader><td colspan="2"><font class=title>&nbsp;/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java</font></tr>
<tr id=RowColor2><td width="50" align="right"><font class=body>58&nbsp;&nbsp;&nbsp;</font></td><td><font class=body>This for loop can be replaced by a foreach loop</font></td></tr>
</table><br><table border="0" width="80%"><tr id=TableHeader><td colspan="2"><font class=title>&nbsp;Problems found</font></td></tr><tr id=RowColor2><td><font class=body>/home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java</font></td><td><font class=body><pre>net.sourceforge.pmd.PMDException: Error while parsing /home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:110)
at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:89)
at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:51)
at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:78)
at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:24)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: net.sourceforge.pmd.lang.java.ast.ParseException: Encountered " "-" "- "" at line 6, column 30.
Was expecting one of:
"extends" ...
"implements" ...
"{" ...
"<" ...
at net.sourceforge.pmd.lang.java.ast.JavaParser.generateParseException(JavaParser.java:12713)
at net.sourceforge.pmd.lang.java.ast.JavaParser.jj_consume_token(JavaParser.java:12597)
at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceBody(JavaParser.java:1554)
at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceDeclaration(JavaParser.java:732)
at net.sourceforge.pmd.lang.java.ast.JavaParser.TypeDeclaration(JavaParser.java:639)
at net.sourceforge.pmd.lang.java.ast.JavaParser.CompilationUnit(JavaParser.java:373)
at net.sourceforge.pmd.lang.java.AbstractJavaParser.parse(AbstractJavaParser.java:62)
at net.sourceforge.pmd.SourceCodeProcessor.parse(SourceCodeProcessor.java:121)
at net.sourceforge.pmd.SourceCodeProcessor.processSource(SourceCodeProcessor.java:185)
at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:107)
... 10 more
</pre></font></td></tr></table><table border="0" width="80%"><tr id=TableHeader><td colspan="2"><font class=title>&nbsp;Configuration problems found</font></td></tr><tr id=RowColor2><td><font class=body>LoosePackageCoupling</font></td><td><font class=body>No packages or classes specified</font></td></tr></table></center></body></html>
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PMD - Benchmarker</title>
</head>
<body>
<h2>Class View</h2>
<h3 align="center">Class: Benchmarker</h3>
<table border="" align="center" cellspacing="0" cellpadding="3">
<tr><th>Method</th><th>Violation</th></tr>
<tr><td>findBooleanSwitch</td><td><table border="0"><tr><td><b>Rule:</b></td><td>ForLoopCanBeForeach</td></tr><tr><td><b>Description:</b></td><td>This for loop can be replaced by a foreach loop</td></tr><tr><td><b>Line:</b></td><td>58 and 62</td></tr></table></td></tr>
</table>
</body>
</html>
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PMD - RuleContext</title>
</head>
<body>
<h2>Class View</h2>
<h3 align="center">Class: RuleContext</h3>
<table border="" align="center" cellspacing="0" cellpadding="3">
<tr><th>Method</th><th>Violation</th></tr>
<tr><td>setSourceCodeFilename</td><td><table border="0"><tr><td><b>Rule:</b></td><td>GuardLogStatement</td></tr><tr><td><b>Description:</b></td><td>Logger calls should be surrounded by log level guards.</td></tr><tr><td><b>Line:</b></td><td>124 and 125</td></tr></table></td></tr>
</table>
</body>
</html>
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PMD</title>
</head>
<body>
<h2>Package View</h2>
<table border="1" align="center" cellspacing="0" cellpadding="3">
<tr><th>Package</th><th>Class</th><th>#</th></tr>
<tr><td><b>Aggregate</b></td> <td>-</td> <td>2</td></tr>
<tr><td><b>net</b></td> <td>-</td> <td>2</td></tr>
<tr><td><b>net.sourceforge</b></td> <td>-</td> <td>2</td></tr>
<tr><td><b>net.sourceforge.pmd</b></td> <td>-</td> <td>2</td></tr>
<tr><td><b>net.sourceforge.pmd</b></td> <td><a href="RuleContext.html">RuleContext</a></td> <td>1</td></tr>
<tr><td><b>net.sourceforge.pmd.benchmark</b></td> <td>-</td> <td>1</td></tr>
<tr><td><b>net.sourceforge.pmd.benchmark</b></td> <td><a href="Benchmarker.html">Benchmarker</a></td> <td>1</td></tr>
</table>
</body>
</html>
@@ -45,12 +45,13 @@ from the rest.
</description>
<priority>3</priority>
<properties>
<property name="version" value="2.0"/>
<property name="xpath">
<value>
<![CDATA[
//IfBlockStatement/BlockStatement[@CurlyBrace='false'][count(child::*) > 0]
//IfBlockStatement/BlockStatement[@CurlyBrace= false()][count(child::*) > 0]
|
//IfElseBlockStatement/BlockStatement[@CurlyBrace='false'][count(child::*) > 0]
//IfElseBlockStatement/BlockStatement[@CurlyBrace= false()][count(child::*) > 0]
]]>
</value>
</property>
@@ -82,10 +83,11 @@ controlled from the rest.
</description>
<priority>3</priority>
<properties>
<property name="version" value="2.0"/>
<property name="xpath">
<value>
<![CDATA[
//IfBlockStatement/BlockStatement[@CurlyBrace='false']
//IfBlockStatement/BlockStatement[@CurlyBrace= false()]
]]>
</value>
</property>
@@ -163,12 +165,13 @@ from the rest.
</description>
<priority>3</priority>
<properties>
<property name="version" value="2.0"/>
<property name="xpath">
<value>
<![CDATA[
//ForLoopStatement/BlockStatement[@CurlyBrace='false']
//ForLoopStatement/BlockStatement[@CurlyBrace= false()]
|
//ForEachStatement/BlockStatement[@CurlyBrace='false']
//ForEachStatement/BlockStatement[@CurlyBrace= false()]
]]>
</value>
</property>
@@ -272,6 +275,7 @@ can lead to quite messy code. This rule looks for several declarations on the sa
</description>
<priority>1</priority>
<properties>
<property name="version" value="2.0"/>
<property name="xpath">
<value>
<![CDATA[
@@ -369,10 +373,11 @@ controlled from the rest.
</description>
<priority>3</priority>
<properties>
<property name="version" value="2.0"/>
<property name="xpath">
<value>
<![CDATA[
//WhileLoopStatement/BlockStatement[@CurlyBrace='false']
//WhileLoopStatement/BlockStatement[@CurlyBrace= false()]
]]>
</value>
</property>
@@ -59,6 +59,7 @@ Avoid directly accessing Trigger.old and Trigger.new as it can lead to a bug. Tr
</description>
<priority>3</priority>
<properties>
<property name="version" value="2.0"/>
<property name="xpath">
<value>
<![CDATA[
@@ -120,6 +121,7 @@ or reported.
</description>
<priority>3</priority>
<properties>
<property name="version" value="2.0"/>
<property name="xpath">
<value>
<![CDATA[
@@ -153,6 +155,7 @@ Empty If Statement finds instances where a condition is checked but nothing is d
</description>
<priority>3</priority>
<properties>
<property name="version" value="2.0"/>
<property name="xpath">
<value>
<![CDATA[
@@ -186,10 +189,11 @@ Empty block statements serve no purpose and should be removed.
</description>
<priority>3</priority>
<properties>
<property name="version" value="2.0"/>
<property name="xpath">
<value>
<![CDATA[
//Method/ModifierNode[@Abstract!='true' and ../BlockStatement[count(*) = 0]]
//Method/ModifierNode[@Abstract!= true() and ../BlockStatement[count(*) = 0]]
| //Method/BlockStatement//BlockStatement[count(*) = 0 and @Location != parent::*/@Location]
]]>
</value>
@@ -221,6 +225,7 @@ Avoid empty try or finally blocks - what's the point?
</description>
<priority>3</priority>
<properties>
<property name="version" value="2.0"/>
<property name="xpath">
<value>
<![CDATA[
@@ -267,6 +272,7 @@ a while loop that does a lot in the exit expression, rewrite it to make it clear
</description>
<priority>3</priority>
<properties>
<property name="version" value="2.0"/>
<property name="xpath">
<value>
<![CDATA[
@@ -99,7 +99,7 @@ public abstract class AbstractTokenizer implements Tokenizer {
private int parseString(StringBuilder token, int loc, char stringDelimiter) {
boolean escaped = false;
boolean done = false;
char tok = ' '; // this will be replaced.
char tok;
while (loc < currentLine.length() && !done) {
tok = currentLine.charAt(loc);
if (escaped && tok == stringDelimiter) { // Found an escaped string
@@ -107,30 +107,24 @@ public abstract class AbstractTokenizer implements Tokenizer {
} else if (tok == stringDelimiter && token.length() > 0) {
// We are done, we found the end of the string...
done = true;
} else if (tok == '\\') { // Found an escaped char
escaped = true;
} else { // Adding char...
escaped = false;
} else {
// Found an escaped char?
escaped = tok == '\\';
}
// Adding char to String:" + token.toString());
token.append(tok);
loc++;
}
// Handling multiple lines string
if (!done && // ... we didn't find the end of the string
loc >= currentLine.length() && // ... we have reach the end of
// the line ( the String is
// incomplete, for the moment at
// least)
spanMultipleLinesString && // ... the language allow multiple
// line span Strings
lineNumber < code.size() - 1 // ... there is still more lines to
// parse
if (!done // ... we didn't find the end of the string (but the end of the line)
&& spanMultipleLinesString // ... the language allow multiple line span Strings
&& lineNumber < code.size() - 1 // ... there is still more lines to parse
) {
// removes last character, if it is the line continuation (e.g.
// backslash) character
if (spanMultipleLinesLineContinuationCharacter != null && token.length() > 0
&& token.charAt(token.length() - 1) == spanMultipleLinesLineContinuationCharacter.charValue()) {
if (spanMultipleLinesLineContinuationCharacter != null
&& token.length() > 0
&& token.charAt(token.length() - 1) == spanMultipleLinesLineContinuationCharacter) {
token.deleteCharAt(token.length() - 1);
}
// parsing new line
@@ -38,7 +38,8 @@ public interface XPathHandler {
* Get a Jaxen Navigator for this Language. May return <code>null</code> if
* there is no Jaxen Navigation for this language.
*
* @deprecated Support for Jaxen will be removed come 7.0.0
* @deprecated Support for Jaxen will be removed come 7.0.0. This isn't used
* anymore
*/
@Deprecated
Navigator getNavigator();
@@ -25,6 +25,8 @@ import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.ast.xpath.Attribute;
import net.sourceforge.pmd.lang.ast.xpath.AttributeAxisIterator;
import net.sourceforge.pmd.lang.ast.xpath.DocumentNavigator;
import net.sourceforge.pmd.lang.ast.xpath.internal.ContextualizedNavigator;
import net.sourceforge.pmd.lang.ast.xpath.internal.DeprecatedAttrLogger;
import net.sourceforge.pmd.lang.dfa.DataFlowNode;
import net.sourceforge.pmd.util.DataMap;
import net.sourceforge.pmd.util.DataMap.DataKey;
@@ -513,7 +515,8 @@ public abstract class AbstractNode implements Node {
@Override
@SuppressWarnings("unchecked")
public List<Node> findChildNodesWithXPath(final String xpathString) throws JaxenException {
return new BaseXPath(xpathString, new DocumentNavigator()).selectNodes(this);
return new BaseXPath(xpathString, new ContextualizedNavigator(DeprecatedAttrLogger.createAdHocLogger()))
.selectNodes(this);
}
@Override
@@ -9,12 +9,9 @@ import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sourceforge.pmd.annotation.Experimental;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.ast.xpath.internal.DeprecatedAttribute;
@@ -29,11 +26,6 @@ import net.sourceforge.pmd.lang.ast.xpath.internal.DeprecatedAttribute;
* @author daniels
*/
public class Attribute {
private static final Logger LOG = Logger.getLogger(Attribute.class.getName());
static final ConcurrentMap<String, Boolean> DETECTED_DEPRECATED_ATTRIBUTES = new ConcurrentHashMap<>();
private static final Object[] EMPTY_OBJ_ARRAY = new Object[0];
private final Node parent;
@@ -73,9 +65,22 @@ public class Attribute {
return method == null ? String.class : method.getReturnType();
}
private boolean isAttributeDeprecated() {
return method != null && (method.isAnnotationPresent(Deprecated.class)
|| method.isAnnotationPresent(DeprecatedAttribute.class));
/**
* Returns null for "not deprecated", empty string for "deprecated without replacement",
* otherwise name of replacement attribute.
*/
@InternalApi
public String replacementIfDeprecated() {
if (method == null) {
return null;
} else {
DeprecatedAttribute annot = method.getAnnotation(DeprecatedAttribute.class);
return annot != null
? annot.replaceWith()
: method.isAnnotationPresent(Deprecated.class)
? DeprecatedAttribute.NO_REPLACEMENT
: null;
}
}
public Object getValue() {
@@ -83,12 +88,6 @@ public class Attribute {
return value.get(0);
}
if (LOG.isLoggable(Level.WARNING) && isAttributeDeprecated()
&& DETECTED_DEPRECATED_ATTRIBUTES.putIfAbsent(getLoggableAttributeName(), Boolean.TRUE) == null) {
// this message needs to be kept in sync with PMDCoverageTest / BinaryDistributionIT
LOG.warning("Use of deprecated attribute '" + getLoggableAttributeName() + "' in XPath query");
}
// this lazy loading reduces calls to Method.invoke() by about 90%
try {
value = Collections.singletonList(method.invoke(parent, EMPTY_OBJ_ARRAY));
@@ -129,11 +128,6 @@ public class Attribute {
return Objects.hash(parent, name);
}
private String getLoggableAttributeName() {
return parent.getXPathNodeName() + "/@" + name;
}
@Override
public String toString() {
return name + ':' + getValue() + ':' + parent.getXPathNodeName();
@@ -0,0 +1,27 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.ast.xpath.internal;
import net.sourceforge.pmd.lang.ast.xpath.Attribute;
import net.sourceforge.pmd.lang.ast.xpath.DocumentNavigator;
/**
* Navigator that records attribute usages.
*/
public class ContextualizedNavigator extends DocumentNavigator {
private final DeprecatedAttrLogger ctx;
public ContextualizedNavigator(DeprecatedAttrLogger ctx) {
this.ctx = ctx;
}
@Override
public String getAttributeStringValue(Object arg0) {
Attribute attr = (Attribute) arg0;
ctx.recordUsageOf(attr);
return attr.getStringValue();
}
}
@@ -0,0 +1,117 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.ast.xpath.internal;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sourceforge.pmd.lang.ast.xpath.Attribute;
import net.sourceforge.pmd.lang.rule.XPathRule;
/**
* Records usages of deprecated attributes in XPath rules. This needs
* to be threadsafe, XPath rules have one each (and share it).
*/
public abstract class DeprecatedAttrLogger {
private static final Logger LOG = Logger.getLogger(Attribute.class.getName());
public abstract void recordUsageOf(Attribute attribute);
/**
* Create a new context for the given rule, returns a noop implementation
* if the warnings would be ignored anyway.
*/
public static DeprecatedAttrLogger create(XPathRule rule) {
if (LOG.isLoggable(Level.WARNING)) {
return new AttrLoggerImpl(rule);
} else {
return noop();
}
}
public static DeprecatedAttrLogger createAdHocLogger() {
if (LOG.isLoggable(Level.WARNING)) {
return new AdhocLoggerImpl();
} else {
return noop();
}
}
public static Noop noop() {
return Noop.INSTANCE;
}
private static String getLoggableAttributeName(Attribute attr) {
return attr.getParent().getXPathNodeName() + "/@" + attr.getName();
}
private static class Noop extends DeprecatedAttrLogger {
static final Noop INSTANCE = new Noop();
@Override
public void recordUsageOf(Attribute attribute) {
// do nothing
}
}
private static class AttrLoggerImpl extends DeprecatedAttrLogger {
private final ConcurrentMap<String, Boolean> deprecated = new ConcurrentHashMap<>();
private final XPathRule rule;
private AttrLoggerImpl(XPathRule rule) {
this.rule = rule;
}
@Override
public void recordUsageOf(Attribute attribute) {
String replacement = attribute.replacementIfDeprecated();
if (replacement != null) {
String name = getLoggableAttributeName(attribute);
Boolean b = deprecated.putIfAbsent(name, Boolean.TRUE);
if (b == null) {
// this message needs to be kept in sync with PMDCoverageTest / BinaryDistributionIT
String msg = "Use of deprecated attribute '" + name + "' by XPath rule " + ruleToString();
if (!replacement.isEmpty()) {
msg += ", please use " + replacement + " instead";
}
LOG.warning(msg);
}
}
}
public String ruleToString() {
// we can't compute that beforehand because the name is set
// outside of the rule constructor
String name = "'" + rule.getName() + "'";
if (rule.getRuleSetName() != null) {
name += " (in ruleset '" + rule.getRuleSetName() + "')";
}
return name;
}
}
private static class AdhocLoggerImpl extends DeprecatedAttrLogger {
@Override
public void recordUsageOf(Attribute attribute) {
String replacement = attribute.replacementIfDeprecated();
if (replacement != null) {
String name = getLoggableAttributeName(attribute);
// this message needs to be kept in sync with PMDCoverageTest / BinaryDistributionIT
String msg = "Use of deprecated attribute '" + name + "' in a findChildNodesWithXPath navigation";
if (!replacement.isEmpty()) {
msg += ", please use " + replacement + " instead";
}
// log with execption stack trace to help figure out where exactly the xpath is used.
LOG.log(Level.WARNING, msg, new RuntimeException(msg));
}
}
}
}
@@ -22,4 +22,13 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DeprecatedAttribute {
String NO_REPLACEMENT = "";
/**
* The simple name of the attribute to use for replacement (with '@' prefix).
* If empty, then the attribute is deprecated for removal.
*/
String replaceWith() default NO_REPLACEMENT;
}
@@ -260,11 +260,11 @@ public class AbstractNodeInfo implements VirtualNode, SiblingCountingNode {
*/
@Override
public AxisIterator iterateAxis(byte axisNumber, NodeTest nodeTest) {
AxisIterator axisIterator = iterateAxis(axisNumber);
if (nodeTest != null) {
axisIterator = new AxisFilter(axisIterator, nodeTest);
}
return axisIterator;
return filter(iterateAxis(axisNumber), nodeTest);
}
protected static AxisIterator filter(AxisIterator axisIterator, NodeTest nodeTest) {
return nodeTest != null ? new AxisFilter(axisIterator, nodeTest) : axisIterator;
}
/**
Loaded 30 of 97 files, more files were not shown because too many files have changed in this diff. Show more