diff --git a/lib/compress/tighten-body.js b/lib/compress/tighten-body.js index 137ed609d..151383ea3 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, 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)) @@ -442,8 +444,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); @@ -509,8 +512,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; @@ -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,18 @@ export function tighten_body(statements, compressor) { } return false; } + + 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; + } } function eliminate_spurious_blocks(statements) { diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index b76b8c6c1..60a6e2328 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_variable_2: { + 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; + } + } +}