diff --git a/crates/oxc_formatter/src/formatter/format_element/document.rs b/crates/oxc_formatter/src/formatter/format_element/document.rs index 3e84aa087bfde..ac8624324225b 100644 --- a/crates/oxc_formatter/src/formatter/format_element/document.rs +++ b/crates/oxc_formatter/src/formatter/format_element/document.rs @@ -605,7 +605,9 @@ impl FormatElements for [FormatElement<'_>] { return true; } } - + FormatElement::Line(line) if line.will_break() => { + return true; + } element if ignore_depth == 0 && element.will_break() => { return true; } diff --git a/crates/oxc_formatter/src/formatter/format_element/mod.rs b/crates/oxc_formatter/src/formatter/format_element/mod.rs index 2ea69c2966fff..af5dc7a52dda6 100644 --- a/crates/oxc_formatter/src/formatter/format_element/mod.rs +++ b/crates/oxc_formatter/src/formatter/format_element/mod.rs @@ -103,6 +103,10 @@ impl LineMode { pub const fn is_hard(self) -> bool { matches!(self, LineMode::Hard) } + + pub const fn will_break(self) -> bool { + matches!(self, LineMode::Hard | LineMode::Empty) + } } #[derive(Debug, Clone, Copy, Eq, PartialEq)] @@ -240,7 +244,7 @@ impl FormatElements for FormatElement<'_> { match self { FormatElement::ExpandParent => true, FormatElement::Tag(Tag::StartGroup(group)) => !group.mode().is_flat(), - FormatElement::Line(line_mode) => matches!(line_mode, LineMode::Hard | LineMode::Empty), + FormatElement::Line(line_mode) => line_mode.will_break(), FormatElement::StaticText { text } | FormatElement::DynamicText { text } => { text.contains('\n') } diff --git a/crates/oxc_formatter/src/formatter/trivia.rs b/crates/oxc_formatter/src/formatter/trivia.rs index 2150089201b55..f5846455c3366 100644 --- a/crates/oxc_formatter/src/formatter/trivia.rs +++ b/crates/oxc_formatter/src/formatter/trivia.rs @@ -207,36 +207,35 @@ impl<'a> Format<'a> for FormatTrailingComments<'a> { // trailing comment for `2`. We can simulate the above by checking // if this a comment on its own line; normal trailing comments are // always at the end of another expression. - if total_lines_before > 0 { + if total_lines_before > 0 + || previous_comment.is_some_and(|comment| comment.is_line()) + { write!( f, - [ - line_suffix(&format_with(|f| { - match lines_before { - _ if should_nestle => {} - 0 => { - // If the comment is immediately following a block-like comment, - // then it can stay on the same line with just a space between. - // Otherwise, it gets a hard break. - // - // [>* hello <] // hi - // [>* - // * docs - // */ [> still on the same line <] - if previous_comment.copied().is_some_and(Comment::is_line) { - write!(f, [hard_line_break()])?; - } else { - write!(f, [space()])?; - } + [line_suffix(&format_with(|f| { + match lines_before { + _ if should_nestle => {} + 0 => { + // If the comment is immediately following a block-like comment, + // then it can stay on the same line with just a space between. + // Otherwise, it gets a hard break. + // + // [>* hello <] // hi + // [>* + // * docs + // */ [> still on the same line <] + if previous_comment.copied().is_some_and(Comment::is_line) { + write!(f, [hard_line_break()])?; + } else { + write!(f, [space()])?; } - 1 => write!(f, [hard_line_break()])?, - _ => write!(f, [empty_line()])?, } + 1 => write!(f, [hard_line_break()])?, + _ => write!(f, [empty_line()])?, + } - write!(f, [comment]) - })), - expand_parent() - ] + write!(f, [comment]) + }))] )?; } else { let content = diff --git a/crates/oxc_formatter/tests/fixtures/js/comments/for-statements.js.snap b/crates/oxc_formatter/tests/fixtures/js/comments/for-statements.js.snap index ebbae9dab608e..4b06d12f59e15 100644 --- a/crates/oxc_formatter/tests/fixtures/js/comments/for-statements.js.snap +++ b/crates/oxc_formatter/tests/fixtures/js/comments/for-statements.js.snap @@ -16,15 +16,13 @@ for (let i of [ ==================== Output ==================== for (let i in [ // comment1 - 1, 2, - 3, + 1, 2, 3, // comment2 ]); for (let i of [ // comment1 - 1, 2, - 3, + 1, 2, 3, // comment2 ]);