From: Alex Lam S.L Date: Mon, 8 Mar 2021 04:38:53 +0000 (+0000) Subject: fix corner case in `inline` (#4754) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=077512d1515d9fbd4e19bce79be75a09df8d5619;p=UglifyJS.git fix corner case in `inline` (#4754) fixes #4753 --- diff --git a/lib/ast.js b/lib/ast.js index 1a1e0454..e77ec093 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -139,7 +139,7 @@ var AST_Node = DEFNODE("Node", "start end", { }, null); (AST_Node.log_function = function(fn, verbose) { - if (!fn) { + if (typeof fn != "function") { AST_Node.info = AST_Node.warn = noop; return; } diff --git a/lib/compress.js b/lib/compress.js index 3551655a..f63c1869 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -9046,6 +9046,7 @@ merge(Compressor.prototype, { if (!all(stat.enclosed, function(def) { return def.scope === stat || !defined[def.name]; })) return false; + if (in_loop) in_loop.push(stat.name.definition()); continue; } if (!(stat instanceof AST_Var)) continue; @@ -9189,32 +9190,56 @@ merge(Compressor.prototype, { } } + function flatten_var(name) { + var redef = name.definition().redefined(); + if (redef) { + name = name.clone(); + name.thedef = redef; + } + return name; + } + function flatten_vars(decls, expressions) { - var pos = expressions.length; + var args = [ insert, 0 ]; + var decl_var = [], expr_var = [], expr_loop = []; for (var i = 0; i < fn.body.length; i++) { var stat = fn.body[i]; + if (stat instanceof AST_LambdaDefinition) { + if (in_loop) { + var name = make_node(AST_SymbolVar, stat.name, flatten_var(stat.name)); + name.definition().orig.push(name); + append_var(decls, expressions, name, to_func_expr(stat, true)); + } else { + var def = stat.name.definition(); + scope.functions.set(def.name, def); + scope.variables.set(def.name, def); + scope.enclosed.push(def); + scope.var_names()[def.name] = true; + args.push(stat); + } + continue; + } if (!(stat instanceof AST_Var)) continue; for (var j = 0; j < stat.definitions.length; j++) { var var_def = stat.definitions[j]; - var name = var_def.name; - var redef = name.definition().redefined(); - if (redef) { - name = name.clone(); - name.thedef = redef; - } - append_var(decls, expressions, name, var_def.value); + var name = flatten_var(var_def.name); + append_var(decl_var, expr_var, name, var_def.value); if (in_loop && !HOP(arg_used, name.name)) { var def = fn.variables.get(name.name); var sym = make_node(AST_SymbolRef, name, name); def.references.push(sym); - expressions.splice(pos++, 0, make_node(AST_Assign, var_def, { + expr_loop.push(make_node(AST_Assign, var_def, { operator: "=", left: sym, - right: make_node(AST_Undefined, name) + right: make_node(AST_Undefined, name), })); } } } + [].push.apply(decls, decl_var); + [].push.apply(expressions, expr_loop); + [].push.apply(expressions, expr_var); + return args; } function flatten_fn() { @@ -9225,19 +9250,8 @@ merge(Compressor.prototype, { } else { flatten_args(decls, expressions); } - flatten_vars(decls, expressions); + var args = flatten_vars(decls, expressions); expressions.push(value); - var args = fn.body.filter(function(stat) { - if (stat instanceof AST_LambdaDefinition) { - var def = stat.name.definition(); - scope.functions.set(def.name, def); - scope.variables.set(def.name, def); - scope.enclosed.push(def); - scope.var_names()[def.name] = true; - return true; - } - }); - args.unshift(insert, 0); if (decls.length) args.push(make_node(AST_Var, fn, { definitions: decls })); diff --git a/lib/parse.js b/lib/parse.js index 835ac21c..5a4d9811 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -1743,7 +1743,7 @@ function parse($TEXT, options) { name: "new.target", start: start, end: prev(), - }) + }); } var newexp = expr_atom(false), args; if (is("punc", "(")) { diff --git a/test/compress/functions.js b/test/compress/functions.js index 856dbcea..682b5844 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -5771,3 +5771,64 @@ new_target: { expect_stdout: "function undefined" node_version: ">=6" } + +issue_4753_1: { + options = { + inline: true, + toplevel: true, + } + input: { + for (var i in [ 1, 2 ]) + (function() { + function f() {} + f && console.log(f.p ^= 42); + })(); + } + expect: { + for (var i in [ 1, 2 ]) + f = function() {}, + void (f && console.log(f.p ^= 42)); + var f; + } + expect_stdout: [ + "42", + "42", + ] +} + +issue_4753_2: { + options = { + inline: true, + reduce_vars: true, + side_effects: true, + toplevel: true, + unused: true, + } + input: { + do { + (function() { + var a = f(); + function f() { + return "PASS"; + } + f; + function g() { + console.log(a); + } + g(); + })(); + } while (0); + } + expect: { + do { + f = function() { + return "PASS"; + }, + a = void 0, + a = f(), + console.log(a); + } while (0); + var f, a; + } + expect_stdout: "PASS" +}