Skip to content

Commit c2946a4

Browse files
committed
fix(formatter): check empty lines between arguments incorrectly
1 parent a5554a8 commit c2946a4

File tree

3 files changed

+165
-5
lines changed

3 files changed

+165
-5
lines changed

crates/oxc_formatter/src/write/call_arguments.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ impl<'a> Format<'a> for AstNode<'a, ArenaVec<'a, Argument<'a>>> {
4444
let r_paren_token = ")";
4545
let call_like_span = self.parent.span();
4646

47+
let arguments = self.as_ref();
48+
4749
if self.is_empty() {
4850
return write!(
4951
f,
@@ -69,7 +71,7 @@ impl<'a> Format<'a> for AstNode<'a, ArenaVec<'a, Argument<'a>>> {
6971
|| (is_test_call && {
7072
self.len() != 2
7173
|| matches!(
72-
self.as_ref().first(),
74+
arguments.first(),
7375
Some(
7476
Argument::StringLiteral(_)
7577
| Argument::TemplateLiteral(_)
@@ -96,10 +98,21 @@ impl<'a> Format<'a> for AstNode<'a, ArenaVec<'a, Argument<'a>>> {
9698
);
9799
}
98100

99-
let has_empty_line = self
100-
.iter()
101-
.skip(1)
102-
.any(|arg| f.source_text().get_lines_before(arg.span(), f.comments()) > 1);
101+
// Check if there's an empty line (2+ newlines) between any consecutive arguments.
102+
// This is used to preserve intentional blank lines in the original source.
103+
let has_empty_line = arguments.windows(2).any(|window| {
104+
let (cur_arg, next_arg) = (&window[0], &window[1]);
105+
106+
// Count newlines between arguments, short-circuiting at 2 for performance
107+
// Check if there are at least two newlines between arguments
108+
f.source_text()
109+
.bytes_range(cur_arg.span().end, next_arg.span().start)
110+
.iter()
111+
.filter(|&&b| b == b'\n')
112+
.nth(1)
113+
.is_some()
114+
});
115+
103116
if has_empty_line
104117
|| (!matches!(self.parent.parent(), AstNodes::Decorator(_))
105118
&& is_function_composition_args(self))
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
call(() => {
2+
// ...
3+
}, "good"
4+
);
5+
6+
call(() => {
7+
// ...
8+
}
9+
10+
, "good"
11+
);
12+
13+
call(() => {
14+
// ...
15+
},
16+
17+
"good"
18+
);
19+
20+
call(() => {
21+
// ...
22+
}, //
23+
"good"
24+
);
25+
26+
call(() => {
27+
// ...
28+
},
29+
//
30+
"good"
31+
);
32+
33+
call(() => {
34+
// ...
35+
},
36+
37+
//
38+
"good"
39+
);
40+
41+
call(() => {
42+
// ...
43+
},
44+
"good" //
45+
);
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
---
2+
source: crates/oxc_formatter/tests/fixtures/mod.rs
3+
---
4+
==================== Input ====================
5+
call(() => {
6+
// ...
7+
}, "good"
8+
);
9+
10+
call(() => {
11+
// ...
12+
}
13+
14+
, "good"
15+
);
16+
17+
call(() => {
18+
// ...
19+
},
20+
21+
"good"
22+
);
23+
24+
call(() => {
25+
// ...
26+
}, //
27+
"good"
28+
);
29+
30+
call(() => {
31+
// ...
32+
},
33+
//
34+
"good"
35+
);
36+
37+
call(() => {
38+
// ...
39+
},
40+
41+
//
42+
"good"
43+
);
44+
45+
call(() => {
46+
// ...
47+
},
48+
"good" //
49+
);
50+
51+
==================== Output ====================
52+
call(() => {
53+
// ...
54+
}, "good");
55+
56+
call(
57+
() => {
58+
// ...
59+
},
60+
"good",
61+
);
62+
63+
call(
64+
() => {
65+
// ...
66+
},
67+
68+
"good",
69+
);
70+
71+
call(
72+
() => {
73+
// ...
74+
}, //
75+
"good",
76+
);
77+
78+
call(
79+
() => {
80+
// ...
81+
},
82+
//
83+
"good",
84+
);
85+
86+
call(
87+
() => {
88+
// ...
89+
},
90+
91+
//
92+
"good",
93+
);
94+
95+
call(
96+
() => {
97+
// ...
98+
},
99+
"good", //
100+
);
101+
102+
===================== End =====================

0 commit comments

Comments
 (0)