Merge branch 'master' into cpd-report-processing-errors

This commit is contained in:
Andreas Dangel
2024-06-21 19:30:35 +02:00
319 changed files with 8113 additions and 6691 deletions

View File

@ -7071,7 +7071,8 @@
"avatar_url": "https://avatars.githubusercontent.com/u/26581168?v=4",
"profile": "https://github.com/mluckam",
"contributions": [
"code"
"code",
"bug"
]
},
{
@ -7534,6 +7535,61 @@
"contributions": [
"bug"
]
},
{
"login": "cowwoc",
"name": "Gili Tzabari",
"avatar_url": "https://avatars.githubusercontent.com/u/633348?v=4",
"profile": "https://github.com/cowwoc",
"contributions": [
"bug"
]
},
{
"login": "bobalicious",
"name": "Rob Baillie",
"avatar_url": "https://avatars.githubusercontent.com/u/6523911?v=4",
"profile": "http://robertbaillie.blogspot.co.uk/",
"contributions": [
"bug"
]
},
{
"login": "mdagcilar",
"name": "Metin Dagcilar",
"avatar_url": "https://avatars.githubusercontent.com/u/6627550?v=4",
"profile": "https://github.com/mdagcilar",
"contributions": [
"bug"
]
},
{
"login": "kesslerj",
"name": "Jonas Keßler",
"avatar_url": "https://avatars.githubusercontent.com/u/25590499?v=4",
"profile": "https://github.com/kesslerj",
"contributions": [
"bug"
]
},
{
"login": "Gold856",
"name": "Gold856",
"avatar_url": "https://avatars.githubusercontent.com/u/117957790?v=4",
"profile": "https://github.com/Gold856",
"contributions": [
"bug",
"code"
]
},
{
"login": "anuragagarwal561994",
"name": "Anurag Agarwal",
"avatar_url": "https://avatars.githubusercontent.com/u/6075379?v=4",
"profile": "https://github.com/anuragagarwal561994",
"contributions": [
"bug"
]
}
],
"contributorsPerLine": 7,

View File

@ -62,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/24/scripts" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/master/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/24/scripts" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/master/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/24/scripts" >> $GITHUB_ENV
echo "PMD_CI_SCRIPTS_URL=https://raw.githubusercontent.com/pmd/build-tools/master/scripts" >> $GITHUB_ENV
- name: Check Environment
shell: bash
run: |

View File

@ -4,7 +4,7 @@ GEM
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
base64 (0.2.0)
bigdecimal (3.1.6)
bigdecimal (3.1.8)
claide (1.1.0)
claide-plugins (0.9.2)
cork
@ -28,7 +28,7 @@ GEM
octokit (>= 4.0)
terminal-table (>= 1, < 4)
differ (0.1.2)
et-orbi (1.2.8)
et-orbi (1.2.11)
tzinfo
faraday (2.9.0)
faraday-net_http (>= 2.0, < 3.2)
@ -36,8 +36,8 @@ GEM
faraday (>= 0.8)
faraday-net_http (3.1.0)
net-http
fugit (1.10.1)
et-orbi (~> 1, >= 1.2.7)
fugit (1.11.0)
et-orbi (~> 1, >= 1.2.11)
raabro (~> 1.4)
git (1.19.1)
addressable (~> 2.8)
@ -46,13 +46,13 @@ GEM
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (5.4.0)
liquid (5.5.0)
logger-colors (1.0.0)
nap (1.1.0)
net-http (0.4.1)
uri
no_proxy_fix (0.1.2)
nokogiri (1.16.2-x86_64-linux)
nokogiri (1.16.5-x86_64-linux)
racc (~> 1.4)
octokit (8.1.0)
base64
@ -66,12 +66,13 @@ GEM
nokogiri (~> 1.13)
rufus-scheduler (~> 3.8)
slop (~> 4.9)
public_suffix (5.0.4)
public_suffix (5.0.5)
raabro (1.4.0)
racc (1.7.3)
racc (1.8.0)
rchardet (1.8.0)
rexml (3.2.6)
rouge (4.2.0)
rexml (3.2.8)
strscan (>= 3.0.9)
rouge (4.2.1)
rufus-scheduler (3.9.1)
fugit (~> 1.1, >= 1.1.6)
safe_yaml (1.0.5)
@ -79,6 +80,7 @@ GEM
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
slop (4.10.1)
strscan (3.1.0)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
tzinfo (2.0.6)

View File

