Merge branch 'master' into issue-2412
This commit is contained in:
23
.github/PULL_REQUEST_TEMPLATE.md
vendored
23
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -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)
|
||||
|
||||
|
@ -49,7 +49,7 @@ jobs:
|
||||
env: BUILD=publish
|
||||
|
||||
before_install:
|
||||
- bash .travis/before_install.sh "11.0.6+10"
|
||||
- bash .travis/before_install.sh "11.0.7+10"
|
||||
- source ${HOME}/java.env
|
||||
install: true
|
||||
before_script: true
|
||||
|
@ -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
|
||||
|
||||
|
@ -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>"
|
||||
|
@ -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
|
||||
|
220
docs/pages/pmd/userdocs/cpd/cpd_report_formats.md
Normal file
220
docs/pages/pmd/userdocs/cpd/cpd_report_formats.md
Normal file
@ -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
|
||||
```
|
339
docs/pages/pmd/userdocs/pmd_report_formats.md
Normal file
339
docs/pages/pmd/userdocs/pmd_report_formats.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -46,12 +46,18 @@ 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
|
||||
* 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
|
||||
* [#2412](https://github.com/pmd/pmd/issues/2412): \[core] HTMLRenderer doesn't render links to source files
|
||||
* [#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
|
||||
* java-design
|
||||
* [#2390](https://github.com/pmd/pmd/issues/2390): \[java] AbstractClassWithoutAnyMethod: missing violation for nested classes
|
||||
@ -59,6 +65,8 @@ Note that XPath 1.0 support, the default XPath version, is deprecated since PMD
|
||||
* [#2402](https://github.com/pmd/pmd/issues/2402): \[java] CloseResource possible false positive with Primitive Streams
|
||||
* java-multithreading
|
||||
* [#2313](https://github.com/pmd/pmd/issues/2313): \[java] Documenation for DoNotUseThreads is outdated
|
||||
* javascript-errorprone
|
||||
* [#384](https://github.com/pmd/pmd/issues/384): \[javascript] Trailing commas not detected on French default locale
|
||||
|
||||
### API Changes
|
||||
|
||||
@ -69,6 +77,11 @@ Note that XPath 1.0 support, the default XPath version, is deprecated since PMD
|
||||
Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0.
|
||||
You can identify them with the `@InternalApi` annotation. You'll also get a deprecation warning.
|
||||
|
||||
* {% jdoc core::lang.rule.xpath.AbstractXPathRuleQuery %}
|
||||
* {% jdoc core::lang.rule.xpath.JaxenXPathRuleQuery %}
|
||||
* {% jdoc core::lang.rule.xpath.SaxonXPathRuleQuery %}
|
||||
* {% jdoc core::lang.rule.xpath.XPathRuleQuery %}
|
||||
|
||||
##### In ASTs
|
||||
|
||||
As part of the changes we'd like to do to AST classes for 7.0.0, we would like to
|
||||
@ -118,6 +131,12 @@ implementations, and their corresponding Parser if it exists (in the same packag
|
||||
* {% jdoc matlab::lang.matlab.MatlabTokenManager %}
|
||||
* {% jdoc objectivec::lang.objectivec.ObjectiveCTokenManager %}
|
||||
|
||||
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) %}
|
||||
@ -125,6 +144,10 @@ implementations, and their corresponding Parser if it exists (in the same packag
|
||||
* {% jdoc !!core::lang.ast.AbstractTokenManager#setFileName(java.lang.String) %}
|
||||
* {% jdoc !!core::lang.ast.AbstractTokenManager#getFileName(java.lang.String) %}
|
||||
* {% jdoc !!core::cpd.token.AntlrToken#getType() %} - use `getKind()` instead.
|
||||
* {% jdoc core::lang.rule.ImmutableLanguage %}
|
||||
* {% jdoc core::lang.rule.MockRule %}
|
||||
* {% jdoc !!java::lang.java.ast.ASTRecordDeclaration#getComponentList() %}
|
||||
* Multiple fields, constructors and methods in {% jdoc core::lang.rule.XPathRule %}. See javadoc for details.
|
||||
|
||||
### External Contributions
|
||||
|
||||
@ -137,6 +160,9 @@ implementations, and their corresponding Parser if it exists (in the same packag
|
||||
* [#2397](https://github.com/pmd/pmd/pull/2397): \[apex] fixed WITH SECURITY_ENFORCED regex to recognise line break characters - [Kieran Black](https://github.com/kieranlblack)
|
||||
* [#2401](https://github.com/pmd/pmd/pull/2401): \[doc] Update DoNotUseThreads rule documentation - [Saikat Sengupta](https://github.com/s4ik4t)
|
||||
* [#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
docs/report-examples/pmd-report-html.html
Normal file
67
docs/report-examples/pmd-report-html.html
Normal 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>
|
223
docs/report-examples/pmd-report-pmd-nicerhtml.html
Normal file
223
docs/report-examples/pmd-report-pmd-nicerhtml.html
Normal file
@ -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>
|
74
docs/report-examples/pmd-report-summaryhtml.html
Normal file
74
docs/report-examples/pmd-report-summaryhtml.html
Normal file
@ -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>
|
42
docs/report-examples/pmd-report-vbhtml.html
Normal file
42
docs/report-examples/pmd-report-vbhtml.html
Normal file
@ -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> /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 </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> /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 </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> 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> 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>
|
15
docs/report-examples/pmd-report-yahtml/Benchmarker.html
Normal file
15
docs/report-examples/pmd-report-yahtml/Benchmarker.html
Normal file
@ -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>
|
15
docs/report-examples/pmd-report-yahtml/RuleContext.html
Normal file
15
docs/report-examples/pmd-report-yahtml/RuleContext.html
Normal file
@ -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>
|
20
docs/report-examples/pmd-report-yahtml/index.html
Normal file
20
docs/report-examples/pmd-report-yahtml/index.html
Normal file
@ -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>
|
@ -12,7 +12,6 @@ import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.lang.VisitorStarter;
|
||||
import net.sourceforge.pmd.lang.XPathHandler;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTUserClassOrInterface;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
|
||||
@ -22,7 +21,6 @@ import net.sourceforge.pmd.lang.apex.metrics.api.ApexClassMetricKey;
|
||||
import net.sourceforge.pmd.lang.apex.metrics.api.ApexOperationMetricKey;
|
||||
import net.sourceforge.pmd.lang.apex.multifile.ApexMultifileVisitorFacade;
|
||||
import net.sourceforge.pmd.lang.apex.rule.ApexRuleViolationFactory;
|
||||
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
|
||||
import net.sourceforge.pmd.lang.metrics.LanguageMetricsProvider;
|
||||
import net.sourceforge.pmd.lang.metrics.internal.AbstractLanguageMetricsProvider;
|
||||
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
|
||||
@ -38,12 +36,6 @@ public class ApexHandler extends AbstractLanguageVersionHandler {
|
||||
return rootNode -> new ApexMultifileVisitorFacade().initializeWith((ApexNode<?>) rootNode);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public XPathHandler getXPathHandler() {
|
||||
return new DefaultASTXPathHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuleViolationFactory getRuleViolationFactory() {
|
||||
return ApexRuleViolationFactory.INSTANCE;
|
||||
|
@ -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[
|
||||
|
@ -305,7 +305,7 @@ public class RuleSetFactory {
|
||||
public RuleSet createSingleRuleRuleSet(final Rule rule) { // TODO make static?
|
||||
final long checksum;
|
||||
if (rule instanceof XPathRule) {
|
||||
checksum = rule.getProperty(XPathRule.XPATH_DESCRIPTOR).hashCode();
|
||||
checksum = ((XPathRule) rule).getXPathExpression().hashCode();
|
||||
} else {
|
||||
// TODO : Is this good enough? all properties' values + rule name
|
||||
checksum = rule.getPropertiesByPropertyDescriptor().values().hashCode() * 31 + rule.getName().hashCode();
|
||||
|
@ -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
|
||||
|
@ -18,6 +18,7 @@ import net.sourceforge.pmd.util.designerbindings.DesignerBindings;
|
||||
*/
|
||||
public abstract class AbstractLanguageVersionHandler implements LanguageVersionHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public DataFlowHandler getDataFlowHandler() {
|
||||
return DataFlowHandler.DUMMY;
|
||||
|
@ -7,6 +7,7 @@ package net.sourceforge.pmd.lang;
|
||||
import org.jaxen.Navigator;
|
||||
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
|
||||
import net.sourceforge.pmd.lang.xpath.Initializer;
|
||||
|
||||
import net.sf.saxon.sxpath.IndependentContext;
|
||||
@ -19,22 +20,7 @@ import net.sf.saxon.sxpath.IndependentContext;
|
||||
@Deprecated
|
||||
public interface XPathHandler {
|
||||
|
||||
XPathHandler DUMMY = new XPathHandler() {
|
||||
@Override
|
||||
public void initialize() {
|
||||
// empty handler - does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(IndependentContext context) {
|
||||
// empty handler - does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public Navigator getNavigator() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
XPathHandler DUMMY = new DefaultASTXPathHandler();
|
||||
|
||||
/**
|
||||
* Initialize. This is intended to be called by {@link Initializer} to
|
||||
@ -52,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
|
||||
|
@ -25,4 +25,14 @@ public abstract class AbstractASTXPathHandler implements XPathHandler {
|
||||
public void initialize(IndependentContext context, Language language, Class<?> functionsClass) {
|
||||
context.declareNamespace("pmd-" + language.getTerseName(), "java:" + functionsClass.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
// override if needed
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(IndependentContext context) {
|
||||
// override if needed
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -12,6 +12,7 @@ import net.sf.saxon.sxpath.IndependentContext;
|
||||
@Deprecated
|
||||
@InternalApi
|
||||
public class DefaultASTXPathHandler extends AbstractASTXPathHandler {
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
// override if needed
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user