From: Alex Lam S.L Date: Fri, 1 May 2020 09:20:23 +0000 (+0100) Subject: fix corner case in `inline` (#3837) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=0794aaa2c24d8d5c27e8ba74c0e485a27e2fcd59;p=UglifyJS.git fix corner case in `inline` (#3837) fixes #3836 --- diff --git a/lib/compress.js b/lib/compress.js index 79f52783..d584bdf3 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -4003,16 +4003,30 @@ merge(Compressor.prototype, { })) break; } if (fn.contains_this()) break; - var j = fn.argnames.length; - if (j > 0 && compressor.option("inline") < 2) break; - if (j > self.argnames.length) break; - if (j < self.argnames.length && !compressor.drop_fargs(fn, call)) break; - while (--j >= 0) { + var len = fn.argnames.length; + if (len > 0 && compressor.option("inline") < 2) break; + if (len > self.argnames.length) break; + for (var j = 0; j < len; j++) { var arg = call.args[j]; if (!(arg instanceof AST_SymbolRef)) break; if (arg.definition() !== self.argnames[j].definition()) break; } - if (j >= 0) break; + if (j < len) break; + for (; j < call.args.length; j++) { + if (call.args[j].has_side_effects(compressor)) break; + } + if (j < call.args.length) break; + if (len < self.argnames.length && !compressor.drop_fargs(self, compressor.parent())) { + if (!compressor.drop_fargs(fn, call)) break; + do { + var argname = make_node(AST_SymbolFunarg, fn, { + name: fn.make_var_name("argument_" + len), + scope: fn + }); + fn.argnames.push(argname); + fn.enclosed.push(fn.def_variable(argname)); + } while (++len < self.argnames.length); + } return call.expression; } break; diff --git a/test/compress/functions.js b/test/compress/functions.js index f5ad08b4..439c073a 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -4151,7 +4151,7 @@ issue_3821_2: { expect_stdout: "PASS" } -substitude: { +substitute: { options = { inline: true, reduce_vars: true, @@ -4189,8 +4189,7 @@ substitude: { }; }, ].forEach(function(g) { - console.log(g()(o)); - console.log(g().call(o, o)); + console.log(g()(o), g().call(o, o), g().length); }); } expect: { @@ -4218,25 +4217,56 @@ substitude: { }; }, ].forEach(function(g) { - console.log(g()(o)); - console.log(g().call(o, o)); + console.log(g()(o), g().call(o, o), g().length); }); } expect_stdout: [ - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", + "PASS PASS 1", + "PASS PASS 1", + "PASS PASS 1", + "PASS PASS 1", + "PASS PASS 2", + ] +} + +substitute_add_farg: { + options = { + inline: true, + keep_fargs: "strict", + } + input: { + function f(g) { + console.log(g.length); + g(null, "FAIL"); + } + f(function() { + return function(a, b) { + return function(c) { + do { + console.log("PASS"); + } while (c); + }(a, b); + }; + }()); + } + expect: { + function f(g) { + console.log(g.length); + g(null, "FAIL"); + } + f(function(c, argument_1) { + do { + console.log("PASS"); + } while (c); + }); + } + expect_stdout: [ + "2", "PASS", ] } -substitude_arguments: { +substitute_arguments: { options = { inline: true, reduce_vars: true, @@ -4244,7 +4274,7 @@ substitude_arguments: { } input: { var o = {}; - function f() { + function f(a) { return arguments[0] === o ? "PASS" : "FAIL"; } [ @@ -4274,13 +4304,12 @@ substitude_arguments: { }; }, ].forEach(function(g) { - console.log(g()(o)); - console.log(g().call(o, o)); + console.log(g()(o), g().call(o, o), g().length); }); } expect: { var o = {}; - function f() { + function f(a) { return arguments[0] === o ? "PASS" : "FAIL"; } [ @@ -4310,25 +4339,19 @@ substitude_arguments: { }; }, ].forEach(function(g) { - console.log(g()(o)); - console.log(g().call(o, o)); + console.log(g()(o), g().call(o, o), g().length); }); } expect_stdout: [ - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", + "PASS PASS 1", + "PASS PASS 1", + "PASS PASS 1", + "PASS PASS 1", + "PASS PASS 2", ] } -substitude_drop_fargs: { +substitute_drop_farg: { options = { inline: true, keep_fargs: false, @@ -4367,8 +4390,7 @@ substitude_drop_fargs: { }; }, ].forEach(function(g) { - console.log(g()(o)); - console.log(g().call(o, o)); + console.log(g()(o), g().call(o, o)); }); } expect: { @@ -4394,25 +4416,19 @@ substitude_drop_fargs: { return f; }, ].forEach(function(g) { - console.log(g()(o)); - console.log(g().call(o, o)); + console.log(g()(o), g().call(o, o)); }); } expect_stdout: [ - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", + "PASS PASS", + "PASS PASS", + "PASS PASS", + "PASS PASS", + "PASS PASS", ] } -substitude_this: { +substitute_this: { options = { inline: true, reduce_vars: true, @@ -4450,8 +4466,7 @@ substitude_this: { }; }, ].forEach(function(g) { - console.log(g()(o)); - console.log(g().call(o, o)); + console.log(g()(o), g().call(o, o), g().length); }); } expect: { @@ -4486,25 +4501,19 @@ substitude_this: { }; }, ].forEach(function(g) { - console.log(g()(o)); - console.log(g().call(o, o)); + console.log(g()(o), g().call(o, o), g().length); }); } expect_stdout: [ - "false", - "true", - "false", - "false", - "false", - "false", - "false", - "false", - "false", - "false", + "false true 1", + "false false 1", + "false false 1", + "false false 1", + "false false 2", ] } -substitude_use_strict: { +substitute_use_strict: { options = { inline: true, reduce_vars: true, @@ -4543,8 +4552,7 @@ substitude_use_strict: { }; }, ].forEach(function(g) { - console.log(g()(o)); - console.log(g().call(o, o)); + console.log(g()(o), g().call(o, o), g().length); }); } expect: { @@ -4573,21 +4581,15 @@ substitude_use_strict: { }; }, ].forEach(function(g) { - console.log(g()(o)); - console.log(g().call(o, o)); + console.log(g()(o), g().call(o, o), g().length); }); } expect_stdout: [ - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", - "PASS", + "PASS PASS 1", + "PASS PASS 1", + "PASS PASS 1", + "PASS PASS 1", + "PASS PASS 2", ] } @@ -4637,3 +4639,24 @@ issue_3835: { } expect_stdout: true } + +issue_3836: { + options = { + inline: true, + } + input: { + (function() { + return function() { + for (var a in 0) + console.log(k); + }(console.log("PASS")); + })(); + } + expect: { + (function() { + for (var a in 0) + console.log(k); + })(console.log("PASS")); + } + expect_stdout: "PASS" +}