diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2018-02-13 01:41:22 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-13 01:41:22 +0800 |
commit | 0c4f315c026e607d00dd74ad7417344a937bf6dd (patch) | |
tree | 83b5324ae53679633bda9b0f50abb62e951f8014 /lib/compress.js | |
parent | 0809699bdc7b1c249c7bbe02924a4a861aff8bea (diff) | |
download | tracifyjs-0c4f315c026e607d00dd74ad7417344a937bf6dd.tar.gz tracifyjs-0c4f315c026e607d00dd74ad7417344a937bf6dd.zip |
fix corner case in `collapse_vars` (#2909)
fixes #2908
Diffstat (limited to 'lib/compress.js')
-rw-r--r-- | lib/compress.js | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/lib/compress.js b/lib/compress.js index 2b796dcc..ad691f7a 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -972,13 +972,13 @@ merge(Compressor.prototype, { || node instanceof AST_Try || node instanceof AST_With || parent instanceof AST_For && node !== parent.init - || (side_effects || !replace_all) + || !replace_all && (node instanceof AST_SymbolRef && !node.is_declared(compressor))) { abort = true; return node; } // Stop only if candidate is found within conditional branches - if (!stop_if_hit && (side_effects || !replace_all) + if (!stop_if_hit && (!lhs_local || !replace_all) && (parent instanceof AST_Binary && lazy_op(parent.operator) && parent.left !== node || parent instanceof AST_Conditional && parent.condition !== node || parent instanceof AST_If && parent.condition !== node)) { @@ -1096,17 +1096,12 @@ merge(Compressor.prototype, { var stop_if_hit = null; var lhs = get_lhs(candidate); if (!lhs || is_lhs_read_only(lhs) || lhs.has_side_effects(compressor)) continue; + var lhs_local = is_lhs_local(lhs); // Locate symbols which may execute code outside of scanning range var lvalues = get_lvalues(candidate); if (lhs instanceof AST_SymbolRef) lvalues[lhs.name] = false; - var replace_all = value_def; - if (!replace_all && lhs instanceof AST_SymbolRef) { - var def = lhs.definition(); - if (def.references.length - def.replaced == (candidate instanceof AST_VarDef ? 1 : 2)) { - replace_all = true; - } - } var side_effects = value_has_side_effects(candidate); + var replace_all = replace_all_symbols(); var may_throw = candidate.may_throw(compressor); var funarg = candidate.name instanceof AST_SymbolFunarg; var hit = funarg; @@ -1151,7 +1146,7 @@ merge(Compressor.prototype, { hit_index++; } branch.expression = branch.expression.transform(scanner); - if (side_effects || !replace_all) break; + if (!replace_all) break; } } abort = true; @@ -1393,11 +1388,28 @@ merge(Compressor.prototype, { })); } + function is_lhs_local(lhs) { + while (lhs instanceof AST_PropAccess) lhs = lhs.expression; + return lhs instanceof AST_SymbolRef && lhs.definition().scope === scope; + } + function value_has_side_effects(expr) { if (expr instanceof AST_Unary) return false; return get_rvalue(expr).has_side_effects(compressor); } + function replace_all_symbols() { + if (side_effects) return false; + if (value_def) return true; + if (lhs instanceof AST_SymbolRef) { + var def = lhs.definition(); + if (def.references.length - def.replaced == (candidate instanceof AST_VarDef ? 1 : 2)) { + return true; + } + } + return false; + } + function may_modify(sym) { var def = sym.definition(); if (def.orig.length == 1 && def.orig[0] instanceof AST_SymbolDefun) return false; |