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