aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2021-03-03 10:47:17 +0000
committerGitHub <noreply@github.com>2021-03-03 18:47:17 +0800
commit2a49760032dea89032d6bc82dabab5e9e53bb310 (patch)
tree62c3b4078e1eee347029776944500ebd3ec6dbaa
parent04ed818f0a53b4ec21887f7d2e44c78a99fd1fa3 (diff)
downloadtracifyjs-2a49760032dea89032d6bc82dabab5e9e53bb310.tar.gz
tracifyjs-2a49760032dea89032d6bc82dabab5e9e53bb310.zip
enhance `side_effects` (#4727)
-rw-r--r--lib/compress.js61
-rw-r--r--test/compress/collapse_vars.js10
-rw-r--r--test/compress/issue-281.js20
-rw-r--r--test/compress/merge_vars.js4
-rw-r--r--test/compress/reduce_vars.js6
-rw-r--r--test/compress/sequences.js8
6 files changed, 65 insertions, 44 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 1b22d861..99e67b91 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -4797,9 +4797,15 @@ merge(Compressor.prototype, {
|| this.right.has_side_effects(compressor);
});
def(AST_Binary, function(compressor) {
- return this.left.has_side_effects(compressor)
- || this.right.has_side_effects(compressor)
- || this.operator == "in" && !is_object(this.right);
+ var lhs = this.left;
+ if (lhs.has_side_effects(compressor)) return true;
+ var rhs = this.right;
+ var op = this.operator;
+ if (!rhs.has_side_effects(compressor)) return op == "in" && !is_object(rhs);
+ if (op == "&&" && rhs instanceof AST_PropAccess && lhs.equivalent_to(rhs.expression)) {
+ return rhs instanceof AST_Sub && rhs.property.has_side_effects(compressor);
+ }
+ return true;
});
def(AST_Block, function(compressor) {
return any(this.body, compressor);
@@ -7208,33 +7214,42 @@ merge(Compressor.prototype, {
return node;
});
def(AST_Binary, function(compressor, first_in_statement) {
- if (this.operator == "in" && !is_object(this.right)) {
- var left = this.left.drop_side_effect_free(compressor, first_in_statement);
- if (left === this.left) return this;
+ var left = this.left;
+ var right = this.right;
+ var op = this.operator;
+ if (op == "in" && !is_object(right)) {
+ var lhs = left.drop_side_effect_free(compressor, first_in_statement);
+ if (lhs === left) return this;
var node = this.clone();
- node.left = left || make_node(AST_Number, this.left, {
- value: 0
- });
+ node.left = lhs || make_node(AST_Number, left, { value: 0 });
return node;
}
- var right = this.right.drop_side_effect_free(compressor, first_in_statement);
- if (!right) return this.left.drop_side_effect_free(compressor, first_in_statement);
- if (lazy_op[this.operator] && !(right instanceof AST_Function)) {
+ var rhs = right.drop_side_effect_free(compressor, first_in_statement);
+ if (!rhs) return left.drop_side_effect_free(compressor, first_in_statement);
+ if (lazy_op[op] && !(rhs instanceof AST_Function)) {
var node = this;
- if (right !== node.right) {
- node = this.clone();
- node.right = right.drop_side_effect_free(compressor);
- }
- if (this.operator == "??") return node;
+ if (op == "&&"
+ && rhs instanceof AST_PropAccess
+ && left.equivalent_to(rhs.expression)
+ && !left.has_side_effects(compressor)) {
+ var prop = rhs instanceof AST_Sub && rhs.property.drop_side_effect_free(compressor);
+ if (!prop) return left.drop_side_effect_free(compressor, first_in_statement);
+ node = node.clone();
+ node.right = prop;
+ } else if (rhs !== right) {
+ node = node.clone();
+ node.right = rhs.drop_side_effect_free(compressor);
+ }
+ if (op == "??") return node;
return (first_in_statement ? best_of_statement : best_of_expression)(node, make_node(AST_Binary, this, {
- operator: node.operator == "&&" ? "||" : "&&",
- left: node.left.negate(compressor, first_in_statement),
- right: node.right
+ operator: op == "&&" ? "||" : "&&",
+ left: left.negate(compressor, first_in_statement),
+ right: node.right,
}));
} else {
- var left = this.left.drop_side_effect_free(compressor, first_in_statement);
- if (!left) return right;
- return make_sequence(this, [ left, right.drop_side_effect_free(compressor) ]);
+ var lhs = left.drop_side_effect_free(compressor, first_in_statement);
+ if (!lhs) return rhs;
+ return make_sequence(this, [ lhs, rhs.drop_side_effect_free(compressor) ]);
}
});
def(AST_Call, function(compressor, first_in_statement) {
diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js
index fe963b4a..c0a545c5 100644
--- a/test/compress/collapse_vars.js
+++ b/test/compress/collapse_vars.js
@@ -2863,7 +2863,7 @@ lvalues_def: {
expect: {
var a = 0, b = 1;
a = b++, b = +void 0;
- a && a[a++];
+ a && a++;
console.log(a, b);
}
expect_stdout: true
@@ -5098,7 +5098,7 @@ issue_2878: {
}
b = f2();
a = 1;
- b && b.b;
+ b && b[console];
f2();
})();
console.log(c);
@@ -5111,7 +5111,7 @@ issue_2878: {
}
b = f2(),
a = 1,
- b && b.b,
+ b && console,
f2();
})(),
console.log(c);
@@ -6546,7 +6546,7 @@ issue_3520: {
(function f() {
c = 0;
var i = void 0;
- var f = f && f[i];
+ var f = f && f[console && i];
})();
a += b;
c && b++;
@@ -6560,7 +6560,7 @@ issue_3520: {
for (var i = 2; --i >= 0;) {
(function() {
c = 0;
- var f = f && f[void 0];
+ var f = f && f[console && void 0];
})();
a += b;
c && b++;
diff --git a/test/compress/issue-281.js b/test/compress/issue-281.js
index 1c339bcd..797f7d9b 100644
--- a/test/compress/issue-281.js
+++ b/test/compress/issue-281.js
@@ -463,15 +463,19 @@ drop_fargs: {
var a = 1;
!function(a_1) {
a++;
- }(a++ + (a && a.var));
+ }(a++ + (a && console.log(a)));
console.log(a);
}
expect: {
var a = 1;
- ++a && a.var, a++;
+ ++a && console.log(a),
+ a++;
console.log(a);
}
- expect_stdout: "3"
+ expect_stdout: [
+ "2",
+ "3",
+ ]
}
keep_fargs: {
@@ -486,13 +490,17 @@ keep_fargs: {
var a = 1;
!function(a_1) {
a++;
- }(a++ + (a && a.var));
+ }(a++ + (a && console.log(a)));
console.log(a);
}
expect: {
var a = 1;
- ++a && a.var, a++;
+ ++a && console.log(a),
+ a++;
console.log(a);
}
- expect_stdout: "3"
+ expect_stdout: [
+ "2",
+ "3",
+ ]
}
diff --git a/test/compress/merge_vars.js b/test/compress/merge_vars.js
index c45f8353..667cacf8 100644
--- a/test/compress/merge_vars.js
+++ b/test/compress/merge_vars.js
@@ -2723,7 +2723,7 @@ issue_4135: {
var c = function() {
var d = 0;
function f() {
- d && d.p;
+ d && d[console];
}
f();
this;
@@ -2735,7 +2735,7 @@ issue_4135: {
0;
a++;
if (!a)
- c = (a++, c = 0, void (c && c.p));
+ c = (a++, c = 0, void (c && console));
var c;
console.log(a, -1, c);
}
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index 5ae0884b..110f046a 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -2554,7 +2554,7 @@ side_effects_assign: {
console.log(a);
}
expect: {
- var a = typeof void (a && a.in);
+ var a = "undefined";
console.log(a);
}
expect_stdout: "undefined"
@@ -2595,9 +2595,7 @@ pure_getters_2: {
var a;
var a = a && a.b;
}
- expect: {
- var a = a && a.b;
- }
+ expect: {}
}
pure_getters_3: {
diff --git a/test/compress/sequences.js b/test/compress/sequences.js
index b8190366..a9dbc707 100644
--- a/test/compress/sequences.js
+++ b/test/compress/sequences.js
@@ -745,12 +745,12 @@ issue_2062: {
}
input: {
var a = 1;
- if ([ a || a++ + a--, a++ + a--, a && a.var ]);
+ if ([ a || a++ + a--, a++ + a--, a && a[console] ]);
console.log(a);
}
expect: {
var a = 1;
- a || (a++, a--), a++, --a && a.var;
+ a || (a++, a--), a++, --a && console;
console.log(a);
}
expect_stdout: "1"
@@ -1088,7 +1088,7 @@ issue_3490_1: {
if ({
3: function() {
var a;
- return (a && a.p) < this;
+ return (a && a[console]) < this;
}(),
}) c = "PASS";
if (b) while ("" == typeof d);
@@ -1098,7 +1098,7 @@ issue_3490_1: {
var b = 42, c = "FAIL";
if (function() {
var a;
- a && a.p;
+ a && console;
}(), c = "PASS", b) while ("" == typeof d);
console.log(c, b);
}