fix(eslint-plugin): [no-unused-vars] remove trailing newline when removing entire import#11990
Conversation
|
Thanks for the PR, @MariaSolOs! typescript-eslint is a 100% community driven project, and we are incredibly grateful that you are contributing to that community. The core maintainers work on this in their personal time, so please understand that it may not be possible for them to review your work immediately. Thanks again! 🙏 Please, if you or your company is finding typescript-eslint valuable, help us sustain the project by sponsoring it transparently on https://opencollective.com/typescript-eslint. |
✅ Deploy Preview for typescript-eslint ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
View your CI Pipeline Execution ↗ for commit 2615be3
☁️ Nx Cloud last updated this comment at |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #11990 +/- ##
==========================================
+ Coverage 90.78% 90.80% +0.01%
==========================================
Files 530 531 +1
Lines 54402 54637 +235
Branches 9196 9228 +32
==========================================
+ Hits 49391 49611 +220
- Misses 4998 5015 +17
+ Partials 13 11 -2
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
As much as I dislike leaving blank lines around, I don't think this is in the scope of what we'd want to add a lot of code to handle? Detection/practices around blank lines are not in the purview of the rule. The general project stance is that if folks care about that, they should use a separate tool: preferably (to us) a dedicated formatter, or alternately a dedicated lint rule. If this PR was just a couple lines it'd be a lot more palatable. But at >30 lines, although I appreciate the work that went into it, I don't think we'd want to take on that maintenance burden. |
|
@JoshuaKGoldberg I understand. I do want to mention that before this fixer was added I was using
I agree that whitespace should preferably be always handled with formatters, but in this specific case a tool like Prettier won't remove the new blank line (it just enforces that there are no multiple lines between imports). Moreover lint rules like
I again agree with you here, but intuitively I think that the least "disruptive" modification when removing an import statement is to remove the new line. |
|
@MariaSolOs this would require an issue first in order to be considered. It's a nontrivial PR for an ordinary feature that doesn't fall under the "minor documentation changes" exception; see https://typescript-eslint.io/contributing/pull-requests Marking as draft for now, pending issue acceptance. |
|
@kirkwaiblinger fair enough, my bad for not following the right order here. Issue created: #11996 |
da169b0 to
f6d67b9
Compare
kirkwaiblinger
left a comment
There was a problem hiding this comment.
This version is slightly buggy and again has explicit references to yucky things like \r\n. I would nudge you to take another look at using .trim() as suggested in https://github.com/typescript-eslint/typescript-eslint/pull/11990/changes#r2718706741
f6d67b9 to
fbaa7a0
Compare
|
Hmm not sure why the CI checks were cancelled... |
bradzacher
left a comment
There was a problem hiding this comment.
This approach should work.
An alternate approach might be to use tokens:
- get the token (incl comments) before the import decl
- if it's on the same line then the decl is not on its own line
- else it's on its own line and and set delete start to
prevToken.range[1]
- get the token (incl comments) after the import decl
- if it's on the same line then the decl is not on its own line
- else it's on its own line and and set delete start to
nextToken.range[0]
That would let us guarantee that we can delete extra whitespace (which is a nice benefit).
There are two edge cases to handle with this though:
- if the import decl is the first statement in the file
- if the import decl is the last statement before non-decls
IDK if this is better than your current approach.. probably not due to the edge cases?
1 extra test and I think we're probably good to go?
…oving entire import
fbaa7a0 to
2615be3
Compare
Yeah because of edge cases I think this is as pretty as it gets. |
kirkwaiblinger
left a comment
There was a problem hiding this comment.
I'm happy with this as-is. The token approach sounds fine to me too so feel free to go with that but it looks like it'll just be a bit longer since you have to do the same wrangling of the edge case when there's no next line 🤷♂️
Thanks for sending this PR!
Thanks to you for all the feedback! Is always a pleasure to contribute to this project :) |
JoshuaKGoldberg
left a comment
There was a problem hiding this comment.
Ok I have to admit, it is nice to see all the removed lines in the test file 😄
Great work, thanks @MariaSolOs! Both on advocating for the change and implementing (+ re-implementing) it.
3df0002
into
typescript-eslint:main
| datasource | package | from | to | | ---------- | -------------------------------- | ------ | ------ | | npm | @typescript-eslint/eslint-plugin | 8.54.0 | 8.55.0 | | npm | @typescript-eslint/parser | 8.54.0 | 8.55.0 | ## [v8.55.0](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#8550-2026-02-09) ##### 🚀 Features - **utils:** deprecate defaultOptions in favor of meta.defaultOptions ([#11992](typescript-eslint/typescript-eslint#11992)) ##### 🩹 Fixes - **eslint-plugin:** \[no-useless-default-assignment] reduce param index to ts this handling ([#11949](typescript-eslint/typescript-eslint#11949)) - **eslint-plugin:** \[no-useless-default-assignment] report unnecessary defaults in ternary expressions ([#11984](typescript-eslint/typescript-eslint#11984)) - **eslint-plugin:** \[no-useless-default-assignment] require strictNullChecks ([#11966](typescript-eslint/typescript-eslint#11966), [#12000](typescript-eslint/typescript-eslint#12000)) - **eslint-plugin:** \[no-unused-vars] remove trailing newline when removing entire import ([#11990](typescript-eslint/typescript-eslint#11990)) ##### ❤️ Thank You - Christian Rose [@chrros95](https://github.com/chrros95) - Josh Goldberg - Maria Solano [@MariaSolOs](https://github.com/MariaSolOs) - Minyeong Kim [@minyeong981](https://github.com/minyeong981) - SungHyun627 [@SungHyun627](https://github.com/SungHyun627) - Yukihiro Hasegawa [@y-hsgw](https://github.com/y-hsgw) See [GitHub Releases](https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.55.0) for more information. You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website.
| datasource | package | from | to | | ---------- | -------------------------------- | ------ | ------ | | npm | @typescript-eslint/eslint-plugin | 8.54.0 | 8.55.0 | | npm | @typescript-eslint/parser | 8.54.0 | 8.55.0 | ## [v8.55.0](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#8550-2026-02-09) ##### 🚀 Features - **utils:** deprecate defaultOptions in favor of meta.defaultOptions ([#11992](typescript-eslint/typescript-eslint#11992)) ##### 🩹 Fixes - **eslint-plugin:** \[no-useless-default-assignment] reduce param index to ts this handling ([#11949](typescript-eslint/typescript-eslint#11949)) - **eslint-plugin:** \[no-useless-default-assignment] report unnecessary defaults in ternary expressions ([#11984](typescript-eslint/typescript-eslint#11984)) - **eslint-plugin:** \[no-useless-default-assignment] require strictNullChecks ([#11966](typescript-eslint/typescript-eslint#11966), [#12000](typescript-eslint/typescript-eslint#12000)) - **eslint-plugin:** \[no-unused-vars] remove trailing newline when removing entire import ([#11990](typescript-eslint/typescript-eslint#11990)) ##### ❤️ Thank You - Christian Rose [@chrros95](https://github.com/chrros95) - Josh Goldberg - Maria Solano [@MariaSolOs](https://github.com/MariaSolOs) - Minyeong Kim [@minyeong981](https://github.com/minyeong981) - SungHyun627 [@SungHyun627](https://github.com/SungHyun627) - Yukihiro Hasegawa [@y-hsgw](https://github.com/y-hsgw) See [GitHub Releases](https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.55.0) for more information. You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website.
| datasource | package | from | to | | ---------- | -------------------------------- | ------ | ------ | | npm | @typescript-eslint/eslint-plugin | 8.54.0 | 8.55.0 | | npm | @typescript-eslint/parser | 8.54.0 | 8.55.0 | ## [v8.55.0](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/eslint-plugin/CHANGELOG.md#8550-2026-02-09) ##### 🚀 Features - **utils:** deprecate defaultOptions in favor of meta.defaultOptions ([#11992](typescript-eslint/typescript-eslint#11992)) ##### 🩹 Fixes - **eslint-plugin:** \[no-useless-default-assignment] reduce param index to ts this handling ([#11949](typescript-eslint/typescript-eslint#11949)) - **eslint-plugin:** \[no-useless-default-assignment] report unnecessary defaults in ternary expressions ([#11984](typescript-eslint/typescript-eslint#11984)) - **eslint-plugin:** \[no-useless-default-assignment] require strictNullChecks ([#11966](typescript-eslint/typescript-eslint#11966), [#12000](typescript-eslint/typescript-eslint#12000)) - **eslint-plugin:** \[no-unused-vars] remove trailing newline when removing entire import ([#11990](typescript-eslint/typescript-eslint#11990)) ##### ❤️ Thank You - Christian Rose [@chrros95](https://github.com/chrros95) - Josh Goldberg - Maria Solano [@MariaSolOs](https://github.com/MariaSolOs) - Minyeong Kim [@minyeong981](https://github.com/minyeong981) - SungHyun627 [@SungHyun627](https://github.com/SungHyun627) - Yukihiro Hasegawa [@y-hsgw](https://github.com/y-hsgw) See [GitHub Releases](https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.55.0) for more information. You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website.

PR Checklist
Overview
The fixer introduced in #11922 leaves blank lines when removing the entire import statement. This PR modifies the fixer to remove trailing new lines when the entire statement is unused.