diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2021-05-30 09:32:48 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-30 16:32:48 +0800 |
commit | 06e3dbc08916d70f3ca26cd89f8b442b23593332 (patch) | |
tree | bca869edc0e61b0aa7961b77c01aa65cc9b6f037 | |
parent | 55a230daa84a004058d8cde0e15543bb2647dc3c (diff) | |
download | tracifyjs-06e3dbc08916d70f3ca26cd89f8b442b23593332.tar.gz tracifyjs-06e3dbc08916d70f3ca26cd89f8b442b23593332.zip |
improve handling of declaration statements (#4980)
-rw-r--r-- | lib/compress.js | 25 | ||||
-rw-r--r-- | test/compress/functions.js | 2 | ||||
-rw-r--r-- | test/compress/let.js | 108 |
3 files changed, 127 insertions, 8 deletions
diff --git a/lib/compress.js b/lib/compress.js index 34d36a0c..b20a41e5 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -325,9 +325,12 @@ merge(Compressor.prototype, { } else if (insert === "awaits" && node instanceof AST_Try) { if (node.bfinally) return node; } - var index = node.body.length - 1; - if (index >= 0) { - node.body[index] = node.body[index].transform(tt); + for (var index = node.body.length; --index >= 0;) { + var stat = node.body[index]; + if (!is_declaration(stat, true)) { + node.body[index] = stat.transform(tt); + break; + } } } else if (node instanceof AST_If) { node.body = node.body.transform(tt); @@ -1695,8 +1698,16 @@ merge(Compressor.prototype, { }); } - function is_declaration(stat) { - return stat instanceof AST_Defun || stat instanceof AST_Var && declarations_only(stat); + function is_declaration(stat, lexical) { + if (stat instanceof AST_DefClass) return lexical && !stat.extends && all(stat.properties, function(prop) { + if (prop.key instanceof AST_Node) return false; + if (prop instanceof AST_ClassField && prop.static && prop.value) return false; + return true; + }); + if (stat instanceof AST_Definitions) return (lexical || stat instanceof AST_Var) && declarations_only(stat); + if (stat instanceof AST_ExportDeclaration) return is_declaration(stat.body, lexical); + if (stat instanceof AST_ExportDefault) return is_declaration(stat.body, lexical); + return stat instanceof AST_LambdaDefinition; } function tighten_body(statements, compressor) { @@ -3157,7 +3168,7 @@ merge(Compressor.prototype, { var index = body.lastIndexOf(stat); if (index < 0) return false; while (++index < body.length) { - if (!is_declaration(body[index])) return false; + if (!is_declaration(body[index], true)) return false; } return true; } @@ -7970,7 +7981,7 @@ merge(Compressor.prototype, { self.condition, ]); body.splice(i, 1); - } else if (!is_declaration(stat)) { + } else if (!is_declaration(stat, true)) { break; } } diff --git a/test/compress/functions.js b/test/compress/functions.js index 8ab7c1fc..988f589e 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -5236,7 +5236,7 @@ issue_4265: { expect: { function f() { return console, function() { - return console.log(a); + console.log(a); var a; }(), 0; } diff --git a/test/compress/let.js b/test/compress/let.js index 64526aa7..0a23f65b 100644 --- a/test/compress/let.js +++ b/test/compress/let.js @@ -569,6 +569,38 @@ loop_block_2: { node_version: ">=4" } +do_break: { + options = { + loops: true, + } + input: { + "use strict"; + try { + do { + if (a) + break; + let a; + } while (!console); + } catch (e) { + console.log("PASS"); + } + } + expect: { + "use strict"; + try { + do { + if (a) + break; + let a; + } while (!console); + } catch (e) { + console.log("PASS"); + } + } + expect_stdout: "PASS" + node_version: ">=4" +} + do_continue: { options = { loops: true, @@ -629,6 +661,82 @@ dead_block_after_return: { node_version: ">=4" } +if_return_1: { + options = { + if_return: true, + } + input: { + "use strict"; + function f(a) { + function g() { + return b = "PASS"; + } + if (a) + return g(); + let b; + return g(); + }; + console.log(f()); + } + expect: { + "use strict"; + function f(a) { + function g() { + return b = "PASS"; + } + if (a) + return g(); + let b; + return g(); + }; + console.log(f()); + } + expect_stdout: "PASS" + node_version: ">=4" +} + +if_return_2: { + options = { + if_return: true, + } + input: { + "use strict"; + function f(a) { + function g() { + return b = "FAIL"; + } + if (a) + return g(); + let b; + return g(); + }; + try { + console.log(f(42)); + } catch (e) { + console.log("PASS"); + } + } + expect: { + "use strict"; + function f(a) { + function g() { + return b = "FAIL"; + } + if (a) + return g(); + let b; + return g(); + }; + try { + console.log(f(42)); + } catch (e) { + console.log("PASS"); + } + } + expect_stdout: "PASS" + node_version: ">=4" +} + do_if_continue_1: { options = { if_return: true, |