Skip to content

Keep comments on labelled parameters in the formatter - #8690

Merged
cknitt merged 7 commits into
masterfrom
cristianoc/fix-formatter-labelled-param-comments
Oct 3, 2026
Merged

cknitt merged 7 commits into
masterfrom
cristianoc/fix-formatter-labelled-param-comments

Conversation

@cristianoc

@cristianoc cristianoc commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Part of #8712.

Summary

  • Print a comment before a default value's = once. walk_expr_parameter split the trailing comments of a labeled parameter's pattern into those adjacent to it and the rest, discarded the first part (_afterPat) and attached the whole list to the pattern while also walking the rest into the default expression, so (~x as y /* a / = / b / 1) printed / b */ twice. Attach only the adjacent comments, as walk_expr_argument does.
  • Print comments on punned labelled parameters. The printer prints a punned labelled parameter (~x, ~x: t) from its label and type, without the pattern, so comments the comment table attaches to the pattern or to the variable inside its type constraint are printed only when that location coincides with the whole parameter's. With a default value it does not, and the comments are dropped: (~x /* a / = / b / 1, ()) printed as (~x=/ b / 1, ()) (~x: int / a / = 1, ()) printed as (~x: int=1, ()) (~x / a */ : int, ()) printed as (~x: int, ())
  • Print =? after the comments of an optional arrow-type argument. The printer printed an optional labelled argument of an arrow type with =? inside the span whose trailing comments it prints, so a comment before =? was printed after it: type f = (~x: int /* a / =?, unit) => int printed as (~x: int=? / a */, unit) => int

Test plan

  • dune build
  • dune build @fmt
  • dune build --profile browser @check
  • make
  • make lib
  • no change in the runtime and Belt lib/ outputs
  • make test-syntax
  • make test-syntax-roundtrip
  • make test
  • make checkformat
  • npm run check

🤖 Generated with Claude Code

cristianoc and others added 3 commits October 2, 2026 07:36
walk_expr_parameter split the trailing comments of a labeled parameter's
pattern into those adjacent to it and the rest, discarded the first part
(_afterPat) and attached the whole list to the pattern while also walking
the rest into the default expression, so (~x as y /* a */ = /* b */ 1) printed
/* b */ twice. Attach only the adjacent comments, as walk_expr_argument does.

Signed-off-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The printer prints a punned labelled parameter (`~x`, `~x: t`) from its
label and type, without the pattern, so comments the comment table
attaches to the pattern or to the variable inside its type constraint are
printed only when that location coincides with the whole parameter's.
With a default value it does not, and the comments are dropped:

  (~x /* a */ = /* b */ 1, ())   printed as (~x=/* b */ 1, ())
  (~x: int /* a */ = 1, ())      printed as (~x: int=1, ())
  (~x /* a */ : int, ())         printed as (~x: int, ())

For `~x /* a */ = ?` the comment was printed after `=?`, where reparsing
attaches it to the next parameter, so formatting was not idempotent.

The punned cases now print the pattern's and the variable's comments, and
`=?` follows the parameter's trailing comments. The namedArgs comment
fixture covers default, typed, optional and aliased parameters; before
the change its snapshot lost `/* a */` in the first four new cases and
placed it after `=?` in the last three.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>
The printer printed an optional labelled argument of an arrow type with
`=?` inside the span whose trailing comments it prints, so a comment
before `=?` was printed after it:

  type f = (~x: int /* a */ =?, unit) => int
  printed as (~x: int=? /* a */, unit) => int

Reparsing attaches that comment to the next argument, so a second format
gave (~x: int=?, /* a */ unit), and for a last argument moved it onto the
return type. The argument's location ends at its type, before `=?`, so its
trailing comments now print before `=?`.

The typexpr comment fixture covers a type alias, a last argument and an
external; before the change its snapshot placed `/* a */` after `=?` in
all three.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>
@cristianoc
cristianoc requested a review from cknitt October 2, 2026 06:29
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-02T06:32:48.822977Z b733f39 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b733f3949a

ℹ️ 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".

Comment thread compiler/syntax/src/res_printer.ml Outdated
print_comments doc cmt_tbl loc
(* [loc] ends before [=?], so the comments attached to it precede [=?] in
the source. *)
Doc.concat [print_comments doc cmt_tbl loc; optional_indicator]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve comments that follow =?

When an optional parameter is written as ~x: int=? /* after */, the comment walker attaches /* after */ to the same pre-marker location as a comment before =?; appending optional_indicator after print_comments therefore reformats it as ~x: int /* after */=?. The analogous expression path at line 5536 also changes ~x=? /* after */ into ~x /* after */=?, so the trailing comments must be partitioned by which side of the marker they occur on rather than placing all of them before it.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed: a comment written after =? (e.g. ~x: int=? /* after */, in a multi-line parameter list) was attached to the same location as one before =?, and both printed before the marker. 4cf8752 splits those trailing comments by their preceding token: a comment whose preceding token ends past the parameter location follows the ? of =? and prints after it, the others before. This applies to both the arrow-type path and the function-parameter path. New cases in printer/comments/namedArgs.res and typexpr.res cover after-only and before-and-after comments; they fail on the previous head and format stably.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up in 0a29474: on a single line, the comments walker gave a comment after =? to the next parameter (or to the body or return type), so (~x=? /* a */, ~y) changed on a second format. Comments now record whether their preceding token is ?, and the parameter-list walker keeps such comments with the preceding parameter. The printer also keeps a run like ~x /* a */ /* a2 */ =? before the marker. Short single-line cases in namedArgs.res and typexpr.res cover this, and formatting their output again gives identical text.

// comment 2
int,
) => unit = "test"
type optionalArg = (~x: int /* a */=?, unit) => int

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add this formatter fix to the changelog

