Merge branch 'master' into pr-4673

This commit is contained in:
Andreas Dangel
2023-10-26 16:25:34 +02:00
418 changed files with 11056 additions and 3329 deletions

View File

@ -7154,7 +7154,8 @@
"avatar_url": "https://avatars.githubusercontent.com/u/111259588?v=4",
"profile": "https://github.com/nwcm",
"contributions": [
"doc"
"doc",
"bug"
]
},
{
@ -7231,6 +7232,52 @@
"bug",
"code"
]
},
{
"login": "eant60",
"name": "eant60",
"avatar_url": "https://avatars.githubusercontent.com/u/41472980?v=4",
"profile": "https://github.com/eant60",
"contributions": [
"bug"
]
},
{
"login": "Marcono1234",
"name": "Marcono1234",
"avatar_url": "https://avatars.githubusercontent.com/u/11685886?v=4",
"profile": "https://github.com/Marcono1234",
"contributions": [
"bug"
]
},
{
"login": "eugenepugach",
"name": "eugenepugach",
"avatar_url": "https://avatars.githubusercontent.com/u/133967768?v=4",
"profile": "https://github.com/eugenepugach",
"contributions": [
"bug"
]
},
{
"login": "harbulot",
"name": "Bruno Harbulot",
"avatar_url": "https://avatars.githubusercontent.com/u/80994?v=4",
"profile": "http://blog.distributedmatter.net/",
"contributions": [
"bug"
]
},
{
"login": "shai-bennathan",
"name": "Shai Bennathan",
"avatar_url": "https://avatars.githubusercontent.com/u/62336907?v=4",
"profile": "https://github.com/shai-bennathan",
"contributions": [
"bug",
"code"
]
}
],
"contributorsPerLine": 7,

View File

