Repository navigation
Keep doc comments and comments in place in four formatter cases - #9119
Conversation
Changelog🐛 Bug fix
Semantic Diff1 commit · Full page ✨ Keep doc comments and comments in place in four formatter cases6d2afac · cknitt + Claude · Oct 28, 2026, 20:24 UTC · new
AST modified (doc comment after an attribute, after formatting) type u = /** d1 */ @a /** d2 */ {x: int}
type_declaration "u"
attribute "res.doc"
- attribute "res.doc"
attribute "a"
+ attribute "res.doc"Format modified (doc comment after an attribute) type u = /** d1 */ @a /** d2 */ {x: int}
/** d1 */
-/** d2 */
-@a type u = {x: int}
+@a /** d2 */ type u = {x: int}Format modified (doc comment on a hugged parameter) let f = (/** r */ {x, y}) => x
-let f = (/** r */
-{x, y}) => x
+let f = (
+ /** r */
+ {x, y},
+) => xFormat modified (comment before a list's tail spread) let l = list{1, /* c */ ...xs}
let f = (list{a, /* c */ ...rest}) => a
-let l = list{1, .../* c */ xs}
-let f = (list{a, .../* c */ rest}) => a
+let l = list{1, /* c */ ...xs}
+let f = (list{a, /* c */ ...rest}) => aFormat modified (file with only a line comment) // c
-"// c\n\n"
+"// c\n"Review
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #9119 +/- ##
=======================================
Coverage 81.47% 81.47%
=======================================
Files 460 460
Lines 64686 64688 +2
=======================================
+ Hits 52700 52705 +5
+ Misses 11986 11983 -3
🚀 New features to boost your workflow:
|
rescript
@rescript/belt
@rescript/darwin-arm64
@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-9119 |
|
@codex review |
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. |
|
Codex Review: Didn't find any major issues. Another round soon, please! 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". |
Why:
The formatter put doc comments and comments in the wrong place in four
of the cases reported in #9107, and in one of them it reordered the
attributes in the AST. Doc comments after an attribute were moved in
front of all attributes. A single parameter with a doc comment was
hugged, so its pattern started at column 0. A comment before a list's
tail spread was printed after the dots, in expressions and in
patterns. A file with only a line comment got an extra newline.
Only the doc comments in front of every other attribute are now
printed first; later ones stay in their place, inline. The fifth case,
a comment after a parenthesized `switch` or `if` operand that moves
into the block, keeps its stable output.
AST modified (doc comment after an attribute, after formatting):
Example:
type u = /** d1 */ @A /** d2 */ {x: int}
Before (parse):
type_declaration "u"
attribute "res.doc"
attribute "res.doc"
attribute "a"
After (parse):
type_declaration "u"
attribute "res.doc"
attribute "a"
attribute "res.doc"
Format modified (doc comment after an attribute):
Example:
type u = /** d1 */ @A /** d2 */ {x: int}
Before (rescript):
/** d1 */
/** d2 */
@A type u = {x: int}
After (rescript):
/** d1 */
@A /** d2 */ type u = {x: int}
Format modified (doc comment on a hugged parameter):
Example:
let f = (/** r */ {x, y}) => x
Before (rescript):
let f = (/** r */
{x, y}) => x
After (rescript):
let f = (
/** r */
{x, y},
) => x
Format modified (comment before a list's tail spread):
Example:
let l = list{1, /* c */ ...xs}
let f = (list{a, /* c */ ...rest}) => a
Before (rescript):
let l = list{1, .../* c */ xs}
let f = (list{a, .../* c */ rest}) => a
After (rescript):
let l = list{1, /* c */ ...xs}
let f = (list{a, /* c */ ...rest}) => a
Format modified (file with only a line comment):
Example:
// c
Before (text): "// c\n\n"
After (text): "// c\n"
Review: Why not fix the comment after a parenthesized operand? It formats
stably with the same AST; fixing it needs a token flag on comments or
operand locations that include the parentheses.
Fixes: #9107
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Kbf3gGkPma9LAZimuQjnrP
Signed-off-by: Christoph Knittel <[email protected]>
2cf5866 to
6d2afac
Compare
|
@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". |
cristianoc
left a comment
There was a problem hiding this comment.
Looks good to me. Thanks for the fix.
The formatter put doc comments and comments in the wrong place in the cases reported in #9107. In one of them it also changed the order of the attributes in the AST, so formatting changed the program that PPXs see.
partition_doc_comment_attributesmoved every doc comment in front of all attributes. For example,type u = /** d1 */ @a /** d2 */ {x: int}came out as/** d1 */ /** d2 */ @a type u. It now takes only the doc comments that come before every other attribute.print_attributesprints later ones inline, in their place:/** d1 */on its own line, then@a /** d2 */ type u = {x: int}. This keeps the attribute order in declarations, constructors, record fields, polymorphic variant tags, type expressions, patterns and module arguments. It also fixestype q = @a /** d */ int, which used to print astype q = /** d */ @a intand then no longer parsed.parameters_should_hugchecked only the parameter's own attributes, but the doc comment is stored on the pattern.let f = (/** r */ {x, y}) => xtherefore printed{x, y}) => xat column 0. A doc comment on the pattern now prevents hugging, and the parameter gets the normal indented layout.list{1, /* c */ ...xs}printed aslist{1, .../* c */ xs}. The list-with-tail printer now uses the same code as the array and dict spreads, now shared asprint_spread_with_comments, so leading comments go before the dots. The list pattern tail takes its leading comments before printing the dots as well.Two related layouts stay as they are. They format stably and keep the AST the same, so they are accepted:
switch/if/loop operand (switch (x) // c) still moves into the block. Fixing it would need a token flag on comments or operand locations that include the parentheses.Tests
printer/comments/docCommentAttributes.resandprinter/typeDef/attributes.res: doc comments after attributes on declarations, constructors, fields, tags and type expressions, including the issue's example.printer/comments/docCommentParameters.res: hugged record, array, tuple and unit parameters with a doc comment, and one with an attribute before the doc comment.printer/comments/array.res: comments around a list's tail spread in expressions and patterns.pattern.resputs the comment before the dots;modExpr/attributes.resandtypeDef/attributes.reskeep the attribute order.Fixes #9107
🤖 Generated with Claude Code
https://claude.ai/code/session_01Kbf3gGkPma9LAZimuQjnrP