From 69ec428ec873a8552fc3bacb5ea9995ef2501e1e Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Tue, 7 Sep 2021 03:04:58 -0400 Subject: [PATCH 1/3] collapse_vars: fix inlining expr into scope with shadowed var --- lib/compress/tighten-body.js | 31 ++++++++++++---- test/compress/collapse_vars.js | 66 ++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 6 deletions(-) diff --git a/lib/compress/tighten-body.js b/lib/compress/tighten-body.js index 137ed609d..163a9ee83 100644 --- a/lib/compress/tighten-body.js +++ b/lib/compress/tighten-body.js @@ -321,7 +321,9 @@ export function tighten_body(statements, compressor) { // Replace variable with assignment when found if (can_replace && !(node instanceof AST_SymbolDeclaration) - && lhs.equivalent_to(node)) { + && lhs.equivalent_to(node) + && !shadows(node.scope, lhs.scope, lvalues) + ) { if (stop_if_hit) { abort = true; return node; @@ -369,7 +371,7 @@ export function tighten_body(statements, compressor) { || node instanceof AST_PropAccess && (side_effects || node.expression.may_throw_on_access(compressor)) || node instanceof AST_SymbolRef - && (lvalues.get(node.name) || side_effects && may_modify(node)) + && ((lvalues.has(node.name) && lvalues.get(node.name).modified) || side_effects && may_modify(node)) || node instanceof AST_VarDef && node.value && (lvalues.has(node.name.name) || side_effects && may_modify(node.name)) || (sym = is_lhs(node.left, node)) @@ -419,6 +421,7 @@ export function tighten_body(statements, compressor) { return node; }); + debugger; while (--stat_index >= 0) { // Treat parameters as collapsible in IIFE, i.e. // function(a, b){ ... }(x()); @@ -442,8 +445,9 @@ export function tighten_body(statements, compressor) { // Locate symbols which may execute code outside of scanning range var lvalues = get_lvalues(candidate); var lhs_local = is_lhs_local(lhs); - if (lhs instanceof AST_SymbolRef) - lvalues.set(lhs.name, false); + if (lhs instanceof AST_SymbolRef) { + lvalues.set(lhs.name, { def: lhs.definition(), modified: false }); + } var side_effects = value_has_side_effects(candidate); var replace_all = replace_all_symbols(); var may_throw = candidate.may_throw(compressor); @@ -791,8 +795,14 @@ export function tighten_body(statements, compressor) { var sym = node; while (sym instanceof AST_PropAccess) sym = sym.expression; - if (sym instanceof AST_SymbolRef || sym instanceof AST_This) { - lvalues.set(sym.name, lvalues.get(sym.name) || is_modified(compressor, tw, node, node, 0)); + if (sym instanceof AST_SymbolRef) { + const prev = lvalues.get(sym.name); + if (!prev || !prev.modified) { + lvalues.set(sym.name, { + def: sym.definition(), + modified: is_modified(compressor, tw, node, node, 0) + }); + } } }); get_rvalue(expr).walk(tw); @@ -904,6 +914,15 @@ export function tighten_body(statements, compressor) { } return false; } + + function shadows(newScope, oldScope, lvalues) { + for (const value of lvalues.values()) { + if (redefined_within_scope(value.def, newScope)) { + return true; + } + } + return false; + } } function eliminate_spurious_blocks(statements) { diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index b76b8c6c1..f5aa9aa63 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -6056,3 +6056,69 @@ do_not_place_chain_on_lhs_2: { a.d = e; } } + +shadowed_variable: { + options = { + pure_getters: true, + collapse_vars: true, + unused: true, + } + input: { + function test(e) { + const result = {}; + const test = e.test; + + { + const e = random(test); + result.discretized = e + } + + return result; + } + } + expect: { + function test(e) { + const result = {}; + const test = e.test; + { + const e = random(test); + result.discretized = e; + } + return result; + } + } +} + +shadowed_variable2: { + options = { + pure_getters: true, + collapse_vars: true, + unused: true, + } + input: { + function test(e) { + const result = {}; + const test = e.test; + { + { + result.discretized = random(test); + } + const e = random(); + console.log(e); + } + return result; + } + } + expect: { + function test(e) { + const result = {}; + const test = e.test; + { + result.discretized = random(test); + const e = random(); + console.log(e); + } + return result; + } + } +} From 1704baceb5725b98411047fc632b349dfb0f4bbd Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Tue, 7 Sep 2021 03:57:12 -0400 Subject: [PATCH 2/3] Fix scope crawl --- lib/compress/tighten-body.js | 16 ++++++++++------ test/compress/collapse_vars.js | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/compress/tighten-body.js b/lib/compress/tighten-body.js index 163a9ee83..2836341a1 100644 --- a/lib/compress/tighten-body.js +++ b/lib/compress/tighten-body.js @@ -322,7 +322,7 @@ export function tighten_body(statements, compressor) { if (can_replace && !(node instanceof AST_SymbolDeclaration) && lhs.equivalent_to(node) - && !shadows(node.scope, lhs.scope, lvalues) + && !shadows(node.scope, lvalues) ) { if (stop_if_hit) { abort = true; @@ -513,8 +513,9 @@ export function tighten_body(statements, compressor) { return false; let cur_scope = def.scope; while (cur_scope && cur_scope !== scope) { - if (cur_scope.variables.has(def.name)) + if (cur_scope.variables.has(def.name)) { return true; + } cur_scope = cur_scope.parent_scope; } return false; @@ -915,10 +916,13 @@ export function tighten_body(statements, compressor) { return false; } - function shadows(newScope, oldScope, lvalues) { - for (const value of lvalues.values()) { - if (redefined_within_scope(value.def, newScope)) { - return true; + function shadows(newScope, lvalues) { + for (const {def} of lvalues.values()) { + let current = newScope; + while (current && current !== def.scope) { + let nested_def = current.variables.get(def.name); + if (nested_def && nested_def !== def) return true; + current = current.parent_scope; } } return false; diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index f5aa9aa63..60a6e2328 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -6089,7 +6089,7 @@ shadowed_variable: { } } -shadowed_variable2: { +shadowed_variable_2: { options = { pure_getters: true, collapse_vars: true, From 0472ff7fd35f93d36b523baec8f352d9d80aadc6 Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Sat, 11 Sep 2021 10:16:19 -0400 Subject: [PATCH 3/3] Update lib/compress/tighten-body.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fábio Santos --- lib/compress/tighten-body.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/compress/tighten-body.js b/lib/compress/tighten-body.js index 2836341a1..151383ea3 100644 --- a/lib/compress/tighten-body.js +++ b/lib/compress/tighten-body.js @@ -421,7 +421,6 @@ export function tighten_body(statements, compressor) { return node; }); - debugger; while (--stat_index >= 0) { // Treat parameters as collapsible in IIFE, i.e. // function(a, b){ ... }(x());