From 80d5f23fee0f727aef1b374b650651e4efc1cd66 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Wed, 29 Dec 2021 21:15:53 +0000 Subject: [PATCH] fix corner case with lexical variables (#5244) --- lib/scope.js | 24 ++++++------ test/compress/let.js | 90 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 14 deletions(-) diff --git a/lib/scope.js b/lib/scope.js index 89c66714..a0b7c648 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -214,10 +214,8 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { } else if (node instanceof AST_SymbolDefun) { var def = defun.def_function(node, tw.parent()); if (exported) def.exported = true; - entangle(defun, scope); } else if (node instanceof AST_SymbolFunarg) { defun.def_variable(node); - entangle(defun, scope); } else if (node instanceof AST_SymbolLambda) { var def = defun.def_function(node, node.name == "arguments" ? undefined : defun); if (options.ie) def.defun = defun.parent_scope.resolve(); @@ -227,7 +225,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { } else if (node instanceof AST_SymbolVar) { var def = defun.def_variable(node, node instanceof AST_SymbolImport ? undefined : null); if (exported) def.exported = true; - entangle(defun, scope); } function walk_scope(descend) { @@ -240,16 +237,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { scope = save_scope; defun = save_defun; } - - function entangle(defun, scope) { - if (defun === scope) return; - node.mark_enclosed(options); - var def = scope.find_variable(node.name); - if (node.thedef === def) return; - node.thedef = def; - def.orig.push(node); - node.mark_enclosed(options); - } }); self.make_def = function(orig, init) { return new SymbolDef(++next_def_id, this, orig, init); @@ -270,6 +257,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { } if (node instanceof AST_Lambda) { in_arg.push(node); + if (node.name) node.name.walk(tw); node.argnames.forEach(function(argname) { argname.walk(tw); }); @@ -296,6 +284,16 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { // ensure compression works if `const` reuses a scope variable var redef = def.redefined(); if (redef) redef.const_redefs = true; + } else if (def.scope !== node.scope && (node instanceof AST_SymbolDefun + || node instanceof AST_SymbolFunarg + || node instanceof AST_SymbolVar)) { + node.mark_enclosed(options); + var redef = node.scope.find_variable(node.name); + if (node.thedef !== redef) { + node.thedef = redef; + redef.orig.push(node); + node.mark_enclosed(options); + } } if (node.name != "arguments") return true; var parent = node instanceof AST_SymbolVar && tw.parent(); diff --git a/test/compress/let.js b/test/compress/let.js index 629119e7..3f4f75df 100644 --- a/test/compress/let.js +++ b/test/compress/let.js @@ -1,4 +1,4 @@ -retain_block: { +retain_block_1: { options = {} input: { "use strict"; @@ -20,6 +20,94 @@ retain_block: { node_version: ">=4" } +retain_block_2: { + options = { + toplevel: true, + unused: true, + } + input: { + "use strict"; + { + var a; + let a; + } + } + expect: { + "use strict"; + { + var a; + let a; + } + } + expect_stdout: true + node_version: ">=4" +} + +retain_block_2_mangle: { + rename = true + mangle = { + toplevel: true, + } + input: { + "use strict"; + { + var a; + let a; + } + } + expect: { + "use strict"; + { + var t; + let t; + } + } +} + +retain_block_3: { + options = { + toplevel: true, + unused: true, + } + input: { + "use strict"; + { + let a; + var a; + } + } + expect: { + "use strict"; + { + let a; + var a; + } + } + expect_stdout: true + node_version: ">=4" +} + +retain_block_3_mangle: { + rename = true + mangle = { + toplevel: true, + } + input: { + "use strict"; + { + let a; + var a; + } + } + expect: { + "use strict"; + { + let t; + var t; + } + } +} + retain_assignment: { options = { dead_code: true,