Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9b811ce83 | ||
|
|
9ac3879b06 | ||
|
|
37d3e4feaa | ||
|
|
43ec350cd2 | ||
|
|
63b04a687a | ||
|
|
9efa02afb6 |
@@ -1828,6 +1828,28 @@ Compressor.prototype.compress = function(node) {
|
|||||||
return wrap ? make_sequence(orig, [ make_node(AST_Number, orig, { value: 0 }), val ]) : val;
|
return wrap ? make_sequence(orig, [ make_node(AST_Number, orig, { value: 0 }), val ]) : val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function merge_expression(base, target) {
|
||||||
|
var fixed_by_id = new Dictionary();
|
||||||
|
base.walk(new TreeWalker(function(node) {
|
||||||
|
if (!(node instanceof AST_SymbolRef)) return;
|
||||||
|
var def = node.definition();
|
||||||
|
var fixed = node.fixed;
|
||||||
|
if (!fixed || !fixed_by_id.has(def.id)) {
|
||||||
|
fixed_by_id.set(def.id, fixed);
|
||||||
|
} else if (fixed_by_id.get(def.id) !== fixed) {
|
||||||
|
fixed_by_id.set(def.id, false);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
if (fixed_by_id.size() > 0) target.walk(new TreeWalker(function(node) {
|
||||||
|
if (!(node instanceof AST_SymbolRef)) return;
|
||||||
|
var def = node.definition();
|
||||||
|
var fixed = node.fixed;
|
||||||
|
if (!fixed || !fixed_by_id.has(def.id)) return;
|
||||||
|
if (fixed_by_id.get(def.id) !== fixed) node.fixed = false;
|
||||||
|
}));
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
function merge_sequence(array, node) {
|
function merge_sequence(array, node) {
|
||||||
if (node instanceof AST_Sequence) {
|
if (node instanceof AST_Sequence) {
|
||||||
[].push.apply(array, node.expressions);
|
[].push.apply(array, node.expressions);
|
||||||
@@ -3813,25 +3835,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
case 2:
|
case 2:
|
||||||
value = value.tail_node();
|
value = value.tail_node();
|
||||||
}
|
}
|
||||||
var fixed_by_id = new Dictionary();
|
merge_expression(value, jump.value);
|
||||||
value.walk(new TreeWalker(function(node) {
|
|
||||||
if (!(node instanceof AST_SymbolRef)) return;
|
|
||||||
var def = node.definition();
|
|
||||||
if (def.scope.resolve() !== scope) return;
|
|
||||||
var fixed = node.fixed;
|
|
||||||
if (!fixed || !fixed_by_id.has(def.id)) {
|
|
||||||
fixed_by_id.set(def.id, fixed);
|
|
||||||
} else if (fixed_by_id.get(def.id) !== fixed) {
|
|
||||||
fixed_by_id.set(def.id, false);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
if (fixed_by_id.size() > 0) jump.value.walk(new TreeWalker(function(node) {
|
|
||||||
if (!(node instanceof AST_SymbolRef)) return;
|
|
||||||
var def = node.definition();
|
|
||||||
var fixed = node.fixed;
|
|
||||||
if (!fixed || !fixed_by_id.has(def.id)) return;
|
|
||||||
if (fixed_by_id.get(def.id) !== fixed) node.fixed = false;
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function next_index(i) {
|
function next_index(i) {
|
||||||
@@ -9718,15 +9722,16 @@ Compressor.prototype.compress = function(node) {
|
|||||||
if (stat.equals(alt_stat)) {
|
if (stat.equals(alt_stat)) {
|
||||||
body_stats.splice(body_index--, 1);
|
body_stats.splice(body_index--, 1);
|
||||||
alt_stats.splice(alt_index--, 1);
|
alt_stats.splice(alt_index--, 1);
|
||||||
stats.unshift(stat);
|
stats.unshift(merge_expression(stat, alt_stat));
|
||||||
} else {
|
} else {
|
||||||
if (!(stat instanceof AST_SimpleStatement)) break;
|
if (!(stat instanceof AST_SimpleStatement)) break;
|
||||||
if (!(alt_stat instanceof AST_SimpleStatement)) break;
|
if (!(alt_stat instanceof AST_SimpleStatement)) break;
|
||||||
var expr = stat.body.tail_node();
|
var expr1 = stat.body.tail_node();
|
||||||
if (!expr.equals(alt_stat.body.tail_node())) break;
|
var expr2 = alt_stat.body.tail_node();
|
||||||
|
if (!expr1.equals(expr2)) break;
|
||||||
body_index = pop_expr(body_stats, stat.body, body_index);
|
body_index = pop_expr(body_stats, stat.body, body_index);
|
||||||
alt_index = pop_expr(alt_stats, alt_stat.body, alt_index);
|
alt_index = pop_expr(alt_stats, alt_stat.body, alt_index);
|
||||||
stats.unshift(make_node(AST_SimpleStatement, expr, { body: expr }));
|
stats.unshift(make_node(AST_SimpleStatement, expr1, { body: merge_expression(expr1, expr2) }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stats.length > 0) {
|
if (stats.length > 0) {
|
||||||
@@ -11590,22 +11595,33 @@ Compressor.prototype.compress = function(node) {
|
|||||||
if (seq !== self) return seq.optimize(compressor);
|
if (seq !== self) return seq.optimize(compressor);
|
||||||
}
|
}
|
||||||
if (compressor.option("assignments") && lazy_op[self.operator]) {
|
if (compressor.option("assignments") && lazy_op[self.operator]) {
|
||||||
var assign = self.right;
|
var right = self.right;
|
||||||
// a || (a = x) ---> a = a || x
|
// a || (a = x) ---> a = a || x
|
||||||
// a && (a = x) ---> a = a && x
|
// a && (a = x) ---> a = a && x
|
||||||
if (self.left instanceof AST_SymbolRef
|
if (self.left instanceof AST_SymbolRef
|
||||||
&& assign instanceof AST_Assign
|
&& right instanceof AST_Assign
|
||||||
&& assign.operator == "="
|
&& right.operator == "="
|
||||||
&& self.left.equals(assign.left)) {
|
&& self.left.equals(right.left)) {
|
||||||
return make_node(AST_Assign, self, {
|
var left = right.left.clone();
|
||||||
|
var assign = make_node(AST_Assign, self, {
|
||||||
operator: "=",
|
operator: "=",
|
||||||
left: assign.left,
|
left: left,
|
||||||
right: make_node(AST_Binary, self, {
|
right: make_node(AST_Binary, self, {
|
||||||
operator: self.operator,
|
operator: self.operator,
|
||||||
left: self.left,
|
left: self.left,
|
||||||
right: assign.right,
|
right: right.right,
|
||||||
}),
|
}),
|
||||||
}).optimize(compressor);
|
});
|
||||||
|
if (left.fixed) {
|
||||||
|
left.fixed = function() {
|
||||||
|
return assign.right;
|
||||||
|
};
|
||||||
|
left.fixed.assigns = [ assign ];
|
||||||
|
}
|
||||||
|
var def = left.definition();
|
||||||
|
def.references.push(left);
|
||||||
|
def.replaced++;
|
||||||
|
return assign.optimize(compressor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compressor.option("comparisons")) switch (self.operator) {
|
if (compressor.option("comparisons")) switch (self.operator) {
|
||||||
@@ -12922,7 +12938,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
right: fuse(consequent, seq_tail, "condition"),
|
right: fuse(consequent, seq_tail, "condition"),
|
||||||
}),
|
}),
|
||||||
consequent: seq_tail.consequent,
|
consequent: seq_tail.consequent,
|
||||||
alternative: alternative,
|
alternative: merge_expression(seq_tail.alternative, alternative),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// x ? (y ? a : b) : a ---> !x || y ? a : b
|
// x ? (y ? a : b) : a ---> !x || y ? a : b
|
||||||
@@ -12934,7 +12950,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
operator: "||",
|
operator: "||",
|
||||||
right: fuse(consequent, seq_tail, "condition"),
|
right: fuse(consequent, seq_tail, "condition"),
|
||||||
}),
|
}),
|
||||||
consequent: alternative,
|
consequent: merge_expression(seq_tail.consequent, alternative),
|
||||||
alternative: seq_tail.alternative,
|
alternative: seq_tail.alternative,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -12947,7 +12963,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
operator: "||",
|
operator: "||",
|
||||||
right: fuse(alternative, alt_tail, "condition"),
|
right: fuse(alternative, alt_tail, "condition"),
|
||||||
}),
|
}),
|
||||||
consequent: consequent,
|
consequent: merge_expression(consequent, alt_tail.consequent),
|
||||||
alternative: alt_tail.alternative,
|
alternative: alt_tail.alternative,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -12961,7 +12977,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
right: fuse(alternative, alt_tail, "condition"),
|
right: fuse(alternative, alt_tail, "condition"),
|
||||||
}),
|
}),
|
||||||
consequent: alt_tail.consequent,
|
consequent: alt_tail.consequent,
|
||||||
alternative: consequent,
|
alternative: merge_expression(consequent, alt_tail.alternative),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// x ? y && a : a ---> (!x || y) && a
|
// x ? y && a : a ---> (!x || y) && a
|
||||||
@@ -12975,7 +12991,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
left: negated,
|
left: negated,
|
||||||
right: fuse(consequent, seq_tail, "left"),
|
right: fuse(consequent, seq_tail, "left"),
|
||||||
}),
|
}),
|
||||||
right: alternative,
|
right: merge_expression(seq_tail.right, alternative),
|
||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
}
|
}
|
||||||
// x ? y || a : a ---> x && y || a
|
// x ? y || a : a ---> x && y || a
|
||||||
@@ -12989,7 +13005,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
left: condition,
|
left: condition,
|
||||||
right: fuse(consequent, seq_tail, "left"),
|
right: fuse(consequent, seq_tail, "left"),
|
||||||
}),
|
}),
|
||||||
right: alternative,
|
right: merge_expression(seq_tail.right, alternative),
|
||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
}
|
}
|
||||||
// x ? a : y && a ---> (x || y) && a
|
// x ? a : y && a ---> (x || y) && a
|
||||||
@@ -13003,7 +13019,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
left: condition,
|
left: condition,
|
||||||
right: fuse(alternative, alt_tail, "left"),
|
right: fuse(alternative, alt_tail, "left"),
|
||||||
}),
|
}),
|
||||||
right: consequent,
|
right: merge_expression(consequent, alt_tail.right),
|
||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
}
|
}
|
||||||
// x ? a : y || a ---> !x && y || a
|
// x ? a : y || a ---> !x && y || a
|
||||||
@@ -13017,7 +13033,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
left: negated,
|
left: negated,
|
||||||
right: fuse(alternative, alt_tail, "left"),
|
right: fuse(alternative, alt_tail, "left"),
|
||||||
}),
|
}),
|
||||||
right: consequent,
|
right: merge_expression(consequent, alt_tail.right),
|
||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
}
|
}
|
||||||
var in_bool = compressor.option("booleans") && compressor.in_boolean_context();
|
var in_bool = compressor.option("booleans") && compressor.in_boolean_context();
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "3.17.1",
|
"version": "3.17.2",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -803,3 +803,23 @@ issue_4924_2: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=15"
|
node_version: ">=15"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5670: {
|
||||||
|
options = {
|
||||||
|
assignments: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b) {
|
||||||
|
a && a && (a = b += "") || console.log("PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a, b) {
|
||||||
|
a = a,
|
||||||
|
console.log("PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -278,6 +278,36 @@ merge_tail_2: {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
merge_tail_3: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b) {
|
||||||
|
if (b = a.shift())
|
||||||
|
console.log(b);
|
||||||
|
else {
|
||||||
|
if (b = a.shift())
|
||||||
|
while (console.log("foo"));
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
})([ false, "bar" ]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a, b) {
|
||||||
|
if (!(b = a.shift()) && (b = a.shift()))
|
||||||
|
while (console.log("foo"));
|
||||||
|
console.log(b);
|
||||||
|
})([ false, "bar" ]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
merge_tail_sequence_1: {
|
merge_tail_sequence_1: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
@@ -368,6 +398,39 @@ merge_tail_sequence_2: {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
merge_tail_sequence_3: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b) {
|
||||||
|
if (b = a.shift())
|
||||||
|
console.log("foo"),
|
||||||
|
console.log(b);
|
||||||
|
else {
|
||||||
|
if (b = a.shift())
|
||||||
|
while (console.log("bar"));
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
})([ false, "baz" ]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a, b) {
|
||||||
|
if (b = a.shift())
|
||||||
|
console.log("foo");
|
||||||
|
else if (b = a.shift())
|
||||||
|
while (console.log("bar"));
|
||||||
|
console.log(b);
|
||||||
|
})([ false, "baz" ]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"bar",
|
||||||
|
"baz",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
cond_1: {
|
cond_1: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
@@ -2928,3 +2991,45 @@ issue_5666_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "NaN"
|
expect_stdout: "NaN"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_5673_1: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS", b = null;
|
||||||
|
console.log(function(c) {
|
||||||
|
return c || (b ? c : (c = a) && c);
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS", b = null;
|
||||||
|
console.log(function(c) {
|
||||||
|
return c || (b || (c = a)) && c;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_5673_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
console.log(function(b) {
|
||||||
|
return (b = a) ? b : (b = a) && b;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
console.log(function(b) {
|
||||||
|
return ((b = a) || (b = a)) && b;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1834,7 +1834,7 @@ switch_return_5: {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
merged_references: {
|
merged_references_1: {
|
||||||
options = {
|
options = {
|
||||||
if_return: true,
|
if_return: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -1861,6 +1861,36 @@ merged_references: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
merged_references_2: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "PASS";
|
||||||
|
var a;
|
||||||
|
console.log(function(b) {
|
||||||
|
if (a = b)
|
||||||
|
return console && a;
|
||||||
|
a = FAIL;
|
||||||
|
return console && a;
|
||||||
|
}(A));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "PASS";
|
||||||
|
var a;
|
||||||
|
console.log(function(b) {
|
||||||
|
if (a = b);
|
||||||
|
else
|
||||||
|
a = FAIL;
|
||||||
|
return console && a;
|
||||||
|
}(A));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
issue_5583: {
|
issue_5583: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user