aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2017-10-30 23:19:27 +0800
committerGitHub <noreply@github.com>2017-10-30 23:19:27 +0800
commita48f87abf2fb09cc8296444eb613021ef66492c3 (patch)
tree44baa58b8268f79548ed1e522b2019636176da0a
parent2fd927a7ccfb55de415bf1faafb45e5006ca9984 (diff)
downloadtracifyjs-a48f87abf2fb09cc8296444eb613021ef66492c3.tar.gz
tracifyjs-a48f87abf2fb09cc8296444eb613021ef66492c3.zip
compress `new` `function` containing `this` (#2417)
-rw-r--r--lib/compress.js27
-rw-r--r--test/compress/hoist_props.js28
-rw-r--r--test/compress/properties.js19
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);
+ }
+}