-
-
Notifications
You must be signed in to change notification settings - Fork 481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(analyzer): top level suppression #4306
Conversation
CodSpeed Performance ReportMerging #4306 will not alter performanceComparing Summary
|
f78eaf7
to
16fa3ad
Compare
2de0850
to
7d9cd48
Compare
7d9cd48
to
1a59e00
Compare
May I ask why we need to enforce top level suppression to be a block comment? Some languages, like GraphQL 😅, only have single line comment. |
I wasn't aware of that. I should be able to lift the restriction |
1a59e00
to
fbd3c8c
Compare
fbd3c8c
to
3b3392f
Compare
@vohoanglong0107 The algorithm has been updated, and the heuristic is different. I updated the PR description to reflect that. |
b945709
to
d1c6e89
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wasn't needed, it didn't emit any suppressions
} | ||
} | ||
|
||
pub(crate) fn with_tags(mut self, tags: DiagnosticTags) -> Self { | ||
self.tags |= tags; | ||
pub(crate) fn note(mut self, message: impl Into<String>, range: impl Into<TextRange>) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new API was created to suppose this new diagnostic: https://github.com/biomejs/biome/pull/4306/files#diff-6b7a758a5c6e91dd2722ccc423ad136ff4e811311c0d49b80c659d61cc54e2a6
Neat :)
/// List of all the rule instances this comment has started suppressing. | ||
suppressed_instances: Vec<(RuleFilter<'static>, String)>, | ||
suppressed_instances: FxHashMap<String, RuleFilter<'static>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to swap this, because the primary key is the instance, not the filter.
|
||
(self.emit_signal)(&signal)?; | ||
if is_top_level_suppression { | ||
self.top_level_suppressions.expand_range(range); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might encounter multiple top level comments, so we need to expand its initial range until the end.
/// A suppression using the legacy syntax to disable a specific rule eg. `// biome-ignore lint(style/useWhile)` | ||
MaybeLegacy(&'a str), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed anymore. It was an old rome thing (the TS codebase one)
pub fn is_inline_suppression(&self) -> bool { | ||
self.category.matches(SUPPRESSION_INLINE_ACTION_CATEGORY) | ||
} | ||
|
||
pub fn is_top_level_suppression(&self) -> bool { | ||
self.category.matches(SUPPRESSION_TOP_LEVEL_ACTION_CATEGORY) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will need these two new functions for the upcoming feature from @anthonyshew
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great stuff! I think people are going to love this!
I do have my doubts about the requirement to have two newlines following the suppression comment. I understand why you’re doing it, but it’s not intuitive and hard to explain. It feels like a “magic behavior” that you have to know about that will easily bite you if you don’t.
Can’t we have a syntax like biome-ignore-all
so that we can lift this requirement?
I put great thoughts into what you suggested. At the beginning, I thought it could work, however I found two downsides that are worth considering. First, lifting the "2 newlines" requirement could cause issues with the import sorting, where a comment is moved with its relative import statement: // biome-ignore-all lint/style/useConst: reason
import zod from "zod"
import lodash from "lodash" // added by IDE automatically If we execute the import sorting, the first import statement will be moved to the end, together with the suppression comment. This will break the suppression system. The "2 newlines" are already understood by the import sorting, which are used as a separator for groups. Second, we need to consider if this new suppression kind has repercussions on the formatter. If so, how? So, if we would want to implement a new suppression kind, we would need to consider what we need to change, where and how. |
Yeah, the import sorting is a valid concern indeed. We could solve it by adding an exception in the sorter, which is one of the benefits of an integrated solution like Biome. It would be extra effort for us, but I think it may benefit users. Not sure what impact it would have on the formatter though. At least I can’t really think of something… The formatter should leave comments where they are, so it should remain a top-level suppression, right? I guess if you wanted to you could let the formatter recognize |
OK, I will apply this change in a later PR. cc @Conaclos, as you're involved in the import sorting, and you should be interested in this conversation. |
Summary
Closes #4305
This PR introduces a new type of suppression: top-level suppression.
TL;DR:
The top-level suppression works only if:
This means this comment is seen as a "next line suppression", and it should raise a diagnostic for
let bar = 12
:To recognise them, the
parse_suppression_comment
now accepts aSyntaxToken
. If the range of the comment starts at0
and there are exactly two newlines after the comment, it means that it's a top-level suppression. The range check is done with the trivia, because we want to make sure to catch the0
position.This PR also removes legacy suppression comments.
More changes
The
Rule
type generates the suppression viaR::suppress
function. Initially, I wanted to change the type returned to aVec
, but that doesn't play well with our infrastructure because the returned type is mapped exactly to a code action, which means that returning a vector wasn't possible.I renamed
R::suppress
toR::inline_suppression
, and I created a new function calledR::toplevel_suppression
. This function leverage the already existing traitSuppressionAction
, which now requires to implement a new function calledapply_top_level_suppression
. The logic of this function is way simpler than that of inline suppression. This function accepts the first token of a root CST, and from there, it's very simple to prepend a new comment trivia.I also created two new known variants to the action category called
OtherActionCategory
, where we can add new known LSP client signals. These two signals were added to the LSP client capabilities.Test Plan
I added various tests for the CLI and the analyzer.
I also updated the LSP tests, which now send a new action for the top-level suppression. I manually tested this with Zed, and I can correctly see the new top-level action pulled and applied via the editor.