compress AST_Sequence within AST_Call (#3117)

This commit is contained in:
Alex Lam S.L
2018-05-03 19:14:56 +08:00
committed by GitHub
parent fc0f168a0c
commit d51a00a450
2 changed files with 86 additions and 11 deletions

View File

@@ -908,7 +908,7 @@ merge(Compressor.prototype, {
// the func (becomes lexical instead of global).
function maintain_this_binding(parent, orig, val) {
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")) {
return make_sequence(orig, [ make_node(AST_Number, orig, { value: 0 }), val ]);
}
@@ -4456,7 +4456,24 @@ merge(Compressor.prototype, {
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 fn = exp;
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")) {
var exp = self.expression;
if (is_undeclared_ref(exp)) {
@@ -5020,15 +5041,13 @@ merge(Compressor.prototype, {
});
AST_Unary.DEFMETHOD("lift_sequences", function(compressor){
if (compressor.option("sequences")) {
if (this.expression instanceof AST_Sequence) {
if (compressor.option("sequences") && this.expression instanceof AST_Sequence) {
var x = this.expression.expressions.slice();
var e = this.clone();
e.expression = x.pop();
x.push(e);
return make_sequence(this, x).optimize(compressor);
}
}
return this;
});

View File

@@ -876,3 +876,59 @@ forin: {
}
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",
]
}