-
Notifications
You must be signed in to change notification settings - Fork 664
feature(formatter): Add BestFitting
IR element
#2591
Conversation
Deploying with Cloudflare Pages
|
6b85f2f
to
77c4385
Compare
Parser conformance results on ubuntu-latestjs/262
jsx/babel
ts/babel
ts/microsoft
|
This PR introduces the new IR element `BestFitting`. The IR matches Prettier's `ConditionalGroupContent`. This IR can be useful if the best representation depends on the available space. `BestFitting` defers the choice of how to print the element to the printer by providing multiple variants. The printer picks the element that best fits given the circumstances (that's where its name is coming from but I'm open for better names). The printer picks the first variant that fits on the current line and falls back to print the last variant in expanded mode if no variant fits.
77c4385
to
b27630c
Compare
|
||
queue.enqueue(PrintElementCall::new( | ||
variant, | ||
args.with_print_mode(PrintMode::Expanded), |
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 it make sense to have the first variant printed in flat mode ? Or maybe it wouldn't make any difference
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.
That's where I intentionally diverged from prettier as I outlined in the PR.
Prettier wraps each variant in an implicit Group
which is why they try to fit each element with Flat
first. We can do the same. The downside of this is that you often want to remove the implicit group from the second variant because you want to make that one break. Prettier does that by commonly wrapping all of the 1... variants in a group with shouldBreak: true
.
We can also go a middle way and add an implicit group for the first variant but not for the other variants. But I'm not sure if that will be confusing.
Nvm, saw comment. I think it's good for now, although I do think it's a little dangerous to have an IR element that relies on an invariant that we don't check. |
|
||
impl BestFitting { | ||
pub fn new(variants: Vec<FormatElement>) -> Self { | ||
assert!(variants.len() > 1, "The variants collection must contain at least two variants where the first is the least expanded state and the last element the most expanded option."); |
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 it necessary to panic when someone tries to construct an invalid BestFitting
rather than returning a result?
Would it be reasonable to expand FormatError
to account for errors during IR construction?
If the intended use of best_fitting
is that it's always passed a vec!
literal rather than a dynamically built up vector, maybe best_fitting
could be a macro that ensures there are always at least two variants at compile-time?
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.
All usages in prettier are indeed using a fixed set of variants. It's unfortunate that rust doesn't allow for var args without using macros.
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 introduced a best_fitting
macro that checks the invariant and marked the from_slice_unchecked
as unsafe.
This PR introduces the new IR element
BestFitting
. The IR matches Prettier'sConditionalGroupContent
. This IR can be useful if the best representation depends on the available space.BestFitting
defers the choice of how to print the element to the printer by providing multiple variants. The printer picks the element that best fits given the circumstances (that's where its name is coming from but I'm open to better names).The printer picks the first variant that fits on the current line and falls back to print the last variant in expanded mode if no variant fits.
Part of #2579
Test Plan
I added an integration test as part of the documentation of the
best_fitting
function.