Merge branch 'master' into issue-2412

This commit is contained in:
Clément Fournier
2020-04-20 10:10:47 +02:00
121 changed files with 3000 additions and 839 deletions

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)

View File

@ -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

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

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:

View File

@ -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>"

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.

View File

@ -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

View 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
```

File diff suppressed because it is too large Load Diff

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

View File

@ -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 %}

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>

View 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>

View 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>

View 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>&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>

View 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>

View 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>

View 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>

View File

@ -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;

View File

@ -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>

View File

@ -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[

View File

@ -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();

View File

@ -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

View File

@ -18,6 +18,7 @@ import net.sourceforge.pmd.util.designerbindings.DesignerBindings;
*/
public abstract class AbstractLanguageVersionHandler implements LanguageVersionHandler {
@Override
public DataFlowHandler getDataFlowHandler() {
return DataFlowHandler.DUMMY;

View File

@ -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();

View File

@ -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

View File

@ -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
}
}

View File

@ -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();

View File

@ -12,6 +12,7 @@ import net.sf.saxon.sxpath.IndependentContext;
@Deprecated
@InternalApi
public class DefaultASTXPathHandler extends AbstractASTXPathHandler {
@Override
public void initialize() {
// override if needed

View File

@ -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