-
Notifications
You must be signed in to change notification settings - Fork 657
feat(rome_js_formatter): variable declarator formatting #2737
feat(rome_js_formatter): variable declarator formatting #2737
Conversation
…nt_if_parent_indents
Will be ready for review after #2729 |
Need to check because Rome and Prettier have different IR for these cases: https://gist.github.com/MichaReiser/77799fe4363bcc48838a159e581d8229#jsassignmentunaryjs
|
crates/rome_js_formatter/tests/specs/prettier/js/babel-plugins/record-tuple-record.js.snap
Show resolved
Hide resolved
crates/rome_js_formatter/tests/specs/prettier/js/bind-expressions/long_name_method.js.snap
Outdated
Show resolved
Hide resolved
d10fcf5
to
984337f
Compare
crates/rome_js_formatter/tests/specs/js/module/string/properties_quotes.js.snap
Show resolved
Hide resolved
crates/rome_js_formatter/tests/specs/prettier/js/babel-plugins/record-tuple-record.js.snap
Show resolved
Hide resolved
crates/rome_js_formatter/tests/specs/prettier/js/bind-expressions/long_name_method.js.snap
Outdated
Show resolved
Hide resolved
…ing' into feature/variable-declarator-formatting # Conflicts: # crates/rome_js_formatter/src/lib.rs # crates/rome_js_formatter/src/utils/assignment_like.rs # crates/rome_js_formatter/tests/specs/js/module/assignment/assignment.js # crates/rome_js_formatter/tests/specs/js/module/assignment/assignment.js.snap # crates/rome_js_formatter/tests/specs/prettier/js/assignment/chain.js.snap
_ => None, | ||
} | ||
} | ||
} | ||
|
||
pub(crate) fn is_complex_type_annotation( |
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.
@@ -183,14 +252,19 @@ pub(crate) enum AssignmentLikeLayout { | |||
} | |||
|
|||
impl JsAnyAssignmentLike { | |||
fn right(&self) -> SyntaxResult<RightAssignmentLike> { | |||
fn right(&self) -> Option<RightAssignmentLike> { |
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.
Is there a particular reason why we changed this into an Option
? The reason why we want SyntaxResult
, is to usually bubble up any syntax error and prevent formatting nodes that are syntactically wrong.
And if the right hand side is missing, it's usually a syntax error.
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.
Yes, you're right. But for JsVariableDeclarator
variant a right part is initializer
and it has Option<JsInitializerClause>
type. We can try to keep SyntaxResult
:
- make
fn right(&self) -> SyntaxResult<Option<RightAssignmentLike>>
. I have concerns that it will be more difficult to use. - unwrap
Option<JsInitializerClause>
here and introduceshould_only_left
function which will be a guarantee of safety.
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.
Yeah, I agree that having SyntaxResult<Option<RightAssignmentLike>
would add a lot of branches/indirection/safety comments. Let's try your second suggested solution. Documenting should_only_left
should help developers understand why we're doing this
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.
@@ -0,0 +1,27 @@ | |||
//break left-hand side layout |
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.
Would you mind adding a test case with a suppression comment? We should make sure that the layout formatting is not applied to the node that is suppressed
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.
c5223b9
Is it correct?
Could you please explain why we need this test? How could we by-pass a suppression comment?
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 could by-pass it by not calling .format()
on a node. Because this union is now taking charge of many nodes (left and right are now unions), we have to be careful and make sure that each node of left and right call format()
…ing' into feature/variable-declarator-formatting # Conflicts: # crates/rome_js_formatter/src/utils/assignment_like.rs
bc1479a
to
796332b
Compare
RightAssignmentLike::JsAnyExpression( | ||
JsAnyExpression::JsArrowFunctionExpression(arrow), | ||
) => { | ||
dbg!("here"); |
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 shouldn't be in here :O
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 PR is closed :( I created another one and it didn't have this line :) #2762
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.
Too bad, I hoped that the performance regression comes from the dbg
expression 😞
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.
Do we have tools to diagnostic the performance issue?
How do you usually debug this?🙏🏼
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.
You can run cargo bench_formatter
to profile the formatter. The command has two useful options
--save-baseline=<name>
: Stores the result under the given name. Useful to e.g. run the benchmarks on main first so that you can then compare against these base results. To compare benchmark, usecritcmp <name1> <name2>
(requires critcmp)- --filter=
filters the files to benchmarks. I often go with
tex-chtml-full` because it seems to be big enough that performance improvements are visible but doesn't take as long to run as e.g. typescript.
Finding bottlenecks inside the formatter can be difficult and the available tools vary depending on the platform you use:
- Mac: I very much like cargo-instruments.
- CLion has a built-in profiler for Linux and I believe MacOS.
The rust book lists some more available tools as well as how you can enable debug information in release builts (you want that to be able to make sense of the output)
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 just found Firefox Profiler. You can do profiling with (assuming linux and that perf is installed)
cargo build --release
perf record -F999 --call-graph dwarf cargo bench_formatter --filter tex --criterion=false
perf script -F +pid > /tmp/test.perf
Then upload the file on the website. They also have great documentation
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.
Thank you so much for your answers!
I'll try to debug it.
Small note. This PR seems to have added a roughly 10% performance regression. I would say this is kind of expected as it has to do many checks but I'm wondering if there are any hotspots that could be improved. We need to be careful to not slowly regress performance by a large margin. Before
After
|
Summary
This PR partially implements #2423
This PR adds
OnlyLeft
layout to the list of layouts. This layout is hit, usually, when variable declarator doesn't have initializer.should_break_left_hand_side
when variable declarationhas_complex_type_annotation
. Prettier hasComplexTypeAnnotation.should_not_indent_if_parent_indents
. Don't indent ifgreat_parent
isJS_VARIABLE_DECLARATOR
.Open questions
There are problems with
BindExpression
andRecordExpression
. I described them in comments.Test Plan
Add new tests specs