From a48f87abf2fb09cc8296444eb613021ef66492c3 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Mon, 30 Oct 2017 23:19:27 +0800 Subject: [PATCH] compress `new` `function` containing `this` (#2417) --- lib/compress.js | 27 ++++++++++++++------------- test/compress/hoist_props.js | 28 ++++++++++++++++++++++++++++ test/compress/properties.js | 19 +++++++++++++++++++ 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index a1db985c..99ab7b7a 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -592,7 +592,7 @@ merge(Compressor.prototype, { || !immutable && parent instanceof AST_Call && parent.expression === node - && (!(value instanceof AST_Function) || value.contains_this())) { + && (!(value instanceof AST_Function) || value.contains_this(parent))) { return true; } else if (parent instanceof AST_Array || parent instanceof AST_Object) { return is_modified(parent, parent, level + 1); @@ -4561,11 +4561,11 @@ merge(Compressor.prototype, { } } if (is_lhs(self, compressor.parent())) return self; - if (compressor.option("properties") && key !== prop) { - var node = self.flatten_object(property); - if (node) { - expr = self.expression = node.expression; - prop = self.property = node.property; + if (key !== prop) { + var sub = self.flatten_object(property, compressor); + if (sub) { + expr = self.expression = sub.expression; + prop = self.property = sub.property; } } if (compressor.option("properties") && compressor.option("side_effects") @@ -4611,7 +4611,8 @@ merge(Compressor.prototype, { return self; }); - AST_Lambda.DEFMETHOD("contains_this", function() { + AST_Lambda.DEFMETHOD("contains_this", function(grandparent) { + if (grandparent instanceof AST_New) return false; var result; var self = this; self.walk(new TreeWalker(function(node) { @@ -4622,7 +4623,8 @@ merge(Compressor.prototype, { return result; }); - AST_PropAccess.DEFMETHOD("flatten_object", function(key) { + AST_PropAccess.DEFMETHOD("flatten_object", function(key, compressor) { + if (!compressor.option("properties")) return; var expr = this.expression; if (expr instanceof AST_Object) { var props = expr.properties; @@ -4633,7 +4635,8 @@ merge(Compressor.prototype, { return prop instanceof AST_ObjectKeyVal; })) break; var value = prop.value; - if (value instanceof AST_Function && value.contains_this()) break; + if (value instanceof AST_Function + && value.contains_this(compressor.parent())) break; return make_node(AST_Sub, this, { expression: make_node(AST_Array, expr, { elements: props.map(function(prop) { @@ -4677,10 +4680,8 @@ merge(Compressor.prototype, { } } if (is_lhs(self, compressor.parent())) return self; - if (compressor.option("properties")) { - var node = self.flatten_object(self.property); - if (node) return node.optimize(compressor); - } + var sub = self.flatten_object(self.property, compressor); + if (sub) return sub.optimize(compressor); var ev = self.evaluate(compressor); if (ev !== self) { ev = make_node_from_constant(ev, self).optimize(compressor); diff --git a/test/compress/hoist_props.js b/test/compress/hoist_props.js index 2e8343a6..ccfc76f8 100644 --- a/test/compress/hoist_props.js +++ b/test/compress/hoist_props.js @@ -369,3 +369,31 @@ contains_this_3: { } expect_stdout: "1 1 true" } + +new_this: { + options = { + evaluate: true, + hoist_props: true, + inline: true, + passes: 2, + reduce_vars: true, + toplevel: true, + unused: true, + } + input: { + var o = { + a: 1, + b: 2, + f: function(a) { + this.b = a; + } + }; + console.log(new o.f(o.a).b, o.b); + } + expect: { + console.log(new function(a) { + this.b = a; + }(1).b, 2); + } + expect_stdout: "1 2" +} diff --git a/test/compress/properties.js b/test/compress/properties.js index 1b5e7fc7..ab202525 100644 --- a/test/compress/properties.js +++ b/test/compress/properties.js @@ -1006,3 +1006,22 @@ array_hole: { } expect_stdout: "2 undefined 3" } + +new_this: { + options = { + properties: true, + side_effects: true, + } + input: { + new { + f: function(a) { + this.a = a; + } + }.f(42); + } + expect: { + new function(a) { + this.a = a; + }(42); + } +} -- 2.34.1