fix corner cases in switch and undefined (#1762)
- fix side effects in switch condition for singular blocks - fix `undefined` confusion with local variable - gate `OPT(AST_Switch)` with `switches` fixes #1758 fixes #1759
This commit is contained in:
@@ -77,6 +77,7 @@ function Compressor(options, false_by_default) {
|
|||||||
screw_ie8 : true,
|
screw_ie8 : true,
|
||||||
sequences : !false_by_default,
|
sequences : !false_by_default,
|
||||||
side_effects : !false_by_default,
|
side_effects : !false_by_default,
|
||||||
|
switches : !false_by_default,
|
||||||
top_retain : null,
|
top_retain : null,
|
||||||
toplevel : !!(options && options["top_retain"]),
|
toplevel : !!(options && options["top_retain"]),
|
||||||
unsafe : false,
|
unsafe : false,
|
||||||
@@ -1054,7 +1055,7 @@ merge(Compressor.prototype, {
|
|||||||
stat.value = cons_seq(stat.value);
|
stat.value = cons_seq(stat.value);
|
||||||
}
|
}
|
||||||
else if (stat instanceof AST_Exit) {
|
else if (stat instanceof AST_Exit) {
|
||||||
stat.value = cons_seq(make_node(AST_Undefined, stat));
|
stat.value = cons_seq(make_node(AST_Undefined, stat).transform(compressor));
|
||||||
}
|
}
|
||||||
else if (stat instanceof AST_Switch) {
|
else if (stat instanceof AST_Switch) {
|
||||||
stat.expression = cons_seq(stat.expression);
|
stat.expression = cons_seq(stat.expression);
|
||||||
@@ -2526,6 +2527,7 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_Switch, function(self, compressor){
|
OPT(AST_Switch, function(self, compressor){
|
||||||
|
if (!compressor.option("switches")) return self;
|
||||||
var branch;
|
var branch;
|
||||||
var value = self.expression.evaluate(compressor);
|
var value = self.expression.evaluate(compressor);
|
||||||
if (value !== self.expression) {
|
if (value !== self.expression) {
|
||||||
@@ -2599,7 +2601,15 @@ merge(Compressor.prototype, {
|
|||||||
has_break = true;
|
has_break = true;
|
||||||
});
|
});
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
if (!has_break) return make_node(AST_BlockStatement, self, body[0]).optimize(compressor);
|
if (!has_break) {
|
||||||
|
body = body[0].body.slice();
|
||||||
|
body.unshift(make_node(AST_SimpleStatement, self.expression, {
|
||||||
|
body: self.expression
|
||||||
|
}));
|
||||||
|
return make_node(AST_BlockStatement, self, {
|
||||||
|
body: body
|
||||||
|
}).optimize(compressor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
|
||||||
@@ -2904,7 +2914,7 @@ merge(Compressor.prototype, {
|
|||||||
if (name instanceof AST_SymbolRef
|
if (name instanceof AST_SymbolRef
|
||||||
&& name.name == "console"
|
&& name.name == "console"
|
||||||
&& name.undeclared()) {
|
&& name.undeclared()) {
|
||||||
return make_node(AST_Undefined, self).transform(compressor);
|
return make_node(AST_Undefined, self).optimize(compressor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ case_1: {
|
|||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 0, b = 1;
|
var a = 0, b = 1;
|
||||||
|
|||||||
@@ -1399,6 +1399,8 @@ issue_1670_1: {
|
|||||||
evaluate: true,
|
evaluate: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1429,6 +1431,8 @@ issue_1670_2: {
|
|||||||
dead_code: true,
|
dead_code: true,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1458,6 +1462,8 @@ issue_1670_3: {
|
|||||||
evaluate: true,
|
evaluate: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1488,6 +1494,8 @@ issue_1670_4: {
|
|||||||
dead_code: true,
|
dead_code: true,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1516,6 +1524,8 @@ issue_1670_5: {
|
|||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -1544,6 +1554,8 @@ issue_1670_6: {
|
|||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
@@ -440,3 +440,29 @@ func_def_5: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "true"
|
expect_stdout: "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_1758: {
|
||||||
|
options = {
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(c) {
|
||||||
|
var undefined = 42;
|
||||||
|
return function() {
|
||||||
|
c--;
|
||||||
|
c--, c.toString();
|
||||||
|
return;
|
||||||
|
}();
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(c) {
|
||||||
|
var undefined = 42;
|
||||||
|
return function() {
|
||||||
|
return c--, c--, c.toString(), void 0;
|
||||||
|
}();
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
constant_switch_1: {
|
constant_switch_1: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (1+1) {
|
switch (1+1) {
|
||||||
case 1: foo(); break;
|
case 1: foo(); break;
|
||||||
@@ -13,7 +18,12 @@ constant_switch_1: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_2: {
|
constant_switch_2: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (1) {
|
switch (1) {
|
||||||
case 1: foo();
|
case 1: foo();
|
||||||
@@ -28,7 +38,12 @@ constant_switch_2: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_3: {
|
constant_switch_3: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (10) {
|
switch (10) {
|
||||||
case 1: foo();
|
case 1: foo();
|
||||||
@@ -44,7 +59,12 @@ constant_switch_3: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_4: {
|
constant_switch_4: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (2) {
|
switch (2) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -65,7 +85,12 @@ constant_switch_4: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_5: {
|
constant_switch_5: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (1) {
|
switch (1) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -94,7 +119,12 @@ constant_switch_5: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_6: {
|
constant_switch_6: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
OUT: {
|
OUT: {
|
||||||
foo();
|
foo();
|
||||||
@@ -123,7 +153,12 @@ constant_switch_6: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_7: {
|
constant_switch_7: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
OUT: {
|
OUT: {
|
||||||
foo();
|
foo();
|
||||||
@@ -161,7 +196,12 @@ constant_switch_7: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_8: {
|
constant_switch_8: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
OUT: switch (1) {
|
OUT: switch (1) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -185,7 +225,12 @@ constant_switch_8: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constant_switch_9: {
|
constant_switch_9: {
|
||||||
options = { dead_code: true, evaluate: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
OUT: switch (1) {
|
OUT: switch (1) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -210,7 +255,10 @@ constant_switch_9: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
drop_default_1: {
|
drop_default_1: {
|
||||||
options = { dead_code: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (foo) {
|
switch (foo) {
|
||||||
case 'bar': baz();
|
case 'bar': baz();
|
||||||
@@ -225,7 +273,10 @@ drop_default_1: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
drop_default_2: {
|
drop_default_2: {
|
||||||
options = { dead_code: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (foo) {
|
switch (foo) {
|
||||||
case 'bar': baz(); break;
|
case 'bar': baz(); break;
|
||||||
@@ -241,7 +292,10 @@ drop_default_2: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
keep_default: {
|
keep_default: {
|
||||||
options = { dead_code: true };
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (foo) {
|
switch (foo) {
|
||||||
case 'bar': baz();
|
case 'bar': baz();
|
||||||
@@ -263,6 +317,8 @@ issue_1663: {
|
|||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 100, b = 10;
|
var a = 100, b = 10;
|
||||||
@@ -294,6 +350,7 @@ issue_1663: {
|
|||||||
drop_case: {
|
drop_case: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (foo) {
|
switch (foo) {
|
||||||
@@ -312,6 +369,7 @@ drop_case: {
|
|||||||
keep_case: {
|
keep_case: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (foo) {
|
switch (foo) {
|
||||||
@@ -332,6 +390,7 @@ issue_376: {
|
|||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (true) {
|
switch (true) {
|
||||||
@@ -354,6 +413,7 @@ issue_376: {
|
|||||||
issue_441_1: {
|
issue_441_1: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (foo) {
|
switch (foo) {
|
||||||
@@ -381,6 +441,7 @@ issue_441_1: {
|
|||||||
issue_441_2: {
|
issue_441_2: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (foo) {
|
switch (foo) {
|
||||||
@@ -414,6 +475,8 @@ issue_1674: {
|
|||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (0) {
|
switch (0) {
|
||||||
@@ -435,6 +498,7 @@ issue_1679: {
|
|||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 100, b = 10;
|
var a = 100, b = 10;
|
||||||
@@ -482,6 +546,7 @@ issue_1680_1: {
|
|||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(x) {
|
function f(x) {
|
||||||
@@ -522,6 +587,7 @@ issue_1680_1: {
|
|||||||
issue_1680_2: {
|
issue_1680_2: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 100, b = 10;
|
var a = 100, b = 10;
|
||||||
@@ -557,6 +623,7 @@ issue_1680_2: {
|
|||||||
issue_1690_1: {
|
issue_1690_1: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (console.log("PASS")) {}
|
switch (console.log("PASS")) {}
|
||||||
@@ -570,6 +637,7 @@ issue_1690_1: {
|
|||||||
issue_1690_2: {
|
issue_1690_2: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: false,
|
dead_code: false,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (console.log("PASS")) {}
|
switch (console.log("PASS")) {}
|
||||||
@@ -585,6 +653,7 @@ if_switch_typeof: {
|
|||||||
conditionals: true,
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
if (a) switch(typeof b) {}
|
if (a) switch(typeof b) {}
|
||||||
@@ -597,6 +666,7 @@ if_switch_typeof: {
|
|||||||
issue_1698: {
|
issue_1698: {
|
||||||
options = {
|
options = {
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 1;
|
var a = 1;
|
||||||
@@ -618,6 +688,7 @@ issue_1698: {
|
|||||||
issue_1705_1: {
|
issue_1705_1: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 0;
|
var a = 0;
|
||||||
@@ -646,6 +717,7 @@ issue_1705_2: {
|
|||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
|
switches: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -666,6 +738,7 @@ issue_1705_2: {
|
|||||||
issue_1705_3: {
|
issue_1705_3: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
switch (a) {
|
switch (a) {
|
||||||
@@ -721,3 +794,25 @@ beautify: {
|
|||||||
"}",
|
"}",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_1758: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1, b = 2;
|
||||||
|
switch (a--) {
|
||||||
|
default:
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1, b = 2;
|
||||||
|
a--;
|
||||||
|
b++;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "0 3"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user