fix has_side_effects() (#1675)

`AST_Try` is an `AST_Block`, so besides try block we also need to inspect catch and finally blocks for possible side effects.

Also extend this functionality to handle `AST_If` and `AST_LabeledStatement` while we are at it.

fixes #1673
This commit is contained in:
Alex Lam S.L
2017-03-25 23:03:26 +08:00
committed by GitHub
parent 0a65de89b9
commit b19aa58cff
2 changed files with 149 additions and 13 deletions

View File

@@ -1600,14 +1600,29 @@ merge(Compressor.prototype, {
return false; return false;
}); });
def(AST_Block, function(compressor){ function any(list, compressor) {
for (var i = this.body.length; --i >= 0;) { for (var i = list.length; --i >= 0;)
if (this.body[i].has_side_effects(compressor)) if (list[i].has_side_effects(compressor))
return true; return true;
}
return false; return false;
}); }
def(AST_Block, function(compressor){
return any(this.body, compressor);
});
def(AST_Try, function(compressor){
return any(this.body, compressor)
|| this.bcatch && this.bcatch.has_side_effects(compressor)
|| this.bfinally && this.bfinally.has_side_effects(compressor);
});
def(AST_If, function(compressor){
return this.condition.has_side_effects(compressor)
|| this.body && this.body.has_side_effects(compressor)
|| this.alternative && this.alternative.has_side_effects(compressor);
});
def(AST_LabeledStatement, function(compressor){
return this.body.has_side_effects(compressor);
});
def(AST_SimpleStatement, function(compressor){ def(AST_SimpleStatement, function(compressor){
return this.body.has_side_effects(compressor); return this.body.has_side_effects(compressor);
}); });
@@ -1633,19 +1648,13 @@ merge(Compressor.prototype, {
return this.global() && this.undeclared(); return this.global() && this.undeclared();
}); });
def(AST_Object, function(compressor){ def(AST_Object, function(compressor){
for (var i = this.properties.length; --i >= 0;) return any(this.properties, compressor);
if (this.properties[i].has_side_effects(compressor))
return true;
return false;
}); });
def(AST_ObjectProperty, function(compressor){ def(AST_ObjectProperty, function(compressor){
return this.value.has_side_effects(compressor); return this.value.has_side_effects(compressor);
}); });
def(AST_Array, function(compressor){ def(AST_Array, function(compressor){
for (var i = this.elements.length; --i >= 0;) return any(this.elements, compressor);
if (this.elements[i].has_side_effects(compressor))
return true;
return false;
}); });
def(AST_Dot, function(compressor){ def(AST_Dot, function(compressor){
if (!compressor.option("pure_getters")) return true; if (!compressor.option("pure_getters")) return true;

127
test/compress/issue-1673.js Normal file
View File

@@ -0,0 +1,127 @@
side_effects_catch: {
options = {
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
function f() {
function g() {
try {
throw 0;
} catch (e) {
console.log("PASS");
}
}
g();
}
f();
}
expect: {
function f() {
(function() {
try {
throw 0;
} catch (e) {
console.log("PASS");
}
})();
}
f();
}
expect_stdout: "PASS"
}
side_effects_else: {
options = {
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
function f(x) {
function g() {
if (x);
else console.log("PASS");
}
g();
}
f(0);
}
expect: {
function f(x) {
(function() {
if (x);
else console.log("PASS");
})();
}
f(0);
}
expect_stdout: "PASS"
}
side_effects_finally: {
options = {
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
function f() {
function g() {
try {
} catch (e) {
} finally {
console.log("PASS");
}
}
g();
}
f();
}
expect: {
function f() {
(function() {
try {
} catch (e) {
} finally {
console.log("PASS");
}
})();
}
f();
}
expect_stdout: "PASS"
}
side_effects_label: {
options = {
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
function f(x) {
function g() {
L: {
console.log("PASS");
break L;
}
}
g();
}
f(0);
}
expect: {
function f(x) {
(function() {
L: {
console.log("PASS");
break L;
}
})();
}
f(0);
}
expect_stdout: "PASS"
}