From 4406be77a00b0a0225c38fd97d29b3277d9b6978 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Sun, 5 May 2024 19:32:40 -0400 Subject: [PATCH] fix: `else` was moved to wrong `if` sometimes when formatting minified code (#633) --- src/generation/generate.rs | 36 +++++++++++++++++++++++++++++--- src/lib.rs | 2 +- tests/specs/issues/issue0632.txt | 7 +++++++ 3 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 tests/specs/issues/issue0632.txt diff --git a/src/generation/generate.rs b/src/generation/generate.rs index 3023cfcb..35e08eae 100644 --- a/src/generation/generate.rs +++ b/src/generation/generate.rs @@ -8294,7 +8294,7 @@ fn gen_control_flow_separator( } struct GenHeaderWithConditionalBraceBodyOptions<'a> { - body_node: Node<'a>, + body_node: Stmt<'a>, generated_header: PrintItems, use_braces: UseBraces, brace_position: BracePosition, @@ -8324,8 +8324,12 @@ fn gen_header_with_conditional_brace_body<'a>( items.push_info(end_header_ln); let result = gen_conditional_brace_body( GenConditionalBraceBodyOptions { - body_node: opts.body_node, - use_braces: opts.use_braces, + body_node: opts.body_node.into(), + use_braces: if force_use_braces_for_stmt(opts.body_node) { + UseBraces::Always + } else { + opts.use_braces + }, brace_position: opts.brace_position, single_body_position: opts.single_body_position, requires_braces_condition_ref: opts.requires_braces_condition_ref, @@ -8343,6 +8347,32 @@ fn gen_header_with_conditional_brace_body<'a>( } } +fn force_use_braces_for_stmt(stmt: Stmt) -> bool { + match stmt { + Stmt::Block(block) => { + if block.stmts.len() != 1 { + true + } else { + force_use_braces_for_stmt(block.stmts[0]) + } + } + // force braces for any children where no braces could be ambiguous + Stmt::Empty(_) + | Stmt::DoWhile(_) + | Stmt::For(_) + | Stmt::ForIn(_) + | Stmt::ForOf(_) + | Stmt::Decl(_) + | Stmt::If(_) // especially force for this as it may cause a bug + | Stmt::Labeled(_) + | Stmt::Switch(_) + | Stmt::Try(_) + | Stmt::While(_) + | Stmt::With(_) => true, + Stmt::Break(_) | Stmt::Continue(_) | Stmt::Debugger(_) | Stmt::Expr(_) | Stmt::Return(_) | Stmt::Throw(_) => false, + } +} + struct GenConditionalBraceBodyOptions<'a> { body_node: Node<'a>, use_braces: UseBraces, diff --git a/src/lib.rs b/src/lib.rs index 68116a5e..38c5a479 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,7 @@ #![allow(clippy::if_same_then_else)] #![allow(clippy::vec_init_then_push)] #![allow(clippy::type_complexity)] -#![allow(clippy::needless_lifetimes)] // todo: enable this in the future +#![allow(clippy::needless_lifetimes)] #![deny(clippy::disallowed_methods)] #![deny(clippy::disallowed_types)] #![deny(clippy::print_stderr)] diff --git a/tests/specs/issues/issue0632.txt b/tests/specs/issues/issue0632.txt new file mode 100644 index 00000000..62249287 --- /dev/null +++ b/tests/specs/issues/issue0632.txt @@ -0,0 +1,7 @@ +== should maintain if stmt == +if(a){if(b){console.log(0);}}else if(d){console.log(1);}else{console.log(2);} + +[expect] +if (a) { if (b) console.log(0); } +else if (d) console.log(1); +else console.log(2);