From: Alex Lam S.L Date: Tue, 17 Oct 2017 18:54:51 +0000 (+0800) Subject: fix `AST_PropAccess` in `collapse_vars` (take 3) (#2375) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=7e5b5cac97a71d0eb0d23f0cba7554e8a9eec179;p=UglifyJS.git fix `AST_PropAccess` in `collapse_vars` (take 3) (#2375) Suppress scanning beyond assignment to `a.b` --- diff --git a/lib/compress.js b/lib/compress.js index 3ab54f16..b89e0df9 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -838,11 +838,12 @@ merge(Compressor.prototype, { if (node instanceof AST_Call || node instanceof AST_Exit || node instanceof AST_PropAccess - && (side_effects || node.has_side_effects(compressor)) + && (side_effects || node.expression.may_throw_on_access(compressor)) || node instanceof AST_SymbolRef && (lvalues[node.name] || side_effects && !references_in_scope(node.definition())) - || (sym = lhs_or_def(node)) && get_symbol(sym).name in lvalues + || (sym = lhs_or_def(node)) + && (sym instanceof AST_PropAccess || sym.name in lvalues) || parent instanceof AST_Binary && lazy_op(parent.operator) || parent instanceof AST_Case || parent instanceof AST_Conditional @@ -933,29 +934,14 @@ merge(Compressor.prototype, { } } - function get_symbol(node) { - while (node instanceof AST_PropAccess) node = node.expression; - return node; - } - function get_lvalues(expr) { var lvalues = Object.create(null); if (expr instanceof AST_Unary) return lvalues; - var scope; var tw = new TreeWalker(function(node, descend) { - if (node instanceof AST_Scope) { - var save_scope = scope; - descend(); - scope = save_scope; - return true; - } - if (node instanceof AST_PropAccess - || node instanceof AST_SymbolRef - || node instanceof AST_This) { - var sym = get_symbol(node); - if (sym instanceof AST_SymbolRef || node instanceof AST_This) { - lvalues[sym.name] = lvalues[sym.name] || is_lhs(node, tw.parent()); - } + var sym = node; + while (sym instanceof AST_PropAccess) sym = sym.expression; + if (sym instanceof AST_SymbolRef || sym instanceof AST_This) { + lvalues[sym.name] = lvalues[sym.name] || is_lhs(node, tw.parent()); } }); expr[expr instanceof AST_Assign ? "right" : "value"].walk(tw); diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index c115763c..13fff97a 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -2783,3 +2783,171 @@ issue_2364_4: { } expect_stdout: "1 0" } + +issue_2364_5: { + options = { + collapse_vars: true, + evaluate: true, + pure_getters: true, + properties: true, + reduce_vars: true, + unused: true, + } + input: { + function f0(o, a, h) { + var b = 3 - a; + var obj = o; + var seven = 7; + var prop = 'run'; + var t = obj[prop](b)[seven] = h; + return t; + } + } + expect: { + function f0(o, a, h) { + return o.run(3 - a)[7] = h; + } + } +} + +issue_2364_6: { + options = { + collapse_vars: true, + pure_getters: true, + } + input: { + function f(a, b) { + var c = a.p; + b.p = "FAIL"; + return c; + } + var o = { + p: "PASS" + } + console.log(f(o, o)); + } + expect: { + function f(a, b) { + var c = a.p; + b.p = "FAIL"; + return c; + } + var o = { + p: "PASS" + } + console.log(f(o, o)); + } + expect_stdout: "PASS" +} + +issue_2364_7: { + options = { + collapse_vars: true, + pure_getters: true, + } + input: { + function f(a, b) { + var c = a.p; + b.f(); + return c; + } + var o = { + p: "PASS", + f: function() { + this.p = "FAIL"; + } + } + console.log(f(o, o)); + } + expect: { + function f(a, b) { + var c = a.p; + b.f(); + return c; + } + var o = { + p: "PASS", + f: function() { + this.p = "FAIL"; + } + } + console.log(f(o, o)); + } + expect_stdout: "PASS" +} + +issue_2364_8: { + options = { + collapse_vars: true, + pure_getters: true, + } + input: { + function f(a, b, c) { + var d = a[b.f = function() { + return "PASS"; + }]; + return c.f(d); + } + var o = { + f: function() { + return "FAIL"; + } + }; + console.log(f({}, o, o)); + } + expect: { + function f(a, b, c) { + var d = a[b.f = function() { + return "PASS"; + }]; + return c.f(d); + } + var o = { + f: function() { + return "FAIL"; + } + }; + console.log(f({}, o, o)); + } + expect_stdout: "PASS" +} + +issue_2364_9: { + options = { + collapse_vars: true, + pure_getters: true, + } + input: { + function f(a, b) { + var d = a(); + return b.f(d); + } + var o = { + f: function() { + return "FAIL"; + } + }; + console.log(f(function() { + o.f = function() { + return "PASS"; + }; + }, o)); + } + expect: { + function f(a, b) { + var d = a(); + return b.f(d); + } + var o = { + f: function() { + return "FAIL"; + } + }; + console.log(f(function() { + o.f = function() { + return "PASS"; + }; + }, o)); + } + expect_stdout: "PASS" +}