Skip to content

Commit 3e2c51a

Browse files
authored
enhance collapse_vars (#3572)
1 parent 0e29ad5 commit 3e2c51a

File tree

2 files changed

+79
-5
lines changed

2 files changed

+79
-5
lines changed

lib/compress.js

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,7 +1235,7 @@ merge(Compressor.prototype, {
12351235
var lvalues = get_lvalues(candidate);
12361236
var lhs_local = is_lhs_local(lhs);
12371237
if (!side_effects) side_effects = value_has_side_effects(candidate);
1238-
var replace_all = replace_all_symbols();
1238+
var replace_all = replace_all_symbols(candidate);
12391239
var may_throw = candidate.may_throw(compressor) ? in_try ? function(node) {
12401240
return node.has_side_effects(compressor);
12411241
} : side_effects_external : return_false;
@@ -1312,6 +1312,7 @@ merge(Compressor.prototype, {
13121312

13131313
function in_conditional(node, parent) {
13141314
if (parent instanceof AST_Binary) return lazy_op[parent.operator] && parent.left !== node;
1315+
if (parent instanceof AST_Case) return parent.expression !== node;
13151316
if (parent instanceof AST_Conditional) return parent.condition !== node;
13161317
return parent instanceof AST_If && parent.condition !== node;
13171318
}
@@ -1477,19 +1478,43 @@ merge(Compressor.prototype, {
14771478
if (parent instanceof AST_Call) return node;
14781479
if (parent instanceof AST_Case) return node;
14791480
if (parent instanceof AST_Conditional) return node;
1480-
if (parent instanceof AST_Definitions) return find_stop(parent, level + 1);
1481+
if (parent instanceof AST_Definitions) return find_stop_unused(parent, level + 1);
14811482
if (parent instanceof AST_Exit) return node;
14821483
if (parent instanceof AST_If) return node;
14831484
if (parent instanceof AST_IterationStatement) return node;
14841485
if (parent instanceof AST_PropAccess) return node;
1485-
if (parent instanceof AST_Sequence) return find_stop(parent, level + 1);
1486-
if (parent instanceof AST_SimpleStatement) return find_stop(parent, level + 1);
1486+
if (parent instanceof AST_Sequence) {
1487+
return (parent.tail_node() === node ? find_stop : find_stop_unused)(parent, level + 1);
1488+
}
1489+
if (parent instanceof AST_SimpleStatement) return find_stop_unused(parent, level + 1);
14871490
if (parent instanceof AST_Switch) return node;
14881491
if (parent instanceof AST_Unary) return node;
14891492
if (parent instanceof AST_VarDef) return node;
14901493
return null;
14911494
}
14921495

1496+
function find_stop_unused(node, level) {
1497+
var parent = scanner.parent(level);
1498+
if (is_last_node(node, parent)) return node;
1499+
if (in_conditional(node, parent)) return node;
1500+
if (parent instanceof AST_Assign) return find_stop_unused(parent, level + 1);
1501+
if (parent instanceof AST_Binary) return find_stop_unused(parent, level + 1);
1502+
if (parent instanceof AST_Call) return find_stop_unused(parent, level + 1);
1503+
if (parent instanceof AST_Case) return find_stop_unused(parent, level + 1);
1504+
if (parent instanceof AST_Conditional) return find_stop_unused(parent, level + 1);
1505+
if (parent instanceof AST_Definitions) return find_stop_unused(parent, level + 1);
1506+
if (parent instanceof AST_Exit) return find_stop_unused(parent, level + 1);
1507+
if (parent instanceof AST_If) return find_stop_unused(parent, level + 1);
1508+
if (parent instanceof AST_IterationStatement) return node;
1509+
if (parent instanceof AST_PropAccess) return find_stop_unused(parent, level + 1);
1510+
if (parent instanceof AST_Sequence) return find_stop_unused(parent, level + 1);
1511+
if (parent instanceof AST_SimpleStatement) return find_stop_unused(parent, level + 1);
1512+
if (parent instanceof AST_Switch) return find_stop_unused(parent, level + 1);
1513+
if (parent instanceof AST_Unary) return find_stop_unused(parent, level + 1);
1514+
if (parent instanceof AST_VarDef) return find_stop_unused(parent, level + 1);
1515+
return null;
1516+
}
1517+
14931518
function mangleable_var(var_def) {
14941519
var value = var_def.value;
14951520
if (!(value instanceof AST_SymbolRef)) return;
@@ -1656,7 +1681,8 @@ merge(Compressor.prototype, {
16561681
return get_rvalue(expr).has_side_effects(compressor);
16571682
}
16581683

1659-
function replace_all_symbols() {
1684+
function replace_all_symbols(expr) {
1685+
if (expr instanceof AST_Unary) return false;
16601686
if (side_effects) return false;
16611687
if (value_def) return true;
16621688
if (lhs instanceof AST_SymbolRef) {

test/compress/collapse_vars.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6387,3 +6387,51 @@ issue_3562: {
63876387
}
63886388
expect_stdout: "PASS PASS"
63896389
}
6390+
6391+
dot_throw_assign_sequence: {
6392+
options = {
6393+
collapse_vars: true,
6394+
}
6395+
input: {
6396+
var a = "FAIL";
6397+
try {
6398+
var b;
6399+
b[0] = (a = "PASS", 0);
6400+
a = 1 + a;
6401+
} catch (c) {
6402+
}
6403+
console.log(a);
6404+
}
6405+
expect: {
6406+
var a = "FAIL";
6407+
try {
6408+
var b;
6409+
b[0] = (a = "PASS", 0);
6410+
a = 1 + a;
6411+
} catch (c) {
6412+
}
6413+
console.log(a);
6414+
}
6415+
expect_stdout: "PASS"
6416+
}
6417+
6418+
call_assign_order: {
6419+
options = {
6420+
collapse_vars: true,
6421+
}
6422+
input: {
6423+
var a, b = 1, c = 0, log = console.log;
6424+
(function() {
6425+
a = b = "PASS";
6426+
})((b = "FAIL", c++));
6427+
log(a, b);
6428+
}
6429+
expect: {
6430+
var a, b = 1, c = 0, log = console.log;
6431+
(function() {
6432+
a = b = "PASS";
6433+
})((b = "FAIL", c++));
6434+
log(a, b);
6435+
}
6436+
expect_stdout: "PASS PASS"
6437+
}

0 commit comments

Comments
 (0)