From: Alex Lam S.L Date: Sat, 6 Feb 2021 04:39:46 +0000 (+0000) Subject: enhance `compress` on arrow and `async` functions (#4616) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=5359900b78fdf3006dafc13a206332d2fb2b1ea4;p=UglifyJS.git enhance `compress` on arrow and `async` functions (#4616) --- diff --git a/lib/compress.js b/lib/compress.js index 781b59f3..d4cf0da9 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1843,7 +1843,7 @@ merge(Compressor.prototype, { if (node instanceof AST_Call) { if (!(lhs instanceof AST_PropAccess)) return false; if (!lhs.equivalent_to(node.expression)) return false; - return !(rvalue instanceof AST_Function && !rvalue.contains_this()); + return !(is_function(rvalue) && !rvalue.contains_this()); } if (node instanceof AST_Debugger) return true; if (node instanceof AST_Defun) return funarg && lhs.name === node.name.name; @@ -2482,7 +2482,7 @@ merge(Compressor.prototype, { if (modify_toplevel) return; var exp = node.expression; if (exp instanceof AST_PropAccess) return; - if (exp instanceof AST_Function && !exp.contains_this()) return; + if (is_function(exp) && !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)) { @@ -4060,7 +4060,7 @@ merge(Compressor.prototype, { key = key._eval(compressor, ignore_side_effects, cached, depth); if (key === prop.key) return this; } - if (prop.value instanceof AST_Function && typeof Object.prototype[key] == "function") return this; + if (key == "toString" || key == "valueOf") return this; val[key] = prop.value._eval(compressor, ignore_side_effects, cached, depth); if (val[key] === prop.value) return this; } @@ -5850,10 +5850,10 @@ merge(Compressor.prototype, { } } else if (compressor.option("functions") && !compressor.option("ie8") - && !(node instanceof AST_Const || node instanceof AST_Let) + && node instanceof AST_Var && var_defs[sym.id] == 1 && sym.assignments == 0 - && value instanceof AST_Function + && (value instanceof AST_AsyncFunction || value instanceof AST_Function) && (sym.references.length ? all(sym.references, function(ref) { return value === ref.fixed_value(); }) : value === def.name.fixed_value()) @@ -5864,7 +5864,7 @@ merge(Compressor.prototype, { && can_declare_defun() && can_rename(value, def.name.name)) { AST_Node.warn("Declaring {name} as function [{file}:{line},{col}]", template(def.name)); - var defun = make_node(AST_Defun, def, value); + var defun = make_node(value instanceof AST_Function ? AST_Defun : AST_AsyncDefun, def, value); defun.name = make_node(AST_SymbolDefun, def.name, def.name); var name_def = def.name.scope.resolve().def_function(defun.name); if (old_def) old_def.forEach(function(node) { @@ -6902,7 +6902,7 @@ merge(Compressor.prototype, { return exprs && make_sequence(self, exprs.map(convert_spread)); } var def; - if (exp instanceof AST_Function + if ((is_arrow(exp) && !exp.value || exp instanceof AST_AsyncFunction || exp instanceof AST_Function) && !(exp.name && (def = exp.name.definition()).references.length > def.replaced)) { exp.process_expression(false, function(node) { var value = node.value && node.value.drop_side_effect_free(compressor, true); diff --git a/test/compress/arrows.js b/test/compress/arrows.js index 6d9f89d1..57d8d395 100644 --- a/test/compress/arrows.js +++ b/test/compress/arrows.js @@ -434,6 +434,46 @@ collapse_value: { node_version: ">=4" } +collapse_property_lambda: { + options = { + collapse_vars: true, + pure_getters: "strict", + } + input: { + console.log(function f() { + f.g = () => 42; + return f.g(); + }()); + } + expect: { + console.log(function f() { + return (f.g = () => 42)(); + }()); + } + expect_stdout: "42" + node_version: ">=4" +} + +drop_return: { + options = { + side_effects: true, + } + input: { + (a => { + while (!console); + return console.log(a); + })(42); + } + expect: { + (a => { + while (!console); + console.log(a); + })(42); + } + expect_stdout: "42" + node_version: ">=4" +} + reduce_iife_1: { options = { evaluate: true, diff --git a/test/compress/awaits.js b/test/compress/awaits.js index c70635da..18012b48 100644 --- a/test/compress/awaits.js +++ b/test/compress/awaits.js @@ -519,6 +519,160 @@ collapse_vars_3: { node_version: ">=8" } +collapse_property_lambda: { + options = { + collapse_vars: true, + pure_getters: "strict", + } + input: { + (async function f() { + f.g = () => 42; + return f.g(); + })().then(console.log); + } + expect: { + (async function f() { + return (f.g = () => 42)(); + })().then(console.log); + } + expect_stdout: "42" + node_version: ">=8" +} + +drop_return: { + options = { + side_effects: true, + } + input: { + (async function(a) { + while (!console); + return console.log(a); + })(42); + } + expect: { + (async function(a) { + while (!console); + console.log(a); + })(42); + } + expect_stdout: "42" + node_version: ">=8" +} + +functions: { + options = { + functions: true, + reduce_vars: true, + unused: true, + } + input: { + !async function() { + var a = async function a() { + return a && "a"; + }; + var b = async function x() { + return !!x; + }; + var c = async function(c) { + return c; + }; + if (await c(await b(await a()))) { + var d = async function() {}; + var e = async function y() { + return typeof y; + }; + var f = async function(f) { + return f; + }; + console.log(await a(await d()), await b(await e()), await c(await f(42)), typeof d, await e(), typeof f); + } + }(); + } + expect: { + !async function() { + async function a() { + return a && "a"; + } + async function b() { + return !!b; + } + var c = async function(c) { + return c; + }; + if (await c(await b(await a()))) { + async function d() {} + async function e() { + return typeof e; + } + var f = async function(f) { + return f; + }; + console.log(await a(await d()), await b(await e()), await c(await f(42)), typeof d, await e(), typeof f); + } + }(); + } + expect_stdout: "a true 42 function function function" + node_version: ">=8" +} + +functions_use_strict: { + options = { + functions: true, + reduce_vars: true, + unused: true, + } + input: { + "use strict"; + !async function() { + var a = async function a() { + return a && "a"; + }; + var b = async function x() { + return !!x; + }; + var c = async function(c) { + return c; + }; + if (await c(await b(await a()))) { + var d = async function() {}; + var e = async function y() { + return typeof y; + }; + var f = async function(f) { + return f; + }; + console.log(await a(await d()), await b(await e()), await c(await f(42)), typeof d, await e(), typeof f); + } + }(); + } + expect: { + "use strict"; + !async function() { + async function a() { + return a && "a"; + } + async function b() { + return !!b; + } + var c = async function(c) { + return c; + }; + if (await c(await b(await a()))) { + var d = async function() {}; + var e = async function y() { + return typeof y; + }; + var f = async function(f) { + return f; + }; + console.log(await a(await d()), await b(await e()), await c(await f(42)), typeof d, await e(), typeof f); + } + }(); + } + expect_stdout: "a true 42 function function function" + node_version: ">=8" +} + issue_4335_1: { options = { inline: true, diff --git a/test/compress/evaluate.js b/test/compress/evaluate.js index 2b1bbc01..f579ee72 100644 --- a/test/compress/evaluate.js +++ b/test/compress/evaluate.js @@ -703,6 +703,7 @@ prototype_function: { var g = 0(); var h = 0(); } + expect_stdout: true } call_args: { @@ -2800,7 +2801,7 @@ operator_in: { console.log("PASS" in { }); console.log("FAIL" in { }); console.log("toString" in { }); - console.log(true); + console.log("toString" in { toString: 3 }); } expect_stdout: [ "true", diff --git a/test/compress/pure_getters.js b/test/compress/pure_getters.js index 58920411..6adc6168 100644 --- a/test/compress/pure_getters.js +++ b/test/compress/pure_getters.js @@ -248,6 +248,35 @@ issue_2110_2: { expect_stdout: "function" } +issue_2110_3: { + options = { + collapse_vars: true, + pure_getters: "strict", + reduce_vars: true, + } + input: { + function g() { + return this; + } + console.log(typeof function() { + function f() {} + f.g = g; + return f.g(); + }()); + } + expect: { + function g() { + return this; + } + console.log(typeof function() { + function f() {} + f.g = g; + return f.g(); + }()); + } + expect_stdout: "function" +} + set_immutable_1: { options = { collapse_vars: true,