aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-01-28 09:58:01 +0800
committerGitHub <noreply@github.com>2020-01-28 09:58:01 +0800
commita478f275e421ccbb428f38272e8e673f6684729c (patch)
tree5675ec1824024633fe933dc5c6d261d5d19ecc33
parente9e76dcf040d5076b6046d7273c3509df106fb84 (diff)
downloadtracifyjs-a478f275e421ccbb428f38272e8e673f6684729c.tar.gz
tracifyjs-a478f275e421ccbb428f38272e8e673f6684729c.zip
enhance `sequences` (#3693)
-rw-r--r--lib/compress.js82
-rw-r--r--test/compress/functions.js2
-rw-r--r--test/compress/sequences.js26
3 files changed, 72 insertions, 38 deletions
diff --git a/lib/compress.js b/lib/compress.js
index e14d9d06..2a338ba1 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -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,
diff --git a/test/compress/functions.js b/test/compress/functions.js
index c8bced52..ef51af72 100644
--- a/test/compress/functions.js
+++ b/test/compress/functions.js
@@ -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);
diff --git a/test/compress/sequences.js b/test/compress/sequences.js
index fbca559a..648f6491 100644
--- a/test/compress/sequences.js
+++ b/test/compress/sequences.js
@@ -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",
]
}