-
Notifications
You must be signed in to change notification settings - Fork 656
refactor(rome_formatter): Pre-compute suppressions #2902
Conversation
!bench_formatter |
Parser conformance results on ubuntu-latestjs/262
jsx/babel
symbols/microsoft
ts/babel
ts/microsoft
|
Deploying with
|
Latest commit: |
e65085a
|
Status: | ✅ Deploy successful! |
Preview URL: | https://aa671e40.tools-8rn.pages.dev |
Branch Preview URL: | https://refactor-formatter-suppressi.tools-8rn.pages.dev |
Formatter Benchmark Results
|
739f903
to
8d7816b
Compare
!bench_formatter |
8d7816b
to
90e6178
Compare
Formatter Benchmark Results
|
90e6178
to
0ccd92f
Compare
0ccd92f
to
bf630fc
Compare
bf630fc
to
f65c7a3
Compare
This PR changes how the formatter extracts formatter suppression comments. The existing implementation used to traverse to a node's first token and then checking if it has any suppression comment when `context.is_suppressed()` was called. This PR iterates over the CST before starting the actual formatting to extract all suppressed nodes and stores them in an index that can be queried during formatting. The benefit of pre-computing the suppressions is that the logic can then be combined with the logic that extracts a nodes leading/trailing comments because that also requires iterating over all trivia pieces in the tree. Adding this traversal on its own would regress performance by about 10% which we can offset if combining it with the suppression handling because the use of `first_token` of the existing implementation is expensive. This change has the added benefit that suppressions are now a core formatter concept. ### Other changes This PR further fixes a few places where the formatter didn't correctly check if a node has any suppression comment and if so, prevents it from changing the formatting. ### Why add suppressions to the `FormatContext` I decided to introduce a new `FormatNodeContext` that replaces the existing `CommentsContext` and `CommentStyle` and now also stores the `suppressions`. The main reason for storing the suppressions on the context rather than on the `state` is that the context, unlike the `FormatState`, is language specific, and thus, it's possible to have a `Language` type parameter on the `Suppressions` type. The one thing I dislike about adding it to the context is that the context is changed AFTER its creation. ### Performance The performance of the two approaches are roughly the same. ### Future improvement It would be possible to improve Rome's overall performance if the workspace provides a way to combine the visitors run for the linter and the visitor for computing the suppression comments.
f65c7a3
to
90e72f7
Compare
Can someone read somewhere what you plan to do? If this is a refactor per preparing something else, I think the reviewers should know what's coming next, so they have more context and everything is out in the open. We can add some comment in the original issue to explain what you have in mind. |
The goal is to address #2768 by distinguishing between leading/node comments and dangling comments as described in this notion document. |
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 have mostly nitpicks
This PR further fixes a few places where the formatter didn't correctly check if a node has any suppression comment and if so, prevents it from changing the formatting.
Would it be possible to add new tests to make sure we demonstrate the bugs you found?
Co-authored-by: Emanuele Stoppa <[email protected]>
Co-authored-by: Emanuele Stoppa <[email protected]>
Summary
This PR changes how the formatter extracts formatter suppression comments. The existing implementation lazily traversed to a node's first token and it checks if the token has any leading suppression comments inside of
context.is_suppressed()
.This PR iterates over the CST before starting the actual formatting to extract all suppressed nodes and it stores them in an index that can be queried during formatting.
This is mainly preparing for the migration to extract leading and trailing node comments with the re-work of the comments handling. Determining if a node is suppressed then becomes as simple as iterating over the leading comments of a node and determining if it has any suppression comment.
This change also shows that the current implementation that calls
node.first_token
is roughly as expensive as iterating the whole tree ahead of time and computing the (suppression) comments.This change has the added benefit that suppressions are now a core formatter concept.
Part of #2768
Other changes
This PR further fixes a few places where the formatter didn't correctly check if a node has any suppression comment and if so, prevents it from changing the formatting.
Why add suppressions to the
FormatContext
The main reason for storing the suppressions on the context rather than on the
state
is that the context, unlike theFormatState
, is language specific, and thus, it's possible to have aLanguage
type parameter on theSuppressions
type.The one thing I dislike about adding it to the context is that the context is changed AFTER its creation.
Performance
The performance of the two approaches is roughly the same.
Future improvement
It would be possible to improve Rome's overall performance if the workspace provides a way to combine the visitors run for the linter and the visitor for computing the suppression comments.
Test Plan
cargo test