diff --git a/crates/oxc_formatter/src/utils/member_chain/groups.rs b/crates/oxc_formatter/src/utils/member_chain/groups.rs index a76f69125f996..b0be5b7a6ec22 100644 --- a/crates/oxc_formatter/src/utils/member_chain/groups.rs +++ b/crates/oxc_formatter/src/utils/member_chain/groups.rs @@ -1,6 +1,7 @@ use std::cell::{Cell, RefCell}; use std::collections::VecDeque; +use oxc_ast::ast::Expression; use oxc_span::GetSpan; use super::chain_member::ChainMember; @@ -186,6 +187,16 @@ impl<'a, 'b> MemberChainGroup<'a, 'b> { return false; }; + // Prettier doesn't preserve blank lines after a terminal call like `fn()` + // whose callee is not part of the chain: `fn()\n\n.bar()` becomes `fn().bar()`. + // + if let Expression::CallExpression(call) = expression.object().as_ref() + && !call.callee.is_member_expression() + && !call.callee.is_call_expression() + { + return false; + } + let source = f.source_text(); // `A \n\n/* comment . */ . / comment . */ B` diff --git a/crates/oxc_formatter/tests/fixtures/js/member-chains/blank-line.js b/crates/oxc_formatter/tests/fixtures/js/member-chains/blank-line.js index 8fc1a0cc537a6..81f145ad2e320 100644 --- a/crates/oxc_formatter/tests/fixtures/js/member-chains/blank-line.js +++ b/crates/oxc_formatter/tests/fixtures/js/member-chains/blank-line.js @@ -11,3 +11,17 @@ Promise.all(writeIconFiles) // TO DO -- END .then(() => writeRegistry()) + +// https://github.com/oxc-project/oxc/issues/19469 +const x = fn() + +.c1(); + +const y = fn() + +.c1() + +.c2() + + +.c3(); diff --git a/crates/oxc_formatter/tests/fixtures/js/member-chains/blank-line.js.snap b/crates/oxc_formatter/tests/fixtures/js/member-chains/blank-line.js.snap index 4e65f03255bb2..8cce6602e0c84 100644 --- a/crates/oxc_formatter/tests/fixtures/js/member-chains/blank-line.js.snap +++ b/crates/oxc_formatter/tests/fixtures/js/member-chains/blank-line.js.snap @@ -16,6 +16,20 @@ Promise.all(writeIconFiles) .then(() => writeRegistry()) +// https://github.com/oxc-project/oxc/issues/19469 +const x = fn() + +.c1(); + +const y = fn() + +.c1() + +.c2() + + +.c3(); + ==================== Output ==================== ------------------ { printWidth: 80 } @@ -34,6 +48,16 @@ Promise.all(writeIconFiles) .then(() => writeRegistry()); +// https://github.com/oxc-project/oxc/issues/19469 +const x = fn().c1(); + +const y = fn() + .c1() + + .c2() + + .c3(); + ------------------- { printWidth: 100 } ------------------- @@ -51,4 +75,14 @@ Promise.all(writeIconFiles) .then(() => writeRegistry()); +// https://github.com/oxc-project/oxc/issues/19469 +const x = fn().c1(); + +const y = fn() + .c1() + + .c2() + + .c3(); + ===================== End =====================