This is a user-facing formatter bug fix, but the commit does not update CHANGELOG.md; add an entry under the current unreleased bug-fix section and end it with the PR link as required.

AGENTS.md reference: AGENTS.md:L93-L95

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in bfcc089, under the Unreleased section with the PR link.

@codecov

codecov Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.20%. Comparing base (7c1c3e9) to head (3bffa5a).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8690      +/-   ##
==========================================
+ Coverage   79.19%   79.20%   +0.01%     
==========================================
  Files         473      473              
  Lines       64031    64057      +26     
==========================================
+ Hits        50712    50739      +27     
+ Misses      13319    13318       -1     
Files with missing lines Coverage Δ
compiler/syntax/src/res_comment.ml 76.66% <100.00%> (+1.66%) ⬆️
compiler/syntax/src/res_comments_table.ml 89.20% <100.00%> (+0.08%) ⬆️
compiler/syntax/src/res_parser.ml 95.86% <100.00%> (+0.10%) ⬆️
compiler/syntax/src/res_printer.ml 93.48% <100.00%> (+0.06%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pkg-pr-new

pkg-pr-new Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

rescript

npm i https://pkg.pr.new/rescript@8690

@rescript/belt

npm i https://pkg.pr.new/@rescript/belt@8690

@rescript/darwin-arm64

npm i https://pkg.pr.new/@rescript/darwin-arm64@8690

@rescript/darwin-x64

npm i https://pkg.pr.new/@rescript/darwin-x64@8690

@rescript/linux-arm64

npm i https://pkg.pr.new/@rescript/linux-arm64@8690

@rescript/linux-x64

npm i https://pkg.pr.new/@rescript/linux-x64@8690

@rescript/runtime

npm i https://pkg.pr.new/@rescript/runtime@8690

@rescript/win32-x64

npm i https://pkg.pr.new/@rescript/win32-x64@8690

commit: 3bffa5a

@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown

cristianoc and others added 2 commits October 2, 2026 22:07
A trailing comment of an optional parameter without a default either
precedes =? or follows it in the source. The comment's preceding token
tells them apart: past the parameter's location it is the ? of =?. Both
the arrow-type and the function-parameter printers now place each
comment on its own side of =?.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>
On a single line, a comment after the =? of an optional parameter
became a leading comment of the next parameter, or of the body or
return type for the last one, so `(~x=? /* a */, ~y)` reformatted to
`(~x=?, /* a */ ~y)`. Comments record whether their preceding token is
`?`, and the list walker keeps such comments, together with the
comments adjacent to them, as trailing comments of the preceding
parameter.

The printer places before =? only the comments adjacent to the
parameter, so a run such as `~x /* a */ /* a2 */ =?` stays before the
marker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>
@cknitt

cknitt commented Oct 3, 2026

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: 0a294745df

ℹ️ 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".

@cknitt
cknitt enabled auto-merge (squash) October 3, 2026 06:11
@cknitt
cknitt merged commit 2a4c1c7 into master Oct 3, 2026
35 of 36 checks passed
@cknitt
cknitt deleted the cristianoc/fix-formatter-labelled-param-comments branch October 3, 2026 07:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants