Skip to content

Issue #20339 fix: use expandedTabsColumnNo in NewHandler.getIndentImpl for tab sup… - #20342

Merged
romani merged 1 commit into
checkstyle:masterfrom
BobSong-dev:fix/indentation-new-tab-false-positive
Jul 17, 2026
Merged

romani merged 1 commit into
checkstyle:masterfrom
BobSong-dev:fix/indentation-new-tab-false-positive

Conversation

@BobSong-dev

@BobSong-dev BobSong-dev commented Jun 14, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #20339
Closes #18614

Hi, thanks for maintaining Checkstyle. I took a look at the false positive reported in #20339 and found the root cause.

Problem

In NewHandler.getIndentImpl() line 124, the code checks if new is at the start of a line:

if (getLineStart(mainAst) == mainAst.getColumnNo())

getLineStart() returns the tab-expanded column, but getColumnNo() returns the raw column. With tab-indented files these two values don't match, even when new is actually the first non-whitespace character on the line.

For example, with tabWidth=4 and 2 tabs of indentation, getLineStart() returns 8 while getColumnNo() returns 2, so the check wrongly evaluates to false.

The reverse case is also broken: when new is NOT at the line start (e.g. after throw), the raw column can coincidentally equal the line start, producing a false true.

Fix

Replace mainAst.getColumnNo() with expandedTabsColumnNo(mainAst) — the same pattern already used by isOnStartOfLine() at line 180 of the same file, and consistent with the fix in PR #18686.

Additional note

While investigating, I noticed MethodCallHandler.java line 185 has the same pattern:

if (getLineStart(rparen) == rparen.getColumnNo())

This would have the same tab-related issue. I kept this PR focused on NewHandler as described in the issue, but wanted to flag it for awareness.

Test

Added two test cases in IndentationCheckTest.java with corresponding input files:

  • testNewKeywordWithTab — non-strict mode (forceStrictCondition=false), new at the first nesting level with tab indentation
  • testNewKeywordWithTabStrict — strict mode (forceStrictCondition=true), new inside an if block (deeper nesting) with tab indentation

Both input files use actual tab characters for indentation. Before the fix these would produce false positives; after the fix no warnings are expected.

BungeeCord Diff Regression

Diff Regression config: https://gist.githubusercontent.com/BobSong-dev/26a6c8d6bc2f6b2fbf53b24de39ab7ac/raw/4c2f8ecb6cb1e2a441bf01ce8e5e7f4255fd29a1/bungeecord-indentation.xml
Diff Regression projects: https://gist.githubusercontent.com/BobSong-dev/e0e12b1681c2023dddd7aa6f4336d0a2/raw/67bc1dbaba119c31587bb14bf35da037de74887b/bungeecord-projects.properties
Report label: BungeeCord default Indentation

@BobSong-dev BobSong-dev changed the title fix: use expandedTabsColumnNo in NewHandler.getIndentImpl for tab sup… Issue #20283 fix: use expandedTabsColumnNo in NewHandler.getIndentImpl for tab sup… Jun 14, 2026
@BobSong-dev BobSong-dev changed the title Issue #20283 fix: use expandedTabsColumnNo in NewHandler.getIndentImpl for tab sup… Issue #20339 fix: use expandedTabsColumnNo in NewHandler.getIndentImpl for tab sup… Jun 14, 2026
@BobSong-dev
BobSong-dev force-pushed the fix/indentation-new-tab-false-positive branch from 74f1f57 to 4daa0ad Compare June 14, 2026 14:54
@BobSong-dev

Copy link
Copy Markdown
Contributor Author

@romani Hi! Since this is my first contribution to Checkstyle, my CI workflows are pending manual approval. Could you please help trigger the runs when you have a moment? I've verified the tests locally. Thanks!

@BobSong-dev
BobSong-dev force-pushed the fix/indentation-new-tab-false-positive branch 2 times, most recently from 0e7ac17 to 1c1ae3a Compare June 19, 2026 13:27
@BobSong-dev

Copy link
Copy Markdown
Contributor Author

@Atharv3221 Done, added two test cases:

testNewKeywordWithTab — non-strict mode, new at the first nesting level
testNewKeywordWithTabStrict — strict mode, new inside an if block (deeper nesting)
Both input files use actual tab characters. Let me know if there's anything I should adjust, and feel free to point out any issues. Thanks!

@romani

romani commented Jul 12, 2026

Copy link
Copy Markdown
Member

Github, generate report for Indentation/Example1

@github-actions

Copy link
Copy Markdown
Contributor

@romani

romani commented Jul 13, 2026

Copy link
Copy Markdown
Member

@BobSong-dev , according to issue, only tab based files should be affected, but diff reprot shows more changes.

please review all, and improve code if you see some false positives

@BobSong-dev

Copy link
Copy Markdown
Contributor Author

@BobSong-dev , according to issue, only tab based files should be affected, but diff reprot shows more changes.

please review all, and improve code if you see some false positives

This update mainly includes two adjustments.

The previous change fixed the false positive reported in #20339, but its impact was broader than intended. It changed the indentation calculation whenever new appeared at the beginning of a tab-indented line, which caused many unrelated warnings in the regression report.

The condition has now been narrowed. The line-start indentation logic is used only when both the raw column and the tab-expanded column confirm that new is at the beginning of the line. This fixes the column-collision case in code such as \t\tthrow new, without changing the existing behavior of other tab-indented code.

I also updated the tests. The previous tests only covered a single-line expression:

Object obj = new Object();

Those tests passed even with the original implementation, so they did not actually reproduce the reported issue. The new tests use the multiline constructor case from the issue:

throw new RuntimeException(
    "Exception");

Both strict and non-strict configurations are now covered.