@ -5,28 +5,26 @@
[![Join the chat](https://img.shields.io/gitter/room/pmd/pmd)](https://app.gitter.im/#/room/#pmd_pmd:gitter.im?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://github.com/pmd/pmd/workflows/build/badge.svg?branch=master)](https://github.com/pmd/pmd/actions)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd)
[![Reproducible Builds](https://img.shields.io/badge/Reproducible_Builds-ok-green?labelColor=blue)](https://github.com/jvm-repo-rebuild/reproducible-central#net.sourceforge.pmd:pmd)
[![Reproducible Builds](https://img.shields.io/badge/Reproducible_Builds-ok-green?labelColor=blue)](https://github.com/jvm-repo-rebuild/reproducible-central/tree/master/content/net/sourceforge/pmd#readme)
[![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&amp;utm_medium=referral&amp;utm_content=pmd/pmd&amp;utm_campaign=Badge_Grade)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/ea550046a02344ec850553476c4aa2ca)](https://app.codacy.com/organizations/gh/pmd/dashboard)
[![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://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.
It uses JavaCC and Antlr to parse source files into abstract syntax trees (AST) and runs rules against them to find violations.
Rules can be written in Java or using a XPath query.
**PMD** is an extensible multilanguage static code analyzer. It finds common programming flaws like unused variables,
empty catch blocks, unnecessary object creation, and so forth. It's mainly concerned with **Java and
Apex**, but **supports 16 other languages**. It comes with **400+ built-in rules**. It can be
extended with custom rules. It uses JavaCC and Antlr to parse source files into abstract syntax trees
(AST) and runs rules against them to find violations. Rules can be written in Java or using a XPath query.
It supports Java, JavaScript, Salesforce.com Apex and Visualforce,
Modelica, PLSQL, Apache Velocity, HTML, XML and XSL.
Currently, PMD supports Java, JavaScript, Salesforce.com Apex and Visualforce,
Kotlin, Swift, Modelica, PLSQL, Apache Velocity, JSP, WSDL, Maven POM, HTML, XML and XSL.
Scala is supported, but there are currently no Scala rules available.
Additionally, it includes **CPD**, the copy-paste-detector. CPD finds duplicated code in
C/C++, C#, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Kotlin, Lua, Matlab, Modelica,
Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex and Visualforce, Scala, Swift, T-SQL,
Apache Velocity, and XML.
In the future we hope to add support for data/control flow analysis and automatic (quick) fixes where
it makes sense.
Coco, C/C++, C#, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Julia, Kotlin,
Lua, Matlab, Modelica, Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex and
Visualforce, Scala, Swift, T-SQL, Typescript, Apache Velocity, WSDL, XML and XSL.
## 🚀 Installation and Usage

View File

@ -254,7 +254,7 @@ permalink: pmd_release_notes.html
keywords: changelog, release notes
---
## {{ site.pmd.date }} - {{ site.pmd.version }}
## {{ site.pmd.date | date: "%d-%B-%Y" }} - {{ site.pmd.version }}
The PMD team is pleased to announce PMD {{ site.pmd.version }}.

View File

@ -1,7 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (7.1.3.2)
activesupport (7.1.3.3)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
@ -14,7 +14,7 @@ GEM
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
base64 (0.2.0)
bigdecimal (3.1.6)
bigdecimal (3.1.8)
coffee-script (2.4.1)
coffee-script-source
execjs
@ -23,8 +23,8 @@ GEM
commonmarker (0.23.10)
concurrent-ruby (1.2.3)
connection_pool (2.4.1)
csv (3.2.8)
dnsruby (1.71.0)
csv (3.3.0)
dnsruby (1.72.1)
simpleidn (~> 0.2.1)
drb (2.2.1)
em-websocket (0.5.3)
@ -96,7 +96,7 @@ GEM
activesupport (>= 2)
nokogiri (>= 1.4)
http_parser.rb (0.8.0)
i18n (1.14.4)
i18n (1.14.5)
concurrent-ruby (~> 1.0)
jekyll (3.9.5)
addressable (~> 2.4)
@ -219,23 +219,24 @@ GEM
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.22.2)
minitest (5.23.1)
mutex_m (0.2.0)
net-http (0.4.1)
uri
nokogiri (1.16.2-x86_64-linux)
nokogiri (1.16.5-x86_64-linux)
racc (~> 1.4)
octokit (4.25.1)
faraday (>= 1, < 3)
sawyer (~> 0.9)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (5.0.4)
racc (1.7.3)
public_suffix (5.0.5)
racc (1.8.0)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
rb-inotify (0.11.1)
ffi (~> 1.0)
rexml (3.2.6)
rexml (3.2.8)
strscan (>= 3.0.9)
rouge (3.30.0)
rubyzip (2.3.2)
safe_yaml (1.0.5)
@ -247,17 +248,14 @@ GEM
sawyer (0.9.2)
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
simpleidn (0.2.1)
unf (~> 0.1.4)
simpleidn (0.2.3)
strscan (3.1.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
typhoeus (1.4.1)
ethon (>= 0.9.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.9.1)
unicode-display_width (1.8.0)
uri (0.13.0)
webrick (1.8.1)

View File

@ -1,16 +1,17 @@
repository: pmd/pmd
pmd:
version: 7.2.0-SNAPSHOT
previous_version: 7.1.0
date: 31-May-2024
version: 7.3.0-SNAPSHOT
previous_version: 7.2.0
date: 2024-06-28
# release types: major, minor, bugfix
release_type: minor
# release types: major, minor, bugfix
output: web
# this property is useful for conditional filtering of content that is separate from the PDF.
sidebar_title: PMD
topnav_title: PMD Source Code Analyzer Project
# this appears on the top navigation bar next to the home button

View File

@ -1,7 +1,5 @@
entries:
- title: sidebar
product: PMD
version: '!PMD_VERSION!'
folders:
- title: null
output: pdf
@ -31,6 +29,12 @@ entries:
- title: Getting help
url: /pmd_about_help.html
output: web, pdf
- title: Release policies
url: /pmd_about_release_policies.html
output: web, pdf
- title: Support lifecycle
url: /pmd_about_support_lifecycle.html
output: web, pdf
- title: User Documentation
output: web, pdf
folderitems:

View File

@ -1,8 +1,8 @@
{% include custom/sidebarconfigs.html %}
<ul id="mysidebar" class="nav">
<li class="sidebarTitle">{{sidebar[0].product}} {{sidebar[0].version | replace: '!PMD_VERSION!', site.pmd.version}}</li>
<div class="sidebarTitleDate">Release date: {{site.pmd.date}}</div>
<li class="sidebarTitle">{{site.sidebar_title}} {{site.pmd.version}}</li>
<div class="sidebarTitleDate">Release date: {{site.pmd.date | date: "%d-%B-%Y" }}</div>
{% for entry in sidebar %}
{% for folder in entry.folders %}
{% if folder.output contains "web" %}

View File

@ -24,10 +24,20 @@ additional_js:
<!-- You can link to an individual panel, the id is determined from the title of the panel -->
<!-- See custom/shuffle_panel.html for the details -->
**PMD** is a static source code analyzer. It finds common programming flaws like
unused variables, empty catch blocks, unnecessary object creation, and
so forth. It's mainly concerned with **Java and Apex**, but **supports 16 other
languages**.
**PMD** is an extensible multilanguage static code analyzer. It finds common programming flaws like unused variables,
empty catch blocks, unnecessary object creation, and so forth. It's mainly concerned with **Java and
Apex**, but **supports 16 other languages**. It comes with **400+ built-in rules**. It can be
extended with custom rules. It uses JavaCC and Antlr to parse source files into abstract syntax trees
(AST) and runs rules against them to find violations. Rules can be written in Java or using a XPath query.
Currently, PMD supports Java, JavaScript, Salesforce.com Apex and Visualforce,
Kotlin, Swift, Modelica, PLSQL, Apache Velocity, JSP, WSDL, Maven POM, HTML, XML and XSL.
Scala is supported, but there are currently no Scala rules available.
Additionally, it includes **CPD**, the copy-paste-detector. CPD finds duplicated code in
Coco, C/C++, C#, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Julia, Kotlin,
Lua, Matlab, Modelica, Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex and
Visualforce, Scala, Swift, T-SQL, Typescript, Apache Velocity, WSDL, XML and XSL.
PMD features many **built-in checks** (in PMD lingo, *rules*), which are documented
for each language in our [Rule references](#shuffle-panel-rule-references). We
@ -43,7 +53,7 @@ things, PMD can be run:
* As a [bld operation](pmd_userdocs_tools_bld.html)
* From [command-line](pmd_userdocs_installation.html#running-pmd-via-command-line)
**CPD**, the **copy-paste detector**, is also distributed with PMD. You can also use it
**CPD**, the **copy-paste detector**, is also distributed with PMD. You can use it
in a variety of ways, which are [documented here](pmd_userdocs_cpd.html).
## 💾 Download

View File

@ -0,0 +1,55 @@
---
title: Release schedule and version policies
permalink: pmd_about_release_policies.html
author: Andreas Dangel <andreas.dangel@pmd-code.org>
last_updated: June 2024 (PMD 7.3.0)
---
## Release schedule
PMD uses a time-based release schedule.
We release a new minor version **every month**, usually on the last Friday of the month.
A patch release will only be done if necessary (e.g. blocker bugs).
## Version policy
PMD aims to follow [SemVer](https://semver.org/), that means, versions are numbered in the form MAJOR.MINOR.PATCH.
A **major** release can break any compatibility, and it means more effort to upgrade to the next major version (like
it was from 6.x to 7.x, see [Migration Guide for PMD 7](pmd_userdocs_migrating_to_pmd7.html).
A **minor** release tries to be compatible so that an effortless (aka "drop-in replacement") upgrade is possible
with some exceptions.
Such releases might contain:
* fixed false-positive (FP) issues for rules
* fixed false-negative (FN) issues for rules: These fixes might break your builds, as new violations might be found.
* new rules: these new rules are not used by default _if_ you use custom rulesets, so they shouldn't affect your builds.
* deprecations of existing functionality
In summary: we only guarantee stability on how you integrate / use the tool, but builds may start failing because
we fixed FNs, or introduced a new rule (ie: for people referencing whole categories).
We stick to our current approach when moving / renaming rules of deprecating them, and referencing
the new one until the next major.
A **patch** release absolutely is a drop-in replacement. So only bugs (ie: crashes or obviously broken stuff,
like rules not being applied at all), or security issues (dependency updates, hardening, etc.) are part of
a patch release.
See also
* [ADR 3 - API evolution principles](pmd_projectdocs_decisions_adr_3.html)
* [Rule deprecation policy](pmd_devdocs_rule_deprecation_policy.html)
## Git branches/tags policy
* Main development happens on the main branch (currently called `master`).
* PR and enhancements are done on the main branch.
* Release are usually done directly from the main branch, we don't create release branches.
* Each release has its own tag named `pmd_releases/MAJOR.MINOR.PATCH`.
* In case of a patch release, we either do it from the main branch (if there was no development ongoing)
or create a separate branch off the last release tag.
* See also [Release process](pmd_projectdocs_committers_releasing.html).

View File

@ -0,0 +1,25 @@
---
title: Support lifecycle
permalink: pmd_about_support_lifecycle.html
author: Andreas Dangel <andreas.dangel@pmd-code.org>
last_updated: June 2024 (PMD 7.3.0)
---
{% capture latest_release %}{{site.pmd.version}} ({{site.pmd.date | date: "%Y-%m-%d" }}){% endcapture %}
| Major version | Initial release | Latest Release | Required Java Version | In development / still supported? |
|---------------|--------------------|----------------------|-----------------------|-----------------------------------|
| 7.x | 7.0.0 (2024-03-22) | {{ latest_release }} | 8 | ✔ yes |
| 6.x | 6.0.0 (2017-12-15) | 6.55.0 (2023-02-25) | 7 | ❌ no |
| 5.x | 5.0.0 (2012-05-01) | 5.8.1 (2017-07-01) | 7 | ❌ no |
| 4.x | 4.0 (2007-07-20) | 4.3 (2011-11-04) | 5 | ❌ no |
| 3.x | 3.0 (2005-03-23) | 3.9 (2006-12-19) | 4 | ❌ no |
| 2.x | 2.0 (2004-10-19) | 2.3 (2005-02-01) | | ❌ no |
| 1.x | 1.0 (2002-11-04) | 1.9 (2004-07-14) | | ❌ no |
In general, only the latest major version is in active development and regularly will receive new features
and bug fixes etc.
Once a new version is released, the previous version becomes unsupported.
We recommend to always update to the latest version to benefit from new features and bug fixes.
See also [Release process and version policies](pmd_about_release_policies.html).

View File

@ -74,7 +74,7 @@ in order to release version "6.34.0", the configuration should look like this:
pmd:
version: 7.2.0
previous_version: 7.1.0
date: 31-May-2024
date: 2024-05-31
release_type: minor
```
@ -307,7 +307,7 @@ There are a couple of manual steps needed to prepare the current main branch for
pmd:
version: 7.3.0-SNAPSHOT
previous_version: 7.2.0
date: ??-??-2024
date: 2024-??-??
release_type: minor
```
@ -324,7 +324,7 @@ permalink: pmd_release_notes.html
keywords: changelog, release notes
---
## {{ site.pmd.date }} - {{ site.pmd.version }}
## {{ site.pmd.date | date: "%d-%B-%Y" }} - {{ site.pmd.version }}
The PMD team is pleased to announce PMD {{ site.pmd.version }}.

File diff suppressed because it is too large Load Diff

View File

@ -49,23 +49,21 @@ To represent attributes, we must map Java values to [XPath Data Model (XDM)](htt
values. In the following table we refer to the type conversion function as `conv`, a function from Java types
to XDM types.
| Java type `T` | XSD type `conv(T)` |
|---------------|---------------------------------------|
| `int` | `xs:integer` |
| `long` | `xs:integer` |
| `double` | `xs:decimal` |
| `float` | `xs:decimal` |
| `boolean` | `xs:boolean` |
| `String` | `xs:string` |
| `Character` | `xs:string` |
| `Enum<E>` | `xs:string` (uses `Object::toString`) |
| `List<E>` | `conv(E)*` (a sequence type) |
| Java type `T` | XSD type `conv(T)` |
|-------------------|---------------------------------------|
| `int` | `xs:integer` |
| `long` | `xs:integer` |
| `double` | `xs:decimal` |
| `float` | `xs:decimal` |
| `boolean` | `xs:boolean` |
| `String` | `xs:string` |
| `Character` | `xs:string` |
| `Enum<E>` | `xs:string` (uses `Object::toString`) |
| `Collection<E>` | `conv(E)*` (a sequence type) |
The same `conv` function is used to translate rule property values to XDM values.
{% include warning.html content="Lists are only supported for rule properties, not attributes." %}
Additionaly, PMD's own `net.sourceforge.pmd.lang.document.Chars` is also translated to a `xs:string`
## Rule properties

View File

@ -2,6 +2,7 @@
title: Gradle
tags: [userdocs, tools]
permalink: pmd_userdocs_tools_gradle.html
last_updated: June 2024 (7.3.0)
---
The [Gradle Build Tool](https://gradle.org/) provides a [PMD Plugin](https://docs.gradle.org/current/userguide/pmd_plugin.html)
@ -49,16 +50,18 @@ with the property `toolVersion`:
```
pmd {
toolVersion = "6.21.0"
toolVersion = "{{ site.pmd.version }}"
}
```
Note: For PMD 7, at least gradle 8.6 is needed. See [Support for PMD 7.0](https://github.com/gradle/gradle/issues/24502).
## References
Source code for Gradles PMD Plugin is available here:
Source code for Gradle's PMD Plugin is available here:
* [gradle/gradle code-quality](https://github.com/gradle/gradle/tree/master/platforms/jvm/code-quality/src/main/groovy/org/gradle/api/plugins/quality)
* [Pmd.java](https://github.com/gradle/gradle/blob/master/platforms/jvm/code-quality/src/main/groovy/org/gradle/api/plugins/quality/Pmd.java)
* [PmdExtension.java](https://github.com/gradle/gradle/blob/master/platforms/jvm/code-quality/src/main/groovy/org/gradle/api/plugins/quality/PmdExtension.java)
* [PmdPlugin.java](https://github.com/gradle/gradle/blob/master/platforms/jvm/code-quality/src/main/groovy/org/gradle/api/plugins/quality/PmdPlugin.java)
* The default PMD version used by gradle: [DEFAULT_PMD_VERSION](https://github.com/gradle/gradle/blob/d6daeeb446e6a966c33efea5f3f5f1a2d96f6b8f/platforms/jvm/code-quality/src/main/groovy/org/gradle/api/plugins/quality/PmdPlugin.java#L66)
* The default PMD version used by gradle: [DEFAULT_PMD_VERSION](https://github.com/gradle/gradle/blob/v8.8.0/platforms/jvm/code-quality/src/main/groovy/org/gradle/api/plugins/quality/PmdPlugin.java#L66)

View File

@ -4,7 +4,7 @@ permalink: pmd_release_notes.html
keywords: changelog, release notes
---
## {{ site.pmd.date }} - {{ site.pmd.version }}
## {{ site.pmd.date | date: "%d-%B-%Y" }} - {{ site.pmd.version }}
The PMD team is pleased to announce PMD {{ site.pmd.version }}.
@ -15,22 +15,15 @@ This is a {{ site.pmd.release_type }} release.
### 🚀 New and noteworthy
### 🐛 Fixed Issues
* core
* [#4978](https://github.com/pmd/pmd/issues/4978): \[core] Referenced Rulesets do not emit details on validation errors
* [#4983](https://github.com/pmd/pmd/pull/4983): \[cpd] Fix CPD crashes about unicode escapes
* [#4992](https://github.com/pmd/pmd/pull/4992): \[core] CPD: Include processing errors in XML report
* java
* [#4912](https://github.com/pmd/pmd/issues/4912): \[java] Unable to parse some Java9+ resource references
* [#4973](https://github.com/pmd/pmd/pull/4973): \[java] Stop parsing Java for CPD
* [#4988](https://github.com/pmd/pmd/pull/4988): \[java] Fix impl of ASTVariableId::isResourceDeclaration / VariableId/@<!-- -->ResourceDeclaration
* apex
* [#5053](https://github.com/pmd/pmd/issues/5053): \[apex] CPD fails to parse string literals with escaped characters
* java-bestpractices
* [#4278](https://github.com/pmd/pmd/issues/4278): \[java] UnusedPrivateMethod FP with Junit 5 @MethodSource and default factory method name
* [#4852](https://github.com/pmd/pmd/issues/4852): \[java] ReplaceVectorWithList false-positive (neither Vector nor List usage)
* [#4975](https://github.com/pmd/pmd/issues/4975): \[java] UnusedPrivateMethod false positive when using @MethodSource on a @Nested test
* [#4985](https://github.com/pmd/pmd/issues/4985): \[java] UnusedPrivateMethod false-positive / method reference in combination with custom object
* java-codestyle
* [#4930](https://github.com/pmd/pmd/issues/4930): \[java] EmptyControlStatement should not allow empty try with concise resources
* [#5047](https://github.com/pmd/pmd/issues/5047): \[java] UnusedPrivateMethod FP for Generics & Overloads
* plsql
* [#1934](https://github.com/pmd/pmd/issues/1934): \[plsql] ParseException with MERGE statement in anonymous block
* [#2779](https://github.com/pmd/pmd/issues/2779): \[plsql] Error while parsing statement with (Oracle) DML Error Logging
### 🚨 API Changes
@ -40,11 +33,6 @@ The CPD XML report will now also contain processing errors (if CPD is called wit
See [Report formats for CPD](pmd_userdocs_cpd_report_formats.html#xml) for an example.
#### Deprecated API
* pmd-java
* {% jdoc !!java::lang.java.ast.ASTResource#getStableName() %} and the corresponding attribute `@StableName`
### ✨ External Contributions
{% endtocmaker %}

View File

@ -5,6 +5,89 @@ permalink: pmd_release_notes_old.html
Previous versions of PMD can be downloaded here: [Releases - pmd/pmd (GitHub)](https://github.com/pmd/pmd/releases)
## 31-May-2024 - 7.2.0
The PMD team is pleased to announce PMD 7.2.0.
This is a minor release.
### Table Of Contents
* [🚀 New and noteworthy](#new-and-noteworthy)
* [Collections exposed as XPath attributes](#collections-exposed-as-xpath-attributes)
* [Updated PMD Designer](#updated-pmd-designer)
* [🐛 Fixed Issues](#fixed-issues)
* [🚨 API Changes](#api-changes)
* [Deprecated API](#deprecated-api)
* [✨ External Contributions](#external-contributions)
* [📈 Stats](#stats)
### 🚀 New and noteworthy
#### Collections exposed as XPath attributes
Up to now, all AST node getters would be exposed to XPath, as long as the return type was a primitive (boxed or unboxed), String or Enum. That meant that collections, even of these basic types, were not exposed, so for instance accessing Apex's `ASTUserClass.getInterfaceNames()` to list the interfaces implemented by a class was impossible from XPath, and would require writing a Java rule to check it.
Since this release, PMD will also expose any getter returning a collection of any supported type as a sequence through an XPath attribute. They would require to use apropriate XQuery functions to manipulate the sequence. So for instance, to detect any given `ASTUserClass` in Apex that implements `Queueable`, it is now possible to write:
```xml
/UserClass[@InterfaceNames = 'Queueable']
```
#### Updated PMD Designer
This PMD release ships a new version of the pmd-designer.
For the changes, see [PMD Designer Changelog (7.2.0)](https://github.com/pmd/pmd-designer/releases/tag/7.2.0).
### 🐛 Fixed Issues
* core
* [#4467](https://github.com/pmd/pmd/issues/4467): \[core] Expose collections from getters as XPath sequence attributes
* [#4978](https://github.com/pmd/pmd/issues/4978): \[core] Referenced Rulesets do not emit details on validation errors
* [#4983](https://github.com/pmd/pmd/pull/4983): \[cpd] Fix CPD crashes about unicode escapes
* [#5009](https://github.com/pmd/pmd/issues/5009): \[core] Kotest tests aren't picked up by surefire
* java
* [#4912](https://github.com/pmd/pmd/issues/4912): \[java] Unable to parse some Java9+ resource references
* [#4973](https://github.com/pmd/pmd/pull/4973): \[java] Stop parsing Java for CPD
* [#4980](https://github.com/pmd/pmd/issues/4980): \[java] Bad intersection, unrelated class types java.lang.Object\[] and java.lang.Number
* [#4988](https://github.com/pmd/pmd/pull/4988): \[java] Fix impl of ASTVariableId::isResourceDeclaration / VariableId/@<!-- -->ResourceDeclaration
* [#4990](https://github.com/pmd/pmd/issues/4990): \[java] Add an attribute @<!-- -->PackageQualifier to ASTClassType
* [#5006](https://github.com/pmd/pmd/issues/5006): \[java] Bad intersection, unrelated class types Child and Parent<? extends Child>
* [#5029](https://github.com/pmd/pmd/issues/5029): \[java] PMD 7.x throws stack overflow in TypeOps$ProjectionVisitor while parsing a Java class
* java-bestpractices
* [#4278](https://github.com/pmd/pmd/issues/4278): \[java] UnusedPrivateMethod FP with Junit 5 @MethodSource and default factory method name
* [#4852](https://github.com/pmd/pmd/issues/4852): \[java] ReplaceVectorWithList false-positive (neither Vector nor List usage)
* [#4975](https://github.com/pmd/pmd/issues/4975): \[java] UnusedPrivateMethod false positive when using @MethodSource on a @Nested test
* [#4985](https://github.com/pmd/pmd/issues/4985): \[java] UnusedPrivateMethod false-positive / method reference in combination with custom object
* java-codestyle
* [#1619](https://github.com/pmd/pmd/issues/1619): \[java] LocalVariableCouldBeFinal on 'size' variable in for loop
* [#3122](https://github.com/pmd/pmd/issues/3122): \[java] LocalVariableCouldBeFinal should consider blank local variables
* [#4903](https://github.com/pmd/pmd/issues/4903): \[java] UnnecessaryBoxing, but explicit conversion is necessary
* [#4924](https://github.com/pmd/pmd/issues/4924): \[java] UnnecessaryBoxing false positive in PMD 7.0.0 in lambda
* [#4930](https://github.com/pmd/pmd/issues/4930): \[java] EmptyControlStatement should not allow empty try with concise resources
* [#4954](https://github.com/pmd/pmd/issues/4954): \[java] LocalVariableNamingConventions should allow unnamed variables by default
* [#5028](https://github.com/pmd/pmd/issues/5028): \[java] FormalParameterNamingConventions should accept unnamed parameters by default
* java-errorprone
* [#4042](https://github.com/pmd/pmd/issues/4042): \[java] A false negative about the rule StringBufferInstantiationWithChar
* [#5007](https://github.com/pmd/pmd/issues/5007): \[java] AvoidUsingOctalValues triggers on non-octal double literals with a leading 0
* java-multithreading
* [#2368](https://github.com/pmd/pmd/issues/2368): \[java] False positive UnsynchronizedStaticFormatter in static initializer
### 🚨 API Changes
#### Deprecated API
* pmd-java
* <a href="https://docs.pmd-code.org/apidocs/pmd-java/7.2.0/net/sourceforge/pmd/lang/java/ast/ASTResource.html#getStableName()"><code>ASTResource#getStableName</code></a> and the corresponding attribute `@StableName`
### ✨ External Contributions
* [#5020](https://github.com/pmd/pmd/issues/5020): \[java] Fix AvoidUsingOctalValues false-positive - [Gold856](https://github.com/Gold856) (@Gold856)
### 📈 Stats
* 152 commits
* 46 closed tickets & PRs
* Days since last release: 35
## 26-April-2024 - 7.1.0
The PMD team is pleased to announce PMD 7.1.0.

View File

@ -7,7 +7,7 @@
<parent>
<artifactId>pmd</artifactId>
<groupId>net.sourceforge.pmd</groupId>
<version>7.2.0-SNAPSHOT</version>
<version>7.3.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.2.0-SNAPSHOT</version>
<version>7.3.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@ -7,6 +7,8 @@ package net.sourceforge.pmd.lang.apex.ast;
import java.util.List;
import java.util.stream.Collectors;
import net.sourceforge.pmd.lang.rule.xpath.NoAttribute;
import com.google.summit.ast.Identifier;
public final class ASTReferenceExpression extends AbstractApexNode.Many<Identifier> {
@ -38,6 +40,7 @@ public final class ASTReferenceExpression extends AbstractApexNode.Many<Identifi
return "";
}
@NoAttribute
public List<String> getNames() {
return nodes.stream().map(Identifier::getString).collect(Collectors.toList());
}

View File

@ -9,37 +9,35 @@ import java.util.Locale;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.Token;
import net.sourceforge.pmd.cpd.CpdLexer;
import net.sourceforge.pmd.cpd.TokenFactory;
import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrToken;
import net.sourceforge.pmd.lang.ast.impl.antlr4.AntlrTokenManager;
import net.sourceforge.pmd.lang.document.TextDocument;
import com.nawforce.apexparser.ApexLexer;
import com.nawforce.apexparser.CaseInsensitiveInputStream;
public class ApexCpdLexer implements CpdLexer {
@Override
public void tokenize(TextDocument document, TokenFactory tokenEntries) throws IOException {
CharStream charStream = CharStreams.fromReader(document.newReader());
ApexLexer lexer = new ApexLexer(charStream);
CaseInsensitiveInputStream caseInsensitiveInputStream = new CaseInsensitiveInputStream(charStream);
ApexLexer lexer = new ApexLexer(caseInsensitiveInputStream);
AntlrTokenManager tokenManager = new AntlrTokenManager(lexer, document);
Token token = lexer.nextToken();
AntlrToken token = tokenManager.getNextToken();
while (token.getType() != Token.EOF) {
if (token.getChannel() == ApexLexer.DEFAULT_TOKEN_CHANNEL) { // exclude WHITESPACE_CHANNEL and COMMENT_CHANNEL
String tokenText = token.getText();
while (!token.isEof()) {
if (token.isDefault()) { // excludes WHITESPACE_CHANNEL and COMMENT_CHANNEL
String tokenText = token.getImage();
// be case-insensitive
tokenText = tokenText.toLowerCase(Locale.ROOT);
tokenEntries.recordToken(
tokenText,
token.getLine(),
token.getCharPositionInLine() + 1,
token.getLine(),
token.getCharPositionInLine() + tokenText.length() + 1
);
tokenEntries.recordToken(tokenText, token.getReportLocation());
}
token = lexer.nextToken();
token = tokenManager.getNextToken();
}
}
}

View File

@ -32,4 +32,14 @@ class ApexCpdLexerTest extends CpdTextComparisonTest {
void testTabWidth() {
doTest("tabWidth");
}
@Test
void lexExceptionExpected() {
expectLexException("class Foo { String s = \"not a string literal\"; }");
}
@Test
void caseInsensitiveStringLiterals() {
doTest("StringLiterals5053");
}
}

View File

@ -1,7 +1,7 @@
+- ApexFile[@DefiningType = "InnerClassLocations", @RealLoc = true]
+- UserClass[@DefiningType = "InnerClassLocations", @Image = "InnerClassLocations", @RealLoc = true, @SimpleName = "InnerClassLocations", @SuperClassName = ""]
+- UserClass[@DefiningType = "InnerClassLocations", @Image = "InnerClassLocations", @InterfaceNames = (), @RealLoc = true, @SimpleName = "InnerClassLocations", @SuperClassName = ""]
+- ModifierNode[@Abstract = false, @DefiningType = "InnerClassLocations", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
+- UserClass[@DefiningType = "InnerClassLocations.bar1", @Image = "bar1", @RealLoc = true, @SimpleName = "bar1", @SuperClassName = ""]
+- UserClass[@DefiningType = "InnerClassLocations.bar1", @Image = "bar1", @InterfaceNames = (), @RealLoc = true, @SimpleName = "bar1", @SuperClassName = ""]
| +- ModifierNode[@Abstract = false, @DefiningType = "InnerClassLocations.bar1", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
| +- Method[@Arity = 0, @CanonicalName = "m", @Constructor = false, @DefiningType = "InnerClassLocations.bar1", @Image = "m", @RealLoc = true, @ReturnType = "void", @StaticInitializer = false]
| +- ModifierNode[@Abstract = false, @DefiningType = "InnerClassLocations.bar1", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
@ -14,7 +14,7 @@
| +- MethodCallExpression[@DefiningType = "InnerClassLocations.bar1", @FullMethodName = "System.out.println", @InputParametersSize = 1, @MethodName = "println", @RealLoc = true]
| +- ReferenceExpression[@DefiningType = "InnerClassLocations.bar1", @Image = "System", @RealLoc = true, @ReferenceType = ReferenceType.METHOD, @SObjectType = false, @SafeNav = false]
| +- LiteralExpression[@Boolean = false, @Decimal = false, @DefiningType = "InnerClassLocations.bar1", @Double = false, @Image = "foo", @Integer = false, @LiteralType = LiteralType.STRING, @Long = false, @Name = null, @Null = false, @RealLoc = true, @String = true]
+- UserClass[@DefiningType = "InnerClassLocations.bar2", @Image = "bar2", @RealLoc = true, @SimpleName = "bar2", @SuperClassName = ""]
+- UserClass[@DefiningType = "InnerClassLocations.bar2", @Image = "bar2", @InterfaceNames = (), @RealLoc = true, @SimpleName = "bar2", @SuperClassName = ""]
+- ModifierNode[@Abstract = false, @DefiningType = "InnerClassLocations.bar2", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
+- Method[@Arity = 0, @CanonicalName = "m", @Constructor = false, @DefiningType = "InnerClassLocations.bar2", @Image = "m", @RealLoc = true, @ReturnType = "void", @StaticInitializer = false]
+- ModifierNode[@Abstract = false, @DefiningType = "InnerClassLocations.bar2", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]

View File

@ -1,5 +1,5 @@
+- ApexFile[@DefiningType = "NullCoalescingOperator", @RealLoc = true]
+- UserClass[@DefiningType = "NullCoalescingOperator", @Image = "NullCoalescingOperator", @RealLoc = true, @SimpleName = "NullCoalescingOperator", @SuperClassName = ""]
+- UserClass[@DefiningType = "NullCoalescingOperator", @Image = "NullCoalescingOperator", @InterfaceNames = (), @RealLoc = true, @SimpleName = "NullCoalescingOperator", @SuperClassName = ""]
+- ModifierNode[@Abstract = false, @DefiningType = "NullCoalescingOperator", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
+- Method[@Arity = 2, @CanonicalName = "leftOrRight", @Constructor = false, @DefiningType = "NullCoalescingOperator", @Image = "leftOrRight", @RealLoc = true, @ReturnType = "String", @StaticInitializer = false]
+- ModifierNode[@Abstract = false, @DefiningType = "NullCoalescingOperator", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]

View File

@ -1,11 +1,11 @@
+- ApexFile[@DefiningType = "Foo", @RealLoc = true]
+- UserClass[@DefiningType = "Foo", @Image = "Foo", @RealLoc = true, @SimpleName = "Foo", @SuperClassName = ""]
+- UserClass[@DefiningType = "Foo", @Image = "Foo", @InterfaceNames = (), @RealLoc = true, @SimpleName = "Foo", @SuperClassName = ""]
+- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
+- Field[@DefiningType = "Foo", @Image = "x", @Name = "x", @RealLoc = true, @Type = "Integer", @Value = null]
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
+- Field[@DefiningType = "Foo", @Image = "profileUrl", @Name = "profileUrl", @RealLoc = true, @Type = "String", @Value = null]
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
+- FieldDeclarationStatements[@DefiningType = "Foo", @RealLoc = true, @TypeName = "Integer"]
+- FieldDeclarationStatements[@DefiningType = "Foo", @RealLoc = true, @TypeArguments = (), @TypeName = "Integer"]
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
| +- FieldDeclaration[@DefiningType = "Foo", @Image = "x", @Name = "x", @RealLoc = true]
| +- VariableExpression[@DefiningType = "Foo", @Image = "anIntegerField", @RealLoc = true]
@ -14,7 +14,7 @@
| | +- EmptyReferenceExpression[@DefiningType = null, @RealLoc = false]
| +- VariableExpression[@DefiningType = "Foo", @Image = "x", @RealLoc = true]
| +- EmptyReferenceExpression[@DefiningType = null, @RealLoc = false]
+- FieldDeclarationStatements[@DefiningType = "Foo", @RealLoc = true, @TypeName = "String"]
+- FieldDeclarationStatements[@DefiningType = "Foo", @RealLoc = true, @TypeArguments = (), @TypeName = "String"]
| +- ModifierNode[@Abstract = false, @DefiningType = "Foo", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false]
| +- FieldDeclaration[@DefiningType = "Foo", @Image = "profileUrl", @Name = "profileUrl", @RealLoc = true]
| +- MethodCallExpression[@DefiningType = "Foo", @FullMethodName = "toExternalForm", @InputParametersSize = 0, @MethodName = "toExternalForm", @RealLoc = true]

View File

@ -0,0 +1,12 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
// See https://github.com/pmd/pmd/issues/5053
public with sharing class PMD7CPD {
public static void example(){
String str = 'alice';
str = str.replace('alice', '<bob></charlie>dan<!--JohannHeinrichvonThünen-->' + '\u00A0' + '"100%"');
}
}

View File

@ -0,0 +1,43 @@
[Image] or [Truncated image[ Bcol Ecol
L7
[public] 1 7
[with] 8 12
[sharing] 13 20
[class] 21 26
[pmd7cpd] 27 34
[{] 35 36
L8
[public] 5 11
[static] 12 18
[void] 19 23
[example] 24 31
[(] 31 32
[)] 32 33
[{] 33 34
L9
[string] 7 13
[str] 14 17
[=] 18 19
['alice'] 20 27
[;] 27 28
L10
[str] 7 10
[=] 11 12
[str] 13 16
[.] 16 17
[replace] 17 24
[(] 24 25
['alice'] 25 32
[,] 32 33
['<bob></charlie>dan<!--johannheinr[ 34 84
[+] 85 86
['\\u00a0'] 87 95
[+] 96 97
['"100%"'] 98 106
[)] 106 107
[;] 107 108
L11
[}] 5 6
L12
[}] 1 2
EOF

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