fix(formatter): keep JSX expression child flat when fill expands its separator#21917
Open
jsmecham wants to merge 1 commit intooxc-project:mainfrom
Open
fix(formatter): keep JSX expression child flat when fill expands its separator#21917jsmecham wants to merge 1 commit intooxc-project:mainfrom
jsmecham wants to merge 1 commit intooxc-project:mainfrom
Conversation
Merging this PR will not alter performance
Comparing Footnotes
|
370a8e3 to
54b0a82
Compare
…separator Fixes oxc-project#21916 When formatting a JSX child list, the printer's `Fill` correctly determined that an expression entry (e.g. `{toCash(...).display_cents}`) fit in flat mode even though the trailing separator needed to break. While printing that flat entry, however, inner groups re-ran their own `fits` check using `AllPredicate`, which walked past the entry boundary into subsequent fill entries — frequently overshooting `printWidth` and causing the expression group to needlessly expand into `{ \n expr \n }`. This adds an `in_flat_fill_item` flag on the printer state that's set while `print_fill_item` is printing a flat entry. Inner regular groups honor it and skip re-measuring (since the fill already verified the entry fits), while `BestFitting` still goes through its variant selection so JSX child lists with both flat and expanded variants can still pick the right form. Prettier conformance: no regressions (746/753 JS, 591/601 TS — unchanged). Co-authored-by: Claude <[email protected]>
54b0a82 to
79d2bfd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #21916
When a JSX expression child whose flat width fits at its current indent is followed by literal text such as
(, the formatter was breaking the expression across three lines ({, content,}) even though the line as written is withinprintWidth. Prettier leaves it inline.Input
Before (incorrect)
After (matches Prettier)
Root cause
In the printer's
Fill, each entry's fit is measured with a flat-onlyFitsMeasurerbounded bySingleEntryPredicate, so the fill correctly determined the expression entry fit on a single line. While printing that flat entry, however, the inner expression group (group(["{", indent([softline, expr]), softline, lineSuffixBoundary, "}"])) re-ran its ownfitscheck viaPrinter::fits, which usesAllPredicateand walks past the entry boundary into subsequent fill entries. The accumulated width frequently exceededprintWidth, so the inner group expanded — even though the fill had already proven the entry fits flat at the current column.Soft line breaks don't terminate a flat-mode
fitswalk (they're a no-op), so the measurement happily kept reading through the next item, separator, and so on until either a hard break or the end of the document.Fix
Adds an
in_flat_fill_itemflag on the printer state that's set whileprint_fill_itemis printing an entry in flat mode. TheStartGrouparm honors it and treats nested groups the same way it would when a parent group has already verified the fit — i.e. it skips the re-measurement and prints the inner group flat.The flag is intentionally scoped to regular groups:
BestFittingstill goes throughprint_best_fitting's variant selection so JSX child lists with both flat and expanded variants (the<Link>BREAK THIS</Link>pattern inissue-16199.jsx) continue to choose the multi-line variant when the surrounding context is too wide for the flat one.Prettier conformance: no regressions (746/753 JS, 591/601 TS — unchanged).
AI Disclosure
This PR was co-authored with Claude Code (AI assistant), as noted in the commit. The fix was reviewed, tested against the full Prettier conformance suite, and verified to produce no regressions.