From 4bbeb09f7c12bfb3d12ac5264bbdf033ee0b66dc Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sat, 7 Nov 2020 02:00:04 +0000 Subject: [PATCH] fix corner case in `reduce_vars` (#4262) fixes #4261 --- lib/compress.js | 2 +- lib/parse.js | 13 ++++------ test/compress/const.js | 40 +++++++++++++++++++++++++++++ test/compress/functions.js | 52 ++++++++++++++++++++++++++++++++++---- 4 files changed, 93 insertions(+), 14 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index ab837f60..9333cdf9 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -8429,7 +8429,7 @@ merge(Compressor.prototype, { fixed.name = make_node(AST_SymbolLambda, fixed.name, fixed.name); } if (fixed instanceof AST_Lambda) { - var scope = self.scope; + var scope = self.scope.resolve(); fixed.enclosed.forEach(function(def) { if (fixed.variables.has(def.name)) return; if (scope.var_names()[def.name]) return; diff --git a/lib/parse.js b/lib/parse.js index 69c14e4a..82717d26 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -753,7 +753,7 @@ function parse($TEXT, options) { } } - var statement = embed_tokens(function(strict_defun) { + var statement = embed_tokens(function() { handle_regexp(); switch (S.token.type) { case "string": @@ -844,9 +844,6 @@ function parse($TEXT, options) { return for_(); case "function": - if (!strict_defun && S.input.has_directive("use strict")) { - croak("In strict mode code, functions can only be declared at top level or immediately within another function."); - } next(); return function_(AST_Defun); @@ -1038,7 +1035,7 @@ function parse($TEXT, options) { S.input.push_directives_stack(); S.in_loop = 0; S.labels = []; - var body = block_(true); + var body = block_(); if (S.input.has_directive("use strict")) { if (name) strict_verify_symbol(name); argnames.forEach(strict_verify_symbol); @@ -1067,12 +1064,12 @@ function parse($TEXT, options) { }); } - function block_(strict_defun) { + function block_() { expect("{"); var a = []; while (!is("punc", "}")) { if (is("eof")) expect_token("punc", "}"); - a.push(statement(strict_defun)); + a.push(statement()); } next(); return a; @@ -1616,7 +1613,7 @@ function parse($TEXT, options) { var body = []; S.input.push_directives_stack(); while (!is("eof")) - body.push(statement(true)); + body.push(statement()); S.input.pop_directives_stack(); var end = prev(); var toplevel = options.toplevel; diff --git a/test/compress/const.js b/test/compress/const.js index 896e8c38..9ffb0d34 100644 --- a/test/compress/const.js +++ b/test/compress/const.js @@ -1135,3 +1135,43 @@ issue_4248: { } expect_stdout: "PASS" } + +issue_4261: { + options = { + inline: true, + reduce_funcs: true, + reduce_vars: true, + toplevel: true, + unused: true, + } + input: { + { + const a = 42; + (function() { + function f() { + console.log(a); + } + function g() { + while (f()); + } + (function() { + while (g()); + })(); + })(); + } + } + expect: { + { + const a = 42; + (function() { + function g() { + while (void console.log(a)); + } + (function() { + while (g()); + })(); + })(); + } + } + expect_stdout: "42" +} diff --git a/test/compress/functions.js b/test/compress/functions.js index c2ab23f6..3b57fb2b 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -2081,7 +2081,7 @@ issue_3016_1: { var b = 1; do { 3[b]; - } while(0); + } while (0); console.log(b); } expect_stdout: "1" @@ -2112,7 +2112,7 @@ issue_3016_2: { do { a = 3, a[b]; - } while(0); + } while (0); var a; console.log(b); } @@ -2145,7 +2145,7 @@ issue_3016_2_ie8: { do { a = 3, a[b]; - } while(0); + } while (0); var a; console.log(b); } @@ -2175,7 +2175,7 @@ issue_3016_3: { var b = 1; do { console.log((a = void 0, a ? "FAIL" : a = "PASS")); - } while(b--); + } while (b--); var a; } expect_stdout: [ @@ -2208,7 +2208,7 @@ issue_3016_3_ie8: { var b = 1; do { console.log((a = void 0, a ? "FAIL" : a = "PASS")); - } while(b--); + } while (b--); var a; } expect_stdout: [ @@ -5141,3 +5141,45 @@ issue_4259: { } expect_stdout: "function" } + +issue_4261: { + options = { + inline: true, + reduce_funcs: true, + reduce_vars: true, + toplevel: true, + unused: true, + } + input: { + try { + throw 42; + } catch (e) { + (function() { + function f() { + e.p; + } + function g() { + while (f()); + } + (function() { + while (console.log(g())); + })(); + })(); + } + } + expect: { + try { + throw 42; + } catch (e) { + (function() { + function g() { + while (void e.p); + } + (function() { + while (console.log(g())); + })(); + })(); + } + } + expect_stdout: true +} -- 2.34.1