From ea8f9ed85a429d7976026f90306737f29514ce4a Mon Sep 17 00:00:00 2001 From: Dunqing <29533304+Dunqing@users.noreply.github.com> Date: Sun, 12 Oct 2025 16:13:20 +0000 Subject: [PATCH] fix(formatter): correct checking comments between the operator and the right side for assignment like nodes (#14482) --- .../oxc_formatter/src/formatter/comments.rs | 8 ++-- .../src/utils/assignment_like.rs | 44 +++++++++---------- .../tests/fixtures/js/comments/assignments.js | 2 + .../fixtures/js/comments/assignments.js.snap | 13 ++++++ 4 files changed, 40 insertions(+), 27 deletions(-) create mode 100644 crates/oxc_formatter/tests/fixtures/js/comments/assignments.js create mode 100644 crates/oxc_formatter/tests/fixtures/js/comments/assignments.js.snap diff --git a/crates/oxc_formatter/src/formatter/comments.rs b/crates/oxc_formatter/src/formatter/comments.rs index f8c2f7f318f3e..248d24db68be9 100644 --- a/crates/oxc_formatter/src/formatter/comments.rs +++ b/crates/oxc_formatter/src/formatter/comments.rs @@ -236,7 +236,7 @@ impl<'a> Comments<'a> { /// Checks if there are any comments between the given positions. pub fn has_comment_in_range(&self, start: u32, end: u32) -> bool { - self.comments_before_iter(end).any(|comment| comment.span.end >= start) + self.comments_before_iter(end).any(|comment| comment.span.end > start) } /// Checks if there are any comments within the given span. @@ -253,10 +253,8 @@ impl<'a> Comments<'a> { /// Checks if there are any leading own-line comments before the given position. pub fn has_leading_own_line_comment(&self, start: u32) -> bool { - self.comments_before_iter(start).any(|comment| { - self.source_text.is_own_line_comment(comment) - || self.source_text.lines_after(comment.span.end) > 0 - }) + self.comments_before_iter(start) + .any(|comment| self.source_text.lines_after(comment.span.end) > 0) } /// Checks if there are leading or trailing comments around `current_span`. diff --git a/crates/oxc_formatter/src/utils/assignment_like.rs b/crates/oxc_formatter/src/utils/assignment_like.rs index 0bb1ae3a82312..47bb9346d0a3e 100644 --- a/crates/oxc_formatter/src/utils/assignment_like.rs +++ b/crates/oxc_formatter/src/utils/assignment_like.rs @@ -314,19 +314,19 @@ impl<'a> AssignmentLike<'a, '_> { } let right_expression = self.get_right_expression(); + if let Some(expr) = right_expression { + if let Some(layout) = self.chain_formatting_layout(expr) { + return layout; + } - if let Some(layout) = right_expression.and_then(|expr| self.chain_formatting_layout(expr)) { - return layout; - } - - if let Some(Expression::CallExpression(call_expression)) = - &right_expression.map(AsRef::as_ref) - && call_expression - .callee - .get_identifier_reference() - .is_some_and(|ident| ident.name == "require") - { - return AssignmentLikeLayout::NeverBreakAfterOperator; + if let Expression::CallExpression(call_expression) = expr.as_ref() + && call_expression + .callee + .get_identifier_reference() + .is_some_and(|ident| ident.name == "require") + { + return AssignmentLikeLayout::NeverBreakAfterOperator; + } } if self.should_break_after_operator(right_expression, f) { @@ -359,10 +359,8 @@ impl<'a> AssignmentLike<'a, '_> { return AssignmentLikeLayout::BreakAfterOperator; } - let is_poorly_breakable = match &right_expression { - Some(expression) => is_poorly_breakable_member_or_call_chain(expression, f), - None => false, - }; + let is_poorly_breakable = + right_expression.is_some_and(|expr| is_poorly_breakable_member_or_call_chain(expr, f)); if is_poorly_breakable { return AssignmentLikeLayout::BreakAfterOperator; @@ -581,17 +579,19 @@ fn should_break_after_operator<'a>( ) -> bool { let is_jsx = matches!(right.as_ref(), Expression::JSXElement(_) | Expression::JSXFragment(_)); + if is_jsx { + return false; + } + + let comments = f.comments(); let source_text = f.source_text(); - for comment in f.comments().comments_before(right.span().start) { - if !is_jsx - && (source_text.lines_after(comment.span.end) > 0 - || source_text.is_own_line_comment(comment)) - { + for comment in comments.comments_before(right.span().start) { + if source_text.lines_after(comment.span.end) > 0 { return true; } // Needs to wrap a parenthesis for the node, so it won't break. - if f.comments().is_type_cast_comment(comment) { + if comments.is_type_cast_comment(comment) { return false; } } diff --git a/crates/oxc_formatter/tests/fixtures/js/comments/assignments.js b/crates/oxc_formatter/tests/fixtures/js/comments/assignments.js new file mode 100644 index 0000000000000..6a4835e6be78b --- /dev/null +++ b/crates/oxc_formatter/tests/fixtures/js/comments/assignments.js @@ -0,0 +1,2 @@ +var longlonglonglonglonglong = /*#__PURE__*/_interopDefaultLegacy(aaaaaaaaaaaaaaa); +var short = /*#__PURE__*/_interopDefaultLegacy(b); diff --git a/crates/oxc_formatter/tests/fixtures/js/comments/assignments.js.snap b/crates/oxc_formatter/tests/fixtures/js/comments/assignments.js.snap new file mode 100644 index 0000000000000..f198800436db5 --- /dev/null +++ b/crates/oxc_formatter/tests/fixtures/js/comments/assignments.js.snap @@ -0,0 +1,13 @@ +--- +source: crates/oxc_formatter/tests/fixtures/mod.rs +--- +==================== Input ==================== +var longlonglonglonglonglong = /*#__PURE__*/_interopDefaultLegacy(aaaaaaaaaaaaaaa); +var short = /*#__PURE__*/_interopDefaultLegacy(b); + +==================== Output ==================== +var longlonglonglonglonglong = + /*#__PURE__*/ _interopDefaultLegacy(aaaaaaaaaaaaaaa); +var short = /*#__PURE__*/ _interopDefaultLegacy(b); + +===================== End =====================