From 505252cfd5ec7004a87c10f98babe2732ad1ad83 Mon Sep 17 00:00:00 2001 From: Dunqing <29533304+Dunqing@users.noreply.github.com> Date: Tue, 4 Nov 2025 06:38:38 +0000 Subject: [PATCH] feat(formatter): wrap parenthesis for AssignmentExpression that is a key of `PropertyDefinition` (#15243) Align the latest Prettier behavior, which hasn't been released yet. --- .../src/parentheses/expression.rs | 32 +++++++++++-------- .../snapshots/prettier.js.snap.md | 4 +-- .../snapshots/prettier.ts.snap.md | 3 +- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/crates/oxc_formatter/src/parentheses/expression.rs b/crates/oxc_formatter/src/parentheses/expression.rs index 573109935ad4c..4a8b2c89237ff 100644 --- a/crates/oxc_formatter/src/parentheses/expression.rs +++ b/crates/oxc_formatter/src/parentheses/expression.rs @@ -531,22 +531,27 @@ impl NeedsParentheses<'_> for AstNode<'_, AssignmentExpression<'_>> { AstNodes::SequenceExpression(sequence) => { // Skip through SequenceExpression and ParenthesizedExpression ancestors if let Some(ancestor) = self.ancestors().find(|p| { - !matches!(p, AstNodes::SequenceExpression(_) | AstNodes::ParenthesizedExpression(_)) - }) && let AstNodes::ForStatement(for_stmt) = ancestor { - let is_initializer = for_stmt - .init - .as_ref() - .is_some_and(|init| init.span().contains_inclusive(self.span())); - let is_update = for_stmt.update.as_ref().is_some_and(|update| { - update.span().contains_inclusive(self.span()) - }); - return !(is_initializer || is_update); - } + !matches!( + p, + AstNodes::SequenceExpression(_) | AstNodes::ParenthesizedExpression(_) + ) + }) && let AstNodes::ForStatement(for_stmt) = ancestor + { + let is_initializer = for_stmt + .init + .as_ref() + .is_some_and(|init| init.span().contains_inclusive(self.span())); + let is_update = for_stmt + .update + .as_ref() + .is_some_and(|update| update.span().contains_inclusive(self.span())); + return !(is_initializer || is_update); + } true } - // `interface { [a = 1]; }` and `class { [a = 1]; }` not need parens - AstNodes::TSPropertySignature(_) | AstNodes::PropertyDefinition(_) | + // `interface A { [a = 1]; }` not need parens + AstNodes::TSPropertySignature(_) | // Never need parentheses in these contexts: // - `a = (b = c)` = nested assignments don't need extra parens AstNodes::AssignmentExpression(_) => false, @@ -567,6 +572,7 @@ impl NeedsParentheses<'_> for AstNode<'_, AssignmentExpression<'_>> { // - `new (a = b)` // - `(a = b).prop` // - `await (a = b)` + // - `class { [a = 1]; }` // - etc. _ => true, } diff --git a/tasks/prettier_conformance/snapshots/prettier.js.snap.md b/tasks/prettier_conformance/snapshots/prettier.js.snap.md index 1cbe0ef9a76c1..d8fd7f26f4c45 100644 --- a/tasks/prettier_conformance/snapshots/prettier.js.snap.md +++ b/tasks/prettier_conformance/snapshots/prettier.js.snap.md @@ -1,12 +1,10 @@ -js compatibility: 696/749 (92.92%) +js compatibility: 698/749 (93.19%) # Failed | Spec path | Failed or Passed | Match ratio | | :-------- | :--------------: | :---------: | | js/arrows/comment.js | 💥💥 | 88.89% | -| js/assignment-expression/property-key.js | 💥 | 88.89% | -| js/assignment-expression/property-value.js | 💥 | 88.89% | | js/call/boolean/boolean.js | 💥 | 77.88% | | js/class-comment/misc.js | 💥 | 72.73% | | js/class-comment/superclass.js | 💥 | 95.35% | diff --git a/tasks/prettier_conformance/snapshots/prettier.ts.snap.md b/tasks/prettier_conformance/snapshots/prettier.ts.snap.md index cf699b4386013..51d7641b82c21 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: 544/598 (90.97%) +ts compatibility: 545/598 (91.14%) # Failed @@ -25,7 +25,6 @@ ts compatibility: 544/598 (90.97%) | typescript/comments/16121.ts | 💥 | 72.46% | | typescript/comments/mapped_types.ts | 💥 | 96.77% | | typescript/comments/method_types.ts | 💥 | 82.05% | -| typescript/compiler/indexSignatureWithInitializer.ts | 💥 | 87.50% | | typescript/conditional-types/comments.ts | 💥✨ | 31.51% | | typescript/conditional-types/conditional-types.ts | 💥✨ | 34.48% | | typescript/conditional-types/infer-type.ts | 💥✨ | 4.76% |