From 903a5df9a5bfcaac6cc6da8294f3de8599004a23 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sat, 11 Apr 2020 12:54:26 +0100 Subject: fix corner case in `inline` (#3778) fixes #3777 --- lib/compress.js | 20 +++++++++---------- lib/utils.js | 6 ++++++ test/compress/functions.js | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 98724bd0..e5b7bf09 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -5820,7 +5820,7 @@ merge(Compressor.prototype, { } } if (is_func) { - var def, value; + var def, value, var_assigned = false; if (can_inline && !fn.uses_arguments && !fn.pinned() @@ -5909,10 +5909,12 @@ merge(Compressor.prototype, { for (var i = 0; i < len; i++) { var line = fn.body[i]; if (line instanceof AST_Var) { - if (stat && !all(line.definitions, function(var_def) { + var assigned = var_assigned || !all(line.definitions, function(var_def) { return !var_def.value; - })) { - return false; + }); + if (assigned) { + var_assigned = true; + if (stat) return false; } } else if (line instanceof AST_Defun || line instanceof AST_EmptyStatement) { continue; @@ -5932,15 +5934,11 @@ merge(Compressor.prototype, { } function can_substitute_directly() { + if (var_assigned) return; if (compressor.option("inline") <= 1 && fn.argnames.length) return; - var var_count = fn.variables.size() - 1; - if (var_count > fn.argnames.length) return; - var var_names = []; - if (!all(fn.argnames, function(argname) { - push_uniq(var_names, argname.name); - return argname.definition().references.length < 2; + if (!fn.variables.all(function(def) { + return def.references.length < 2 && def.orig[0] instanceof AST_SymbolFunarg; })) return; - if (var_count > var_names.length) return; var abort = false; var begin; var in_order = []; diff --git a/lib/utils.js b/lib/utils.js index 9959305a..508aba9c 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -217,6 +217,12 @@ Dictionary.prototype = { return this; }, has: function(key) { return ("$" + key) in this._values }, + all: function(predicate) { + for (var i in this._values) + if (!predicate(this._values[i], i.substr(1))) + return false; + return true; + }, each: function(f) { for (var i in this._values) f(this._values[i], i.substr(1)); diff --git a/test/compress/functions.js b/test/compress/functions.js index c1522e2e..4dc685be 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -4014,3 +4014,51 @@ issue_3772: { } expect_stdout: "PASS" } + +issue_3777_1: { + options = { + inline: true, + reduce_vars: true, + side_effects: true, + } + input: { + (function() { + ff && ff(NaN); + function ff(a) { + var a = console.log("PASS"); + } + })(); + } + expect: { + (function() { + ff && ff(NaN); + function ff(a) { + var a = console.log("PASS"); + } + })(); + } + expect_stdout: "PASS" +} + +issue_3777_2: { + options = { + inline: true, + pure_getters: "strict", + reduce_vars: true, + side_effects: true, + toplevel: true, + } + input: { + ff(ff.p); + function ff(a) { + var a = console.log("PASS"); + } + } + expect: { + ff(ff.p); + function ff(a) { + var a = console.log("PASS"); + } + } + expect_stdout: "PASS" +} -- cgit v1.2.3