Skip to content

Commit 2e72c97

Browse files
committed
fix: add trailing comma after wrapped arrow expression body in call (#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.
1 parent f7dd1f3 commit 2e72c97

3 files changed

Lines changed: 120 additions & 1 deletion

File tree

src/generation/generate.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7618,6 +7618,18 @@ where
76187618
items.push_signal(Signal::SpaceIfNotTrailing);
76197619
}
76207620
items.push_condition(conditions::indent_if_start_of_line(generated_node));
7621+
// When the arrow's expression body forced the call onto multiple lines and
7622+
// the trailing-comma configuration is `always`, emit the trailing comma
7623+
// before the closing paren (issue #696). `onlyMultiLine` historically did
7624+
// not emit a comma here, so preserve that behavior to avoid churn.
7625+
let trailing_break_items = {
7626+
let mut break_items = PrintItems::new();
7627+
if matches!(trailing_commas, TrailingCommas::Always) {
7628+
break_items.push_sc(sc!(","));
7629+
}
7630+
break_items.push_signal(Signal::NewLine);
7631+
break_items
7632+
};
76217633
items.push_condition(if_true_or(
76227634
"isDifferentLineAndStartLineIndentation",
76237635
Rc::new(move |context| {
@@ -7627,7 +7639,7 @@ where
76277639
let is_different_start_line_indentation = start_lsil != context.writer_info.line_start_indent_level;
76287640
Some(is_different_line && is_different_start_line_indentation)
76297641
}),
7630-
Signal::NewLine.into(),
7642+
trailing_break_items,
76317643
if space_around { Signal::SpaceIfNotTrailing.into() } else { PrintItems::new() },
76327644
));
76337645
} else {
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
~~ lineWidth: 60, trailingCommas: always ~~
2+
== should add trailing comma to single-arg call ==
3+
foo(x);
4+
5+
[expect]
6+
foo(x,);
7+
8+
== should add trailing comma to multi-arg call ==
9+
foo(a, b, c);
10+
11+
[expect]
12+
foo(a, b, c,);
13+
14+
== should add trailing comma in multi-line call ==
15+
foo(
16+
aLongerName,
17+
anotherLongerName
18+
);
19+
20+
[expect]
21+
foo(
22+
aLongerName,
23+
anotherLongerName,
24+
);
25+
26+
== should add trailing comma after arrow expression body when call wraps (issue #696) ==
27+
[1, 2, 3].map(value =>
28+
value == "a quite long paragraph with many words")
29+
30+
[expect]
31+
[1, 2, 3,].map(value =>
32+
value == "a quite long paragraph with many words",
33+
);
34+
35+
== should add trailing comma after block-bodied arrow ==
36+
foo(
37+
(v) => {
38+
return v;
39+
}
40+
)
41+
42+
[expect]
43+
foo(
44+
(v,) => {
45+
return v;
46+
},
47+
);
48+
49+
== should not add trailing comma after rest argument in call when never-trailing applies ==
50+
foo(...args);
51+
52+
[expect]
53+
foo(...args,);
54+
55+
== should not add trailing comma in dynamic import ==
56+
import(
57+
"myreallylongdynamicallyloadedmodulename"
58+
);
59+
60+
[expect]
61+
import(
62+
"myreallylongdynamicallyloadedmodulename"
63+
);
64+
65+
== should add trailing comma when last arg is arrow whose body wraps ==
66+
a.b().c({ d: 1 }, () =>
67+
doSomethingThatDoesNotFitOnTheSameLine())
68+
69+
[expect]
70+
a.b().c(
71+
{ d: 1, },
72+
() => doSomethingThatDoesNotFitOnTheSameLine(),
73+
);

tests/specs/issues/issue0696.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
~~ lineWidth: 60, trailingCommas: always ~~
2+
== should add trailing comma after arrow expression body when call breaks across lines (issue #696) ==
3+
const test = ["a","b","c"].map(value =>
4+
value == "a quite long paragraph with many words")
5+
6+
[expect]
7+
const test = ["a", "b", "c",].map(value =>
8+
value == "a quite long paragraph with many words",
9+
);
10+
11+
== should add trailing comma after nested expression body that wraps ==
12+
longCallExpression(value =>
13+
someVeryLongCondition && anotherCondition)
14+
15+
[expect]
16+
longCallExpression(value =>
17+
someVeryLongCondition && anotherCondition,
18+
);
19+
20+
== should not add trailing comma when arrow body stays on the same line ==
21+
foo(v => v);
22+
23+
[expect]
24+
foo(v => v);
25+
26+
== should keep dynamic import without trailing comma ==
27+
import(
28+
"myreallylongdynamicallyloadedmodulename"
29+
);
30+
31+
[expect]
32+
import(
33+
"myreallylongdynamicallyloadedmodulename"
34+
);

0 commit comments

Comments
 (0)