Merge branch 'master' into pr-2963-update

This commit is contained in:
Andreas Dangel
2021-01-21 11:43:01 +01:00
208 changed files with 6404 additions and 998 deletions
+4
View File
@@ -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))"
+12 -1
View File
@@ -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} \
+38 -76
View File
@@ -33,93 +33,55 @@ function regression_tester_setup_ci() {
}
#
# Generate a new baseline and upload it to sourceforge
#
# Note: this function always succeeds, even if the upload fails.
# In that case, just a error logging is provided.
# Generate a new baseline and upload it to pmd-code.org
#
function regression_tester_uploadBaseline() {
log_debug "$FUNCNAME branch=${PMD_CI_BRANCH}"
local targetUrl="https://sourceforge.net/projects/pmd/files/pmd-regression-tester/"
local pmdcodeUrl="https://pmd-code.org/pmd-regression-tester/"
local baseline_branch="${PMD_CI_BRANCH:-$PMD_CI_TAG}"
log_debug "$FUNCNAME branch=${baseline_branch}"
local errexitstate="$(shopt -po errexit)"
set +e # disable errexit
(
# This handler is called if any command fails
function upload_failed() {
log_error "Error while uploading ${BRANCH_FILENAME}-baseline.zip to pmd-code.org!"
log_error "Please upload manually: ${pmdcodeUrl}"
#log_error "Error while uploading ${BRANCH_FILENAME}-baseline.zip to sourceforge!"
#log_error "Please upload manually: ${targetUrl}"
}
# exit subshell after trap
set -e
trap upload_failed ERR
log_info "Generating and uploading baseline for pmdtester..."
cd ..
bundle config --local gemfile pmd/Gemfile
bundle exec pmdtester \
--mode single \
--local-git-repo ./pmd \
--patch-branch ${PMD_CI_BRANCH} \
--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/\//_}"
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/
log_success "Successfully uploaded ${BRANCH_FILENAME}-baseline.zip to ${pmdcodeUrl}"
#../../pmd/.ci/travis_wait "rsync -avh ${BRANCH_FILENAME}-baseline.zip ${PMD_SF_USER}@web.sourceforge.net:/home/frs/project/pmd/pmd-regression-tester/"
#log_success "Successfully uploaded ${BRANCH_FILENAME}-baseline.zip to ${targetUrl}"
)
# restore errexit state
eval "$errexitstate"
log_info "Generating and uploading baseline for pmdtester (${baseline_branch})..."
pushd ..
rm -f .bundle/config
bundle config set --local gemfile pmd/Gemfile
bundle exec pmdtester \
--mode single \
--local-git-repo ./pmd \
--patch-branch ${baseline_branch} \
--patch-config ./pmd/.ci/files/all-java.xml \
--list-of-project ./pmd/.ci/files/project-list.xml --html-flag \
--error-recovery
pushd target/reports
BRANCH_FILENAME="${baseline_branch/\//_}"
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/
log_success "Successfully uploaded ${BRANCH_FILENAME}-baseline.zip to ${pmdcodeUrl}"
popd
popd
}
#
# Execute danger, which executes pmd-regression-tester (via Dangerfile).
#
# Note: this function always succeeds, even if the danger fails.
# In that case, just a error logging is provided.
#
function regression_tester_executeDanger() {
log_debug "$FUNCNAME"
local errexitstate="$(shopt -po errexit)"
set +e # disable errexit
(
# This handler is called if any command fails
function danger_failed() {
log_error "Error while executing danger/pmd-regression-tester"
}
# Create a corresponding remote branch locally
if ! git show-ref --verify --quiet refs/heads/${PMD_CI_BRANCH}; then
git fetch --no-tags --depth=1 origin +refs/heads/${PMD_CI_BRANCH}:refs/remotes/origin/${PMD_CI_BRANCH}
git branch ${PMD_CI_BRANCH} origin/${PMD_CI_BRANCH}
log_debug "Created local branch ${PMD_CI_BRANCH}"
fi
# Fetch more commits of the PR for danger and regression tester
git fetch --no-tags --depth=50 origin +$(git rev-parse HEAD^2):
# Fetch more commits from master branch for regression tester
if [[ "${PMD_CI_BRANCH}" != "master" ]]; then
git fetch --no-tags --depth=50 origin +master:
git branch master origin/master
fi
# exit subshell after trap
set -e
trap danger_failed ERR
# Create a corresponding remote branch locally
if ! git show-ref --verify --quiet refs/heads/${PMD_CI_BRANCH}; then
git fetch --no-tags --depth=1 origin +refs/heads/${PMD_CI_BRANCH}:refs/remotes/origin/${PMD_CI_BRANCH}
git branch ${PMD_CI_BRANCH} origin/${PMD_CI_BRANCH}
log_debug "Created local branch ${PMD_CI_BRANCH}"
fi
# Fetch more commits of the PR for danger and regression tester
git fetch --no-tags --depth=50 origin +$(git rev-parse HEAD^2):
# Fetch more commits from master branch for regression tester
if [[ "${PMD_CI_BRANCH}" != "master" ]]; then
git fetch --no-tags --depth=50 origin +master:
git branch master origin/master
fi
log_info "Running danger on branch ${PMD_CI_BRANCH}"
bundle exec danger --verbose
log_success "Executing danger successfully"
)
# restore errexit state
eval "$errexitstate"
log_info "Running danger on branch ${PMD_CI_BRANCH}"
bundle exec danger --verbose
log_success "Executed danger successfully"
}
+3
View File
@@ -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
-14
View File
@@ -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:**
+1 -1
View File
@@ -6,7 +6,7 @@ jobs:
build:
runs-on: ${{ matrix.os }}
continue-on-error: false
timeout-minutes: 30
timeout-minutes: 60
strategy:
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
+4
View File
@@ -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 -1
View File
@@ -45,7 +45,7 @@ There are various channels, on which you can ask questions:
* On [StackOverflow](https://stackoverflow.com/questions/tagged/pmd): Make sure, to tag your question with "pmd".
* Create a issue for your question at <https://github.com/pmd/pmd/issues>.
* Create a new discussion for your question at <https://github.com/pmd/pmd/discussions>.
* Ask your question on Gitter <https://gitter.im/pmd/pmd>.
+2 -2
View File
@@ -16,7 +16,7 @@ def run_pmdtester
'--auto-gen-config',
'--error-recovery',
'--baseline-download-url', 'https://pmd-code.org/pmd-regression-tester/',
# '--debug',
#'--debug',
]
begin
@summary = PmdTester::Runner.new(argv).run
@@ -39,7 +39,7 @@ def upload_report
`tar -cf #{tar_filename} diff/`
report_url = `curl -u #{ENV['PMD_CI_CHUNK_TOKEN']} -T #{tar_filename} https://chunk.io`
if $?.success?
@logger.info "Successfully uploaded #{tar_filename} to chunk.io"
@logger.info "Successfully uploaded #{tar_filename} to #{report_url}"
# set value of sticky to true and the message is kept after new commits are submitted to the PR
message("This changeset " \
+1 -1
View File
@@ -3,7 +3,7 @@ source 'https://rubygems.org/'
# bleeding edge from git
#gem 'pmdtester', :git => 'https://github.com/pmd/pmd-regression-tester.git'
gem 'pmdtester', '~> 1.1'
gem 'pmdtester', '~> 1'
gem 'danger', '~> 5.6', '>= 5.6'
# This group is only needed for rendering release notes
+15 -13
View File
@@ -31,36 +31,38 @@ GEM
multipart-post (>= 1.2, < 3)
faraday-http-cache (1.3.1)
faraday (~> 0.8)
fugit (1.4.1)
fugit (1.4.2)
et-orbi (~> 1.1, >= 1.1.8)
raabro (~> 1.4)
git (1.7.0)
git (1.8.1)
rchardet (~> 1.8)
kramdown (1.17.0)
liquid (4.0.3)
liquid (5.0.0)
logger-colors (1.0.0)
mini_portile2 (2.4.0)
mini_portile2 (2.5.0)
multipart-post (2.1.1)
nap (1.1.0)
no_proxy_fix (0.1.2)
nokogiri (1.10.10)
mini_portile2 (~> 2.4.0)
octokit (4.19.0)
nokogiri (1.11.1)
mini_portile2 (~> 2.5.0)
racc (~> 1.4)
octokit (4.20.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
open4 (1.3.4)
pmdtester (1.1.0)
pmdtester (1.1.1)
differ (~> 0.1)
liquid (>= 4.0)
logger-colors (~> 1.0)
nokogiri (~> 1.8)
nokogiri (>= 1.11.0.rc4)
rufus-scheduler (~> 3.5)
slop (~> 4.6)
public_suffix (4.0.6)
raabro (1.4.0)
racc (1.5.2)
rchardet (1.8.0)
rouge (3.25.0)
rufus-scheduler (3.6.0)
rouge (3.26.0)
rufus-scheduler (3.7.0)
fugit (~> 1.1, >= 1.1.6)
safe_yaml (1.0.5)
sawyer (0.8.2)
@@ -69,7 +71,7 @@ GEM
slop (4.8.2)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
tzinfo (2.0.3)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
unicode-display_width (1.7.0)
@@ -79,7 +81,7 @@ PLATFORMS
DEPENDENCIES
danger (~> 5.6, >= 5.6)
liquid (>= 4.0.0)
pmdtester (~> 1.1)
pmdtester (~> 1)
rouge (>= 1.7, < 4)
safe_yaml (>= 1.0)
+6 -4
View File
@@ -1,7 +1,7 @@
# PMD
[![Join the chat at https://gitter.im/pmd/pmd](https://badges.gitter.im/pmd/pmd.svg)](https://gitter.im/pmd/pmd?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://github.com/pmd/pmd/workflows/.github/workflows/pushes.yml/badge.svg?branch=master)](https://github.com/pmd/pmd/actions)
[![Build Status](https://github.com/pmd/pmd/workflows/Pushes/badge.svg?branch=master)](https://github.com/pmd/pmd/actions)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd)
[![Reproducible Builds](https://img.shields.io/badge/Reproducible_Builds-ok-green?labelColor=blue)](https://github.com/jvm-repo-rebuild/reproducible-central#net.sourceforge.pmd:pmd)
[![Coverage Status](https://coveralls.io/repos/github/pmd/pmd/badge.svg)](https://coveralls.io/github/pmd/pmd)
@@ -20,10 +20,12 @@ Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex, Scala, Swift,
## Support
* How do I? -- Ask a question on [StackOverflow](https://stackoverflow.com/questions/tagged/pmd).
* I got this error, why? -- Ask a question on [StackOverflow](https://stackoverflow.com/questions/tagged/pmd).
* How do I? -- Ask a question on [StackOverflow](https://stackoverflow.com/questions/tagged/pmd)
or on [discussions](https://github.com/pmd/pmd/discussions).
* I got this error, why? -- Ask a question on [StackOverflow](https://stackoverflow.com/questions/tagged/pmd)
or on [discussions](https://github.com/pmd/pmd/discussions).
* I got this error and I'm sure it's a bug -- file an [issue](https://github.com/pmd/pmd/issues).
* I have an idea/request/question -- file an [issue](https://github.com/pmd/pmd/issues).
* I have an idea/request/question -- create a new [discussion](https://github.com/pmd/pmd/discussions).
* I have a quick question -- ask on our [Gitter chat](https://gitter.im/pmd/pmd).
* Where's your documentation? -- <https://pmd.github.io/latest/>
+37 -30
View File
@@ -1,7 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (6.0.3.2)
activesupport (6.0.3.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
@@ -17,37 +17,40 @@ GEM
commonmarker (0.17.13)
ruby-enum (~> 0.5)
concurrent-ruby (1.1.7)
dnsruby (1.61.4)
dnsruby (1.61.5)
simpleidn (~> 0.1)
em-websocket (0.5.1)
em-websocket (0.5.2)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0)
ethon (0.12.0)
ffi (>= 1.3.0)
eventmachine (1.2.7)
execjs (2.7.0)
faraday (1.0.1)
faraday (1.3.0)
faraday-net_http (~> 1.0)
multipart-post (>= 1.2, < 3)
ffi (1.13.1)
ruby2_keywords
faraday-net_http (1.0.0)
ffi (1.14.2)
forwardable-extended (2.6.0)
gemoji (3.0.1)
github-pages (207)
github-pages (209)
github-pages-health-check (= 1.16.1)
jekyll (= 3.9.0)
jekyll-avatar (= 0.7.0)
jekyll-coffeescript (= 1.1.1)
jekyll-commonmark-ghpages (= 0.1.6)
jekyll-default-layout (= 0.1.4)
jekyll-feed (= 0.13.0)
jekyll-feed (= 0.15.1)
jekyll-gist (= 1.5.0)
jekyll-github-metadata (= 2.13.0)
jekyll-mentions (= 1.5.1)
jekyll-mentions (= 1.6.0)
jekyll-optional-front-matter (= 0.3.2)
jekyll-paginate (= 1.1.0)
jekyll-readme-index (= 0.3.0)
jekyll-redirect-from (= 0.15.0)
jekyll-redirect-from (= 0.16.0)
jekyll-relative-links (= 0.6.1)
jekyll-remote-theme (= 0.4.1)
jekyll-remote-theme (= 0.4.2)
jekyll-sass-converter (= 1.5.2)
jekyll-seo-tag (= 2.6.1)
jekyll-sitemap (= 1.4.0)
@@ -55,7 +58,7 @@ GEM
jekyll-theme-architect (= 0.1.1)
jekyll-theme-cayman (= 0.1.1)
jekyll-theme-dinky (= 0.1.1)
jekyll-theme-hacker (= 0.1.1)
jekyll-theme-hacker (= 0.1.2)
jekyll-theme-leap-day (= 0.1.1)
jekyll-theme-merlot (= 0.1.1)
jekyll-theme-midnight (= 0.1.1)
@@ -66,14 +69,14 @@ GEM
jekyll-theme-tactile (= 0.1.1)
jekyll-theme-time-machine (= 0.1.1)
jekyll-titles-from-headings (= 0.5.3)
jemoji (= 0.11.1)
jemoji (= 0.12.0)
kramdown (= 2.3.0)
kramdown-parser-gfm (= 1.1.0)
liquid (= 4.0.3)
mercenary (~> 0.3)
minima (= 2.5.1)
nokogiri (>= 1.10.4, < 2.0)
rouge (= 3.19.0)
rouge (= 3.23.0)
terminal-table (~> 1.4)
github-pages-health-check (1.16.1)
addressable (~> 2.3)
@@ -114,14 +117,14 @@ GEM
rouge (>= 2.0, < 4.0)
jekyll-default-layout (0.1.4)
jekyll (~> 3.0)
jekyll-feed (0.13.0)
jekyll-feed (0.15.1)
jekyll (>= 3.7, < 5.0)
jekyll-gist (1.5.0)
octokit (~> 4.2)
jekyll-github-metadata (2.13.0)
jekyll (>= 3.4, < 5.0)
octokit (~> 4.0, != 4.4.0)
jekyll-mentions (1.5.1)
jekyll-mentions (1.6.0)
html-pipeline (~> 2.3)
jekyll (>= 3.7, < 5.0)
jekyll-optional-front-matter (0.3.2)
@@ -129,14 +132,15 @@ GEM
jekyll-paginate (1.1.0)
jekyll-readme-index (0.3.0)
jekyll (>= 3.0, < 5.0)
jekyll-redirect-from (0.15.0)
jekyll-redirect-from (0.16.0)
jekyll (>= 3.3, < 5.0)
jekyll-relative-links (0.6.1)
jekyll (>= 3.3, < 5.0)
jekyll-remote-theme (0.4.1)
jekyll-remote-theme (0.4.2)
addressable (~> 2.0)
jekyll (>= 3.5, < 5.0)
rubyzip (>= 1.3.0)
jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
rubyzip (>= 1.3.0, < 3.0)
jekyll-sass-converter (1.5.2)
sass (~> 3.4)
jekyll-seo-tag (2.6.1)
@@ -153,8 +157,8 @@ GEM
jekyll-theme-dinky (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-hacker (0.1.1)
jekyll (~> 3.5)
jekyll-theme-hacker (0.1.2)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-leap-day (0.1.1)
jekyll (~> 3.5)
@@ -188,7 +192,7 @@ GEM
jekyll (>= 3.3, < 5.0)
jekyll-watch (2.2.1)
listen (~> 3.0)
jemoji (0.11.1)
jemoji (0.12.0)
gemoji (~> 3.0)
html-pipeline (~> 2.2)
jekyll (>= 3.0, < 5.0)
@@ -197,32 +201,35 @@ GEM
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (4.0.3)
listen (3.2.1)
listen (3.4.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
mini_portile2 (2.4.0)
mini_portile2 (2.5.0)
minima (2.5.1)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.14.1)
minitest (5.14.3)
multipart-post (2.1.1)
nokogiri (1.10.10)
mini_portile2 (~> 2.4.0)
octokit (4.18.0)
nokogiri (1.11.1)
mini_portile2 (~> 2.5.0)
racc (~> 1.4)
octokit (4.20.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (3.1.1)
racc (1.5.2)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
rexml (3.2.4)
rouge (3.19.0)
rouge (3.23.0)
ruby-enum (0.8.0)
i18n
ruby2_keywords (0.0.2)
rubyzip (2.3.0)
safe_yaml (1.0.5)
sass (3.7.4)
@@ -240,13 +247,13 @@ GEM
thread_safe (0.3.6)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (1.2.7)
tzinfo (1.2.9)
thread_safe (~> 0.1)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
unicode-display_width (1.7.0)
zeitwerk (2.4.0)
zeitwerk (2.4.2)
PLATFORMS
ruby
+3 -3
View File
@@ -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
+41
View File
@@ -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::RulesetsFactoryUtils %} have been deprecated in favor of {% jdoc core::RuleSetLoader %}. This is easier to configure, and more maintainable than the multiple overloads of `RulesetsFactoryUtils`.
* Some static creation methods have been added to {% jdoc core::RuleSet %} for simple cases, eg {% jdoc core::RuleSet#forSingleRule(core::Rule) %}. These replace some counterparts in {% jdoc core::RuleSetFactory %}
* Since {% jdoc core::RuleSets %} is also deprecated, many APIs that require a RuleSets instance now are deprecated, and have a counterpart that expects a `List<RuleSet>`.
* {% jdoc core::RuleSetReferenceId %}, {% jdoc core::RuleSetReference %}, {% jdoc core::RuleSetFactoryCompatibility %} are deprecated. They are most likely not relevant outside of the implementation of pmd-core.
###### 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.
+3 -3
View File
@@ -1,8 +1,8 @@
---
title: Getting Help
permalink: pmd_about_help.html
author: Andreas Dangel <andreas.dangel@adangel.org>
last_updated: September 2017
author: Andreas Dangel <andreas.dangel@pmd-code.org>
last_updated: January 2021
---
There are numerous ways of getting help:
@@ -13,7 +13,7 @@ There are numerous ways of getting help:
* If you found a bug, please create a new [github issue](https://github.com/pmd/pmd/issues).
* You can also ask questions in our [sourceforge forum](https://sourceforge.net/p/pmd/discussion/).
* You can also ask questions on [github discussions](https://github.com/pmd/pmd/discussions).
* Or you can join the [Mailing List](https://lists.sourceforge.net/lists/listinfo/pmd-devel) or browse
through the archives ([archive1](http://java-pmd.30631.n5.nabble.com/), [archive2](http://web.archive.org/web/20160715035623/http://blog.gmane.org:80/gmane.comp.java.audit.pmd.devel)).
+1 -1
View File
@@ -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)." %}
Youll need to either check out the source code or download the latest source release. Assuming youve got the latest source release, unzip it to a directory:
+17 -46
View File
@@ -14,40 +14,24 @@ This is a {{ site.pmd.release_type }} release.
### New and noteworthy
##### CPD
#### New Rules
* 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)
* The new Apex rule {% rule "apex/errorprone/OverrideBothEqualsAndHashcode" %} brings the well known Java rule
to Apex. In Apex the same principle applies: `equals` and `hashCode` should always be overridden
together to ensure collection classes such as Maps and Sets work as expected.
### 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
* [#2970](https://github.com/pmd/pmd/issues/2970): \[core] PMD 6.30.0 release is not reproducible
* [#2994](https://github.com/pmd/pmd/pull/2994): \[core] Fix code climate severity strings
* java-bestpractices
* [#575](https://github.com/pmd/pmd/issues/575): \[java] LiteralsFirstInComparisons should consider constant fields
* java-codestyle
* [#2960](https://github.com/pmd/pmd/issues/2960): \[java] Thread issue in MethodNamingConventionsRule
### API Changes
#### Deprecated APIs
* {% 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)
#### Experimental APIs
* The method {% jdoc !!core::lang.ast.GenericToken#getKind() %} has been added as experimental. This
@@ -56,27 +40,14 @@ This is a {{ site.pmd.release_type }} release.
returned constant depends on the actual language and might change whenever the grammar
of the language is changed.
#### Internal APIs
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)
* [#2666](https://github.com/pmd/pmd/pull/2666): \[swift] Manage swift5 string literals - [kenji21](https://github.com/kenji21)
* [#2959](https://github.com/pmd/pmd/pull/2959): \[apex] New Rule: override equals and hashcode rule - [recdevs](https://github.com/recdevs)
* [#2964](https://github.com/pmd/pmd/pull/2964): \[cs] Update C# grammar for additional C# 7 and C# 8 features - [Maikel Steneker](https://github.com/maikelsteneker)
* [#2965](https://github.com/pmd/pmd/pull/2965): \[cs] Improvements for ignore sequences of literals functionality - [Maikel Steneker](https://github.com/maikelsteneker)
* [#2983](https://github.com/pmd/pmd/pull/2983): \[java] LiteralsFirstInComparisons should consider constant fields - [Ozan Gulle](https://github.com/ozangulle)
* [#2994](https://github.com/pmd/pmd/pull/2994): \[core] Fix code climate severity strings - [Vincent Maurin](https://github.com/vmaurin)
{% endtocmaker %}
+117
View File
@@ -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 `RulesetsFactoryUtils`.
* Some static creation methods have been added to <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSet.html#"><code>RuleSet</code></a> for simple cases, eg <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSet.html#forSingleRule(net.sourceforge.pmd.Rule)"><code>forSingleRule</code></a>. These replace some counterparts in <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetFactory.html#"><code>RuleSetFactory</code></a>
* Since <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSets.html#"><code>RuleSets</code></a> is also deprecated, many APIs that require a RuleSets instance now are deprecated, and have a counterpart that expects a `List<RuleSet>`.
* <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetReferenceId.html#"><code>RuleSetReferenceId</code></a>, <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetReference.html#"><code>RuleSetReference</code></a>, <a href="https://docs.pmd-code.org/apidocs/pmd-core/6.30.0/net/sourceforge/pmd/RuleSetFactoryCompatibility.html#"><code>RuleSetFactoryCompatibility</code></a> are deprecated. They are most likely not relevant outside of the implementation of pmd-core.
##### 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.
+1 -1
View File
@@ -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
View File
@@ -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>
@@ -0,0 +1,68 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.rule.errorprone;
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
import net.sourceforge.pmd.lang.apex.ast.ASTParameter;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule;
public class OverrideBothEqualsAndHashcodeRule extends AbstractApexRule {
public OverrideBothEqualsAndHashcodeRule() {
addRuleChainVisit(ASTUserClass.class);
}
@Override
public Object visit(ASTUserClass node, Object data) {
ApexNode<?> equalsNode = null;
ApexNode<?> hashNode = null;
for (ASTMethod method : node.findChildrenOfType(ASTMethod.class)) {
if (equalsNode == null && isEquals(method)) {
equalsNode = method;
}
if (hashNode == null && isHashCode(method)) {
hashNode = method;
}
if (hashNode != null && equalsNode != null) {
break;
}
}
if (equalsNode != null && hashNode == null) {
addViolation(data, equalsNode);
} else if (hashNode != null && equalsNode == null) {
addViolation(data, hashNode);
}
return data;
}
private boolean isEquals(ASTMethod node) {
int numParams = 0;
String paramType = null;
for (int ix = 0; ix < node.getNumChildren(); ix++) {
ApexNode<?> sn = node.getChild(ix);
if (sn instanceof ASTParameter) {
numParams++;
paramType = ((ASTParameter) sn).getType();
}
}
return numParams == 1 && "equals".equalsIgnoreCase(node.getImage()) && "Object".equalsIgnoreCase(paramType);
}
private boolean isHashCode(ASTMethod node) {
int numParams = 0;
for (int ix = 0; ix < node.getNumChildren(); ix++) {
ApexNode<?> sn = node.getChild(ix);
if (sn instanceof ASTParameter) {
numParams++;
}
}
return numParams == 0 && "hashCode".equalsIgnoreCase(node.getImage());
}
}
@@ -111,6 +111,30 @@ public without sharing class Foo {
</example>
</rule>
<rule name="AvoidNonExistentAnnotations"
language="apex"
since="6.5.0"
message="Use of non existent annotations will lead to broken Apex code which will not compile in the future."
class="net.sourceforge.pmd.lang.apex.rule.errorprone.AvoidNonExistentAnnotationsRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_errorprone.html#avoidnonexistentannotations">
<description>
Apex supported non existent annotations for legacy reasons.
In the future, use of such non-existent annotations could result in broken apex code that will not compile.
This will prevent users of garbage annotations from being able to use legitimate annotations added to Apex in the future.
A full list of supported annotations can be found at https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation.htm
</description>
<priority>3</priority>
<example>
<![CDATA[
@NonExistentAnnotation public class ClassWithNonexistentAnnotation {
@NonExistentAnnotation public void methodWithNonExistentAnnotation() {
// ...
}
}
]]>
</example>
</rule>
<rule name="EmptyCatchBlock"
language="apex"
since="6.0.0"
@@ -317,24 +341,39 @@ public class MyClass {
</example>
</rule>
<rule name="AvoidNonExistentAnnotations"
<rule name="OverrideBothEqualsAndHashcode"
language="apex"
since="6.5.0"
message="Use of non existent annotations will lead to broken Apex code which will not compile in the future."
class="net.sourceforge.pmd.lang.apex.rule.errorprone.AvoidNonExistentAnnotationsRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_errorprone.html#avoidnonexistentannotations">
since="6.31.0"
message="Ensure you override both equals() and hashCode()"
class="net.sourceforge.pmd.lang.apex.rule.errorprone.OverrideBothEqualsAndHashcodeRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_errorprone.html#overridebothequalsandhashcode">
<description>
Apex supported non existent annotations for legacy reasons.
In the future, use of such non-existent annotations could result in broken apex code that will not compile.
This will prevent users of garbage annotations from being able to use legitimate annotations added to Apex in the future.
A full list of supported annotations can be found at https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation.htm
Override both `public Boolean equals(Object obj)`, and `public Integer hashCode()`, or override neither.
Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly
delegating to your superclass.
This is especially important when [Using Custom Types in Map Keys and Sets](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_collections_maps_keys_userdefined.htm).
</description>
<priority>3</priority>
<example>
<![CDATA[@NonExistentAnnotation public class ClassWithNonexistentAnnotation {
@NonExistentAnnotation public void methodWithNonExistentAnnotation() {
// ...
}
<![CDATA[
public class Bar { // poor, missing a hashCode() method
public Boolean equals(Object o) {
// do some comparison
}
}
public class Baz { // poor, missing an equals() method
public Integer hashCode() {
// return some hash value
}
}
public class Foo { // perfect, both methods provided
public Boolean equals(Object other) {
// do some comparison
}
public Integer hashCode() {
// return some hash value
}
}
]]>
</example>
@@ -472,5 +472,6 @@
</properties>
</rule>
<!-- <rule ref="category/apex/bestpractices.xml/UnusedLocalVariable"/> -->
<!-- <rule ref="category/apex/errorprone.xml/OverrideBothEqualsAndHashcode" /> -->
</ruleset>
@@ -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 {
@@ -0,0 +1,11 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.rule.errorprone;
import net.sourceforge.pmd.testframework.PmdRuleTst;
public class OverrideBothEqualsAndHashcodeTest extends PmdRuleTst {
// no additional unit tests
}
@@ -0,0 +1,166 @@
<?xml version="1.0" encoding="UTF-8"?>
<test-data
xmlns="http://pmd.sourceforge.net/rule-tests"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd">
<test-code>
<description>hash code only</description>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class Foo {
public Integer hashCode() {}
}
]]></code>
</test-code>
<test-code>
<description>nested hash code only</description>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class Foo {
public class Bar {
public Integer hashCode() {}
}
}
]]></code>
</test-code>
<test-code>
<description>equals only</description>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class Foo {
public boolean equals(Object other) {}
}
]]></code>
</test-code>
<test-code>
<description>nested equals only, checking case insensitiveness</description>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class Foo {
public class Bar {
public Integer eQuAlS(Object other) {}
}
}
]]></code>
</test-code>
<test-code>
<description>overrides both</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
public boolean equals(Object other) {}
public Integer hashCode() {}
}
]]></code>
</test-code>
<test-code>
<description>nested overrides both</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
public class Bar {
public boolean equals(Object other) {}
public Integer hashCode() {}
}
}
]]></code>
</test-code>
<test-code>
<description>overrides neither</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {}
]]></code>
</test-code>
<test-code>
<description>equals sig uses String, not Object</description>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class Foo {
public boolean equals(String o) {
return true;
}
public Integer hashCode() {
return 0;
}
}
]]></code>
</test-code>
<test-code>
<description>interface</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public interface Foo {
boolean equals(Object o);
}
]]></code>
</test-code>
<test-code>
<description>implements equals but with 2 args, hashCode overloaded as well</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
public boolean equals(java.lang.Object o1, java.lang.Object o2) {
return true;
}
public Integer hashCode(java.lang.Object o) {
return 0;
}
}
]]></code>
</test-code>
<test-code>
<description>overloaded hashCode</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
public Integer hashCode(Object o1) { return false; }
}
]]></code>
</test-code>
<test-code>
<description>overloaded both</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
public boolean equals(Object o1, Object o2) { return false; }
public Integer hashCode(Object o1) { return false; }
}
]]></code>
</test-code>
<test-code>
<description>overloaded hashCode, should fail on equals</description>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class Foo {
public boolean equals(Object o1) { return false; }
public Integer hashCode(Object o1) { return false; }
}
]]></code>
</test-code>
<test-code>
<description>implements hashCode but with args</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
public Integer hashCode(List<Decimal> a) {
return 0;
}
}
]]></code>
</test-code>
</test-data>
+1 -1
View File
@@ -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>
+15 -7
View File
@@ -30,15 +30,23 @@
<delete dir="${target}/net/sourceforge/pmd/lang/ast/dummy" />
<mkdir dir="${target}/net/sourceforge/pmd/lang/ast/dummy" />
<echo>Using JavaCC home: ${javacc-home.path}</echo>
<jjtree target="etc/grammar/dummy.jjt"
outputdirectory="${target}/net/sourceforge/pmd/lang/ast/dummy"
javacchome="${javacc-home.path}" />
<java fork="true"
classname="jjtree"
classpath="${javacc-home.path}/javacc.jar">
<sysproperty key="file.encoding" value="UTF-8" />
<arg value="-OUTPUT_DIRECTORY:${target}/net/sourceforge/pmd/lang/ast/dummy" />
<arg value="etc/grammar/dummy.jjt" />
</java>
<!-- Generate CharStream interface -->
<javacc usercharstream="true"
target="${target}/net/sourceforge/pmd/lang/ast/dummy/dummy.jj"
outputdirectory="${target}/net/sourceforge/pmd/lang/ast/dummy"
javacchome="${javacc-home.path}" />
<java fork="true"
classname="javacc"
classpath="${javacc-home.path}/javacc.jar">
<sysproperty key="file.encoding" value="UTF-8" />
<arg value="-USER_CHAR_STREAM:true" />
<arg value="-OUTPUT_DIRECTORY:${target}/net/sourceforge/pmd/lang/ast/dummy" />
<arg value="${target}/net/sourceforge/pmd/lang/ast/dummy/dummy.jj" />
</java>
<replace file="${target}/net/sourceforge/pmd/lang/ast/dummy/CharStream.java"
token="net.sourceforge.pmd.lang.ast.dummy"
value="net.sourceforge.pmd.lang.ast" />
@@ -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) {
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

Some files were not shown because too many files have changed in this diff Show More