From e616916de5d28df06ae33bd4ed3b9431ae47d64b Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sun, 17 Jan 2021 17:47:07 +0000 Subject: [PATCH] fix corner case in `reduce_vars` (#4563) fixes #4562 --- lib/compress.js | 4 +-- test/compress/rests.js | 17 +++++++++++ .../reduce/destructured_catch.reduced.js | 8 ++--- test/reduce.js | 30 ++++++++++++------- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 6bbae0ff..d5334a95 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -620,7 +620,7 @@ merge(Compressor.prototype, { var save = fixed; if (save) fixed = function() { var value = save(); - return is_undefined(value) ? make_sequence(node, [ value, node.value ]) : node.name; + return is_undefined(value) ? make_sequence(node, [ value, node.value ]) : node; }; node.name.walk(scanner); fixed = save; @@ -646,7 +646,7 @@ merge(Compressor.prototype, { var value = save(); return value instanceof AST_Array ? make_node(AST_Array, node, { elements: value.elements.slice(node.elements.length), - }) : node.rest; + }) : node; }; node.rest.walk(scanner); } diff --git a/test/compress/rests.js b/test/compress/rests.js index 6bc5b756..017f871b 100644 --- a/test/compress/rests.js +++ b/test/compress/rests.js @@ -646,3 +646,20 @@ issue_4544_2: { expect_stdout: "PASS" node_version: ">=6" } + +issue_4562: { + options = { + evaluate: true, + reduce_vars: true, + rests: true, + unsafe: true, + } + input: { + console.log((([ ...[ a ] ]) => a)("foo")); + } + expect: { + console.log((([ a ]) => a)("foo")); + } + expect_stdout: "f" + node_version: ">=6" +} diff --git a/test/input/reduce/destructured_catch.reduced.js b/test/input/reduce/destructured_catch.reduced.js index c7a6736d..1979b99d 100644 --- a/test/input/reduce/destructured_catch.reduced.js +++ b/test/input/reduce/destructured_catch.reduced.js @@ -1,14 +1,12 @@ // (beautified) try { 1 in 0; -} catch ({ - message: message -}) { +} catch (message) { console.log(message); } -// output: Cannot use 'in' operator to search for '1' in 0 +// output: TypeError: Cannot use 'in' operator to search for '1' in 0 // -// minify: Cannot use 'in' operator to search for '0' in 0 +// minify: TypeError: Cannot use 'in' operator to search for '0' in 0 // // options: { // "mangle": false diff --git a/test/reduce.js b/test/reduce.js index 3f24b7b4..c478da5f 100644 --- a/test/reduce.js +++ b/test/reduce.js @@ -104,15 +104,14 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options) // quick ignores if (node instanceof U.AST_Accessor) return; - if (node instanceof U.AST_Destructured) return; if (node instanceof U.AST_Directive) return; if (!in_list && node instanceof U.AST_EmptyStatement) return; if (node instanceof U.AST_Label) return; if (node instanceof U.AST_LabelRef) return; - if (!in_list && node instanceof U.AST_SymbolDeclaration) return; if (node instanceof U.AST_Toplevel) return; var parent = tt.parent(); if (node instanceof U.AST_SymbolFunarg && parent instanceof U.AST_Accessor) return; + if (!in_list && parent.rest !== node && node instanceof U.AST_SymbolDeclaration) return; // ensure that the _permute prop is a number. // can not use `node.start._permute |= 0;` as it will erase fractional part. @@ -124,6 +123,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options) // ignore lvalues if (parent instanceof U.AST_Assign && parent.left === node) return; + if (parent instanceof U.AST_DefaultValue && parent.name === node) return; if (parent instanceof U.AST_DestructuredKeyVal && parent.value === node) return; if (parent instanceof U.AST_Unary && parent.expression === node) switch (parent.operator) { case "++": @@ -229,6 +229,23 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options) CHANGED = true; return node.name; } + else if (node instanceof U.AST_DestructuredArray) { + var expr = node.elements[0]; + if (expr && !(expr instanceof U.AST_Hole)) { + node.start._permute++; + CHANGED = true; + return expr; + } + } + else if (node instanceof U.AST_DestructuredObject) { + // first property's value + var expr = node.properties[0]; + if (expr) { + node.start._permute++; + CHANGED = true; + return expr.value; + } + } else if (node instanceof U.AST_Defun) { switch (((node.start._permute += step) * steps | 0) % 2) { case 0: @@ -443,15 +460,6 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options) CHANGED = true; return List.skip; } - - // skip element/property from (destructured) array/object - if (parent instanceof U.AST_Array - || parent instanceof U.AST_Destructured - || parent instanceof U.AST_Object) { - node.start._permute++; - CHANGED = true; - return List.skip; - } } else if (parent.rest === node) { node.start._permute++; CHANGED = true; -- 2.34.1