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). // 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;
}); });

View File

@@ -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",
]
}