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:
@@ -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
127
test/compress/issue-1673.js
Normal 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"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user