I ran the relevant tests as well as the full mvn clean verify, and everything passed.

Feedback and corrections are very welcome.

@BobSong-dev
BobSong-dev force-pushed the fix/indentation-new-tab-false-positive branch from b629813 to 56546a0 Compare July 15, 2026 14:22
@romani

romani commented Jul 15, 2026 •

Copy link
Copy Markdown
Member

which caused many unrelated warnings in the regression report.

this is a big concern, as users wihtout tabs, majority of codebases will get false-positives.
We need to find way how to not affect others, and affect only source codes with tabs.

please add to our Inputs this snippet with violation asd fixed form of it https://checkstyle-diff-reports.s3.us-east-2.amazonaws.com/1c1ae3aec5d09ffb34fb5490ab42d29c45f19ae8_2026232108/reports/diff/java-design-patterns/index.html#A1

and https://checkstyle-diff-reports.s3.us-east-2.amazonaws.com/1c1ae3aec5d09ffb34fb5490ab42d29c45f19ae8_2026232108/reports/diff/spring-framework/index.html#A1
as is from them with violation and what is expected formatting.

@BobSong-dev
BobSong-dev force-pushed the fix/indentation-new-tab-false-positive branch from 56546a0 to f0558e9 Compare July 16, 2026 02:06

@romani romani 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.

itms:

@BobSong-dev
BobSong-dev force-pushed the fix/indentation-new-tab-false-positive branch 2 times, most recently from 6e5a633 to 2a18cff Compare July 16, 2026 02:39
@BobSong-dev
BobSong-dev requested a review from romani July 16, 2026 03:08
@romani

romani commented Jul 16, 2026

Copy link
Copy Markdown
Member

ok ,thanks a lot, it looks like we resolved few other problems :) by this tab issue.
Ok ,lets move forward ... advanced CI is enabled, please check status of it.

@romani

romani commented Jul 16, 2026 •

Copy link
Copy Markdown
Member

@BobSong-dev

Copy link
Copy Markdown
Contributor Author

@BobSong-dev , pelase glance at https://github.com/checkstyle/checkstyle/issues?q=is%3Aissue%20state%3Aopen%20label%3Aindentation do you see any issue that you resovled by your update ?请浏览 https://github.com/checkstyle/checkstyle/issues?q=is%3Aissue%20state%3Aopen%20label%3Aindentation,您是否看到您通过更新解决的任何问题?

Thanks! I checked the advanced CI.

The functional checks look good, including the indentation tests and the test-resources compilation check. The only red job is the Java performance check. It looks like the run was faster than the baseline, but the performance threshold was still exceeded. The javadoc job was cancelled as a result. AppVeyor is still running.

I also checked the open indentation issues, and this change seems to resolve #18614 as well as #20339.

I reproduced the tab-indented cases from #18614 with the current PR. The correctly indented constructor arguments inside try now pass, while an incorrectly indented new is correctly reported.

The root cause appears to be the same raw-column versus tab-expanded-column mismatch in NewHandler.

@romani

romani commented Jul 16, 2026 •

Copy link
Copy Markdown
Member

ok, please add users code from #18614 to Input to make sure it is fixed.
and add link to it to PR description to not forget to close after merge.

But all such issues are from same Author and with TAB usage.
But diff testing shows us difference that is non-TAB code sources, and this worries me.

https://checkstyle-diff-reports.s3.us-east-2.amazonaws.com/1c1ae3aec5d09ffb34fb5490ab42d29c45f19ae8_2026232108/reports/diff/spoon/index.html#A1
Please add this snippet to Inputs, new XXXXXX in method (without assignment to var) and correct form of it next to it.

and add https://checkstyle-diff-reports.s3.us-east-2.amazonaws.com/1c1ae3aec5d09ffb34fb5490ab42d29c45f19ae8_2026232108/reports/diff/spring-framework/index.html#A6


Looks like we affected new blocks. It is hard to judge on diff report as when sources are not compliant from the begining, diff can show side effects - just another mess over mess.

Lets take https://github.com/SpigotMC/BungeeCord project, looks like it uses default Indentation and enforce no error.
We need to make two config file, read https://github.com/checkstyle/contribution/tree/master/checkstyle-tester#executing-generation-using-github-action , place them in PR descriptin and trigger diff report. If no diff on this project, we can assume we are good enough to merge

@BobSong-dev
BobSong-dev force-pushed the fix/indentation-new-tab-false-positive branch from 2a18cff to 326bf1e Compare July 17, 2026 02:02
@BobSong-dev

Copy link
Copy Markdown
Contributor Author

GitHub, generate report

@github-actions

Copy link
Copy Markdown
Contributor

@BobSong-dev

Copy link
Copy Markdown
Contributor Author

Done, thanks. I completed the requested follow-up:

The BungeeCord report completed with 0 differences:
https://checkstyle-diff-reports.s3.us-east-2.amazonaws.com/326bf1e_2026020700/reports/diff/index.html

@romani romani 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.

thanks a lot

@BobSong-dev

Copy link
Copy Markdown
Contributor Author

thanks a lot  多谢
thanks for your review

The Semaphore failure appears unrelated to this PR. The external
methods-distance project fails to compile because it calls TreeWalker
methods that now have protected access. This PR does not change TreeWalker.

The local full verification passes, and the BungeeCord diff report has
0 differences.

@romani

romani commented Jul 17, 2026

Copy link
Copy Markdown
Member

Semaphore got regression cause by previos PRs, CI is very unstable today .... that is why we got leak .
I will handle it, it wil not block this PR

@romani
romani merged commit d08e213 into checkstyle:master Jul 17, 2026
129 of 131 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.

False positive: Indentation on file with tabs False positive: indentation inside of constructor parameters inside try block

3 participants