Skip to content

[html] Fix #5313: CPD end line without trailing newline - #7050

Merged
UncleOwen merged 3 commits into
pmd:mainfrom
Eymenonar:fix-5313-html-cpd-end-line
Oct 8, 2026
Merged

UncleOwen merged 3 commits into
pmd:mainfrom
Eymenonar:fix-5313-html-cpd-end-line

Conversation

@Eymenonar

@Eymenonar Eymenonar commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Describe the PR

Uses Jsoup's tracked source ranges for HTML CPD tokens. Element tokens cover their opening tags, while explicit closing tags are emitted as separate post-order tokens at their own source ranges. Implicit, self-closing, and void elements do not get synthetic closing tokens.

This makes duplicate ranges include the final explicit closing tag when inputs lack trailing newlines, including mixed trailing-newline inputs, without extending unrelated token locations.

Related issues

Ready?

  • Added unit tests for fixed bug/feature
  • Passing all unit tests
  • Complete build ./mvnw clean verify passes (checked automatically by github actions)
  • Added (in-code) documentation (if needed)

Tests

  • ./mvnw -pl pmd-html -am verify
  • ./mvnw -pl pmd-html verify

@pmd-actions-helper

pmd-actions-helper Bot commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Documentation Preview

Compared to main:
This changeset changes 0 violations,
introduces 0 new violations, 0 new errors and 0 new configuration errors,
removes 0 violations, 0 errors and 0 configuration errors.
There are 0 changed duplications, 0 new duplications and 0 removed duplications.
There are 0 changed CPD errors, 0 new CPD errors and 0 removed CPD errors.

Regression Tester Report

(comment created at 2026-09-29 20:16:20+00:00 for 51762a8)

@Eymenonar
Eymenonar force-pushed the fix-5313-html-cpd-end-line branch 2 times, most recently from b50388a to 1fc2e11 Compare September 9, 2026 09:19
@Eymenonar
Eymenonar force-pushed the fix-5313-html-cpd-end-line branch 4 times, most recently from 9c7831f to cf6cb32 Compare September 29, 2026 10:50
@UncleOwen

Copy link
Copy Markdown
Member

If I understand this PR correctly, this changes the location of the token before each </html> (which should happen only once per document)? So in the case of the SimpleHtmlFile.html test, it changes the location of the newline at the end of line 6?

Why does that change if the </html> is included in the duplicate chunk or not? I don't understand it.

What does this do, if there is no text directly before the </html>, but another tag?

I'm skeptical if faking any locations is the way to go here. If one file ends with a newline and the other doesn't, maybe not reporting the last line is correct? I'd be more interested in finding out why the last line isn't reported if both files don't end with a newline.

@adangel adangel changed the title [html] Fix CPD end line without trailing newline [html] Fix #5313: CPD end line without trailing newline Sep 29, 2026
@Eymenonar
Eymenonar force-pushed the fix-5313-html-cpd-end-line branch from cf6cb32 to b332140 Compare September 29, 2026 15:56
@UncleOwen

Copy link
Copy Markdown
Member

Now we have (again, going with SimpleHtmlFile.html) a <html> tag, going from line 2 to line 7, and a closing </html> tag, going from line 7 to line 7. That's confusing.

Comment on lines +18 to +20
[h1] 9 13
[world] 13 17
[/h1] 18 23

@UncleOwen UncleOwen Oct 6, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The h1 tag used to go from line 5, column 9 to line 5, column 22
Now it goes from line 5, column 9 to line 5, column 23

Do we have an off-by-one-error somewhere?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked this against the source positions and PMD's end-exclusive location convention. The line in question is the separate [/h1] token: starts at column 18 and ends after the > at exclusive column 23, while the > itself is column 22. The opening [h1] token remains 9-13. The focused HtmlCpdLexerTest passes 9/9, so I don't think this is an off-by-one.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. The new positions are correct. Looks like the old values were wrong.

@UncleOwen

Copy link
Copy Markdown
Member

@adangel This PR completely changes how we do tokenization of HTML. Is this ok for you?

I never liked how we had tokens nested within tokens for HTML, so I like it. But if this change is too much for a minor version, please stop me before I merge this.

@UncleOwen UncleOwen added this to the 7.29.0 milestone Oct 7, 2026

@adangel adangel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks!

@adangel This PR completely changes how we do tokenization of HTML. Is this ok for you?

I never liked how we had tokens nested within tokens for HTML, so I like it. But if this change is too much for a minor version, please stop me before I merge this.

I'd consider the actual tokenization an implementation detail, so I think this is fine. The important point is, that CPD can correctly detect duplicates, and I think, this still works. It might of course now change, what exactly it detects at duplicates (the whole point of the bugfix).
So, yes, go ahead and merge it :)

I agree, that the new way makes more sense, to have the end tags recorded as individual tokens. And the endcolumn of the start tags was obviously the endcolumn of the closing tag (which might have been on a different line anyway). So, it was a real bug.

One thing, that's still wrong (Could be done with a separate PR for completeness): For text nodes, we report the wrong endcolumn. The endcolumn should be exclusive, but e.g. "hello" in L3 in SimpleHtmlFile.txt should go from columns 11-16.

@UncleOwen
UncleOwen merged commit 8871b62 into pmd:main Oct 8, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[html] CPD does not include the last line in the duplication chunk

3 participants