enhance sequences (#3693)
This commit is contained in:
@@ -5400,25 +5400,32 @@ merge(Compressor.prototype, {
|
||||
return self.definitions.length ? self : make_node(AST_EmptyStatement, self);
|
||||
});
|
||||
|
||||
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 (needs_unbinding(compressor, tail) && !(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);
|
||||
});
|
||||
function lift_sequence_in_expression(node, compressor) {
|
||||
var exp = node.expression;
|
||||
if (!(exp instanceof AST_Sequence)) return node;
|
||||
var x = exp.expressions.slice();
|
||||
var e = node.clone();
|
||||
e.expression = x.pop();
|
||||
x.push(e);
|
||||
return make_sequence(node, x);
|
||||
}
|
||||
|
||||
OPT(AST_Call, function(self, compressor) {
|
||||
var seq = self.lift_sequences(compressor);
|
||||
if (seq !== self) {
|
||||
return seq;
|
||||
}
|
||||
var exp = self.expression;
|
||||
if (compressor.option("sequences")) {
|
||||
if (exp instanceof AST_PropAccess) {
|
||||
var seq = lift_sequence_in_expression(exp, compressor);
|
||||
if (seq !== exp) {
|
||||
var call = self.clone();
|
||||
call.expression = seq.expressions.pop();
|
||||
seq.expressions.push(call);
|
||||
return seq.optimize(compressor);
|
||||
}
|
||||
} else if (!needs_unbinding(compressor, exp.tail_node())) {
|
||||
var seq = lift_sequence_in_expression(self, compressor);
|
||||
if (seq !== self) return seq.optimize(compressor);
|
||||
}
|
||||
}
|
||||
var fn = exp;
|
||||
if (compressor.option("reduce_vars") && fn instanceof AST_SymbolRef) {
|
||||
fn = fn.fixed_value();
|
||||
@@ -5989,9 +5996,9 @@ merge(Compressor.prototype, {
|
||||
});
|
||||
|
||||
OPT(AST_New, function(self, compressor) {
|
||||
var seq = self.lift_sequences(compressor);
|
||||
if (seq !== self) {
|
||||
return seq;
|
||||
if (compressor.option("sequences")) {
|
||||
var seq = lift_sequence_in_expression(self, compressor);
|
||||
if (seq !== self) return seq.optimize(compressor);
|
||||
}
|
||||
if (compressor.option("unsafe")) {
|
||||
var exp = self.expression;
|
||||
@@ -6047,19 +6054,12 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
});
|
||||
|
||||
AST_Unary.DEFMETHOD("lift_sequences", function(compressor) {
|
||||
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;
|
||||
});
|
||||
|
||||
OPT(AST_UnaryPostfix, function(self, compressor) {
|
||||
return self.lift_sequences(compressor);
|
||||
if (compressor.option("sequences")) {
|
||||
var seq = lift_sequence_in_expression(self, compressor);
|
||||
if (seq !== self) return seq.optimize(compressor);
|
||||
}
|
||||
return self;
|
||||
});
|
||||
|
||||
OPT(AST_UnaryPrefix, function(self, compressor) {
|
||||
@@ -6076,9 +6076,9 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
return make_sequence(self, [ e, make_node(AST_True, self) ]).optimize(compressor);
|
||||
}
|
||||
var seq = self.lift_sequences(compressor);
|
||||
if (seq !== self) {
|
||||
return seq;
|
||||
if (compressor.option("sequences")) {
|
||||
var seq = lift_sequence_in_expression(self, compressor);
|
||||
if (seq !== self) return seq.optimize(compressor);
|
||||
}
|
||||
if (compressor.option("side_effects") && self.operator == "void") {
|
||||
e = e.drop_side_effect_free(compressor);
|
||||
@@ -6211,7 +6211,8 @@ merge(Compressor.prototype, {
|
||||
// result. hence, force switch.
|
||||
reverse();
|
||||
}
|
||||
self = self.lift_sequences(compressor);
|
||||
var seq = self.lift_sequences(compressor);
|
||||
if (seq !== self) return seq;
|
||||
if (compressor.option("assignments") && lazy_op[self.operator]) {
|
||||
var assign = self.right;
|
||||
// a || (a = x) => a = a || x
|
||||
@@ -7127,7 +7128,8 @@ merge(Compressor.prototype, {
|
||||
|| parent instanceof AST_UnaryPrefix);
|
||||
}
|
||||
}
|
||||
self = self.lift_sequences(compressor);
|
||||
var seq = self.lift_sequences(compressor);
|
||||
if (seq !== self) return seq;
|
||||
if (!compressor.option("assignments")) return self;
|
||||
if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary) {
|
||||
// x = expr1 OP expr2
|
||||
@@ -7486,6 +7488,10 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
|
||||
OPT(AST_Sub, function(self, compressor) {
|
||||
if (compressor.option("sequences") && compressor.parent().TYPE != "Call") {
|
||||
var seq = lift_sequence_in_expression(self, compressor);
|
||||
if (seq !== self) return seq.optimize(compressor);
|
||||
}
|
||||
var expr = self.expression;
|
||||
var prop = self.property;
|
||||
if (compressor.option("properties")) {
|
||||
@@ -7650,6 +7656,10 @@ merge(Compressor.prototype, {
|
||||
});
|
||||
|
||||
OPT(AST_Dot, function(self, compressor) {
|
||||
if (compressor.option("sequences") && compressor.parent().TYPE != "Call") {
|
||||
var seq = lift_sequence_in_expression(self, compressor);
|
||||
if (seq !== self) return seq.optimize(compressor);
|
||||
}
|
||||
if (self.property == "arguments" || self.property == "caller") {
|
||||
AST_Node.warn("Function.prototype.{prop} not supported [{file}:{line},{col}]", {
|
||||
prop: self.property,
|
||||
|
||||
@@ -2244,7 +2244,7 @@ issue_3076: {
|
||||
var c = "PASS";
|
||||
(function(b) {
|
||||
var n = 2;
|
||||
while (--b + (e = void 0, e && (c = "FAIL"), e = 5, 1).toString() && --n > 0);
|
||||
while (--b + (e = void 0, e && (c = "FAIL"), e = 5, 1..toString()) && --n > 0);
|
||||
var e;
|
||||
})(2),
|
||||
console.log(c);
|
||||
|
||||
@@ -910,15 +910,23 @@ call: {
|
||||
console.log(this === b ? "bar" : "baz");
|
||||
};
|
||||
(a, b)();
|
||||
(a, b).c();
|
||||
(a, b.c)();
|
||||
(a, b)["c"]();
|
||||
(a, b["c"])();
|
||||
(a, function() {
|
||||
console.log(this === a);
|
||||
})();
|
||||
new (a, b)();
|
||||
new (a, b).c();
|
||||
new (a, b.c)();
|
||||
new (a, b)["c"]();
|
||||
new (a, b["c"])();
|
||||
new (a, function() {
|
||||
console.log(this === a);
|
||||
})();
|
||||
console.log(typeof (a, b).c);
|
||||
console.log(typeof (a, b)["c"]);
|
||||
}
|
||||
expect: {
|
||||
var a = function() {
|
||||
@@ -931,23 +939,39 @@ call: {
|
||||
console.log(this === b ? "bar" : "baz");
|
||||
},
|
||||
b(),
|
||||
b.c(),
|
||||
(a, b.c)(),
|
||||
b["c"](),
|
||||
(a, b["c"])(),
|
||||
function() {
|
||||
console.log(this === a);
|
||||
}(),
|
||||
new b(),
|
||||
new b.c(),
|
||||
new b.c(),
|
||||
new b["c"](),
|
||||
new b["c"](),
|
||||
new function() {
|
||||
console.log(this === a);
|
||||
}();
|
||||
}(),
|
||||
console.log((a, typeof b.c)),
|
||||
console.log((a, typeof b["c"]));
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
"bar",
|
||||
"baz",
|
||||
"true",
|
||||
"foo",
|
||||
"baz",
|
||||
"baz",
|
||||
"baz",
|
||||
"baz",
|
||||
"false",
|
||||
"function",
|
||||
"function",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user