@ -9,7 +9,7 @@ SCRIPT_INCLUDES="log.bash utils.bash setup-secrets.bash openjdk.bash maven.bash
source "$(dirname "$0")/inc/fetch_ci_scripts.bash" && fetch_ci_scripts
function build() {
pmd_ci_log_group_start "Prepare Java 8+11+17, Bundler"
pmd_ci_log_group_start "Prepare Java 8+11+17+21, Bundler"
pmd_ci_openjdk_install_adoptium 11
pmd_ci_openjdk_setdefault 11
PMD_MAVEN_EXTRA_OPTS=()
@ -18,7 +18,13 @@ function build() {
pmd_ci_openjdk_install_adoptium 8
pmd_ci_log_info "Install openjdk17 for integration tests and pmd-regression-tests"
pmd_ci_openjdk_install_adoptium 17
PMD_MAVEN_EXTRA_OPTS=(-Djava8.home="${HOME}/openjdk8" -Djava17.home="${HOME}/openjdk17")
pmd_ci_log_info "Install openjdk21 for integration tests and pmd-regression-tests"
pmd_ci_openjdk_install_adoptium 21
PMD_MAVEN_EXTRA_OPTS=(
-Djava8.home="${HOME}/openjdk8"
-Djava17.home="${HOME}/openjdk17"
-Djava21.home="${HOME}/openjdk21"
)
fi
pmd_ci_build_setup_bundler
pmd_ci_log_group_end
@ -100,7 +106,8 @@ function build() {
pmd_ci_build_and_upload_doc
pmd_ci_log_group_end
if pmd_ci_maven_isReleaseBuild; then
# release is published only for the case b) pmd-cli/pmd-dist release
if pmd_ci_maven_isReleaseBuild && [[ "${PMD_CI_TAG}" == *-dist ]]; then
pmd_ci_log_group_start "Publishing Release"
pmd_ci_gh_releases_publishRelease "$GH_RELEASE"
pmd_ci_sourceforge_selectDefault "${PMD_CI_MAVEN_PROJECT_VERSION}"
@ -108,10 +115,14 @@ function build() {
pmd_ci_log_group_end
fi
# create a baseline for snapshot builds (when pmd-dist is built)
# or for release builds for case b) when pmd-cli/pmd-dist is released
if pmd_ci_maven_isSnapshotBuild || [[ "${PMD_CI_TAG}" == *-dist ]]; then
pmd_ci_log_group_start "Creating new baseline for regression tester"
regression_tester_setup_ci
regression_tester_uploadBaseline
pmd_ci_log_group_end
fi
#
# everything from here runs only on snapshots, not on release builds
@ -130,7 +141,7 @@ function build() {
-Dpmd.skip \
--show-version --errors --batch-mode \
clean package \
sonar:sonar -Dsonar.login="${SONAR_TOKEN}" -Psonar
sonar:sonar -Dsonar.login="${SONAR_TOKEN}" -Psonar,cli-dist
pmd_ci_log_success "New sonar results: https://sonarcloud.io/dashboard?id=net.sourceforge.pmd%3Apmd"
pmd_ci_log_group_end
@ -146,7 +157,7 @@ function build() {
-DrepoToken="${COVERALLS_REPO_TOKEN}" \
--show-version --errors --batch-mode \
clean package jacoco:report \
coveralls:report -Pcoveralls
coveralls:report -Pcoveralls,cli-dist
pmd_ci_log_success "New coveralls result: https://coveralls.io/github/pmd/pmd"
pmd_ci_log_group_end
fi
@ -172,30 +183,58 @@ function pmd_ci_build_run() {
if pmd_ci_maven_isReleaseBuild; then
pmd_ci_log_info "This is a release build"
mvn_profiles="${mvn_profiles},pmd-release"
# There are two possible (release) builds:
if [[ "${PMD_CI_TAG}" != *-dist ]]; then
# a) pmd-core and languages modules
./mvnw clean deploy -P"${mvn_profiles}",'!cli-dist' --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}"
else
# b) pmd-cli and pmd-dist
./mvnw clean deploy -P"${mvn_profiles},cli-dist" -pl pmd-cli,pmd-dist --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}"
fi
else
pmd_ci_log_info "This is a snapshot build"
./mvnw clean deploy -P"${mvn_profiles},cli-dist" --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}"
fi
./mvnw clean deploy -P${mvn_profiles} --show-version --errors --batch-mode "${PMD_MAVEN_EXTRA_OPTS[@]}"
}
#
# Deploys the binary distribution
#
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-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip"
pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.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_isSnapshotBuild; then
# 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-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip"
pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.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"
fi
if pmd_ci_maven_isReleaseBuild; then
# release build case a): only pmd-core and language modules released
if pmd_ci_maven_isReleaseBuild && [[ "${PMD_CI_TAG}" != *-dist ]]; then
# create a draft github release
pmd_ci_gh_releases_createDraftRelease "${PMD_CI_TAG}" "$(git rev-list -n 1 "${PMD_CI_TAG}")"
GH_RELEASE="$RESULT"
fi
# release build case b): pmd-cli and pmd-dist are released
if pmd_ci_maven_isReleaseBuild && [[ "${PMD_CI_TAG}" == *-dist ]]; then
# 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-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip"
pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-src.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"
# draft release has already been created
pmd_ci_gh_releases_getLatestDraftRelease
GH_RELEASE="$RESULT"
# Deploy to github releases
pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "pmd-dist/target/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-bin.zip"
@ -215,7 +254,7 @@ function pmd_ci_build_and_upload_doc() {
pmd_doc_create_archive
pmd_ci_sourceforge_uploadFile "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip"
if pmd_ci_maven_isReleaseBuild; then
if pmd_ci_maven_isReleaseBuild && [[ "${PMD_CI_TAG}" != *-dist ]]; then
pmd_ci_gh_releases_uploadAsset "$GH_RELEASE" "docs/pmd-dist-${PMD_CI_MAVEN_PROJECT_VERSION}-doc.zip"
fi
@ -224,19 +263,21 @@ function pmd_ci_build_and_upload_doc() {
# Deploy javadoc to https://docs.pmd-code.org/apidocs/*/${PMD_CI_MAVEN_PROJECT_VERSION}/
pmd_code_uploadJavadoc "${PMD_CI_MAVEN_PROJECT_VERSION}" "$(pwd)"
# render release notes
# updating github release text
rm -f .bundle/config
bundle config set --local path vendor/bundle
bundle config set --local with release_notes_preprocessing
bundle install
# renders, and skips the first 6 lines - the Jekyll front-matter
local rendered_release_notes
rendered_release_notes=$(bundle exec docs/render_release_notes.rb docs/pages/release_notes.md | tail -n +6)
local release_name
release_name="PMD ${PMD_CI_MAVEN_PROJECT_VERSION} ($(date -u +%d-%B-%Y))"
# Upload to https://sourceforge.net/projects/pmd/files/pmd/${PMD_CI_MAVEN_PROJECT_VERSION}/ReadMe.md
pmd_ci_sourceforge_uploadReleaseNotes "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "${rendered_release_notes}"
if pmd_ci_maven_isSnapshotBuild || [[ "${PMD_CI_TAG}" != *-dist ]]; then
# render release notes
# updating github release text
rm -f .bundle/config
bundle config set --local path vendor/bundle
bundle config set --local with release_notes_preprocessing
bundle install
# renders, and skips the first 6 lines - the Jekyll front-matter
local rendered_release_notes
rendered_release_notes=$(bundle exec docs/render_release_notes.rb docs/pages/release_notes.md | tail -n +6)
local release_name
release_name="PMD ${PMD_CI_MAVEN_PROJECT_VERSION} ($(date -u +%d-%B-%Y))"
# Upload to https://sourceforge.net/projects/pmd/files/pmd/${PMD_CI_MAVEN_PROJECT_VERSION}/ReadMe.md
pmd_ci_sourceforge_uploadReleaseNotes "pmd/${PMD_CI_MAVEN_PROJECT_VERSION}" "${rendered_release_notes}"
fi
if pmd_ci_maven_isSnapshotBuild && [ "${PMD_CI_BRANCH}" = "master" ]; then
# only for snapshot builds from branch master: https://docs.pmd-code.org/snapshot -> pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}
@ -248,7 +289,7 @@ function pmd_ci_build_and_upload_doc() {
pmd_ci_sourceforge_rsyncSnapshotDocumentation "${PMD_CI_MAVEN_PROJECT_VERSION}" "snapshot"
fi
if pmd_ci_maven_isReleaseBuild; then
if pmd_ci_maven_isReleaseBuild && [[ "${PMD_CI_TAG}" != *-dist ]]; then
# documentation is already uploaded to https://docs.pmd-code.org/pmd-doc-${PMD_CI_MAVEN_PROJECT_VERSION}
# we only need to setup symlinks for the released version
pmd_code_createSymlink "${PMD_CI_MAVEN_PROJECT_VERSION}" "latest"

View File

@ -1,4 +1,4 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="All Regression Rules"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"

View File

@ -32,7 +32,7 @@ jobs:
os: [ ubuntu-latest, windows-latest, macos-latest ]
if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 2
- uses: actions/cache@v3
@ -55,7 +55,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/22/scripts" >> $GITHUB_ENV
- name: Check Environment
shell: bash
run: |

View File

@ -17,14 +17,14 @@ jobs:
runs-on: ubuntu-latest
continue-on-error: false
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 100
- name: Setup Environment
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/22/scripts" >> $GITHUB_ENV
- name: Sync
run: .ci/git-repo-sync.sh
shell: bash

View File

@ -15,7 +15,7 @@ jobs:
os: [ ubuntu-latest ]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions/cache@v3
with:
path: |
@ -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/22/scripts" >> $GITHUB_ENV
- name: Check Environment
shell: bash
run: |

View File

@ -1,8 +1,9 @@
GEM
remote: https://rubygems.org/
specs:
addressable (2.8.4)
addressable (2.8.5)
public_suffix (>= 2.0.2, < 6.0)
base64 (0.1.1)
claide (1.1.0)
claide-plugins (0.9.2)
cork
@ -12,23 +13,24 @@ GEM
concurrent-ruby (1.2.2)
cork (0.3.0)
colored2 (~> 3.1)
danger (9.2.0)
danger (9.3.2)
claide (~> 1.0)
claide-plugins (>= 0.9.2)
colored2 (~> 3.1)
cork (~> 0.1)
faraday (>= 0.9.0, < 3.0)
faraday-http-cache (~> 2.0)
git (~> 1.7)
git (~> 1.13)
kramdown (~> 2.3)
kramdown-parser-gfm (~> 1.0)
no_proxy_fix
octokit (~> 5.0)
octokit (~> 6.0)
terminal-table (>= 1, < 4)
differ (0.1.2)
et-orbi (1.2.7)
tzinfo
faraday (2.7.5)
faraday (2.7.11)
base64
faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
faraday-http-cache (2.5.0)
@ -46,13 +48,13 @@ GEM
kramdown (~> 2.0)
liquid (5.4.0)
logger-colors (1.0.0)
mini_portile2 (2.8.2)
mini_portile2 (2.8.4)
nap (1.1.0)
no_proxy_fix (0.1.2)
nokogiri (1.15.2)
nokogiri (1.15.4)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
octokit (5.6.1)
octokit (6.1.1)
faraday (>= 1, < 3)
sawyer (~> 0.9)
open4 (1.3.4)
@ -63,14 +65,14 @@ GEM
nokogiri (~> 1.13)
rufus-scheduler (~> 3.8)
slop (~> 4.9)
public_suffix (5.0.1)
public_suffix (5.0.3)
raabro (1.4.0)
racc (1.6.2)
racc (1.7.1)
rchardet (1.8.0)
rexml (3.2.5)
rouge (4.1.1)
rexml (3.2.6)
rouge (4.1.3)
ruby2_keywords (0.0.5)
rufus-scheduler (3.8.2)
rufus-scheduler (3.9.1)
fugit (~> 1.1, >= 1.1.6)
safe_yaml (1.0.5)
sawyer (0.9.2)

View File

@ -101,8 +101,8 @@ echo " the new release based on the release notes. Also add any deprecated ru
echo
echo "* Update **../pmd.github.io/_config.yml** to mention the new release"
echo
echo "* Update property \`pmd-designer.version\` in **pom.xml** to reference the latest pmd-designer release"
echo " See <https://search.maven.org/search?q=g:net.sourceforge.pmd%20AND%20a:pmd-ui&core=gav> for the available releases."
echo "* Update property \`pmd-designer.version\` in **pom.xml** to reference the version, that will be released"
echo " later in this process."
echo
echo "Press enter to continue..."
read -r
@ -170,8 +170,8 @@ git commit -a -m "Prepare pmd release ${RELEASE_VERSION}"
-DreleaseVersion="${RELEASE_VERSION}" \
-DdevelopmentVersion="${DEVELOPMENT_VERSION}" \
-DscmCommentPrefix="[release] " \
-Pgenerate-rule-docs
-Darguments='-Pgenerate-rule-docs,!cli-dist' \
'-Pgenerate-rule-docs,!cli-dist'
echo
echo "Tag has been pushed.... now check github actions: <https://github.com/pmd/pmd/actions>"
@ -235,14 +235,46 @@ EOF
git commit -a -m "Prepare next development version [skip ci]"
git push origin "${CURRENT_BRANCH}"
./mvnw -B release:clean
echo
echo
echo
echo "* Wait until the new version is synced to maven central and appears as latest version in"
echo " <https://repo.maven.apache.org/maven2/net/sourceforge/pmd/pmd/maven-metadata.xml>."
echo
echo
echo "Then proceed with releasing pmd-designer..."
echo "<https://github.com/pmd/pmd-designer/blob/master/releasing.md>"
echo
echo "Press enter to continue when pmd-designer is available in maven-central..."
echo "<https://repo.maven.apache.org/maven2/net/sourceforge/pmd/pmd-ui/maven-metadata.xml>."
read -r
echo
echo "Continuing with release of pmd-cli and pmd-dist..."
git checkout "pmd_releases/${RELEASE_VERSION}"
./mvnw versions:update-parent -DparentVersion="${RELEASE_VERSION}" -DskipResolution=true -DgenerateBackupPoms=false -pl pmd-cli,pmd-dist
git add pmd-cli/pom.xml pmd-dist/pom.xml
git commit -m "[release] prepare release pmd_releases/${RELEASE_VERSION}-dist"
git tag -m "[release] copy for tag pmd_releases/${RELEASE_VERSION}-dist" "pmd_releases/${RELEASE_VERSION}-dist"
git push origin tag "pmd_releases/${RELEASE_VERSION}-dist"
git checkout master
# make sure parent reference is correct
./mvnw versions:update-parent -DparentVersion="${DEVELOPMENT_VERSION}" -DskipResolution=true -DgenerateBackupPoms=false -pl pmd-cli,pmd-dist
git add pmd-cli/pom.xml pmd-dist/pom.xml
changes=$(git status --porcelain 2>/dev/null | grep -c -E "^[AMDRC]" || true)
if [ "$changes" -gt 0 ]; then
git commit -m "Prepare next development version [skip ci]"
git push origin "${CURRENT_BRANCH}"
fi
echo
echo "Second tag 'pmd_releases/${RELEASE_VERSION}-dist' has been pushed ... now check github actions: <https://github.com/pmd/pmd/actions>"
echo
echo
echo "Verify the new release on github: <https://github.com/pmd/pmd/releases/tag/pmd_releases/${RELEASE_VERSION}>"
echo "and the news entry at <https://sourceforge.net/p/pmd/news/>"
echo
echo "* Wait until the new version is synced to maven central and appears as latest version in"
echo " <https://repo.maven.apache.org/maven2/net/sourceforge/pmd/pmd/maven-metadata.xml>."
echo "* Send out an announcement mail to the mailing list:"
echo
echo "To: PMD Developers List <pmd-devel@lists.sourceforge.net>"

View File

@ -1,19 +1,20 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (7.0.5)
activesupport (7.0.8)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
addressable (2.8.4)
addressable (2.8.5)
public_suffix (>= 2.0.2, < 6.0)
base64 (0.1.1)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.11.1)
colorator (1.1.0)
commonmarker (0.23.9)
commonmarker (0.23.10)
concurrent-ruby (1.2.2)
dnsruby (1.70.0)
simpleidn (~> 0.2.1)
@ -23,12 +24,13 @@ GEM
ethon (0.16.0)
ffi (>= 1.15.0)
eventmachine (1.2.7)
execjs (2.8.1)
faraday (2.7.5)
execjs (2.9.1)
faraday (2.7.11)
base64
faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
faraday-net_http (3.0.2)
ffi (1.15.5)
ffi (1.16.2)
forwardable-extended (2.6.0)
gemoji (3.0.1)
github-pages (228)
@ -86,7 +88,7 @@ GEM
activesupport (>= 2)
nokogiri (>= 1.4)
http_parser.rb (0.8.0)
i18n (1.13.0)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
jekyll (3.9.3)
addressable (~> 2.4)
@ -205,13 +207,13 @@ GEM
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
mini_portile2 (2.8.2)
mini_portile2 (2.8.4)
minima (2.5.1)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.18.0)
nokogiri (1.15.2)
minitest (5.20.0)
nokogiri (1.15.4)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
octokit (4.25.1)
@ -220,11 +222,11 @@ GEM
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (4.0.7)
racc (1.6.2)
racc (1.7.1)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
rexml (3.2.5)
rexml (3.2.6)
rouge (3.26.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)

View File

@ -124,6 +124,9 @@ entries:
- title: PMD Java API
output: web, pdf
url: /pmd_userdocs_tools_java_api.html
- title: bld PMD Extension
output: web, pdf
url: /pmd_userdocs_tools_bld.html
- title: CI integrations
output: web, pdf
url: /pmd_userdocs_tools_ci.html
@ -313,7 +316,7 @@ entries:
- title: null
output: web, pdf
subfolders:
- title: Salesforce VisualForce Rules
- title: Salesforce Visualforce Rules
output: web, pdf
subfolderitems:
- title: Index
@ -349,7 +352,7 @@ entries:
- title: null
output: web, pdf
subfolders:
- title: VM Rules
- title: Velocity Template Language (VTL) Rules
output: web, pdf
subfolderitems:
- title: Index
@ -382,6 +385,9 @@ entries:
- title: Index
output: web, pdf
url: /pmd_rules_xml.html
- title: Best Practices
output: web, pdf
url: /pmd_rules_xml_bestpractices.html
- title: Error Prone
output: web, pdf
url: /pmd_rules_xml_errorprone.html
@ -403,12 +409,41 @@ entries:
- title: Language-Specific Documentation
output: web, pdf
folderitems:
- title: Overview
url: /pmd_languages_index.html
output: web, pdf
- title: Language configuration
url: /pmd_languages_configuration.html
output: web, pdf
- title: Apex
url: /pmd_languages_apex.html
output: web, pdf
- title: C/C++
url: /pmd_languages_cpp.html
output: web, pdf
- title: C#
url: /pmd_languages_cs.html
output: web, pdf
- title: Coco
url: /pmd_languages_coco.html
output: web, pdf
- title: Dart
url: /pmd_languages_dart.html
output: web, pdf
- title: Fortran
url: /pmd_languages_fortran.html
output: web, pdf
- title: Gherkin
url: /pmd_languages_gherkin.html
output: web, pdf
- title: Go
url: /pmd_languages_go.html
output: web, pdf
- title: Groovy
url: /pmd_languages_groovy.html
- title: HTML
url: /pmd_languages_html.html
output: web, pdf
- title: Java
url: /pmd_languages_java.html
output: web, pdf
@ -418,30 +453,57 @@ entries:
- title: JSP
url: /pmd_languages_jsp.html
output: web, pdf
- title: Julia
url: /pmd_languages_julia.html
output: web, pdf
- title: Kotlin
url: /pmd_languages_kotlin.html
output: web, pdf
- title: Lua
url: /pmd_languages_lua.html
output: web, pdf
- title: Matlab
url: /pmd_languages_matlab.html
output: web, pdf
- title: Modelica
url: /pmd_languages_modelica.html
output: web, pdf
- title: Objective-C
url: /pmd_languages_objectivec.html
output: web, pdf
- title: Perl
url: /pmd_languages_perl.html
output: web, pdf
- title: PHP
url: /pmd_languages_php.html
output: web, pdf
- title: PLSQL
url: /pmd_languages_plsql.html
output: web, pdf
- title: Python
url: /pmd_languages_python.html
output: web, pdf
- title: Ruby
url: /pmd_languages_ruby.html
output: web, pdf
- title: Scala
url: /pmd_languages_scala.html
output: web, pdf
- title: Swift
url: /pmd_languages_swift.html
output: web, pdf
- title: T-SQL
url: /pmd_languages_tsql.html
output: web, pdf
- title: Visualforce
url: /pmd_languages_visualforce.html
output: web, pdf
- title: Velocity Template Language (VTL)
url: /pmd_languages_vm.html
output: web, pdf
- title: XML and XML dialects
url: /pmd_languages_xml.html
output: web, pdf
- title: HTML
url: /pmd_languages_html.html
output: web, pdf
- title: Gherkin
url: /pmd_languages_gherkin.html
output: web, pdf
- title: Julia
url: /pmd_languages_julia.html
output: web, pdf
- title: Coco
url: /pmd_languages_coco.html
output: web, pdf
- title: Developer Documentation
output: web, pdf
folderitems:
@ -493,6 +555,9 @@ entries:
- title: Creating (XML) dump of the AST
url: /pmd_devdocs_experimental_ast_dump.html
output: web, pdf
- title: List of experimental Features
url: /tag_experimental.html
output: web, pdf
- title: Project documentation
output: web, pdf
folderitems:

View File

@ -10,3 +10,6 @@ allowed-tags:
- tools # About tools and integrations, Maven, gradle, etc.
- devdocs # About PMD internals, contributing, building, projects
- languages # Language-specific documentation pages
- PmdCapableLanguage
- CpdCapableLanguage
- experimental

View File

@ -0,0 +1,12 @@
<details class="language-info">
<summary>Language Info for {{include.name}}</summary>
<div class="card">
<ul class="list-group list-group-flush">
{% if include.since %}<li class="list-group-item">Since PMD {{include.since}}</li>{% endif %}
<li class="list-group-item">Implementation: {% jdoc include.implementation %}</li>
<li class="list-group-item">Id: {{include.id}}</li>
<li class="list-group-item">PMD: {% if include.supports_pmd %}✔️{% else %}❌{% endif %}</li>
<li class="list-group-item">CPD: {% if include.supports_cpd %}✔️{% else %}❌{% endif %}</li>
</ul>
</div>
</details>

View File

@ -106,16 +106,25 @@ class JavadocTag < Liquid::Tag
def initialize(tag_name, doc_ref, tokens)
super
# sanitize a little
doc_ref.delete! " \"'"
@doc_ref = doc_ref
end
arr = doc_ref.split("#") # split into fqcn + member suffix
def render(var_ctx)
# maybe the parameter is actually a variable - try to resolve it first
if var_ctx.key?(@doc_ref)
@doc_ref = var_ctx[@doc_ref]
end
# sanitize a little
@doc_ref.delete! " \"'"
arr = @doc_ref.split("#") # split into fqcn + member suffix
@type_fqcn = arr[0]
@member_suffix = arr[1] || "" # default to empty string
unless Regexp.new('(!\w*!)?' + Regexp.union(JDocNamespaceDeclaration::NAMESPACED_FQCN_REGEX, JDocNamespaceDeclaration::SYM_REGEX).source ) =~ @type_fqcn
fail "Wrong syntax for type reference, expected eg nspace::a.b.C, !opts!nspace::a.b.C, or :nspace"
fail "Wrong syntax for type reference, expected eg nspace::a.b.C, !opts!nspace::a.b.C, or :nspace, but got \'" + @type_fqcn + "\'"
end
# If no options, then split produces [@type_fqcn]
@ -130,14 +139,11 @@ class JavadocTag < Liquid::Tag
elsif tag_name == "jdoc_old"
@use_previous_api_version = true
end
end
def render(var_ctx)
artifact_name, @type_fqcn = JDocNamespaceDeclaration::parse_fqcn(@type_fqcn, var_ctx)
resolved_type = JavadocTag::fqcn_type(artifact_name, @type_fqcn)
JavadocTag::diagnose(artifact_name, @type_fqcn, @is_package_ref, resolved_type)
diagnose(var_ctx, artifact_name, @type_fqcn, @is_package_ref, resolved_type)
# Expand FQCN of arguments
@member_suffix.gsub!(JDocNamespaceDeclaration::NAMESPACED_FQCN_REGEX) {|fqcn| JDocNamespaceDeclaration::parse_fqcn(fqcn, var_ctx)[1]}
@ -215,15 +221,18 @@ class JavadocTag < Liquid::Tag
BASE_PMD_DIR = File.join(File.expand_path(File.dirname(__FILE__)), "..", "..")
def self.diagnose(artifact_id, fqcn, expect_package, resolved_type)
def diagnose(context, artifact_id, fqcn, expect_package, resolved_type)
tag_name= expect_package ? "jdoc_package" : "jdoc"
# Note: the line numbers don't account for the frontmatter lines
# See https://github.com/jekyll/jekyll/issues/7192 and https://github.com/jekyll/jekyll/pull/9385
location = "#{context['page']['path']}:#{@line_number}+?"
if resolved_type == :package && !expect_package
warn "\e[33;1m#{tag_name} generated link to #{fqcn}, but it was found to be a package name. Did you mean to use jdoc_package instead of jdoc?\e[0m"
warn "\e[33;1m#{location}: #{tag_name} generated link to #{fqcn}, but it was found to be a package name. Did you mean to use jdoc_package instead of jdoc?\e[0m"
elsif resolved_type == :file && expect_package
warn "\e[33;1m#{tag_name} generated link to #{fqcn}, but it was found to be a java file name. Did you mean to use jdoc instead of jdoc_package?\e[0m"
warn "\e[33;1m#{location}: #{tag_name} generated link to #{fqcn}, but it was found to be a java file name. Did you mean to use jdoc instead of jdoc_package?\e[0m"
elsif !resolved_type
warn "\e[33;1m#{tag_name} generated link to #{fqcn}, but the #{expect_package ? "directory" : "source file"} couldn't be found in the source tree of #{artifact_id}\e[0m"
warn "\e[33;1m#{location}: #{tag_name} generated link to #{fqcn}, but the #{expect_package ? "directory" : "source file"} couldn't be found in the source tree of #{artifact_id}\e[0m"
end
end

View File

@ -99,10 +99,11 @@ class JDocNamespaceDeclaration < Liquid::Tag
private
JDOC_NAMESPACE_MAP = "jdoc_nspaces"
RESERVED_NSPACES = ['ant', 'apex', 'cli', 'core', 'cpp', 'cs', 'dart', 'dist', 'doc', 'fortran', 'go', 'groovy', 'java',
'javascript', 'jsp',
RESERVED_NSPACES = ['ant', 'apex', 'cli', 'coco', 'core', 'cpp', 'cs', 'dart', 'dist', 'doc',
'fortran', 'gherkin', 'go', 'groovy', 'html', 'java',
'javascript', 'jsp', 'julia',
'kotlin', 'lang-test', 'lua', 'matlab', 'objectivec', 'perl', 'php', 'plsql', 'python', 'ruby', 'scala', 'swift',
'test', 'test-schema', 'ui',
'test', 'test-schema', 'tsql', 'ui',
'modelica', 'visualforce', 'vm', 'xml'].flat_map {|m| [m, "pmd-" + m]}
def self.make_base_namespaces

View File

@ -1008,8 +1008,11 @@ span.soft {
}
@media (min-height: 600px) and (min-width: 990px) {
/* sticky sidebar for big screens */
#mysidebar {
position: fixed !important;
overflow: scroll;
height: 80%;
}
}
@ -1268,3 +1271,7 @@ h4.panel-title {
a.edit-header {
font-size: 15px;
}
.language-info {
margin: 2em;
}

View File

@ -87,3 +87,10 @@ li.sidebarTitle {
margin-bottom:2.5px;
margin-left:5px;
}
blockquote {
border-left: 5px solid #01c172;
padding: 10px 0 10px 1rem;
margin: 1rem 0;
font-style: italic;
}

View File

@ -142,7 +142,9 @@ definitely don't come for free. It is much effort and requires perseverance to i
* 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
* violation suppression logic
* violation decorators, to add additional language specific information to the created violations
* {% jdoc core::reporting::ViolationDecorator %}s, to add additional language specific information to the
created violations. The [Java language module](pmd_languages_java.html#violation-decorators) uses this to
provide the method name or class name, where the violation occurred.
* metrics
* custom XPath functions
@ -228,3 +230,25 @@ definitely don't come for free. It is much effort and requires perseverance to i
This will load all rulesets and verify, that all required attributes are provided.
*Note:* You'll need to add your ruleset to `categories.properties`, so that it can be found.
### 15. Create documentation page
Finishing up your new language module by adding a page in the documentation. Create a new markdown file
`<langId>.md` in `docs/pages/pmd/languages/`. This file should have the following frontmatter:
```
---
title: <Language Name>
permalink: pmd_languages_<langId>.html
last_updated: <Month> <Year> (<PMD Version>)
tags: [languages, PmdCapableLanguage, CpdCapableLanguage]
---
```
On this page, language specifics can be documented, e.g. when the language was first supported by PMD.
There is also the following Jekyll Include, that creates summary box for the language:
```
{% raw %}
{% include language_info.html name='<Language Name>' id='<langId>' implementation='<langId>::lang.<langId>.<langId>LanguageModule' supports_cpd=true supports_pmd=true %}
{% endraw %}
```

View File

@ -81,7 +81,9 @@ definitely don't come for free. It is much effort and requires perseverance to i
* For a minimal implementation, it just needs to return a parser *(see step #5)*.
* It can be used to provide other features for your language like
* violation suppression logic
* violation decorators, to add additional language specific information to the created violations
* {% jdoc core::reporting::ViolationDecorator %}s, to add additional language specific information to the
created violations. The [Java language module](pmd_languages_java.html#violation-decorators) uses this to
provide the method name or class name, where the violation occurred.
* metrics (see below "Optional features")
* custom XPath functions
* See `VmHandler` class as an example
@ -181,6 +183,29 @@ The Scala module also has a test, written in Kotlin instead of Java:
*Note:* You'll need to add your category ruleset to `categories.properties`, so that it can be found.
### 13. Create documentation page
Finishing up your new language module by adding a page in the documentation. Create a new markdown file
`<langId>.md` in `docs/pages/pmd/languages/`. This file should have the following frontmatter:
```
---
title: <Language Name>
permalink: pmd_languages_<langId>.html
last_updated: <Month> <Year> (<PMD Version>)
tags: [languages, PmdCapableLanguage, CpdCapableLanguage]
---
```
On this page, language specifics can be documented, e.g. when the language was first supported by PMD.
There is also the following Jekyll Include, that creates summary box for the language:
```
{% raw %}
{% include language_info.html name='<Language Name>' id='<langId>' implementation='<langId>::lang.<langId>.<langId>LanguageModule' supports_cpd=true supports_pmd=true %}
{% endraw %}
```
## Debugging with Rule Designer
When implementing your grammar it may be very useful to see how PMD parses your example files.

View File

@ -79,6 +79,27 @@ If your language only supports CPD, then you can subclass {% jdoc core::lang.imp
5. Add some tests for your tokenizer by following the [section below](#testing-your-implementation).
6. Finishing up your new language module by adding a page in the documentation. Create a new markdown file
`<langId>.md` in `docs/pages/pmd/languages/`. This file should have the following frontmatter:
```
---
title: <Language Name>
permalink: pmd_languages_<langId>.html
last_updated: <Month> <Year> (<PMD Version>)
tags: [languages, CpdCapableLanguage]
---
```
On this page, language specifics can be documented, e.g. when the language was first supported by PMD.
There is also the following Jekyll Include, that creates summary box for the language:
```
{% raw %}
{% include language_info.html name='<Language Name>' id='<langId>' implementation='<langId>::lang.<langId>.<langId>LanguageModule' supports_cpd=true %}
{% endraw %}
```
### Declaring tokenizer options
To make the tokenizer configurable, first define some property descriptors using

View File

@ -1,15 +1,40 @@
---
title: Apex support
permalink: pmd_languages_apex.html
last_updated: September 2023 (7.0.0)
author: Clément Fournier
last_updated: March 2021 (7.0.0)
tags: [languages]
tags: [languages, PmdCapableLanguage, CpdCapableLanguage]
summary: "Apex-specific features and guidance"
---
{% include warning.html content="Todo for pmd 7" %}
> [Apex](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dev_guide.htm) is a strongly
> typed, object-oriented programming language that allows developers to execute flow and
> transaction control statements on the Salesforce Platform server, in conjunction with calls to the API.
### Metrics framework
{% include language_info.html name='Apex' id='apex' implementation='apex::lang.apex.ApexLanguageModule' supports_pmd=true supports_cpd=true since='5.5.0' %}
In order to use code metrics in Java, use the metrics constants in {% jdoc apex::lang.apex.metrics.ApexMetrics %},
## Metrics framework
In order to use code metrics in Apex, use the metrics constants in {% jdoc apex::lang.apex.metrics.ApexMetrics %},
together with {% jdoc core::lang.metrics.MetricsUtil %}.
## Multifile Analysis
Integration happens in {% jdoc apex::lang.apex.multifile.ApexMultifileAnalysis %}. It uses
[ApexLink](https://github.com/nawforce/apex-link). For detailed information, see also [Apexlink POC #2830](https://github.com/pmd/pmd/pull/2830).
{% include note.html content="ApexLink's new home: <https://github.com/apex-dev-tools>" %}
Used for rule {% rule apex/design/UnusedMethod %}
## Language Properties
See [Apex language properties](pmd_languages_configuration.html#apex-language-properties)
## Parser
We use Jorje, the Apex parsers that is shipped within the Apex Language Server. This is part of
the [Salesforce Extensions for VS Code](https://github.com/forcedotcom/salesforcedx-vscode).
We take the binary from <https://github.com/forcedotcom/salesforcedx-vscode/tree/develop/packages/salesforcedx-vscode-apex/out>
and provide it as a maven dependency (see [pmd-apex-jorje](https://github.com/pmd/pmd/tree/master/pmd-apex-jorje)).

View File

@ -1,10 +1,15 @@
---
title: Coco
title: Coco support
permalink: pmd_languages_coco.html
last_updated: September 2023 (7.0.0)
tags: [languages, CpdCapableLanguage]
summary: "Coco features and guidance"
---
Coco is a modern programming language designed specifically for building event-driven software.
It is part of the Coco Platform from <https://cocotec.io/>.
> Coco is a modern programming language designed specifically for building event-driven software.
> It is part of the Coco Platform from <https://cocotec.io/>.
{% include language_info.html name='Coco' id='coco' implementation='coco::lang.coco.CocoLanguageModule' supports_cpd=true since='7.0.0' %}
## Support in PMD
Starting from version 7.0.0, Coco support was added to CPD.

View File

@ -0,0 +1,13 @@
---
title: C/C++ support
permalink: pmd_languages_cpp.html
last_updated: September 2023 (7.0.0)
tags: [languages, CpdCapableLanguage]
summary: "C/C++ features and guidance"
---
{% include language_info.html name='C++' id='cpp' implementation='cpp::lang.cpp.CppLanguageModule' supports_cpd=true since='3.5' %}
## Language Properties
See [Cpp language properties](pmd_languages_configuration.html#cpp-language-properties)

View File

@ -0,0 +1,9 @@
---
title: C# support
permalink: pmd_languages_cs.html
last_updated: September 2023 (7.0.0)
tags: [languages, CpdCapableLanguage]
summary: "C#-specific features and guidance"
---
{% include language_info.html name='C#' id='cs' implementation='cs::lang.cs.CsLanguageModule' supports_cpd=true since='4.3' %}

View File

@ -0,0 +1,11 @@
---
title: Dart support
permalink: pmd_languages_dart.html
last_updated: September 2023 (7.0.0)
tags: [languages, CpdCapableLanguage]
summary: "Dart-specific features and guidance"
---
> [Dart](https://dart.dev/) is a client-optimized language for fast apps on any platform.
{% include language_info.html name='Dart' id='dart' implementation='dart::lang.dart.DartLanguageModule' supports_cpd=true since='6.14.0' %}

View File

@ -0,0 +1,9 @@
---
title: Fortran support
permalink: pmd_languages_fortran.html
last_updated: September 2023 (7.0.0)
tags: [languages, CpdCapableLanguage]
summary: "Fortran features and guidance"
---
{% include language_info.html name='Fortran' id='fortran' implementation='fortran::lang.fortran.FortranLanguageModule' supports_cpd=true %}

View File

@ -1,12 +1,17 @@
---
title: Gherkin
title: Gherkin support
permalink: pmd_languages_gherkin.html
last_updated: September 2023 (7.0.0)
tags: [languages, CpdCapableLanguage]
summary: "Gherkin features and guidance"
---
The [Gherkin](https://cucumber.io/docs/gherkin/) language is used to define test cases for the
[Cucumber](https://cucumber.io/) testing tool for behavior-driven development.
The Gherkin syntax is designed to be non-technical, making it human-readable for a wide audience.
{% include language_info.html name='Gherkin' id='gherkin' implementation='gherkin::lang.gherkin.GherkinLanguageModule' supports_cpd=true since='6.48.0' %}
## Support in PMD
Starting from version 6.48.0, Gherkin support was added to CPD.

View File

@ -0,0 +1,11 @@
---
title: Go support
permalink: pmd_languages_go.html
last_updated: September 2023 (7.0.0)
tags: [languages, CpdCapableLanguage]
summary: "Go features and guidance"
---
> [Go](https://golang.org/) is a statically typed, compiled high-level programming language.
{% include language_info.html name='Go' id='go' implementation='go::lang.go.GoLanguageModule' supports_cpd=true since='5.2.0' %}

View File

@ -0,0 +1,13 @@
---
title: Groovy support
permalink: pmd_languages_groovy.html
last_updated: September 2023 (7.0.0)
tags: [languages, CpdCapableLanguage]
summary: "Groovy-specific features and guidance"
---
> [Apache Groovy](https://groovy-lang.org/) is a powerful, optionally typed and dynamic language, with static-typing and
> static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise,
> familiar and easy to learn syntax.
{% include language_info.html name='Groovy' id='groovy' implementation='groovy::lang.groovy.GroovyLanguageModule' supports_cpd=true since='5.5.2' %}

View File

@ -1,24 +1,20 @@
---
title: Processing HTML files
title: HTML support
permalink: pmd_languages_html.html
last_updated: April 2022 (6.45.0)
last_updated: September 2023 (7.0.0)
tags: [languages, PmdCapableLanguage, CpdCapableLanguage, experimental]
summary: "HTML-specific features and guidance"
---
## The HTML language module
**Since:** 6.45.0
**Minimum Java Runtime:** Java 8
{% include language_info.html name='HTML' id='html' implementation='html::lang.html.HtmlLanguageModule' supports_pmd=true supports_cpd=true since='6.45.0' %}
{% include warning.html content="This language module is experimental and may change any time." %}
The HTML language module uses [jsoup](https://jsoup.org/) for parsing.
XPath 2.0 rules are supported, but the DOM is not always a typical XML/XPath DOM.
XPath rules are supported, but the DOM is not always a typical XML/XPath DOM.
In the Designer, text nodes appear as nodes with name "#text", but they can
be selected as usual using `text()`.
XML Namespaces are not supported. The local name of attributes include the prefix,
XML Namespaces are not supported. The local name of attributes includes the prefix,
so that you have to select attributes by e.g. `//*[@*[local-name() = 'if:true']]`.
Only XPath 1.0 rules are not supported.

View File

@ -0,0 +1,9 @@
---
title: Overview
permalink: pmd_languages_index.html
last_updated: September 2023 (7.0.0)
tags: [languages]
---
* [PmdCapableLanguages](tag_PmdCapableLanguage.html)
* [CpdCapableLanguages](tag_CpdCapableLanguage.html)

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