Merge branch 'master' into pr/2964
This commit is contained in:
@@ -181,6 +181,10 @@ function pmd_ci_build_and_upload_doc() {
|
||||
pmd_code_removeJavadoc "${VERSION}-SNAPSHOT"
|
||||
|
||||
# updating github release text
|
||||
rm -f .bundle/config
|
||||
bundle config set --local path vendor/bundle
|
||||
bundle config set --local with release_notes_preprocessing
|
||||
bundle install
|
||||
# renders, and skips the first 6 lines - the Jekyll front-matter
|
||||
local rendered_release_notes=$(bundle exec .ci/render_release_notes.rb docs/pages/release_notes.md | tail -n +6)
|
||||
local release_name="PMD ${VERSION} ($(date -u +%d-%B-%Y))"
|
||||
|
||||
@@ -20,7 +20,18 @@ function maven_dependencies_resolve() {
|
||||
dokka_version=$(./mvnw -q -Dexec.executable="echo" -Dexec.args='${dokka.version}' \
|
||||
--non-recursive org.codehaus.mojo:exec-maven-plugin:3.0.0:exec)
|
||||
|
||||
./mvnw dependency:resolve
|
||||
# build first the modules, that have dependencies between themselves
|
||||
# first build pmd-lang-test, pmd-test and pmd-core - used by all modules
|
||||
./mvnw clean install -pl pmd-core,pmd-test,pmd-lang-test -DskipTests -Dpmd.skip=true \
|
||||
-Dcheckstyle.skip=true -Dmaven.javadoc.skip=true -Dmaven.source.skip=true
|
||||
# then build dependencies for pmd-visualforce needs: pmd-apex->pmd-apex-jorje+pmd-test+pmd-core
|
||||
./mvnw clean install -pl pmd-core,pmd-test,pmd-lang-test,pmd-apex-jorje,pmd-apex -DskipTests -Dpmd.skip=true \
|
||||
-Dcheckstyle.skip=true -Dmaven.javadoc.skip=true -Dmaven.source.skip=true
|
||||
|
||||
# the resolve most other projects. The excluded projects depend on other projects in the reactor, which is not
|
||||
# completely built yet, so these are excluded.
|
||||
./mvnw dependency:resolve -pl '!pmd-dist,!pmd-java8,!pmd-doc,!pmd-scala'
|
||||
|
||||
./mvnw dependency:get -DgroupId=org.jetbrains.dokka \
|
||||
-DartifactId=dokka-maven-plugin \
|
||||
-Dversion=${dokka_version} \
|
||||
|
||||
@@ -61,15 +61,17 @@ function regression_tester_uploadBaseline() {
|
||||
log_info "Generating and uploading baseline for pmdtester..."
|
||||
cd ..
|
||||
bundle config --local gemfile pmd/Gemfile
|
||||
bundle config set --local path pmd/vendor/bundle
|
||||
bundle exec pmdtester \
|
||||
--mode single \
|
||||
--local-git-repo ./pmd \
|
||||
--patch-branch ${PMD_CI_BRANCH} \
|
||||
--patch-branch ${PMD_CI_BRANCH:-$PMD_CI_TAG} \
|
||||
--patch-config ./pmd/.ci/files/all-java.xml \
|
||||
--list-of-project ./pmd/.ci/files/project-list.xml --html-flag \
|
||||
--error-recovery
|
||||
cd target/reports
|
||||
BRANCH_FILENAME="${PMD_CI_BRANCH/\//_}"
|
||||
BRANCH_FILENAME="${PMD_CI_BRANCH:-$PMD_CI_TAG}"
|
||||
BRANCH_FILENAME="${BRANCH_FILENAME/\//_}"
|
||||
zip -q -r ${BRANCH_FILENAME}-baseline.zip ${BRANCH_FILENAME}/
|
||||
# ssh-key for pmd-code.org is setup already by pmd_ci_setup_ssh
|
||||
scp ${BRANCH_FILENAME}-baseline.zip pmd@pmd-code.org:/httpdocs/pmd-regression-tester/
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Question
|
||||
url: https://github.com/pmd/pmd/discussions?discussions_q=category%3AQ%26A
|
||||
about: Feel free to ask any question about PMD and its usage
|
||||
- name: PMD Designer Issues
|
||||
url: https://github.com/pmd/pmd-designer/issues
|
||||
about: Issues about the rule designer
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
name: Question
|
||||
about: Feel free to ask any question about PMD and its usage
|
||||
title: ''
|
||||
labels: 'a:question'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Have a look at https://github.com/pmd/pmd/issues?utf8=%E2%9C%93&q=label%3Aa%3Aquestion if there is already
|
||||
a similar question -->
|
||||
|
||||
**Description:**
|
||||
|
||||
@@ -10,6 +10,10 @@ jobs:
|
||||
continue-on-error: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Ruby 2.7
|
||||
uses: actions/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 2.7
|
||||
- name: Check Environment
|
||||
run: .ci/check-environment.sh
|
||||
shell: bash
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# PMD
|
||||
|
||||
[](https://gitter.im/pmd/pmd?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://github.com/pmd/pmd/actions)
|
||||
[](https://github.com/pmd/pmd/actions)
|
||||
[](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd)
|
||||
[](https://github.com/jvm-repo-rebuild/reproducible-central#net.sourceforge.pmd:pmd)
|
||||
[](https://coveralls.io/github/pmd/pmd)
|
||||
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
repository: pmd/pmd
|
||||
|
||||
pmd:
|
||||
version: 6.30.0-SNAPSHOT
|
||||
previous_version: 6.29.0
|
||||
date: ??-November-2020
|
||||
version: 6.31.0-SNAPSHOT
|
||||
previous_version: 6.30.0
|
||||
date: ??-January-2021
|
||||
release_type: minor
|
||||
|
||||
# release types: major, minor, bugfix
|
||||
|
||||
@@ -125,6 +125,47 @@ the breaking API changes will be performed in 7.0.0.
|
||||
an API is tagged as `@Deprecated` or not in the latest minor release. During the development of 7.0.0,
|
||||
we may decide to remove some APIs that were not tagged as deprecated, though we'll try to avoid it." %}
|
||||
|
||||
#### 6.30.0
|
||||
|
||||
##### Deprecated API
|
||||
|
||||
###### Around RuleSet parsing
|
||||
|
||||
* {% jdoc core::RuleSetFactory %} and {% jdoc core::RuleSetFactoryUtils %} have been deprecated in favor of {% jdoc core::RuleSetLoader %}. This is easier to configure, and more maintainable than the multiple overloads of `RuleSetFactoryUtils`.
|
||||
* Some static creation methods have been added to {% jdoc core::RuleSet %} for simple cases, eg {% jdoc core::RuleSet#forSingleRule(core::Rule) %}. These replace some counterparts in {% jdoc core::RuleSetFactory %}
|
||||
* Since {% jdoc core::RuleSets %} is also deprecated, many APIs that require a RuleSets instance now are deprecated, and have a counterpart that expects a `List<RuleSet>`.
|
||||
* {% jdoc core::RuleSetReferenceId %}, {% jdoc core::RuleSetReference %}, {% jdoc core::RuleSetFactoryCompatibility %} are deprecated. They are most likely not relevant outside of the implementation of pmd-core.
|
||||
|
||||
###### Around the `PMD` class
|
||||
|
||||
Many classes around PMD's entry point ({% jdoc core::PMD %}) have been deprecated as internal, including:
|
||||
* The contents of the packages {% jdoc_package core::cli %}, {% jdoc_package core::processor %}
|
||||
* {% jdoc core::SourceCodeProcessor %}
|
||||
* The constructors of {% jdoc core::PMD %} (the class will be made a utility class)
|
||||
|
||||
###### Miscellaneous
|
||||
|
||||
* {% jdoc !!java::lang.java.ast.ASTPackageDeclaration#getPackageNameImage() %},
|
||||
{% jdoc !!java::lang.java.ast.ASTTypeParameter#getParameterName() %}
|
||||
and the corresponding XPath attributes. In both cases they're replaced with a new method `getName`,
|
||||
the attribute is `@Name`.
|
||||
* {% jdoc !!java::lang.java.ast.ASTClassOrInterfaceBody#isAnonymousInnerClass() %},
|
||||
and {% jdoc !!java::lang.java.ast.ASTClassOrInterfaceBody#isEnumChild() %},
|
||||
refs [#905](https://github.com/pmd/pmd/issues/905)
|
||||
|
||||
##### Internal API
|
||||
|
||||
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 !!javascript::lang.ecmascript.Ecmascript3Handler %}
|
||||
* {% jdoc !!javascript::lang.ecmascript.Ecmascript3Parser %}
|
||||
* {% jdoc !!javascript::lang.ecmascript.ast.EcmascriptParser#parserOptions %}
|
||||
* {% jdoc !!javascript::lang.ecmascript.ast.EcmascriptParser#getSuppressMap() %}
|
||||
* {% jdoc !!core::lang.rule.ParametricRuleViolation %}
|
||||
* {% jdoc !!core::lang.ParserOptions#suppressMarker %}
|
||||
* {% jdoc !!modelica::lang.modelica.rule.ModelicaRuleViolationFactory %}
|
||||
|
||||
#### 6.29.0
|
||||
|
||||
No changes.
|
||||
|
||||
@@ -12,7 +12,7 @@ author: Tom Copeland, Xavier Le Vourch <xlv@users.sourceforge.net>
|
||||
|
||||
* JDK 11 or higher
|
||||
|
||||
{% include note.html content="While Java 11 is required for building, running PMD only requires Java 7 (or Java 8 for Apex and the Designer)." %}
|
||||
{% include note.html content="While Java 11 is required for building, running PMD only requires Java 7 (or Java 8 for Apex, Scala, Visualforce, and the Designer)." %}
|
||||
|
||||
You’ll need to either check out the source code or download the latest source release. Assuming you’ve got the latest source release, unzip it to a directory:
|
||||
|
||||
|
||||
@@ -14,61 +14,11 @@ This is a {{ site.pmd.release_type }} release.
|
||||
|
||||
### New and noteworthy
|
||||
|
||||
##### CPD
|
||||
|
||||
* The C# module now supports the new option [`--ignore-literal-sequences`](https://pmd.github.io/latest/pmd_userdocs_cpd.html#-ignore-literal-sequences), which can be used to avoid detection of some uninteresting clones. Support for other languages may be added in the future. See [#2945](https://github.com/pmd/pmd/pull/2945)
|
||||
|
||||
* The Scala module now supports [suppression](https://pmd.github.io/latest/pmd_userdocs_cpd.html#suppression) through `CPD-ON`/`CPD-OFF` comment pairs. See [#2929](https://github.com/pmd/pmd/pull/2929)
|
||||
|
||||
### Fixed Issues
|
||||
|
||||
* core
|
||||
* [#1939](https://github.com/pmd/pmd/issues/1939): \[core] XPath expressions return handling
|
||||
* [#1961](https://github.com/pmd/pmd/issues/1961): \[core] Text renderer should include name of violated rule
|
||||
* [#2874](https://github.com/pmd/pmd/pull/2874): \[core] Fix XMLRenderer with UTF-16
|
||||
* cs
|
||||
* [#2938](https://github.com/pmd/pmd/pull/2938): \[cs] CPD: ignoring using directives could not be disabled
|
||||
* java
|
||||
* [#2911](https://github.com/pmd/pmd/issues/2911): \[java] `ClassTypeResolver#searchNodeNameForClass` leaks memory
|
||||
* [#2934](https://github.com/pmd/pmd/pull/2934): \[java] CompareObjectsWithEquals / UseEqualsToCompareStrings - False negatives with fields
|
||||
* [#2940](https://github.com/pmd/pmd/pull/2940): \[java] Catch additional TypeNotPresentExceptions / LinkageErrors
|
||||
* scala
|
||||
* [#2480](https://github.com/pmd/pmd/issues/2480): \[scala] Support CPD suppressions
|
||||
|
||||
|
||||
### API Changes
|
||||
|
||||
#### Deprecated API
|
||||
|
||||
* {% jdoc !!java::lang.java.ast.ASTPackageDeclaration#getPackageNameImage() %},
|
||||
{% jdoc !!java::lang.java.ast.ASTTypeParameter#getParameterName() %}
|
||||
and the corresponding XPath attributes. In both cases they're replaced with a new method `getName`,
|
||||
the attribute is `@Name`.
|
||||
* {% jdoc !!java::lang.java.ast.ASTClassOrInterfaceBody#isAnonymousInnerClass() %},
|
||||
and {% jdoc !!java::lang.java.ast.ASTClassOrInterfaceBody#isEnumChild() %},
|
||||
refs [#905](https://github.com/pmd/pmd/issues/905)
|
||||
|
||||
#### Internal API
|
||||
|
||||
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 !!javascript::lang.ecmascript.Ecmascript3Handler %}
|
||||
* {% jdoc !!javascript::lang.ecmascript.Ecmascript3Parser %}
|
||||
* {% jdoc !!javascript::lang.ecmascript.ast.EcmascriptParser#parserOptions %}
|
||||
* {% jdoc !!javascript::lang.ecmascript.ast.EcmascriptParser#getSuppressMap() %}
|
||||
* {% jdoc !!core::lang.rule.ParametricRuleViolation %}
|
||||
* {% jdoc !!core::lang.ParserOptions#suppressMarker %}
|
||||
* {% jdoc !!modelica::lang.modelica.rule.ModelicaRuleViolationFactory %}
|
||||
|
||||
|
||||
### External Contributions
|
||||
|
||||
* [#2914](https://github.com/pmd/pmd/pull/2914): \[core] Include rule name in text renderer - [Gunther Schrijvers](https://github.com/GuntherSchrijvers)
|
||||
* [#2925](https://github.com/pmd/pmd/pull/2925): Cleanup: Correct annotation array initializer indents from checkstyle #8083 - [Abhishek Kumar](https://github.com/Abhishek-kumar09)
|
||||
* [#2929](https://github.com/pmd/pmd/pull/2929): \[scala] Add support for CPD-ON and CPD-OFF special comments - [Andy Robinson](https://github.com/andyrobinson)
|
||||
* [#2936](https://github.com/pmd/pmd/pull/2936): \[java] (doc) Fix typo: "an accessor" not "a" - [Igor Moreno](https://github.com/igormoreno)
|
||||
* [#2938](https://github.com/pmd/pmd/pull/2938): \[cs] CPD: fix issue where ignoring using directives could not be disabled - [Maikel Steneker](https://github.com/maikelsteneker)
|
||||
* [#2945](https://github.com/pmd/pmd/pull/2945): \[cs] Add option to ignore sequences of literals - [Maikel Steneker](https://github.com/maikelsteneker)
|
||||
|
||||
{% endtocmaker %}
|
||||
|
||||
|
||||
@@ -5,6 +5,123 @@ permalink: pmd_release_notes_old.html
|
||||
|
||||
Previous versions of PMD can be downloaded here: https://github.com/pmd/pmd/releases
|
||||
|
||||
## 12-December-2020 - 6.30.0
|
||||
|
||||
The PMD team is pleased to announce PMD 6.30.0.
|
||||
|
||||
This is a minor release.
|
||||
|
||||
### Table Of Contents
|
||||
|
||||
* [New and noteworthy](#new-and-noteworthy)
|
||||
* [CPD](#cpd)
|
||||
* [Type information for VisualForce](#type-information-for-visualforce)
|
||||
* [Fixed Issues](#fixed-issues)
|
||||
* [API Changes](#api-changes)
|
||||
* [Deprecated API](#deprecated-api)
|
||||
* [Around RuleSet parsing](#around-ruleset-parsing)
|
||||
* [Around the `PMD` class](#around-the-`pmd`-class)
|
||||
* [Miscellaneous](#miscellaneous)
|
||||
* [Internal API](#internal-api)
|
||||
* [External Contributions](#external-contributions)
|
||||
* [Stats](#stats)
|
||||
|
||||
### New and noteworthy
|
||||
|
||||
##### CPD
|
||||
|
||||
* The C# module now supports the new option [`--ignore-literal-sequences`](https://pmd.github.io/latest/pmd_userdocs_cpd.html#-ignore-literal-sequences), which can be used to avoid detection of some uninteresting clones. Support for other languages may be added in the future. See [#2945](https://github.com/pmd/pmd/pull/2945)
|
||||
|
||||
* The Scala module now supports [suppression](https://pmd.github.io/latest/pmd_userdocs_cpd.html#suppression) through `CPD-ON`/`CPD-OFF` comment pairs. See [#2929](https://github.com/pmd/pmd/pull/2929)
|
||||
|
||||
|
||||
##### Type information for VisualForce
|
||||
|
||||
The Visualforce AST now can resolve the data type of Visualforce expressions that reference Apex Controller properties and Custom Object fields. This feature improves the precision of existing rules, like [`VfUnescapeEl`](https://pmd.github.io/pmd-6.30.0/pmd_rules_vf_security.html#vfunescapeel).
|
||||
|
||||
This can be configured using two environment variables:
|
||||
* `PMD_VF_APEXDIRECTORIES`: Comma separated list of directories for Apex classes. Absolute or relative to the Visualforce directory. Default is `../classes`. Specifying an empty string will disable data type resolution for Apex Controller properties.
|
||||
* `PMD_VF_OBJECTSDIRECTORIES`: Comma separated list of directories for Custom Objects. Absolute or relative to the Visualforce directory. Default is `../objects`. Specifying an empty string will disable data type resolution for Custom Object fields.
|
||||
|
||||
This feature is experimental, in particular, expect changes to the way the configuration is specified. We'll probably extend the CLI instead of relying on environment variables in a future version.
|
||||
|
||||
Thanks to Jeff Bartolotta and Roopa Mohan for contributing this!
|
||||
|
||||
### Fixed Issues
|
||||
|
||||
* core
|
||||
* [#1939](https://github.com/pmd/pmd/issues/1939): \[core] XPath expressions return handling
|
||||
* [#1961](https://github.com/pmd/pmd/issues/1961): \[core] Text renderer should include name of violated rule
|
||||
* [#2874](https://github.com/pmd/pmd/pull/2874): \[core] Fix XMLRenderer with UTF-16
|
||||
* cs
|
||||
* [#2938](https://github.com/pmd/pmd/pull/2938): \[cs] CPD: ignoring using directives could not be disabled
|
||||
* java
|
||||
* [#2911](https://github.com/pmd/pmd/issues/2911): \[java] `ClassTypeResolver#searchNodeNameForClass` leaks memory
|
||||
* [#2934](https://github.com/pmd/pmd/pull/2934): \[java] CompareObjectsWithEquals / UseEqualsToCompareStrings - False negatives with fields
|
||||
* [#2940](https://github.com/pmd/pmd/pull/2940): \[java] Catch additional TypeNotPresentExceptions / LinkageErrors
|
||||
* scala
|
||||
* [#2480](https://github.com/pmd/pmd/issues/2480): \[scala] Support CPD suppressions
|
||||
|
||||
|
||||
### API Changes
|
||||
|
||||
#### Deprecated API
|
||||
|
||||
|
||||
##### Around RuleSet parsing
|
||||
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetFactory.html#"><code>RuleSetFactory</code></a> and <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RulesetsFactoryUtils.html#"><code>RulesetsFactoryUtils</code></a> have been deprecated in favor of <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetLoader.html#"><code>RuleSetLoader</code></a>. This is easier to configure, and more maintainable than the multiple overloads of `RuleSetFactoryUtils`.
|
||||
* Some static creation methods have been added to <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSet.html#"><code>RuleSet</code></a> for simple cases, eg <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSet.html#forSingleRule(net.sourceforge.pmd.Rule)"><code>forSingleRule</code></a>. These replace some counterparts in <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetFactory.html#"><code>RuleSetFactory</code></a>
|
||||
* Since <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSets.html#"><code>RuleSets</code></a> is also deprecated, many APIs that require a RuleSets instance now are deprecated, and have a counterpart that expects a `List<RuleSet>`.
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetReferenceId.html#"><code>RuleSetReferenceId</code></a>, <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetReference.html#"><code>RuleSetReference</code></a>, <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetFactoryCompatibility.html#"><code>RuleSetFactoryCompatibility</code></a> are deprecated. They are most likely not relevant outside of the implementation of pmd-core.
|
||||
|
||||
##### Around the `PMD` class
|
||||
|
||||
Many classes around PMD's entry point (<a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/PMD.html#"><code>PMD</code></a>) have been deprecated as internal, including:
|
||||
* The contents of the packages <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/cli/package-summary.html#"><code>net.sourceforge.pmd.cli</code></a>, <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/processor/package-summary.html#"><code>net.sourceforge.pmd.processor</code></a>
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/SourceCodeProcessor.html#"><code>SourceCodeProcessor</code></a>
|
||||
* The constructors of <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/PMD.html#"><code>PMD</code></a> (the class will be made a utility class)
|
||||
|
||||
##### Miscellaneous
|
||||
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.30.0/net/sourceforge/pmd/lang/java/ast/ASTPackageDeclaration.html#getPackageNameImage()"><code>ASTPackageDeclaration#getPackageNameImage</code></a>,
|
||||
<a href="https://docs.pmd-code.org/apidocs/pmd-java/6.30.0/net/sourceforge/pmd/lang/java/ast/ASTTypeParameter.html#getParameterName()"><code>ASTTypeParameter#getParameterName</code></a>
|
||||
and the corresponding XPath attributes. In both cases they're replaced with a new method `getName`,
|
||||
the attribute is `@Name`.
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.30.0/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceBody.html#isAnonymousInnerClass()"><code>ASTClassOrInterfaceBody#isAnonymousInnerClass</code></a>,
|
||||
and <a href="https://docs.pmd-code.org/apidocs/pmd-java/6.30.0/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceBody.html#isEnumChild()"><code>ASTClassOrInterfaceBody#isEnumChild</code></a>,
|
||||
refs [#905](https://github.com/pmd/pmd/issues/905)
|
||||
|
||||
#### Internal API
|
||||
|
||||
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.
|
||||
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-javascript/6.30.0/net/sourceforge/pmd/lang/ecmascript/Ecmascript3Handler.html#"><code>net.sourceforge.pmd.lang.ecmascript.Ecmascript3Handler</code></a>
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-javascript/6.30.0/net/sourceforge/pmd/lang/ecmascript/Ecmascript3Parser.html#"><code>net.sourceforge.pmd.lang.ecmascript.Ecmascript3Parser</code></a>
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-javascript/6.30.0/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParser.html#parserOptions"><code>EcmascriptParser#parserOptions</code></a>
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-javascript/6.30.0/net/sourceforge/pmd/lang/ecmascript/ast/EcmascriptParser.html#getSuppressMap()"><code>EcmascriptParser#getSuppressMap</code></a>
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/lang/rule/ParametricRuleViolation.html#"><code>net.sourceforge.pmd.lang.rule.ParametricRuleViolation</code></a>
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/lang/ParserOptions.html#suppressMarker"><code>ParserOptions#suppressMarker</code></a>
|
||||
* <a href="https://docs.pmd-code.org/apidocs/pmd-modelica/6.30.0/net/sourceforge/pmd/lang/modelica/rule/ModelicaRuleViolationFactory.html#"><code>net.sourceforge.pmd.lang.modelica.rule.ModelicaRuleViolationFactory</code></a>
|
||||
|
||||
|
||||
### External Contributions
|
||||
|
||||
* [#2864](https://github.com/pmd/pmd/pull/2864): [vf] Provide expression type information to Visualforce rules to avoid false positives - [Jeff Bartolotta](https://github.com/jbartolotta-sfdc)
|
||||
* [#2914](https://github.com/pmd/pmd/pull/2914): \[core] Include rule name in text renderer - [Gunther Schrijvers](https://github.com/GuntherSchrijvers)
|
||||
* [#2925](https://github.com/pmd/pmd/pull/2925): Cleanup: Correct annotation array initializer indents from checkstyle #8083 - [Abhishek Kumar](https://github.com/Abhishek-kumar09)
|
||||
* [#2929](https://github.com/pmd/pmd/pull/2929): \[scala] Add support for CPD-ON and CPD-OFF special comments - [Andy Robinson](https://github.com/andyrobinson)
|
||||
* [#2936](https://github.com/pmd/pmd/pull/2936): \[java] (doc) Fix typo: "an accessor" not "a" - [Igor Moreno](https://github.com/igormoreno)
|
||||
* [#2938](https://github.com/pmd/pmd/pull/2938): \[cs] CPD: fix issue where ignoring using directives could not be disabled - [Maikel Steneker](https://github.com/maikelsteneker)
|
||||
* [#2945](https://github.com/pmd/pmd/pull/2945): \[cs] Add option to ignore sequences of literals - [Maikel Steneker](https://github.com/maikelsteneker)
|
||||
* [#2962](https://github.com/pmd/pmd/pull/2962): \[cpp] Add support for C++ 14 binary literals - [Maikel Steneker](https://github.com/maikelsteneker)
|
||||
|
||||
### Stats
|
||||
* 190 commits
|
||||
* 25 closed tickets & PRs
|
||||
* Days since last release: 49
|
||||
|
||||
## 24-October-2020 - 6.29.0
|
||||
|
||||
The PMD team is pleased to announce PMD 6.29.0.
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.30.0-SNAPSHOT</version>
|
||||
<version>6.31.0-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.30.0-SNAPSHOT</version>
|
||||
<version>6.31.0-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -14,16 +14,15 @@ import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.contrib.java.lang.system.SystemErrRule;
|
||||
|
||||
import net.sourceforge.pmd.RulePriority;
|
||||
import net.sourceforge.pmd.RuleSet;
|
||||
import net.sourceforge.pmd.RuleSetFactory;
|
||||
import net.sourceforge.pmd.RulesetsFactoryUtils;
|
||||
import net.sourceforge.pmd.RuleSetLoader;
|
||||
|
||||
public class DefaultRulesetTest {
|
||||
@Rule
|
||||
public final SystemErrRule systemErrRule = new SystemErrRule().enableLog().muteForSuccessfulTests();
|
||||
|
||||
private RuleSetFactory factory = RulesetsFactoryUtils.createFactory(RulePriority.LOW, true, false);
|
||||
private RuleSetFactory factory = new RuleSetLoader().enableCompatibility(false).toFactory();
|
||||
|
||||
@Test
|
||||
public void loadDefaultRuleset() throws Exception {
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>6.30.0-SNAPSHOT</version>
|
||||
<version>6.31.0-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -11,16 +11,18 @@ import java.io.Writer;
|
||||
import java.net.URISyntaxException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
import net.sourceforge.pmd.benchmark.TextTimingReportRenderer;
|
||||
import net.sourceforge.pmd.benchmark.TimeTracker;
|
||||
import net.sourceforge.pmd.benchmark.TimedOperation;
|
||||
@@ -41,11 +43,9 @@ import net.sourceforge.pmd.processor.AbstractPMDProcessor;
|
||||
import net.sourceforge.pmd.processor.MonoThreadProcessor;
|
||||
import net.sourceforge.pmd.processor.MultiThreadProcessor;
|
||||
import net.sourceforge.pmd.renderers.Renderer;
|
||||
import net.sourceforge.pmd.stat.Metric;
|
||||
import net.sourceforge.pmd.util.ClasspathClassLoader;
|
||||
import net.sourceforge.pmd.util.FileUtil;
|
||||
import net.sourceforge.pmd.util.IOUtil;
|
||||
import net.sourceforge.pmd.util.ResourceLoader;
|
||||
import net.sourceforge.pmd.util.database.DBMSMetadata;
|
||||
import net.sourceforge.pmd.util.database.DBURI;
|
||||
import net.sourceforge.pmd.util.database.SourceObject;
|
||||
@@ -89,7 +89,10 @@ public class PMD {
|
||||
/**
|
||||
* Create a PMD instance using a default Configuration. Changes to the
|
||||
* configuration may be required.
|
||||
*
|
||||
* @deprecated Just use the static methods, and maintain your {@link PMDConfiguration} separately.
|
||||
*/
|
||||
@Deprecated
|
||||
public PMD() {
|
||||
this(new PMDConfiguration());
|
||||
}
|
||||
@@ -97,9 +100,11 @@ public class PMD {
|
||||
/**
|
||||
* Create a PMD instance using the specified Configuration.
|
||||
*
|
||||
* @param configuration
|
||||
* The runtime Configuration of PMD to use.
|
||||
* @param configuration The runtime Configuration of PMD to use.
|
||||
*
|
||||
* @deprecated Just use the static methods, and maintain your {@link PMDConfiguration} separately.
|
||||
*/
|
||||
@Deprecated
|
||||
public PMD(PMDConfiguration configuration) {
|
||||
this.configuration = configuration;
|
||||
this.rulesetsFileProcessor = new SourceCodeProcessor(configuration);
|
||||
@@ -115,7 +120,10 @@ public class PMD {
|
||||
* @throws PMDException
|
||||
* if the URI couldn't be parsed
|
||||
* @see DBURI
|
||||
*
|
||||
* @deprecated Will be hidden as part of the parsing of {@link PMD#getApplicableFiles(PMDConfiguration, Set)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static List<DataSource> getURIDataSources(String uriString) throws PMDException {
|
||||
List<DataSource> dataSources = new ArrayList<>();
|
||||
|
||||
@@ -161,7 +169,11 @@ public class PMD {
|
||||
* @param configuration
|
||||
* the given configuration
|
||||
* @return the pre-configured parser
|
||||
*
|
||||
* @deprecated This is internal
|
||||
*/
|
||||
@Deprecated
|
||||
@InternalApi
|
||||
public static Parser parserFor(LanguageVersion languageVersion, PMDConfiguration configuration) {
|
||||
|
||||
// TODO Handle Rules having different parser options.
|
||||
@@ -179,7 +191,10 @@ public class PMD {
|
||||
*
|
||||
* @return The configuration.
|
||||
* @see PMDConfiguration
|
||||
*
|
||||
* @deprecated Don't create a PMD instance just to create a {@link PMDConfiguration}
|
||||
*/
|
||||
@Deprecated
|
||||
public PMDConfiguration getConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
@@ -188,7 +203,9 @@ public class PMD {
|
||||
* Gets the source code processor.
|
||||
*
|
||||
* @return SourceCodeProcessor
|
||||
* @deprecated Source code processor is internal
|
||||
*/
|
||||
@Deprecated
|
||||
public SourceCodeProcessor getSourceCodeProcessor() {
|
||||
return rulesetsFileProcessor;
|
||||
}
|
||||
@@ -203,7 +220,7 @@ public class PMD {
|
||||
public static int doPMD(PMDConfiguration configuration) {
|
||||
|
||||
// Load the RuleSets
|
||||
final RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.getRulesetFactory(configuration, new ResourceLoader());
|
||||
final RuleSetFactory ruleSetFactory = RuleSetLoader.fromPmdConfig(configuration).toFactory();
|
||||
final RuleSets ruleSets = RulesetsFactoryUtils.getRuleSetsWithBenchmark(configuration.getRuleSets(), ruleSetFactory);
|
||||
if (ruleSets == null) {
|
||||
return PMDCommandLineInterface.NO_ERRORS_STATUS;
|
||||
@@ -221,28 +238,15 @@ public class PMD {
|
||||
renderer.start();
|
||||
}
|
||||
|
||||
RuleContext ctx = new RuleContext();
|
||||
final AtomicInteger violations = new AtomicInteger(0);
|
||||
ctx.getReport().addListener(new ThreadSafeReportListener() {
|
||||
@Override
|
||||
public void ruleViolationAdded(RuleViolation ruleViolation) {
|
||||
violations.getAndIncrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void metricAdded(Metric metric) {
|
||||
// ignored - not needed for counting violations
|
||||
}
|
||||
});
|
||||
|
||||
Report report;
|
||||
try (TimedOperation to = TimeTracker.startOperation(TimedOperationCategory.FILE_PROCESSING)) {
|
||||
processFiles(configuration, ruleSetFactory, files, ctx, renderers);
|
||||
report = processFiles(configuration, Arrays.asList(ruleSets.getAllRuleSets()), files, renderers);
|
||||
}
|
||||
|
||||
try (TimedOperation rto = TimeTracker.startOperation(TimedOperationCategory.REPORTING)) {
|
||||
renderer.end();
|
||||
renderer.flush();
|
||||
return violations.get();
|
||||
return report.getViolations().size();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String message = e.getMessage();
|
||||
@@ -274,7 +278,10 @@ public class PMD {
|
||||
* @param sourceCodeFile
|
||||
* the source code file
|
||||
* @return the rule context
|
||||
*
|
||||
* @deprecated Not useful
|
||||
*/
|
||||
@Deprecated
|
||||
public static RuleContext newRuleContext(String sourceCodeFilename, File sourceCodeFile) {
|
||||
|
||||
RuleContext context = new RuleContext();
|
||||
@@ -297,19 +304,60 @@ public class PMD {
|
||||
* RuleContext
|
||||
* @param renderers
|
||||
* List of {@link Renderer}s
|
||||
*
|
||||
* @deprecated Use {@link #processFiles(PMDConfiguration, List, Collection, List)}
|
||||
* so as not to depend on {@link RuleSetFactory}. Note that this sorts the list of data sources in-place,
|
||||
* which won't be fixed
|
||||
*/
|
||||
@Deprecated
|
||||
public static void processFiles(final PMDConfiguration configuration, final RuleSetFactory ruleSetFactory,
|
||||
final List<DataSource> files, final RuleContext ctx, final List<Renderer> renderers) {
|
||||
// Note that this duplicates the other routine, because the old behavior was
|
||||
// that we parsed rulesets (a second time) inside the processor execution.
|
||||
// To not mess up error handling, we keep this behavior.
|
||||
|
||||
encourageToUseIncrementalAnalysis(configuration);
|
||||
sortFiles(configuration, files);
|
||||
// Make sure the cache is listening for analysis results
|
||||
ctx.getReport().addListener(configuration.getAnalysisCache());
|
||||
|
||||
final RuleSetFactory silentFactory = new RuleSetFactory(ruleSetFactory, false);
|
||||
final RuleSetFactory silentFactory = ruleSetFactory.toLoader().warnDeprecated(false).toFactory();
|
||||
newFileProcessor(configuration).processFiles(silentFactory, files, ctx, renderers);
|
||||
configuration.getAnalysisCache().persist();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run PMD using the given configuration. This replaces the other overload.
|
||||
*
|
||||
* @param configuration Configuration for the run. Note that the files,
|
||||
* and rulesets, are ignored, as they are supplied
|
||||
* as parameters
|
||||
* @param rulesets Parsed rulesets
|
||||
* @param files Files to process, will be closed by this method.
|
||||
* @param renderers Renderers that render the report
|
||||
*
|
||||
* @return Report in which violations are accumulated
|
||||
*
|
||||
* @throws RuntimeException If processing fails
|
||||
*/
|
||||
public static Report processFiles(final PMDConfiguration configuration,
|
||||
final List<RuleSet> rulesets,
|
||||
final Collection<? extends DataSource> files,
|
||||
final List<Renderer> renderers) {
|
||||
encourageToUseIncrementalAnalysis(configuration);
|
||||
Report report = new Report();
|
||||
report.addListener(configuration.getAnalysisCache());
|
||||
|
||||
List<DataSource> sortedFiles = new ArrayList<>(files);
|
||||
sortFiles(configuration, sortedFiles);
|
||||
|
||||
RuleContext ctx = new RuleContext();
|
||||
ctx.setReport(report);
|
||||
newFileProcessor(configuration).processFiles(new RuleSets(rulesets), sortedFiles, ctx, renderers);
|
||||
configuration.getAnalysisCache().persist();
|
||||
return report;
|
||||
}
|
||||
|
||||
private static void sortFiles(final PMDConfiguration configuration, final List<DataSource> files) {
|
||||
if (configuration.isStressTest()) {
|
||||
// randomize processing order
|
||||
@@ -442,7 +490,7 @@ public class PMD {
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry to invoke PMD as command line tool
|
||||
* Entry to invoke PMD as command line tool. Note that this will invoke {@link System#exit(int)}.
|
||||
*
|
||||
* @param args
|
||||
* command line arguments
|
||||
@@ -452,7 +500,8 @@ public class PMD {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the command line arguments and executes PMD.
|
||||
* Parses the command line arguments and executes PMD. Returns the
|
||||
* exit code without exiting the VM.
|
||||
*
|
||||
* @param args
|
||||
* command line arguments
|
||||
|
||||
@@ -13,6 +13,7 @@ package net.sourceforge.pmd;
|
||||
* @version $Revision$, $Date$
|
||||
* @since August 30, 2002
|
||||
*/
|
||||
@Deprecated
|
||||
public class PMDException extends Exception {
|
||||
private static final long serialVersionUID = 6938647389367956874L;
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ public class Report implements Iterable<RuleViolation> {
|
||||
private final List<ThreadSafeReportListener> listeners = new ArrayList<>();
|
||||
private final List<ProcessingError> errors = new ArrayList<>();
|
||||
private final List<ConfigurationError> configErrors = new ArrayList<>();
|
||||
private final Object lock = new Object();
|
||||
private Map<Integer, String> linesToSuppress = new HashMap<>();
|
||||
private long start;
|
||||
private long end;
|
||||
@@ -394,11 +395,15 @@ public class Report implements Iterable<RuleViolation> {
|
||||
* summary over all violations is needed as PMD creates one report per file
|
||||
* by default.
|
||||
*
|
||||
* @param r
|
||||
* the report to be merged into this.
|
||||
* <p>This is synchronized on an internal lock (note that other mutation
|
||||
* operations are not synchronized, todo for pmd 7).
|
||||
*
|
||||
* @param r the report to be merged into this.
|
||||
*
|
||||
* @see AbstractAccumulatingRenderer
|
||||
*/
|
||||
public void merge(Report r) {
|
||||
synchronized (lock) {
|
||||
errors.addAll(r.errors);
|
||||
configErrors.addAll(r.configErrors);
|
||||
metrics.addAll(r.metrics);
|
||||
@@ -410,6 +415,7 @@ public class Report implements Iterable<RuleViolation> {
|
||||
violationTree.addRuleViolation(violation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether any metrics have been reported
|
||||
|
||||
@@ -28,6 +28,7 @@ import net.sourceforge.pmd.lang.Language;
|
||||
import net.sourceforge.pmd.lang.LanguageVersion;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.rule.RuleReference;
|
||||
import net.sourceforge.pmd.lang.rule.XPathRule;
|
||||
import net.sourceforge.pmd.util.filter.Filter;
|
||||
import net.sourceforge.pmd.util.filter.Filters;
|
||||
|
||||
@@ -100,6 +101,89 @@ public class RuleSet implements ChecksumAware {
|
||||
filter = rs.filter; // filters are immutable, can be shared
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ruleset containing a single rule. The ruleset will
|
||||
* have default description, name, and null file name.
|
||||
*
|
||||
* @param rule The rule being created
|
||||
*
|
||||
* @return The newly created RuleSet
|
||||
*/
|
||||
public static RuleSet forSingleRule(final Rule rule) {
|
||||
final long checksum;
|
||||
if (rule instanceof XPathRule) {
|
||||
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();
|
||||
}
|
||||
|
||||
final RuleSetBuilder builder =
|
||||
new RuleSetBuilder(checksum)
|
||||
.withName(rule.getName())
|
||||
.withDescription("RuleSet for " + rule.getName());
|
||||
builder.addRule(rule);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new ruleset with the given metadata such as name, description,
|
||||
* fileName, exclude/include patterns are used. The rules are taken from the given
|
||||
* collection.
|
||||
*
|
||||
* <p><strong>Note:</strong> The rule instances are shared between the collection
|
||||
* and the new ruleset (copy-by-reference). This might lead to concurrency issues,
|
||||
* if the rules of the collection are also referenced by other rulesets and used
|
||||
* in different threads.
|
||||
* </p>
|
||||
*
|
||||
* @param name the name of the ruleset
|
||||
* @param description the description
|
||||
* @param fileName the filename
|
||||
* @param excludePatterns list of exclude patterns
|
||||
* @param includePatterns list of include patterns, that override the exclude patterns
|
||||
* @param rules the collection with the rules to add to the new ruleset
|
||||
*
|
||||
* @return the new ruleset
|
||||
*
|
||||
* @throws NullPointerException If any parameter is null, or the collections contain null elements
|
||||
*/
|
||||
public static RuleSet create(String name,
|
||||
String description,
|
||||
String fileName,
|
||||
Collection<Pattern> excludePatterns,
|
||||
Collection<Pattern> includePatterns,
|
||||
Iterable<? extends Rule> rules) {
|
||||
RuleSetBuilder builder = new RuleSetBuilder(0L); // TODO: checksum missing
|
||||
builder.withName(name)
|
||||
.withDescription(description)
|
||||
.withFileName(fileName)
|
||||
.replaceFileExclusions(excludePatterns)
|
||||
.replaceFileInclusions(includePatterns);
|
||||
for (Rule rule : rules) {
|
||||
builder.addRule(rule);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of the given ruleset. All properties like name, description, fileName
|
||||
* and exclude/include patterns are copied.
|
||||
*
|
||||
* <p><strong>Note:</strong> The rule instances are shared between the original
|
||||
* and the new ruleset (copy-by-reference). This might lead to concurrency issues,
|
||||
* if the original ruleset and the new ruleset are used in different threads.
|
||||
* </p>
|
||||
*
|
||||
* @param original the original rule set to copy from
|
||||
*
|
||||
* @return the copy
|
||||
*/
|
||||
public static RuleSet copy(RuleSet original) {
|
||||
return new RuleSet(original);
|
||||
}
|
||||
|
||||
/* package */ static class RuleSetBuilder {
|
||||
|
||||
public String description;
|
||||
|
||||
@@ -13,7 +13,6 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@@ -34,22 +33,20 @@ import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import net.sourceforge.pmd.RuleSet.RuleSetBuilder;
|
||||
import net.sourceforge.pmd.lang.Language;
|
||||
import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||
import net.sourceforge.pmd.lang.rule.MockRule;
|
||||
import net.sourceforge.pmd.lang.rule.RuleReference;
|
||||
import net.sourceforge.pmd.lang.rule.XPathRule;
|
||||
import net.sourceforge.pmd.rules.RuleFactory;
|
||||
import net.sourceforge.pmd.util.ResourceLoader;
|
||||
|
||||
/**
|
||||
* RuleSetFactory is responsible for creating RuleSet instances from XML
|
||||
* content. By default Rules will be loaded using the {@link RulePriority#LOW} priority,
|
||||
* with Rule deprecation warnings off;
|
||||
* the ruleset compatibility filter is active, too (see {@link RuleSetFactoryCompatibility});
|
||||
* if the ruleset contains rule references (e.g. for renamed or moved rules), these
|
||||
* are ignored by default.
|
||||
* content. See {@link RuleSetLoader} for configuration options and
|
||||
* their defaults.
|
||||
*
|
||||
* @deprecated Use a {@link RuleSetLoader} instead. This will be hidden in PMD 7
|
||||
* (it's the implementation, while {@link RuleSetLoader} is the API).
|
||||
*/
|
||||
@Deprecated
|
||||
public class RuleSetFactory {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(RuleSetFactory.class.getName());
|
||||
@@ -67,7 +64,7 @@ public class RuleSetFactory {
|
||||
private final Map<RuleSetReferenceId, RuleSet> parsedRulesets = new HashMap<>();
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link RulesetsFactoryUtils#defaultFactory()}
|
||||
* @deprecated Use a {@link RuleSetLoader} to build a new factory
|
||||
*/
|
||||
@Deprecated // to be removed with PMD 7.0.0.
|
||||
public RuleSetFactory() {
|
||||
@@ -75,8 +72,7 @@ public class RuleSetFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link RulesetsFactoryUtils#createFactory(ClassLoader, RulePriority, boolean, boolean)}
|
||||
* or {@link RulesetsFactoryUtils#createFactory(RulePriority, boolean, boolean)}
|
||||
* @deprecated Use a {@link RuleSetLoader} to build a new factory
|
||||
*/
|
||||
@Deprecated // to be removed with PMD 7.0.0.
|
||||
public RuleSetFactory(final ClassLoader classLoader, final RulePriority minimumPriority,
|
||||
@@ -85,8 +81,7 @@ public class RuleSetFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link RulesetsFactoryUtils#createFactory(ClassLoader, RulePriority, boolean, boolean)}
|
||||
* or {@link RulesetsFactoryUtils#createFactory(RulePriority, boolean, boolean)}
|
||||
* @deprecated Use a {@link RuleSetLoader} to build a new factory
|
||||
*/
|
||||
@Deprecated // to be hidden with PMD 7.0.0.
|
||||
public RuleSetFactory(final ResourceLoader resourceLoader, final RulePriority minimumPriority,
|
||||
@@ -111,16 +106,18 @@ public class RuleSetFactory {
|
||||
/**
|
||||
* Constructor copying all configuration from another factory.
|
||||
*
|
||||
* @param factory
|
||||
* The factory whose configuration to copy.
|
||||
* @param warnDeprecated
|
||||
* Whether deprecation warnings are to be produced by this
|
||||
* factory.
|
||||
* @param factory The factory whose configuration to copy.
|
||||
* @param warnDeprecated Whether deprecation warnings are to be produced by this
|
||||
* factory
|
||||
*
|
||||
* @deprecated Use {@link #toLoader()} to rebuild a factory from a configuration
|
||||
*/
|
||||
@Deprecated
|
||||
public RuleSetFactory(final RuleSetFactory factory, final boolean warnDeprecated) {
|
||||
this(factory.resourceLoader, factory.minimumPriority, warnDeprecated, factory.compatibilityFilter != null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the compatibility filter in order to adjust it, e.g. add additional
|
||||
* filters.
|
||||
@@ -138,28 +135,12 @@ public class RuleSetFactory {
|
||||
* @return An Iterator of RuleSet objects.
|
||||
*
|
||||
* @throws RuleSetNotFoundException if the ruleset file could not be found
|
||||
*
|
||||
* @deprecated Use {@link RuleSetLoader#getStandardRuleSets()}
|
||||
*/
|
||||
@Deprecated
|
||||
public Iterator<RuleSet> getRegisteredRuleSets() throws RuleSetNotFoundException {
|
||||
String rulesetsProperties = null;
|
||||
List<RuleSetReferenceId> ruleSetReferenceIds = new ArrayList<>();
|
||||
for (Language language : LanguageRegistry.findWithRuleSupport()) {
|
||||
Properties props = new Properties();
|
||||
rulesetsProperties = "category/" + language.getTerseName() + "/categories.properties";
|
||||
try (InputStream inputStream = resourceLoader.loadClassPathResourceAsStreamOrThrow(rulesetsProperties)) {
|
||||
props.load(inputStream);
|
||||
String rulesetFilenames = props.getProperty("rulesets.filenames");
|
||||
if (rulesetFilenames != null) {
|
||||
ruleSetReferenceIds.addAll(RuleSetReferenceId.parse(rulesetFilenames));
|
||||
}
|
||||
} catch (RuleSetNotFoundException e) {
|
||||
LOG.warning("The language " + language.getTerseName() + " provides no " + rulesetsProperties + ".");
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException("Couldn't find " + rulesetsProperties
|
||||
+ "; please ensure that the directory is on the classpath. The current classpath is: "
|
||||
+ System.getProperty("java.class.path"));
|
||||
}
|
||||
}
|
||||
return createRuleSets(ruleSetReferenceIds).getRuleSetsIterator();
|
||||
return toLoader().getStandardRuleSets().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,7 +155,11 @@ public class RuleSetFactory {
|
||||
* @return The new RuleSets.
|
||||
* @throws RuleSetNotFoundException
|
||||
* if unable to find a resource.
|
||||
*
|
||||
* @deprecated Use {@link RuleSetLoader#loadFromResource(String)},
|
||||
* but note that that method does not split on commas
|
||||
*/
|
||||
@Deprecated
|
||||
public RuleSets createRuleSets(String referenceString) throws RuleSetNotFoundException {
|
||||
return createRuleSets(RuleSetReferenceId.parse(referenceString));
|
||||
}
|
||||
@@ -188,7 +173,10 @@ public class RuleSetFactory {
|
||||
* @return The new RuleSets.
|
||||
* @throws RuleSetNotFoundException
|
||||
* if unable to find a resource.
|
||||
*
|
||||
* @deprecated Will not be replaced
|
||||
*/
|
||||
@Deprecated
|
||||
public RuleSets createRuleSets(List<RuleSetReferenceId> ruleSetReferenceIds) throws RuleSetNotFoundException {
|
||||
RuleSets ruleSets = new RuleSets();
|
||||
for (RuleSetReferenceId ruleSetReferenceId : ruleSetReferenceIds) {
|
||||
@@ -210,7 +198,10 @@ public class RuleSetFactory {
|
||||
* @return A new RuleSet.
|
||||
* @throws RuleSetNotFoundException
|
||||
* if unable to find a resource.
|
||||
*
|
||||
* @deprecated Use {@link RuleSetLoader#loadFromResource(String)} and discard the rest of the list.
|
||||
*/
|
||||
@Deprecated
|
||||
public RuleSet createRuleSet(String referenceString) throws RuleSetNotFoundException {
|
||||
List<RuleSetReferenceId> references = RuleSetReferenceId.parse(referenceString);
|
||||
if (references.isEmpty()) {
|
||||
@@ -229,7 +220,10 @@ public class RuleSetFactory {
|
||||
* @return A new RuleSet.
|
||||
* @throws RuleSetNotFoundException
|
||||
* if unable to find a resource.
|
||||
*
|
||||
* @deprecated Will not be replaced
|
||||
*/
|
||||
@Deprecated
|
||||
public RuleSet createRuleSet(RuleSetReferenceId ruleSetReferenceId) throws RuleSetNotFoundException {
|
||||
return createRuleSet(ruleSetReferenceId, includeDeprecatedRuleReferences);
|
||||
}
|
||||
@@ -250,7 +244,10 @@ public class RuleSetFactory {
|
||||
*
|
||||
* @param original the original rule set to copy from
|
||||
* @return the copy
|
||||
*
|
||||
* @deprecated Use {@link RuleSet#copy(RuleSet)}
|
||||
*/
|
||||
@Deprecated
|
||||
public RuleSet createRuleSetCopy(RuleSet original) {
|
||||
RuleSetBuilder builder = new RuleSetBuilder(original);
|
||||
return builder.build();
|
||||
@@ -274,23 +271,17 @@ public class RuleSetFactory {
|
||||
* @param includePatterns list of include patterns, if any is not a valid regular expression, it will be ignored
|
||||
* @param rules the collection with the rules to add to the new ruleset
|
||||
* @return the new ruleset
|
||||
*
|
||||
* @deprecated Use {@link RuleSet#create(String, String, String, Collection, Collection, Iterable)}
|
||||
*/
|
||||
@Deprecated
|
||||
public RuleSet createNewRuleSet(String name,
|
||||
String description,
|
||||
String fileName,
|
||||
Collection<String> excludePatterns,
|
||||
Collection<String> includePatterns,
|
||||
Collection<Rule> rules) {
|
||||
RuleSetBuilder builder = new RuleSetBuilder(0L); // TODO: checksum missing
|
||||
builder.withName(name)
|
||||
.withDescription(description)
|
||||
.withFileName(fileName)
|
||||
.replaceFileExclusions(toPatterns(excludePatterns))
|
||||
.replaceFileInclusions(toPatterns(includePatterns));
|
||||
for (Rule rule : rules) {
|
||||
builder.addRule(rule);
|
||||
}
|
||||
return builder.build();
|
||||
return RuleSet.create(name, description, fileName, toPatterns(excludePatterns), toPatterns(includePatterns), rules);
|
||||
}
|
||||
|
||||
private Collection<Pattern> toPatterns(Collection<String> sources) {
|
||||
@@ -308,24 +299,15 @@ public class RuleSetFactory {
|
||||
/**
|
||||
* Creates a new RuleSet containing a single rule.
|
||||
*
|
||||
* @param rule
|
||||
* The rule being created
|
||||
* @param rule The rule being created
|
||||
*
|
||||
* @return The newly created RuleSet
|
||||
*
|
||||
* @deprecated Use {@link RuleSet#forSingleRule(Rule)}
|
||||
*/
|
||||
public RuleSet createSingleRuleRuleSet(final Rule rule) { // TODO make static?
|
||||
final long checksum;
|
||||
if (rule instanceof XPathRule) {
|
||||
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();
|
||||
}
|
||||
|
||||
final RuleSetBuilder builder = new RuleSetBuilder(checksum)
|
||||
.withName(rule.getName())
|
||||
.withDescription("RuleSet for " + rule.getName());
|
||||
builder.addRule(rule);
|
||||
return builder.build();
|
||||
@Deprecated
|
||||
public RuleSet createSingleRuleRuleSet(final Rule rule) {
|
||||
return RuleSet.forSingleRule(rule);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -348,7 +330,8 @@ public class RuleSetFactory {
|
||||
private Rule createRule(RuleSetReferenceId ruleSetReferenceId, boolean withDeprecatedRuleReferences)
|
||||
throws RuleSetNotFoundException {
|
||||
if (ruleSetReferenceId.isAllRules()) {
|
||||
throw new IllegalArgumentException("Cannot parse a single Rule from an all Rule RuleSet reference: <" + ruleSetReferenceId + ">.");
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot parse a single Rule from an all Rule RuleSet reference: <" + ruleSetReferenceId + ">.");
|
||||
}
|
||||
RuleSet ruleSet;
|
||||
// java8: computeIfAbsent
|
||||
@@ -438,9 +421,6 @@ public class RuleSetFactory {
|
||||
ruleSetBuilder.filterRulesByPriority(minimumPriority);
|
||||
|
||||
return ruleSetBuilder.build();
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
ex.printStackTrace();
|
||||
throw new RuntimeException("Couldn't find the class " + ex.getMessage(), ex);
|
||||
} catch (ParserConfigurationException | IOException | SAXException ex) {
|
||||
ex.printStackTrace();
|
||||
throw new RuntimeException("Couldn't read the ruleset " + ruleSetReferenceId + ": " + ex.getMessage(), ex);
|
||||
@@ -512,7 +492,7 @@ public class RuleSetFactory {
|
||||
*/
|
||||
private void parseRuleNode(RuleSetReferenceId ruleSetReferenceId, RuleSetBuilder ruleSetBuilder, Node ruleNode,
|
||||
boolean withDeprecatedRuleReferences, Set<String> rulesetReferences)
|
||||
throws ClassNotFoundException, InstantiationException, IllegalAccessException, RuleSetNotFoundException {
|
||||
throws RuleSetNotFoundException {
|
||||
Element ruleElement = (Element) ruleNode;
|
||||
String ref = ruleElement.getAttribute("ref");
|
||||
if (ref.endsWith("xml")) {
|
||||
@@ -557,7 +537,7 @@ public class RuleSetFactory {
|
||||
|
||||
// load the ruleset with minimum priority low, so that we get all rules, to be able to exclude any rule
|
||||
// minimum priority will be applied again, before constructing the final ruleset
|
||||
RuleSetFactory ruleSetFactory = new RuleSetFactory(resourceLoader, RulePriority.LOW, false, this.compatibilityFilter != null);
|
||||
RuleSetFactory ruleSetFactory = toLoader().filterAbovePriority(RulePriority.LOW).warnDeprecated(false).toFactory();
|
||||
RuleSet otherRuleSet = ruleSetFactory.createRuleSet(RuleSetReferenceId.parse(ref).get(0));
|
||||
List<RuleReference> potentialRules = new ArrayList<>();
|
||||
int countDeprecated = 0;
|
||||
@@ -620,7 +600,7 @@ public class RuleSetFactory {
|
||||
* Must be a rule element node.
|
||||
*/
|
||||
private void parseSingleRuleNode(RuleSetReferenceId ruleSetReferenceId, RuleSetBuilder ruleSetBuilder,
|
||||
Node ruleNode) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
|
||||
Node ruleNode) {
|
||||
Element ruleElement = (Element) ruleNode;
|
||||
|
||||
// Stop if we're looking for a particular Rule, and this element is not
|
||||
@@ -672,7 +652,7 @@ public class RuleSetFactory {
|
||||
|
||||
// load the ruleset with minimum priority low, so that we get all rules, to be able to exclude any rule
|
||||
// minimum priority will be applied again, before constructing the final ruleset
|
||||
RuleSetFactory ruleSetFactory = new RuleSetFactory(resourceLoader, RulePriority.LOW, false, this.compatibilityFilter != null);
|
||||
RuleSetFactory ruleSetFactory = toLoader().filterAbovePriority(RulePriority.LOW).warnDeprecated(false).toFactory();
|
||||
|
||||
boolean isSameRuleSet = false;
|
||||
RuleSetReferenceId otherRuleSetReferenceId = RuleSetReferenceId.parse(ref).get(0);
|
||||
@@ -832,4 +812,19 @@ public class RuleSetFactory {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@link RuleSetLoader} with the same config as this
|
||||
* factory. This is a transitional API.
|
||||
*/
|
||||
public RuleSetLoader toLoader() {
|
||||
return new RuleSetLoader().loadResourcesWith(resourceLoader)
|
||||
.filterAbovePriority(minimumPriority)
|
||||
.warnDeprecated(warnDeprecated)
|
||||
.enableCompatibility(compatibilityFilter != null)
|
||||
.includeDeprecatedRuleReferences(includeDeprecatedRuleReferences);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -18,13 +18,20 @@ import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
|
||||
/**
|
||||
* Provides a simple filter mechanism to avoid failing to parse an old ruleset,
|
||||
* which references rules, that have either been removed from PMD already or
|
||||
* renamed or moved to another ruleset.
|
||||
*
|
||||
* @see <a href="https://sourceforge.net/p/pmd/bugs/1360/">issue 1360</a>
|
||||
*
|
||||
* @deprecated Use {@link RuleSetLoader#enableCompatibility(boolean)} to enable this feature.
|
||||
* This implementation is internal API.
|
||||
*/
|
||||
@InternalApi
|
||||
@Deprecated
|
||||
public class RuleSetFactoryCompatibility {
|
||||
private static final Logger LOG = Logger.getLogger(RuleSetFactoryCompatibility.class.getName());
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd;
|
||||
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
|
||||
/**
|
||||
* An exception that is thrown when something wrong occurs while
|
||||
* {@linkplain RuleSetLoader loading rulesets}. This may be because the
|
||||
* XML is not well-formed, does not respect the ruleset schema, is
|
||||
* not a valid ruleset or is otherwise unparsable.
|
||||
*
|
||||
* <p>In the new {@link RuleSetLoader} API, this is thrown instead of
|
||||
* {@link RuleSetNotFoundException}.
|
||||
*/
|
||||
public final class RuleSetLoadException extends RuntimeException {
|
||||
|
||||
/** Constructors are internal. */
|
||||
@InternalApi
|
||||
public RuleSetLoadException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/** Constructors are internal. */
|
||||
@InternalApi
|
||||
public RuleSetLoadException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.sourceforge.pmd.lang.Language;
|
||||
import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||
import net.sourceforge.pmd.util.CollectionUtil;
|
||||
import net.sourceforge.pmd.util.ResourceLoader;
|
||||
|
||||
/**
|
||||
* Configurable object to load rulesets from XML resources.
|
||||
* This can be configured using a fluent API, see eg {@link #warnDeprecated(boolean)}.
|
||||
* To create a new ruleset, use {@link #loadFromResource(String)}
|
||||
* or some such overload.
|
||||
*/
|
||||
public final class RuleSetLoader {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(RuleSetLoader.class.getName());
|
||||
|
||||
private ResourceLoader resourceLoader = new ResourceLoader(RuleSetLoader.class.getClassLoader());
|
||||
private RulePriority minimumPriority = RulePriority.LOW;
|
||||
private boolean warnDeprecated = true;
|
||||
private boolean enableCompatibility = true;
|
||||
private boolean includeDeprecatedRuleReferences = false;
|
||||
|
||||
/**
|
||||
* Specify that the given classloader should be used to resolve
|
||||
* paths to external ruleset references. The default uses PMD's
|
||||
* own classpath.
|
||||
*/
|
||||
public RuleSetLoader loadResourcesWith(ClassLoader classLoader) {
|
||||
this.resourceLoader = new ResourceLoader(classLoader);
|
||||
return this;
|
||||
}
|
||||
|
||||
// internal
|
||||
RuleSetLoader loadResourcesWith(ResourceLoader loader) {
|
||||
this.resourceLoader = loader;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter loaded rules to only those that match or are above
|
||||
* the given priority. The default is {@link RulePriority#LOW},
|
||||
* ie, no filtering occurs.
|
||||
*
|
||||
* @return This instance, modified
|
||||
*/
|
||||
public RuleSetLoader filterAbovePriority(RulePriority minimumPriority) {
|
||||
this.minimumPriority = minimumPriority;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a warning when referencing a deprecated rule.
|
||||
* This is enabled by default.
|
||||
*
|
||||
* @return This instance, modified
|
||||
*/
|
||||
public RuleSetLoader warnDeprecated(boolean warn) {
|
||||
this.warnDeprecated = warn;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable translating old rule references to newer ones, if they have
|
||||
* been moved or renamed. This is enabled by default, if disabled,
|
||||
* unresolved references will not be translated and will produce an
|
||||
* error.
|
||||
*
|
||||
* @return This instance, modified
|
||||
*/
|
||||
public RuleSetLoader enableCompatibility(boolean enable) {
|
||||
this.enableCompatibility = enable;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Follow deprecated rule references. By default this is off,
|
||||
* and those references will be ignored (with a warning depending
|
||||
* on {@link #enableCompatibility(boolean)}).
|
||||
*
|
||||
* @return This instance, modified
|
||||
*/
|
||||
public RuleSetLoader includeDeprecatedRuleReferences(boolean enable) {
|
||||
this.includeDeprecatedRuleReferences = enable;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new rule set factory, if you have to (that class is deprecated).
|
||||
* That factory will use the configuration that was set using the setters of this.
|
||||
*
|
||||
* @deprecated {@link RuleSetFactory} is deprecated, replace its usages
|
||||
* with usages of this class, or of static factory methods of {@link RuleSet}
|
||||
*/
|
||||
@Deprecated
|
||||
public RuleSetFactory toFactory() {
|
||||
return new RuleSetFactory(
|
||||
this.resourceLoader,
|
||||
this.minimumPriority,
|
||||
this.warnDeprecated,
|
||||
this.enableCompatibility,
|
||||
this.includeDeprecatedRuleReferences
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses and returns a ruleset from its location. The location may
|
||||
* be a file system path, or a resource path (see {@link #loadResourcesWith(ClassLoader)}).
|
||||
*
|
||||
* <p>This replaces {@link RuleSetFactory#createRuleSet(String)},
|
||||
* but does not split commas.
|
||||
*
|
||||
* @param rulesetPath A reference to a single ruleset
|
||||
*
|
||||
* @throws RuleSetLoadException If any error occurs (eg, invalid syntax, or resource not found)
|
||||
*/
|
||||
public RuleSet loadFromResource(String rulesetPath) {
|
||||
return loadFromResource(new RuleSetReferenceId(rulesetPath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses several resources into a list of rulesets.
|
||||
*
|
||||
* @param paths Paths
|
||||
*
|
||||
* @throws RuleSetLoadException If any error occurs (eg, invalid syntax, or resource not found),
|
||||
* for any of the parameters
|
||||
* @throws NullPointerException If the parameter, or any component is null
|
||||
*/
|
||||
public List<RuleSet> loadFromResources(Collection<String> paths) {
|
||||
List<RuleSet> ruleSets = new ArrayList<>(paths.size());
|
||||
for (String path : paths) {
|
||||
ruleSets.add(loadFromResource(path));
|
||||
}
|
||||
return ruleSets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses several resources into a list of rulesets.
|
||||
*
|
||||
* @param first First path
|
||||
* @param rest Paths
|
||||
*
|
||||
* @throws RuleSetLoadException If any error occurs (eg, invalid syntax, or resource not found),
|
||||
* for any of the parameters
|
||||
* @throws NullPointerException If the parameter, or any component is null
|
||||
*/
|
||||
public List<RuleSet> loadFromResources(String first, String... rest) {
|
||||
return loadFromResources(CollectionUtil.listOf(first, rest));
|
||||
}
|
||||
|
||||
// package private
|
||||
RuleSet loadFromResource(RuleSetReferenceId ruleSetReferenceId) {
|
||||
try {
|
||||
return toFactory().createRuleSet(ruleSetReferenceId);
|
||||
} catch (Exception e) {
|
||||
throw new RuleSetLoadException("Cannot parse " + ruleSetReferenceId, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Configure a new ruleset factory builder according to the parameters
|
||||
* of the given PMD configuration.
|
||||
*/
|
||||
public static RuleSetLoader fromPmdConfig(PMDConfiguration configuration) {
|
||||
return new RuleSetLoader().filterAbovePriority(configuration.getMinimumPriority())
|
||||
.enableCompatibility(configuration.isRuleSetFactoryCompatibilityEnabled());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an Iterator of RuleSet objects loaded from descriptions from the
|
||||
* "categories.properties" resource for each language. This
|
||||
* uses the classpath of the resource loader ({@link #loadResourcesWith(ClassLoader)}).
|
||||
*
|
||||
* @return A list of all category rulesets
|
||||
*
|
||||
* @throws RuleSetLoadException If a standard ruleset cannot be loaded.
|
||||
* This is a corner case, that probably should not be caught by clients.
|
||||
* The standard rulesets are well-formed, at least in stock PMD distributions.
|
||||
*
|
||||
*/
|
||||
public List<RuleSet> getStandardRuleSets() {
|
||||
String rulesetsProperties;
|
||||
List<RuleSetReferenceId> ruleSetReferenceIds = new ArrayList<>();
|
||||
for (Language language : LanguageRegistry.findWithRuleSupport()) {
|
||||
Properties props = new Properties();
|
||||
rulesetsProperties = "category/" + language.getTerseName() + "/categories.properties";
|
||||
try (InputStream inputStream = resourceLoader.loadClassPathResourceAsStreamOrThrow(rulesetsProperties)) {
|
||||
props.load(inputStream);
|
||||
String rulesetFilenames = props.getProperty("rulesets.filenames");
|
||||
if (rulesetFilenames != null) {
|
||||
ruleSetReferenceIds.addAll(RuleSetReferenceId.parse(rulesetFilenames));
|
||||
}
|
||||
} catch (RuleSetNotFoundException e) {
|
||||
if (LOG.isLoggable(Level.FINE)) {
|
||||
LOG.fine("The language " + language.getTerseName() + " provides no " + rulesetsProperties + ".");
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
if (LOG.isLoggable(Level.FINE)) {
|
||||
LOG.fine("Couldn't read " + rulesetsProperties
|
||||
+ "; please ensure that the directory is on the classpath. The current classpath is: "
|
||||
+ System.getProperty("java.class.path"));
|
||||
LOG.fine(ioe.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<RuleSet> ruleSets = new ArrayList<>();
|
||||
for (RuleSetReferenceId id : ruleSetReferenceIds) {
|
||||
ruleSets.add(loadFromResource(id)); // may throw
|
||||
}
|
||||
return ruleSets;
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,20 @@
|
||||
|
||||
package net.sourceforge.pmd;
|
||||
|
||||
/**
|
||||
* @deprecated This is now only thrown by deprecated apis. {@link RuleSetLoader}
|
||||
* throws {@link RuleSetLoadException} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public class RuleSetNotFoundException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -4617033110919250810L;
|
||||
|
||||
public RuleSetNotFoundException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public RuleSetNotFoundException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,15 @@ import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
|
||||
/**
|
||||
* This class represents a reference to RuleSet.
|
||||
*
|
||||
* @deprecated This is part of the internals of the {@link RuleSetLoader}.
|
||||
*/
|
||||
@Deprecated
|
||||
@InternalApi
|
||||
public class RuleSetReference {
|
||||
private final String ruleSetFileName;
|
||||
private final boolean allRules;
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
import net.sourceforge.pmd.util.ResourceLoader;
|
||||
|
||||
/**
|
||||
@@ -78,7 +79,11 @@ import net.sourceforge.pmd.util.ResourceLoader;
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
*
|
||||
* @deprecated This is part of the internals of the {@link RuleSetLoader}.
|
||||
*/
|
||||
@Deprecated
|
||||
@InternalApi
|
||||
public class RuleSetReferenceId {
|
||||
private final boolean external;
|
||||
private final String ruleSetFileName;
|
||||
|
||||
@@ -56,21 +56,31 @@ public class RuleSets {
|
||||
/**
|
||||
* Public constructor. Add the given rule set.
|
||||
*
|
||||
* @param ruleSet
|
||||
* the RuleSet
|
||||
* @param ruleSet the RuleSet
|
||||
*/
|
||||
public RuleSets(RuleSet ruleSet) {
|
||||
addRuleSet(ruleSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Aggregate the given rulesets.
|
||||
*/
|
||||
public RuleSets(List<RuleSet> ruleSet) {
|
||||
for (RuleSet set : ruleSet) {
|
||||
addRuleSet(set);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a ruleset for a language. Only one ruleset can be added for a
|
||||
* specific language. If ruleSet.getLanguage() is null, it is assumed to be
|
||||
* a RuleSet of java rules.
|
||||
*
|
||||
* @param ruleSet
|
||||
* the RuleSet
|
||||
* @param ruleSet the RuleSet
|
||||
*
|
||||
* @deprecated Use {@link #RuleSets(List)} and don't mutate RuleSets after creation
|
||||
*/
|
||||
@Deprecated
|
||||
public void addRuleSet(RuleSet ruleSet) {
|
||||
ruleSets.add(ruleSet);
|
||||
ruleChain.add(ruleSet);
|
||||
@@ -85,6 +95,11 @@ public class RuleSets {
|
||||
return ruleSets.toArray(new RuleSet[0]);
|
||||
}
|
||||
|
||||
// internal
|
||||
List<RuleSet> getRuleSetsInternal() {
|
||||
return ruleSets;
|
||||
}
|
||||
|
||||
public Iterator<RuleSet> getRuleSetsIterator() {
|
||||
return ruleSets.iterator();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,10 @@ import net.sourceforge.pmd.benchmark.TimedOperation;
|
||||
import net.sourceforge.pmd.benchmark.TimedOperationCategory;
|
||||
import net.sourceforge.pmd.util.ResourceLoader;
|
||||
|
||||
/**
|
||||
* @deprecated Use a {@link RuleSetLoader} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public final class RulesetsFactoryUtils {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(RulesetsFactoryUtils.class.getName());
|
||||
@@ -76,7 +80,7 @@ public final class RulesetsFactoryUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #createFactory(PMDConfiguration)} or {@link #createFactory(PMDConfiguration, ClassLoader)}
|
||||
* @deprecated Use a {@link RuleSetLoader}
|
||||
*/
|
||||
@InternalApi
|
||||
@Deprecated
|
||||
@@ -96,7 +100,10 @@ public final class RulesetsFactoryUtils {
|
||||
* @return A ruleset factory
|
||||
*
|
||||
* @see #createFactory(PMDConfiguration, ClassLoader)
|
||||
*
|
||||
* @deprecated Use {@link RuleSetLoader#fromPmdConfig(PMDConfiguration)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static RuleSetFactory createFactory(final PMDConfiguration configuration) {
|
||||
return createFactory(configuration, RulesetsFactoryUtils.class.getClassLoader());
|
||||
}
|
||||
@@ -107,7 +114,7 @@ public final class RulesetsFactoryUtils {
|
||||
*
|
||||
* @return A ruleset factory
|
||||
*
|
||||
* @see #createFactory(PMDConfiguration, ClassLoader)
|
||||
* @see RuleSetLoader
|
||||
*/
|
||||
public static RuleSetFactory defaultFactory() {
|
||||
return new RuleSetFactory();
|
||||
@@ -124,7 +131,10 @@ public final class RulesetsFactoryUtils {
|
||||
* @return A ruleset factory
|
||||
*
|
||||
* @see #createFactory(PMDConfiguration)
|
||||
*
|
||||
* @deprecated Use a {@link RuleSetLoader}
|
||||
*/
|
||||
@Deprecated
|
||||
public static RuleSetFactory createFactory(final PMDConfiguration configuration, ClassLoader classLoader) {
|
||||
return createFactory(classLoader,
|
||||
configuration.getMinimumPriority(),
|
||||
@@ -145,7 +155,10 @@ public final class RulesetsFactoryUtils {
|
||||
* @return A ruleset factory
|
||||
*
|
||||
* @see #createFactory(PMDConfiguration)
|
||||
*
|
||||
* @deprecated Use a {@link RuleSetLoader}
|
||||
*/
|
||||
@Deprecated
|
||||
public static RuleSetFactory createFactory(ClassLoader classLoader,
|
||||
RulePriority minimumPriority,
|
||||
boolean warnDeprecated,
|
||||
@@ -166,11 +179,13 @@ public final class RulesetsFactoryUtils {
|
||||
* @return A ruleset factory
|
||||
*
|
||||
* @see #createFactory(PMDConfiguration)
|
||||
*
|
||||
* @deprecated Use a {@link RuleSetLoader}
|
||||
*/
|
||||
@Deprecated
|
||||
public static RuleSetFactory createFactory(RulePriority minimumPriority,
|
||||
boolean warnDeprecated,
|
||||
boolean enableCompatibility) {
|
||||
|
||||
return new RuleSetFactory(new ResourceLoader(), minimumPriority, warnDeprecated, enableCompatibility);
|
||||
}
|
||||
|
||||
@@ -190,7 +205,9 @@ public final class RulesetsFactoryUtils {
|
||||
* @return A ruleset factory
|
||||
*
|
||||
* @see #createFactory(PMDConfiguration)
|
||||
* @deprecated Use a {@link RuleSetLoader}
|
||||
*/
|
||||
@Deprecated
|
||||
public static RuleSetFactory createFactory(RulePriority minimumPriority,
|
||||
boolean warnDeprecated,
|
||||
boolean enableCompatibility,
|
||||
|
||||
@@ -11,6 +11,7 @@ import java.io.Reader;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
import net.sourceforge.pmd.benchmark.TimeTracker;
|
||||
import net.sourceforge.pmd.benchmark.TimedOperation;
|
||||
import net.sourceforge.pmd.benchmark.TimedOperationCategory;
|
||||
@@ -23,6 +24,11 @@ import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.ast.ParseException;
|
||||
import net.sourceforge.pmd.lang.xpath.Initializer;
|
||||
|
||||
/**
|
||||
* Source code processor is internal.
|
||||
*/
|
||||
@Deprecated
|
||||
@InternalApi
|
||||
public class SourceCodeProcessor {
|
||||
|
||||
private final PMDConfiguration configuration;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user