From 076739db079306c103b8a6c45dde2371b25c64e4 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Fri, 11 Dec 2020 16:57:05 +0000 Subject: [PATCH] fix corner case in `unused` (#4362) fixes #4361 --- lib/compress.js | 50 ++++++++++++++++------------------------- test/compress/spread.js | 30 +++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 31 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index cb3351ac..1862fd10 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -4260,6 +4260,22 @@ merge(Compressor.prototype, { return map && map[prop]; }); + function spread_side_effects(exp) { + while ((exp = exp.tail_node()) instanceof AST_SymbolRef) { + exp = exp.fixed_value(); + if (!exp) return true; + } + return !(exp instanceof AST_Array + || exp.TYPE == "Binary" && !lazy_op[exp.operator] + || exp instanceof AST_Constant + || exp instanceof AST_Lambda + || exp instanceof AST_Object && all(exp.properties, function(prop) { + return !(prop instanceof AST_ObjectGetter || prop instanceof AST_Spread); + }) + || exp instanceof AST_This + || exp instanceof AST_Unary); + } + // determine if expression has side effects (function(def) { function any(list, compressor, spread) { @@ -4340,19 +4356,7 @@ merge(Compressor.prototype, { def(AST_Object, function(compressor) { return any(this.properties, compressor, function(node, compressor) { var exp = node.expression; - if (exp instanceof AST_Object) return true; - if (exp instanceof AST_PropAccess) return true; - if (exp instanceof AST_SymbolRef) { - exp = exp.fixed_value(); - if (!exp) return true; - if (exp instanceof AST_SymbolRef) return true; - if (exp instanceof AST_PropAccess) return true; - if (!(exp instanceof AST_Object)) return false; - return !all(exp.properties, function(prop) { - return !(prop instanceof AST_ObjectGetter || prop instanceof AST_Spread); - }); - } - return exp.has_side_effects(compressor); + return spread_side_effects(exp) || exp.has_side_effects(compressor); }); }); def(AST_ObjectProperty, function(compressor) { @@ -6459,24 +6463,8 @@ merge(Compressor.prototype, { } }); var values = trim(exprs, compressor, first_in_statement, function(node, compressor, first_in_statement) { - var exp = node.expression.tail_node(); - if (exp instanceof AST_SymbolRef) { - exp = exp.fixed_value(); - if (!exp) return node; - exp = exp.tail_node(); - } - if (exp instanceof AST_Array - || exp.TYPE == "Binary" && !lazy_op[exp.operator] - || exp instanceof AST_Constant - || exp instanceof AST_Lambda - || exp instanceof AST_Object && all(exp.properties, function(prop) { - return !(prop instanceof AST_ObjectGetter || prop instanceof AST_Spread); - }) - || exp instanceof AST_This - || exp instanceof AST_Unary) { - return node.expression.drop_side_effect_free(compressor, first_in_statement); - } - return node; + var exp = node.expression; + return spread_side_effects(exp) ? node : exp.drop_side_effect_free(compressor, first_in_statement); }); if (!values) return null; if (values === exprs && !all(values, function(node) { diff --git a/test/compress/spread.js b/test/compress/spread.js index 32ed0b86..8af7bffb 100644 --- a/test/compress/spread.js +++ b/test/compress/spread.js @@ -728,3 +728,33 @@ issue_4345: { expect_stdout: "PASS" node_version: ">=8" } + +issue_4361: { + options = { + reduce_vars: true, + unused: true, + } + input: { + console.log(function() { + var a = console.log("foo"); + console; + var b = { + ...a, + }; + }()); + } + expect: { + console.log(function() { + var a = console.log("foo"); + console; + ({ + ...a, + }); + }()); + } + expect_stdout: [ + "foo", + "undefined", + ] + node_version: ">=8" +} -- 2.34.1