Skip to content

Commit

Permalink
collapse_vars: fix inlining expr into scope with shadowed var (#1065)
Browse files Browse the repository at this point in the history
* collapse_vars: fix inlining expr into scope with shadowed var

* Fix scope crawl

* Update lib/compress/tighten-body.js

Co-authored-by: F谩bio Santos <fabiosantosart@gmail.com>

Co-authored-by: F谩bio Santos <fabiosantosart@gmail.com>
  • Loading branch information
jridgewell and fabiosantoscode committed Sep 11, 2021
1 parent 438806d commit f8a1f89
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 7 deletions.
36 changes: 29 additions & 7 deletions lib/compress/tighten-body.js
Expand Up @@ -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;
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down
66 changes: 66 additions & 0 deletions test/compress/collapse_vars.js
Expand Up @@ -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;
}
}
}

0 comments on commit f8a1f89

Please sign in to comment.