compress new function containing this (#2417)

This commit is contained in:
Alex Lam S.L
2017-10-30 23:19:27 +08:00
committed by GitHub
parent 2fd927a7cc
commit a48f87abf2
3 changed files with 61 additions and 13 deletions

View File

@@ -592,7 +592,7 @@ merge(Compressor.prototype, {
|| !immutable || !immutable
&& parent instanceof AST_Call && parent instanceof AST_Call
&& parent.expression === node && parent.expression === node
&& (!(value instanceof AST_Function) || value.contains_this())) { && (!(value instanceof AST_Function) || value.contains_this(parent))) {
return true; return true;
} else if (parent instanceof AST_Array || parent instanceof AST_Object) { } else if (parent instanceof AST_Array || parent instanceof AST_Object) {
return is_modified(parent, parent, level + 1); return is_modified(parent, parent, level + 1);
@@ -4561,11 +4561,11 @@ merge(Compressor.prototype, {
} }
} }
if (is_lhs(self, compressor.parent())) return self; if (is_lhs(self, compressor.parent())) return self;
if (compressor.option("properties") && key !== prop) { if (key !== prop) {
var node = self.flatten_object(property); var sub = self.flatten_object(property, compressor);
if (node) { if (sub) {
expr = self.expression = node.expression; expr = self.expression = sub.expression;
prop = self.property = node.property; prop = self.property = sub.property;
} }
} }
if (compressor.option("properties") && compressor.option("side_effects") if (compressor.option("properties") && compressor.option("side_effects")
@@ -4611,7 +4611,8 @@ merge(Compressor.prototype, {
return self; 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 result;
var self = this; var self = this;
self.walk(new TreeWalker(function(node) { self.walk(new TreeWalker(function(node) {
@@ -4622,7 +4623,8 @@ merge(Compressor.prototype, {
return result; 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; var expr = this.expression;
if (expr instanceof AST_Object) { if (expr instanceof AST_Object) {
var props = expr.properties; var props = expr.properties;
@@ -4633,7 +4635,8 @@ merge(Compressor.prototype, {
return prop instanceof AST_ObjectKeyVal; return prop instanceof AST_ObjectKeyVal;
})) break; })) break;
var value = prop.value; 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, { return make_node(AST_Sub, this, {
expression: make_node(AST_Array, expr, { expression: make_node(AST_Array, expr, {
elements: props.map(function(prop) { elements: props.map(function(prop) {
@@ -4677,10 +4680,8 @@ merge(Compressor.prototype, {
} }
} }
if (is_lhs(self, compressor.parent())) return self; if (is_lhs(self, compressor.parent())) return self;
if (compressor.option("properties")) { var sub = self.flatten_object(self.property, compressor);
var node = self.flatten_object(self.property); if (sub) return sub.optimize(compressor);
if (node) return node.optimize(compressor);
}
var ev = self.evaluate(compressor); var ev = self.evaluate(compressor);
if (ev !== self) { if (ev !== self) {
ev = make_node_from_constant(ev, self).optimize(compressor); ev = make_node_from_constant(ev, self).optimize(compressor);

View File

@@ -369,3 +369,31 @@ contains_this_3: {
} }
expect_stdout: "1 1 true" 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"
}

View File

@@ -1006,3 +1006,22 @@ array_hole: {
} }
expect_stdout: "2 undefined 3" 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);
}
}