From: Alex Lam S.L Date: Fri, 21 Aug 2020 02:35:34 +0000 (+0100) Subject: fix corner case in `collapse_vars` (#4061) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=fee677786ed35faa3eea7b9cd287730550ddd7d3;p=UglifyJS.git fix corner case in `collapse_vars` (#4061) --- diff --git a/lib/compress.js b/lib/compress.js index f15776c8..595e5032 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1952,6 +1952,7 @@ merge(Compressor.prototype, { function get_lvalues(expr) { var lvalues = new Dictionary(); if (expr instanceof AST_VarDef) lvalues.add(expr.name.name, lhs); + var find_arguments = scope.uses_arguments && !compressor.has_directive("use strict"); var scan_toplevel = scope instanceof AST_Toplevel; var tw = new TreeWalker(function(node) { var value; @@ -1960,21 +1961,27 @@ merge(Compressor.prototype, { } else if (node instanceof AST_This) { value = node; } - if (value) { - lvalues.add(node.name, is_modified(compressor, tw, node, value, 0)); - } else if (scan_toplevel) { - if (node.TYPE == "Call") { - if (modify_toplevel) return; - var exp = node.expression; - if (exp instanceof AST_PropAccess) return; - if (exp instanceof AST_Function && !exp.contains_this()) return; - modify_toplevel = true; - } else if (node instanceof AST_PropAccess && may_be_global(node.expression)) { - if (node === lhs && !(expr instanceof AST_Unary)) { - modify_toplevel = true; - } else { - read_toplevel = true; + if (value) lvalues.add(node.name, is_modified(compressor, tw, node, value, 0)); + if (find_arguments && node instanceof AST_Sub) { + scope.argnames.forEach(function(argname) { + if (!compressor.option("reduce_vars") || argname.definition().assignments) { + lvalues.add(argname.name, true); } + }); + find_arguments = false; + } + if (!scan_toplevel) return; + if (node.TYPE == "Call") { + if (modify_toplevel) return; + var exp = node.expression; + if (exp instanceof AST_PropAccess) return; + if (exp instanceof AST_Function && !exp.contains_this()) return; + modify_toplevel = true; + } else if (node instanceof AST_PropAccess && may_be_global(node.expression)) { + if (node === lhs && !(expr instanceof AST_Unary)) { + modify_toplevel = true; + } else { + read_toplevel = true; } } }); diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index aa8b89c9..c042f969 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -1599,7 +1599,7 @@ collapse_vars_constants: { } } -collapse_vars_arguments: { +collapse_vars_arguments_1: { options = { booleans: true, collapse_vars: true, @@ -1636,6 +1636,78 @@ collapse_vars_arguments: { expect_stdout: true } +collapse_vars_arguments_2: { + options = { + collapse_vars: true, + } + input: { + function log(a, b) { + console.log(b); + } + function f(c) { + var d = arguments[0]; + c = "FAIL"; + log(c, d); + } + f(); + f("PASS"); + } + expect: { + function log(a, b) { + console.log(b); + } + function f(c) { + var d = arguments[0]; + log(c = "FAIL", d); + } + f(); + f("PASS"); + } + expect_stdout: [ + "undefined", + "PASS", + ] +} + +collapse_vars_arguments_3: { + options = { + collapse_vars: true, + } + input: { + function log(a, b) { + console.log(b); + } + function f(c) { + var args = arguments; + console.log(c); + var d = args[0]; + c = "FAIL"; + log(c, d); + } + f(); + f("PASS"); + } + expect: { + function log(a, b) { + console.log(b); + } + function f(c) { + var args = arguments; + console.log(c); + var d = args[0]; + log(c = "FAIL", d); + } + f(); + f("PASS"); + } + expect_stdout: [ + "undefined", + "undefined", + "PASS", + "PASS", + ] +} + collapse_vars_short_circuit: { options = { booleans: true,