From 896ff860f9b860046e9968284490abc2db84ef6c Mon Sep 17 00:00:00 2001 From: Boshen <1430279+Boshen@users.noreply.github.com> Date: Thu, 28 Nov 2024 10:37:41 +0000 Subject: [PATCH] fix(minifier): do not fold if statement block with lexical declaration (#7519) --- crates/oxc_allocator/src/vec.rs | 11 +++++----- .../peephole_minimize_conditions.rs | 21 +++++++++++++++---- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index 057333aae5c36..bb098c9c66fd3 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -223,12 +223,11 @@ impl<'alloc, T> ops::Index for Vec<'alloc, T> { } } -// Unused right now. -// impl<'alloc, T> ops::IndexMut for Vec<'alloc, T> { -// fn index_mut(&mut self, index: usize) -> &mut Self::Output { -// self.0.index_mut(index) -// } -// } +impl<'alloc, T> ops::IndexMut for Vec<'alloc, T> { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + self.0.index_mut(index) + } +} #[cfg(any(feature = "serialize", test))] impl<'alloc, T> Serialize for Vec<'alloc, T> diff --git a/crates/oxc_minifier/src/ast_passes/peephole_minimize_conditions.rs b/crates/oxc_minifier/src/ast_passes/peephole_minimize_conditions.rs index d29c6c8341f03..9f94bd52d2401 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_minimize_conditions.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_minimize_conditions.rs @@ -68,15 +68,19 @@ impl<'a> PeepholeMinimizeConditions { /// Duplicate logic to DCE part. fn try_fold_if_block_one(&mut self, if_stmt: &mut IfStatement<'a>, ctx: &mut TraverseCtx<'a>) { if let Statement::BlockStatement(block) = &mut if_stmt.consequent { - if block.body.len() == 1 { + if block.body.len() == 1 + && !matches!(&block.body[0], Statement::VariableDeclaration(decl) if !decl.kind.is_var()) + { self.changed = true; - if_stmt.consequent = ctx.ast.move_statement(block.body.first_mut().unwrap()); + if_stmt.consequent = ctx.ast.move_statement(&mut block.body[0]); } } if let Some(Statement::BlockStatement(block)) = &mut if_stmt.alternate { - if block.body.len() == 1 { + if block.body.len() == 1 + && !matches!(&block.body[0], Statement::VariableDeclaration(decl) if !decl.kind.is_var()) + { self.changed = true; - if_stmt.alternate = Some(ctx.ast.move_statement(block.body.first_mut().unwrap())); + if_stmt.alternate = Some(ctx.ast.move_statement(&mut block.body[0])); } } } @@ -241,6 +245,15 @@ mod test { fold_same("function f(){foo()}"); fold_same("switch(x){case y: foo()}"); fold_same("try{foo()}catch(ex){bar()}finally{baz()}"); + + // Dot not fold `let` and `const`. + // Lexical declaration cannot appear in a single-statement context. + fold_same("if (foo) { const bar = 1 } else { const baz = 1 }"); + fold_same("if (foo) { let bar = 1 } else { let baz = 1 }"); + fold( + "if (foo) { var bar = 1 } else { var baz = 1 }", + "if (foo) var bar = 1; else var baz = 1;", + ); } /** Try to minimize returns */