From 1c0d6c6a4f14bab244788935816264354173fbe8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Mar 2023 11:52:18 +0200 Subject: [PATCH 01/63] [doc] Fix base url for documentation --- docs/pages/release_notes.md | 2 +- docs/pages/release_notes_old.md | 42 ++++++++++++++++----------------- pom.xml | 4 ++-- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 14d4904e35..4aff5f8980 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -5,7 +5,7 @@ keywords: changelog, release notes --- {% if is_release_notes_processor %} -{% capture baseurl %}https://pmd.github.io/pmd-{{ site.pmd.version }}/{% endcapture %} +{% capture baseurl %}https://docs.pmd-code.org/pmd-doc-{{ site.pmd.version }}/{% endcapture %} {% else %} {% assign baseurl = "" %} {% endif %} diff --git a/docs/pages/release_notes_old.md b/docs/pages/release_notes_old.md index 7b05d6ff5b..433ad55870 100644 --- a/docs/pages/release_notes_old.md +++ b/docs/pages/release_notes_old.md @@ -12,7 +12,7 @@ Previous versions of PMD can be downloaded here: https://github.com/pmd/pmd/rele We're excited to bring you the next major version of PMD! Since this is a big release, we provide here only a concise version of the release notes. We prepared a separate -page with the full [Detailed Release Notes for PMD 7.0.0](https://pmd.github.io/pmd-7.0.0-rc1/pmd_release_notes_pmd7.html). +page with the full [Detailed Release Notes for PMD 7.0.0](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_release_notes_pmd7.html).
ℹ️ Release Candidates @@ -57,7 +57,7 @@ for all.

The new official logo of PMD: -![New PMD Logo](https://pmd.github.io/pmd-7.0.0-rc1/images/logo/pmd-logo-300px.png) +![New PMD Logo](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/images/logo/pmd-logo-300px.png) #### Revamped Java module @@ -82,7 +82,7 @@ Contributors: [Clément Fournier](https://github.com/oowekyala) (@oowekyala), * progress bar support for `pmd check` * shell completion -![Demo](https://pmd.github.io/pmd-7.0.0-rc1/images/userdocs/pmd-demo.gif) +![Demo](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/images/userdocs/pmd-demo.gif) For more information, see the [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html). @@ -136,46 +136,46 @@ Contributors: [Lucas Soncini](https://github.com/lsoncini) (@lsoncini), #### New Rules **Apex** -* [`UnusedMethod`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_apex_design.html#unusedmethod) finds unused methods in your code. +* [`UnusedMethod`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_apex_design.html#unusedmethod) finds unused methods in your code. **Java** -* [`UnnecessaryBoxing`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_codestyle.html#unnecessaryboxing) reports boxing and unboxing conversions that may be made implicit. +* [`UnnecessaryBoxing`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_codestyle.html#unnecessaryboxing) reports boxing and unboxing conversions that may be made implicit. **Kotlin** -* [`FunctionNameTooShort`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_kotlin_bestpractices.html#functionnametooshort) -* [`OverrideBothEqualsAndHashcode`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_kotlin_errorprone.html#overridebothequalsandhashcode) +* [`FunctionNameTooShort`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_kotlin_bestpractices.html#functionnametooshort) +* [`OverrideBothEqualsAndHashcode`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_kotlin_errorprone.html#overridebothequalsandhashcode) **Swift** -* [`ProhibitedInterfaceBuilder`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_swift_bestpractices.html#prohibitedinterfacebuilder) -* [`UnavailableFunction`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_swift_bestpractices.html#unavailablefunction) -* [`ForceCast`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_swift_errorprone.html#forcecast) -* [`ForceTry`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_swift_errorprone.html#forcetry) +* [`ProhibitedInterfaceBuilder`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_swift_bestpractices.html#prohibitedinterfacebuilder) +* [`UnavailableFunction`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_swift_bestpractices.html#unavailablefunction) +* [`ForceCast`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_swift_errorprone.html#forcecast) +* [`ForceTry`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_swift_errorprone.html#forcetry) #### Changed Rules **Java** -* [`UnnecessaryFullyQualifiedName`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_codestyle.html#unnecessaryfullyqualifiedname): the rule has two new properties, +* [`UnnecessaryFullyQualifiedName`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_codestyle.html#unnecessaryfullyqualifiedname): the rule has two new properties, to selectively disable reporting on static field and method qualifiers. The rule also has been improved to be more precise. -* [`UselessParentheses`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_codestyle.html#uselessparentheses): the rule has two new properties which control how strict +* [`UselessParentheses`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_codestyle.html#uselessparentheses): the rule has two new properties which control how strict the rule should be applied. With `ignoreClarifying` (default: true) parentheses that are strictly speaking not necessary are allowed, if they separate expressions of different precedence. The other property `ignoreBalancing` (default: true) is similar, in that it allows parentheses that help reading and understanding the expressions. -* [`LooseCoupling`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_bestpractices.html#loosecoupling): the rule has a new property to allow some types to be coupled +* [`LooseCoupling`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_bestpractices.html#loosecoupling): the rule has a new property to allow some types to be coupled to (`allowedTypes`). -* [`EmptyCatchBlock`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_errorprone.html#emptycatchblock): `CloneNotSupportedException` and `InterruptedException` are not +* [`EmptyCatchBlock`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_errorprone.html#emptycatchblock): `CloneNotSupportedException` and `InterruptedException` are not special-cased anymore. Rename the exception parameter to `ignored` to ignore them. -* [`DontImportSun`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_errorprone.html#dontimportsun): `sun.misc.Signal` is not special-cased anymore. -* [`UseDiamondOperator`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_codestyle.html#usediamondoperator): the property `java7Compatibility` is removed. The rule now +* [`DontImportSun`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_errorprone.html#dontimportsun): `sun.misc.Signal` is not special-cased anymore. +* [`UseDiamondOperator`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_codestyle.html#usediamondoperator): the property `java7Compatibility` is removed. The rule now handles Java 7 properly without a property. -* [`SingularField`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_design.html#singularfield): Properties `checkInnerClasses` and `disallowNotAssignment` are removed. +* [`SingularField`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_design.html#singularfield): Properties `checkInnerClasses` and `disallowNotAssignment` are removed. The rule is now more precise and will check these cases properly. -* [`UseUtilityClass`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_design.html#useutilityclass): The property `ignoredAnnotations` has been removed. -* [`LawOfDemeter`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_design.html#lawofdemeter): the rule has a new property `trustRadius`. This defines the maximum degree +* [`UseUtilityClass`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_design.html#useutilityclass): The property `ignoredAnnotations` has been removed. +* [`LawOfDemeter`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_design.html#lawofdemeter): the rule has a new property `trustRadius`. This defines the maximum degree of trusted data. The default of 1 is the most restrictive. -* [`CommentContent`](https://pmd.github.io/pmd-7.0.0-rc1/pmd_rules_java_documentation.html#commentcontent): The properties `caseSensitive` and `disallowedTerms` are removed. The +* [`CommentContent`](https://docs.pmd-code.org/pmd-doc-7.0.0-rc1/pmd_rules_java_documentation.html#commentcontent): The properties `caseSensitive` and `disallowedTerms` are removed. The new property `fobiddenRegex` can be used now to define the disallowed terms with a single regular expression. diff --git a/pom.xml b/pom.xml index a2b90df0c5..9f963eb5c2 100644 --- a/pom.xml +++ b/pom.xml @@ -108,7 +108,7 @@ UTF-8 UTF-8 - https://pmd.github.io/pmd + https://docs.pmd-code.org/snapshot -Xmx512m -Dfile.encoding=${project.build.sourceEncoding} ${extraArgLine} @@ -1031,7 +1031,7 @@ pmd-release - https://pmd.github.io/pmd-${project.version} + https://docs.pmd-code.org/pmd-doc-${project.version} From 910d3178dbf61b68bb3e6dd70f0446a3560106ff Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Mar 2023 12:35:21 +0200 Subject: [PATCH 02/63] [doc] Fix urls for documentation - Don't publish the doc anymore to pmd.github.io - the docs are now hosted at docs.pmd-code.org - Update sitemap.xml - no extra sitemap generation anymore --- .ci/build.sh | 6 ++--- .ci/inc/pmd-doc.inc | 50 +--------------------------------- docs/_config.yml | 3 +-- docs/sitemap.xml | 26 +++++++++++++++--- docs/sitemap_generator.sh | 56 --------------------------------------- 5 files changed, 26 insertions(+), 115 deletions(-) delete mode 100755 docs/sitemap_generator.sh diff --git a/.ci/build.sh b/.ci/build.sh index 5f4d321698..2ed082bbe1 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -224,7 +224,7 @@ function pmd_ci_build_and_upload_doc() { pmd_ci_sourceforge_uploadReleaseNotes "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "${rendered_release_notes}" if pmd_ci_maven_isSnapshotBuild && [ "${PMD_CI_BRANCH}" = "master" ]; then - # only for snapshot builds from branch master + # only for snapshot builds from branch master: https://docs.pmd-code.org/snapshot -> pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION} pmd_code_createSymlink "${PMD_CI_MAVEN_PROJECT_VERSION}" "snapshot" # update github pages https://pmd.github.io/pmd/ @@ -249,14 +249,12 @@ function pmd_ci_build_and_upload_doc() { local rendered_release_notes_with_links rendered_release_notes_with_links=" * Downloads: https://github.com/pmd/pmd/releases/tag/pmd_releases%2F${PMD_CI_MAVEN_PROJECT_VERSION} -* Documentation: https://pmd.github.io/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}/ +* Documentation: https://docs.pmd-code.org/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/ ${rendered_release_notes}" pmd_ci_sourceforge_createDraftBlogPost "${release_name} released" "${rendered_release_notes_with_links}" "pmd,release" SF_BLOG_URL="${RESULT}" - # updates https://pmd.github.io/latest/ and https://pmd.github.io/pmd-${PMD_CI_MAVEN_PROJECT_VERSION} - publish_release_documentation_github # rsync site to https://pmd.sourceforge.io/pmd-${PMD_CI_MAVEN_PROJECT_VERSION} pmd_ci_sourceforge_rsyncSnapshotDocumentation "${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-${PMD_CI_MAVEN_PROJECT_VERSION}" fi diff --git a/.ci/inc/pmd-doc.inc b/.ci/inc/pmd-doc.inc index 4a6d5acc14..8969f8a4d8 100644 --- a/.ci/inc/pmd-doc.inc +++ b/.ci/inc/pmd-doc.inc @@ -42,55 +42,7 @@ function pmd_doc_create_archive() { } # -# Publishes the site to https://pmd.github.io/pmd-${PMD_CI_MAVEN_PROJECT_VERSION} and -# https://pmd.github.io/latest/ -# -function publish_release_documentation_github() { - echo -e "\n\n" - pmd_ci_log_info "Adding the new doc to pmd.github.io..." - # clone pmd.github.io. Note: This uses the ssh key setup earlier - # In order to speed things up, we use a sparse checkout - no need to checkout all directories here - mkdir pmd.github.io - ( - cd pmd.github.io || { echo "Directory 'pmd.github.io' doesn't exist"; exit 1; } - git init - git config user.name "PMD CI (pmd-bot)" - git config user.email "pmd-bot@users.noreply.github.com" - git config core.sparsecheckout true - git remote add origin git@github.com-pmd.github.io:pmd/pmd.github.io.git - echo "/latest/" > .git/info/sparse-checkout - echo "/sitemap.xml" >> .git/info/sparse-checkout - git pull --depth=1 origin master - pmd_ci_log_info "Copying documentation from ../docs/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/ to pmd-${PMD_CI_MAVEN_PROJECT_VERSION}/ ..." - rsync -ah --stats "../docs/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}/" "pmd-${PMD_CI_MAVEN_PROJECT_VERSION}/" - git status - pmd_ci_log_debug "Executing: git add pmd-${PMD_CI_MAVEN_PROJECT_VERSION}" - git add --sparse "pmd-${PMD_CI_MAVEN_PROJECT_VERSION}" - pmd_ci_log_debug "Executing: git commit..." - git commit -q -m "Added pmd-${PMD_CI_MAVEN_PROJECT_VERSION}" - - pmd_ci_log_info "Copying pmd-${PMD_CI_MAVEN_PROJECT_VERSION} to latest ..." - git rm -qr latest - cp -a "pmd-${PMD_CI_MAVEN_PROJECT_VERSION}" latest - pmd_ci_log_debug "Executing: git add latest" - git add latest - pmd_ci_log_debug "Executing: git commit..." - git commit -q -m "Copying pmd-${PMD_CI_MAVEN_PROJECT_VERSION} to latest" - - pmd_ci_log_info "Generating sitemap.xml" - ../docs/sitemap_generator.sh > sitemap.xml - pmd_ci_log_debug "Executing: git add sitemap.xml" - git add sitemap.xml - pmd_ci_log_debug "Executing: git commit..." - git commit -q -m "Generated sitemap.xml" - - pmd_ci_log_info "Executing: git push origin master" - git push origin master - ) -} - -# -# Updates github pages of the main repository, +# Updates github pages branch "gh-pages" of the main repository, # so that https://pmd.github.io/pmd/ has the latest (snapshot) content # function pmd_doc_publish_to_github_pages() { diff --git a/docs/_config.yml b/docs/_config.yml index 920e5d9a1c..4dc5eee07d 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -44,7 +44,6 @@ exclude: - pdf-*.sh - pdfconfigs/ - pdf/ - - sitemap_generator.sh - render_release_notes.rb feedback_subject_line: PMD Source Code Analyzer @@ -117,7 +116,7 @@ description: "Intended as a documentation theme based on Jekyll for technical wr # the description is used in the feed.xml file # needed for sitemap.xml file only -url: https://pmd.github.io/pmd +url: https://docs.pmd-code.org/latest baseurl: "" # used by javadoc_tag.rb diff --git a/docs/sitemap.xml b/docs/sitemap.xml index 38a04d6c4e..5a1d7dc52e 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -1,24 +1,42 @@ --- layout: none search: exclude +# https://www.sitemaps.org/protocol.html +# Priority is relative to the website, can be chosen in {0.1, 0.2, ..., 1} +# Default priority is 0.5 +latestPriority: 0.8 --- + + {{site.url}}/index.html + 0.9 + monthly + {{ site.time | date: "%Y-%m-%d" }} + + + {% for post in site.posts %} {% unless post.search == "exclude" %} {{site.url}}{{post.url}} + {{page.latestPriority}} + monthly + {{ site.time | date: "%Y-%m-%d" }} {% endunless %} {% endfor %} - {% for page in site.pages %} - {% unless page.search == "exclude" %} + {% for p in site.pages %} + {% unless p.search == "exclude" %} - {{site.url}}{{ page.url}} + {{site.url}}{{ p.url}} + {{page.latestPriority}} + monthly + {{ site.time | date: "%Y-%m-%d" }} {% endunless %} {% endfor %} - \ No newline at end of file + diff --git a/docs/sitemap_generator.sh b/docs/sitemap_generator.sh deleted file mode 100755 index 03e25a0bcf..0000000000 --- a/docs/sitemap_generator.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash - -# Sitemap generator for pmd.github.io main landing page. -# Assumes we have the latest version of the site under "latest" -# https://www.sitemaps.org/protocol.html - -WEBSITE_PREFIX="https://pmd.github.io/" -DOC_PREFIX="latest/" -DATE=`date +%Y-%m-%d` -# Priority is relative to the website, can be chosen in {0.1, 0.2, ..., 1} -# Default priority is 0.5 -LATEST_PRIORITY=0.8 - - -# Writes to standard output - -cat << HEADER_END - - - - - ${WEBSITE_PREFIX}index.html - 1 - monthly - $DATE - - - - ${WEBSITE_PREFIX}${DOC_PREFIX}index.html - 0.9 - monthly - $DATE - - - - -HEADER_END - - -for page in ${DOC_PREFIX}pmd_*.html -do - - cat << ENTRY_END - - ${WEBSITE_PREFIX}$page - $LATEST_PRIORITY - monthly - $DATE - - -ENTRY_END - -done - -echo "" - From 65a713a96da4d86c682449bf116a423b823759b4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Mar 2023 12:42:52 +0200 Subject: [PATCH 03/63] [doc] Update release notes (#4438) --- docs/pages/release_notes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 4aff5f8980..fbd27645e5 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -39,6 +39,9 @@ for all.

This section lists the most important changes from the last release candidate. The remaining section describe the complete release notes for 7.0.0. +#### Fixed issues +* [#4438](https://github.com/pmd/pmd/issues/4438): \[doc] Documentation links in VS Code are outdated + ### 🚀 Major Features and Enhancements #### New official logo @@ -238,6 +241,8 @@ See [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html). * [#2234](https://github.com/pmd/pmd/issues/2234): \[core] Consolidate PMD CLI into a single command * [#3828](https://github.com/pmd/pmd/issues/3828): \[core] Progress reporting * [#4079](https://github.com/pmd/pmd/issues/4079): \[cli] Split off CLI implementation into a pmd-cli submodule +* doc + * [#4438](https://github.com/pmd/pmd/issues/4438): \[doc] Documentation links in VS Code are outdated * testing * [#2435](https://github.com/pmd/pmd/issues/2435): \[test] Remove duplicated Dummy language module * [#4234](https://github.com/pmd/pmd/issues/4234): \[test] Tests that change the logging level do not work From 2e21c193fef0e4bfd33e048da0148f0493014379 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Mar 2023 15:05:14 +0200 Subject: [PATCH 04/63] Fix externalInfoURLs in rulesets --- pmd-swift/pom.xml | 6 ++++++ .../src/main/resources/category/swift/bestpractices.xml | 8 ++++---- .../src/main/resources/category/swift/errorprone.xml | 8 ++++---- .../net/sourceforge/pmd/AbstractRuleSetFactoryTest.java | 2 +- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/pmd-swift/pom.xml b/pmd-swift/pom.xml index cd7697bdbf..9f008e7e3f 100644 --- a/pmd-swift/pom.xml +++ b/pmd-swift/pom.xml @@ -16,6 +16,12 @@ + + + ${project.basedir}/src/main/resources + true + + diff --git a/pmd-swift/src/main/resources/category/swift/bestpractices.xml b/pmd-swift/src/main/resources/category/swift/bestpractices.xml index 6bf75958e6..cab248b276 100644 --- a/pmd-swift/src/main/resources/category/swift/bestpractices.xml +++ b/pmd-swift/src/main/resources/category/swift/bestpractices.xml @@ -10,11 +10,11 @@ Rules which enforce generally accepted best practices. + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_swift_bestpractices.html#prohibitedinterfacebuilder"> Creating views using Interface Builder should be avoided. Defining views by code allows the compiler to detect issues that otherwise will be runtime errors. @@ -45,11 +45,11 @@ class ViewController: UIViewController { + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_swift_bestpractices.html#unavailablefunction"> Due to Objective-C and Swift interoperability some functions are often required to be implemented but aren't really needed. It is extremely common that the sole implementation of the functions consist of throwing diff --git a/pmd-swift/src/main/resources/category/swift/errorprone.xml b/pmd-swift/src/main/resources/category/swift/errorprone.xml index 1a64a50b85..e4dab5022d 100644 --- a/pmd-swift/src/main/resources/category/swift/errorprone.xml +++ b/pmd-swift/src/main/resources/category/swift/errorprone.xml @@ -11,10 +11,10 @@ + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_swift_errorprone.html#forcecast"> Force casts should be avoided. This may lead to a crash if it's not used carefully. For example assuming a JSON property has a given type, or your reused Cell has a certain contract. @@ -41,10 +41,10 @@ NSNumber() as? Int // no violation + externalInfoUrl="${pmd.website.baseurl}/pmd_rules_swift_errorprone.html#forcetry"> Force tries should be avoided. If the code being wrapped happens to raise and exception, our application will crash. Consider using a conditional try and handling the resulting optional, or wrapping the try statement in a do-catch block. diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java b/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java index 372e55b422..c4f8c22a46 100644 --- a/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java +++ b/pmd-test/src/main/java/net/sourceforge/pmd/AbstractRuleSetFactoryTest.java @@ -147,7 +147,7 @@ public abstract class AbstractRuleSetFactoryTest { .append(rule.getName()) .append(" is missing 'externalInfoURL' attribute\n"); } else { - String expectedExternalInfoURL = "https?://pmd.(sourceforge.net|github.io)/.+/pmd_rules_" + String expectedExternalInfoURL = "https://docs.pmd-code.org/.+/pmd_rules_" + language.getTerseName() + "_" + IOUtil.getFilenameBase(fileName) + ".html#" From f7d0444d86e8a891c94a6d6fe93edd13bbbfc8e2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 30 Mar 2023 15:28:56 +0200 Subject: [PATCH 05/63] Replace more old URLs --- .ci/README.md | 2 +- .../0rule_violation_false-positive.md | 2 +- .../1rule_violation_false-negative.md | 2 +- CONTRIBUTING.md | 4 +- README.md | 10 ++--- docs/README.md | 6 ++- docs/_plugins/rule_tag.rb | 2 +- .../committers/main_landing_page.md | 6 --- .../pmd/projectdocs/committers/releasing.md | 42 +++++++++---------- docs/report-examples/pmd-report.sarif.json | 8 ++-- .../java/net/sourceforge/pmd/PmdAnalysis.java | 4 +- .../pmd/renderers/CodeClimateRenderer.java | 8 ++-- .../pmd/renderers/SarifRenderer.java | 1 + .../internal/sarif/SarifLogBuilder.java | 2 +- .../renderers/CodeClimateRendererTest.java | 8 ++-- .../pmd/renderers/sarif/empty.sarif.json | 4 +- .../sarif/expected-configerror.sarif.json | 4 +- .../sarif/expected-error-nomessage.sarif.json | 4 +- .../renderers/sarif/expected-error.sarif.json | 4 +- .../expected-multiple-locations.sarif.json | 4 +- .../sarif/expected-multiple.sarif.json | 4 +- .../pmd/renderers/sarif/expected.sarif.json | 4 +- 22 files changed, 64 insertions(+), 71 deletions(-) diff --git a/.ci/README.md b/.ci/README.md index 87250d6ba7..6286fd14b4 100644 --- a/.ci/README.md +++ b/.ci/README.md @@ -138,7 +138,7 @@ f=check-environment.sh; \ Calling `.ci/build.sh` directly would re-release the tag $TAG_NAME - that's why it is commented out. All the side-effects of a release would be carried out like creating and publishing a release on github, -uploading the release to sourceforge, uploading the docs to pmd.github.io/docs.pmd-code.org, uploading a +uploading the release to sourceforge, uploading the docs to docs.pmd-code.org, uploading a new baseline for the regression tester and so on. While the release should be reproducible and therefore should produce exactly the same artifacts, re-uploading artifacts is not desired just for testing. diff --git a/.github/ISSUE_TEMPLATE/0rule_violation_false-positive.md b/.github/ISSUE_TEMPLATE/0rule_violation_false-positive.md index 8faed7c14a..9daab4f380 100644 --- a/.github/ISSUE_TEMPLATE/0rule_violation_false-positive.md +++ b/.github/ISSUE_TEMPLATE/0rule_violation_false-positive.md @@ -13,7 +13,7 @@ assignees: '' **Rule:** Please provide the rule name and a link to the rule documentation: - + **Description:** diff --git a/.github/ISSUE_TEMPLATE/1rule_violation_false-negative.md b/.github/ISSUE_TEMPLATE/1rule_violation_false-negative.md index 51702e0038..d6ae5c5d0d 100644 --- a/.github/ISSUE_TEMPLATE/1rule_violation_false-negative.md +++ b/.github/ISSUE_TEMPLATE/1rule_violation_false-negative.md @@ -13,7 +13,7 @@ assignees: '' **Rule:** Please provide the rule name and a link to the rule documentation: - + **Description:** diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ed97a2878b..b4fe5f9d27 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,11 +33,11 @@ When filing a bug report, please provide as much information as possible, so tha ## Documentation -There is some documentation available under . Feel free to create a bug report if +There is some documentation available under . Feel free to create a bug report if documentation is missing, incomplete or outdated. See [Bug reports](#bug-reports). The documentation is generated as a Jekyll site, the source is available at: . You can find build instructions there. -For more on contributing documentation check +For more on contributing documentation check ## Questions diff --git a/README.md b/README.md index 5fe24a5db5..382eb8ca61 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![Coverage Status](https://coveralls.io/repos/github/pmd/pmd/badge.svg)](https://coveralls.io/github/pmd/pmd) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/ea550046a02344ec850553476c4aa2ca)](https://www.codacy.com/gh/pmd/pmd/dashboard?utm_source=github.com&utm_medium=referral&utm_content=pmd/pmd&utm_campaign=Badge_Grade) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](code_of_conduct.md) -[![Documentation (latest)](https://img.shields.io/badge/docs-latest-green)](https://pmd.github.io/latest/) +[![Documentation (latest)](https://img.shields.io/badge/docs-latest-green)](https://docs.pmd-code.org/latest/) **PMD** is a source code analyzer. It finds common programming flaws like unused variables, empty catch blocks, unnecessary object creation, and so forth. It supports many languages. It can be extended with custom rules. @@ -32,9 +32,9 @@ it makes sense. Download the latest binary zip from the [releases](https://github.com/pmd/pmd/releases/latest) and extract it somewhere. -Execute `bin/run.sh pmd` or `bin\pmd.bat`. +Execute `bin/pmd check` or `bin\pmd.bat check`. -See also [Getting Started](https://pmd.github.io/latest/pmd_userdocs_installation.html) +See also [Getting Started](https://docs.pmd-code.org/latest/pmd_userdocs_installation.html) **Demo:** @@ -43,7 +43,7 @@ This shows how PMD can detect for loops, that can be replaced by for-each loops. ![Demo](docs/images/userdocs/pmd-demo.gif) There are plugins for Maven and Gradle as well as for various IDEs. -See [Tools / Integrations](https://pmd.github.io/latest/pmd_userdocs_tools.html) +See [Tools / Integrations](https://docs.pmd-code.org/latest/pmd_userdocs_tools.html) ## ℹ️ How to get support? @@ -54,7 +54,7 @@ See [Tools / Integrations](https://pmd.github.io/latest/pmd_userdocs_tools.html) * 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 -- create a new [discussion](https://github.com/pmd/pmd/discussions). * I have a quick question -- ask in our [Gitter room](https://app.gitter.im/#/room/#pmd_pmd:gitter.im). -* Where's your documentation? -- +* Where's your documentation? -- ## 🤝 Contributing diff --git a/docs/README.md b/docs/README.md index d0aef2914f..71c8eaf911 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,8 +1,10 @@ # PMD Documentation -The documentation is available at: +The snapshot documentation (build by github pages) is available at: . -The documentation for the latest release is at: +The same documentation (build with our own scripts) is available at: . + +The documentation for the latest release is at: ## Site Theme diff --git a/docs/_plugins/rule_tag.rb b/docs/_plugins/rule_tag.rb index 36eeb12032..7b5aa3ee13 100644 --- a/docs/_plugins/rule_tag.rb +++ b/docs/_plugins/rule_tag.rb @@ -53,7 +53,7 @@ class RuleTag < Liquid::Tag # This is passed from the release notes processing script # When generating links for the release notes, the links should be absolute if context["is_release_notes_processor"] - url_prefix = "https://pmd.github.io/pmd-#{context["site.pmd.version"]}/" + url_prefix = "https://docs.pmd-code.org/pmd-doc-#{context["site.pmd.version"]}/" end if @was_removed diff --git a/docs/pages/pmd/projectdocs/committers/main_landing_page.md b/docs/pages/pmd/projectdocs/committers/main_landing_page.md index a0f2515068..8ad63c686f 100644 --- a/docs/pages/pmd/projectdocs/committers/main_landing_page.md +++ b/docs/pages/pmd/projectdocs/committers/main_landing_page.md @@ -27,12 +27,6 @@ It usually takes 15 minutes. * There is also a sub page "news" which lists all news. * Layout: [_layouts/news.html](https://github.com/pmd/pmd.github.io/blob/master/_layouts/news.html) * Page (which is pretty empty): [news.html](https://github.com/pmd/pmd.github.io/blob/master/news.html) -* Documentation for the latest release: - * The PMD documentation of the latest release is simply copied as static html into the folder [latest/](https://github.com/pmd/pmd.github.io/tree/master/latest). - This makes the latest release documentation available under the stable URL - . This URL is also used for the [sitemap.xml](https://github.com/pmd/pmd.github.io/blob/master/sitemap.xml). -* Documentation for previous releases are still being kept under the folders `pmd-/`. - ## Building the page locally diff --git a/docs/pages/pmd/projectdocs/committers/releasing.md b/docs/pages/pmd/projectdocs/committers/releasing.md index d41605db65..92ddf8035c 100644 --- a/docs/pages/pmd/projectdocs/committers/releasing.md +++ b/docs/pages/pmd/projectdocs/committers/releasing.md @@ -45,7 +45,7 @@ e.g. it requires that the repo `pmd.github.io` is checked out aside the main pmd The script `do-release.sh` is called in the directory `/home/joe/source/pmd` and searches for `../pmd.github.io`. -Also make sure, that the repo "pmd.github.io" is locally up to date and has no local changes. +Also make sure, that the repo "pmd.github.io" is locally up-to-date and has no local changes. ### The Release Notes and docs @@ -183,11 +183,8 @@ Here is, what happens: * Remove old javadoc for the SNAPSHOT version, e.g. delete . * Create a draft news post on for the new release. This contains the rendered release notes. -* Add the documentation of the new release to a subfolder on , also make - this folder available as `latest`, so that shows the new - version and is the URL for the specific release. -* Also copy the documentation to sourceforge's web space, so that it is available as - . All previously copied version are listed +* Copy the documentation to sourceforge's web space, so that it is available as + . All previously copied versions are listed under . * After all this is done, the release on github () is published and the news post on sourceforge (https://sourceforge.net/p/pmd/news/> is publishes as well. @@ -206,7 +203,7 @@ news: * Downloads: https://github.com/pmd/pmd/releases/tag/pmd_releases%2F - * Documentation: https://pmd.github.io/pmd-/ + * Documentation: https://docs.pmd-code.org/pmd-doc-/ And Copy-Paste the release notes @@ -219,20 +216,21 @@ Tweet on , eg.: ### Checklist -| Task | Description | URL | ☐ / ✔ | -|------|-------------|-----|-------| -| maven central | The new version of all artifacts are available in maven central | | | -| github releases | A new release with 3 assets (bin, src, doc) is created | | | -| sourceforge files | The 3 assets (bin, src, doc) are uploaded, the new version is pre-selected as latest | | | -| homepage | Main landing page points to new version, doc for new version is available | | | -| homepage2 | New blogpost for the new release is posted | | | -| docs | New docs are uploaded | | | -| docs-archive | New docs are also on archive site | | | -| javadoc | New javadocs are uploaded | | | -| news | New blogpost on sourceforge is posted | | | -| regression-tester | New release baseline is uploaded | | | -| mailing list | announcement on mailing list is sent | | | -| twitter | tweet about the new release | | | +| Task | Description | URL | ☐ / ✔ | +|-------------------|--------------------------------------------------------------------------------------|-----------------------------------------------------------------|-------------------------| +| maven central | The new version of all artifacts are available in maven central | | | +| github releases | A new release with 3 assets (bin, src, doc) is created | | | +| sourceforge files | The 3 assets (bin, src, doc) are uploaded, the new version is pre-selected as latest | | | +| homepage | Main landing page points to new version, doc for new version is available | | | +| homepage2 | New blogpost for the new release is posted | | | +| docs | New docs are uploaded | | | +| docs2 | New version in the docs is listed under "Version specific documentation" | | | +| docs-archive | New docs are also on archive site | | | +| javadoc | New javadocs are uploaded | | | +| news | New blogpost on sourceforge is posted | | | +| regression-tester | New release baseline is uploaded | | | +| mailing list | announcement on mailing list is sent | | | +| twitter | tweet about the new release | | | ## Prepare the next release @@ -309,7 +307,7 @@ In theory, the fixes should already be there, but you never now. If releases from multiple branches are being done, the order matters. You should start from the "oldest" branch, e.g. `pmd/5.4.x`, release from there. Then merge (see above) into the next branch, e.g. `pmd/5.5.x` and release from there. Then merge into the `master` branch and release from there. This way, the last release done, becomes -automatically the latest release on and on sourceforge. +automatically the latest release on and on sourceforge. ### (Optional) Create a new release branch diff --git a/docs/report-examples/pmd-report.sarif.json b/docs/report-examples/pmd-report.sarif.json index e785af258d..005c000c90 100644 --- a/docs/report-examples/pmd-report.sarif.json +++ b/docs/report-examples/pmd-report.sarif.json @@ -7,7 +7,7 @@ "driver": { "name": "PMD", "version": "", - "informationUri": "https://pmd.github.io/pmd/", + "informationUri": "https://docs.pmd-code.org/latest/", "rules": [ { "id": "ApexSharingViolations", @@ -17,7 +17,7 @@ "fullDescription": { "text": "Detect classes declared without explicit sharing mode if DML methods are used. This forces the developer to take access restrictions into account before modifying objects." }, - "helpUri": "https://pmd.github.io/pmd/pmd_rules_apex_security.html#apexsharingviolations", + "helpUri": "https://docs.pmd-code.org/latest/pmd_rules_apex_security.html#apexsharingviolations", "help": { "text": "Detect classes declared without explicit sharing mode if DML methods are used. This forces the developer to take access restrictions into account before modifying objects." }, @@ -37,7 +37,7 @@ "fullDescription": { "text": "This rule validates that: ApexDoc comments are present for classes, methods, and properties that are public or global, excluding overrides and test classes (as well as the contents of test classes)." }, - "helpUri": "https://pmd.github.io/pmd/pmd_rules_apex_documentation.html#apexdoc", + "helpUri": "https://docs.pmd-code.org/latest/pmd_rules_apex_documentation.html#apexdoc", "help": { "text": "This rule validates that: ApexDoc comments are present for classes, methods, and properties that are public or global, excluding overrides and test classes (as well as the contents of test classes)." }, @@ -152,4 +152,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java b/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java index d2c9ad4a77..905b18da14 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java @@ -546,9 +546,9 @@ public final class PmdAnalysis implements AutoCloseable { && configuration.getAnalysisCache() instanceof NoopAnalysisCache && reporter.isLoggable(Level.WARN)) { final String version = - PMDVersion.isUnknown() || PMDVersion.isSnapshot() ? "latest" : "pmd-" + PMDVersion.VERSION; + PMDVersion.isUnknown() || PMDVersion.isSnapshot() ? "latest" : "pmd-doc-" + PMDVersion.VERSION; reporter.warn("This analysis could be faster, please consider using Incremental Analysis: " - + "https://pmd.github.io/{0}/pmd_userdocs_incremental_analysis.html", version); + + "https://docs.pmd-code.org/{0}/pmd_userdocs_incremental_analysis.html", version); } } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java index 7bd956c2cb..0bcc86158c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java @@ -39,12 +39,10 @@ public class CodeClimateRenderer extends AbstractIncrementingRenderer { } private static String getPmdPropertiesURL() { + final String BASE_URL = "https://docs.pmd-code.org/"; final String PAGE = "/pmd_userdocs_configuring_rules.html#rule-properties"; - String url = "https://pmd.github.io/pmd-" + PMDVersion.VERSION + PAGE; - if (PMDVersion.isSnapshot() || PMDVersion.isUnknown()) { - url = "https://pmd.github.io/latest" + PAGE; - } - return url; + final String VERSION_PART = PMDVersion.isUnknown() || PMDVersion.isSnapshot() ? "latest" : "pmd-doc-" + PMDVersion.VERSION; + return BASE_URL + VERSION_PART + PAGE; } @Override diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SarifRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SarifRenderer.java index f4052818d0..39cb54baf6 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SarifRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/SarifRenderer.java @@ -71,6 +71,7 @@ public class SarifRenderer extends AbstractIncrementingRenderer { final SarifLog sarifLog = sarifLogBuilder.build(); final String json = gson.toJson(sarifLog); writer.write(json); + writer.println(); } @Override diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java index 23fa770a0c..b391b4f5f9 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/internal/sarif/SarifLogBuilder.java @@ -190,7 +190,7 @@ public class SarifLogBuilder { return Component.builder() .name("PMD") .version(PMDVersion.VERSION) - .informationUri("https://pmd.github.io/pmd/") + .informationUri("https://docs.pmd-code.org/latest/") .build(); } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java index 283f39f6c3..0a0b87b385 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java @@ -27,7 +27,7 @@ class CodeClimateRendererTest extends AbstractRendererTest { + "[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): Style\\n\\n" + "[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): 50000\\n\\n" + "Description with Unicode Character U+2013: – .\\n\\n" - + "### [PMD properties](https://pmd.github.io/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n" + + "### [PMD properties](https://docs.pmd-code.org/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n" + "Name | Value | Description\\n" + "--- | --- | ---\\n" + "violationSuppressRegex | | Suppress violations with messages matching a regular expression\\n" + "violationSuppressXPath | | Suppress violations on nodes which match a given relative XPath expression.\\n" @@ -42,7 +42,7 @@ class CodeClimateRendererTest extends AbstractRendererTest { + "[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): Style\\n\\n" + "[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): 50000\\n\\n" + "Description with Unicode Character U+2013: – .\\n\\n" - + "### [PMD properties](https://pmd.github.io/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n" + + "### [PMD properties](https://docs.pmd-code.org/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n" + "Name | Value | Description\\n" + "--- | --- | ---\\n" + "violationSuppressRegex | | Suppress violations with messages matching a regular expression\\n" + "violationSuppressXPath | | Suppress violations on nodes which match a given relative XPath expression.\\n" @@ -64,7 +64,7 @@ class CodeClimateRendererTest extends AbstractRendererTest { + "[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): Style\\n\\n" + "[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): 50000\\n\\n" + "Description with Unicode Character U+2013: – .\\n\\n" - + "### [PMD properties](https://pmd.github.io/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n" + + "### [PMD properties](https://docs.pmd-code.org/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n" + "Name | Value | Description\\n" + "--- | --- | ---\\n" + "violationSuppressRegex | | Suppress violations with messages matching a regular expression\\n" + "violationSuppressXPath | | Suppress violations on nodes which match a given relative XPath expression.\\n" @@ -74,7 +74,7 @@ class CodeClimateRendererTest extends AbstractRendererTest { + "[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): Style\\n\\n" + "[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): 50000\\n\\n" + "desc\\n\\n" - + "### [PMD properties](https://pmd.github.io/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n" + + "### [PMD properties](https://docs.pmd-code.org/latest/pmd_userdocs_configuring_rules.html#rule-properties)\\n\\n" + "Name | Value | Description\\n" + "--- | --- | ---\\n" + "violationSuppressRegex | | Suppress violations with messages matching a regular expression\\n" + "violationSuppressXPath | | Suppress violations on nodes which match a given relative XPath expression.\\n" diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/empty.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/empty.sarif.json index 91178676f0..43307fcb5f 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/empty.sarif.json +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/empty.sarif.json @@ -7,7 +7,7 @@ "driver": { "name": "PMD", "version": "unknown", - "informationUri": "https://pmd.github.io/pmd/", + "informationUri": "https://docs.pmd-code.org/latest/", "rules": [] } }, @@ -21,4 +21,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-configerror.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-configerror.sarif.json index 16adc0caf0..7f467c9aab 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-configerror.sarif.json +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-configerror.sarif.json @@ -7,7 +7,7 @@ "driver": { "name": "PMD", "version": "unknown", - "informationUri": "https://pmd.github.io/pmd/", + "informationUri": "https://docs.pmd-code.org/latest/", "rules": [] } }, @@ -30,4 +30,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error-nomessage.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error-nomessage.sarif.json index 6b7ad4c6fc..e0f849cf32 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error-nomessage.sarif.json +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error-nomessage.sarif.json @@ -7,7 +7,7 @@ "driver": { "name": "PMD", "version": "unknown", - "informationUri": "https://pmd.github.io/pmd/", + "informationUri": "https://docs.pmd-code.org/latest/", "rules": [] } }, @@ -39,4 +39,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error.sarif.json index 84ef17fe38..f4732be117 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error.sarif.json +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-error.sarif.json @@ -7,7 +7,7 @@ "driver": { "name": "PMD", "version": "unknown", - "informationUri": "https://pmd.github.io/pmd/", + "informationUri": "https://docs.pmd-code.org/latest/", "rules": [] } }, @@ -39,4 +39,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json index 7b54693e8d..ab4a9f0f02 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple-locations.sarif.json @@ -7,7 +7,7 @@ "driver": { "name": "PMD", "version": "unknown", - "informationUri": "https://pmd.github.io/pmd/", + "informationUri": "https://docs.pmd-code.org/latest/", "rules": [ { "id": "Foo", @@ -127,4 +127,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json index 8fcab6485e..99dbab1140 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected-multiple.sarif.json @@ -7,7 +7,7 @@ "driver": { "name": "PMD", "version": "unknown", - "informationUri": "https://pmd.github.io/pmd/", + "informationUri": "https://docs.pmd-code.org/latest/", "rules": [ { "id": "Foo", @@ -105,4 +105,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json index 7395beb6d8..19e9ff805f 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/renderers/sarif/expected.sarif.json @@ -7,7 +7,7 @@ "driver": { "name": "PMD", "version": "unknown", - "informationUri": "https://pmd.github.io/pmd/", + "informationUri": "https://docs.pmd-code.org/latest/", "rules": [ { "id": "Foo", @@ -64,4 +64,4 @@ ] } ] -} \ No newline at end of file +} From be19c6fe9badeae3ba270307298e8834f3e71ea1 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Mar 2023 09:18:17 +0200 Subject: [PATCH 06/63] [doc] Add logos in square shape Refs #4307 --- docs/images/logo/pmd-logo-300px-squared.png | Bin 0 -> 11936 bytes docs/images/logo/pmd-logo-600px-squared.png | Bin 0 -> 20708 bytes docs/images/logo/pmd-logo-70px-squared.png | Bin 0 -> 5850 bytes .../logo/pmd-logo-white-300px-squared.png | Bin 0 -> 12237 bytes docs/images/logo/pmd-logo-white-400x165px.png | Bin 0 -> 11985 bytes .../logo/pmd-logo-white-600px-squared.png | Bin 0 -> 21237 bytes docs/pages/pmd/projectdocs/logo.md | 9 ++++++++- 7 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 docs/images/logo/pmd-logo-300px-squared.png create mode 100644 docs/images/logo/pmd-logo-600px-squared.png create mode 100644 docs/images/logo/pmd-logo-70px-squared.png create mode 100644 docs/images/logo/pmd-logo-white-300px-squared.png create mode 100644 docs/images/logo/pmd-logo-white-400x165px.png create mode 100644 docs/images/logo/pmd-logo-white-600px-squared.png diff --git a/docs/images/logo/pmd-logo-300px-squared.png b/docs/images/logo/pmd-logo-300px-squared.png new file mode 100644 index 0000000000000000000000000000000000000000..78c2df32c397b7fb5c7d6080df9ae8d66ec427b8 GIT binary patch literal 11936 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 literal 0 HcmV?d00001 diff --git a/docs/images/logo/pmd-logo-600px-squared.png b/docs/images/logo/pmd-logo-600px-squared.png new file mode 100644 index 0000000000000000000000000000000000000000..d42ea787d2256dd816a13c473e4ab8fdf57db9cf GIT binary patch literal 20708 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 MdLvo-+W6i70Jn&tZvX%Q literal 0 HcmV?d00001 diff --git a/docs/images/logo/pmd-logo-70px-squared.png b/docs/images/logo/pmd-logo-70px-squared.png new file mode 100644 index 0000000000000000000000000000000000000000..104df9769a8ea980d329077c85ca3fe2b70d56bd GIT binary patch literal 5850 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 literal 0 HcmV?d00001 diff --git a/docs/images/logo/pmd-logo-white-400x165px.png b/docs/images/logo/pmd-logo-white-400x165px.png new file mode 100644 index 0000000000000000000000000000000000000000..d8187aeb846cea48d80474081189d86450a89d03 GIT binary patch literal 11985 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 Fe*m~ixU&EN literal 0 HcmV?d00001 diff --git a/docs/images/logo/pmd-logo-white-600px-squared.png b/docs/images/logo/pmd-logo-white-600px-squared.png new file mode 100644 index 0000000000000000000000000000000000000000..9e47e815d8a2f2c90897436458033556f8cf9ab2 GIT binary patch literal 21237 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 Date: Fri, 31 Mar 2023 09:25:45 +0200 Subject: [PATCH 07/63] [doc] Add old logo as reference documentation --- .../logo/pmd-old-logo-white-600x440px.png | Bin 0 -> 13787 bytes docs/images/logo/pmd-old.svg | 442 ++++++++++++++++++ docs/pages/pmd/projectdocs/logo.md | 8 + 3 files changed, 450 insertions(+) create mode 100644 docs/images/logo/pmd-old-logo-white-600x440px.png create mode 100644 docs/images/logo/pmd-old.svg diff --git a/docs/images/logo/pmd-old-logo-white-600x440px.png b/docs/images/logo/pmd-old-logo-white-600x440px.png new file mode 100644 index 0000000000000000000000000000000000000000..90023b450c73b047fd32d617f07940c26e6fc72b GIT binary patch literal 13787 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 j-@oDbJK15x?s1K9x_`Y#?4 literal 0 HcmV?d00001 diff --git a/docs/images/logo/pmd-old.svg b/docs/images/logo/pmd-old.svg new file mode 100644 index 0000000000..1e1bc36936 --- /dev/null +++ b/docs/images/logo/pmd-old.svg @@ -0,0 +1,442 @@ + + + + + PMD + + + + image/svg+xml + + PMD + + + http://www.bijzonderbezig.nl + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/pages/pmd/projectdocs/logo.md b/docs/pages/pmd/projectdocs/logo.md index 4457066362..3838039f8e 100644 --- a/docs/pages/pmd/projectdocs/logo.md +++ b/docs/pages/pmd/projectdocs/logo.md @@ -25,3 +25,11 @@ The following PMD Logos and Icons are licensed under [CC BY 4.0](https://creativ * [Logo (600px, white, suqare shape)](images/logo/pmd-logo-white-600px-squared.png) * [Favicon (16x16)](images/logo/favicon.ico) + +This new greenish logo was introduced with PMD 7. + +Before that, PMD used the following logo with the tagline "Don't shoot the messenger". +These old logos are provided here only as reference for historical reasons and shouldn't be used anymore. + +* [Old logo - pmd-old.svg](images/logo/pmd-old.svg) +* [Old logo (600x440px, white)](images/logo/pmd-old-logo-white-600x440px.png) From a9d8fe70a78c2cb63e10d48854c1f82adcb95e64 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 31 Mar 2023 09:27:04 +0200 Subject: [PATCH 08/63] [doc] Fix github logo in footer --- docs/_includes/footer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_includes/footer.html b/docs/_includes/footer.html index e8e3c871f4..46187408cf 100755 --- a/docs/_includes/footer.html +++ b/docs/_includes/footer.html @@ -9,7 +9,7 @@ target="_blank" href="https://github.com/{{site.github_editme_path}}{{editmepath}}" role="button" - > Edit on GitHub Edit on GitHub
{% endif %} From 702318a41df6b9c647093f8430d95ec9b2dcdb8c Mon Sep 17 00:00:00 2001 From: nwcm <111259588+nwcm@users.noreply.github.com> Date: Tue, 4 Apr 2023 23:07:08 +1000 Subject: [PATCH 09/63] Update design.xml --- pmd-apex/src/main/resources/category/apex/design.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pmd-apex/src/main/resources/category/apex/design.xml b/pmd-apex/src/main/resources/category/apex/design.xml index 6f34471e41..f00fbe652e 100644 --- a/pmd-apex/src/main/resources/category/apex/design.xml +++ b/pmd-apex/src/main/resources/category/apex/design.xml @@ -48,13 +48,13 @@ Avoid having unused methods since they make understanding and maintaining code h This rule finds not only unused private methods, but public methods as well. [ApexLink](https://github.com/nawforce/ApexLink) is used to make this possible and this needs -additional configuration. The environment variable `PMD_APEX_ROOTDIRECTORY` needs to be set prior to executing +additional configuration. The environment variable `PMD_APEX_ROOT_DIRECTORY` needs to be set prior to executing PMD. With this variable the root directory of the Salesforce metadata, where `sfdx-project.json` resides, is specified. ApexLink can then load all the classes in the project and figure out, whether a method is used or not. -For an accurate analysis it is important that the `PMD_APEX_ROOTDIRECTORY` contains a complete set of metadata that +For an accurate analysis it is important that the `PMD_APEX_ROOT_DIRECTORY` contains a complete set of metadata that may be referenced from the Apex source code, such as Custom Objects, Visualforce Pages, Flows and Labels. The -`PMD_APEX_ROOTDIRECTORY` directory must contain a `sfdx-project.json`, but metadata may be either in the +`PMD_APEX_ROOT_DIRECTORY` directory must contain a `sfdx-project.json`, but metadata may be either in the [SFDX Source format](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_source_file_format.htm) or the older MDAPI format. The `packageDirectories` entries in `sfdx-project.json` are used to determine which directories to search for metadata, if a `.forceignore` file is present it will be respected. From cf213fbbe3ab1e516da18c4f539b5d71ac3f08fa Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 4 Apr 2023 18:18:58 +0200 Subject: [PATCH 10/63] [doc] Fix links to pmd_release_notes_pmd7.html --- docs/pages/release_notes.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index fbd27645e5..326c7f4c5f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -57,7 +57,7 @@ The new official logo of PMD: * Rewritten type resolution framework and symbol table correctly implements the JLS * AST exposes more semantic information (method calls, field accesses) -For more information, see the [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html). +For more information, see the [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html). Contributors: [Clément Fournier](https://github.com/oowekyala) (@oowekyala), [Andreas Dangel](https://github.com/adangel) (@adangel), @@ -75,7 +75,7 @@ Contributors: [Clément Fournier](https://github.com/oowekyala) (@oowekyala), ![Demo]({{ baseurl }}images/userdocs/pmd-demo.gif) -For more information, see the [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html). +For more information, see the [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html). Contributors: [Juan Martín Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod) @@ -85,7 +85,7 @@ Contributors: [Juan Martín Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuy * Previously, Antlr grammar could only be used for CPD * New supported languages: Swift and Kotlin -For more information, see the [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html). +For more information, see the [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html). Contributors: [Lucas Soncini](https://github.com/lsoncini) (@lsoncini), [Matías Fraga](https://github.com/matifraga) (@matifraga), @@ -94,7 +94,7 @@ Contributors: [Lucas Soncini](https://github.com/lsoncini) (@lsoncini), ### 🎉 Language Related Changes Note that this is just a concise listing of the highlight. -For more information on the languages, see the [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html). +For more information on the languages, see the [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html). #### New: Swift support @@ -173,7 +173,7 @@ Contributors: [Lucas Soncini](https://github.com/lsoncini) (@lsoncini), #### Removed Rules Many rules, that were previously deprecated have been finally removed. -See [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html) for the complete list. +See [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html) for the complete list. ### 🚨 API @@ -182,7 +182,7 @@ have a clear separation between a well-defined API and the implementation, which This should help us in future development. Also, there are some improvement and changes in different areas. For the detailed description -of the changes listed here, see [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html). +of the changes listed here, see [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html). * Miscellaneous smaller changes and cleanups * XPath 3.1 support for XPath-based rules @@ -192,7 +192,7 @@ of the changes listed here, see [Detailed Release Notes for PMD 7](pmd_release_n * Language Lifecycle and Language Properties ### 💥 Compatibility and migration notes -See [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html). +See [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html). ### 🐛 Fixed Issues From 1c2d77fd6a4e760bc8ad29cde77c6bb71a75a0bc Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Apr 2023 10:17:04 +0200 Subject: [PATCH 11/63] Introduce a pmd-languages-deps module This is kind of a [BOM](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#bill-of-materials-bom-poms), but different: It defines hard dependencies and not just versions for dependencyManagement. This new module depends on all languages modules and is used by pmd-cli and by pmd-dist. So, we have only one place to modify, when we add new language modules. --- pmd-cli/pom.xml | 165 +----------------- pmd-dist/pom.xml | 142 +-------------- .../src/main/resources/assemblies/pmd-bin.xml | 2 + pmd-languages-deps/pom.xml | 158 +++++++++++++++++ pom.xml | 1 + 5 files changed, 171 insertions(+), 297 deletions(-) create mode 100644 pmd-languages-deps/pom.xml diff --git a/pmd-cli/pom.xml b/pmd-cli/pom.xml index 5d65824a77..a144afdd06 100644 --- a/pmd-cli/pom.xml +++ b/pmd-cli/pom.xml @@ -78,168 +78,15 @@ ${project.version} - - + net.sourceforge.pmd - pmd-apex - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-cpp - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-cs - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-dart - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-fortran - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-gherkin - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-go - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-groovy - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-html - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-lua - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-java - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-javascript - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-jsp - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-kotlin - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-matlab - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-modelica - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-perl - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-objectivec - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-php - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-plsql - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-python - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-ruby - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-scala_2.13 - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-swift - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-visualforce - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-vm - ${project.version} - runtime - - - net.sourceforge.pmd - pmd-xml + pmd-languages-deps ${project.version} + pom runtime diff --git a/pmd-dist/pom.xml b/pmd-dist/pom.xml index 554b2cb809..43bc6c06d8 100644 --- a/pmd-dist/pom.xml +++ b/pmd-dist/pom.xml @@ -126,7 +126,7 @@ net.sourceforge.pmd - pmd-apex + pmd-core ${project.version} @@ -142,136 +142,11 @@ sh completion - - net.sourceforge.pmd - pmd-core - ${project.version} - net.sourceforge.pmd pmd-ant ${project.version} - - net.sourceforge.pmd - pmd-cpp - ${project.version} - - - net.sourceforge.pmd - pmd-cs - ${project.version} - - - net.sourceforge.pmd - pmd-dart - ${project.version} - - - net.sourceforge.pmd - pmd-fortran - ${project.version} - - - net.sourceforge.pmd - pmd-gherkin - ${project.version} - - - net.sourceforge.pmd - pmd-go - ${project.version} - - - net.sourceforge.pmd - pmd-groovy - ${project.version} - - - net.sourceforge.pmd - pmd-html - ${project.version} - - - net.sourceforge.pmd - pmd-lua - ${project.version} - - - net.sourceforge.pmd - pmd-java - ${project.version} - - - net.sourceforge.pmd - pmd-javascript - ${project.version} - - - net.sourceforge.pmd - pmd-jsp - ${project.version} - - - net.sourceforge.pmd - pmd-kotlin - ${project.version} - - - net.sourceforge.pmd - pmd-matlab - ${project.version} - - - net.sourceforge.pmd - pmd-modelica - ${project.version} - - - net.sourceforge.pmd - pmd-perl - ${project.version} - - - net.sourceforge.pmd - pmd-objectivec - ${project.version} - - - net.sourceforge.pmd - pmd-php - ${project.version} - - - net.sourceforge.pmd - pmd-plsql - ${project.version} - - - net.sourceforge.pmd - pmd-python - ${project.version} - - - net.sourceforge.pmd - pmd-ruby - ${project.version} - - - net.sourceforge.pmd - pmd-scala_2.13 - ${project.version} - - - net.sourceforge.pmd - pmd-swift - ${project.version} - - - net.sourceforge.pmd - pmd-tsql - ${project.version} - net.sourceforge.pmd pmd-ui @@ -279,20 +154,11 @@ net.sourceforge.pmd - pmd-visualforce + pmd-languages-deps ${project.version} + pom + runtime - - net.sourceforge.pmd - pmd-vm - ${project.version} - - - net.sourceforge.pmd - pmd-xml - ${project.version} - - org.slf4j diff --git a/pmd-dist/src/main/resources/assemblies/pmd-bin.xml b/pmd-dist/src/main/resources/assemblies/pmd-bin.xml index 2215aa3265..aa5a06faab 100644 --- a/pmd-dist/src/main/resources/assemblies/pmd-bin.xml +++ b/pmd-dist/src/main/resources/assemblies/pmd-bin.xml @@ -71,7 +71,9 @@ runtime + net.sourceforge.pmd:pmd-apex-jorje:pom net.sourceforge.pmd:pmd-cli:sh:completion:* + net.sourceforge.pmd:pmd-languages-deps:pom lib 0755 diff --git a/pmd-languages-deps/pom.xml b/pmd-languages-deps/pom.xml new file mode 100644 index 0000000000..580aa5f130 --- /dev/null +++ b/pmd-languages-deps/pom.xml @@ -0,0 +1,158 @@ + + + 4.0.0 + + net.sourceforge.pmd + pmd + 7.0.0-SNAPSHOT + + + pmd-languages-deps + pom + PMD Languages Dependencies + + + + net.sourceforge.pmd + pmd-apex + ${project.version} + + + net.sourceforge.pmd + pmd-cpp + ${project.version} + + + net.sourceforge.pmd + pmd-cs + ${project.version} + + + net.sourceforge.pmd + pmd-dart + ${project.version} + + + net.sourceforge.pmd + pmd-fortran + ${project.version} + + + net.sourceforge.pmd + pmd-gherkin + ${project.version} + + + net.sourceforge.pmd + pmd-go + ${project.version} + + + net.sourceforge.pmd + pmd-groovy + ${project.version} + + + net.sourceforge.pmd + pmd-html + ${project.version} + + + net.sourceforge.pmd + pmd-java + ${project.version} + + + net.sourceforge.pmd + pmd-javascript + ${project.version} + + + net.sourceforge.pmd + pmd-jsp + ${project.version} + + + net.sourceforge.pmd + pmd-kotlin + ${project.version} + + + net.sourceforge.pmd + pmd-lua + ${project.version} + + + net.sourceforge.pmd + pmd-matlab + ${project.version} + + + net.sourceforge.pmd + pmd-modelica + ${project.version} + + + net.sourceforge.pmd + pmd-objectivec + ${project.version} + + + net.sourceforge.pmd + pmd-perl + ${project.version} + + + net.sourceforge.pmd + pmd-php + ${project.version} + + + net.sourceforge.pmd + pmd-plsql + ${project.version} + + + net.sourceforge.pmd + pmd-python + ${project.version} + + + net.sourceforge.pmd + pmd-ruby + ${project.version} + + + net.sourceforge.pmd + pmd-scala_2.13 + ${project.version} + + + net.sourceforge.pmd + pmd-swift + ${project.version} + + + net.sourceforge.pmd + pmd-tsql + ${project.version} + + + net.sourceforge.pmd + pmd-visualforce + ${project.version} + + + net.sourceforge.pmd + pmd-vm + ${project.version} + + + net.sourceforge.pmd + pmd-xml + ${project.version} + + + diff --git a/pom.xml b/pom.xml index a2b90df0c5..b637405c38 100644 --- a/pom.xml +++ b/pom.xml @@ -1185,5 +1185,6 @@ pmd-vm pmd-xml pmd-ant + pmd-languages-deps From 3d6e15b523205aa64ee0373adaa4741cad1b4823 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Apr 2023 11:57:37 +0200 Subject: [PATCH 12/63] Disable maven-pmd-plugin option linkXRef We don't have the jxr plugin and also don't create reports. Disabling this option avoids the many warnings like `[WARNING] Unable to locate Source XRef to link to - DISABLED`. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a2b90df0c5..45490d2351 100644 --- a/pom.xml +++ b/pom.xml @@ -436,7 +436,7 @@ - true + false 100 1.${java.version} From ae0bf240d76130bbae58e72a960aadf5b440e4d6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 6 Apr 2023 12:49:37 +0200 Subject: [PATCH 13/63] Provide Software Bill of Materials (SBOM) - Add cyclonedx plugin to generate SBOM (Software Bill of Materials) - The SBOM is attached and deployed into maven central - The SBOM is also included in the binary distribution of PMD See https://github.com/CycloneDX/cyclonedx-maven-plugin --- docs/pages/release_notes.md | 3 +++ .../src/main/resources/assemblies/pmd-bin.xml | 13 ++++++++++ .../pmd/it/BinaryDistributionIT.java | 2 ++ pom.xml | 25 +++++++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b875222f4d..a6a58421b7 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -40,6 +40,8 @@ This section lists the most important changes from the last release candidate. The remaining section describe the complete release notes for 7.0.0. Fixed Issues: +* miscellaneous + * [#4462](https://github.com/pmd/pmd/issues/4462): Provide Software Bill of Materials (SBOM) * java-codestyle * [#4273](https://github.com/pmd/pmd/issues/4273): \[java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default * java-errorprone @@ -208,6 +210,7 @@ See [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html). * [#2497](https://github.com/pmd/pmd/issues/2497): PMD 7 Logo page * [#2498](https://github.com/pmd/pmd/issues/2498): Update PMD 7 Logo in documentation * [#3797](https://github.com/pmd/pmd/issues/3797): \[all] Use JUnit5 + * [#4462](https://github.com/pmd/pmd/issues/4462): Provide Software Bill of Materials (SBOM) * ant * [#4080](https://github.com/pmd/pmd/issues/4080): \[ant] Split off Ant integration into a new submodule * core diff --git a/pmd-dist/src/main/resources/assemblies/pmd-bin.xml b/pmd-dist/src/main/resources/assemblies/pmd-bin.xml index 2215aa3265..738017141b 100644 --- a/pmd-dist/src/main/resources/assemblies/pmd-bin.xml +++ b/pmd-dist/src/main/resources/assemblies/pmd-bin.xml @@ -53,6 +53,19 @@ + + + target/bom.xml + sbom + pmd-${project.version}-cyclonedx.xml + + + target/bom.json + sbom + pmd-${project.version}-cyclonedx.json + + + diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java b/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java index c1331cbd67..569c17e5cd 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java @@ -87,6 +87,8 @@ class BinaryDistributionIT extends AbstractBinaryDistributionTest { result.add(basedir + "shell/pmd-completion.sh"); result.add(basedir + "lib/pmd-core-" + PMDVersion.VERSION + ".jar"); result.add(basedir + "lib/pmd-java-" + PMDVersion.VERSION + ".jar"); + result.add(basedir + "sbom/pmd-" + PMDVersion.VERSION + "-cyclonedx.xml"); + result.add(basedir + "sbom/pmd-" + PMDVersion.VERSION + "-cyclonedx.json"); return result; } diff --git a/pom.xml b/pom.xml index a2b90df0c5..353eb10d90 100644 --- a/pom.xml +++ b/pom.xml @@ -503,6 +503,11 @@ jacoco-maven-plugin 0.8.8 + + org.cyclonedx + cyclonedx-maven-plugin + 2.7.6 + @@ -624,6 +629,26 @@ https://oss.sonatype.org/ + + org.cyclonedx + cyclonedx-maven-plugin + + + package + + makeAggregateBom + + + + + + + org.ow2.asm + asm + 9.5 + + + From a4893b964b45eae012ea0ddbfdb7dbb2cbdf7ff6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Mon, 10 Apr 2023 09:54:02 +0200 Subject: [PATCH 14/63] Upload sbom as release artifact Uploads xml/json to sourceforge and to Githu releases --- .ci/build.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.ci/build.sh b/.ci/build.sh index 5f4d321698..2479f35e82 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -179,6 +179,11 @@ function pmd_ci_deploy_build_artifacts() { # Deploy to sourceforge files https://sourceforge.net/projects/pmd/files/pmd/ pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-bin-${PMD_CI_MAVEN_PROJECT_VERSION}.zip" pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-src-${PMD_CI_MAVEN_PROJECT_VERSION}.zip" + # Deploy SBOM + cp pmd-dist/target/bom.xml "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" + cp pmd-dist/target/bom.json "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" + pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" + pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" if pmd_ci_maven_isReleaseBuild; then # create a draft github release @@ -188,6 +193,9 @@ function pmd_ci_deploy_build_artifacts() { # Deploy to github releases pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-bin-${PMD_CI_MAVEN_PROJECT_VERSION}.zip" pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-src-${PMD_CI_MAVEN_PROJECT_VERSION}.zip" + # Deploy SBOM + pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.xml" + pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-${PMD_CI_MAVEN_PROJECT_VERSION}-cyclonedx.json" fi } From af74964fcd423382a12bc9f54a79d65fae6c48c6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 11 Apr 2023 18:57:53 +0200 Subject: [PATCH 15/63] [core] Fix FileCollector#addSourceFile parameter order In PMD 6.55.0 the first parameter is sourceContents and the second is pathId (see https://github.com/pmd/pmd/blob/ef3455348603aa25f86894b9930f05f141f44d20/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java#L192). This restores that argument order in PMD 7. --- docs/pages/release_notes.md | 8 +++++++- .../net/sourceforge/pmd/lang/document/FileCollector.java | 2 +- .../test/java/net/sourceforge/pmd/PmdAnalysisTest.java | 4 ++-- .../net/sourceforge/pmd/processor/GlobalListenerTest.java | 6 +++--- .../net/sourceforge/pmd/processor/PmdRunnableTest.java | 2 +- .../sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt | 2 +- 6 files changed, 15 insertions(+), 9 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b875222f4d..4491a58657 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -39,7 +39,13 @@ for all.

This section lists the most important changes from the last release candidate. The remaining section describe the complete release notes for 7.0.0. -Fixed Issues: +**API Changes:** +* The parameter order of {% jdoc core::lang.document.FileCollector#addSourceFile(String, String) %} has been swapped + in order to have the same meaning as in 6.55.0. That will make it easier if you upgrade from 6.55.0 to 7.0.0. + However, that means, that you need to change these method calls if you have migrated to 7.0.0-rc1 already. + +**Fixed Issues:** + * java-codestyle * [#4273](https://github.com/pmd/pmd/issues/4273): \[java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default * java-errorprone diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java index 516851b167..1d8884a77c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java @@ -200,7 +200,7 @@ public final class FileCollector implements AutoCloseable { * * @return True if the file has been added */ - public boolean addSourceFile(String pathId, String sourceContents) { + public boolean addSourceFile(String sourceContents, String pathId) { AssertionUtil.requireParamNotNull("sourceContents", sourceContents); AssertionUtil.requireParamNotNull("pathId", pathId); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/PmdAnalysisTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/PmdAnalysisTest.java index e0ef291766..3da89a4ca3 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/PmdAnalysisTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/PmdAnalysisTest.java @@ -93,7 +93,7 @@ class PmdAnalysisTest { config.setForceLanguageVersion(DummyLanguageModule.getInstance().getVersionWhereParserThrows()); try (PmdAnalysis pmd = PmdAnalysis.create(config)) { pmd.addRuleSet(RuleSet.forSingleRule(new MockRule())); - pmd.files().addSourceFile("file", "some source"); + pmd.files().addSourceFile("some source", "file"); ReportStats stats = pmd.runAndReturnStats(); assertEquals(1, stats.getNumErrors(), "Errors"); @@ -116,7 +116,7 @@ class PmdAnalysisTest { } })); - pmd.files().addSourceFile("file", "some source"); + pmd.files().addSourceFile("some source", "file"); ReportStats stats = pmd.runAndReturnStats(); // the error number here is only for FileAnalysisException, so diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/processor/GlobalListenerTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/processor/GlobalListenerTest.java index 9fcebd99ed..82ebbc4777 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/processor/GlobalListenerTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/processor/GlobalListenerTest.java @@ -131,9 +131,9 @@ class GlobalListenerTest { private void runPmd(PMDConfiguration config, GlobalAnalysisListener listener, Rule rule) { try (PmdAnalysis pmd = PmdAnalysis.create(config)) { pmd.addRuleSet(RuleSet.forSingleRule(rule)); - pmd.files().addSourceFile("fname1.dummy", "abc"); - pmd.files().addSourceFile("fname2.dummy", "abcd"); - pmd.files().addSourceFile("fname21.dummy", "abcd"); + pmd.files().addSourceFile("abc", "fname1.dummy"); + pmd.files().addSourceFile("abcd", "fname2.dummy"); + pmd.files().addSourceFile("abcd", "fname21.dummy"); pmd.addListener(listener); pmd.performAnalysis(); } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/processor/PmdRunnableTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/processor/PmdRunnableTest.java index 65761e9bd0..47f9afc689 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/processor/PmdRunnableTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/processor/PmdRunnableTest.java @@ -74,7 +74,7 @@ class PmdRunnableTest { configuration.setForceLanguageVersion(lv); configuration.setIgnoreIncrementalAnalysis(true); try (PmdAnalysis pmd = PmdAnalysis.create(configuration)) { - pmd.files().addSourceFile("test.dummy", "foo"); + pmd.files().addSourceFile("foo", "test.dummy"); pmd.addRuleSet(RuleSet.forSingleRule(rule)); return pmd.performAnalysisAndCollectReport(); } diff --git a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt index db9367730d..211c5de605 100644 --- a/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt +++ b/pmd-lang-test/src/main/kotlin/net/sourceforge/pmd/lang/ast/test/BaseParsingHelper.kt @@ -239,7 +239,7 @@ abstract class BaseParsingHelper, T : RootNode return PmdAnalysis.create(config).use { pmd -> pmd.addListener(GlobalAnalysisListener.exceptionThrower()) pmd.addRuleSet(RuleSet.forSingleRule(rule)) - pmd.files().addSourceFile(fileName, code) + pmd.files().addSourceFile(code, fileName) pmd.performAnalysisAndCollectReport() } } From bdd06be619c367152e73bb9c4c2d4713ee1300b6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Apr 2023 16:24:02 +0200 Subject: [PATCH 16/63] [doc] Mention pmd-languages-deps --- .../adding_a_new_antlr_based_language.md | 6 ++++++ .../adding_a_new_javacc_based_language.md | 7 ++++++- .../devdocs/major_contributions/adding_new_cpd_language.md | 6 ++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md index 4ee9585405..a2faa0967e 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md @@ -52,6 +52,12 @@ definitely don't come for free. It is much effort and requires perseverance to i ## 1. Start with a new sub-module * See pmd-swift for examples. +* Make sure to add your new module to the parent pom as `` entry, so that it is built alongside the + other languages. +* Also add your new module to the dependencies list in "pmd-languages-deps/pom.xml", so that the new language + is automatically available in the binary distribution (pmd-dist) as well as for the shell-completion + in the pmd-cli module. + ## 2. Implement an AST parser for your language * ANTLR will generate the parser for you based on the grammar file. The grammar file needs to be placed in the diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md index 1e4e523b1c..5cf6c66757 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md @@ -35,7 +35,12 @@ definitely don't come for free. It is much effort and requires perseverance to i ## 1. Start with a new sub-module -* See pmd-java or pmd-vm for examples. +* See pmd-java or pmd-vm for examples. +* Make sure to add your new module to the parent pom as `` entry, so that it is built alongside the + other languages. +* Also add your new module to the dependencies list in "pmd-languages-deps/pom.xml", so that the new language + is automatically available in the binary distribution (pmd-dist) as well as for the shell-completion + in the pmd-cli module. ## 2. Implement an AST parser for your language * Ideally an AST parser should be implemented as a JJT file *(see VmParser.jjt or Java.jjt for example)* diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md index 4590867fa8..5d6b2b4784 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md @@ -17,6 +17,12 @@ Happily for you, to add CPD support for a new language is now easier than ever! All you need to do is follow this few steps: 1. Create a new module for your language, you can take [the Golang module](https://github.com/pmd/pmd/tree/master/pmd-go) as an example + * Make sure to add your new module to the parent pom as `` entry, so that it is built alongside the + other languages. + * Also add your new module to the dependencies list in "pmd-languages-deps/pom.xml", so that the new language + is automatically available in the binary distribution (pmd-dist) as well as for the shell-completion + in the pmd-cli module. + 2. Create a Tokenizer - For Antlr grammars you can take the grammar from [here](https://github.com/antlr/grammars-v4) and extend [AntlrTokenizer](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java) taking Go as an example From ccf431aaadc0ebd987a274e8e05c1f6232366bde Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Apr 2023 16:56:17 +0200 Subject: [PATCH 17/63] Add @nwcm as a contributor --- .all-contributorsrc | 9 +++++++++ docs/pages/pmd/projectdocs/credits.md | 23 ++++++++++++----------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index ce485028d8..be48515595 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7145,6 +7145,15 @@ "bug", "code" ] + }, + { + "login": "nwcm", + "name": "nwcm", + "avatar_url": "https://avatars.githubusercontent.com/u/111259588?v=4", + "profile": "https://github.com/nwcm", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 7c364b7d02..60ed54ac18 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -919,100 +919,101 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
nicolas-harraudeau-sonarsource

🐛
noerremark

🐛
novsirion

🐛 +
nwcm

📖
oggboy

🐛 -
oinume

🐛 +
oinume

🐛
orimarko

💻 🐛
pacvz

💻
pallavi agarwal

🐛
parksungrin

🐛
patpatpat123

🐛
patriksevallius

🐛 -
pbrajesh1

🐛 +
pbrajesh1

🐛
phoenix384

🐛
piotrszymanski-sc

💻
plan3d

🐛
poojasix

🐛
prabhushrikant

🐛
pujitha8783

🐛 -
r-r-a-j

🐛 +
r-r-a-j

🐛
raghujayjunk

🐛
rajeshveera

🐛
rajeswarreddy88

🐛
recdevs

🐛
reudismam

💻 🐛
rijkt

🐛 -
rillig-tk

🐛 +
rillig-tk

🐛
rmohan20

💻 🐛
rnveach

🐛
rxmicro

🐛
ryan-gustafson

💻 🐛
sabi0

🐛
scais

🐛 -
sebbASF

🐛 +
sebbASF

🐛
sergeygorbaty

💻
shilko2013

🐛
shiomiyan

📖
simeonKondr

🐛
snajberk

🐛
sniperrifle2004

🐛 -
snuyanzin

🐛 💻 +
snuyanzin

🐛 💻
sratz

🐛
stonio

🐛
sturton

💻 🐛
sudharmohan

🐛
suruchidawar

🐛
svenfinitiv

🐛 -
tashiscool

🐛 +
tashiscool

🐛
test-git-hook

🐛
testation21

💻 🐛
thanosa

🐛
tiandiyixian

🐛
tobwoerk

🐛
tprouvot

🐛 💻 -
trentchilders

🐛 +
trentchilders

🐛
triandicAnt

🐛
trishul14

🐛
tsui

🐛
winhkey

🐛
witherspore

🐛
wjljack

🐛 -
wuchiuwong

🐛 +
wuchiuwong

🐛
xingsong

🐛
xioayuge

🐛
xnYi9wRezm

💻 🐛
xuanuy

🐛
xyf0921

🐛
yalechen-cyw3

🐛 -
yasuharu-sato

🐛 +
yasuharu-sato

🐛
zenglian

🐛
zgrzyt93

💻 🐛
zh3ng

🐛
zt_soft

🐛
ztt79

🐛
zzzzfeng

🐛 -
Árpád Magosányi

🐛 +
Árpád Magosányi

🐛
任贵杰

🐛
茅延安

💻 From 0d73abbd5224570ae9438a91793715f4dba0a286 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Apr 2023 16:57:57 +0200 Subject: [PATCH 18/63] [doc] Update release notes (#4452) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b875222f4d..45e3fa24ac 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -399,6 +399,7 @@ Language specific fixes: * [#4428](https://github.com/pmd/pmd/pull/4428): \[apex] ApexBadCrypto bug fix for #4427 - inline detection of hard coded values - [Steven Stearns](https://github.com/sfdcsteve) (@sfdcsteve) * [#4444](https://github.com/pmd/pmd/pull/4444): \[java] CommentDefaultAccessModifier - ignore org.junit.jupiter.api.extension.RegisterExtension by default - [Nirvik Patel](https://github.com/nirvikpatel) (@nirvikpatel) * [#4450](https://github.com/pmd/pmd/pull/4450): \[java] Fix #4449 AvoidAccessibilityAlteration: Correctly handle Lambda expressions in PrivilegedAction scenarios - [Seren](https://github.com/mohui1999) (@mohui1999) +* [#4452](https://github.com/pmd/pmd/pull/4452): \[doc] Update PMD_APEX_ROOT_DIRECTORY documentation reference - [nwcm](https://github.com/nwcm) (@nwcm) ### 📈 Stats * 4416 commits From bdacd38437e6ee36ed4cd9a3a4b68a78ad8bcc0e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Apr 2023 19:08:58 +0200 Subject: [PATCH 19/63] [core] Move AntlrTokenizer and JavaCCTokenizer into impl packages --- .../major_contributions/adding_new_cpd_language.md | 9 ++++++--- docs/pages/release_notes.md | 7 ++++++- docs/pages/release_notes_pmd7.md | 4 ++++ .../pmd/cpd/{internal => impl}/AntlrTokenizer.java | 2 +- .../pmd/cpd/{internal => impl}/JavaCCTokenizer.java | 2 +- .../pmd/lang/ast/impl/javacc/JavaccTokenDocument.java | 2 +- .../main/java/net/sourceforge/pmd/cpd/CPPTokenizer.java | 2 +- .../main/java/net/sourceforge/pmd/cpd/CsTokenizer.java | 2 +- .../main/java/net/sourceforge/pmd/cpd/DartTokenizer.java | 2 +- .../pmd/lang/gherkin/cpd/GherkinTokenizer.java | 2 +- .../main/java/net/sourceforge/pmd/cpd/GoTokenizer.java | 2 +- .../main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java | 2 +- .../net/sourceforge/pmd/cpd/EcmascriptTokenizer.java | 2 +- .../main/java/net/sourceforge/pmd/cpd/JSPTokenizer.java | 2 +- .../java/net/sourceforge/pmd/cpd/KotlinTokenizer.java | 2 +- .../main/java/net/sourceforge/pmd/cpd/LuaTokenizer.java | 2 +- .../java/net/sourceforge/pmd/cpd/MatlabTokenizer.java | 2 +- .../java/net/sourceforge/pmd/cpd/ModelicaTokenizer.java | 2 +- .../net/sourceforge/pmd/cpd/ObjectiveCTokenizer.java | 2 +- .../java/net/sourceforge/pmd/cpd/PLSQLTokenizer.java | 2 +- .../java/net/sourceforge/pmd/cpd/PythonTokenizer.java | 2 +- .../java/net/sourceforge/pmd/cpd/SwiftTokenizer.java | 2 +- .../net/sourceforge/pmd/lang/tsql/cpd/TSqlTokenizer.java | 2 +- .../main/java/net/sourceforge/pmd/cpd/VfTokenizer.java | 2 +- .../java/net/sourceforge/pmd/xml/cpd/XmlTokenizer.java | 2 +- 25 files changed, 38 insertions(+), 26 deletions(-) rename pmd-core/src/main/java/net/sourceforge/pmd/cpd/{internal => impl}/AntlrTokenizer.java (98%) rename pmd-core/src/main/java/net/sourceforge/pmd/cpd/{internal => impl}/JavaCCTokenizer.java (98%) diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md index 5d6b2b4784..52ffb4bbec 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_new_cpd_language.md @@ -25,8 +25,9 @@ All you need to do is follow this few steps: 2. Create a Tokenizer - - For Antlr grammars you can take the grammar from [here](https://github.com/antlr/grammars-v4) and extend [AntlrTokenizer](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java) taking Go as an example - + - For Antlr grammars you can take the grammar from [here](https://github.com/antlr/grammars-v4) and + extend [AntlrTokenizer](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/AntlrTokenizer.java) + taking Go as an example ```java public class GoTokenizer extends AntlrTokenizer { @@ -38,7 +39,9 @@ All you need to do is follow this few steps: } ``` - - For JavaCC grammars you should subclass [JavaCCTokenizer](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/JavaCCTokenizer.java) which has many examples you could follow, you should also take the [Python implementation](https://github.com/pmd/pmd/blob/master/pmd-python/src/main/java/net/sourceforge/pmd/cpd/PythonTokenizer.java) as reference + - For JavaCC grammars you should subclass [JavaCCTokenizer](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/JavaCCTokenizer.java) + which has many examples you could follow, you should also take the + [Python implementation](https://github.com/pmd/pmd/blob/master/pmd-python/src/main/java/net/sourceforge/pmd/cpd/PythonTokenizer.java) as reference - For any other scenario you can use [AnyTokenizer](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AnyTokenizer.java) If you're using Antlr or JavaCC, update the pom.xml of your submodule to use the appropriate ant wrapper. See `pmd-go/pom.xml` and `pmd-python/pom.xml` for examples. diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 45e3fa24ac..b0f117486a 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -39,7 +39,12 @@ for all.

This section lists the most important changes from the last release candidate. The remaining section describe the complete release notes for 7.0.0. -Fixed Issues: +#### API Changes +* Moved the two classes {% jdoc core::cpd.impl.AntlrTokenizer %} and {% jdoc core::cpd.impl.JavaCCTokenizer %} from + `internal` package into package {% jdoc_package core::cpd.impl %}. These two classes are part of the API and + are base classes for CPD language implementations. + +#### Fixed Issues: * java-codestyle * [#4273](https://github.com/pmd/pmd/issues/4273): \[java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default * java-errorprone diff --git a/docs/pages/release_notes_pmd7.md b/docs/pages/release_notes_pmd7.md index 9f74c26e59..9589c566d2 100644 --- a/docs/pages/release_notes_pmd7.md +++ b/docs/pages/release_notes_pmd7.md @@ -750,6 +750,10 @@ until the next major release, but it is recommended to stop using them. * {% jdoc core::util.IteratorUtil %} * {% jdoc core::util.StringUtil %} +* Moved the two classes {% jdoc core::cpd.impl.AntlrTokenizer %} and {% jdoc core::cpd.impl.JavaCCTokenizer %} from + `internal` package into package {% jdoc_package core::cpd.impl %}. These two classes are part of the API and + are base classes for CPD language implementations. + ### XPath 3.1 support Support for XPath versions 1.0, 1.0-compatibility was removed, support for XPath 2.0 is deprecated. The default diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/AntlrTokenizer.java similarity index 98% rename from pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java rename to pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/AntlrTokenizer.java index b09703881a..a5cc1767f9 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/AntlrTokenizer.java @@ -2,7 +2,7 @@ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ -package net.sourceforge.pmd.cpd.internal; +package net.sourceforge.pmd.cpd.impl; import java.io.IOException; import java.io.UncheckedIOException; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/JavaCCTokenizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/JavaCCTokenizer.java similarity index 98% rename from pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/JavaCCTokenizer.java rename to pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/JavaCCTokenizer.java index 3c45b96033..1b1710cbe3 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/JavaCCTokenizer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/JavaCCTokenizer.java @@ -2,7 +2,7 @@ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ -package net.sourceforge.pmd.cpd.internal; +package net.sourceforge.pmd.cpd.impl; import java.io.IOException; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java index 6b13d723d4..5887805ec4 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/javacc/JavaccTokenDocument.java @@ -10,7 +10,7 @@ import java.util.List; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import net.sourceforge.pmd.cpd.internal.JavaCCTokenizer; +import net.sourceforge.pmd.cpd.impl.JavaCCTokenizer; import net.sourceforge.pmd.lang.ast.impl.TokenDocument; import net.sourceforge.pmd.lang.document.TextDocument; diff --git a/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPTokenizer.java b/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPTokenizer.java index 0728e9afbf..ccfd511bdb 100644 --- a/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPTokenizer.java +++ b/pmd-cpp/src/main/java/net/sourceforge/pmd/cpd/CPPTokenizer.java @@ -7,7 +7,7 @@ package net.sourceforge.pmd.cpd; import java.util.Properties; import java.util.regex.Pattern; -import net.sourceforge.pmd.cpd.internal.JavaCCTokenizer; +import net.sourceforge.pmd.cpd.impl.JavaCCTokenizer; import net.sourceforge.pmd.cpd.token.JavaCCTokenFilter; import net.sourceforge.pmd.cpd.token.TokenFilter; import net.sourceforge.pmd.lang.TokenManager; diff --git a/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java b/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java index 64822f1a38..712fae22c3 100644 --- a/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java +++ b/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java @@ -9,7 +9,7 @@ import java.util.Properties; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.Lexer; -import net.sourceforge.pmd.cpd.internal.AntlrTokenizer; +import net.sourceforge.pmd.cpd.impl.AntlrTokenizer; import net.sourceforge.pmd.cpd.token.AntlrTokenFilter; import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken; import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrTokenManager; diff --git a/pmd-dart/src/main/java/net/sourceforge/pmd/cpd/DartTokenizer.java b/pmd-dart/src/main/java/net/sourceforge/pmd/cpd/DartTokenizer.java index 6c847754a2..048a0a3a6f 100644 --- a/pmd-dart/src/main/java/net/sourceforge/pmd/cpd/DartTokenizer.java +++ b/pmd-dart/src/main/java/net/sourceforge/pmd/cpd/DartTokenizer.java @@ -7,7 +7,7 @@ package net.sourceforge.pmd.cpd; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.Lexer; -import net.sourceforge.pmd.cpd.internal.AntlrTokenizer; +import net.sourceforge.pmd.cpd.impl.AntlrTokenizer; import net.sourceforge.pmd.cpd.token.AntlrTokenFilter; import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken; import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrTokenManager; diff --git a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/cpd/GherkinTokenizer.java b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/cpd/GherkinTokenizer.java index fd9d03a244..1bbe22cf51 100644 --- a/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/cpd/GherkinTokenizer.java +++ b/pmd-gherkin/src/main/java/net/sourceforge/pmd/lang/gherkin/cpd/GherkinTokenizer.java @@ -7,7 +7,7 @@ package net.sourceforge.pmd.lang.gherkin.cpd; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.Lexer; -import net.sourceforge.pmd.cpd.internal.AntlrTokenizer; +import net.sourceforge.pmd.cpd.impl.AntlrTokenizer; import net.sourceforge.pmd.lang.gherkin.ast.GherkinLexer; /** diff --git a/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoTokenizer.java b/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoTokenizer.java index 98d2653f85..d46d4827ed 100644 --- a/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoTokenizer.java +++ b/pmd-go/src/main/java/net/sourceforge/pmd/cpd/GoTokenizer.java @@ -7,7 +7,7 @@ package net.sourceforge.pmd.cpd; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.Lexer; -import net.sourceforge.pmd.cpd.internal.AntlrTokenizer; +import net.sourceforge.pmd.cpd.impl.AntlrTokenizer; import net.sourceforge.pmd.lang.go.ast.GolangLexer; public class GoTokenizer extends AntlrTokenizer { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java b/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java index 525d1731b2..a1ac11bfc8 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/cpd/JavaTokenizer.java @@ -9,7 +9,7 @@ import java.util.Deque; import java.util.LinkedList; import java.util.Properties; -import net.sourceforge.pmd.cpd.internal.JavaCCTokenizer; +import net.sourceforge.pmd.cpd.impl.JavaCCTokenizer; import net.sourceforge.pmd.cpd.token.JavaCCTokenFilter; import net.sourceforge.pmd.cpd.token.TokenFilter; import net.sourceforge.pmd.lang.TokenManager; diff --git a/pmd-javascript/src/main/java/net/sourceforge/pmd/cpd/EcmascriptTokenizer.java b/pmd-javascript/src/main/java/net/sourceforge/pmd/cpd/EcmascriptTokenizer.java index d66d74949f..2d52fa0896 100644 --- a/pmd-javascript/src/main/java/net/sourceforge/pmd/cpd/EcmascriptTokenizer.java +++ b/pmd-javascript/src/main/java/net/sourceforge/pmd/cpd/EcmascriptTokenizer.java @@ -4,7 +4,7 @@ package net.sourceforge.pmd.cpd; -import net.sourceforge.pmd.cpd.internal.JavaCCTokenizer; +import net.sourceforge.pmd.cpd.impl.JavaCCTokenizer; import net.sourceforge.pmd.lang.TokenManager; import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; diff --git a/pmd-jsp/src/main/java/net/sourceforge/pmd/cpd/JSPTokenizer.java b/pmd-jsp/src/main/java/net/sourceforge/pmd/cpd/JSPTokenizer.java index 5617484d1b..bc5858dc05 100644 --- a/pmd-jsp/src/main/java/net/sourceforge/pmd/cpd/JSPTokenizer.java +++ b/pmd-jsp/src/main/java/net/sourceforge/pmd/cpd/JSPTokenizer.java @@ -4,7 +4,7 @@ package net.sourceforge.pmd.cpd; -import net.sourceforge.pmd.cpd.internal.JavaCCTokenizer; +import net.sourceforge.pmd.cpd.impl.JavaCCTokenizer; import net.sourceforge.pmd.lang.TokenManager; import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; diff --git a/pmd-kotlin/src/main/java/net/sourceforge/pmd/cpd/KotlinTokenizer.java b/pmd-kotlin/src/main/java/net/sourceforge/pmd/cpd/KotlinTokenizer.java index 143c1f5f06..b2512fb67b 100644 --- a/pmd-kotlin/src/main/java/net/sourceforge/pmd/cpd/KotlinTokenizer.java +++ b/pmd-kotlin/src/main/java/net/sourceforge/pmd/cpd/KotlinTokenizer.java @@ -7,7 +7,7 @@ package net.sourceforge.pmd.cpd; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.Lexer; -import net.sourceforge.pmd.cpd.internal.AntlrTokenizer; +import net.sourceforge.pmd.cpd.impl.AntlrTokenizer; import net.sourceforge.pmd.cpd.token.AntlrTokenFilter; import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken; import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrTokenManager; diff --git a/pmd-lua/src/main/java/net/sourceforge/pmd/cpd/LuaTokenizer.java b/pmd-lua/src/main/java/net/sourceforge/pmd/cpd/LuaTokenizer.java index 509a7803c6..aa5288deec 100644 --- a/pmd-lua/src/main/java/net/sourceforge/pmd/cpd/LuaTokenizer.java +++ b/pmd-lua/src/main/java/net/sourceforge/pmd/cpd/LuaTokenizer.java @@ -9,7 +9,7 @@ import java.util.Properties; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.Lexer; -import net.sourceforge.pmd.cpd.internal.AntlrTokenizer; +import net.sourceforge.pmd.cpd.impl.AntlrTokenizer; import net.sourceforge.pmd.cpd.token.AntlrTokenFilter; import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken; import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrTokenManager; diff --git a/pmd-matlab/src/main/java/net/sourceforge/pmd/cpd/MatlabTokenizer.java b/pmd-matlab/src/main/java/net/sourceforge/pmd/cpd/MatlabTokenizer.java index 9459c44696..002e40c081 100644 --- a/pmd-matlab/src/main/java/net/sourceforge/pmd/cpd/MatlabTokenizer.java +++ b/pmd-matlab/src/main/java/net/sourceforge/pmd/cpd/MatlabTokenizer.java @@ -4,7 +4,7 @@ package net.sourceforge.pmd.cpd; -import net.sourceforge.pmd.cpd.internal.JavaCCTokenizer; +import net.sourceforge.pmd.cpd.impl.JavaCCTokenizer; import net.sourceforge.pmd.lang.TokenManager; import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; diff --git a/pmd-modelica/src/main/java/net/sourceforge/pmd/cpd/ModelicaTokenizer.java b/pmd-modelica/src/main/java/net/sourceforge/pmd/cpd/ModelicaTokenizer.java index 3258a3cda7..fb22a555d3 100644 --- a/pmd-modelica/src/main/java/net/sourceforge/pmd/cpd/ModelicaTokenizer.java +++ b/pmd-modelica/src/main/java/net/sourceforge/pmd/cpd/ModelicaTokenizer.java @@ -4,7 +4,7 @@ package net.sourceforge.pmd.cpd; -import net.sourceforge.pmd.cpd.internal.JavaCCTokenizer; +import net.sourceforge.pmd.cpd.impl.JavaCCTokenizer; import net.sourceforge.pmd.cpd.token.JavaCCTokenFilter; import net.sourceforge.pmd.lang.TokenManager; import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; diff --git a/pmd-objectivec/src/main/java/net/sourceforge/pmd/cpd/ObjectiveCTokenizer.java b/pmd-objectivec/src/main/java/net/sourceforge/pmd/cpd/ObjectiveCTokenizer.java index acccfcd24a..236eea59a3 100644 --- a/pmd-objectivec/src/main/java/net/sourceforge/pmd/cpd/ObjectiveCTokenizer.java +++ b/pmd-objectivec/src/main/java/net/sourceforge/pmd/cpd/ObjectiveCTokenizer.java @@ -4,7 +4,7 @@ package net.sourceforge.pmd.cpd; -import net.sourceforge.pmd.cpd.internal.JavaCCTokenizer; +import net.sourceforge.pmd.cpd.impl.JavaCCTokenizer; import net.sourceforge.pmd.lang.TokenManager; import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; diff --git a/pmd-plsql/src/main/java/net/sourceforge/pmd/cpd/PLSQLTokenizer.java b/pmd-plsql/src/main/java/net/sourceforge/pmd/cpd/PLSQLTokenizer.java index 77abbf8794..8a7a153c3f 100644 --- a/pmd-plsql/src/main/java/net/sourceforge/pmd/cpd/PLSQLTokenizer.java +++ b/pmd-plsql/src/main/java/net/sourceforge/pmd/cpd/PLSQLTokenizer.java @@ -6,7 +6,7 @@ package net.sourceforge.pmd.cpd; import java.util.Properties; -import net.sourceforge.pmd.cpd.internal.JavaCCTokenizer; +import net.sourceforge.pmd.cpd.impl.JavaCCTokenizer; import net.sourceforge.pmd.lang.TokenManager; import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; diff --git a/pmd-python/src/main/java/net/sourceforge/pmd/cpd/PythonTokenizer.java b/pmd-python/src/main/java/net/sourceforge/pmd/cpd/PythonTokenizer.java index c80d572f67..82720a8ea1 100644 --- a/pmd-python/src/main/java/net/sourceforge/pmd/cpd/PythonTokenizer.java +++ b/pmd-python/src/main/java/net/sourceforge/pmd/cpd/PythonTokenizer.java @@ -6,7 +6,7 @@ package net.sourceforge.pmd.cpd; import java.util.regex.Pattern; -import net.sourceforge.pmd.cpd.internal.JavaCCTokenizer; +import net.sourceforge.pmd.cpd.impl.JavaCCTokenizer; import net.sourceforge.pmd.lang.TokenManager; import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken; diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java b/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java index 41d7c28d36..8153ba4455 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java @@ -7,7 +7,7 @@ package net.sourceforge.pmd.cpd; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.Lexer; -import net.sourceforge.pmd.cpd.internal.AntlrTokenizer; +import net.sourceforge.pmd.cpd.impl.AntlrTokenizer; import net.sourceforge.pmd.lang.swift.ast.SwiftLexer; /** diff --git a/pmd-tsql/src/main/java/net/sourceforge/pmd/lang/tsql/cpd/TSqlTokenizer.java b/pmd-tsql/src/main/java/net/sourceforge/pmd/lang/tsql/cpd/TSqlTokenizer.java index 6274dbf6da..9676b37f7c 100644 --- a/pmd-tsql/src/main/java/net/sourceforge/pmd/lang/tsql/cpd/TSqlTokenizer.java +++ b/pmd-tsql/src/main/java/net/sourceforge/pmd/lang/tsql/cpd/TSqlTokenizer.java @@ -7,7 +7,7 @@ package net.sourceforge.pmd.lang.tsql.cpd; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.Lexer; -import net.sourceforge.pmd.cpd.internal.AntlrTokenizer; +import net.sourceforge.pmd.cpd.impl.AntlrTokenizer; import net.sourceforge.pmd.lang.tsql.ast.TSqlLexer; public class TSqlTokenizer extends AntlrTokenizer { diff --git a/pmd-visualforce/src/main/java/net/sourceforge/pmd/cpd/VfTokenizer.java b/pmd-visualforce/src/main/java/net/sourceforge/pmd/cpd/VfTokenizer.java index 17926160b0..d0baf84e24 100644 --- a/pmd-visualforce/src/main/java/net/sourceforge/pmd/cpd/VfTokenizer.java +++ b/pmd-visualforce/src/main/java/net/sourceforge/pmd/cpd/VfTokenizer.java @@ -4,7 +4,7 @@ package net.sourceforge.pmd.cpd; -import net.sourceforge.pmd.cpd.internal.JavaCCTokenizer; +import net.sourceforge.pmd.cpd.impl.JavaCCTokenizer; import net.sourceforge.pmd.lang.TokenManager; import net.sourceforge.pmd.lang.ast.impl.javacc.CharStream; import net.sourceforge.pmd.lang.ast.impl.javacc.JavaEscapeTranslator; diff --git a/pmd-xml/src/main/java/net/sourceforge/pmd/xml/cpd/XmlTokenizer.java b/pmd-xml/src/main/java/net/sourceforge/pmd/xml/cpd/XmlTokenizer.java index 278e8463eb..120b448d09 100644 --- a/pmd-xml/src/main/java/net/sourceforge/pmd/xml/cpd/XmlTokenizer.java +++ b/pmd-xml/src/main/java/net/sourceforge/pmd/xml/cpd/XmlTokenizer.java @@ -7,7 +7,7 @@ package net.sourceforge.pmd.xml.cpd; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.Lexer; -import net.sourceforge.pmd.cpd.internal.AntlrTokenizer; +import net.sourceforge.pmd.cpd.impl.AntlrTokenizer; import net.sourceforge.pmd.lang.xml.antlr4.XMLLexer; public class XmlTokenizer extends AntlrTokenizer { From ee227b13972b2ff259e9892e7130a820af9d4a21 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 13 Apr 2023 20:18:53 +0200 Subject: [PATCH 20/63] [core] Introduce an AbstractVisitorRule Remove AntlrBaseRule --- .../adding_a_new_antlr_based_language.md | 9 +++++--- docs/pages/release_notes.md | 1 + docs/pages/release_notes_pmd7.md | 4 +++- .../AbstractVisitorRule.java} | 21 +++++++------------ .../pmd/lang/kotlin/AbstractKotlinRule.java | 4 ++-- .../pmd/lang/swift/AbstractSwiftRule.java | 8 +++---- .../UnavailableFunctionRule.java | 4 ++-- 7 files changed, 25 insertions(+), 26 deletions(-) rename pmd-core/src/main/java/net/sourceforge/pmd/lang/{ast/impl/antlr4/AntlrBaseRule.java => rule/AbstractVisitorRule.java} (63%) diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md index a2faa0967e..bfb6197eff 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md @@ -154,9 +154,12 @@ definitely don't come for free. It is much effort and requires perseverance to i ## 10. Create an abstract rule class for the language * You need to create your own `AbstractRule` in order to interface your language with PMD's generic rule execution. -* See [`AbstractSwiftRule`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java) as an example. -* While the rule basically just extends - [`AntlrBaseRule`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java) without adding anything, every language should have its own base class for rule. +* See [`AbstractSwiftRule`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java) as an example. +* The rule basically just extends + [`AbstractVisitorRule`](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractVisitorRule.java) + and only redefines the abstract `buildVisitor()` method to return our own type of visitor. + In this case our `SwiftVisitor` is used. + While there is no real functionality added, every language should have its own base class for rules. This helps to organize the code. * All other rules for your language should extend this class. The purpose of this class is to provide a visitor via the method `buildVisitor()` for analyzing the AST. The provided visitor only implements the visit methods diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b0f117486a..cd313c8362 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -43,6 +43,7 @@ The remaining section describe the complete release notes for 7.0.0. * Moved the two classes {% jdoc core::cpd.impl.AntlrTokenizer %} and {% jdoc core::cpd.impl.JavaCCTokenizer %} from `internal` package into package {% jdoc_package core::cpd.impl %}. These two classes are part of the API and are base classes for CPD language implementations. +* `AntlrBaseRule` is gone in favor of {% jdoc core::pmd.lang.rule.AbstractVisitorRule %}. #### Fixed Issues: * java-codestyle diff --git a/docs/pages/release_notes_pmd7.md b/docs/pages/release_notes_pmd7.md index 9589c566d2..2fe6c79009 100644 --- a/docs/pages/release_notes_pmd7.md +++ b/docs/pages/release_notes_pmd7.md @@ -752,7 +752,9 @@ until the next major release, but it is recommended to stop using them. * Moved the two classes {% jdoc core::cpd.impl.AntlrTokenizer %} and {% jdoc core::cpd.impl.JavaCCTokenizer %} from `internal` package into package {% jdoc_package core::cpd.impl %}. These two classes are part of the API and - are base classes for CPD language implementations. + are base classes for CPD language implementations. Since 7.0.0-rc2. +* `AntlrBaseRule` is gone in favor of {% jdoc core::pmd.lang.rule.AbstractVisitorRule %}. Since 7.0.0-rc2. + ### XPath 3.1 support diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractVisitorRule.java similarity index 63% rename from pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java rename to pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractVisitorRule.java index bc56f0084d..9ef6e4a472 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseRule.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/rule/AbstractVisitorRule.java @@ -2,38 +2,31 @@ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ -package net.sourceforge.pmd.lang.ast.impl.antlr4; +package net.sourceforge.pmd.lang.rule; import net.sourceforge.pmd.RuleContext; import net.sourceforge.pmd.lang.ast.AstVisitor; import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.rule.AbstractRule; - -/** - * Base implementation of an antlr rule. - */ -public abstract class AntlrBaseRule extends AbstractRule { - - protected AntlrBaseRule() { - // inheritance constructor - } +public abstract class AbstractVisitorRule extends AbstractRule { @Override public void apply(Node target, RuleContext ctx) { AstVisitor visitor = buildVisitor(); assert visitor != null : "Rule should provide a non-null visitor"; - assert target instanceof AntlrNode : "Incorrect node type " + target + " passed to " + this; - ((AntlrNode) target).acceptVisitor(visitor, ctx); + target.acceptVisitor(visitor, ctx); } /** * Returns a rule visitor that can visit nodes for the given rule context. * This visitor should explore the nodes it's interested in and report * violations on the given rule context. + *

+ * Language specific subclasses should redefine the return type to use + * a language specific visitor interface. + *

* * @return A visitor bound to the given rule context */ public abstract AstVisitor buildVisitor(); - } diff --git a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/AbstractKotlinRule.java b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/AbstractKotlinRule.java index 31262b1473..7c13206023 100644 --- a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/AbstractKotlinRule.java +++ b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/AbstractKotlinRule.java @@ -5,10 +5,10 @@ package net.sourceforge.pmd.lang.kotlin; import net.sourceforge.pmd.RuleContext; -import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrBaseRule; import net.sourceforge.pmd.lang.kotlin.ast.KotlinVisitor; +import net.sourceforge.pmd.lang.rule.AbstractVisitorRule; -public abstract class AbstractKotlinRule extends AntlrBaseRule { +public abstract class AbstractKotlinRule extends AbstractVisitorRule { protected AbstractKotlinRule() { // inheritance constructor diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java index 11199a0239..a4a11d3ad2 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java @@ -5,15 +5,15 @@ package net.sourceforge.pmd.lang.swift; import net.sourceforge.pmd.RuleContext; -import net.sourceforge.pmd.lang.ast.AstVisitor; -import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrBaseRule; +import net.sourceforge.pmd.lang.rule.AbstractVisitorRule; +import net.sourceforge.pmd.lang.swift.ast.SwiftVisitor; -public abstract class AbstractSwiftRule extends AntlrBaseRule { +public abstract class AbstractSwiftRule extends AbstractVisitorRule { protected AbstractSwiftRule() { // inheritance constructor } @Override - public abstract AstVisitor buildVisitor(); + public abstract SwiftVisitor buildVisitor(); } diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java index 5c49fb5669..1c1c0da91b 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java @@ -7,7 +7,6 @@ package net.sourceforge.pmd.lang.swift.rule.bestpractices; import java.util.List; import net.sourceforge.pmd.RuleContext; -import net.sourceforge.pmd.lang.ast.AstVisitor; import net.sourceforge.pmd.lang.swift.AbstractSwiftRule; import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwAttribute; import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwAttributes; @@ -15,6 +14,7 @@ import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwCodeBlock; import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwFunctionDeclaration; import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwInitializerDeclaration; import net.sourceforge.pmd.lang.swift.ast.SwiftParser.SwStatement; +import net.sourceforge.pmd.lang.swift.ast.SwiftVisitor; import net.sourceforge.pmd.lang.swift.ast.SwiftVisitorBase; public class UnavailableFunctionRule extends AbstractSwiftRule { @@ -29,7 +29,7 @@ public class UnavailableFunctionRule extends AbstractSwiftRule { } @Override - public AstVisitor buildVisitor() { + public SwiftVisitor buildVisitor() { return new SwiftVisitorBase() { @Override From 0d5ecebd4eb8498c95a084e59c472912ae5ef566 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 14 Apr 2023 09:41:52 +0200 Subject: [PATCH 21/63] [core] Antlr - make more methods protected The abstract methods createPmdTerminal and createPmdError in AntlrGeneratedParserBase don't need to be public. They are just implementation. The language specific inner nodes (KotlinInnerNode, SwiftInnerNode) can be package private. Only the concrete subclasses are considered public API. --- .../adding_a_new_antlr_based_language.md | 18 +++++++++++------- docs/pages/release_notes.md | 4 +++- docs/pages/release_notes_pmd7.md | 5 +++-- .../impl/antlr4/AntlrGeneratedParserBase.java | 7 ++++--- .../sourceforge/pmd/lang/kotlin/ast/Kotlin.g4 | 4 ++-- .../sourceforge/pmd/lang/kotlin/ast/README.md | 4 ++-- .../pmd/lang/kotlin/ast/KotlinInnerNode.java | 3 +-- .../sourceforge/pmd/lang/swift/ast/Swift.g4 | 4 ++-- .../pmd/lang/swift/ast/SwiftInnerNode.java | 3 ++- 9 files changed, 30 insertions(+), 22 deletions(-) diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md index bfb6197eff..7d2be2372a 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md @@ -75,20 +75,24 @@ definitely don't come for free. It is much effort and requires perseverance to i * a language specific inner node - these nodes represent the production rules from the grammar. In Antlr, they are called "ParserRuleContext". We call them "InnerNode". Use the base class from pmd-core - [`BaseAntlrInnerNode`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrInnerNode.java) - . And example is [`SwiftInnerNode`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftInnerNode.java). + [`BaseAntlrInnerNode`](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrInnerNode.java) + . And example is [`SwiftInnerNode`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftInnerNode.java). + Note that this language specific inner node is package-private, as it is only the base class for the concrete + nodes generated by ANLTR. * a language specific root node - this provides the root of the AST and our parser will return subtypes of this node. The root node itself is a "InnerNode". - See [`SwiftRootNode`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftRootNode.java). + See [`SwiftRootNode`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftRootNode.java). + Note that this language specific root node is package-private, as it is only the base class for the concrete + node generated by ANLTR. * a language specific terminal node. - See [`SwiftTerminalNode`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftTerminalNode.java). + See [`SwiftTerminalNode`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftTerminalNode.java). * a language specific error node. - See [`SwiftErrorNode`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftErrorNode.java). + See [`SwiftErrorNode`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftErrorNode.java). * In order for the generated code to match and use our custom classes, we have a common ant script, that fiddles with - the generated code. The ant script is [`antlr4-wrapper.xml`](https://github.com/pmd/pmd/blob/pmd/7.0.x/antlr4-wrapper.xml) and + the generated code. The ant script is [`antlr4-wrapper.xml`](https://github.com/pmd/pmd/blob/master/antlr4-wrapper.xml) and does not need to be adjusted - it has plenty of parameters to set. The ant script is added in the language module's `pom.xml` where the parameters are set (e.g. name of root name class). Have a look at - Swift's example: [`pmd-swift/pom.xml`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/pom.xml). + Swift's example: [`pmd-swift/pom.xml`](https://github.com/pmd/pmd/blob/master/pmd-swift/pom.xml). * You can add additional methods in your "InnerNode" (e.g. `SwiftInnerNode`) that are available on all nodes. But on most cases you won't need to do anything. diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index cd313c8362..3376a48d59 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -43,7 +43,9 @@ The remaining section describe the complete release notes for 7.0.0. * Moved the two classes {% jdoc core::cpd.impl.AntlrTokenizer %} and {% jdoc core::cpd.impl.JavaCCTokenizer %} from `internal` package into package {% jdoc_package core::cpd.impl %}. These two classes are part of the API and are base classes for CPD language implementations. -* `AntlrBaseRule` is gone in favor of {% jdoc core::pmd.lang.rule.AbstractVisitorRule %}. +* `AntlrBaseRule` is gone in favor of {% jdoc core::lang.rule.AbstractVisitorRule %}. +* The classes {% jdoc kotlin::lang.kotlin.ast.KotlinInnerNode %} and {% jdoc swift::lang.swift.ast.SwiftInnerNode %} + are package-private now. #### Fixed Issues: * java-codestyle diff --git a/docs/pages/release_notes_pmd7.md b/docs/pages/release_notes_pmd7.md index 2fe6c79009..d83c4cfff8 100644 --- a/docs/pages/release_notes_pmd7.md +++ b/docs/pages/release_notes_pmd7.md @@ -753,8 +753,9 @@ until the next major release, but it is recommended to stop using them. * Moved the two classes {% jdoc core::cpd.impl.AntlrTokenizer %} and {% jdoc core::cpd.impl.JavaCCTokenizer %} from `internal` package into package {% jdoc_package core::cpd.impl %}. These two classes are part of the API and are base classes for CPD language implementations. Since 7.0.0-rc2. -* `AntlrBaseRule` is gone in favor of {% jdoc core::pmd.lang.rule.AbstractVisitorRule %}. Since 7.0.0-rc2. - +* `AntlrBaseRule` is gone in favor of {% jdoc core::lang.rule.AbstractVisitorRule %}. Since 7.0.0-rc2. +* The classes {% jdoc kotlin::lang.kotlin.ast.KotlinInnerNode %} and {% jdoc swift::lang.swift.ast.SwiftInnerNode %} + are package-private now. Since 7.0.0-rc2. ### XPath 3.1 support diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrGeneratedParserBase.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrGeneratedParserBase.java index edf18dbedb..6f2750966a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrGeneratedParserBase.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrGeneratedParserBase.java @@ -31,7 +31,8 @@ import net.sourceforge.pmd.lang.ast.Node; * which stores the XPath names of the generated nodes (and terminals). * *

Additional members can be added to a parser with {@code @parser::members { ... }} - * in the g4 file. + * in the g4 file. That's how the implementations for {@link #createPmdTerminal(ParserRuleContext, Token)} + * and {@link #createPmdError(ParserRuleContext, Token)} can be added. */ public abstract class AntlrGeneratedParserBase> extends Parser { @@ -52,9 +53,9 @@ public abstract class AntlrGeneratedParserBase> extends P // Those two need to return a node that implements eg SwiftNode - public abstract BaseAntlrTerminalNode createPmdTerminal(ParserRuleContext parent, Token t); + protected abstract BaseAntlrTerminalNode createPmdTerminal(ParserRuleContext parent, Token t); - public abstract BaseAntlrErrorNode createPmdError(ParserRuleContext parent, Token t); + protected abstract BaseAntlrErrorNode createPmdError(ParserRuleContext parent, Token t); protected Node asPmdNode(RuleContext ctx) { diff --git a/pmd-kotlin/src/main/antlr4/net/sourceforge/pmd/lang/kotlin/ast/Kotlin.g4 b/pmd-kotlin/src/main/antlr4/net/sourceforge/pmd/lang/kotlin/ast/Kotlin.g4 index 282b737351..16e602e2cc 100644 --- a/pmd-kotlin/src/main/antlr4/net/sourceforge/pmd/lang/kotlin/ast/Kotlin.g4 +++ b/pmd-kotlin/src/main/antlr4/net/sourceforge/pmd/lang/kotlin/ast/Kotlin.g4 @@ -15,12 +15,12 @@ import net.sourceforge.pmd.lang.ast.AstVisitor; static final AntlrNameDictionary DICO = new KotlinNameDictionary(VOCABULARY, ruleNames); @Override - public KotlinTerminalNode createPmdTerminal(ParserRuleContext parent, Token t) { + protected KotlinTerminalNode createPmdTerminal(ParserRuleContext parent, Token t) { return new KotlinTerminalNode(t); } @Override - public KotlinErrorNode createPmdError(ParserRuleContext parent, Token t) { + protected KotlinErrorNode createPmdError(ParserRuleContext parent, Token t) { return new KotlinErrorNode(t); } } diff --git a/pmd-kotlin/src/main/antlr4/net/sourceforge/pmd/lang/kotlin/ast/README.md b/pmd-kotlin/src/main/antlr4/net/sourceforge/pmd/lang/kotlin/ast/README.md index 20361f9a64..0bce081a13 100644 --- a/pmd-kotlin/src/main/antlr4/net/sourceforge/pmd/lang/kotlin/ast/README.md +++ b/pmd-kotlin/src/main/antlr4/net/sourceforge/pmd/lang/kotlin/ast/README.md @@ -50,12 +50,12 @@ import net.sourceforge.pmd.lang.ast.AstVisitor; static final AntlrNameDictionary DICO = new KotlinNameDictionary(VOCABULARY, ruleNames); @Override - public KotlinTerminalNode createPmdTerminal(ParserRuleContext parent, Token t) { + protected KotlinTerminalNode createPmdTerminal(ParserRuleContext parent, Token t) { return new KotlinTerminalNode(t); } @Override - public KotlinErrorNode createPmdError(ParserRuleContext parent, Token t) { + protected KotlinErrorNode createPmdError(ParserRuleContext parent, Token t) { return new KotlinErrorNode(t); } } diff --git a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/KotlinInnerNode.java b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/KotlinInnerNode.java index a6d58699ae..683f78b4de 100644 --- a/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/KotlinInnerNode.java +++ b/pmd-kotlin/src/main/java/net/sourceforge/pmd/lang/kotlin/ast/KotlinInnerNode.java @@ -9,8 +9,7 @@ import org.antlr.v4.runtime.ParserRuleContext; import net.sourceforge.pmd.lang.ast.AstVisitor; import net.sourceforge.pmd.lang.ast.impl.antlr4.BaseAntlrInnerNode; -public abstract class KotlinInnerNode - extends BaseAntlrInnerNode implements KotlinNode { +abstract class KotlinInnerNode extends BaseAntlrInnerNode implements KotlinNode { KotlinInnerNode(ParserRuleContext parent, int invokingStateNumber) { super(parent, invokingStateNumber); diff --git a/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 b/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 index 7d9bd13ff6..17c2e3f934 100644 --- a/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 +++ b/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4 @@ -44,12 +44,12 @@ import net.sourceforge.pmd.lang.ast.AstVisitor; static final AntlrNameDictionary DICO = new SwiftNameDictionary(VOCABULARY, ruleNames); @Override - public SwiftTerminalNode createPmdTerminal(ParserRuleContext parent, Token t) { + protected SwiftTerminalNode createPmdTerminal(ParserRuleContext parent, Token t) { return new SwiftTerminalNode(t); } @Override - public SwiftErrorNode createPmdError(ParserRuleContext parent, Token t) { + protected SwiftErrorNode createPmdError(ParserRuleContext parent, Token t) { return new SwiftErrorNode(t); } } diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftInnerNode.java b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftInnerNode.java index ea082bfbdc..48c5de1aeb 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftInnerNode.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftInnerNode.java @@ -9,7 +9,8 @@ import org.antlr.v4.runtime.ParserRuleContext; import net.sourceforge.pmd.lang.ast.AstVisitor; import net.sourceforge.pmd.lang.ast.impl.antlr4.BaseAntlrInnerNode; -public abstract class SwiftInnerNode +// package private base class +abstract class SwiftInnerNode extends BaseAntlrInnerNode implements SwiftNode { SwiftInnerNode() { From d20257ad67a4f16a075474c43cf7386ac092509d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 14 Apr 2023 15:27:22 +0200 Subject: [PATCH 22/63] [doc] Update release notes (#2500) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 3376a48d59..b77fb93350 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -48,6 +48,8 @@ The remaining section describe the complete release notes for 7.0.0. are package-private now. #### Fixed Issues: +* core + * [#2500](https://github.com/pmd/pmd/issues/2500): \[core] Clarify API for ANTLR based languages * java-codestyle * [#4273](https://github.com/pmd/pmd/issues/4273): \[java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default * java-errorprone @@ -228,6 +230,7 @@ See [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html). * [#2218](https://github.com/pmd/pmd/issues/2218): \[core] `isFindBoundary` should not be an attribute * [#2234](https://github.com/pmd/pmd/issues/2234): \[core] Consolidate PMD CLI into a single command * [#2239](https://github.com/pmd/pmd/issues/2239): \[core] Merging Javacc build scripts + * [#2500](https://github.com/pmd/pmd/issues/2500): \[core] Clarify API for ANTLR based languages * [#2518](https://github.com/pmd/pmd/issues/2518): \[core] Language properties * [#2602](https://github.com/pmd/pmd/issues/2602): \[core] Remove ParserOptions * [#2614](https://github.com/pmd/pmd/pull/2614): \[core] Upgrade Saxon, add XPath 3.1, remove Jaxen From 414aa3ec3ae68cb53c4812dfaed0dd08ead0f3e6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 14 Apr 2023 14:16:03 +0200 Subject: [PATCH 23/63] [doc] ANTLR: Update URLs to point to github.com/pmd/pmd/blob/master... --- .../adding_a_new_antlr_based_language.md | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md index 7d2be2372a..71cd1c6a89 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md @@ -3,15 +3,10 @@ title: Adding PMD support for a new ANTLR grammar based language short_title: Adding a new language with ANTLR tags: [devdocs, extending] summary: "How to add a new language to PMD using ANTLR grammar." -last_updated: February 2023 (7.0.0) +last_updated: April 2023 (7.0.0) sidebar: pmd_sidebar permalink: pmd_devdocs_major_adding_new_language_antlr.html folder: pmd/devdocs - -# -# needs to be changed to branch master instead of pmd/7.0.x once pmd7 is released -# https://github.com/pmd/pmd/blob/pmd/7.0.x -> https://github.com/pmd/pmd/blob/master -# --- {% include callout.html type="warning" content=" @@ -62,14 +57,14 @@ definitely don't come for free. It is much effort and requires perseverance to i ## 2. Implement an AST parser for your language * ANTLR will generate the parser for you based on the grammar file. The grammar file needs to be placed in the folder `src/main/antlr4` in the appropriate sub package `ast` of the language. E.g. for swift, the grammar - file is [Swift.g4](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4) + file is [Swift.g4](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4) and is placed in the package `net.sourceforge.pmd.lang.swift.ast`. ## 3. Create AST node classes * The individual AST nodes are generated, but you need to define the common interface for them. * You need to define the supertype interface for all nodes of the language. For that, we provide - [`AntlrNode`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNode.java). -* See [`SwiftNode`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftNode.java) + [`AntlrNode`](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrNode.java). +* See [`SwiftNode`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftNode.java) as an example. * Additionally, you need several base classes: * a language specific inner node - these nodes represent the production rules from the grammar. @@ -103,31 +98,31 @@ definitely don't come for free. It is much effort and requires perseverance to i have the parser generated. * The generated code will be placed under `target/generated-sources/antlr4` and will not be committed to source control. -* You should review the [swift pom](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/pom.xml). +* You should review the [swift pom](https://github.com/pmd/pmd/blob/master/pmd-swift/pom.xml). ## 5. Create a TokenManager * This is needed to support CPD (copy paste detection) -* We provide a default implementation using [`AntlrTokenManager`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java). +* We provide a default implementation using [`AntlrTokenManager`](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java). * You must create your own "AntlrTokenizer" such as we do with - [`SwiftTokenizer`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java). + [`SwiftTokenizer`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java). * If you wish to filter specific tokens (e.g. comments to support CPD suppression via "CPD-OFF" and "CPD-ON") you can create your own implementation of - [`AntlrTokenFilter`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/AntlrTokenFilter.java). + [`AntlrTokenFilter`](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/AntlrTokenFilter.java). You'll need to override then the protected method `getTokenFilter(AntlrTokenManager)` and return your custom filter. See the tokenizer for C# as an exmaple: - [`CsTokenizer`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java). + [`CsTokenizer`](https://github.com/pmd/pmd/blob/master/pmd-cs/src/main/java/net/sourceforge/pmd/cpd/CsTokenizer.java). If you don't need a custom token filter, you don't need to override the method. It returns the default `AntlrTokenFilter` which doesn't filter anything. ## 6. Create a PMD parser “adapter” * Create your own parser, that adapts the ANLTR interface to PMD's parser interface. -* We provide a [`AntlrBaseParser`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseParser.java) +* We provide a [`AntlrBaseParser`](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrBaseParser.java) implementation that you need to extend to create your own adapter as we do with - [`PmdSwiftParser`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/PmdSwiftParser.java). + [`PmdSwiftParser`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/PmdSwiftParser.java). ## 7. Create a language version handler -* Now you need to create your version handler, as we did with [`SwiftHandler`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftHandler.java). +* Now you need to create your version handler, as we did with [`SwiftHandler`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftHandler.java). * This class is sort of a gateway between PMD and all parsing logic specific to your language. * For a minimal implementation, it just needs to return a parser *(see step #6)*. * It can be used to provide other features for your language like @@ -140,15 +135,15 @@ definitely don't come for free. It is much effort and requires perseverance to i * A parser visitor adapter is not needed anymore with PMD 7. The visitor interface now provides a default implementation. * The visitor for ANTLR based AST is generated along the parser from the ANTLR grammar file. The - base interface for a visitor is [`AstVisitor`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstVisitor.java). + base interface for a visitor is [`AstVisitor`](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/AstVisitor.java). * The generated visitor class for Swift is called `SwiftVisitor`. * In order to help use this visitor later on, a base visitor class should be created. - See [`SwiftVisitorBase`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftVisitorBase.java) + See [`SwiftVisitorBase`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftVisitorBase.java) as an example. ## 9. Make PMD recognize your language * Create your own subclass of `net.sourceforge.pmd.lang.impl.SimpleLanguageModuleBase`, see Swift as an example: - [`SwiftLanguageModule`](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftLanguageModule.java). + [`SwiftLanguageModule`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/SwiftLanguageModule.java). * Add for each version of your language a call to `addVersion` in your language module’s constructor. Use `addDefaultVersion` for defining the default version. * You’ll need to refer the language version handler created in step #7. @@ -175,7 +170,7 @@ definitely don't come for free. It is much effort and requires perseverance to i * PMD supports 2 types of rules, through visitors or XPath. * To add a visitor rule: * You need to extend the abstract rule you created on the previous step, you can use the swift - rule [UnavailableFunctionRule](https://github.com/pmd/pmd/blob/pmd/7.0.x/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java) + rule [UnavailableFunctionRule](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionRule.java) as an example. Note, that all rule classes should be suffixed with `Rule` and should be placed in a package the corresponds to their category. * To add an XPath rule you can follow our guide [Writing XPath Rules](pmd_userdocs_extending_writing_xpath_rules.html). From f0b729b2e92ae31b6519d554894d2330d0d32dfa Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 14 Apr 2023 14:44:26 +0200 Subject: [PATCH 24/63] [doc] ANTLR: Update paragraph about limitations (CST vs. AST) --- .../adding_a_new_antlr_based_language.md | 26 ++++++++++++------- .../adding_a_new_javacc_based_language.md | 6 ++--- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md index 71cd1c6a89..1edf655642 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md @@ -16,27 +16,33 @@ folder: pmd/devdocs This is really a big contribution and can't be done with a drive by contribution. It requires dedicated passion and long commitment to implement support for a new language.

-This step-by-step guide is just a small intro to get the basics started and it's also not necessarily up-to-date -or complete and you have to be able to fill in the blanks.

+This step-by-step guide is just a small intro to get the basics started, and it's also not necessarily up-to-date +or complete. You have to be able to fill in the blanks.

-Currently the Antlr integration has some basic limitations compared to JavaCC: The output of the -Antlr parser generator is not an abstract syntax tree (AST) but a parse tree. As such, a parse tree is -much more fine-grained than what a typical JavaCC grammar will produce. This means that the +Currently, the Antlr integration has some basic limitations compared to JavaCC: The output of the +Antlr parser generator is not an abstract syntax tree (AST) but a parse tree (also known as CST, concrete syntax tree). +As such, a parse tree is much more fine-grained than what a typical JavaCC grammar will produce. This means that the parse tree is much deeper and contains nodes down to the different token types.

-The Antlr nodes themselves don't have any attributes because they are on the wrong abstraction level. -As they don't have attributes, there are no attributes that can be used in XPath based rules.

+The Antlr nodes are context objects and serve a different abstraction than nodes in an AST. These context objects +themselves don't have any attributes because they themselves represent the attributes (as nodes or leaves in the +parse tree). As they don't have attributes, there are no attributes that can be used in XPath based rules.

+ +The current implementation of the languages using ANTLR use these context objects as nodes in PMD's AST +representation.

In order to overcome these limitations, one would need to implement a post-processing step that transforms -a parse tree into an abstract syntax tree and introducing real nodes on a higher abstraction level. This -step is **not** described in this guide.

+a parse tree into an abstract syntax tree and introducing real nodes on a higher abstraction level. These +real nodes can then have attributes which are available in XPath based rules. The transformation can happen +with a visitor, but the implementation of the AST is a manual step. This step is **not** described +in this guide.

After the basic support for a language is there, there are lots of missing features left. Typical features that can greatly improve rule writing are: symbol table, type resolution, call/data flow analysis.

Symbol table keeps track of variables and their usages. Type resolution tries to find the actual class type of each used type, following along method calls (including overloaded and overwritten methods), allowing -to query sub types and type hierarchy. This requires additional configuration of an auxiliary classpath. +to query subtypes and type hierarchy. This requires additional configuration of an auxiliary classpath. Call and data flow analysis keep track of the data as it is moving through different execution paths a program has.

diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md index 5cf6c66757..4e4d1f1443 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md @@ -16,15 +16,15 @@ folder: pmd/devdocs This is really a big contribution and can't be done with a drive by contribution. It requires dedicated passion and long commitment to implement support for a new language.

-This step-by-step guide is just a small intro to get the basics started and it's also not necessarily up-to-date -or complete and you have to be able to fill in the blanks.

+This step-by-step guide is just a small intro to get the basics started, and it's also not necessarily up-to-date +or complete. You have to be able to fill in the blanks.

After the basic support for a language is there, there are lots of missing features left. Typical features that can greatly improve rule writing are: symbol table, type resolution, call/data flow analysis.

Symbol table keeps track of variables and their usages. Type resolution tries to find the actual class type of each used type, following along method calls (including overloaded and overwritten methods), allowing -to query sub types and type hierarchy. This requires additional configuration of an auxiliary classpath. +to query subtypes and type hierarchy. This requires additional configuration of an auxiliary classpath. Call and data flow analysis keep track of the data as it is moving through different execution paths a program has.

From 079ff2050b21a12ef80807930c6a8207cfd4e84c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 14 Apr 2023 15:23:24 +0200 Subject: [PATCH 25/63] [doc] ANTLR: Update documentation Fixes #2501 --- docs/_data/sidebars/pmd_sidebar.yml | 2 +- .../adding_a_new_antlr_based_language.md | 55 +++++++++++++++---- .../adding_a_new_javacc_based_language.md | 2 +- docs/pages/release_notes.md | 4 ++ 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index 6ca086dc8f..83db036e88 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -469,7 +469,7 @@ entries: - title: Adding a new language (JavaCC) url: /pmd_devdocs_major_adding_new_language_javacc.html output: web, pdf - - title: Adding a new language (Antlr) + - title: Adding a new language (ANTLR) url: /pmd_devdocs_major_adding_new_language_antlr.html output: web, pdf - title: Adding a new CPD language diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md index 1edf655642..f4f8fd21c5 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md @@ -19,7 +19,7 @@ and long commitment to implement support for a new language.

This step-by-step guide is just a small intro to get the basics started, and it's also not necessarily up-to-date or complete. You have to be able to fill in the blanks.

-Currently, the Antlr integration has some basic limitations compared to JavaCC: The output of the +Currently, the Antlr integration has some basic **limitations** compared to JavaCC: The output of the Antlr parser generator is not an abstract syntax tree (AST) but a parse tree (also known as CST, concrete syntax tree). As such, a parse tree is much more fine-grained than what a typical JavaCC grammar will produce. This means that the parse tree is much deeper and contains nodes down to the different token types.

@@ -53,7 +53,7 @@ definitely don't come for free. It is much effort and requires perseverance to i ## 1. Start with a new sub-module * See pmd-swift for examples. -* Make sure to add your new module to the parent pom as `` entry, so that it is built alongside the +* Make sure to add your new module to PMD's parent pom as `` entry, so that it is built alongside the other languages. * Also add your new module to the dependencies list in "pmd-languages-deps/pom.xml", so that the new language is automatically available in the binary distribution (pmd-dist) as well as for the shell-completion @@ -65,6 +65,8 @@ definitely don't come for free. It is much effort and requires perseverance to i folder `src/main/antlr4` in the appropriate sub package `ast` of the language. E.g. for swift, the grammar file is [Swift.g4](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/antlr4/net/sourceforge/pmd/lang/swift/ast/Swift.g4) and is placed in the package `net.sourceforge.pmd.lang.swift.ast`. +* Configure the options "superClass" and "contextSuperClass". These are the base classes for the generated + classes. ## 3. Create AST node classes * The individual AST nodes are generated, but you need to define the common interface for them. @@ -89,11 +91,19 @@ definitely don't come for free. It is much effort and requires perseverance to i See [`SwiftTerminalNode`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftTerminalNode.java). * a language specific error node. See [`SwiftErrorNode`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftErrorNode.java). + * a language name dictionary. This is used to convert ANTLR node names to useful XPath node names. + See [`SwiftNameDictionary'](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/ast/SwiftNameDictionary.java). +* Once these base classes exist, you need to change the ANTLR grammar to add additional members via `@parser::members` + * Define a package private field `DICO` which creates a new instance of your language name dictionary using the + vocabulary from the generated parser (`VOCABULARY`). + * Define two additional methods to help converting the ANTLR context objects into PMD AST nodes. + The methods are abstract in [`AntlrGeneratedParserBase`](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/AntlrGeneratedParserBase.java) + and need to be implemented here for the concrete language: `createPmdTerminal()` and `createPmdError()`. * In order for the generated code to match and use our custom classes, we have a common ant script, that fiddles with - the generated code. The ant script is [`antlr4-wrapper.xml`](https://github.com/pmd/pmd/blob/master/antlr4-wrapper.xml) and - does not need to be adjusted - it has plenty of parameters to set. The ant script is added in the - language module's `pom.xml` where the parameters are set (e.g. name of root name class). Have a look at - Swift's example: [`pmd-swift/pom.xml`](https://github.com/pmd/pmd/blob/master/pmd-swift/pom.xml). + the generated code. The ant script is [`antlr4-wrapper.xml`](https://github.com/pmd/pmd/blob/master/antlr4-wrapper.xml) + and does not need to be adjusted - it has plenty of parameters that can be configured. + The ant script is added in the language module's `pom.xml` where the parameters are set (e.g. name of root name + class). Have a look at Swift's example: [`pmd-swift/pom.xml`](https://github.com/pmd/pmd/blob/master/pmd-swift/pom.xml). * You can add additional methods in your "InnerNode" (e.g. `SwiftInnerNode`) that are available on all nodes. But on most cases you won't need to do anything. @@ -104,7 +114,7 @@ definitely don't come for free. It is much effort and requires perseverance to i have the parser generated. * The generated code will be placed under `target/generated-sources/antlr4` and will not be committed to source control. -* You should review the [swift pom](https://github.com/pmd/pmd/blob/master/pmd-swift/pom.xml). +* You should review [`pmd-swift/pom.xml`](https://github.com/pmd/pmd/blob/master/pmd-swift/pom.xml). ## 5. Create a TokenManager * This is needed to support CPD (copy paste detection) @@ -157,7 +167,7 @@ definitely don't come for free. It is much effort and requires perseverance to i Add your fully qualified class name as a single line into it. ## 10. Create an abstract rule class for the language -* You need to create your own `AbstractRule` in order to interface your language with PMD's generic rule +* You need to create your own abstract rule class in order to interface your language with PMD's generic rule execution. * See [`AbstractSwiftRule`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/lang/swift/AbstractSwiftRule.java) as an example. * The rule basically just extends @@ -168,7 +178,10 @@ definitely don't come for free. It is much effort and requires perseverance to i This helps to organize the code. * All other rules for your language should extend this class. The purpose of this class is to provide a visitor via the method `buildVisitor()` for analyzing the AST. The provided visitor only implements the visit methods - for specific AST nodes. The other node types use the default behavior and you don't need to care about them. + for specific AST nodes. The other node types use the default behavior, and you don't need to care about them. +* Note: This is different from how it was in PMD 6: Each rule in PMD 6 was itself a visitor (implementing the visitor + interface of the specific language). Now the rule just provides a visitor, which can be hidden and potentially + shared between rules. ## 11. Create rules * Creating rules is already pretty well documented in PMD - and it’s no different for a new language, except you @@ -180,16 +193,34 @@ definitely don't come for free. It is much effort and requires perseverance to i as an example. Note, that all rule classes should be suffixed with `Rule` and should be placed in a package the corresponds to their category. * To add an XPath rule you can follow our guide [Writing XPath Rules](pmd_userdocs_extending_writing_xpath_rules.html). +* When creating the category ruleset XML file, the XML can reference build properties that are replaced + during the build. This is used for the `externalInfoUrl` attribute of a rule. E.g. we use `${pmd.website.baseurl}` + to point to the correct webpage (depending on the PMD version). In order for this to work, you need to add a + resource filtering configuration in the language module's `pom.xml`. Under `` add the following lines: + ```xml + + + ${project.basedir}/src/main/resources + true + + + ``` ## 14. Test the rules * Testing rules is described in depth in [Testing your rules](pmd_userdocs_extending_testing.html). * Each rule has its own test class: Create a test class for your rule extending `PmdRuleTst` - *(see UnavailableFunctionTest for example)* - * Create a category rule set for your language *(see pmd-swift/src/main/resources/bestpractices.xml for example)* + *(see + [`UnavailableFunctionTest`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/test/java/net/sourceforge/pmd/lang/swift/rule/bestpractices/UnavailableFunctionTest.java) + for example)* + * Create a category rule set for your language *(see + [`pmd-swift/src/main/resources/bestpractices.xml`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/resources/category/swift/bestpractices.xml) + for example)* * Place the test XML file with the test cases in the correct location * When executing the test class * this triggers the unit test to read the corresponding XML file with the rule test data - *(see `UnavailableFunction.xml` for example)* + *(see + [`UnavailableFunction.xml`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/test/resources/net/sourceforge/pmd/lang/swift/rule/bestpractices/xml/UnavailableFunction.xml) + for example)* * This test XML file contains sample pieces of code which should trigger a specified number of violations of this rule. The unit test will execute the rule on this piece of code, and verify that the number of violations matches. diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md index 4e4d1f1443..0501ec73b8 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_javacc_based_language.md @@ -36,7 +36,7 @@ definitely don't come for free. It is much effort and requires perseverance to i ## 1. Start with a new sub-module * See pmd-java or pmd-vm for examples. -* Make sure to add your new module to the parent pom as `` entry, so that it is built alongside the +* Make sure to add your new module to PMD's parent pom as `` entry, so that it is built alongside the other languages. * Also add your new module to the dependencies list in "pmd-languages-deps/pom.xml", so that the new language is automatically available in the binary distribution (pmd-dist) as well as for the shell-completion diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b77fb93350..dbe88c64b5 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -50,6 +50,8 @@ The remaining section describe the complete release notes for 7.0.0. #### Fixed Issues: * core * [#2500](https://github.com/pmd/pmd/issues/2500): \[core] Clarify API for ANTLR based languages +* doc + * [#2501](https://github.com/pmd/pmd/issues/2501): \[doc] Verify ANTLR Documentation * java-codestyle * [#4273](https://github.com/pmd/pmd/issues/4273): \[java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default * java-errorprone @@ -255,6 +257,8 @@ See [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html). * [#2234](https://github.com/pmd/pmd/issues/2234): \[core] Consolidate PMD CLI into a single command * [#3828](https://github.com/pmd/pmd/issues/3828): \[core] Progress reporting * [#4079](https://github.com/pmd/pmd/issues/4079): \[cli] Split off CLI implementation into a pmd-cli submodule +* doc + * [#2501](https://github.com/pmd/pmd/issues/2501): \[doc] Verify ANTLR Documentation * testing * [#2435](https://github.com/pmd/pmd/issues/2435): \[test] Remove duplicated Dummy language module * [#4234](https://github.com/pmd/pmd/issues/4234): \[test] Tests that change the logging level do not work From 175d4498d8c7c4cfd788a527e652485e95d1e37f Mon Sep 17 00:00:00 2001 From: Pim van der Loos Date: Sat, 15 Apr 2023 13:48:53 +0200 Subject: [PATCH 26/63] Add @PimvanderLoos as a contributor --- .all-contributorsrc | 10 +++ docs/pages/pmd/projectdocs/credits.md | 95 ++++++++++++++------------- 2 files changed, 58 insertions(+), 47 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index be48515595..398fbbf078 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -7154,6 +7154,16 @@ "contributions": [ "doc" ] + }, + { + "login": "PimvanderLoos", + "name": "Pim van der Loos", + "avatar_url": "https://avatars.githubusercontent.com/u/3114723?v=4", + "profile": "https://github.com/PimvanderLoos", + "contributions": [ + "code", + "test" + ] } ], "contributorsPerLine": 7, diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md index 60ed54ac18..18ef84958e 100644 --- a/docs/pages/pmd/projectdocs/credits.md +++ b/docs/pages/pmd/projectdocs/credits.md @@ -593,426 +593,427 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Philippe Ozil

🐛
Phinehas Artemix

🐛
Phokham Nonava

🐛 +
Pim van der Loos

💻 ⚠️
Piotr Szymański

🐛
Piotrek Żygieło

💻 🐛 📖
Pranay Jaiswal

🐛 -
Prasad Kamath

🐛 +
Prasad Kamath

🐛
Prasanna

🐛
Presh-AR

🐛
Puneet1726

🐛
Rafael Cortês

🐛
RaheemShaik999

🐛
RajeshR

💻 🐛 -
Ramachandra Mohan

🐛 +
Ramachandra Mohan

🐛
Ramel0921

🐛
Raquel Pau

🐛
Ravikiran Janardhana

🐛
Reda Benhemmouche

🐛
Renato Oliveira

💻 🐛
Rich DiCroce

🐛 -
Riot R1cket

🐛 +
Riot R1cket

🐛
Rishabh Jain

🐛
RishabhDeep Singh

🐛
Robbie Martinus

💻 🐛
Robert Henry

🐛
Robert Mihaly

🐛
Robert Painsi

🐛 -
Robert Russell

🐛 +
Robert Russell

🐛
Robert Sösemann

💻 📖 📢 🐛
Robert Whitebit

🐛
Robin Richtsfeld

🐛
Robin Stocker

💻 🐛
Robin Wils

🐛
RochusOest

🐛 -
Rodolfo Noviski

🐛 +
Rodolfo Noviski

🐛
Rodrigo Casara

🐛
Rodrigo Fernandes

🐛
Roman Salvador

💻 🐛
Ronald Blaschke

🐛
Róbert Papp

🐛
Saikat Sengupta

🐛 -
Saksham Handu

🐛 +
Saksham Handu

🐛
Saladoc

🐛
Salesforce Bob Lightning

🐛
Sam Carlberg

🐛
Satoshi Kubo

🐛
Scott Kennedy

🐛
Scott Wells

🐛 💻 -
Scrsloota

💻 +
Scrsloota

💻
Sebastian Bögl

🐛
Sebastian Schuberth

🐛
Sebastian Schwarz

🐛
Seren

🐛 💻
Sergey Gorbaty

🐛
Sergey Kozlov

🐛 -
Sergey Yanzin

💻 🐛 +
Sergey Yanzin

💻 🐛
Seth Wilcox

💻
Shubham

💻 🐛
Simon Abykov

💻 🐛
Simon Xiao

🐛
Srinivasan Venkatachalam

🐛
Stanislav Gromov

🐛 -
Stanislav Myachenkov

💻 +
Stanislav Myachenkov

💻
Stefan Birkner

🐛
Stefan Bohn

🐛
Stefan Endrullis

🐛
Stefan Klöss-Schuster

🐛
Stefan Wolf

🐛
Stephan H. Wissel

🐛 -
Stephen

🐛 +
Stephen

🐛
Stephen Friedrich

🐛
Steve Babula

💻
Steven Stearns

🐛 💻
Stexxe

🐛
Stian Lågstad

🐛
StuartClayton5

🐛 -
Supun Arunoda

🐛 +
Supun Arunoda

🐛
Suren Abrahamyan

🐛
Suvashri

📖
SwatiBGupta1110

🐛
SyedThoufich

🐛
Szymon Sasin

🐛
T-chuangxin

🐛 -
TERAI Atsuhiro

🐛 +
TERAI Atsuhiro

🐛
TIOBE Software

💻 🐛
Tarush Singh

💻
Taylor Smock

🐛
Techeira Damián

💻 🐛
Ted Husted

🐛
TehBakker

🐛 -
The Gitter Badger

🐛 +
The Gitter Badger

🐛
Theodoor

🐛
Thiago Henrique Hüpner

🐛
Thibault Meyer

🐛
Thomas Güttler

🐛
Thomas Jones-Low

🐛
Thomas Smith

💻 🐛 -
ThrawnCA

🐛 +
ThrawnCA

🐛
Thunderforge

💻 🐛
Tim van der Lippe

🐛
Tobias Weimer

💻 🐛
Tom Copeland

🐛 💻 📖
Tom Daly

🐛
Tomer Figenblat

🐛 -
Tomi De Lucca

💻 🐛 +
Tomi De Lucca

💻 🐛
Torsten Kleiber

🐛
TrackerSB

🐛
Tyson Stewart

🐛
Ullrich Hafner

🐛
Utku Cuhadaroglu

💻 🐛
Valentin Brandl

🐛 -
Valeria

🐛 +
Valeria

🐛
Valery Yatsynovich

📖
Vasily Anisimov

🐛
Vibhor Goyal

🐛
Vickenty Fesunov

🐛
Victor Noël

🐛
Vincent Galloy

💻 -
Vincent HUYNH

🐛 +
Vincent HUYNH

🐛
Vincent Maurin

🐛
Vincent Privat

🐛
Vishhwas

🐛
Vitaly

🐛
Vitaly Polonetsky

🐛
Vojtech Polivka

🐛 -
Vsevolod Zholobov

🐛 +
Vsevolod Zholobov

🐛
Vyom Yadav

💻
Wang Shidong

🐛
Waqas Ahmed

🐛
Wayne J. Earl

🐛
Wchenghui

🐛
Will Winder

🐛 -
William Brockhus

💻 🐛 +
William Brockhus

💻 🐛
Wilson Kurniawan

🐛
Wim Deblauwe

🐛
Woongsik Choi

🐛
XenoAmess

💻 🐛
Yang

💻
YaroslavTER

🐛 -
Yasar Shaikh

💻 +
Yasar Shaikh

💻
Young Chan

💻 🐛
YuJin Kim

🐛
Yuri Dolzhenko

🐛
Yurii Dubinka

🐛
Zoltan Farkas

🐛
Zustin

🐛 -
aaronhurst-google

🐛 💻 +
aaronhurst-google

🐛 💻
alexmodis

🐛
andreoss

🐛
andrey81inmd

💻 🐛
anicoara

🐛
arunprasathav

🐛
asiercamara

🐛 -
astillich-igniti

💻 +
astillich-igniti

💻
avesolovksyy

🐛
avishvat

🐛
avivmu

🐛
axelbarfod1

🐛
b-3-n

🐛
balbhadra9

🐛 -
base23de

🐛 +
base23de

🐛
bergander

🐛
berkam

💻 🐛
breizh31

🐛
caesarkim

🐛
carolyujing

🐛
cbfiddle

🐛 -
cesares-basilico

🐛 +
cesares-basilico

🐛
chrite

🐛
cobratbq

🐛
coladict

🐛
cosmoJFH

🐛
cristalp

🐛
crunsk

🐛 -
cwholmes

🐛 +
cwholmes

🐛
cyberjj999

🐛
cyw3

🐛
d1ss0nanz

🐛
dague1

📖
dalizi007

💻
danbrycefairsailcom

🐛 -
dariansanity

🐛 +
dariansanity

🐛
darrenmiliband

🐛
davidburstrom

🐛
dbirkman-paloalto

🐛
deepak-patra

🐛
dependabot[bot]

💻 🐛
dinesh150

🐛 -
diziaq

🐛 +
diziaq

🐛
dreaminpast123

🐛
duanyanan

🐛
dutt-sanjay

🐛
dylanleung

🐛
dzeigler

🐛
ekkirala

🐛 -
emersonmoura

🐛 +
emersonmoura

🐛
fairy

🐛
filiprafalowicz

💻
foxmason

🐛
frankegabor

🐛
frankl

🐛
freafrea

🐛 -
fsapatin

🐛 +
fsapatin

🐛
gracia19

🐛
guo fei

🐛
gurmsc5

🐛
gwilymatgearset

💻 🐛
haigsn

🐛
hemanshu070

🐛 -
henrik242

🐛 +
henrik242

🐛
hongpuwu

🐛
hvbtup

💻 🐛
igniti GmbH

🐛
ilovezfs

🐛
itaigilo

🐛
jakivey32

🐛 -
jbennett2091

🐛 +
jbennett2091

🐛
jcamerin

🐛
jkeener1

🐛
jmetertea

🐛
johnra2

💻
josemanuelrolon

💻 🐛
kabroxiko

💻 🐛 -
karwer

🐛 +
karwer

🐛
kaulonline

🐛
kdaemonv

🐛
kdebski85

🐛 💻
kenji21

💻 🐛
kfranic

🐛
khalidkh

🐛 -
koalalam

🐛 +
koalalam

🐛
krzyk

🐛
lasselindqvist

🐛
lgemeinhardt

🐛
lihuaib

🐛
lonelyma1021

🐛
lpeddy

🐛 -
lujiefsi

💻 +
lujiefsi

💻
lukelukes

💻
lyriccoder

🐛
marcelmore

🐛
matchbox

🐛
matthiaskraaz

🐛
meandonlyme

🐛 -
mikesive

🐛 +
mikesive

🐛
milossesic

🐛
mluckam

💻
mohan-chinnappan-n

💻
mriddell95

🐛
mrlzh

🐛
msloan

🐛 -
mucharlaravalika

🐛 +
mucharlaravalika

🐛
mvenneman

🐛
nareshl119

🐛
nicolas-harraudeau-sonarsource

🐛
noerremark

🐛
novsirion

🐛
nwcm

📖 -
oggboy

🐛 +
oggboy

🐛
oinume

🐛
orimarko

💻 🐛
pacvz

💻
pallavi agarwal

🐛
parksungrin

🐛
patpatpat123

🐛 -
patriksevallius

🐛 +
patriksevallius

🐛
pbrajesh1

🐛
phoenix384

🐛
piotrszymanski-sc

💻
plan3d

🐛
poojasix

🐛
prabhushrikant

🐛 -
pujitha8783

🐛 +
pujitha8783

🐛
r-r-a-j

🐛
raghujayjunk

🐛
rajeshveera

🐛
rajeswarreddy88

🐛
recdevs

🐛
reudismam

💻 🐛 -
rijkt

🐛 +
rijkt

🐛
rillig-tk

🐛
rmohan20

💻 🐛
rnveach

🐛
rxmicro

🐛
ryan-gustafson

💻 🐛
sabi0

🐛 -
scais

🐛 +
scais

🐛
sebbASF

🐛
sergeygorbaty

💻
shilko2013

🐛
shiomiyan

📖
simeonKondr

🐛
snajberk

🐛 -
sniperrifle2004

🐛 +
sniperrifle2004

🐛
snuyanzin

🐛 💻
sratz

🐛
stonio

🐛
sturton

💻 🐛
sudharmohan

🐛
suruchidawar

🐛 -
svenfinitiv

🐛 +
svenfinitiv

🐛
tashiscool

🐛
test-git-hook

🐛
testation21

💻 🐛
thanosa

🐛
tiandiyixian

🐛
tobwoerk

🐛 -
tprouvot

🐛 💻 +
tprouvot

🐛 💻
trentchilders

🐛
triandicAnt

🐛
trishul14

🐛
tsui

🐛
winhkey

🐛
witherspore

🐛 -
wjljack

🐛 +
wjljack

🐛
wuchiuwong

🐛
xingsong

🐛
xioayuge

🐛
xnYi9wRezm

💻 🐛
xuanuy

🐛
xyf0921

🐛 -
yalechen-cyw3

🐛 +
yalechen-cyw3

🐛
yasuharu-sato

🐛
zenglian

🐛
zgrzyt93

💻 🐛
zh3ng

🐛
zt_soft

🐛
ztt79

🐛 -
zzzzfeng

🐛 +
zzzzfeng

🐛
Árpád Magosányi

🐛
任贵杰

🐛
茅延安

💻 From 0a99c28bef8f3612b065a38b33a50bbb5cb8dfb8 Mon Sep 17 00:00:00 2001 From: Pim van der Loos Date: Sat, 15 Apr 2023 14:21:29 +0200 Subject: [PATCH 27/63] [java] ImmutableField: False positive with lombok (fixes #4254) --- .../java/rule/design/ImmutableFieldRule.java | 2 +- .../java/rule/design/xml/ImmutableField.xml | 21 ++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java index ecd65ef8b6..3cf13a3d5e 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java @@ -32,7 +32,7 @@ import net.sourceforge.pmd.util.CollectionUtil; public class ImmutableFieldRule extends AbstractJavaRulechainRule { private static final PropertyDescriptor> IGNORED_ANNOTS = - JavaPropertyUtil.ignoredAnnotationsDescriptor(); + JavaPropertyUtil.ignoredAnnotationsDescriptor("lombok.Getter", "lombok.Setter"); private static final Set INVALIDATING_CLASS_ANNOT = setOf( diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml index 3c6dd6a849..491c490520 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml @@ -415,7 +415,7 @@ public class CombinersTest { - #410 [java] ImmutableField: False positive with lombok + #410 [java] ImmutableField: False positive with lombok on class 0 + + #410 [java] ImmutableField: False positive with lombok on field + 0 + + + #855 [java] ImmutableField: False positive within lambda 0 From 66ddd5617f0c7ea71ed71e13b083b0555b6ad0a0 Mon Sep 17 00:00:00 2001 From: Pim van der Loos Date: Mon, 17 Apr 2023 11:10:55 +0200 Subject: [PATCH 28/63] Apply feedback --- .../pmd/lang/java/rule/design/ImmutableFieldRule.java | 9 ++++++++- .../pmd/lang/java/rule/design/xml/ImmutableField.xml | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java index 3cf13a3d5e..9a72491009 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java @@ -32,7 +32,7 @@ import net.sourceforge.pmd.util.CollectionUtil; public class ImmutableFieldRule extends AbstractJavaRulechainRule { private static final PropertyDescriptor> IGNORED_ANNOTS = - JavaPropertyUtil.ignoredAnnotationsDescriptor("lombok.Getter", "lombok.Setter"); + JavaPropertyUtil.ignoredAnnotationsDescriptor(); private static final Set INVALIDATING_CLASS_ANNOT = setOf( @@ -43,6 +43,12 @@ public class ImmutableFieldRule extends AbstractJavaRulechainRule { "lombok.Value" ); + private static final Set INVALIDATING_FIELD_ANNOT = + setOf( + "lombok.Getter", + "lombok.Setter" + ); + public ImmutableFieldRule() { super(ASTFieldDeclaration.class); definePropertyDescriptor(IGNORED_ANNOTS); @@ -55,6 +61,7 @@ public class ImmutableFieldRule extends AbstractJavaRulechainRule { if (field.getEffectiveVisibility().isAtMost(Visibility.V_PRIVATE) && !field.getModifiers().hasAny(JModifier.VOLATILE, JModifier.STATIC, JModifier.FINAL) && !JavaAstUtils.hasAnyAnnotation(enclosingType, INVALIDATING_CLASS_ANNOT) + && !JavaAstUtils.hasAnyAnnotation(field, INVALIDATING_FIELD_ANNOT) && !JavaAstUtils.hasAnyAnnotation(field, getProperty(IGNORED_ANNOTS))) { DataflowResult dataflow = DataflowPass.getDataflowResult(field.getRoot()); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml index 491c490520..5fec5f311f 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml @@ -434,7 +434,7 @@ public class Foo { - #410 [java] ImmutableField: False positive with lombok on field + #4254 [java] ImmutableField: False positive with lombok on field 0 Date: Tue, 18 Apr 2023 19:32:45 +0200 Subject: [PATCH 29/63] [doc] Update release notes (#4254, #4474) --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 45e3fa24ac..a19a66b1ec 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -345,6 +345,7 @@ Language specific fixes: * [#3754](https://github.com/pmd/pmd/issues/3754): \[java] SingularField false positive with read in while condition * [#3786](https://github.com/pmd/pmd/issues/3786): \[java] SimplifyBooleanReturns should consider operator precedence * [#4238](https://github.com/pmd/pmd/pull/4238): \[java] Make LawOfDemeter not use the rulechain + * [#4254](https://github.com/pmd/pmd/issues/4254): \[java] ImmutableField - false positive with Lombok @Setter * java-documentation * [#4369](https://github.com/pmd/pmd/pull/4369): \[java] Improve CommentSize * [#4416](https://github.com/pmd/pmd/pull/4416): \[java] Fix reported line number in CommentContentRule @@ -400,6 +401,7 @@ Language specific fixes: * [#4444](https://github.com/pmd/pmd/pull/4444): \[java] CommentDefaultAccessModifier - ignore org.junit.jupiter.api.extension.RegisterExtension by default - [Nirvik Patel](https://github.com/nirvikpatel) (@nirvikpatel) * [#4450](https://github.com/pmd/pmd/pull/4450): \[java] Fix #4449 AvoidAccessibilityAlteration: Correctly handle Lambda expressions in PrivilegedAction scenarios - [Seren](https://github.com/mohui1999) (@mohui1999) * [#4452](https://github.com/pmd/pmd/pull/4452): \[doc] Update PMD_APEX_ROOT_DIRECTORY documentation reference - [nwcm](https://github.com/nwcm) (@nwcm) +* [#4474](https://github.com/pmd/pmd/pull/4474): \[java] ImmutableField: False positive with lombok (fixes #4254) - [Pim van der Loos](https://github.com/PimvanderLoos) (@PimvanderLoos) ### 📈 Stats * 4416 commits From 1789014dc6be1dabc3cee34f8d398d8df92e7709 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 18 Apr 2023 20:18:06 +0200 Subject: [PATCH 30/63] [doc] Update release notes (#4483) Closes #4483 --- docs/pages/release_notes.md | 1 + .../java/rule/multithreading/xml/NonThreadSafeSingleton.xml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a19a66b1ec..49fedcfcbf 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -372,6 +372,7 @@ Language specific fixes: * [#2537](https://github.com/pmd/pmd/issues/2537): \[java] DontCallThreadRun can't detect the case that call run() in `this.run()` * [#2538](https://github.com/pmd/pmd/issues/2538): \[java] DontCallThreadRun can't detect the case that call run() in `foo.bar.run()` * [#2577](https://github.com/pmd/pmd/issues/2577): \[java] UseNotifyAllInsteadOfNotify falsely detect a special case with argument: `foo.notify(bar)` + * [#4483](https://github.com/pmd/pmd/issues/4483): \[java] NonThreadSafeSingleton false positive with double-checked locking * java-performance * [#1224](https://github.com/pmd/pmd/issues/1224): \[java] InefficientEmptyStringCheck false negative in anonymous class * [#2587](https://github.com/pmd/pmd/issues/2587): \[java] AvoidArrayLoops could also check for list copy through iterated List.add() diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/NonThreadSafeSingleton.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/NonThreadSafeSingleton.xml index 23a897b482..9a177239f3 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/NonThreadSafeSingleton.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/multithreading/xml/NonThreadSafeSingleton.xml @@ -176,7 +176,7 @@ class A extends B { - False positive with correct double checked pattern + False positive with correct double-checked pattern #4483 0 Date: Tue, 18 Apr 2023 20:15:48 -0300 Subject: [PATCH 31/63] Fix #4484 - Avoid an NPE on properties. --- .../pmd/cli/commands/internal/TreeExportCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/TreeExportCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/TreeExportCommand.java index c034682f07..452d1410fd 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/TreeExportCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/TreeExportCommand.java @@ -75,7 +75,7 @@ public class TreeExportCommand extends AbstractPmdSubcommand { @Option(names = "-P", description = "Key-value pair defining a property for the report format.%n" + "Supported values for each report format:%n${sys:pmd-cli.tree-export.report.properties.help}", completionCandidates = TreeExportReportPropertiesCandidates.class) - private Properties properties; + private Properties properties = new Properties(); @Option(names = "--file", description = "The file to parse and dump.") private Path file; From 1a488c79a4a437889e448a5c41681bc4fa101622 Mon Sep 17 00:00:00 2001 From: LynnBroe <109954313+LynnBroe@users.noreply.github.com> Date: Wed, 19 Apr 2023 17:01:56 +0800 Subject: [PATCH 32/63] Update TestFrameworksUtil.java --- .../pmd/lang/java/rule/internal/TestFrameworksUtil.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java index d8ccc72e28..08478500ed 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java @@ -79,6 +79,8 @@ public final class TestFrameworksUtil { || method.isAnnotationPresent("org.junit.BeforeClass") || method.isAnnotationPresent("org.junit.After") || method.isAnnotationPresent("org.junit.AfterClass") + || method.isAnnotationPresent("org.testng.annotations.AfterClass") + || method.isAnnotationPresent("org.testng.annotations.BeforeClass") || isJUnit3Class(method.getEnclosingType()) && ("setUp".equals(method.getName()) || "tearDown".equals(method.getName())); From 95de880b4b5f86ef1fe60cb63bc2d5370273170c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Apr 2023 14:36:15 +0200 Subject: [PATCH 33/63] [doc] Update release notes for 7.0.0-rc2 --- docs/pages/release_notes.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index ea7c5ab106..a8d3cf5e26 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -50,7 +50,7 @@ The remaining section describe the complete release notes for 7.0.0. in order to have the same meaning as in 6.55.0. That will make it easier if you upgrade from 6.55.0 to 7.0.0. However, that means, that you need to change these method calls if you have migrated to 7.0.0-rc1 already. -#### Fixed Issues: +#### Fixed Issues * core * [#2500](https://github.com/pmd/pmd/issues/2500): \[core] Clarify API for ANTLR based languages * doc @@ -58,11 +58,21 @@ The remaining section describe the complete release notes for 7.0.0. * [#4438](https://github.com/pmd/pmd/issues/4438): \[doc] Documentation links in VS Code are outdated * java-codestyle * [#4273](https://github.com/pmd/pmd/issues/4273): \[java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default +* java-design + * [#4254](https://github.com/pmd/pmd/issues/4254): \[java] ImmutableField - false positive with Lombok @Setter * java-errorprone * [#4449](https://github.com/pmd/pmd/issues/4449): \[java] AvoidAccessibilityAlteration: Possible false positive in AvoidAccessibilityAlteration rule when using Lambda expression +* java-multithreading + * [#4483](https://github.com/pmd/pmd/issues/4483): \[java] NonThreadSafeSingleton false positive with double-checked locking * miscellaneous * [#4462](https://github.com/pmd/pmd/issues/4462): Provide Software Bill of Materials (SBOM) +#### External contributions +* [#4444](https://github.com/pmd/pmd/pull/4444): \[java] CommentDefaultAccessModifier - ignore org.junit.jupiter.api.extension.RegisterExtension by default - [Nirvik Patel](https://github.com/nirvikpatel) (@nirvikpatel) +* [#4450](https://github.com/pmd/pmd/pull/4450): \[java] Fix #4449 AvoidAccessibilityAlteration: Correctly handle Lambda expressions in PrivilegedAction scenarios - [Seren](https://github.com/mohui1999) (@mohui1999) +* [#4452](https://github.com/pmd/pmd/pull/4452): \[doc] Update PMD_APEX_ROOT_DIRECTORY documentation reference - [nwcm](https://github.com/nwcm) (@nwcm) +* [#4474](https://github.com/pmd/pmd/pull/4474): \[java] ImmutableField: False positive with lombok (fixes #4254) - [Pim van der Loos](https://github.com/PimvanderLoos) (@PimvanderLoos) + ### 🚀 Major Features and Enhancements #### New official logo From f0722277211927feccd58164d9127ba7cba31ad9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Apr 2023 14:37:48 +0200 Subject: [PATCH 34/63] [doc] Fix dead link in adding_a_new_antlr_based_language.md --- .../major_contributions/adding_a_new_antlr_based_language.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md index f4f8fd21c5..473648ea00 100644 --- a/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md +++ b/docs/pages/pmd/devdocs/major_contributions/adding_a_new_antlr_based_language.md @@ -118,7 +118,7 @@ definitely don't come for free. It is much effort and requires perseverance to i ## 5. Create a TokenManager * This is needed to support CPD (copy paste detection) -* We provide a default implementation using [`AntlrTokenManager`](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/cpd/internal/AntlrTokenizer.java). +* We provide a default implementation using [`AntlrTokenManager`](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/java/net/sourceforge/pmd/cpd/impl/AntlrTokenizer.java). * You must create your own "AntlrTokenizer" such as we do with [`SwiftTokenizer`](https://github.com/pmd/pmd/blob/master/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java). * If you wish to filter specific tokens (e.g. comments to support CPD suppression via "CPD-OFF" and "CPD-ON") From 990fb9484516eb57cb13323f15e24b65e86bb080 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Apr 2023 14:14:06 +0200 Subject: [PATCH 35/63] [java] ImmutableField: Remove deprecated property "ignoredAnnotations" --- docs/pages/release_notes.md | 6 ++++++ docs/pages/release_notes_pmd7.md | 2 ++ .../java/rule/design/ImmutableFieldRule.java | 14 +++----------- .../java/rule/design/xml/ImmutableField.xml | 17 ----------------- 4 files changed, 11 insertions(+), 28 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a8d3cf5e26..e1347e3e7d 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -50,6 +50,10 @@ The remaining section describe the complete release notes for 7.0.0. in order to have the same meaning as in 6.55.0. That will make it easier if you upgrade from 6.55.0 to 7.0.0. However, that means, that you need to change these method calls if you have migrated to 7.0.0-rc1 already. +#### Rule Changes +* {% rule "java/design/ImmutableField" %}: the property `ignoredAnnotations` has been removed. The property was + deprecated since PMD 6.52.0. + #### Fixed Issues * core * [#2500](https://github.com/pmd/pmd/issues/2500): \[core] Clarify API for ANTLR based languages @@ -200,6 +204,8 @@ Contributors: [Lucas Soncini](https://github.com/lsoncini) (@lsoncini), * {% rule "java/documentation/CommentContent" %}: The properties `caseSensitive` and `disallowedTerms` are removed. The new property `fobiddenRegex` can be used now to define the disallowed terms with a single regular expression. +* {% rule "java/design/ImmutableField" %}: the property `ignoredAnnotations` has been removed. The property was + deprecated since PMD 6.52.0. #### Removed Rules diff --git a/docs/pages/release_notes_pmd7.md b/docs/pages/release_notes_pmd7.md index d83c4cfff8..53ead8c58e 100644 --- a/docs/pages/release_notes_pmd7.md +++ b/docs/pages/release_notes_pmd7.md @@ -550,6 +550,8 @@ Related issue: [[core] Explicitly name all language versions (#4120)](https://gi * {% rule "java/documentation/CommentContent" %}: The properties `caseSensitive` and `disallowedTerms` are removed. The new property `fobiddenRegex` can be used now to define the disallowed terms with a single regular expression. +* {% rule "java/design/ImmutableField" %}: the property `ignoredAnnotations` has been removed. The property was + deprecated since PMD 6.52.0. ### Deprecated Rules diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java index 9a72491009..5a9d28808b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java @@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.java.rule.design; import static net.sourceforge.pmd.util.CollectionUtil.setOf; -import java.util.List; import java.util.Set; import net.sourceforge.pmd.lang.ast.NodeStream; @@ -25,15 +24,10 @@ import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule; import net.sourceforge.pmd.lang.java.rule.internal.DataflowPass; import net.sourceforge.pmd.lang.java.rule.internal.DataflowPass.AssignmentEntry; import net.sourceforge.pmd.lang.java.rule.internal.DataflowPass.DataflowResult; -import net.sourceforge.pmd.lang.java.rule.internal.JavaPropertyUtil; -import net.sourceforge.pmd.properties.PropertyDescriptor; import net.sourceforge.pmd.util.CollectionUtil; public class ImmutableFieldRule extends AbstractJavaRulechainRule { - private static final PropertyDescriptor> IGNORED_ANNOTS = - JavaPropertyUtil.ignoredAnnotationsDescriptor(); - private static final Set INVALIDATING_CLASS_ANNOT = setOf( "lombok.Builder", @@ -51,7 +45,6 @@ public class ImmutableFieldRule extends AbstractJavaRulechainRule { public ImmutableFieldRule() { super(ASTFieldDeclaration.class); - definePropertyDescriptor(IGNORED_ANNOTS); } @@ -61,8 +54,7 @@ public class ImmutableFieldRule extends AbstractJavaRulechainRule { if (field.getEffectiveVisibility().isAtMost(Visibility.V_PRIVATE) && !field.getModifiers().hasAny(JModifier.VOLATILE, JModifier.STATIC, JModifier.FINAL) && !JavaAstUtils.hasAnyAnnotation(enclosingType, INVALIDATING_CLASS_ANNOT) - && !JavaAstUtils.hasAnyAnnotation(field, INVALIDATING_FIELD_ANNOT) - && !JavaAstUtils.hasAnyAnnotation(field, getProperty(IGNORED_ANNOTS))) { + && !JavaAstUtils.hasAnyAnnotation(field, INVALIDATING_FIELD_ANNOT)) { DataflowResult dataflow = DataflowPass.getDataflowResult(field.getRoot()); @@ -89,9 +81,9 @@ public class ImmutableFieldRule extends AbstractJavaRulechainRule { if (!hasWrite && !isBlank) { //todo this case may also handle static fields easily. - addViolation(data, varId, varId.getName()); + asCtx(data).addViolation(varId, varId.getName()); } else if (hasWrite && defaultValueDoesNotReachEndOfCtor(dataflow, varId)) { - addViolation(data, varId, varId.getName()); + asCtx(data).addViolation(varId, varId.getName()); } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml index 5fec5f311f..7a282ddea4 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml @@ -496,23 +496,6 @@ class Foo { ]]> - - #1056 [java] Property ignoredAnnotations does not work for SingularField and ImmutableField - java.lang.Deprecated - 0 - - - #1792 Immutable field should still be detected with @Delegate 1 From d9a98b9f9ab48b3500722d2b3f5cb737af80325f Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Apr 2023 14:49:36 +0200 Subject: [PATCH 36/63] [java] ImmutableField - remove @Getter This fixes a potential false negative when @Getter is used. See discussion on #4474 --- docs/pages/release_notes.md | 2 ++ .../java/rule/design/ImmutableFieldRule.java | 2 -- .../java/rule/design/xml/ImmutableField.xml | 22 ++++++++++++++++--- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a8d3cf5e26..d74b9ed494 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -60,6 +60,7 @@ The remaining section describe the complete release notes for 7.0.0. * [#4273](https://github.com/pmd/pmd/issues/4273): \[java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default * java-design * [#4254](https://github.com/pmd/pmd/issues/4254): \[java] ImmutableField - false positive with Lombok @Setter + * [#4490](https://github.com/pmd/pmd/issues/4490): \[java] ImmutableField - false negative with Lombok @Getter * java-errorprone * [#4449](https://github.com/pmd/pmd/issues/4449): \[java] AvoidAccessibilityAlteration: Possible false positive in AvoidAccessibilityAlteration rule when using Lambda expression * java-multithreading @@ -379,6 +380,7 @@ Language specific fixes: * [#3786](https://github.com/pmd/pmd/issues/3786): \[java] SimplifyBooleanReturns should consider operator precedence * [#4238](https://github.com/pmd/pmd/pull/4238): \[java] Make LawOfDemeter not use the rulechain * [#4254](https://github.com/pmd/pmd/issues/4254): \[java] ImmutableField - false positive with Lombok @Setter + * [#4490](https://github.com/pmd/pmd/issues/4490): \[java] ImmutableField - false negative with Lombok @Getter * java-documentation * [#4369](https://github.com/pmd/pmd/pull/4369): \[java] Improve CommentSize * [#4416](https://github.com/pmd/pmd/pull/4416): \[java] Fix reported line number in CommentContentRule diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java index 9a72491009..b12cb1a5da 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/ImmutableFieldRule.java @@ -38,14 +38,12 @@ public class ImmutableFieldRule extends AbstractJavaRulechainRule { setOf( "lombok.Builder", "lombok.Data", - "lombok.Getter", "lombok.Setter", "lombok.Value" ); private static final Set INVALIDATING_FIELD_ANNOT = setOf( - "lombok.Getter", "lombok.Setter" ); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml index 5fec5f311f..3fbfd5a585 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/ImmutableField.xml @@ -418,10 +418,8 @@ public class CombinersTest { #410 [java] ImmutableField: False positive with lombok on class 0 + + + + #4490 False negative with Lombok @Getter only + 1 + 6 + From dec7c7dabcaf3e3d33fc56ebc93b40b10273f57e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Apr 2023 17:02:01 +0200 Subject: [PATCH 37/63] [dist] Add integration test for ast-dump --- .../pmd/it/BinaryDistributionIT.java | 9 ++++ .../net/sourceforge/pmd/it/CpdExecutor.java | 21 +-------- .../net/sourceforge/pmd/it/PMDExecutor.java | 43 ++++++++----------- 3 files changed, 29 insertions(+), 44 deletions(-) diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java b/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java index c1331cbd67..f6e5d18e03 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/it/BinaryDistributionIT.java @@ -218,4 +218,13 @@ class BinaryDistributionIT extends AbstractBinaryDistributionTest { result = CpdExecutor.runCpd(tempDir, "--minimum-tokens", "1000", "--format", "text", "--dir", srcDir); result.assertExitCode(0); } + + @Test + void runAstDump() throws Exception { + File jumbledIncrementerSrc = new File(srcDir, "JumbledIncrementer.java"); + List args = listOf("--format", "xml", "--language", "java", "--file", jumbledIncrementerSrc.toString()); + ExecutionResult result = PMDExecutor.runCommand(tempDir, "ast-dump", args); + result.assertExitCode(0); + } + } diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/it/CpdExecutor.java b/pmd-dist/src/test/java/net/sourceforge/pmd/it/CpdExecutor.java index 0948d9ff28..4875c560d5 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/it/CpdExecutor.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/it/CpdExecutor.java @@ -4,14 +4,8 @@ package net.sourceforge.pmd.it; -import static net.sourceforge.pmd.util.CollectionUtil.listOf; - import java.nio.file.Path; -import java.util.List; - -import org.apache.commons.lang3.SystemUtils; - -import net.sourceforge.pmd.PMDVersion; +import java.util.Arrays; /** * Executes CPD from command line. Deals with the differences, when CPD is run on Windows or on Linux. @@ -19,8 +13,6 @@ import net.sourceforge.pmd.PMDVersion; * @author Andreas Dangel */ public class CpdExecutor { - private static final String PMD_BIN_PREFIX = "pmd-bin-"; - private CpdExecutor() { // this is a helper class only } @@ -33,15 +25,6 @@ public class CpdExecutor { * @throws Exception if the execution fails for any reason (executable not found, ...) */ public static ExecutionResult runCpd(Path tempDir, String... arguments) throws Exception { - String cmd; - List args; - if (SystemUtils.IS_OS_WINDOWS) { - cmd = "/bin/pmd.bat"; - } else { - cmd = "/bin/pmd"; - } - args = listOf("cpd", arguments); - cmd = tempDir.resolve(PMD_BIN_PREFIX + PMDVersion.VERSION + cmd).toAbsolutePath().toString(); - return PMDExecutor.runCommand(cmd, args, null); + return PMDExecutor.runCommand(tempDir, "cpd", Arrays.asList(arguments)); } } diff --git a/pmd-dist/src/test/java/net/sourceforge/pmd/it/PMDExecutor.java b/pmd-dist/src/test/java/net/sourceforge/pmd/it/PMDExecutor.java index ccc151ddc3..22357c3eba 100644 --- a/pmd-dist/src/test/java/net/sourceforge/pmd/it/PMDExecutor.java +++ b/pmd-dist/src/test/java/net/sourceforge/pmd/it/PMDExecutor.java @@ -36,31 +36,21 @@ public class PMDExecutor { // this is a helper class only } - private static ExecutionResult runPMDUnix(Path tempDir, Path reportFile, String... arguments) throws Exception { - String cmd = tempDir.resolve(AbstractBinaryDistributionTest.PMD_BIN_PREFIX + PMDVersion.VERSION + "/bin/pmd").toAbsolutePath().toString(); - List args = new ArrayList<>(); - args.add("check"); - args.addAll(Arrays.asList(arguments)); - return runCommand(cmd, args, reportFile); + static ExecutionResult runCommand(Path tempDir, String cmd, List arguments) throws Exception { + return runCommand(tempDir, cmd, arguments, null); } - private static ExecutionResult runPMDWindows(Path tempDir, Path reportFile, String... arguments) throws Exception { - String cmd = tempDir.resolve(AbstractBinaryDistributionTest.PMD_BIN_PREFIX + PMDVersion.VERSION + "/bin/pmd.bat").toAbsolutePath().toString(); - List args = new ArrayList<>(); - args.add("check"); - args.addAll(Arrays.asList(arguments)); - return runCommand(cmd, args, reportFile); - } - - static ExecutionResult runCommand(String cmd, List arguments, Path reportFile) throws Exception { - ProcessBuilder pb = new ProcessBuilder(cmd); - - if (reportFile != null) { - arguments.add(REPORTFILE_FLAG); - arguments.add(reportFile.toString()); + static ExecutionResult runCommand(Path tempDir, String cmd, List arguments, Path reportFile) throws Exception { + final String pmdScript; + if (SystemUtils.IS_OS_WINDOWS) { + pmdScript = tempDir.resolve(AbstractBinaryDistributionTest.PMD_BIN_PREFIX + PMDVersion.VERSION + "/bin/pmd.bat").toAbsolutePath().toString(); + } else { + pmdScript = tempDir.resolve(AbstractBinaryDistributionTest.PMD_BIN_PREFIX + PMDVersion.VERSION + "/bin/pmd").toAbsolutePath().toString(); } - + ProcessBuilder pb = new ProcessBuilder(pmdScript); + pb.command().add(cmd); pb.command().addAll(arguments); + pb.redirectErrorStream(false); // Ensure no ANSI output so tests can properly look at it @@ -137,10 +127,13 @@ public class PMDExecutor { * @throws Exception if the execution fails for any reason (executable not found, ...) */ public static ExecutionResult runPMD(Path reportFile, Path tempDir, String... arguments) throws Exception { - if (SystemUtils.IS_OS_WINDOWS) { - return runPMDWindows(tempDir, reportFile, arguments); - } else { - return runPMDUnix(tempDir, reportFile, arguments); + List args = new ArrayList<>(); + if (reportFile != null) { + args.add(REPORTFILE_FLAG); + args.add(reportFile.toString()); } + args.addAll(Arrays.asList(arguments)); + + return runCommand(tempDir, "check", args, reportFile); } } From e860d6aad53c299786bb1bf9ff6e91a445fc258c Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Apr 2023 17:04:28 +0200 Subject: [PATCH 38/63] [doc] Update release notes (#4484) --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 49fedcfcbf..2db45005c2 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -40,6 +40,8 @@ This section lists the most important changes from the last release candidate. The remaining section describe the complete release notes for 7.0.0. Fixed Issues: +* cli + * [#4484](https://github.com/pmd/pmd/issues/4484): \[cli] ast-dump with no properties produce an NPE * java-codestyle * [#4273](https://github.com/pmd/pmd/issues/4273): \[java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default * java-errorprone @@ -244,6 +246,7 @@ See [Detailed Release Notes for PMD 7](pmd_release_notes_pmd7.html). * [#2234](https://github.com/pmd/pmd/issues/2234): \[core] Consolidate PMD CLI into a single command * [#3828](https://github.com/pmd/pmd/issues/3828): \[core] Progress reporting * [#4079](https://github.com/pmd/pmd/issues/4079): \[cli] Split off CLI implementation into a pmd-cli submodule + * [#4484](https://github.com/pmd/pmd/issues/4484): \[cli] ast-dump with no properties produce an NPE * testing * [#2435](https://github.com/pmd/pmd/issues/2435): \[test] Remove duplicated Dummy language module * [#4234](https://github.com/pmd/pmd/issues/4234): \[test] Tests that change the logging level do not work From 3cf0ba2b3f0fd8986b35bf7d2b772e4d0a6818b4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Apr 2023 20:50:13 +0200 Subject: [PATCH 39/63] [dist] Fix pmd.bat script Fixes #4482 --- docs/pages/release_notes.md | 2 + pmd-dist/src/main/resources/scripts/pmd | 9 ++++ pmd-dist/src/main/resources/scripts/pmd.bat | 36 ++++++------- .../scripts/{designertest.bat => pmdtest.bat} | 50 +++++++++++++++---- 4 files changed, 69 insertions(+), 28 deletions(-) rename pmd-dist/src/test/resources/scripts/{designertest.bat => pmdtest.bat} (72%) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 710eea3d29..8cde6f0d29 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -52,6 +52,7 @@ The remaining section describe the complete release notes for 7.0.0. #### Fixed Issues * cli + * [#4482](https://github.com/pmd/pmd/issues/4482): \[cli] pmd.bat can only be executed once * [#4484](https://github.com/pmd/pmd/issues/4484): \[cli] ast-dump with no properties produce an NPE * core * [#2500](https://github.com/pmd/pmd/issues/2500): \[core] Clarify API for ANTLR based languages @@ -277,6 +278,7 @@ See [Detailed Release Notes for PMD 7]({{ baseurl }}pmd_release_notes_pmd7.html) * [#2234](https://github.com/pmd/pmd/issues/2234): \[core] Consolidate PMD CLI into a single command * [#3828](https://github.com/pmd/pmd/issues/3828): \[core] Progress reporting * [#4079](https://github.com/pmd/pmd/issues/4079): \[cli] Split off CLI implementation into a pmd-cli submodule + * [#4482](https://github.com/pmd/pmd/issues/4482): \[cli] pmd.bat can only be executed once * [#4484](https://github.com/pmd/pmd/issues/4484): \[cli] ast-dump with no properties produce an NPE * doc * [#2501](https://github.com/pmd/pmd/issues/2501): \[doc] Verify ANTLR Documentation diff --git a/pmd-dist/src/main/resources/scripts/pmd b/pmd-dist/src/main/resources/scripts/pmd index 6407edb1e0..926238f9da 100755 --- a/pmd-dist/src/main/resources/scripts/pmd +++ b/pmd-dist/src/main/resources/scripts/pmd @@ -95,6 +95,13 @@ function script_exit() { exit 1 } +function check_java() { + java -version >/dev/null 2>&1 + if [ $? -ne 0 ]; then + script_exit "No java executable found in PATH" + fi +} + determine_java_version() { local full_ver=$(java -version 2>&1) # java_ver is eg "80" for java 1.8, "90" for java 9.0, "100" for java 10.0.x @@ -183,6 +190,8 @@ readonly APPNAME="${1}" is_cygwin +check_java + set_lib_dir check_lib_dir set_conf_dir diff --git a/pmd-dist/src/main/resources/scripts/pmd.bat b/pmd-dist/src/main/resources/scripts/pmd.bat index f7d3fe9474..c4dc049770 100644 --- a/pmd-dist/src/main/resources/scripts/pmd.bat +++ b/pmd-dist/src/main/resources/scripts/pmd.bat @@ -1,19 +1,26 @@ @echo off +rem make all variables local to not add new global environment variables to the current cmd session +setlocal set TOPDIR="%~dp0.." set OPTS= set COMMAND=%1 set MAIN_CLASS=net.sourceforge.pmd.cli.PmdCli +rem check whether java is available at all +java -version > nul 2>&1 || ( + echo No java executable found in PATH + exit /b 1 +) -:: sets the jver variable to the java version, eg 90 for 9.0.1+x or 80 for 1.8.0_171-b11 or 110 for 11.0.6.1 -:: sets the jvendor variable to either java (oracle) or openjdk +rem sets the jver variable to the java version, eg 90 for 9.0.1+x or 80 for 1.8.0_171-b11 or 110 for 11.0.6.1 +rem sets the jvendor variable to either java (oracle) or openjdk for /f tokens^=1^,3^,4^,5^ delims^=.-_+^"^ %%j in ('java -version 2^>^&1 ^| findstr /c:"version"') do ( set jvendor=%%j if %%l EQU ea ( set /A "jver=%%k0" ) else ( if %%k EQU 1 ( - :: for java version 1.7.x, 1.8.x, ignore the first 1. + rem for java version 1.7.x, 1.8.x, ignore the first 1. set /A "jver=%%l%%m" ) else ( set /A "jver=%%k%%l" @@ -22,11 +29,11 @@ for /f tokens^=1^,3^,4^,5^ delims^=.-_+^"^ %%j in ('java -version 2^>^&1 ^| fin ) Set "jreopts=" -:: oracle java 9 and 10 has javafx included as a module +rem oracle java 9 and 10 has javafx included as a module if /I %jvendor% == java ( if %jver% GEQ 90 ( if %jver% LSS 110 ( - :: enable reflection + rem enable reflection SETLOCAL EnableDelayedExpansion rem java9 and java10 from oracle contain javafx as a module rem open internal module of javafx to reflection (for our TreeViewWrapper) @@ -38,7 +45,6 @@ if /I %jvendor% == java ( set "jreopts=!jreopts! --add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED" rem Warn of remaining illegal accesses set "jreopts=!jreopts! --illegal-access=warn" - ) ) ) @@ -53,25 +59,21 @@ if [%COMMAND%] == [designer] ( if %_needjfxlib% EQU 1 ( if %jver% LSS 100 ( echo For openjfx at least java 10 is required. - pause - exit + exit /b 1 ) - if [%JAVAFX_HOME%] EQU [] ( + if not defined JAVAFX_HOME ( echo The environment variable JAVAFX_HOME is missing. - pause - exit + exit /b 1 ) - :: The wildcard will include only jar files, but we need to access also - :: property files such as javafx.properties that lay bare in the dir + rem The wildcard will include only jar files, but we need to access also + rem property files such as javafx.properties that lay bare in the dir set pmd_classpath=%TOPDIR%\conf;%TOPDIR%\lib\*;%JAVAFX_HOME%\lib\*;%JAVAFX_HOME%\lib\ ) else ( set pmd_classpath=%TOPDIR%\conf;%TOPDIR%\lib\* ) -if [%CLASSPATH%] NEQ [] ( - set classpath=%CLASSPATH%;%pmd_classpath% -) else ( - set classpath=%pmd_classpath% +if defined CLASSPATH ( + set pmd_classpath=%CLASSPATH%;%pmd_classpath% ) java %PMD_JAVA_OPTS% %jreopts% -classpath %pmd_classpath% %OPTS% %MAIN_CLASS% %* diff --git a/pmd-dist/src/test/resources/scripts/designertest.bat b/pmd-dist/src/test/resources/scripts/pmdtest.bat similarity index 72% rename from pmd-dist/src/test/resources/scripts/designertest.bat rename to pmd-dist/src/test/resources/scripts/pmdtest.bat index d43a5ff146..a9ee3ff388 100644 --- a/pmd-dist/src/test/resources/scripts/designertest.bat +++ b/pmd-dist/src/test/resources/scripts/pmdtest.bat @@ -1,27 +1,27 @@ @echo off -:: BSD-style license; for more info see http://pmd.sourceforge.net/license.html +rem BSD-style license; for more info see http://pmd.sourceforge.net/license.html -:: -:: Simple manual test script -:: - code is copied from designer.bat to be tested here (so please check, it might be out of sync) -:: - mostly the function "determine_java_version" is tested here -:: - just run it with "designertest.bat" and look at the output -:: - test cases are at the end of this script -:: +rem +rem Simple manual test script +rem - code is copied from designer.bat to be tested here (so please check, it might be out of sync) +rem - mostly the function "determine_java_version" is tested here +rem - just run it with "designertest.bat" and look at the output +rem - test cases are at the end of this script +rem GOTO :main :determine_java_version -:: sets the jver variable to the java version, eg 90 for 9.0.1+x or 80 for 1.8.0_171-b11 or 110 for 11.0.6.1 -:: sets the jvendor variable to either java (oracle) or openjdk +rem sets the jver variable to the java version, eg 90 for 9.0.1+x or 80 for 1.8.0_171-b11 or 110 for 11.0.6.1 +rem sets the jvendor variable to either java (oracle) or openjdk for /f tokens^=1^,3^,4^,5^ delims^=.-_+^"^ %%j in (%full_version%) do ( set jvendor=%%j if %%l EQU ea ( set /A "jver=%%k0" ) else ( if %%k EQU 1 ( - :: for java version 1.7.x, 1.8.x, ignore the first 1. + rem for java version 1.7.x, 1.8.x, ignore the first 1. set /A "jver=%%l%%m" ) else ( set /A "jver=%%k%%l" @@ -67,6 +67,24 @@ if [%detection%] == [] ( EXIT /B +:check_for_java_command +set cmd=%1 +echo cmd=%1 +%cmd% -version > nul 2>&1 || ( + echo No java executable not found in PATH + EXIT /B 1 +) +EXIT /B 0 + +:check_classpath_extension +setlocal +set cp=%1 +echo testing cp=%1 +if defined cp ( + echo classpath is not empty +) +endlocal +EXIT /B :run_test set full_version=%1 @@ -86,6 +104,16 @@ EXIT /B :main +CALL :check_for_java_command javanotfound +echo errorlevel: %ERRORLEVEL% + +CALL :check_classpath_extension +CALL :check_classpath_extension a\b.jar +CALL :check_classpath_extension "a\b.jar;c\d.jar" +CALL :check_classpath_extension "a\b.jar" +CALL :check_classpath_extension "a"\b.jar +CALL :check_classpath_extension "a"\b.jar;"c"\d.jar + CALL :run_test "java version ""1.7.0_80""" java 70 "detected java 7" CALL :run_test "openjdk version ""1.7.0_352""" openjdk 70 "detected java 7" CALL :run_test "java version ""1.8.0_271""" java 80 "detected java 8" From dffab8e4fbb83a587fc57ec60af2de2cfa4f0be0 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 20 Apr 2023 21:02:36 +0200 Subject: [PATCH 40/63] Fix comment [skip ci] --- pmd-dist/src/test/resources/scripts/pmdtest.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pmd-dist/src/test/resources/scripts/pmdtest.bat b/pmd-dist/src/test/resources/scripts/pmdtest.bat index a9ee3ff388..40f189ce7a 100644 --- a/pmd-dist/src/test/resources/scripts/pmdtest.bat +++ b/pmd-dist/src/test/resources/scripts/pmdtest.bat @@ -4,9 +4,9 @@ rem BSD-style license; for more info see http://pmd.sourceforge.net/license.html rem rem Simple manual test script -rem - code is copied from designer.bat to be tested here (so please check, it might be out of sync) +rem - code is copied from pmd.bat to be tested here (so please check, it might be out of sync) rem - mostly the function "determine_java_version" is tested here -rem - just run it with "designertest.bat" and look at the output +rem - just run it with "pmd.bat" and look at the output rem - test cases are at the end of this script rem From 5eee9f6a13b0c6d29c723cb7c373461516293bae Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 21 Apr 2023 09:02:05 +0200 Subject: [PATCH 41/63] [test] Fix rule test reporting --- .../main/java/net/sourceforge/pmd/testframework/RuleTst.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pmd-test/src/main/java/net/sourceforge/pmd/testframework/RuleTst.java b/pmd-test/src/main/java/net/sourceforge/pmd/testframework/RuleTst.java index 5c3041c7dc..1185d26c74 100644 --- a/pmd-test/src/main/java/net/sourceforge/pmd/testframework/RuleTst.java +++ b/pmd-test/src/main/java/net/sourceforge/pmd/testframework/RuleTst.java @@ -201,8 +201,9 @@ public abstract class RuleTst { System.out.println(" -> Expected messages: " + test.getExpectedMessages()); System.out.println(" -> Expected line numbers: " + test.getExpectedLineNumbers()); System.out.println(); + StringWriter reportOutput = new StringWriter(); TextRenderer renderer = new TextRenderer(); - renderer.setWriter(new StringWriter()); + renderer.setWriter(reportOutput); try { renderer.start(); renderer.renderFileReport(report); @@ -210,7 +211,7 @@ public abstract class RuleTst { } catch (IOException e) { throw new RuntimeException(e); } - System.out.println(renderer.getWriter().toString()); + System.out.println(reportOutput); System.out.println("--------------------------------------------------------------"); } From 2f0d83f98dc1f3a5c4ad243150123ae75698b41a Mon Sep 17 00:00:00 2001 From: LynnBroe <109954313+LynnBroe@users.noreply.github.com> Date: Fri, 21 Apr 2023 15:33:21 +0800 Subject: [PATCH 42/63] fix issue4487 --- .../codestyle/UnnecessaryConstructorRule.java | 4 +++- .../rule/codestyle/xml/UnnecessaryConstructor.xml | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java index f3e9e4a253..3f14330852 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java @@ -4,6 +4,7 @@ package net.sourceforge.pmd.lang.java.rule.codestyle; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -35,7 +36,8 @@ public class UnnecessaryConstructorRule extends AbstractIgnoredAnnotationRule { @Override protected Collection defaultSuppressionAnnotations() { - return Collections.singletonList("javax.inject.Inject"); + return Arrays.asList("javax.inject.Inject", + "com.google.inject.Inject"); } @Override diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryConstructor.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryConstructor.xml index 1754836837..beb118aa29 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryConstructor.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryConstructor.xml @@ -209,6 +209,21 @@ public class Foo { @Deprecated public Foo() { } +} + ]]> + + + + Issue #4487: [java]A false-positive about UnnecessaryConstructor and @Inject + 0 + From cced58c9a0b6a4c8d8e5510b8e6727791023a39e Mon Sep 17 00:00:00 2001 From: LynnBroe <109954313+LynnBroe@users.noreply.github.com> Date: Fri, 21 Apr 2023 16:01:34 +0800 Subject: [PATCH 43/63] fix issue4493 --- .../main/resources/category/java/errorprone.xml | 2 +- ...singStaticMethodInNonInstantiatableClass.xml | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/resources/category/java/errorprone.xml b/pmd-java/src/main/resources/category/java/errorprone.xml index c888a021ff..ac2a1558e0 100644 --- a/pmd-java/src/main/resources/category/java/errorprone.xml +++ b/pmd-java/src/main/resources/category/java/errorprone.xml @@ -2349,7 +2349,7 @@ See the property `annotations`. 3 - + + + + #4493:[java]false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject + 0 + + + From add3c461790a1a765dfb839fe1882ab516efe941 Mon Sep 17 00:00:00 2001 From: LynnBroe <109954313+LynnBroe@users.noreply.github.com> Date: Fri, 21 Apr 2023 16:13:29 +0800 Subject: [PATCH 44/63] Update UnnecessaryConstructorRule.java --- .../pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java | 1 - 1 file changed, 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java index 3f14330852..5eebfec8fd 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java @@ -6,7 +6,6 @@ package net.sourceforge.pmd.lang.java.rule.codestyle; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.List; import org.checkerframework.checker.nullness.qual.NonNull; From e899909c3f58428fa92d5c3b8187bd8717eedafe Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 21 Apr 2023 12:08:39 +0200 Subject: [PATCH 45/63] [apex] Fix NcssMethodCount message --- .../pmd/lang/apex/rule/design/NcssMethodCountRule.java | 5 +++++ .../pmd/lang/apex/rule/design/xml/NcssMethodCount.xml | 3 +++ 2 files changed, 8 insertions(+) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java index 15b86516cd..7fc2b60feb 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java @@ -29,4 +29,9 @@ public class NcssMethodCountRule extends AbstractNcssCountRule { protected boolean isIgnored(ASTMethod node) { return node.isConstructor(); } + + @Override + protected Object[] getViolationParameters(ASTMethod node, int metric) { + return new Object[]{ node.getImage(), metric }; + } } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssMethodCount.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssMethodCount.xml index 6562dcb876..fd9f426828 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssMethodCount.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssMethodCount.xml @@ -70,6 +70,9 @@ public class Foo { long method 13 1 + + The method 'foo()' has an NCSS line count of 13 + From 646fb09908a48e8ad2b3ac8128b65192fee71ead Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 21 Apr 2023 14:21:46 +0200 Subject: [PATCH 46/63] [apex] Improve ExcessivePublicCount message and verify inner class behavior. --- .../rule/design/ExcessivePublicCountRule.java | 4 +++ .../main/resources/category/apex/design.xml | 2 +- .../rule/design/xml/ExcessivePublicCount.xml | 25 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java index 5be16d0783..a9893c10e3 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java @@ -52,4 +52,8 @@ public class ExcessivePublicCountRule extends AbstractCounterCheckRule diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessivePublicCount.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessivePublicCount.xml index 45e7fe4a93..87cd272afa 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessivePublicCount.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessivePublicCount.xml @@ -113,4 +113,29 @@ public class SomeClass { } ]]> + + + class with inner classes + 1 + 2 + 1,5 + + The class OuterClass has 2 public methods and attributes + The class InnerClass has 4 public methods and attributes + + + From 3f941449270ab3eb0a2c4297a5dd9091910e757e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sat, 22 Apr 2023 00:59:24 -0300 Subject: [PATCH 47/63] Update changelog, refs #4493 --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 8cde6f0d29..60a87ae042 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -66,6 +66,7 @@ The remaining section describe the complete release notes for 7.0.0. * [#4490](https://github.com/pmd/pmd/issues/4490): \[java] ImmutableField - false negative with Lombok @Getter * java-errorprone * [#4449](https://github.com/pmd/pmd/issues/4449): \[java] AvoidAccessibilityAlteration: Possible false positive in AvoidAccessibilityAlteration rule when using Lambda expression + * [#4493](https://github.com/pmd/pmd/issues/4493): \[java]false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject * java-multithreading * [#4483](https://github.com/pmd/pmd/issues/4483): \[java] NonThreadSafeSingleton false positive with double-checked locking * miscellaneous @@ -76,6 +77,7 @@ The remaining section describe the complete release notes for 7.0.0. * [#4450](https://github.com/pmd/pmd/pull/4450): \[java] Fix #4449 AvoidAccessibilityAlteration: Correctly handle Lambda expressions in PrivilegedAction scenarios - [Seren](https://github.com/mohui1999) (@mohui1999) * [#4452](https://github.com/pmd/pmd/pull/4452): \[doc] Update PMD_APEX_ROOT_DIRECTORY documentation reference - [nwcm](https://github.com/nwcm) (@nwcm) * [#4474](https://github.com/pmd/pmd/pull/4474): \[java] ImmutableField: False positive with lombok (fixes #4254) - [Pim van der Loos](https://github.com/PimvanderLoos) (@PimvanderLoos) +* [#4495](https://github.com/pmd/pmd/pull/4495): \[java] Fix #4493: false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) ### 🚀 Major Features and Enhancements From d5b2abe2c1c51f1e8f77c4216f69d916e409f65a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 22 Apr 2023 09:32:34 +0200 Subject: [PATCH 48/63] [doc] Update release notes Add new issues/PRs to the final 7.0.0 release notes --- docs/pages/release_notes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index eef2496c32..596441e8cf 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -70,7 +70,7 @@ The remaining section describe the complete release notes for 7.0.0. * [#4490](https://github.com/pmd/pmd/issues/4490): \[java] ImmutableField - false negative with Lombok @Getter * java-errorprone * [#4449](https://github.com/pmd/pmd/issues/4449): \[java] AvoidAccessibilityAlteration: Possible false positive in AvoidAccessibilityAlteration rule when using Lambda expression - * [#4493](https://github.com/pmd/pmd/issues/4493): \[java]false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject + * [#4493](https://github.com/pmd/pmd/issues/4493): \[java] MissingStaticMethodInNonInstantiatableClass: false-positive about @Inject * java-multithreading * [#4483](https://github.com/pmd/pmd/issues/4483): \[java] NonThreadSafeSingleton false positive with double-checked locking * miscellaneous @@ -416,6 +416,7 @@ Language specific fixes: * [#3400](https://github.com/pmd/pmd/issues/3400): \[java] AvoidUsingOctalValues FN with underscores * [#4356](https://github.com/pmd/pmd/pull/4356): \[java] Fix NPE in CloseResourceRule * [#4449](https://github.com/pmd/pmd/issues/4449): \[java] AvoidAccessibilityAlteration: Possible false positive in AvoidAccessibilityAlteration rule when using Lambda expression + * [#4493](https://github.com/pmd/pmd/issues/4493): \[java] MissingStaticMethodInNonInstantiatableClass: false-positive about @Inject * java-multithreading * [#2537](https://github.com/pmd/pmd/issues/2537): \[java] DontCallThreadRun can't detect the case that call run() in `this.run()` * [#2538](https://github.com/pmd/pmd/issues/2538): \[java] DontCallThreadRun can't detect the case that call run() in `foo.bar.run()` @@ -451,6 +452,7 @@ Language specific fixes: * [#4450](https://github.com/pmd/pmd/pull/4450): \[java] Fix #4449 AvoidAccessibilityAlteration: Correctly handle Lambda expressions in PrivilegedAction scenarios - [Seren](https://github.com/mohui1999) (@mohui1999) * [#4452](https://github.com/pmd/pmd/pull/4452): \[doc] Update PMD_APEX_ROOT_DIRECTORY documentation reference - [nwcm](https://github.com/nwcm) (@nwcm) * [#4474](https://github.com/pmd/pmd/pull/4474): \[java] ImmutableField: False positive with lombok (fixes #4254) - [Pim van der Loos](https://github.com/PimvanderLoos) (@PimvanderLoos) +* [#4495](https://github.com/pmd/pmd/pull/4495): \[java] Fix #4493: false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) ### 📈 Stats * 4416 commits From 3e9d6081a4f23b866b4112ae995083b9d6ad0a3a Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 22 Apr 2023 09:43:19 +0200 Subject: [PATCH 49/63] [apex] Add limit in ExcessivePublicCount message --- .../apex/rule/design/ExcessivePublicCountRule.java | 4 ++-- .../apex/rule/internal/AbstractCounterCheckRule.java | 10 +++++----- pmd-apex/src/main/resources/category/apex/design.xml | 2 +- .../lang/apex/rule/design/xml/ExcessivePublicCount.xml | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java index a9893c10e3..b833424ced 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/ExcessivePublicCountRule.java @@ -53,7 +53,7 @@ public class ExcessivePublicCountRule extends AbstractCounterCheckRule> extends Ab protected abstract int defaultReportLevel(); - - protected Object[] getViolationParameters(T node, int metric) { - return new Object[] {metric}; + protected Object[] getViolationParameters(T node, int metric, int limit) { + return new Object[] {metric, limit}; } @@ -70,8 +69,9 @@ public abstract class AbstractCounterCheckRule> extends Ab if (!isIgnored(t)) { int metric = getMetric(t); - if (metric >= getProperty(reportLevel)) { - addViolation(data, node, getViolationParameters(t, metric)); + int limit = getProperty(reportLevel); + if (metric >= limit) { + addViolation(data, node, getViolationParameters(t, metric, limit)); } } diff --git a/pmd-apex/src/main/resources/category/apex/design.xml b/pmd-apex/src/main/resources/category/apex/design.xml index e4a1809489..028c0b6528 100644 --- a/pmd-apex/src/main/resources/category/apex/design.xml +++ b/pmd-apex/src/main/resources/category/apex/design.xml @@ -281,7 +281,7 @@ public void addPerson(Date birthdate, BodyMeasurements measurements, int ssn) { diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessivePublicCount.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessivePublicCount.xml index 87cd272afa..b424122e23 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessivePublicCount.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/ExcessivePublicCount.xml @@ -120,8 +120,8 @@ public class SomeClass { 2 1,5 - The class OuterClass has 2 public methods and attributes - The class InnerClass has 4 public methods and attributes + The class OuterClass has 2 public methods and attributes (limit: 1) + The class InnerClass has 4 public methods and attributes (limit: 1) Date: Sat, 22 Apr 2023 10:31:16 +0200 Subject: [PATCH 50/63] [apex] Fix compile errors after merge --- .../pmd/lang/apex/rule/design/NcssMethodCountRule.java | 4 ++-- pmd-apex/src/main/resources/category/apex/design.xml | 2 +- .../pmd/lang/apex/rule/design/xml/NcssMethodCount.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java index 7fc2b60feb..2891dc9235 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/design/NcssMethodCountRule.java @@ -31,7 +31,7 @@ public class NcssMethodCountRule extends AbstractNcssCountRule { } @Override - protected Object[] getViolationParameters(ASTMethod node, int metric) { - return new Object[]{ node.getImage(), metric }; + protected Object[] getViolationParameters(ASTMethod node, int metric, int limit) { + return new Object[]{ node.getImage(), metric, limit }; } } diff --git a/pmd-apex/src/main/resources/category/apex/design.xml b/pmd-apex/src/main/resources/category/apex/design.xml index 028c0b6528..808ceb08b7 100644 --- a/pmd-apex/src/main/resources/category/apex/design.xml +++ b/pmd-apex/src/main/resources/category/apex/design.xml @@ -340,7 +340,7 @@ public class Foo extends Bar { diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssMethodCount.xml b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssMethodCount.xml index fd9f426828..b278b7299b 100644 --- a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssMethodCount.xml +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/rule/design/xml/NcssMethodCount.xml @@ -71,7 +71,7 @@ public class Foo { 13 1 - The method 'foo()' has an NCSS line count of 13 + The method 'foo()' has an NCSS line count of 13 (limit: 13) From d457cce9c53c895ab32568a1c90f1bdb17b5ef42 Mon Sep 17 00:00:00 2001 From: LynnBroe <109954313+LynnBroe@users.noreply.github.com> Date: Sun, 23 Apr 2023 14:28:19 +0800 Subject: [PATCH 51/63] Update UnnecessaryConstructorRule.java --- .../lang/java/rule/codestyle/UnnecessaryConstructorRule.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java index 5eebfec8fd..6eafbbb05a 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryConstructorRule.java @@ -36,7 +36,8 @@ public class UnnecessaryConstructorRule extends AbstractIgnoredAnnotationRule { @Override protected Collection defaultSuppressionAnnotations() { return Arrays.asList("javax.inject.Inject", - "com.google.inject.Inject"); + "com.google.inject.Inject", + "org.springframework.beans.factory.annotation.Autowired"); } @Override From 7034d40cc88d1f24f83740ea3b86b037682e2852 Mon Sep 17 00:00:00 2001 From: LynnBroe <109954313+LynnBroe@users.noreply.github.com> Date: Sun, 23 Apr 2023 14:37:46 +0800 Subject: [PATCH 52/63] Update UnnecessaryConstructor.xml --- .../lang/java/rule/codestyle/xml/UnnecessaryConstructor.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryConstructor.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryConstructor.xml index beb118aa29..a656bfd98c 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryConstructor.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryConstructor.xml @@ -218,12 +218,17 @@ public class Foo { 0 From fa7143b8de967f02ae527c4a159cc379a63d5885 Mon Sep 17 00:00:00 2001 From: LynnBroe <109954313+LynnBroe@users.noreply.github.com> Date: Sun, 23 Apr 2023 15:12:14 +0800 Subject: [PATCH 53/63] add annotations --- .../java/rule/internal/TestFrameworksUtil.java | 15 +++++++++++++-- .../xml/SignatureDeclareThrowsException.xml | 12 ++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java index 08478500ed..7c04bcb6cd 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java @@ -45,6 +45,18 @@ public final class TestFrameworksUtil { "org.testng.Assert", "junit.framework.Assert", "junit.framework.TestCase"); + private static final Set TEST_CONFIGURATION_ANNOTATIONS = + setOf("org.testng.annotations.AfterClass", + "org.testng.annotations.AfterGroups", + "org.testng.annotations.AfterMethod", + "org.testng.annotations.AfterSuite", + "org.testng.annotations.AfterTest", + "org.testng.annotations.BeforeClass", + "org.testng.annotations.BeforeGroups", + "org.testng.annotations.BeforeMethod", + "org.testng.annotations.BeforeSuite", + "org.testng.annotations.BeforeTest" + ); private TestFrameworksUtil() { // utility class @@ -79,8 +91,7 @@ public final class TestFrameworksUtil { || method.isAnnotationPresent("org.junit.BeforeClass") || method.isAnnotationPresent("org.junit.After") || method.isAnnotationPresent("org.junit.AfterClass") - || method.isAnnotationPresent("org.testng.annotations.AfterClass") - || method.isAnnotationPresent("org.testng.annotations.BeforeClass") + || TEST_CONFIGURATION_ANNOTATIONS.stream().anyMatch(method::isAnnotationPresent) || isJUnit3Class(method.getEnclosingType()) && ("setUp".equals(method.getName()) || "tearDown".equals(method.getName())); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SignatureDeclareThrowsException.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SignatureDeclareThrowsException.xml index fab1305cfa..cfe692eaa2 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SignatureDeclareThrowsException.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/SignatureDeclareThrowsException.xml @@ -256,6 +256,18 @@ public final class Namespace { public class WeirdException extends @Weird Exception { } +} + ]]> + + + + #4477:[java] SignatureDeclareThrowsException: false-positive with TestNG annotations + 0 + From ba93312a50c87dd04c8a0e6c7d563c5c3627ce57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sun, 23 Apr 2023 19:00:37 -0300 Subject: [PATCH 54/63] Update changelog, refs #4494 --- docs/pages/release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 8cde6f0d29..845de807f9 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -61,6 +61,7 @@ The remaining section describe the complete release notes for 7.0.0. * [#4438](https://github.com/pmd/pmd/issues/4438): \[doc] Documentation links in VS Code are outdated * java-codestyle * [#4273](https://github.com/pmd/pmd/issues/4273): \[java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default + * [#4487](https://github.com/pmd/pmd/issues/4487): \[java] UnnecessaryConstructor: false-positive with @Inject and @Autowired * java-design * [#4254](https://github.com/pmd/pmd/issues/4254): \[java] ImmutableField - false positive with Lombok @Setter * [#4490](https://github.com/pmd/pmd/issues/4490): \[java] ImmutableField - false negative with Lombok @Getter @@ -76,6 +77,7 @@ The remaining section describe the complete release notes for 7.0.0. * [#4450](https://github.com/pmd/pmd/pull/4450): \[java] Fix #4449 AvoidAccessibilityAlteration: Correctly handle Lambda expressions in PrivilegedAction scenarios - [Seren](https://github.com/mohui1999) (@mohui1999) * [#4452](https://github.com/pmd/pmd/pull/4452): \[doc] Update PMD_APEX_ROOT_DIRECTORY documentation reference - [nwcm](https://github.com/nwcm) (@nwcm) * [#4474](https://github.com/pmd/pmd/pull/4474): \[java] ImmutableField: False positive with lombok (fixes #4254) - [Pim van der Loos](https://github.com/PimvanderLoos) (@PimvanderLoos) +* [#4494](https://github.com/pmd/pmd/pull/4494): \[java] Fix #4487: A false-positive about UnnecessaryConstructor and @Inject and @Autowired - [AnnaDev](https://github.com/LynnBroe) (@AnnaDev) ### 🚀 Major Features and Enhancements From 3c7675ac583afa5e5c20ac48e935006774bfdea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sun, 23 Apr 2023 19:06:27 -0300 Subject: [PATCH 55/63] Simplify check - Move all annotation to the set, not only TestNG's --- .../lang/java/rule/internal/TestFrameworksUtil.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java index 7c04bcb6cd..f3a35f4361 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/TestFrameworksUtil.java @@ -45,8 +45,13 @@ public final class TestFrameworksUtil { "org.testng.Assert", "junit.framework.Assert", "junit.framework.TestCase"); + private static final Set TEST_CONFIGURATION_ANNOTATIONS = - setOf("org.testng.annotations.AfterClass", + setOf("org.junit.Before", + "org.junit.BeforeClass", + "org.junit.After", + "org.junit.AfterClass", + "org.testng.annotations.AfterClass", "org.testng.annotations.AfterGroups", "org.testng.annotations.AfterMethod", "org.testng.annotations.AfterSuite", @@ -87,11 +92,7 @@ public final class TestFrameworksUtil { * Returns true if this is a Before/setUp method or After/tearDown. */ public static boolean isTestConfigurationMethod(ASTMethodDeclaration method) { - return method.isAnnotationPresent("org.junit.Before") - || method.isAnnotationPresent("org.junit.BeforeClass") - || method.isAnnotationPresent("org.junit.After") - || method.isAnnotationPresent("org.junit.AfterClass") - || TEST_CONFIGURATION_ANNOTATIONS.stream().anyMatch(method::isAnnotationPresent) + return TEST_CONFIGURATION_ANNOTATIONS.stream().anyMatch(method::isAnnotationPresent) || isJUnit3Class(method.getEnclosingType()) && ("setUp".equals(method.getName()) || "tearDown".equals(method.getName())); From b077b6658cd42b5b3d759a09364fd57b79195590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Sun, 23 Apr 2023 19:09:49 -0300 Subject: [PATCH 56/63] Update changelog, refs #4488 --- docs/pages/release_notes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index ea7c5ab106..b95813c669 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -58,11 +58,16 @@ The remaining section describe the complete release notes for 7.0.0. * [#4438](https://github.com/pmd/pmd/issues/4438): \[doc] Documentation links in VS Code are outdated * java-codestyle * [#4273](https://github.com/pmd/pmd/issues/4273): \[java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default +* java-design + * [#4477](https://github.com/pmd/pmd/issues/4477): \[java] SignatureDeclareThrowsException: false-positive with TestNG annotations * java-errorprone * [#4449](https://github.com/pmd/pmd/issues/4449): \[java] AvoidAccessibilityAlteration: Possible false positive in AvoidAccessibilityAlteration rule when using Lambda expression * miscellaneous * [#4462](https://github.com/pmd/pmd/issues/4462): Provide Software Bill of Materials (SBOM) +#### External contributions + * [#4488](https://github.com/pmd/pmd/pull/4488): \[java] Fix #4477: A false-positive about SignatureDeclareThrowsException - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) + ### 🚀 Major Features and Enhancements #### New official logo From ff026ce8276fbe2a0ff92d139deba547c700941d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 24 Apr 2023 17:37:27 +0200 Subject: [PATCH 57/63] Fix #4505 --- .../lang/java/rule/internal/DataflowPass.java | 8 +++++-- .../xml/ImplicitSwitchFallThrough.xml | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java index c5c070249a..66741473a1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/internal/DataflowPass.java @@ -36,6 +36,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall; import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTContinueStatement; import net.sourceforge.pmd.lang.java.ast.ASTDoStatement; +import net.sourceforge.pmd.lang.java.ast.ASTEnumConstant; import net.sourceforge.pmd.lang.java.ast.ASTExpression; import net.sourceforge.pmd.lang.java.ast.ASTFieldAccess; import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; @@ -954,6 +955,7 @@ public final class DataflowPass { @Override public SpanInfo visitTypeDecl(ASTAnyTypeDeclaration node, SpanInfo data) { + // process initializers and ctors first processInitializers(node.getDeclarations(), data, node.getSymbol()); for (ASTBodyDeclaration decl : node.getDeclarations()) { @@ -989,12 +991,14 @@ public final class DataflowPass { for (ASTBodyDeclaration declaration : declarations) { final boolean isStatic; - if (declaration instanceof ASTFieldDeclaration) { + if (declaration instanceof ASTEnumConstant) { + isStatic = true; + } else if (declaration instanceof ASTFieldDeclaration) { isStatic = ((ASTFieldDeclaration) declaration).isStatic(); } else if (declaration instanceof ASTInitializer) { isStatic = ((ASTInitializer) declaration).isStatic(); } else if (declaration instanceof ASTConstructorDeclaration - || declaration instanceof ASTCompactConstructorDeclaration) { + || declaration instanceof ASTCompactConstructorDeclaration) { ctors.add(declaration); continue; } else { diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml index 15895fdede..daafe67d26 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml @@ -400,4 +400,25 @@ record MyRecord(boolean b) { } ]]> + + + NPE with Switch in enum constant body + 1 + 7 + + From 6ca8d376b0b04a517e0f73893732ff5df36866c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 24 Apr 2023 17:50:42 +0200 Subject: [PATCH 58/63] Update release notes --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index e0230f5b7e..6ef27859d2 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -421,6 +421,7 @@ Language specific fixes: * [#4356](https://github.com/pmd/pmd/pull/4356): \[java] Fix NPE in CloseResourceRule * [#4449](https://github.com/pmd/pmd/issues/4449): \[java] AvoidAccessibilityAlteration: Possible false positive in AvoidAccessibilityAlteration rule when using Lambda expression * [#4493](https://github.com/pmd/pmd/issues/4493): \[java] MissingStaticMethodInNonInstantiatableClass: false-positive about @Inject + * [#4505](https://github.com/pmd/pmd/issues/4505): \[java] ImplicitSwitchFallThrough NPE in PMD 7.0.0-rc1 * java-multithreading * [#2537](https://github.com/pmd/pmd/issues/2537): \[java] DontCallThreadRun can't detect the case that call run() in `this.run()` * [#2538](https://github.com/pmd/pmd/issues/2538): \[java] DontCallThreadRun can't detect the case that call run() in `foo.bar.run()` From 25c24b2f1bae90921e748160bce392b5cbe258f7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 25 Apr 2023 19:26:49 +0200 Subject: [PATCH 59/63] [doc] Update release notes - make sure that changes listed for rc2 are also listed in the complete release notes - escape annotations to avoid github mentions --- docs/pages/release_notes.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index e0230f5b7e..4317791402 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -65,7 +65,7 @@ The remaining section describe the complete release notes for 7.0.0. * [#4438](https://github.com/pmd/pmd/issues/4438): \[doc] Documentation links in VS Code are outdated * java-codestyle * [#4273](https://github.com/pmd/pmd/issues/4273): \[java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default - * [#4487](https://github.com/pmd/pmd/issues/4487): \[java] UnnecessaryConstructor: false-positive with @Inject and @Autowired + * [#4487](https://github.com/pmd/pmd/issues/4487): \[java] UnnecessaryConstructor: false-positive with @Inject and @Autowired * java-design * [#4254](https://github.com/pmd/pmd/issues/4254): \[java] ImmutableField - false positive with Lombok @Setter * [#4477](https://github.com/pmd/pmd/issues/4477): \[java] SignatureDeclareThrowsException: false-positive with TestNG annotations @@ -84,8 +84,8 @@ The remaining section describe the complete release notes for 7.0.0. * [#4452](https://github.com/pmd/pmd/pull/4452): \[doc] Update PMD_APEX_ROOT_DIRECTORY documentation reference - [nwcm](https://github.com/nwcm) (@nwcm) * [#4474](https://github.com/pmd/pmd/pull/4474): \[java] ImmutableField: False positive with lombok (fixes #4254) - [Pim van der Loos](https://github.com/PimvanderLoos) (@PimvanderLoos) * [#4488](https://github.com/pmd/pmd/pull/4488): \[java] Fix #4477: A false-positive about SignatureDeclareThrowsException - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) -* [#4494](https://github.com/pmd/pmd/pull/4494): \[java] Fix #4487: A false-positive about UnnecessaryConstructor and @Inject and @Autowired - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) -* [#4495](https://github.com/pmd/pmd/pull/4495): \[java] Fix #4493: false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) +* [#4494](https://github.com/pmd/pmd/pull/4494): \[java] Fix #4487: A false-positive about UnnecessaryConstructor and @Inject and @Autowired - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) +* [#4495](https://github.com/pmd/pmd/pull/4495): \[java] Fix #4493: false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) ### 🚀 Major Features and Enhancements @@ -342,7 +342,7 @@ Language specific fixes: * [#1189](https://github.com/pmd/pmd/issues/1189): \[java] UnusedPrivateMethod false positive from inner class via external class * [#1205](https://github.com/pmd/pmd/issues/1205): \[java] Improve ConstantsInInterface message to mention alternatives * [#1212](https://github.com/pmd/pmd/issues/1212): \[java] Don't raise JUnitTestContainsTooManyAsserts on JUnit 5's assertAll - * [#1422](https://github.com/pmd/pmd/issues/1422): \[java] JUnitTestsShouldIncludeAssert false positive with inherited @Rule field + * [#1422](https://github.com/pmd/pmd/issues/1422): \[java] JUnitTestsShouldIncludeAssert false positive with inherited @Rule field * [#1565](https://github.com/pmd/pmd/issues/1565): \[java] JUnitAssertionsShouldIncludeMessage false positive with AssertJ * [#1747](https://github.com/pmd/pmd/issues/1747): \[java] PreserveStackTrace false-positive * [#1969](https://github.com/pmd/pmd/issues/1969): \[java] MissingOverride false-positive triggered by package-private method overwritten in another package by extending class @@ -383,6 +383,7 @@ Language specific fixes: * [#3500](https://github.com/pmd/pmd/pull/3500): \[java] UnnecessaryBoxing - check for Integer.valueOf(String) calls * [#4273](https://github.com/pmd/pmd/issues/4273): \[java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default * [#4357](https://github.com/pmd/pmd/pull/4357): \[java] Fix IllegalStateException in UseDiamondOperator rule + * [#4487](https://github.com/pmd/pmd/issues/4487): \[java] UnnecessaryConstructor: false-positive with @Inject and @Autowired * java-design * [#1014](https://github.com/pmd/pmd/issues/1014): \[java] LawOfDemeter: False positive with lambda expression * [#1605](https://github.com/pmd/pmd/issues/1605): \[java] LawOfDemeter: False positive for standard UTF-8 charset name @@ -397,6 +398,7 @@ Language specific fixes: * [#3786](https://github.com/pmd/pmd/issues/3786): \[java] SimplifyBooleanReturns should consider operator precedence * [#4238](https://github.com/pmd/pmd/pull/4238): \[java] Make LawOfDemeter not use the rulechain * [#4254](https://github.com/pmd/pmd/issues/4254): \[java] ImmutableField - false positive with Lombok @Setter + * [#4477](https://github.com/pmd/pmd/issues/4477): \[java] SignatureDeclareThrowsException: false-positive with TestNG annotations * [#4490](https://github.com/pmd/pmd/issues/4490): \[java] ImmutableField - false negative with Lombok @Getter * java-documentation * [#4369](https://github.com/pmd/pmd/pull/4369): \[java] Improve CommentSize @@ -405,7 +407,7 @@ Language specific fixes: * [#659](https://github.com/pmd/pmd/issues/659): \[java] MissingBreakInSwitch - last default case does not contain a break * [#1005](https://github.com/pmd/pmd/issues/1005): \[java] CloneMethodMustImplementCloneable triggers for interfaces * [#1669](https://github.com/pmd/pmd/issues/1669): \[java] NullAssignment - FP with ternay and null as constructor argument - * [#1899](https://github.com/pmd/pmd/issues/1899): \[java] Recognize @SuppressWanings("fallthrough") for MissingBreakInSwitch + * [#1899](https://github.com/pmd/pmd/issues/1899): \[java] Recognize @SuppressWanings("fallthrough") for MissingBreakInSwitch * [#2320](https://github.com/pmd/pmd/issues/2320): \[java] NullAssignment - FP with ternary and null as method argument * [#2532](https://github.com/pmd/pmd/issues/2532): \[java] AvoidDecimalLiteralsInBigDecimalConstructor can not detect the case `new BigDecimal(Expression)` * [#2579](https://github.com/pmd/pmd/issues/2579): \[java] MissingBreakInSwitch detects the lack of break in the last case @@ -456,7 +458,9 @@ Language specific fixes: * [#4450](https://github.com/pmd/pmd/pull/4450): \[java] Fix #4449 AvoidAccessibilityAlteration: Correctly handle Lambda expressions in PrivilegedAction scenarios - [Seren](https://github.com/mohui1999) (@mohui1999) * [#4452](https://github.com/pmd/pmd/pull/4452): \[doc] Update PMD_APEX_ROOT_DIRECTORY documentation reference - [nwcm](https://github.com/nwcm) (@nwcm) * [#4474](https://github.com/pmd/pmd/pull/4474): \[java] ImmutableField: False positive with lombok (fixes #4254) - [Pim van der Loos](https://github.com/PimvanderLoos) (@PimvanderLoos) -* [#4495](https://github.com/pmd/pmd/pull/4495): \[java] Fix #4493: false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) +* [#4488](https://github.com/pmd/pmd/pull/4488): \[java] Fix #4477: A false-positive about SignatureDeclareThrowsException - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) +* [#4494](https://github.com/pmd/pmd/pull/4494): \[java] Fix #4487: A false-positive about UnnecessaryConstructor and @Inject and @Autowired - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) +* [#4495](https://github.com/pmd/pmd/pull/4495): \[java] Fix #4493: false-positive about MissingStaticMethodInNonInstantiatableClass and @Inject - [AnnaDev](https://github.com/LynnBroe) (@LynnBroe) ### 📈 Stats * 4416 commits From e8d9ec434772415c38df825ae204aca2972d3fa9 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 25 Apr 2023 20:26:38 +0200 Subject: [PATCH 60/63] [doc] Update release notes (#4505) --- docs/pages/release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 6ef27859d2..d999d34d1b 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -73,6 +73,7 @@ The remaining section describe the complete release notes for 7.0.0. * java-errorprone * [#4449](https://github.com/pmd/pmd/issues/4449): \[java] AvoidAccessibilityAlteration: Possible false positive in AvoidAccessibilityAlteration rule when using Lambda expression * [#4493](https://github.com/pmd/pmd/issues/4493): \[java] MissingStaticMethodInNonInstantiatableClass: false-positive about @Inject + * [#4505](https://github.com/pmd/pmd/issues/4505): \[java] ImplicitSwitchFallThrough NPE in PMD 7.0.0-rc1 * java-multithreading * [#4483](https://github.com/pmd/pmd/issues/4483): \[java] NonThreadSafeSingleton false positive with double-checked locking * miscellaneous From 8b5aba41fef84858a839e50c8e2a2d4e675baf2e Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 25 Apr 2023 20:27:39 +0200 Subject: [PATCH 61/63] [java] ImplicitSwitchFallThrough: Update test description --- .../lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml index daafe67d26..16afc0e794 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/errorprone/xml/ImplicitSwitchFallThrough.xml @@ -402,7 +402,7 @@ record MyRecord(boolean b) { - NPE with Switch in enum constant body + #4505 NPE with Switch in enum constant body 1 7 Date: Tue, 25 Apr 2023 21:47:04 +0200 Subject: [PATCH 62/63] Ensure #1563 is fixed Fix #1563 --- docs/pages/release_notes.md | 1 + .../bestpractices/xml/ForLoopCanBeForeach.xml | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 1ef85bfee9..cb1b86e11d 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -344,6 +344,7 @@ Language specific fixes: * [#1205](https://github.com/pmd/pmd/issues/1205): \[java] Improve ConstantsInInterface message to mention alternatives * [#1212](https://github.com/pmd/pmd/issues/1212): \[java] Don't raise JUnitTestContainsTooManyAsserts on JUnit 5's assertAll * [#1422](https://github.com/pmd/pmd/issues/1422): \[java] JUnitTestsShouldIncludeAssert false positive with inherited @Rule field + * [#1563](https://github.com/pmd/pmd/issues/1563): \[java] False positive ForLoopCanBeForeach * [#1565](https://github.com/pmd/pmd/issues/1565): \[java] JUnitAssertionsShouldIncludeMessage false positive with AssertJ * [#1747](https://github.com/pmd/pmd/issues/1747): \[java] PreserveStackTrace false-positive * [#1969](https://github.com/pmd/pmd/issues/1969): \[java] MissingOverride false-positive triggered by package-private method overwritten in another package by extending class diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ForLoopCanBeForeach.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ForLoopCanBeForeach.xml index 3bf4c879d8..263659c9f6 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ForLoopCanBeForeach.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/bestpractices/xml/ForLoopCanBeForeach.xml @@ -409,4 +409,21 @@ public class Test { } ]]> + + #1563 FP with ForLoopCanBeForeach + 0 + mList) { + for (int i = 0; i < mList.size(); i++) { + mList.get(i).setIndex(i); + } + } + interface Foo { + void setIndex(int i); + } + } + ]]> + From c2b18ce229ee4855e09005907db88ec3338361ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Tue, 25 Apr 2023 21:49:36 +0200 Subject: [PATCH 63/63] Ensure #1480 is fixed Fix #1480 --- docs/pages/release_notes.md | 1 + .../codestyle/xml/IdenticalCatchBranches.xml | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index cb1b86e11d..81ac362d84 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -368,6 +368,7 @@ Language specific fixes: * java-codestyle * [#1208](https://github.com/pmd/pmd/issues/1208): \[java] PrematureDeclaration rule false-positive on variable declared to measure time * [#1429](https://github.com/pmd/pmd/issues/1429): \[java] PrematureDeclaration as result of method call (false positive) + * [#1480](https://github.com/pmd/pmd/issues/1480): \[java] IdenticalCatchBranches false positive * [#1673](https://github.com/pmd/pmd/issues/1673): \[java] UselessParentheses false positive with conditional operator * [#1790](https://github.com/pmd/pmd/issues/1790): \[java] UnnecessaryFullyQualifiedName false positive with enum constant * [#1918](https://github.com/pmd/pmd/issues/1918): \[java] UselessParentheses false positive with boolean operators diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml index 44f66afec7..82a3c4d246 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/IdenticalCatchBranches.xml @@ -126,4 +126,23 @@ class Foo { } ]]> + + [java] IdenticalCatchBranches false positive #1480 + 0 + +