Repository navigation
format JSX expression children with explicit braces - #8666
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
4495a55 to
78476d8
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a479f8349e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
78476d8 to
701313d
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 701313d0e0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #8666 +/- ##
==========================================
+ Coverage 80.51% 80.54% +0.03%
==========================================
Files 447 447
Lines 61060 61155 +95
==========================================
+ Hits 49162 49259 +97
+ Misses 11898 11896 -2
🚀 New features to boost your workflow:
|
rescript
@rescript/belt
@rescript/darwin-arm64
@rescript/darwin-x64
@rescript/linux-arm64
@rescript/linux-x64
@rescript/runtime
@rescript/win32-x64
commit: |
|
Developer playground preview: https://rescript-lang.github.io/rescript/dev-playground/?version=pr-8666 |
|
@codex review |
|
Codex Review: Didn't find any major issues. 🎉 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
Good to be moving closer to JS here in terms of whitespace handling. The multiline formatting as can be seen in the snapshot diffs seems weird to me though, and doesn't seem to be necessary / match JS behavior. ReScript, before the change: let x =
<div>
{value
? <XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX />
: <YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY />}
</div>ReScript, after the change: let x =
<div>{
value
? <XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX />
: <YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY />
}</div>Prettier (JS): let x = (
<div>
{value ? (
<XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX />
) : (
<YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY />
)}
</div>
);Babel output for the latter: import { jsx as _jsx } from "react/jsx-runtime";
let x = /*#__PURE__*/_jsx("div", {
children: value ? /*#__PURE__*/_jsx(XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX, {}) : /*#__PURE__*/_jsx(YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY, {})
});So it is not necessary that the opening/closing brace moves to the line of the opening/closing JSX tag. |
e1ac4c7 to
7442c14
Compare
4697172 to
e7c4842
Compare
|
@codex review |
|
Tested against a large company project of ours. Looks perfect now, only the expected changes, no more unexpected multiline format changes. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8b62553851
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
a98621e to
0635ad6
Compare
|
Thanks for working on this! I had Claude review the PR. It built Correctness
Cleanups
Each of these cases would make a good addition to the syntax test fixtures, together with |
|
@codex review |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
There was a problem hiding this comment.
Thanks, this looks solid. I ran a batch of edge cases through it at several widths: all stable, comments kept, no semantic changes. It also fixes several cases where the current formatter moves comments around. A few remaining points:
Design: print line comments as block comments
Line comments in children currently expand to multiline blocks:
// standalone `// c` becomes
{
// c
}
// `x // note` becomes
{
x // note
}
// `{x} // note` gets detached from its expression
{x}
{
// note
}Would it be worth turning them into block comments when the text doesn't contain */? Then these would print as {/* c */} and {x /* note */}, and x // note and {x} // note would format the same way. I understand keeping the comment style was deliberate. I'm raising it because of the churn this will cause in existing codebases.
Nits
res_printer.ml:4841:if doc = Doc.nilrelies on structural equality onDoc.t; branching onhas_children(or matching) would be clearer.res_core.ml:2926: thep.comments != comments_beforecheck only works becauseParser.nextcommits a token's leading comments when it consumes that token, so the secondnextadds exactly the comments inside the braces. A short comment saying so would help, since it depends on parser internals.res_comment.ml:16:jsx_containeris mutable state on the comment object, sowith_checkpointdoesn't roll it back. It's harmless today, since the only speculative parses are attributes, which re-parse the same way. It would be worth a note in case JSX ever gets parsed speculatively.
🤖 Generated with Claude Code
5bb2161 to
3f84589
Compare
Signed-Off-By: Paul Tsnobiladzé <dontshootthink@gmail.com>
Signed-Off-By: Paul Tsnobiladzé <dontshootthink@gmail.com>
Signed-Off-By: Paul Tsnobiladzé <dontshootthink@gmail.com>
Signed-Off-By: Paul Tsnobiladzé <dontshootthink@gmail.com>
Signed-Off-By: Paul Tsnobiladzé <dontshootthink@gmail.com>
Signed-Off-By: Paul Tsnobiladzé <dontshootthink@gmail.com>
Signed-Off-By: Paul Tsnobiladzé <dontshootthink@gmail.com>
Signed-Off-By: Paul Tsnobiladzé <dontshootthink@gmail.com>
Signed-Off-By: Paul Tsnobiladzé <dontshootthink@gmail.com>
Signed-Off-By: Paul Tsnobiladzé <dontshootthink@gmail.com>
Signed-Off-By: Paul Tsnobiladzé <dontshootthink@gmail.com>
Signed-Off-By: Paul Tsnobiladzé <dontshootthink@gmail.com>
Signed-Off-By: Paul Tsnobiladzé <dontshootthink@gmail.com>
3f84589 to
239d943
Compare
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@codex review |
|
Codex Review: Didn't find any major issues. Bravo. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
cknitt
left a comment
There was a problem hiding this comment.
Thanks, the nits are all addressed and the block-comment conversion works nicely. I checked the edge cases: //*doc doesn't turn into a doc comment, and comments that contain a delimiter keep the line form. Formatting is stable at every width I tried.
Two very minor things left, both optional:
-
A line comment after an already braced child still ends up in its own container:
// input <div> {x} // note </div> // output <div> {x} {/* note */} </div>
The unbraced form
x // noteprints as<div>{x /* note */}</div>. It would be nice if both did that. -
Line comments on adjacent lines become a multiline container with one block comment per line:
{ /* c1 */ /* c2 */ }{/* c1 */ /* c2 */}would be more compact, but following the source line layout is reasonable too.
Neither needs to block this PR.
🤖 Generated with Claude Code
|
@cknitt I'm merging it as is, I feel like we might presume too much of the user's intentions when merging the line-comment inside the braces or merging multiple block comments. We can of course revisit this later after some usage. |
Prepare JSX for future literal text support by formatting expression children with explicit braces and no surrounding inline spaces:
Existing unbraced expressions remain valid syntax. Nested JSX elements stay unwrapped, and existing expression braces do not accumulate. Single expression children stay inline when they fit; multiline children remain indented between the opening and closing tags.
Standalone comments use their own comment-only containers, including before or after expression children and in empty elements or fragments. Separate containers, comment order, and intentional blank-line separation are preserved:
To reduce formatting churn, safe JSX child line comments become block comments. Conversion is limited to comments whose text contains neither
/*nor*/; comments containing either delimiter retain//and the newlines needed to keep the closing brace outside the comment. Comments already inside an expression container stay with that expression:The parser retains comment-only containers as trivia without adding a child, preserving the distinction between zero, one, and multiple children for React and custom JSX. Bare
{}still denotes an empty record child;{{/* comment */}}keeps the comment inside that record.Literal text parsing remains future work, including handling formatting indentation around children. The next migration step is to reject unbraced expressions before enabling literal text, so existing variable references cannot silently become strings.
Validation:
make test,make test-syntax,make test-syntax-roundtrip, andyarn changelog:checkpass locally.Supersedes #7863.