Skip to content

Commit c0dfd9b

Browse files
committed
fix(formatter): print comments before fat arrow as-is for ArrowFunctionExpression (#15050)
1 parent 206b519 commit c0dfd9b

File tree

3 files changed

+108
-41
lines changed

3 files changed

+108
-41
lines changed

crates/oxc_formatter/src/write/arrow_function_expression.rs

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ use crate::{
1010
Buffer, Comments, Format, FormatError, FormatResult, Formatter, SourceText,
1111
buffer::RemoveSoftLinesBuffer,
1212
prelude::*,
13-
trivia::{FormatLeadingComments, format_trailing_comments},
13+
trivia::{
14+
DanglingIndentMode, FormatDanglingComments, FormatLeadingComments,
15+
FormatTrailingComments, format_trailing_comments,
16+
},
1417
},
1518
options::FormatTrailingCommas,
1619
utils::{assignment_like::AssignmentLikeLayout, expression::ExpressionLeftSide},
@@ -502,34 +505,46 @@ impl<'a> Format<'a> for ArrowChain<'a, '_> {
502505
let is_first = is_first_in_chain;
503506

504507
let formatted_signature = format_with(|f| {
505-
if should_format_comments {
506-
// A grouped layout implies that the arrow chain is trying to be rendered
507-
// in a condensed, single-line format (at least the signatures, not
508-
// necessarily the body). In that case, we _need_ to prevent the leading
509-
// comments from inserting line breaks. But if it's _not_ a grouped layout,
510-
// then we want to _force_ the line break so that the leading comments
511-
// don't inadvertently end up on the previous line after the fat arrow.
512-
if is_grouped_call_arg_layout {
513-
write!(f, [space(), format_leading_comments(arrow.span())])?;
508+
let format_leading_comments = format_once(|f| {
509+
if should_format_comments {
510+
// A grouped layout implies that the arrow chain is trying to be rendered
511+
// in a condensed, single-line format (at least the signatures, not
512+
// necessarily the body). In that case, we _need_ to prevent the leading
513+
// comments from inserting line breaks. But if it's _not_ a grouped layout,
514+
// then we want to _force_ the line break so that the leading comments
515+
// don't inadvertently end up on the previous line after the fat arrow.
516+
if is_grouped_call_arg_layout {
517+
write!(f, [space(), format_leading_comments(arrow.span())])
518+
} else {
519+
write!(
520+
f,
521+
[
522+
soft_line_break_or_space(),
523+
format_leading_comments(arrow.span())
524+
]
525+
)
526+
}
514527
} else {
515-
write!(
516-
f,
517-
[
518-
soft_line_break_or_space(),
519-
format_leading_comments(arrow.span())
520-
]
521-
)?;
528+
Ok(())
522529
}
523-
}
530+
});
524531

532+
let start = arrow.span().start;
525533
write!(
526534
f,
527-
[format_signature(
528-
arrow,
529-
is_grouped_call_arg_layout,
530-
is_first,
531-
self.options.cache_mode
532-
)]
535+
[
536+
FormatContentWithCacheMode::new(
537+
Span::new(start, start),
538+
format_leading_comments,
539+
self.options.cache_mode,
540+
),
541+
format_signature(
542+
arrow,
543+
is_grouped_call_arg_layout,
544+
is_first,
545+
self.options.cache_mode
546+
)
547+
]
533548
)
534549
});
535550

@@ -559,7 +574,7 @@ impl<'a> Format<'a> for ArrowChain<'a, '_> {
559574
Ok(())
560575
});
561576

562-
write!(f, [group(&join_signatures).should_expand(*expand_signatures)])
577+
group(&join_signatures).should_expand(*expand_signatures).fmt(f)
563578
});
564579

565580
let format_tail_body_inner = format_with(|f| {
@@ -607,14 +622,6 @@ impl<'a> Format<'a> for ArrowChain<'a, '_> {
607622
write!(f, [format_tail_body])?;
608623
}
609624
}
610-
611-
// Format the trailing comments of all arrow function EXCEPT the first one because
612-
// the comments of the head get formatted as part of the `FormatJsArrowFunctionExpression` call.
613-
// TODO: It seems unneeded in the current oxc implementation?
614-
// for arrow in self.arrows().skip(1) {
615-
// write!(f, format_trailing_comments(arrow.span().end))?;
616-
// }
617-
618625
Ok(())
619626
});
620627

@@ -758,12 +765,12 @@ fn format_signature<'a, 'b>(
758765
)?;
759766
}
760767

761-
// TODO: for case `a = (x: any): x is string /* comment */ => {}`
762-
// if f.comments().has_dangling_comments(arrow.span()) {
763-
// write!(f, [space(), format_dangling_comments(arrow.span())])?;
764-
// }
765-
766-
Ok(())
768+
// Print comments before the fat arrow (`=>`)
769+
let comments_before_fat_arrow =
770+
f.context().comments().comments_before_character(arrow.params.span().end, b'=');
771+
let content =
772+
format_once(|f| FormatTrailingComments::Comments(comments_before_fat_arrow).fmt(f));
773+
write!(f, [FormatContentWithCacheMode::new(arrow.span, content, cache_mode)])
767774
})
768775
}
769776

crates/oxc_formatter/tests/fixtures/js/comments/arrow.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,24 @@
44

55
() =>
66
// comment
7-
({})
7+
({});
8+
9+
() /* comment1 */ => /* comment2 */ { };
10+
11+
() /**/ => //
12+
() /**/ => /**/
13+
() /**/ => /**/ {
14+
//
15+
}
16+
17+
call(
18+
() /* comment1 */ => /* comment2 */ { }
19+
);
20+
21+
call(
22+
() /**/ => //
23+
() /**/ => /**/
24+
() /**/ => /**/ {
25+
//
26+
}
27+
);

crates/oxc_formatter/tests/fixtures/js/comments/arrow.js.snap

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,27 @@ source: crates/oxc_formatter/tests/fixtures/mod.rs
88

99
() =>
1010
// comment
11-
({})
11+
({});
12+
13+
() /* comment1 */ => /* comment2 */ { };
14+
15+
() /**/ => //
16+
() /**/ => /**/
17+
() /**/ => /**/ {
18+
//
19+
}
20+
21+
call(
22+
() /* comment1 */ => /* comment2 */ { }
23+
);
24+
25+
call(
26+
() /**/ => //
27+
() /**/ => /**/
28+
() /**/ => /**/ {
29+
//
30+
}
31+
);
1232

1333
==================== Output ====================
1434
() =>
@@ -19,4 +39,24 @@ source: crates/oxc_formatter/tests/fixtures/mod.rs
1939
// comment
2040
({});
2141

42+
() /* comment1 */ => /* comment2 */ {};
43+
44+
() /**/ =>
45+
//
46+
() /**/ =>
47+
/**/
48+
() /**/ => /**/ {
49+
//
50+
};
51+
52+
call(() /* comment1 */ => /* comment2 */ {});
53+
54+
call(() /**/ =>
55+
//
56+
() /**/ =>
57+
/**/
58+
() /**/ => /**/ {
59+
//
60+
});
61+
2262
===================== End =====================

0 commit comments

Comments
 (0)