From eb525297342c5f2b8f991305504c673f989285a0 Mon Sep 17 00:00:00 2001 From: Dunqing <29533304+Dunqing@users.noreply.github.com> Date: Thu, 16 Oct 2025 21:50:02 +0000 Subject: [PATCH] fix(formatter): incorrect handling of `ObjectPattern` as a parameter (#14670) --- .../src/write/object_pattern_like.rs | 16 ++--------- crates/oxc_formatter/src/write/parameters.rs | 17 +++++++++-- .../fixtures/ts/parameters/object-pattern.ts | 9 ++++++ .../ts/parameters/object-pattern.ts.snap | 28 +++++++++++++++++++ 4 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 crates/oxc_formatter/tests/fixtures/ts/parameters/object-pattern.ts create mode 100644 crates/oxc_formatter/tests/fixtures/ts/parameters/object-pattern.ts.snap diff --git a/crates/oxc_formatter/src/write/object_pattern_like.rs b/crates/oxc_formatter/src/write/object_pattern_like.rs index 9396af4efe034..43d756cff1d85 100644 --- a/crates/oxc_formatter/src/write/object_pattern_like.rs +++ b/crates/oxc_formatter/src/write/object_pattern_like.rs @@ -9,7 +9,6 @@ use crate::{ }, generated::ast_nodes::{AstNode, AstNodes}, write, - write::parameters::{get_this_param, should_hug_function_parameters}, }; use super::{ @@ -54,7 +53,9 @@ impl<'a> ObjectPatternLike<'a, '_> { fn is_inline(&self, f: &Formatter<'_, 'a>) -> bool { match self { - Self::ObjectPattern(node) => self.is_hug_parameter(f), + Self::ObjectPattern(node) => { + matches!(node.parent, AstNodes::FormalParameter(_)) + } Self::ObjectAssignmentTarget(node) => false, } } @@ -113,17 +114,6 @@ impl<'a> ObjectPatternLike<'a, '_> { } } - fn is_hug_parameter(&self, f: &Formatter<'_, 'a>) -> bool { - matches!(self, Self::ObjectPattern(node) if { - matches!(node.parent, AstNodes::FormalParameter(param) if { - matches!(param.parent, AstNodes::FormalParameters(params) if { - let this_param = get_this_param(param.parent); - should_hug_function_parameters(params, this_param, false, f) - }) - }) - }) - } - fn layout(&self, f: &Formatter<'_, 'a>) -> ObjectPatternLayout { if self.is_empty() { return ObjectPatternLayout::Empty; diff --git a/crates/oxc_formatter/src/write/parameters.rs b/crates/oxc_formatter/src/write/parameters.rs index 5a274db55a563..f6851ec4ffb11 100644 --- a/crates/oxc_formatter/src/write/parameters.rs +++ b/crates/oxc_formatter/src/write/parameters.rs @@ -111,9 +111,22 @@ impl<'a> FormatWrite<'a> for AstNode<'a, FormalParameter<'a>> { write!(f, self.pattern()) }); + let is_hug_parameter = matches!(self.parent, AstNodes::FormalParameters(params) if { + let this_param = get_this_param(self.parent); + let parentheses_not_needed = if let AstNodes::ArrowFunctionExpression(arrow) = params.parent { + can_avoid_parentheses(arrow, f) + } else { + false + }; + should_hug_function_parameters(params, this_param, parentheses_not_needed, f) + }); + let decorators = self.decorators(); - if decorators.is_empty() { - write!(f, [decorators, content]) + + if is_hug_parameter && decorators.is_empty() { + write!(f, [&content]) + } else if decorators.is_empty() { + write!(f, [group(&content)]) } else { write!(f, [group(&decorators), group(&content)]) } diff --git a/crates/oxc_formatter/tests/fixtures/ts/parameters/object-pattern.ts b/crates/oxc_formatter/tests/fixtures/ts/parameters/object-pattern.ts new file mode 100644 index 0000000000000..2f29c99fa14e9 --- /dev/null +++ b/crates/oxc_formatter/tests/fixtures/ts/parameters/object-pattern.ts @@ -0,0 +1,9 @@ +( + options, + { log, logger, messenger }: { + log: LogFun; + logger: Logger; + messenger: Messenger; + }) => { + +} \ No newline at end of file diff --git a/crates/oxc_formatter/tests/fixtures/ts/parameters/object-pattern.ts.snap b/crates/oxc_formatter/tests/fixtures/ts/parameters/object-pattern.ts.snap new file mode 100644 index 0000000000000..55afc470185ce --- /dev/null +++ b/crates/oxc_formatter/tests/fixtures/ts/parameters/object-pattern.ts.snap @@ -0,0 +1,28 @@ +--- +source: crates/oxc_formatter/tests/fixtures/mod.rs +--- +==================== Input ==================== +( + options, + { log, logger, messenger }: { + log: LogFun; + logger: Logger; + messenger: Messenger; + }) => { + +} +==================== Output ==================== +( + options, + { + log, + logger, + messenger, + }: { + log: LogFun; + logger: Logger; + messenger: Messenger; + }, +) => {}; + +===================== End =====================