From d6fd18d0b000e1e4fbe01259139043f42d8fdebf Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Wed, 13 Nov 2019 04:17:09 +0800 Subject: [PATCH] enhance `evaluate` & `inline` (#3580) --- lib/compress.js | 20 ++++++++------------ test/compress/collapse_vars.js | 4 ++-- test/compress/dead-code.js | 4 +--- test/compress/evaluate.js | 21 +++++++++++++++++++++ test/compress/functions.js | 3 ++- test/compress/reduce_vars.js | 26 ++++++++++---------------- test/compress/typeof.js | 4 +--- 7 files changed, 45 insertions(+), 37 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 08728bb4..2bf120b3 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -3059,15 +3059,15 @@ merge(Compressor.prototype, { }); def(AST_Call, function(compressor, cached, depth) { var exp = this.expression; - if (exp instanceof AST_SymbolRef) { - var fn = exp.fixed_value(); - if (!(fn instanceof AST_Lambda)) return this; + var fn = exp instanceof AST_SymbolRef ? exp.fixed_value() : exp; + if (fn instanceof AST_Lambda) { + if (fn.evaluating) return this; if (fn.name && fn.name.definition().recursive_refs > 0) return this; - if (fn.body.length != 1 || !fn.is_constant_expression()) return this; var stat = fn.body[0]; if (!(stat instanceof AST_Return)) return this; var args = eval_args(this.args); if (!args) return this; + if (!stat.value) return undefined; fn.argnames.forEach(function(sym, i) { var value = args[i]; sym.definition().references.forEach(function(node) { @@ -3077,8 +3077,9 @@ merge(Compressor.prototype, { cached.push(node); }); }); - if (!stat.value) return undefined; + fn.evaluating = true; var val = stat.value._eval(compressor, cached, depth); + delete fn.evaluating; if (val === stat.value) return this; return val; } else if (compressor.option("unsafe") && exp instanceof AST_PropAccess) { @@ -5280,15 +5281,10 @@ merge(Compressor.prototype, { } var stat = is_func && fn.body[0]; var can_inline = compressor.option("inline") && !self.is_expr_pure(compressor); - if (can_inline && stat instanceof AST_Return) { + if (exp === fn && can_inline && stat instanceof AST_Return) { var value = stat.value; if (!value || value.is_constant_expression()) { - if (value) { - value = value.clone(true); - } else { - value = make_node(AST_Undefined, self); - } - var args = self.args.concat(value); + var args = self.args.concat(value || make_node(AST_Undefined, self)); return make_sequence(self, args).optimize(compressor); } } diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index 86e8d632..e67425af 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -1458,7 +1458,7 @@ collapse_vars_constants: { function f3(x) { var b = x.prop; sideeffect1(); - return b + (function() { return -9; })(); + return b + -9; } } } @@ -5748,7 +5748,7 @@ issue_3215_1: { }()); } expect: { - console.log("number"); + console.log(typeof 42); } expect_stdout: "number" } diff --git a/test/compress/dead-code.js b/test/compress/dead-code.js index d4832c73..627630ab 100644 --- a/test/compress/dead-code.js +++ b/test/compress/dead-code.js @@ -892,9 +892,7 @@ issue_2860_1: { }()); } expect: { - console.log(function(a) { - return 1 ^ a; - }()); + console.log(1); } expect_stdout: "1" } diff --git a/test/compress/evaluate.js b/test/compress/evaluate.js index 74cb65ff..ea707e63 100644 --- a/test/compress/evaluate.js +++ b/test/compress/evaluate.js @@ -1900,3 +1900,24 @@ issue_3568: { } expect_stdout: "NaN" } + +conditional_function: { + options = { + evaluate: true, + reduce_vars: true, + toplevel: true, + } + input: { + function f(a) { + return a && "undefined" != typeof A ? A : 42; + } + console.log(f(0), f(1)); + } + expect: { + function f(a) { + return a && "undefined" != typeof A ? A : 42; + } + console.log(42, f(1)); + } + expect_stdout: "42 42" +} diff --git a/test/compress/functions.js b/test/compress/functions.js index 1208b62d..e36176bd 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -2265,7 +2265,8 @@ issue_3054: { return { a: !0 }; } console.log(function(b) { - return { a: !(b = !1) }; + b = !1; + return f(); }().a, f.call().a); } expect_stdout: "true true" diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js index ce7c16da..a3421c00 100644 --- a/test/compress/reduce_vars.js +++ b/test/compress/reduce_vars.js @@ -1427,13 +1427,13 @@ defun_inline_3: { defun_call: { options = { - inline: true, + evaluate: true, reduce_funcs: true, reduce_vars: true, unused: true, } input: { - function f() { + console.log(function f() { return g() + h(1) - h(g(), 2, 3); function g() { return 4; @@ -1441,21 +1441,17 @@ defun_call: { function h(a) { return a; } - } + }()); } expect: { - function f() { - return 4 + h(1) - h(4); - function h(a) { - return a; - } - } + console.log(1); } + expect_stdout: "1" } defun_redefine: { options = { - inline: true, + evaluate: true, reduce_funcs: true, reduce_vars: true, unused: true, @@ -1480,7 +1476,7 @@ defun_redefine: { (function() { return 3; }); - return 3 + 2; + return 5; } console.log(f()); } @@ -1517,7 +1513,7 @@ func_inline: { func_modified: { options = { - inline: true, + evaluate: true, reduce_funcs: true, reduce_vars: true, unused: true, @@ -1550,7 +1546,7 @@ func_modified: { (function() { return 4; }); - return 1 + 2 + 4; + return 7; } console.log(f()); } @@ -5516,9 +5512,7 @@ issue_2860_1: { }()); } expect: { - console.log(function(a) { - return 1 ^ a; - }()); + console.log(1); } expect_stdout: "1" } diff --git a/test/compress/typeof.js b/test/compress/typeof.js index 3b99521e..aae7405f 100644 --- a/test/compress/typeof.js +++ b/test/compress/typeof.js @@ -166,9 +166,7 @@ duplicate_lambda_arg_name: { }()); } expect: { - console.log(function long_name(long_name) { - return typeof long_name; - }()); + console.log("undefined"); } expect_stdout: "undefined" } -- 2.34.1