From 4e06e1ca349f3c56e107dcd83e70b0f13577fb2a Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Mon, 18 Nov 2019 15:04:55 +0800 Subject: [PATCH] fix corner case in `inline` (#3595) --- lib/compress.js | 19 ++++++--- test/compress/functions.js | 81 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 6 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index b7a73430ad..a878ef21b9 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -862,13 +862,9 @@ merge(Compressor.prototype, { AST_Toplevel.DEFMETHOD("reset_opt_flags", function(compressor) { var tw = new TreeWalker(compressor.option("reduce_vars") ? function(node, descend) { - node._squeezed = false; - node._optimized = false; + reset_flags(node); return node.reduce_vars(tw, descend, compressor); - } : function(node) { - node._squeezed = false; - node._optimized = false; - }); + } : reset_flags); // Flow control for visiting `AST_Defun`s tw.defun_ids = Object.create(null); tw.defun_visited = Object.create(null); @@ -881,6 +877,12 @@ merge(Compressor.prototype, { // - backup & restore via `save_ids` when visiting out-of-order sections tw.safe_ids = Object.create(null); this.walk(tw); + + function reset_flags(node) { + node._squeezed = false; + node._optimized = false; + if (node instanceof AST_Scope) delete node._var_names; + } }); AST_Symbol.DEFMETHOD("fixed_value", function(final) { @@ -5582,6 +5584,11 @@ merge(Compressor.prototype, { definitions: decls })); [].splice.apply(scope.body, args); + fn.enclosed.forEach(function(def) { + if (scope.var_names()[def.name]) return; + scope.enclosed.push(def); + scope.var_names()[def.name] = true; + }); return expressions; } }); diff --git a/test/compress/functions.js b/test/compress/functions.js index 297dac788f..2af14a6240 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -3487,3 +3487,84 @@ hoisted_single_use: { "bar", ] } + +pr_3592_1: { + options = { + inline: true, + reduce_funcs: false, + reduce_vars: true, + toplevel: true, + unused: true, + } + input: { + function problem(w) { + return g.indexOf(w); + } + function unused(x) { + return problem(x); + } + function B(problem) { + return g[problem]; + } + function A(y) { + return problem(y); + } + function main(z) { + return B(A(z)); + } + var g = [ "PASS" ]; + console.log(main("PASS")); + } + expect: { + function problem(w) { + return g.indexOf(w); + } + function B(problem) { + return g[problem]; + } + var g = [ "PASS" ]; + console.log((z = "PASS", B((y = z, problem(y))))); + var z, y; + } + expect_stdout: "PASS" +} + +pr_3592_2: { + options = { + inline: true, + reduce_funcs: true, + reduce_vars: true, + toplevel: true, + unused: true, + } + input: { + function problem(w) { + return g.indexOf(w); + } + function unused(x) { + return problem(x); + } + function B(problem) { + return g[problem]; + } + function A(y) { + return problem(y); + } + function main(z) { + return B(A(z)); + } + var g = [ "PASS" ]; + console.log(main("PASS")); + } + expect: { + function problem(w) { + return g.indexOf(w); + } + var g = [ "PASS" ]; + console.log((z = "PASS", function(problem) { + return g[problem]; + }((y = z, problem(y))))); + var z, y; + } + expect_stdout: "PASS" +}