Skip to content

fix: add trailing comma after wrapped arrow expression body in call (#696)#789

Open
todor-a wants to merge 2 commits into
dprint:mainfrom
todor-a:fix-trailing-comma-arrow-expr-body
Open

fix: add trailing comma after wrapped arrow expression body in call (#696)#789
todor-a wants to merge 2 commits into
dprint:mainfrom
todor-a:fix-trailing-comma-arrow-expr-body

Conversation

@todor-a

@todor-a todor-a commented May 28, 2026

Copy link
Copy Markdown
Contributor

Fixes #696.


Transparency note: This PR was prepared with AI assistance (Claude).


Problem

With trailingCommas: always:

const test = ["a","b","c"].map(value =>
  value == "a quite long paragraph with many words")

…formats to (no comma after the arrow body):

const test = ["a", "b", "c",].map(value =>
  value == "a quite long paragraph with many words"
)

Issue reports the expected output should be:

const test = ["a", "b", "c",].map(value =>
  value == "a quite long paragraph with many words",
)

Root cause

gen_parameters_or_arguments (src/generation/generate.rs) has a special branch for calls with a single argument that is an arrow function with an expression body:

if !force_use_new_lines && nodes.len() == 1 && is_arrow_function_with_expr_body(nodes[0]) {
    …
    items.push_condition(if_true_or(
      "isDifferentLineAndStartLineIndentation",,
      Signal::NewLine.into(),                    // <-- true branch: just newline
      if space_around {} else {},
    ));
}

When the arrow body forces the call onto multiple lines, the true branch emits a bare Signal::NewLine before the closing paren — no comma, regardless of trailingCommas. The fallthrough gen_separated_values branch (which honors trailingCommas via separator: trailing_commas.into()) is bypassed.

Fix

Inject , into the true branch when trailingCommas resolves to always:

let trailing_break_items = {
  let mut break_items = PrintItems::new();
  if matches!(trailing_commas, TrailingCommas::Always) {
    break_items.push_sc(sc!(","));
  }
  break_items.push_signal(Signal::NewLine);
  break_items
};
items.push_condition(if_true_or(
  "isDifferentLineAndStartLineIndentation",,
  trailing_break_items,,
));

Scope is limited to always. onlyMultiLine keeps existing behavior — extending it would update several existing specs (issue105, issue165, JsxElement_MultiLineParens_Never, Arguments_SpaceAround_True) and might surprise users running the default config. Could be revisited as a follow-up.

Tests

Corner-case probe also based on prettier's tests/format/js/trailing-comma (function-calls.js, dynamic-import.js, jsx.js).

todor-a added 2 commits May 28, 2026 14:11
…print#696)

`gen_parameters_or_arguments` has a special branch for single-argument
calls whose argument is an arrow function with an expression body. When
the body wraps the call across lines, the branch emitted a plain
`Signal::NewLine` before the closing paren, never a comma — so:

    ["a", "b", "c"].map(value =>
      value == "a long paragraph"
    )

…stayed comma-less even with `trailingCommas: always`.

Emit `,` in that conditional branch when `trailingCommas` resolves to
`always`. `onlyMultiLine` keeps its previous behavior to avoid churn
for the default config; switching it would update many existing specs
and could be revisited separately.
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.

Does not add trailing comma for multi-line arrow functions

1 participant