Merge branch 'master' into xpath-seq-attributes

This commit is contained in:
Juan Martín Sotuyo Dodero 2024-04-28 17:39:08 +02:00 committed by GitHub
commit 66606648a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
116 changed files with 3446 additions and 1717 deletions

View File

@ -7462,6 +7462,78 @@
"contributions": [
"bug"
]
},
{
"login": "BurovnikovEvgeniy",
"name": "BurovnikovEvgeniy",
"avatar_url": "https://avatars.githubusercontent.com/u/71849985?v=4",
"profile": "https://github.com/BurovnikovEvgeniy",
"contributions": [
"bug"
]
},
{
"login": "kohlschuetter",
"name": "Dr. Christian Kohlschütter",
"avatar_url": "https://avatars.githubusercontent.com/u/822690?v=4",
"profile": "https://kohlschuetter.github.io/blog/",
"contributions": [
"bug"
]
},
{
"login": "Luro02",
"name": "Lucas",
"avatar_url": "https://avatars.githubusercontent.com/u/24826124?v=4",
"profile": "https://github.com/Luro02",
"contributions": [
"bug"
]
},
{
"login": "rs23",
"name": "Reinhard Schiedermeier",
"avatar_url": "https://avatars.githubusercontent.com/u/12321337?v=4",
"profile": "http://sol.cs.hm.edu/rs",
"contributions": [
"bug"
]
},
{
"login": "andygoossens",
"name": "Andy Goossens",
"avatar_url": "https://avatars.githubusercontent.com/u/2099087?v=4",
"profile": "https://github.com/andygoossens",
"contributions": [
"bug"
]
},
{
"login": "mitchspano",
"name": "Mitch Spano",
"avatar_url": "https://avatars.githubusercontent.com/u/18402464?v=4",
"profile": "https://github.com/mitchspano",
"contributions": [
"bug"
]
},
{
"login": "mfvanek",
"name": "Ivan Vakhrushev",
"avatar_url": "https://avatars.githubusercontent.com/u/37612014?v=4",
"profile": "https://www.linkedin.com/in/mfvanek/",
"contributions": [
"bug"
]
},
{
"login": "VishV-Android",
"name": "Vishv_Android",
"avatar_url": "https://avatars.githubusercontent.com/u/126696109?v=4",
"profile": "https://github.com/VishV-Android",
"contributions": [
"bug"
]
}
],
"contributorsPerLine": 7,

View File

@ -48,6 +48,8 @@ jobs:
~/.cache
~/work/pmd/target/repositories
vendor/bundle
# avoid caching missed dependencies
!~/.m2/repository/**/*.lastUpdated
key: v3-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}
restore-keys: |
v3-${{ runner.os }}-
@ -60,7 +62,7 @@ jobs:
run: |
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DautoReleaseAfterClose=true -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/master/scripts" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/24/scripts" >> $GITHUB_ENV
- name: Check Environment
shell: bash
run: |

View File

@ -24,7 +24,7 @@ jobs:
shell: bash
run: |
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/master/scripts" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/24/scripts" >> $GITHUB_ENV
- name: Sync
run: .ci/git-repo-sync.sh
shell: bash

View File

@ -36,7 +36,7 @@ jobs:
run: |
echo "LANG=en_US.UTF-8" >> $GITHUB_ENV
echo "MAVEN_OPTS=-Daether.connector.http.connectionMaxTtl=180 -DstagingProgressTimeoutMinutes=30" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/master/scripts" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/24/scripts" >> $GITHUB_ENV
- name: Check Environment
shell: bash
run: |

View File

@ -44,7 +44,7 @@ def run_pmdtester
@base_branch = 'master'
@logger.info "\n\n--------------------------------------"
@logger.info "Run against #{@base_branch}"
@summary = PmdTester::Runner.new(get_args(@base_branch, FALSE, 'target/diff1/patch_config.xml')).run
@summary = PmdTester::Runner.new(get_args(@base_branch, false, 'target/diff1/patch_config.xml')).run
# move the generated report out of the way
FileUtils.mv 'target/reports/diff', 'target/diff2'
@ -53,12 +53,12 @@ def run_pmdtester
tar_report
message1 += "[Download full report as build artifact](#{ENV['PMD_CI_JOB_URL']})"
message1 += "[Download full report as build artifact](#{ENV['PMD_CI_JOB_URL']}?pr=#{ENV['PMD_CI_PULL_REQUEST_NUMBER']})"
# set value of sticky to true and the message is kept after new commits are submitted to the PR
message(message1, sticky: true)
if message2
message2 += "[Download full report as build artifact](#{ENV['PMD_CI_JOB_URL']})"
message2 += "[Download full report as build artifact](#{ENV['PMD_CI_JOB_URL']}?pr=#{ENV['PMD_CI_PULL_REQUEST_NUMBER']})"
# set value of sticky to true and the message is kept after new commits are submitted to the PR
message(message2, sticky: true)
end

View File

@ -204,6 +204,7 @@ echo
echo "Tag has been pushed.... now check github actions: <https://github.com/pmd/pmd/actions>"
echo
echo "Now wait, until first stage of the release is finished successfully..."
echo "You don't need to wait until artifacts are in maven central, just the github action must be successful."
echo
echo "If it is failing, you can fix the code/scripts and force push the tag via"
echo
@ -245,9 +246,6 @@ ${NEW_RELEASE_NOTES}
${OLD_RELEASE_NOTES}" > docs/pages/release_notes_old.md
# update release_notes_pmd7 with prerendered version (jdoc tags are replaced with released version)
echo "$RELEASE_NOTES_PMD7" > docs/pages/release_notes_pmd7.md
# reset release notes template
cat > docs/pages/release_notes.md <<EOF
---
@ -348,6 +346,8 @@ tweet="${tweet//$'\r'/}"
tweet="${tweet//$'\n'/%0A}"
echo "* Tweet about this release on https://twitter.com/pmd_analyzer:"
echo " <https://twitter.com/intent/tweet?text=$tweet>"
echo "* Post this also into <https://matrix.to/#/#pmd_pmd:gitter.im>:"
echo " PMD ${RELEASE_VERSION} released: https://github.com/pmd/pmd/releases/tag/pmd_releases/${RELEASE_VERSION} #PMD"
echo
echo
echo "Now waiting for the release to be finished..."

View File

@ -1,9 +1,9 @@
repository: pmd/pmd
pmd:
version: 7.1.0-SNAPSHOT
previous_version: 7.0.0
date: 26-April-2024
version: 7.2.0-SNAPSHOT
previous_version: 7.1.0
date: 31-May-2024
release_type: minor
# release types: major, minor, bugfix

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="300"
height="300"
viewBox="0 0 79.374998 79.375"
version="1.1"
id="svg247"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="PMD_small.svg"
inkscape:export-filename="pmd-logo-small-64px.png"
inkscape:export-xdpi="20.48"
inkscape:export-ydpi="20.48"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview249"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.56819522"
inkscape:cx="-48.398859"
inkscape:cy="568.46659"
inkscape:window-width="1920"
inkscape:window-height="1131"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs244" />
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<path
fill="none"
d="m 178.59473,145.37516 h -6.58813 v 20.98146 h 6.90563 c 5.66208,0 9.81604,-4.2598 9.81604,-10.45105 0.0265,-6.2177 -4.33917,-10.53041 -10.13354,-10.53041 z"
id="path4"
style="stroke-width:0.264583" />
<g
id="g358"
transform="translate(-66.292186,-115.39785)">
<path
fill="#58595b"
d="m 81.968898,178.10412 c -0.132292,-0.82021 -0.291042,-1.64042 -0.291042,-2.46063 -0.02646,-4.65667 0,-9.31333 -0.05292,-13.97 -0.02646,-1.93146 -0.502708,-3.75708 -1.878541,-5.21229 -0.47625,-0.50271 -1.031875,-0.9525 -1.561042,-1.42875 0.529167,-0.47625 1.084792,-0.92604 1.561042,-1.42875 1.375833,-1.45521 1.852083,-3.25438 1.878541,-5.21229 0.05292,-4.65667 0.02646,-9.31334 0.05292,-13.97 0,-0.82021 0.15875,-1.64042 0.291042,-2.46063 0.15875,-1.05833 0.820208,-1.66687 1.852083,-1.79916 h 5.503333 v -5.87375 h -3.783541 c -2.963334,-0.1323 -5.820834,0.26458 -8.281459,2.38125 -2.010833,1.74625 -2.672291,4.10104 -2.725208,6.61458 -0.105833,4.31271 -0.02646,8.62542 -0.07937,12.93812 0,0.9525 -0.105833,1.905 -0.343958,2.83105 -0.02646,0.0794 -0.05292,0.15875 -0.07937,0.23812 -0.3175,0.84667 -0.846667,1.40229 -1.481667,1.79917 -0.3175,0.18521 -0.687916,0.34396 -1.084791,0.44979 -0.343959,0.10583 -0.635,0.15875 -0.846667,0.23812 -0.211667,0.0265 -0.396875,0.0529 -0.582083,0.0794 h -2.248959 v 3.12208 3.12209 H 70.0362 c 0.185208,0.0265 0.370416,0.0265 0.582083,0.0794 0.211667,0.0794 0.47625,0.15875 0.846667,0.23813 0.396875,0.10583 0.767291,0.26458 1.084791,0.44979 0.608542,0.39687 1.164167,0.9525 1.481667,1.79916 0.02646,0.0794 0.05292,0.15875 0.07937,0.23813 0.238125,0.92604 0.343958,1.87854 0.343958,2.83104 0.05292,4.31271 -0.02646,8.62542 0.07937,12.93813 0.05292,2.51354 0.740834,4.86833 2.725208,6.61458 2.460625,2.14312 5.318125,2.51354 8.281459,2.38125 h 3.783541 v -5.87375 h -5.503333 c -1.005417,-0.0265 -1.693333,-0.635 -1.852083,-1.69333 z"
id="path60"
style="stroke-width:0.264583" />
<path
fill="#58595b"
d="m 141.92317,151.96328 c -0.18521,-0.0265 -0.37042,-0.0265 -0.58209,-0.0794 -0.21166,-0.0794 -0.47625,-0.15875 -0.84666,-0.23813 -0.39688,-0.10583 -0.76729,-0.26458 -1.08479,-0.44979 -0.60855,-0.39687 -1.16417,-0.9525 -1.48167,-1.79917 -0.0265,-0.0794 -0.0529,-0.15875 -0.0794,-0.23812 -0.23812,-0.92604 -0.34395,-1.87854 -0.34395,-2.83104 -0.0529,-4.31271 0.0264,-8.62542 -0.0794,-12.93813 -0.0529,-2.51354 -0.74083,-4.86833 -2.72521,-6.61458 -2.46062,-2.14313 -5.31812,-2.51354 -8.28146,-2.38125 H 122.635 v 5.87375 h 5.50334 c 1.03187,0.13229 1.69333,0.74083 1.85208,1.79917 0.13229,0.8202 0.29104,1.64041 0.29104,2.46062 0.0265,4.65667 0,9.31333 0.0529,13.97 0.0265,1.93146 0.50271,3.75708 1.87854,5.21229 0.47625,0.50271 1.03187,0.9525 1.56104,1.42875 -0.52917,0.47625 -1.08479,0.92604 -1.56104,1.42875 -1.37583,1.45521 -1.85208,3.25438 -1.87854,5.21229 -0.0529,4.65667 -0.0265,9.31334 -0.0529,13.97 0,0.82021 -0.15875,1.64042 -0.29104,2.46063 -0.15875,1.05833 -0.82021,1.66687 -1.85208,1.79917 H 122.635 v 5.87375 h 3.78354 c 2.96334,0.13229 5.82084,-0.26459 8.28146,-2.38125 2.01084,-1.74625 2.67229,-4.10105 2.72521,-6.61459 0.10583,-4.31271 0.0265,-8.62541 0.0794,-12.93812 0,-0.9525 0.10583,-1.905 0.34395,-2.83104 0.0265,-0.0794 0.0529,-0.15875 0.0794,-0.23813 0.3175,-0.84667 0.84667,-1.40229 1.48167,-1.79917 0.3175,-0.1852 0.68791,-0.34395 1.08479,-0.44979 0.34396,-0.10583 0.635,-0.15875 0.84666,-0.23812 0.21167,-0.0265 0.39688,-0.0529 0.58209,-0.0794 h 2.24896 v -3.12208 -3.12208 h -2.24896 z"
id="path62"
style="stroke-width:0.264583" />
<g
id="g70"
transform="matrix(0.26458333,0,0,0.26458333,-68.737767,-2.3681738)">
<path
fill="#1dbf73"
d="m 723.3,525.6 c -4,2.2 -7.9,4.7 -11.7,7.2 -7.4,5 -14.1,10.3 -19.8,15.2 -2.7,2.4 -5.2,4.6 -7.4,6.7 -1.1,0.9 -2.1,1.8 -3.1,2.7 -3.4,3 -6.6,6 -9.7,8.8 -17,15.8 -29.2,28.9 -29.2,28.9 l -16,-18 -8,-8.9 -5.7,-6.4 c 0.6,-3.1 2.9,-5.7 5.7,-7.9 1.9,-1.5 4,-2.7 6.1,-3.8 4.1,-2.1 7.7,-3.2 7.7,-3.2 l 2.7,3.2 6.8,7.9 8,9.3 c 2.9,-3 5.8,-5.9 8.6,-8.6 3.2,-3.1 6.4,-6 9.5,-8.6 2.2,-1.9 4.4,-3.8 6.6,-5.5 2.1,-1.6 4.2,-3.1 6.5,-4.6 -7.8,-3.8 -17.6,-5.9 -29,-5.9 H 597.6 V 662 h 28.9 v -36.5 h 25.4 c 32.5,0 51.2,-17.2 51.2,-47 0,-9.9 -2.3,-18.4 -6.7,-25.1 z"
id="path68" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -2,7 +2,7 @@
title: Release process
permalink: pmd_projectdocs_committers_releasing.html
author: Romain Pelisse <rpelisse@users.sourceforge.net>, Andreas Dangel <andreas.dangel@pmd-code.org>
last_updated: April 2021
last_updated: April 2024
---
This page describes the current status of the release process.
@ -72,13 +72,13 @@ in order to release version "6.34.0", the configuration should look like this:
```yaml
pmd:
version: 6.34.0
previous_version: 6.33.0
date: 24-April-2021
version: 7.2.0
previous_version: 7.1.0
date: 31-May-2024
release_type: minor
```
The release type could be one of "bugfix" (e.g. 6.34.x), "minor" (6.x.0), or "major" (x.0.0).
The release type could be one of "bugfix" (e.g. 7.1.x), "minor" (7.x.0), or "major" (x.0.0).
The release notes usually mention any new rules that have been added since the last release.
@ -88,7 +88,7 @@ Add the new rules as comments to the quickstart rulesets:
The designer lives at [pmd/pmd-designer](https://github.com/pmd/pmd-designer).
Update property `pmd-designer.version` in **pom.xml** to reference the new version, that will be released
shortly. Note: This version does at the moment not exist. That means, that a full build of the sources
shortly. Note: This new version does at the moment not exist. That means, that a full build of the sources
will currently fail. That's why the first phase of the release will build only pmd-core and languages but
not pmd-cli and pmd-dist.
@ -97,13 +97,14 @@ Then we can skip the release of pmd-designer and immediately start the second ph
Starting with PMD 6.23.0 we'll provide small statistics for every release. This needs to be added
to the release notes as the last section. To count the closed issues and pull requests, the milestone
on GitHub with the title of the new release is searched. Make sure, there is a milestone
on <https://github.com/pmd/pmd/milestones>. The following snippet will
on GitHub with the title of the new release is searched. It is important, that the due date of the milestone
is correctly set, as the returned milestones in the API call are sorted by due date.
Make sure, there is such a milestone on <https://github.com/pmd/pmd/milestones>. The following snippet will
create the numbers, that can be attached to the release notes as a last section:
```shell
LAST_VERSION=6.33.0
NEW_VERSION=6.34.0
LAST_VERSION=7.1.0
NEW_VERSION=7.2.0
NEW_VERSION_COMMITISH=HEAD
echo "### Stats"
@ -129,14 +130,14 @@ The new version needs to be entered into `_config.yml`, e.g.:
```yaml
pmd:
latestVersion: 6.34.0
latestVersionDate: 24-April-2021
latestVersion: 7.2.0
latestVersionDate: 31-May-2024
```
Also move the previous version down into the "downloads" section. We usually keep only the last 3 versions
in this list, so remove the oldest version.
Then create a new page for the new release, e.g. `_posts/2021-04-24-PMD-6.34.0.md` and copy
Then create a new page for the new release, e.g. `_posts/2024-05-31-PMD-7.2.0.md` and copy
the release notes into this page. This will appear under the news section.
Note: The release notes typically contain some Jekyll macros for linking to the rule pages. These macros won't
@ -164,7 +165,7 @@ Check in all (version, blog post) changes to branch master:
The actual release is done by changing the versions, creating a tag and pushing this tag. Previously this was done
by calling _maven-release-plugin_, but these steps are done without the plugin to have more control. And since we
might reference a not yet released pmd-designer version, the test-build will fail.
might reference a not yet released pmd-designer version, the test-build would fail.
We first change the version of PMD and all modules by basically removing the "-SNAPSHOT" suffix, building the changed
project locally with tests (and with skipping pmd-cli and pmd-dist) in order to be sure, everything is in working
@ -176,8 +177,8 @@ next snapshot version after the release. Skipping the builds of pmd-cli and pmd-
the property `skip-cli-dist`.
```shell
RELEASE_VERSION=6.34.0
DEVELOPMENT_VERSION=6.35.0-SNAPSHOT
RELEASE_VERSION=7.2.0
DEVELOPMENT_VERSION=7.3.0-SNAPSHOT
# Change version in the POMs to ${RELEASE_VERSION} and update build timestamp
./mvnw --quiet versions:set -DnewVersion="${RELEASE_VERSION}" -DgenerateBackupPoms=false -DupdateBuildOutputTimestampPolicy=always
# Transform the SCM information in the POM
@ -218,18 +219,18 @@ Here is, what happens:
* Render the documentation in `docs/` with `bundle exec jekyll build` and create a zip file from it.
* Upload the doc zip file to the current (draft) GitHub Release under <https://github.com/pmd/pmd/releases> and
to <https://sourceforge.net/projects/pmd/files/pmd/>.
* Upload the documentation to <https://docs.pmd-code.org>, e.g. <https://docs.pmd-code.org/pmd-doc-6.34.0/> and
* Upload the documentation to <https://docs.pmd-code.org>, e.g. <https://docs.pmd-code.org/pmd-doc-7.2.0/> and
create a symlink, so that <https://docs.pmd-code.org/latest/> points to the new version.
* Remove the old snapshot documentation, e.g. so that <https://docs.pmd-code.org/pmd-doc-6.34.0-SNAPSHOT/> is gone.
Also create a symlink from pmd-doc-6.34.0-SNAPSHOT to pmd-doc-6.34.0, so that old references still work, e.g.
<https://docs.pmd-code.org/pmd-doc-6.34.0-SNAPSHOT/> points to the released version.
* Remove the old snapshot documentation, e.g. so that <https://docs.pmd-code.org/pmd-doc-7.2.0-SNAPSHOT/> is gone.
Also create a symlink from pmd-doc-7.2.0-SNAPSHOT to pmd-doc-7.2.0, so that old references still work, e.g.
<https://docs.pmd-code.org/pmd-doc-7.2.0-SNAPSHOT/> points to the released version.
* Deploy javadoc to "https://docs.pmd-code.org/apidocs/*/RELEASE_VERSION/", e.g.
<https://docs.pmd-code.org/apidocs/pmd-core/6.34.0/>. This is done for all modules.
* Remove old javadoc for the SNAPSHOT version, e.g. delete <https://docs.pmd-code.org/apidocs/pmd-core/6.34.0-SNAPSHOT/>.
<https://docs.pmd-code.org/apidocs/pmd-core/7.2.0/>. This is done for all modules.
* Remove old javadoc for the SNAPSHOT version, e.g. delete <https://docs.pmd-code.org/apidocs/pmd-core/7.2.0-SNAPSHOT/>.
* Create a draft news post on <https://sourceforge.net/p/pmd/news/> for the new release. This contains the
rendered release notes.
* Copy the documentation to sourceforge's web space, so that it is available as
<https://pmd.sourceforge.io/pmd-6.34.0/>. All previously copied versions are listed
<https://pmd.sourceforge.io/pmd-7.2.0/>. All previously copied versions are listed
under <https://pmd.sourceforge.io/archive.phtml>.
The release on GitHub Actions currently takes about 30-45 minutes. Once this is done, you
@ -271,6 +272,7 @@ Tweet on <https://twitter.com/pmd_analyzer>, eg.:
PMD 6.34.0 released: https://github.com/pmd/pmd/releases/tag/pmd_releases/6.34.0 #PMD
* Post the same twitter message into the gitter chat at <https://matrix.to/#/#pmd_pmd:gitter.im>
### Checklist
@ -289,6 +291,7 @@ Tweet on <https://twitter.com/pmd_analyzer>, eg.:
| regression-tester | New release baseline is uploaded | <https://pmd-code.org/pmd-regression-tester> | <input type="checkbox"> |
| mailing list | announcement on mailing list is sent | <https://sourceforge.net/p/pmd/mailman/pmd-devel/> | <input type="checkbox"> |
| twitter | tweet about the new release | <https://twitter.com/pmd_analyzer> | <input type="checkbox"> |
| gitter | message about the new release | <https://matrix.to/#/#pmd_pmd:gitter.im> | <input type="checkbox"> |
## Prepare the next release
@ -302,9 +305,9 @@ There are a couple of manual steps needed to prepare the current main branch for
```yaml
pmd:
version: 6.35.0-SNAPSHOT
previous_version: 6.34.0
date: ??-??-2021
version: 7.3.0-SNAPSHOT
previous_version: 7.2.0
date: ??-??-2024
release_type: minor
```
@ -329,13 +332,13 @@ This is a {{ site.pmd.release_type }} release.
{% tocmaker %}
### New and noteworthy
### 🚀 New and noteworthy
### Fixed Issues
### 🐛 Fixed Issues
### API Changes
### 🚨 API Changes
### External Contributions
### External Contributions
{% endtocmaker %}
@ -368,15 +371,11 @@ from there. Then merge into the `master` branch and release from there. This way
automatically the latest release on <https://docs.pmd-code.org/latest/> and on sourceforge.
### (Optional) Create a new release branch
### (Optional) Create a new maintenance branch
At some point, it might be time for a new maintenance branch. Such a branch is usually created from
the `master` branch. Here are the steps:
the tag. Here are the steps:
* Create a new branch: `git branch pmd/5.6.x master`
* Update the version in both the new branch and master, e.g. `mvn versions:set -DnewVersion=5.6.1-SNAPSHOT`
and `mvn versions:set -DnewVersion=5.7.0-SNAPSHOT`.
* Update the release notes on both the new branch and master
The maintenance or bugfix branch could also be created later when needed from the actual tag. Then only the version on
the maintenance branch needs to be set.
* Create a new branch: `git branch pmd/7.1.x pmd_releases/7.1.0`
* Update the version in both the new branch, e.g. `mvn versions:set -DnewVersion=7.1.1-SNAPSHOT`.
* Update the release notes on both the new branch

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,13 @@ The following PMD Logos and Icons are licensed under [CC BY 4.0](https://creativ
* [Logo (600px, white)](images/logo/pmd-logo-white-600px.png)
* [Logo (600px, white, suqare shape)](images/logo/pmd-logo-white-600px-squared.png)
* [Favicon (16x16)](images/logo/favicon.ico)
Small variants, square shaped:
* [PMD_small.svg](images/logo/PMD_small.svg)
* [Small Logo (64px, transparent)](images/logo/pmd-logo-small-64px.png)
* [Small Logo (64px, white)](images/logo/pmd-logo-small-white-64px.png)
* [Small Logo (300px, transparent)](images/logo/pmd-logo-small-300px.png)
* [Small Logo (300px, white)](images/logo/pmd-logo-small-white-300px.png)
* [Favicon (32x32)](images/logo/favicon.ico)
This new greenish logo was introduced with PMD 7.

View File

@ -24,70 +24,15 @@ Since this release, PMD will also expose any getter returning a collection of an
/UserClass[@InterfaceNames = 'Queueable']
```
### ✨ New rules
- The new Java rule {%rule java/bestpractices/UnnecessaryVarargsArrayCreation %} reports explicit array creation
when a varargs is expected. This is more heavy to read and could be simplified.
### 🌟 Rule Changes
* {%rule java/bestpractices/JUnitTestsShouldIncludeAssert %} and {% rule java/bestpractices/JUnitTestContainsTooManyAsserts %}
have a new property named `extraAssertMethodNames`. With this property, you can configure which additional static
methods should be considered as valid verification methods. This allows to use custom mocking or assertion libraries.
### 🐛 Fixed Issues
* core
* [#494](https://github.com/pmd/pmd/issues/494): \[core] Adopt JApiCmp to enforce control over API changes
* [#4942](https://github.com/pmd/pmd/issues/4942): \[core] CPD: `--skip-duplicate-files` has no effect (7.0.0 regression)
* [#4959](https://github.com/pmd/pmd/pull/4959): \[core] Upgrade saxon to 12.4
* cli
* [#4791](https://github.com/pmd/pmd/issues/4791): \[cli] Could not find or load main class
* [#4913](https://github.com/pmd/pmd/issues/4913): \[cli] cpd-gui closes immediately
* doc
* [#4901](https://github.com/pmd/pmd/issues/4901): \[doc] Improve documentation on usage of violationSuppressXPath
* apex
* [#4418](https://github.com/pmd/pmd/issues/4418): \[apex] ASTAnnotation.getImage() does not return value as written in the class
* apex-errorprone
* [#3953](https://github.com/pmd/pmd/issues/3953): \[apex] EmptyCatchBlock false positive with formal (doc) comments
* java
* [#4899](https://github.com/pmd/pmd/issues/4899): \[java] Parsing failed in ParseLock#doParse() java.io.IOException: Stream closed
* [#4902](https://github.com/pmd/pmd/issues/4902): \[java] "Bad intersection, unrelated class types" for Constable\[] and Enum\[]
* [#4947](https://github.com/pmd/pmd/issues/4947): \[java] Broken TextBlock parser
* java-bestpractices
* [#1084](https://github.com/pmd/pmd/issues/1084): \[java] Allow JUnitTestsShouldIncludeAssert to configure verification methods
* [#3216](https://github.com/pmd/pmd/issues/3216): \[java] New rule: UnnecessaryVarargsArrayCreation
* [#4435](https://github.com/pmd/pmd/issues/4435): \[java] \[7.0-rc1] UnusedAssignment for used field
* [#4569](https://github.com/pmd/pmd/issues/4569): \[java] ForLoopCanBeForeach reports on loop `for (int i = 0; i < list.size(); i += 2)`
* [#4618](https://github.com/pmd/pmd/issues/4618): \[java] UnusedAssignment false positive with conditional assignments of fields
* java-codestyle
* [#4602](https://github.com/pmd/pmd/issues/4602): \[java] UnnecessaryImport: false positives with static imports
* [#4785](https://github.com/pmd/pmd/issues/4785): \[java] False Positive: PMD Incorrectly report violation for UnnecessaryImport
* [#4779](https://github.com/pmd/pmd/issues/4779): \[java] Examples in documentation of MethodArgumentCanBeFinal do not trigger the rule
* [#4881](https://github.com/pmd/pmd/issues/4881): \[java] ClassNamingConventions: interfaces are identified as abstract classes (regression in 7.0.0)
* java-design
* [#2440](https://github.com/pmd/pmd/issues/2440): \[java] FinalFieldCouldBeStatic FN when the right side of the assignment is a constant expression
* [#3694](https://github.com/pmd/pmd/issues/3694): \[java] SingularField ignores static variables
* [#4873](https://github.com/pmd/pmd/issues/4873): \[java] AvoidCatchingGenericException: Can no longer suppress on the exception itself
* java-errorprone
* [#2056](https://github.com/pmd/pmd/issues/2056): \[java] CloseResource false-positive with URLClassLoader in cast expression
* [#4928](https://github.com/pmd/pmd/issues/4928): \[java] EmptyCatchBlock false negative when allowCommentedBlocks=true
* java-performance
* [#3845](https://github.com/pmd/pmd/issues/3845): \[java] InsufficientStringBufferDeclaration should consider literal expression
* [#4874](https://github.com/pmd/pmd/issues/4874): \[java] StringInstantiation: False-positive when using `new String(charArray)`
* [#4886](https://github.com/pmd/pmd/issues/4886): \[java] BigIntegerInstantiation: False Positive with Java 17 and BigDecimal.TWO
* pom-errorprone
* [#4388](https://github.com/pmd/pmd/issues/4388): \[pom] InvalidDependencyTypes doesn't consider dependencies at all
* [#4278](https://github.com/pmd/pmd/issues/4278): \[java] UnusedPrivateMethod FP with Junit 5 @MethodSource and default factory method name
* [#4975](https://github.com/pmd/pmd/issues/4975): \[java] UnusedPrivateMethod false positive when using @MethodSource on a @Nested test
### 🚨 API Changes
#### Deprecated methods
* {%jdoc java::lang.java.rule.design.SingularFieldRule#mayBeSingular(java::lang.java.ast.ModifierOwner) %} has been deprecated for
removal. The method is only useful for the rule itself and shouldn't be used otherwise.
### ✨ External Contributions
* [#4864](https://github.com/pmd/pmd/pull/4864): Fix #1084 \[Java] add extra assert method names to Junit rules - [Erwan Moutymbo](https://github.com/emouty) (@emouty)
* [#4894](https://github.com/pmd/pmd/pull/4894): Fix #4791 Error caused by space in JDK path - [Scrates1](https://github.com/Scrates1) (@Scrates1)
{% endtocmaker %}

View File

@ -5,6 +5,113 @@ permalink: pmd_release_notes_old.html
Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](https://github.com/pmd/pmd/releases)
## 26-April-2024 - 7.1.0
The PMD team is pleased to announce PMD 7.1.0.
This is a minor release.
### Table Of Contents
* [🚀 New and noteworthy](#new-and-noteworthy)
* [More robust CPD reports](#more-robust-cpd-reports)
* [✨ New Rules](#new-rules)
* [🌟 Rule Changes](#rule-changes)
* [🐛 Fixed Issues](#fixed-issues)
* [🚨 API Changes](#api-changes)
* [Deprecated methods](#deprecated-methods)
* [✨ External Contributions](#external-contributions)
* [📈 Stats](#stats)
### 🚀 New and noteworthy
#### More robust CPD reports
There were a number of circumstances, specially around (but not limited to) literal sequences, were CPD would
report duplicate overlapping or partially overlapping matches. These have now been fixed, and CPD will report
only the longest non-overlapping duplicate.
These improvements apply to all supported languages, irrespective of supported flags.
#### ✨ New Rules
- The new Java rule [`UnnecessaryVarargsArrayCreation`](https://docs.pmd-code.org/pmd-doc-7.1.0/pmd_rules_java_bestpractices.html#unnecessaryvarargsarraycreation) reports explicit array creation
when a varargs is expected. This is more heavy to read and could be simplified.
- The new Java rule [`ConfusingArgumentToVarargsMethod`](https://docs.pmd-code.org/pmd-doc-7.1.0/pmd_rules_java_errorprone.html#confusingargumenttovarargsmethod) reports some confusing situations
where a varargs method is called with an inexact argument type. These may end up in a mismatch between the expected
parameter type and the actual value.
- The new Java rule [`LambdaCanBeMethodReference`](https://docs.pmd-code.org/pmd-doc-7.1.0/pmd_rules_java_codestyle.html#lambdacanbemethodreference) reports lambda expressions that can be replaced
with a method reference. Please read the documentation of the rule for more info. This rule is now part of the Quickstart
ruleset.
#### 🌟 Rule Changes
* [`JUnitTestsShouldIncludeAssert`](https://docs.pmd-code.org/pmd-doc-7.1.0/pmd_rules_java_bestpractices.html#junittestsshouldincludeassert) and [`JUnitTestContainsTooManyAsserts`](https://docs.pmd-code.org/pmd-doc-7.1.0/pmd_rules_java_bestpractices.html#junittestcontainstoomanyasserts)
have a new property named `extraAssertMethodNames`. With this property, you can configure which additional static
methods should be considered as valid verification methods. This allows to use custom mocking or assertion libraries.
### 🐛 Fixed Issues
* core
* [#494](https://github.com/pmd/pmd/issues/494): \[core] Adopt JApiCmp to enforce control over API changes
* [#4942](https://github.com/pmd/pmd/issues/4942): \[core] CPD: `--skip-duplicate-files` has no effect (7.0.0 regression)
* [#4959](https://github.com/pmd/pmd/pull/4959): \[core] Upgrade saxon to 12.4
* cli
* [#4791](https://github.com/pmd/pmd/issues/4791): \[cli] Could not find or load main class
* [#4913](https://github.com/pmd/pmd/issues/4913): \[cli] cpd-gui closes immediately
* doc
* [#4901](https://github.com/pmd/pmd/issues/4901): \[doc] Improve documentation on usage of violationSuppressXPath
* apex
* [#4418](https://github.com/pmd/pmd/issues/4418): \[apex] ASTAnnotation.getImage() does not return value as written in the class
* apex-errorprone
* [#3953](https://github.com/pmd/pmd/issues/3953): \[apex] EmptyCatchBlock false positive with formal (doc) comments
* cpp
* [#2438](https://github.com/pmd/pmd/issues/2438): \[cpp] Repeated Duplication blocks
* java
* [#4899](https://github.com/pmd/pmd/issues/4899): \[java] Parsing failed in ParseLock#doParse() java.io.IOException: Stream closed
* [#4902](https://github.com/pmd/pmd/issues/4902): \[java] "Bad intersection, unrelated class types" for Constable\[] and Enum\[]
* [#4947](https://github.com/pmd/pmd/issues/4947): \[java] Broken TextBlock parser
* java-bestpractices
* [#1084](https://github.com/pmd/pmd/issues/1084): \[java] Allow JUnitTestsShouldIncludeAssert to configure verification methods
* [#3216](https://github.com/pmd/pmd/issues/3216): \[java] New rule: UnnecessaryVarargsArrayCreation
* [#4435](https://github.com/pmd/pmd/issues/4435): \[java] \[7.0-rc1] UnusedAssignment for used field
* [#4569](https://github.com/pmd/pmd/issues/4569): \[java] ForLoopCanBeForeach reports on loop `for (int i = 0; i < list.size(); i += 2)`
* [#4618](https://github.com/pmd/pmd/issues/4618): \[java] UnusedAssignment false positive with conditional assignments of fields
* java-codestyle
* [#4602](https://github.com/pmd/pmd/issues/4602): \[java] UnnecessaryImport: false positives with static imports
* [#4785](https://github.com/pmd/pmd/issues/4785): \[java] False Positive: PMD Incorrectly report violation for UnnecessaryImport
* [#4779](https://github.com/pmd/pmd/issues/4779): \[java] Examples in documentation of MethodArgumentCanBeFinal do not trigger the rule
* [#4881](https://github.com/pmd/pmd/issues/4881): \[java] ClassNamingConventions: interfaces are identified as abstract classes (regression in 7.0.0)
* java-design
* [#2440](https://github.com/pmd/pmd/issues/2440): \[java] FinalFieldCouldBeStatic FN when the right side of the assignment is a constant expression
* [#3694](https://github.com/pmd/pmd/issues/3694): \[java] SingularField ignores static variables
* [#4873](https://github.com/pmd/pmd/issues/4873): \[java] AvoidCatchingGenericException: Can no longer suppress on the exception itself
* java-errorprone
* [#2056](https://github.com/pmd/pmd/issues/2056): \[java] CloseResource false-positive with URLClassLoader in cast expression
* [#4751](https://github.com/pmd/pmd/issues/4751): \[java] PMD crashes when analyzing CloseResource Rule
* [#4928](https://github.com/pmd/pmd/issues/4928): \[java] EmptyCatchBlock false negative when allowCommentedBlocks=true
* [#4948](https://github.com/pmd/pmd/issues/4948): \[java] ImplicitSwitchFallThrough: False-positive with nested switch statements
* java-performance
* [#3845](https://github.com/pmd/pmd/issues/3845): \[java] InsufficientStringBufferDeclaration should consider literal expression
* [#4874](https://github.com/pmd/pmd/issues/4874): \[java] StringInstantiation: False-positive when using `new String(charArray)`
* [#4886](https://github.com/pmd/pmd/issues/4886): \[java] BigIntegerInstantiation: False Positive with Java 17 and BigDecimal.TWO
* pom-errorprone
* [#4388](https://github.com/pmd/pmd/issues/4388): \[pom] InvalidDependencyTypes doesn't consider dependencies at all
* misc
* [#4967](https://github.com/pmd/pmd/pull/4967): Fix reproducible build issues with 7.0.0
### 🚨 API Changes
#### Deprecated methods
* pmd-java
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.1.0/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpression.html#getBlock()"><code>ASTLambdaExpression#getBlock</code></a> and <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.1.0/net/sourceforge/pmd/lang/java/ast/ASTLambdaExpression.html#getExpression()"><code>ASTLambdaExpression#getExpression</code></a>
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.1.0/net/sourceforge/pmd/lang/java/rule/design/SingularFieldRule.html#mayBeSingular(net.sourceforge.pmd.lang.java.ast.ModifierOwner)"><code>SingularFieldRule#mayBeSingular</code></a> has been deprecated for
removal. The method is only useful for the rule itself and shouldn't be used otherwise.
### ✨ External Contributions
* [#4864](https://github.com/pmd/pmd/pull/4864): Fix #1084 \[Java] add extra assert method names to Junit rules - [Erwan Moutymbo](https://github.com/emouty) (@emouty)
* [#4894](https://github.com/pmd/pmd/pull/4894): Fix #4791 Error caused by space in JDK path - [Scrates1](https://github.com/Scrates1) (@Scrates1)
### 📈 Stats
* 205 commits
* 71 closed tickets & PRs
* Days since last release: 34
## 22-March-2024 - 7.0.0

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
<parent>
<artifactId>pmd</artifactId>
<groupId>net.sourceforge.pmd</groupId>
<version>7.1.0-SNAPSHOT</version>
<version>7.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>7.1.0-SNAPSHOT</version>
<version>7.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -75,7 +75,7 @@ public class CognitiveComplexityRule extends AbstractApexRule {
String.valueOf(classLevelThreshold),
};
asCtx(data).addViolation(node, messageParams);
asCtx(data).addViolation(node, (Object[]) messageParams);
}
}
return data;

View File

@ -78,7 +78,7 @@ public class CyclomaticComplexityRule extends AbstractApexRule {
" total",
classWmc + " (highest " + classHighest + ")", };
asCtx(data).addViolation(node, messageParams);
asCtx(data).addViolation(node, (Object[]) messageParams);
}
}
return data;

View File

@ -7,7 +7,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>7.1.0-SNAPSHOT</version>
<version>7.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>7.1.0-SNAPSHOT</version>
<version>7.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>7.1.0-SNAPSHOT</version>
<version>7.2.0-SNAPSHOT</version>
</parent>
<artifactId>pmd-compat6</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>7.1.0-SNAPSHOT</version>
<version>7.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -5,14 +5,20 @@
package net.sourceforge.pmd.cpd;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
class MatchCollector {
private final List<Match> matchList = new ArrayList<>();
private final Map<Integer, Map<Integer, Match>> matchTree = new TreeMap<>();
private final Map<Integer, List<Match>> matchTree = new TreeMap<>();
private final Map<Integer, Set<Integer>> tokenMatchSets = new HashMap<>();
private final MatchAlgorithm ma;
MatchCollector(MatchAlgorithm ma) {
@ -21,12 +27,18 @@ class MatchCollector {
public void collect(List<TokenEntry> marks) {
// first get a pairwise collection of all maximal matches
for (int i = 0; i < marks.size() - 1; i++) {
int skipped;
for (int i = 0; i < marks.size() - 1; i += skipped + 1) {
skipped = 0;
TokenEntry mark1 = marks.get(i);
for (int j = i + 1; j < marks.size(); j++) {
TokenEntry mark2 = marks.get(j);
int diff = mark1.getIndex() - mark2.getIndex();
if (-diff < ma.getMinimumTileSize()) {
// self-repeating sequence such as ABBABBABB with min 6,
// will match 2 against any other occurrence of ABBABB
// avoid duplicate overlapping reports by skipping it on the next outer loop
skipped++;
continue;
}
if (hasPreviousDupe(mark1, mark2)) {
@ -38,7 +50,7 @@ class MatchCollector {
if (dupes < ma.getMinimumTileSize()) {
continue;
}
// is it still too close together
// both blocks overlap
if (diff + dupes >= 1) {
continue;
}
@ -48,37 +60,71 @@ class MatchCollector {
}
private void reportMatch(TokenEntry mark1, TokenEntry mark2, int dupes) {
matchTree.compute(dupes, (dupCount, matches) -> {
if (matches == null) {
matches = new TreeMap<>();
addNewMatch(mark1, mark2, dupCount, matches);
} else {
Match matchA = matches.get(mark1.getIndex());
Match matchB = matches.get(mark2.getIndex());
/*
* Check if the match is previously know. This can happen when a snippet is duplicated more than once.
* If A, B and C are identical snippets, MatchAlgorithm will find the matching pairs:
* - AB
* - AC
* - BC
* It should be reduced to a single match with 3 marks
*/
if (tokenMatchSets.computeIfAbsent(mark1.getIndex(), HashSet::new).contains(mark2.getIndex())) {
return;
}
if (matchA == null && matchB == null) {
addNewMatch(mark1, mark2, dupes, matches);
} else if (matchA == null) {
matchB.addMark(mark1);
matches.put(mark1.getIndex(), matchB);
} else if (matchB == null) {
matchA.addMark(mark2);
matches.put(mark2.getIndex(), matchA);
// This may not be a "new match", but actually a sub-match of a larger one.
// always rely on the lowest mark index, as that's the order in which process them
final int lowestKey = tokenMatchSets.get(mark1.getIndex()).stream().reduce(mark1.getIndex(), Math::min);
List<Match> matches = matchTree.computeIfAbsent(lowestKey, ArrayList::new);
Iterator<Match> matchIterator = matches.iterator();
while (matchIterator.hasNext()) {
Match m = matchIterator.next();
// Check all other marks
for (Mark otherMark : m.getMarkSet()) {
TokenEntry otherEnd = otherMark.getToken();
if (otherEnd.getIndex() == mark1.getIndex()) {
continue;
}
// does the new match supersedes this one?
if (otherEnd.getIndex() < mark2.getIndex() && otherEnd.getIndex() + m.getTokenCount() >= mark2.getIndex() + dupes) {
// this match is embedded in the previous one ignore it.
return;
} else if (mark2.getIndex() < otherEnd.getIndex() && mark2.getIndex() + dupes >= otherEnd.getIndex() + m.getTokenCount()) {
// the new match is longer and overlaps with the old one - replace it
matchIterator.remove();
break;
} else if (dupes == m.getTokenCount()) {
// we found yet another exact match of the same snippet. Roll it together
// Add this adjacency to all combinations
m.iterator().forEachRemaining(other -> registerTokenMatch(other.getToken(), mark2));
m.addMark(mark2);
return;
}
}
return matches;
});
}
// this is a new match, add it
matches.add(new Match(dupes, mark1, mark2));
// add matches in both directions
registerTokenMatch(mark1, mark2);
}
private void addNewMatch(TokenEntry mark1, TokenEntry mark2, int dupes, Map<Integer, Match> matches) {
Match match = new Match(dupes, mark1, mark2);
matches.put(mark1.getIndex(), match);
matches.put(mark2.getIndex(), match);
matchList.add(match);
private void registerTokenMatch(TokenEntry mark1, TokenEntry mark2) {
tokenMatchSets.computeIfAbsent(mark1.getIndex(), HashSet::new).add(mark2.getIndex());
tokenMatchSets.computeIfAbsent(mark2.getIndex(), HashSet::new).add(mark1.getIndex());
}
List<Match> getMatches() {
return matchList;
return matchTree.values().stream().reduce(new ArrayList<>(), (acc, matches) -> {
acc.addAll(matches);
return acc;
});
}
private boolean hasPreviousDupe(TokenEntry mark1, TokenEntry mark2) {

View File

@ -5,6 +5,7 @@
package net.sourceforge.pmd.lang.rule.xpath.internal;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
@ -105,16 +106,15 @@ abstract class BaseNodeInfo extends AbstractNodeWrapper implements SiblingCounti
return iterateList(nodes, true);
}
@SuppressWarnings({"unchecked", "rawtypes"})
static AxisIterator iterateList(List<? extends NodeInfo> nodes, boolean forwards) {
return forwards ? new NodeListIterator((List<NodeInfo>) nodes)
: new RevListAxisIterator((List<NodeInfo>) nodes);
static <N extends NodeInfo> AxisIterator iterateList(List<N> nodes, boolean forwards) {
return forwards ? new NodeListIterator(Collections.unmodifiableList(nodes))
: new RevListAxisIterator<>(nodes);
}
private static class RevListAxisIterator implements AxisIterator {
private final ListIterator<NodeInfo> iter;
private static class RevListAxisIterator<N extends NodeInfo> implements AxisIterator {
private final ListIterator<N> iter;
RevListAxisIterator(List<NodeInfo> list) {
RevListAxisIterator(List<N> list) {
iter = list.listIterator(list.size());
}

View File

@ -662,6 +662,18 @@ public final class CollectionUtil {
}
}
/**
* Union of two PSets, which avoids creating a new pset if possible.
*/
public static <V> PSet<V> union(PSet<V> as, PSet<V> bs) {
if (as.isEmpty()) {
return bs;
} else if (bs.isEmpty()) {
return as;
}
return as.plusAll(bs);
}
public static @NonNull <T> List<T> makeUnmodifiableAndNonNull(@Nullable List<? extends T> list) {
if (list instanceof PSequence) {
return (List<T>) list;

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