compress AST_Sequence within AST_Call (#3117)
This commit is contained in:
@@ -908,7 +908,7 @@ merge(Compressor.prototype, {
|
|||||||
// the func (becomes lexical instead of global).
|
// the func (becomes lexical instead of global).
|
||||||
function maintain_this_binding(parent, orig, val) {
|
function maintain_this_binding(parent, orig, val) {
|
||||||
if (parent instanceof AST_UnaryPrefix && parent.operator == "delete"
|
if (parent instanceof AST_UnaryPrefix && parent.operator == "delete"
|
||||||
|| parent instanceof AST_Call && parent.expression === orig
|
|| parent.TYPE == "Call" && parent.expression === orig
|
||||||
&& (val instanceof AST_PropAccess || val instanceof AST_SymbolRef && val.name == "eval")) {
|
&& (val instanceof AST_PropAccess || val instanceof AST_SymbolRef && val.name == "eval")) {
|
||||||
return make_sequence(orig, [ make_node(AST_Number, orig, { value: 0 }), val ]);
|
return make_sequence(orig, [ make_node(AST_Number, orig, { value: 0 }), val ]);
|
||||||
}
|
}
|
||||||
@@ -4456,7 +4456,24 @@ merge(Compressor.prototype, {
|
|||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_Call, function(self, compressor){
|
AST_Call.DEFMETHOD("lift_sequences", function(compressor) {
|
||||||
|
if (!compressor.option("sequences")) return this;
|
||||||
|
var exp = this.expression;
|
||||||
|
if (!(exp instanceof AST_Sequence)) return this;
|
||||||
|
var tail = exp.tail_node();
|
||||||
|
if (tail instanceof AST_PropAccess && !(this instanceof AST_New)) return this;
|
||||||
|
var expressions = exp.expressions.slice(0, -1);
|
||||||
|
var node = this.clone();
|
||||||
|
node.expression = tail;
|
||||||
|
expressions.push(node);
|
||||||
|
return make_sequence(this, expressions).optimize(compressor);
|
||||||
|
});
|
||||||
|
|
||||||
|
OPT(AST_Call, function(self, compressor) {
|
||||||
|
var seq = self.lift_sequences(compressor);
|
||||||
|
if (seq !== self) {
|
||||||
|
return seq;
|
||||||
|
}
|
||||||
var exp = self.expression;
|
var exp = self.expression;
|
||||||
var fn = exp;
|
var fn = exp;
|
||||||
if (compressor.option("reduce_vars") && fn instanceof AST_SymbolRef) {
|
if (compressor.option("reduce_vars") && fn instanceof AST_SymbolRef) {
|
||||||
@@ -4964,7 +4981,11 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_New, function(self, compressor){
|
OPT(AST_New, function(self, compressor) {
|
||||||
|
var seq = self.lift_sequences(compressor);
|
||||||
|
if (seq !== self) {
|
||||||
|
return seq;
|
||||||
|
}
|
||||||
if (compressor.option("unsafe")) {
|
if (compressor.option("unsafe")) {
|
||||||
var exp = self.expression;
|
var exp = self.expression;
|
||||||
if (is_undeclared_ref(exp)) {
|
if (is_undeclared_ref(exp)) {
|
||||||
@@ -5020,14 +5041,12 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
AST_Unary.DEFMETHOD("lift_sequences", function(compressor){
|
AST_Unary.DEFMETHOD("lift_sequences", function(compressor){
|
||||||
if (compressor.option("sequences")) {
|
if (compressor.option("sequences") && this.expression instanceof AST_Sequence) {
|
||||||
if (this.expression instanceof AST_Sequence) {
|
var x = this.expression.expressions.slice();
|
||||||
var x = this.expression.expressions.slice();
|
var e = this.clone();
|
||||||
var e = this.clone();
|
e.expression = x.pop();
|
||||||
e.expression = x.pop();
|
x.push(e);
|
||||||
x.push(e);
|
return make_sequence(this, x).optimize(compressor);
|
||||||
return make_sequence(this, x).optimize(compressor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -876,3 +876,59 @@ forin: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
call: {
|
||||||
|
options = {
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function() {
|
||||||
|
return this;
|
||||||
|
}();
|
||||||
|
function b() {
|
||||||
|
console.log("foo");
|
||||||
|
}
|
||||||
|
b.c = function() {
|
||||||
|
console.log(this === b ? "bar" : "baz");
|
||||||
|
};
|
||||||
|
(a, b)();
|
||||||
|
(a, b.c)();
|
||||||
|
(a, function() {
|
||||||
|
console.log(this === a);
|
||||||
|
})();
|
||||||
|
new (a, b)();
|
||||||
|
new (a, b.c)();
|
||||||
|
new (a, function() {
|
||||||
|
console.log(this === a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function() {
|
||||||
|
return this;
|
||||||
|
}();
|
||||||
|
function b() {
|
||||||
|
console.log("foo");
|
||||||
|
}
|
||||||
|
b.c = function() {
|
||||||
|
console.log(this === b ? "bar" : "baz");
|
||||||
|
},
|
||||||
|
a, b(),
|
||||||
|
(a, b.c)(),
|
||||||
|
a, function() {
|
||||||
|
console.log(this === a);
|
||||||
|
}(),
|
||||||
|
a, new b(),
|
||||||
|
a, new b.c(),
|
||||||
|
a, new function() {
|
||||||
|
console.log(this === a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"baz",
|
||||||
|
"true",
|
||||||
|
"foo",
|
||||||
|
"baz",
|
||||||
|
"false",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user