From: Alex Lam S.L Date: Wed, 22 Apr 2020 10:22:45 +0000 (+0100) Subject: enhance `dead_code` (#3811) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=01b13d797cdeabecad25c33e039fd3ec848b71d0;p=UglifyJS.git enhance `dead_code` (#3811) --- diff --git a/lib/compress.js b/lib/compress.js index d055132d..6926b357 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1034,6 +1034,16 @@ merge(Compressor.prototype, { return false; } + function has_declarations_only(block) { + return all(block.body, function(stat) { + return is_empty(stat) + || stat instanceof AST_Defun + || stat instanceof AST_Var && all(stat.definitions, function(var_def) { + return !var_def.value; + }); + }); + } + function loop_body(x) { if (x instanceof AST_IterationStatement) { return x.body instanceof AST_BlockStatement ? x.body : x; @@ -5493,15 +5503,15 @@ merge(Compressor.prototype, { var stat = branch.body[branch.body.length - 1]; if (is_break(stat, compressor)) branch.body.pop(); if (branch === default_branch) { - if (!is_body_empty(branch)) break; + if (!has_declarations_only(branch)) break; } else if (branch.expression.has_side_effects(compressor)) { break; } else if (default_branch) { - if (!is_body_empty(default_branch)) break; + if (!has_declarations_only(default_branch)) break; if (body[body.length - 2] !== default_branch) break; default_branch.body = default_branch.body.concat(branch.body); branch.body = []; - } else if (!is_body_empty(branch)) break; + } else if (!has_declarations_only(branch)) break; eliminate_branch(branch); if (body.pop() === default_branch) default_branch = null; } @@ -5543,16 +5553,6 @@ merge(Compressor.prototype, { return node instanceof AST_Break && tw.loopcontrol_target(node) === self; } - function is_body_empty(branch) { - return all(branch.body, function(stat) { - return is_empty(stat) - || stat instanceof AST_Defun - || stat instanceof AST_Var && all(stat.definitions, function(var_def) { - return !var_def.value; - }); - }); - } - function eliminate_branch(branch, prev) { if (prev && !aborts(prev)) { prev.body = prev.body.concat(branch.body); @@ -5564,25 +5564,35 @@ merge(Compressor.prototype, { OPT(AST_Try, function(self, compressor) { self.body = tighten_body(self.body, compressor); - if (self.bcatch && self.bfinally && all(self.bfinally.body, is_empty)) self.bfinally = null; - if (compressor.option("dead_code") && all(self.body, is_empty)) { - var body = []; - if (self.bcatch) { - extract_declarations_from_unreachable_code(self.bcatch, body); - body.forEach(function(stat) { - if (!(stat instanceof AST_Definitions)) return; - stat.definitions.forEach(function(var_def) { - var def = var_def.name.definition().redefined(); - if (!def) return; - var_def.name = var_def.name.clone(); - var_def.name.thedef = def; + if (compressor.option("dead_code")) { + if (has_declarations_only(self)) { + var body = []; + if (self.bcatch) { + extract_declarations_from_unreachable_code(self.bcatch, body); + body.forEach(function(stat) { + if (!(stat instanceof AST_Definitions)) return; + stat.definitions.forEach(function(var_def) { + var def = var_def.name.definition().redefined(); + if (!def) return; + var_def.name = var_def.name.clone(); + var_def.name.thedef = def; + }); }); - }); + } + [].unshift.apply(body, self.body); + if (self.bfinally) [].push.apply(body, self.bfinally.body); + return make_node(AST_BlockStatement, self, { + body: body + }).optimize(compressor); + } + if (self.bfinally && has_declarations_only(self.bfinally)) { + var body = self.body.concat(self.bfinally.body); + if (!self.bcatch) return make_node(AST_BlockStatement, self, { + body: body + }).optimize(compressor); + self.body = body; + self.bfinally = null; } - if (self.bfinally) body = body.concat(self.bfinally.body); - return make_node(AST_BlockStatement, self, { - body: body - }).optimize(compressor); } return self; }); diff --git a/test/compress/dead-code.js b/test/compress/dead-code.js index 344e1ff9..5de9ad37 100644 --- a/test/compress/dead-code.js +++ b/test/compress/dead-code.js @@ -97,6 +97,66 @@ dead_code_constant_boolean_should_warn_more: { node_version: "<=4" } +trim_try: { + options = { + dead_code: true, + } + input: { + try { + var a; + } catch (e) { + console.log("FAIL"); + } finally { + console.log(a); + } + } + expect: { + var a; + console.log(a); + } + expect_stdout: "undefined" +} + +trim_finally_1: { + options = { + dead_code: true, + } + input: { + try { + console.log("PASS"); + } finally { + var a; + } + } + expect: { + console.log("PASS"); + var a; + } + expect_stdout: "PASS" +} + +trim_finally_2: { + options = { + dead_code: true, + } + input: { + try { + console.log("PASS"); + } catch (e) { + } finally { + var a; + } + } + expect: { + try { + console.log("PASS"); + var a; + } catch (e) { + } + } + expect_stdout: "PASS" +} + try_catch_finally: { options = { conditionals: true, @@ -130,10 +190,7 @@ try_catch_finally: { a = 3; console.log("PASS"); }(); - try { - console.log(a); - } finally { - } + console.log(a); } expect_stdout: [ "PASS",