From 975646947467103288a391bc62ae89b257467486 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Sat, 25 Jan 2025 18:32:09 +0900 Subject: [PATCH] fix(mangler): handle cases where a var is declared in a block scope --- crates/oxc_mangler/src/lib.rs | 9 ++++++ crates/oxc_minifier/tests/mangler/mod.rs | 4 +++ .../tests/mangler/snapshots/mangler.snap | 28 +++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/crates/oxc_mangler/src/lib.rs b/crates/oxc_mangler/src/lib.rs index 0dc5fab99de5c..e20d61f30260f 100644 --- a/crates/oxc_mangler/src/lib.rs +++ b/crates/oxc_mangler/src/lib.rs @@ -232,6 +232,9 @@ impl Mangler { { slots[symbol_id.index()] = assigned_slot; + let declared_scope_id = + ast_nodes.get_node(symbol_table.get_declaration(*symbol_id)).scope_id(); + // Calculate the scope ids that this symbol is alive in. let lived_scope_ids = symbol_table .get_resolved_references(*symbol_id) @@ -239,6 +242,12 @@ impl Mangler { let used_scope_id = ast_nodes.get_node(reference.node_id()).scope_id(); scope_tree.ancestors(used_scope_id).take_while(|s_id| *s_id != scope_id) }) + // also include scopes that this symbol was declared (for cases like `function foo() { { var x; let y; } }`) + .chain( + scope_tree + .ancestors(declared_scope_id) + .take_while(|s_id| *s_id != scope_id), + ) .chain(iter::once(scope_id)); // Since the slot is now assigned to this symbol, it is alive in all the scopes that this symbol is alive in. diff --git a/crates/oxc_minifier/tests/mangler/mod.rs b/crates/oxc_minifier/tests/mangler/mod.rs index 8534638354ddb..a99e7ccd6fedb 100644 --- a/crates/oxc_minifier/tests/mangler/mod.rs +++ b/crates/oxc_minifier/tests/mangler/mod.rs @@ -40,6 +40,10 @@ fn mangler() { "function _() { var x; try { throw 0 } catch (e) { e } }", // e can shadow x "function _() { var x; try { throw 0 } catch (e) { var e } }", // e can shadow x (not implemented) "function _() { var x; try { throw 0 } catch { var e } }", // e should not shadow x + "function _() { var x; var y; }", // x and y should have different names + "function _() { var x; let y; }", // x and y should have different names + "function _() { { var x; var y; } }", // x and y should have different names + "function _() { { var x; let y; } }", // x and y should have different names ]; let top_level_cases = [ "function foo(a) {a}", diff --git a/crates/oxc_minifier/tests/mangler/snapshots/mangler.snap b/crates/oxc_minifier/tests/mangler/snapshots/mangler.snap index 5056372bf82bf..e54ece1cb3849 100644 --- a/crates/oxc_minifier/tests/mangler/snapshots/mangler.snap +++ b/crates/oxc_minifier/tests/mangler/snapshots/mangler.snap @@ -153,6 +153,34 @@ function _() { } } +function _() { var x; var y; } +function _() { + var a; + var b; +} + +function _() { var x; let y; } +function _() { + var a; + let b; +} + +function _() { { var x; var y; } } +function _() { + { + var a; + var b; + } +} + +function _() { { var x; let y; } } +function _() { + { + var a; + let b; + } +} + function foo(a) {a} function a(a) { a;