Skip to content

Issue #10924: Fix LeftCurly empty blocks after supplementary Unicode - #21506

Open
ishu7w wants to merge 1 commit into
checkstyle:masterfrom
ishu7w:codex/10924-left-curly-unicode
Open

Issue #10924: Fix LeftCurly empty blocks after supplementary Unicode#21506
ishu7w wants to merge 1 commit into
checkstyle:masterfrom
ishu7w:codex/10924-left-curly-unicode

Conversation

@ishu7w

@ishu7w ishu7w commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Issue: #10924

With LeftCurly configured with option=NL and tokens=METHOD_DEF, void 𝒜() {} and void emoji() /* 😀 */ {} incorrectly report brace-placement violations, while void ascii() {} is accepted. The check uses a Unicode code-point AST column to index a UTF-16 String, so supplementary characters prevent recognition of the adjacent {} exemption.

Use getLineCodePoints and CodePointUtil.hasWhitespaceBefore for the brace line. Add regression cases for a supplementary method name and an emoji comment, an ASCII control, and a nonempty Unicode method that must still report a violation. This addresses only the LeftCurly portion of the umbrella issue.

Validation: the new regression test failed before the production change with two unexpected violations. After the fix, Java 21 mvn -B -ntp clean verify passed, including all 50 LeftCurly tests, 6,788 unit/example tests (2 skipped), 1,347 integration tests, and all configured quality checks.

Diff Regression config: https://gist.github.com/ishu7w/1900fa70b1807fd559f0f1423101ac51/raw/a6db845a813d122061e4861f2585de9b964e6b3d/left-curly-unicode.xml

AI assistance: Codex investigated the bug, prepared the fix and regression test, ran local validation, and drafted this description.

@ishu7w

ishu7w commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

GitHub, generate report

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Report generation failed on phase make_report,
step Generate report.
Link: https://github.com/checkstyle/checkstyle/actions/runs/34152070045

@arturict arturict left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reproduced this against 14.1.0 first: with option=nl and tokens=METHOD_DEF, both 𝒜() {} and emoji() /* 😀 */ {} are reported while the ascii twin is not. On this branch they are silent.

I also diffed LeftCurly output between master and this branch over guava, commons-lang and spring-framework, in nl and in the default eol, and there is no difference at all (262k violations in nl).

@@ -344,8 +345,8 @@ else if (!TokenUtil.areOnSameLine(startToken, brace)) {
* @param brace brace AST
* @param braceLine line content

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

These are code points now, not line content. Same in validateNewLinePosition and in the verifyBrace javadoc.

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.

Done in 6c7d3b6. Updated both braceLine parameter descriptions to say they contain code points of the line containing the brace, and clarified the verifyBrace Javadoc as well. Thanks for the review and independent regression checks.

@ishu7w
ishu7w force-pushed the codex/10924-left-curly-unicode branch from 6c7d3b6 to 4024055 Compare September 8, 2026 01:57
@romani

romani commented Sep 10, 2026

Copy link
Copy Markdown
Member

Github, generate report for LeftCurly/all-examples-in-one

@romani

romani commented Sep 10, 2026

Copy link
Copy Markdown
Member

@arturict , please always run diff testing on wild real projects, even update looks simple. Surprises are very frequent.

@arturict

Copy link
Copy Markdown
Collaborator

understood, i will trigger the report before approving from now on, also on the small ones.

@github-actions

Copy link
Copy Markdown
Contributor

@romani

romani commented Sep 11, 2026

Copy link
Copy Markdown
Member

@arturict

Copy link
Copy Markdown
Collaborator

all three are an empty {} on a line with an emoji before the brace, e.g. if (a == "12🤣") {} else {...} at 31:25.

columnNo counts code points, but master does braceLine.charAt(columnNo + 1) on the String. after a surrogate pair that index still lands on the { itself, so the {} skip in verifyBrace is missed and nl reports it. same line without the emoji (if (a == "12") {}) gives nothing on master. so these were false positives, and reading the line as code points is what removes them.

@ishu7w
ishu7w force-pushed the codex/10924-left-curly-unicode branch from 4024055 to 0dc3894 Compare September 13, 2026 14:12
@romani
romani requested a review from arturict September 13, 2026 20:31
@romani

romani commented Sep 13, 2026

Copy link
Copy Markdown
Member

@ishu7w , please respond to my question

@ishu7w

ishu7w commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@romani Sorry for the delayed response. The disappearing violations are false positives for empty {} blocks with a supplementary Unicode character, such as an emoji, earlier on the same line.

The AST column counts Unicode code points, while String.charAt() indexes UTF-16 code units. The emoji occupies two UTF-16 units, so using columnNo + 1 with charAt() reads the wrong character. In these examples, it reads { instead of }, causing the check to miss the empty-block exception and incorrectly report a violation.

The fix uses code-point indexing consistently, so the empty block is recognized correctly and the false positive disappears. The equivalent code without the emoji already produces no violation.

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.

3 participants