From 7f418978c9d39bd0827108176d817259a6e60f5c Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Wed, 13 Dec 2017 18:20:53 +0800 Subject: [PATCH] recover lost opportunities from #2574 (#2584) --- lib/compress.js | 23 ++++++++++++++++- test/compress/collapse_vars.js | 46 +++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 6aee9497..004858ac 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -863,6 +863,7 @@ merge(Compressor.prototype, { if (scope.uses_eval || scope.uses_with) return statements; var args; var candidates = []; + var in_try = compressor.self() instanceof AST_Try; var stat_index = statements.length; var scanner = new TreeTransformer(function(node, descend) { if (abort) return node; @@ -956,7 +957,8 @@ merge(Compressor.prototype, { || side_effects && !references_in_scope(node.definition())) || (sym = lhs_or_def(node)) && (sym instanceof AST_PropAccess || sym.name in lvalues) - || may_throw && node.has_side_effects(compressor) + || may_throw + && (in_try ? node.has_side_effects(compressor) : side_effects_external(node)) || (side_effects || !replace_all) && (parent instanceof AST_Binary && lazy_op(parent.operator) || parent instanceof AST_Conditional @@ -1192,6 +1194,25 @@ merge(Compressor.prototype, { return ref.scope === scope; }); } + + function side_effects_external(node, lhs) { + if (node instanceof AST_Assign) { + return side_effects_external(node.left, true) + || side_effects_external(node.right); + } + if (node instanceof AST_Definitions) return false; + if (node instanceof AST_Unary) return side_effects_external(node.expression, true); + if (node instanceof AST_VarDef) return node.value && side_effects_external(node.value); + if (lhs) { + if (node instanceof AST_Dot) return side_effects_external(node.expression, true); + if (node instanceof AST_Sub) { + return side_effects_external(node.expression, true) + || side_effects_external(node.property); + } + if (node instanceof AST_SymbolRef) return node.definition().scope !== scope; + } + return node.has_side_effects(compressor); + } } function eliminate_spurious_blocks(statements) { diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index 58405801..9dd69019 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -69,11 +69,10 @@ collapse_vars_side_effects_1: { log(x, s.charAt(i++), y, 7); } function f4() { - var log = console.log.bind(console), - i = 10, + var i = 10, x = i += 2, y = i += 3; - log(x, i += 4, y, i); + console.log.bind(console)(x, i += 4, y, i); } f1(), f2(), f3(), f4(); } @@ -676,8 +675,8 @@ collapse_vars_lvalues: { function f4(x) { var a = (x -= 3); return x + a; } function f5(x) { var w = e1(), v = e2(), c = v = --x; return (w = x) - c; } function f6(x) { var w = e1(), v = e2(); return (v = --x) - (w = x); } - function f7(x) { var w = e1(), v = e2(); return (w = x) - (v - x); } - function f8(x) { var w = e1(), v = e2(); return (w = x) - (v - x); } + function f7(x) { var w = e1(); return (w = x) - (e2() - x); } + function f8(x) { var w = e1(); return (w = x) - (e2() - x); } function f9(x) { var w = e1(); return e2() - x - (w = x); } } } @@ -2251,7 +2250,7 @@ issue_315: { expect: { console.log(function() { var w, _i, _len, _ref, _results; - for (_ref = "test".trim().split(" "), _results = [], _i = 0, _len = _ref.length; _i < _len ; _i++) + for (_results = [], _i = 0, _len = (_ref = "test".trim().split(" ")).length; _i < _len ; _i++) w = _ref[_i], _results.push(w.toLowerCase()); return _results; }()); @@ -3164,8 +3163,8 @@ issue_2437: { return Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc || {}), result; } - var req = new XMLHttpRequest(), detectFunc = function() {}; - req.onreadystatechange = detectFunc; + var req, detectFunc = function() {}; + (req = new XMLHttpRequest()).onreadystatechange = detectFunc; result = req[SYMBOL_FAKE_ONREADYSTATECHANGE_1] === detectFunc; req.onreadystatechange = null; }(); @@ -3786,7 +3785,7 @@ issue_2571_2: { expect_stdout: "undefined" } -may_throw: { +may_throw_1: { options = { collapse_vars: true, } @@ -3806,6 +3805,35 @@ may_throw: { } } +may_throw_2: { + options = { + collapse_vars: true, + unused: true, + } + input: { + function f(b) { + try { + var a = x(); + ++b; + return b(a); + } catch(e) {} + console.log(b); + } + f(0); + } + expect: { + function f(b) { + try { + var a = x(); + return (++b)(a); + } catch(e) {} + console.log(b); + } + f(0); + } + expect_stdout: "0" +} + side_effect_free_replacement: { options = { collapse_vars: true, -- 2.34.1