From d75a946707f6f721b69d046f607426d5a3c6f8db Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sun, 3 Apr 2022 14:57:37 +0100 Subject: [PATCH] fix corner case in `reduce_vars` (#5406) fixes #5405 --- lib/compress.js | 36 +++++++++++++++++++++------------ test/compress/destructured.js | 38 +++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 1998311f..918366e2 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -751,6 +751,18 @@ Compressor.prototype.compress = function(node) { }); } + function make_fixed(save, fn) { + var prev_save, prev_value; + return function() { + var current = save(); + if (prev_save !== current) { + prev_save = current; + prev_value = fn(current); + } + return prev_value; + }; + } + function scan_declaration(tw, compressor, lhs, fixed, visit) { var scanner = new TreeWalker(function(node) { if (node instanceof AST_DefaultValue) { @@ -759,15 +771,14 @@ Compressor.prototype.compress = function(node) { node.value.walk(tw); pop(tw); var save = fixed; - if (save) fixed = function() { - var value = save(); + if (save) fixed = make_fixed(save, function(value) { var ev; if (is_undefined(value, compressor) || (ev = fuzzy_eval(compressor, value, true)) === undefined) { return make_sequence(node, [ value, node.value ]); } return ev instanceof AST_Node ? node : value; - }; + }); node.name.walk(scanner); fixed = save; return true; @@ -777,18 +788,17 @@ Compressor.prototype.compress = function(node) { var save = fixed; node.elements.forEach(function(node, index) { if (node instanceof AST_Hole) return reset_flags(node); - if (save) fixed = function() { + if (save) fixed = make_fixed(save, function(value) { return make_node(AST_Sub, node, { - expression: save(), + expression: value, property: make_node(AST_Number, node, { value: index }), }); - }; + }); node.walk(scanner); }); if (node.rest) { var fixed_node; - if (save) fixed = compressor.option("rests") && function() { - var value = save(); + if (save) fixed = compressor.option("rests") && make_fixed(save, function(value) { if (!(value instanceof AST_Array)) return node; for (var i = 0, len = node.elements.length; i < len; i++) { if (value.elements[i] instanceof AST_Spread) return node; @@ -796,7 +806,7 @@ Compressor.prototype.compress = function(node) { if (!fixed_node) fixed_node = make_node(AST_Array, node); fixed_node.elements = value.elements.slice(len); return fixed_node; - }; + }); node.rest.walk(scanner); } fixed = save; @@ -812,7 +822,7 @@ Compressor.prototype.compress = function(node) { node.key.walk(tw); pop(tw); } - if (save) fixed = function() { + if (save) fixed = make_fixed(save, function(value) { var key = node.key; var type = AST_Sub; if (typeof key == "string") { @@ -823,10 +833,10 @@ Compressor.prototype.compress = function(node) { } } return make_node(type, node, { - expression: save(), - property: key + expression: value, + property: key, }); - }; + }); node.value.walk(scanner); }); if (node.rest) { diff --git a/test/compress/destructured.js b/test/compress/destructured.js index 7850d516..9a06c35b 100644 --- a/test/compress/destructured.js +++ b/test/compress/destructured.js @@ -3497,3 +3497,41 @@ issue_5370: { expect_stdout: true node_version: ">=6" } + +issue_5405_1: { + options = { + evaluate: true, + reduce_vars: true, + toplevel: true, + unsafe: true, + } + input: { + var [ a ] = [ {} ]; + console.log(a === a ? "PASS" : "FAIL"); + } + expect: { + var [ a ] = [ {} ]; + console.log(true ? "PASS" : "FAIL"); + } + expect_stdout: "PASS" + node_version: ">=6" +} + +issue_5405_2: { + options = { + evaluate: true, + reduce_vars: true, + toplevel: true, + unsafe: true, + } + input: { + var { p: a } = { p: [] }; + console.log(a === a ? "PASS" : "FAIL"); + } + expect: { + var { p: a } = { p: [] }; + console.log(true ? "PASS" : "FAIL"); + } + expect_stdout: "PASS" + node_version: ">=6" +}