Skip to content

Conversation

@bombsimon
Copy link
Owner

@bombsimon bombsimon commented Jan 14, 2026

This adds a new check type to enforce newline after any block (closing }). In addition, it also makes the check for empty line while using case-max-lines a bit more strict by now not counting a trailing comment as an empty line.

While doing this, there's a new column based logic to figure out where the newline should go in the end of a case. If it's aligned with the last statement of the case body the line is inserted after. If it's aligned with then next case arm, the line is inserted before the comment.

While working on this we're also moving to a line based check that uses LineStart to make replacements and with that simplifying some comment parsing since we only need to know the pos where the line starts. This also allowed to add support to fix removal of whitespaces both before and after leading comments in blocks.


This change does:

  • Not add unnecessary amount of maintenance
    Rather simplified a lot of comment and line parsing. Some added complexity for case trailing comments.
  • Not have too much weird or unexpected (preferable any) conflicts with existing rules
    Confirmed by adding tests enabling all checks.
  • Possible to implement as a standalone checker
  • Not add unreasonable amount of slowdown

The change seems to add 25% slowdown when enabled.

Average time in seconds over 10 runs example with cache on prometheus repo:

v4 default v4 all new default new default + new check new all
4.172 4.200 4.454 5.699 5.738

Closes #204

This adds a new check type to enforce newline after any block (closing
`}`). In addition, it also makes the check for empty line while using
`case-max-lines` a bit more strict by now _not_ counting a trailing
comment as an empty line.

While doing this, there's a new column based logic to figure out where
the newline should go in the end of a case. If it's aligned with the
last statement of the case body the line is inserted after. If it's
aligned with then next case arm, the line is inserted before the
comment.

While working on this we're also moving to a line based check that uses
`LineStart` to make replacements and with that simplifying some comment
parsing since we only need to know the pos where the line starts. This
also allowed to add support to fix removal of whitespaces both before
_and_ after leading comments in blocks.
@coveralls
Copy link

coveralls commented Jan 14, 2026

Coverage Status

coverage: 92.576% (+0.8%) from 91.751%
when pulling edab8b3 on newline-after-block
into 22e3aba on main.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds support for a new newline-after-block check that enforces a blank line after any block statement (closing }). The implementation includes refined handling of trailing comments in case clauses and switches to line-based logic using LineStart for more reliable fix positioning. The changes also improve comment parsing and support whitespace removal both before and after leading comments in blocks.

Changes:

  • Added new CheckNewlineAfterBlock check type that requires blank lines after block statements
  • Refactored checkCaseTrailingNewline to use column-based logic for comment classification (trailing vs leading)
  • Extracted isErrNotNilCheck helper function to detect error checking patterns and reuse across checks
  • Updated line-based whitespace handling using LineStart for precise fix positioning

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
wsl.go Core implementation of newline-after-block check, refactored error checking logic, improved comment handling
config.go Added CheckNewlineAfterBlock constant and string mapping
config_test.go Updated max check number from 23 to 24
analyzer_test.go Added test configurations for all_enabled and newline_after_block scenarios
README.md Documented the new check as disabled by default
CHECKS.md Added comprehensive documentation for newline-after-block and case-max-lines
testdata/ Comprehensive test coverage for the new check across various scenarios

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

We don't need to check line number to find relevant comments, if we
instead use the `ast.Pos` as long as possible we save a ton of
conversions and gets some speed improvement.
Removes extra check for statement type before calling function.

Also adds a more detailed comment to why we skip complex groups.
@bombsimon
Copy link
Owner Author

bombsimon commented Jan 18, 2026

Some new numbers after the recent change, still on prometheus main branch. Average run time with cache on ~10 runs.

Linter Branch Checks Time
newline-after-block master 1.762
wsl newline-after-block newline-after-block + case-max-lines 7.617
wsl newline-after-block default 4.169
wsl newline-after-block default + case-max-lines 7.646
wsl newline-after-block none + case-max-lines 6.426
wsl newline-after-block all 5.291
wsl newline-after-block all + case-max-lines 8.895
wsl main default 4.927
wsl main default + case-max-lines 4.132
wsl main none + case-max-lines 2.947
wsl main all 4.195
wsl main all + case-max-lines 4.160

I have no clue how all checks can be faster than default checks (which disables some) on the main branch but it consistently is.

However there's clearly some issue with how I handle trailing comments in case blocks which wasn't handled at all before. But it's ~3x slower now and it's also clear that where time is spent.

It would be nice if enabling newline-after-block and case-max-lines was at leat somewhat close to the standalone linter but it doesn't look likely now. I will however see how I can improve the slowdown of case-max-lines.

EDIT Oh, I was recreating a file comment map on every run. If I cache it we're back to normal times:

Linter Branch Checks Time
wsl newline-after-block newline-after-block + case-max-lines 4.320
wsl newline-after-block default + case-max-lines 4.290
wsl newline-after-block none + case-max-lines 3.170
wsl newline-after-block all + case-max-lines 5.622

And if I don't create a comment map at all and iterate over file.Comments:

Linter Branch Checks Time
wsl newline-after-block newline-after-block + case-max-lines 4.178
wsl newline-after-block default + case-max-lines 4.109
wsl newline-after-block none + case-max-lines 2.962
wsl newline-after-block all + case-max-lines 5.353

So I guess we can consider this no slowdown.

EDIT 2: Found some speed improvement areas that might help depending on what checks you have enabled so created tickets for that to do as follow-ups. So all that's left now is to decide on the trailing comment handling in case blocks.

@bombsimon bombsimon force-pushed the newline-after-block branch from ae585e9 to 63c7e0d Compare January 18, 2026 20:21
@bombsimon bombsimon force-pushed the newline-after-block branch from a2aeda0 to a7bc7b7 Compare January 18, 2026 21:36
Similar to how we do support trailing comments in a block, but no
newline after the comment, we want to support left-aligned comments in
case bodies but keep them flush against the next case.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@bombsimon bombsimon force-pushed the newline-after-block branch from 9c1660d to edab8b3 Compare January 21, 2026 21:19
@bombsimon bombsimon merged commit 456abcf into main Jan 21, 2026
5 checks passed
@bombsimon bombsimon deleted the newline-after-block branch January 21, 2026 21:25
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.

Feature Proposal: Add newline-after-block checks to whitespace linter

2 participants