From 2e354a3872688a244ea3f12f3b4b4269fc5c6679 Mon Sep 17 00:00:00 2001 From: alexlamsl Date: Wed, 17 Feb 2016 02:52:28 +0800 Subject: [PATCH] preserve ThisBinding for side_effects --- lib/compress.js | 20 ++++++++-------- test/compress/issue-782.js | 4 ++++ test/compress/issue-973.js | 47 ++++++++++++++++++++++++++++++-------- 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index df8975d5..ed4f62ff 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -179,9 +179,9 @@ merge(Compressor.prototype, { // we shouldn't compress (1,func)(something) to // func(something) because that changes the meaning of // the func (becomes lexical instead of global). - function maintain_call_binding(parent, orig, val) { + function maintain_this_binding(parent, orig, val) { if (parent instanceof AST_Call && parent.expression === orig) { - if (val instanceof AST_PropAccess || (val instanceof AST_Symbol && val.name === "eval")) { + if (val instanceof AST_PropAccess || val instanceof AST_SymbolRef && val.name === "eval") { return make_node(AST_Seq, orig, { car: make_node(AST_Number, orig, { value: 0 @@ -383,7 +383,7 @@ merge(Compressor.prototype, { if (is_lvalue(node, parent)) return node; // Remove var definition and return its value to the TreeTransformer to replace. - var value = maintain_call_binding(parent, node, var_decl.value); + var value = maintain_this_binding(parent, node, var_decl.value); var_decl.value = null; var_defs.splice(var_defs_index, 1); @@ -2125,7 +2125,7 @@ merge(Compressor.prototype, { if (!compressor.option("side_effects")) return self; if (!self.car.has_side_effects(compressor)) { - return maintain_call_binding(compressor.parent(), self, self.cdr); + return maintain_this_binding(compressor.parent(), self, self.cdr); } if (compressor.option("cascade")) { if (self.car instanceof AST_Assign @@ -2315,10 +2315,10 @@ merge(Compressor.prototype, { if (ll.length > 1) { if (ll[1]) { compressor.warn("Condition left of && always true [{file}:{line},{col}]", self.start); - return maintain_call_binding(compressor.parent(), self, self.right.evaluate(compressor)[0]); + return maintain_this_binding(compressor.parent(), self, self.right.evaluate(compressor)[0]); } else { compressor.warn("Condition left of && always false [{file}:{line},{col}]", self.start); - return maintain_call_binding(compressor.parent(), self, ll[0]); + return maintain_this_binding(compressor.parent(), self, ll[0]); } } } @@ -2327,10 +2327,10 @@ merge(Compressor.prototype, { if (ll.length > 1) { if (ll[1]) { compressor.warn("Condition left of || always true [{file}:{line},{col}]", self.start); - return maintain_call_binding(compressor.parent(), self, ll[0]); + return maintain_this_binding(compressor.parent(), self, ll[0]); } else { compressor.warn("Condition left of || always false [{file}:{line},{col}]", self.start); - return maintain_call_binding(compressor.parent(), self, self.right.evaluate(compressor)[0]); + return maintain_this_binding(compressor.parent(), self, self.right.evaluate(compressor)[0]); } } } @@ -2555,10 +2555,10 @@ merge(Compressor.prototype, { if (cond.length > 1) { if (cond[1]) { compressor.warn("Condition always true [{file}:{line},{col}]", self.start); - return maintain_call_binding(compressor.parent(), self, self.consequent); + return maintain_this_binding(compressor.parent(), self, self.consequent); } else { compressor.warn("Condition always false [{file}:{line},{col}]", self.start); - return maintain_call_binding(compressor.parent(), self, self.alternative); + return maintain_this_binding(compressor.parent(), self, self.alternative); } } var negated = cond[0].negate(compressor); diff --git a/test/compress/issue-782.js b/test/compress/issue-782.js index 80b1493c..2f72d1ab 100644 --- a/test/compress/issue-782.js +++ b/test/compress/issue-782.js @@ -1,10 +1,12 @@ remove_redundant_sequence_items: { options = { side_effects: true }; input: { + (0, 1, eval)(); (0, 1, logThis)(); (0, 1, _decorators.logThis)(); } expect: { + (0, eval)(); logThis(); (0, _decorators.logThis)(); } @@ -13,10 +15,12 @@ remove_redundant_sequence_items: { dont_remove_this_binding_sequence: { options = { side_effects: true }; input: { + (0, eval)(); (0, logThis)(); (0, _decorators.logThis)(); } expect: { + (0, eval)(); logThis(); (0, _decorators.logThis)(); } diff --git a/test/compress/issue-973.js b/test/compress/issue-973.js index f2d44010..0e040922 100644 --- a/test/compress/issue-973.js +++ b/test/compress/issue-973.js @@ -18,6 +18,11 @@ this_binding_conditionals: { (0 || a[b])(); (0 || 1 && a[b])(); (1 ? a[b] : 0)(); + + (1 && eval)(); + (0 || eval)(); + (0 || 1 && eval)(); + (1 ? eval : 0)(); } expect: { a(); @@ -34,6 +39,11 @@ this_binding_conditionals: { (0, a[b])(); (0, a[b])(); (0, a[b])(); + + (0, eval)(); + (0, eval)(); + (0, eval)(); + (0, eval)(); } } @@ -44,26 +54,43 @@ this_binding_collapse_vars: { input: { var c = a; c(); var d = a.b; d(); + var e = eval; e(); } expect: { a(); (0, a.b)(); + (0, eval)(); } } -eval_direct_calls: { +this_binding_side_effects: { options = { - side_effects: true, - collapse_vars: true - } + side_effects : true + }; input: { - (0, eval)(''); - - var fn = eval; - fn(''); + (function (foo) { + (0, foo)(); + (0, foo.bar)(); + (0, eval)('console.log(foo);'); + }()); + (function (foo) { + var eval = console; + (0, foo)(); + (0, foo.bar)(); + (0, eval)('console.log(foo);'); + }()); } expect: { - (0, eval)(''); - (0, eval)(''); + (function (foo) { + foo(); + (0, foo.bar)(); + (0, eval)('console.log(foo);'); + }()); + (function (foo) { + var eval = console; + foo(); + (0, foo.bar)(); + (0, eval)('console.log(foo);'); + }()); } } \ No newline at end of file