Skip to content

Commit 5562dd6

Browse files
committed
fix(formatter): incorrect formatting method chain with trailing comments (oxc-project#16027)
* close oxc-project#15983
1 parent e2ca770 commit 5562dd6

File tree

4 files changed

+60
-2
lines changed

4 files changed

+60
-2
lines changed

crates/oxc_formatter/src/utils/member_chain/chain_member.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ impl ChainMember<'_, '_> {
5555
pub const fn is_computed_expression(&self) -> bool {
5656
matches!(self, Self::ComputedMember { .. })
5757
}
58+
59+
pub fn span(&self) -> oxc_span::Span {
60+
match self {
61+
Self::StaticMember(member) => member.span(),
62+
Self::TSNonNullExpression(e) => e.span(),
63+
Self::CallExpression { expression, .. } => expression.span(),
64+
Self::ComputedMember(member) => member.span(),
65+
Self::Node(node) => node.span(),
66+
}
67+
}
5868
}
5969

6070
impl<'a> Format<'a> for ChainMember<'a, '_> {
@@ -64,7 +74,6 @@ impl<'a> Format<'a> for ChainMember<'a, '_> {
6474
write!(
6575
f,
6676
[
67-
line_suffix_boundary(),
6877
FormatLeadingComments::Comments(
6978
f.context().comments().comments_before(member.property().span().start)
7079
),

crates/oxc_formatter/src/utils/member_chain/mod.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl<'a, 'b> MemberChain<'a, 'b> {
4545
// `flattened_items` now contains only the nodes that should have a sequence of
4646
// `[ StaticMemberExpression -> AnyNode + CallExpression ]`
4747
let tail_groups =
48-
compute_remaining_groups(chain_members.drain(remaining_members_start_index..));
48+
compute_remaining_groups(chain_members.drain(remaining_members_start_index..), f);
4949
let head_group = MemberChainGroup::from(chain_members);
5050

5151
let mut member_chain = Self { head: head_group, tail: tail_groups, root: call_expression };
@@ -300,11 +300,18 @@ fn get_split_index_of_head_and_tail_groups(members: &[ChainMember<'_, '_>]) -> u
300300
/// computes groups coming after the first group
301301
fn compute_remaining_groups<'a, 'b>(
302302
members: impl IntoIterator<Item = ChainMember<'a, 'b>>,
303+
f: &Formatter<'_, 'a>,
303304
) -> TailChainGroups<'a, 'b> {
304305
let mut has_seen_call_expression = false;
305306
let mut groups_builder = MemberChainGroupsBuilder::default();
306307

307308
for member in members {
309+
let span = member.span();
310+
let has_trailing_comment =
311+
f.comments().comments_after(span.end).first().is_some_and(|comment| {
312+
f.source_text().bytes_range(span.end, comment.span.start).trim_ascii().is_empty()
313+
});
314+
308315
match member {
309316
// [0] should be appended at the end of the group instead of the
310317
// beginning of the next one
@@ -333,6 +340,14 @@ fn compute_remaining_groups<'a, 'b>(
333340
}
334341
ChainMember::Node(_) => unreachable!("Remaining members never have a `Node` variant"),
335342
}
343+
344+
// Close the group immediately if the node had any trailing comments to
345+
// ensure those are printed in a trailing position for the token they
346+
// were originally commenting
347+
if has_trailing_comment {
348+
groups_builder.close_group();
349+
has_seen_call_expression = false;
350+
}
336351
}
337352

338353
groups_builder.finish()
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
wow /** do something weird here */
2+
.omg! /** do something weird here */
3+
.map((x) => x.name) /** do something weird here */
4+
.filter((x) => x.length > 3)
5+
.sort((a, b) => a.length - b.length);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
source: crates/oxc_formatter/tests/fixtures/mod.rs
3+
---
4+
==================== Input ====================
5+
wow /** do something weird here */
6+
.omg! /** do something weird here */
7+
.map((x) => x.name) /** do something weird here */
8+
.filter((x) => x.length > 3)
9+
.sort((a, b) => a.length - b.length);
10+
==================== Output ====================
11+
------------------
12+
{ printWidth: 80 }
13+
------------------
14+
wow /** do something weird here */
15+
.omg! /** do something weird here */
16+
.map((x) => x.name) /** do something weird here */
17+
.filter((x) => x.length > 3)
18+
.sort((a, b) => a.length - b.length);
19+
20+
-------------------
21+
{ printWidth: 100 }
22+
-------------------
23+
wow /** do something weird here */
24+
.omg! /** do something weird here */
25+
.map((x) => x.name) /** do something weird here */
26+
.filter((x) => x.length > 3)
27+
.sort((a, b) => a.length - b.length);
28+
29+
===================== End =====================

0 commit comments

Comments
 (0)