From 99bd995ce9c01bedaca720e9b106074c234e8db0 Mon Sep 17 00:00:00 2001 From: Dunqing <29533304+Dunqing@users.noreply.github.com> Date: Thu, 30 Oct 2025 00:36:48 +0000 Subject: [PATCH] fix(formatter): print parenthesis for sequence expression in `ReturnStatement` and `ExpressionStatement` (#15062) --- crates/oxc_formatter/src/parentheses/expression.rs | 11 ++++++----- .../src/write/return_or_throw_statement.rs | 12 +++++------- .../snapshots/prettier.js.snap.md | 13 +------------ .../snapshots/prettier.ts.snap.md | 3 +-- 4 files changed, 13 insertions(+), 26 deletions(-) diff --git a/crates/oxc_formatter/src/parentheses/expression.rs b/crates/oxc_formatter/src/parentheses/expression.rs index f3656e77fc752..573109935ad4c 100644 --- a/crates/oxc_formatter/src/parentheses/expression.rs +++ b/crates/oxc_formatter/src/parentheses/expression.rs @@ -579,14 +579,15 @@ impl NeedsParentheses<'_> for AstNode<'_, SequenceExpression<'_>> { return false; } - !matches!( - self.parent, + match self.parent { AstNodes::ReturnStatement(_) + | AstNodes::ThrowStatement(_) // There's a precedence for writing `x++, y++` | AstNodes::ForStatement(_) - | AstNodes::ExpressionStatement(_) - | AstNodes::SequenceExpression(_) - ) + | AstNodes::SequenceExpression(_) => false, + AstNodes::ExpressionStatement(stmt) => !stmt.is_arrow_function_body(), + _ => true, + } } } diff --git a/crates/oxc_formatter/src/write/return_or_throw_statement.rs b/crates/oxc_formatter/src/write/return_or_throw_statement.rs index ae7fbda6b89ff..7f7ee3fe256e7 100644 --- a/crates/oxc_formatter/src/write/return_or_throw_statement.rs +++ b/crates/oxc_formatter/src/write/return_or_throw_statement.rs @@ -95,7 +95,7 @@ impl<'a> Format<'a> for FormatAdjacentArgument<'a, '_> { && has_argument_leading_comments(argument, f) { write!(f, [text("("), &block_indent(&argument), text(")")]) - } else if is_binary_or_sequence_argument(argument) { + } else if argument.is_binaryish() { write!( f, [group(&format_args!( @@ -104,6 +104,8 @@ impl<'a> Format<'a> for FormatAdjacentArgument<'a, '_> { if_group_breaks(&text(")")) ))] ) + } else if matches!(argument.as_ref(), Expression::SequenceExpression(_)) { + write!(f, [group(&format_args!(text("("), soft_block_indent(&argument), text(")")))]) } else { write!(f, argument) } @@ -168,11 +170,7 @@ fn has_argument_leading_comments(argument: &AstNode, f: &Formatter<' false } +#[inline] fn is_binary_or_sequence_argument(argument: &Expression) -> bool { - matches!( - argument, - Expression::BinaryExpression(_) - | Expression::LogicalExpression(_) - | Expression::SequenceExpression(_) - ) + matches!(argument, Expression::BinaryExpression(_) | Expression::LogicalExpression(_)) } diff --git a/tasks/prettier_conformance/snapshots/prettier.js.snap.md b/tasks/prettier_conformance/snapshots/prettier.js.snap.md index f94eef5024f3f..fee7b04305a16 100644 --- a/tasks/prettier_conformance/snapshots/prettier.js.snap.md +++ b/tasks/prettier_conformance/snapshots/prettier.js.snap.md @@ -1,4 +1,4 @@ -js compatibility: 673/749 (89.85%) +js compatibility: 684/749 (91.32%) # Failed @@ -43,8 +43,6 @@ js compatibility: 673/749 (89.85%) | js/last-argument-expansion/dangling-comment-in-arrow-function.js | 💥 | 22.22% | | js/logical-expressions/multiple-comments/17192.js | 💥 | 60.00% | | js/method-chain/issue-17457.js | 💥 | 0.00% | -| js/no-semi/issue2006.js | 💥💥 | 75.00% | -| js/no-semi/no-semi.js | 💥💥 | 98.90% | | js/object-multiline/multiline.js | 💥✨ | 22.22% | | js/quote-props/classes.js | 💥💥✨✨ | 47.06% | | js/quote-props/objects.js | 💥💥✨✨ | 45.10% | @@ -52,15 +50,7 @@ js compatibility: 673/749 (89.85%) | js/quotes/objects.js | 💥💥 | 80.00% | | js/require/comments.js | 💥 | 81.25% | | js/require/long-module-name.js | 💥 | 18.18% | -| js/reserved-word/interfaces.js | 💥 | 85.71% | -| js/reserved-word/let.js | 💥 | 85.71% | -| js/reserved-word/yield.js | 💥 | 85.71% | -| js/sequence-break/break.js | 💥 | 90.91% | -| js/sequence-expression/expression.js | 💥 | 33.33% | | js/sequence-expression/ignored.js | 💥 | 25.00% | -| js/sequence-expression/return.js | 💥 | 50.00% | -| js/sequence-expression/no-semi/expression.js | 💥 | 50.00% | -| js/strings/non-octal-eight-and-nine.js | 💥💥 | 71.43% | | js/strings/template-literals.js | 💥💥 | 98.01% | | js/ternaries/binary.js | 💥💥💥💥✨✨✨✨ | 18.42% | | js/ternaries/func-call.js | 💥💥💥💥✨✨✨✨ | 25.00% | @@ -76,7 +66,6 @@ js compatibility: 673/749 (89.85%) | js/trailing-comma/dynamic-import.js | 💥💥💥 | 0.00% | | jsx/fbt/test.js | 💥 | 84.06% | | jsx/jsx/quotes.js | 💥💥💥💥 | 79.41% | -| jsx/jsx/regex.js | 💥💥💥💥 | 75.00% | | jsx/optional-chaining/optional-chaining.jsx | 💥 | 85.96% | | jsx/single-attribute-per-line/single-attribute-per-line.js | 💥✨ | 43.37% | | jsx/text-wrap/test.js | 💥 | 99.56% | diff --git a/tasks/prettier_conformance/snapshots/prettier.ts.snap.md b/tasks/prettier_conformance/snapshots/prettier.ts.snap.md index e5859b0c876f4..0592a29936b8a 100644 --- a/tasks/prettier_conformance/snapshots/prettier.ts.snap.md +++ b/tasks/prettier_conformance/snapshots/prettier.ts.snap.md @@ -1,4 +1,4 @@ -ts compatibility: 537/598 (89.80%) +ts compatibility: 538/598 (89.97%) # Failed @@ -6,7 +6,6 @@ ts compatibility: 537/598 (89.80%) | :-------- | :--------------: | :---------: | | jsx/fbt/test.js | 💥 | 84.06% | | jsx/jsx/quotes.js | 💥💥💥💥 | 79.41% | -| jsx/jsx/regex.js | 💥💥💥💥 | 75.00% | | jsx/optional-chaining/optional-chaining.jsx | 💥 | 85.96% | | jsx/single-attribute-per-line/single-attribute-per-line.js | 💥✨ | 43.37% | | jsx/text-wrap/test.js | 💥 | 99.56% |