From 3ff625de7e3d381de43b4703faae402381844c9f Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Wed, 27 Dec 2017 05:31:37 +0800 Subject: [PATCH] fix bugs on substituted `AST_Defun` (#2661) fixes #2660 --- lib/compress.js | 18 ++++++------ test/compress/drop-unused.js | 54 ++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index d890caf7..4a2a436b 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -3685,8 +3685,9 @@ merge(Compressor.prototype, { if (compressor.option("reduce_vars") && fn instanceof AST_SymbolRef) { fn = fn.fixed_value(); } + var is_func = fn instanceof AST_Lambda; if (compressor.option("unused") - && fn instanceof AST_Function + && is_func && !fn.uses_arguments && !fn.uses_eval) { var pos = 0, last = 0; @@ -3855,7 +3856,7 @@ merge(Compressor.prototype, { if (func instanceof AST_SymbolRef) { func = func.fixed_value(); } - if (func instanceof AST_Function && !func.contains_this()) { + if (func instanceof AST_Lambda && !func.contains_this()) { return make_sequence(this, [ self.args[0], make_node(AST_Call, self, { @@ -3925,7 +3926,7 @@ merge(Compressor.prototype, { } } } - var stat = fn instanceof AST_Function && fn.body[0]; + var stat = is_func && fn.body[0]; if (compressor.option("inline") && stat instanceof AST_Return) { var value = stat.value; if (!value || value.is_constant_expression()) { @@ -3933,7 +3934,7 @@ merge(Compressor.prototype, { return make_sequence(self, args).optimize(compressor); } } - if (fn instanceof AST_Function) { + if (is_func) { var def, value, scope, level = -1; if (compressor.option("inline") && !fn.uses_arguments @@ -4670,11 +4671,8 @@ merge(Compressor.prototype, { && is_lhs(self, compressor.parent()) !== self) { var d = self.definition(); var fixed = self.fixed_value(); - if (fixed instanceof AST_Defun) { - d.fixed = fixed = make_node(AST_Function, fixed, fixed); - } var single_use = d.single_use; - if (single_use && fixed instanceof AST_Function) { + if (single_use && fixed instanceof AST_Lambda) { if (d.scope !== self.scope && (!compressor.option("reduce_funcs") || d.escaped == 1 @@ -4695,6 +4693,9 @@ merge(Compressor.prototype, { } } if (single_use && fixed) { + if (fixed instanceof AST_Defun) { + fixed = make_node(AST_Function, fixed, fixed); + } var value; if (d.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) { value = fixed.clone(true); @@ -4705,6 +4706,7 @@ merge(Compressor.prototype, { value.walk(new TreeWalker(function(node) { if (node instanceof AST_SymbolRef && node.definition() === defun_def) { node.thedef = lambda_def; + lambda_def.references.push(node); } })); } else { diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js index 90206ec6..714e1d16 100644 --- a/test/compress/drop-unused.js +++ b/test/compress/drop-unused.js @@ -1434,3 +1434,57 @@ defun_lambda_same_name: { } expect_stdout: "120" } + +issue_2660_1: { + options = { + reduce_vars: true, + side_effects: true, + toplevel: true, + unused: true, + } + input: { + var a = 2; + function f(b) { + return b && f() || a--; + } + f(1); + console.log(a); + } + expect: { + var a = 2; + (function f(b) { + return b && f() || a--; + })(1); + console.log(a); + } + expect_stdout: "1" +} + +issue_2660_2: { + options = { + collapse_vars: true, + reduce_vars: true, + sequences: true, + side_effects: true, + toplevel: true, + unused: true, + } + input: { + var a = 1; + function f(b) { + b && f(); + --a, a.toString(); + } + f(); + console.log(a); + } + expect: { + var a = 1; + (function f(b) { + b && f(), + (--a).toString(); + })(), + console.log(a); + } + expect_stdout: "0" +} -- 2.34.1