From bb225367cbf427c6588a541c3936f94b67cbc1c5 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sat, 8 May 2021 19:59:45 +0100 Subject: [PATCH] fix corner case `collapse_vars` (#4921) fixes #4920 --- lib/compress.js | 50 +++++++++++++++++++--------------- test/compress/collapse_vars.js | 26 ++++++++++++++++++ 2 files changed, 54 insertions(+), 22 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index af9ff7e30b..3e8d894665 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -2446,6 +2446,25 @@ merge(Compressor.prototype, { return node; } + function find_stop_expr(expr, cont, node, parent, level) { + var replace = can_replace; + can_replace = false; + var after = stop_after; + var if_hit = stop_if_hit; + var stack = scanner.stack; + scanner.stack = [ parent ]; + expr.transform(scanner); + scanner.stack = stack; + stop_if_hit = if_hit; + stop_after = after; + can_replace = replace; + if (abort) { + abort = false; + return node; + } + return cont(parent, level + 1); + } + function find_stop_value(node, level) { var parent = scanner.parent(level); if (parent instanceof AST_Array) return find_stop_value(parent, level + 1); @@ -2497,7 +2516,11 @@ merge(Compressor.prototype, { return prop instanceof AST_ObjectKeyVal; }) ? find_stop_value(obj, level + 2) : obj; } - if (parent instanceof AST_PropAccess) return find_stop_value(parent, level + 1); + if (parent instanceof AST_PropAccess) { + var exp = parent.expression; + if (exp === node) return find_stop_value(parent, level + 1); + return find_stop_expr(exp, find_stop_value, node, parent, level); + } if (parent instanceof AST_Sequence) { return (parent.tail_node() === node ? find_stop_value : find_stop_unused)(parent, level + 1); } @@ -2546,7 +2569,7 @@ merge(Compressor.prototype, { if (parent instanceof AST_PropAccess) { var exp = parent.expression; if (exp === node) return find_stop_unused(parent, level + 1); - return check_expr(exp); + return find_stop_expr(exp, find_stop_unused, node, parent, level); } if (parent instanceof AST_Sequence) return find_stop_unused(parent, level + 1); if (parent instanceof AST_SimpleStatement) return find_stop_unused(parent, level + 1); @@ -2557,28 +2580,11 @@ merge(Compressor.prototype, { if (parent instanceof AST_Yield) return node; return null; - function check_expr(expr) { - var replace = can_replace; - can_replace = false; - var after = stop_after; - var if_hit = stop_if_hit; - var stack = scanner.stack; - scanner.stack = [ parent ]; - expr.transform(scanner); - scanner.stack = stack; - stop_if_hit = if_hit; - stop_after = after; - can_replace = replace; - if (abort) { - abort = false; - return node; - } - return find_stop_unused(parent, level + 1); - } - function check_assignment(lhs) { if (may_throw(parent)) return node; - if (lhs !== node && lhs instanceof AST_Destructured) return check_expr(lhs); + if (lhs !== node && lhs instanceof AST_Destructured) { + return find_stop_expr(lhs, find_stop_unused, node, parent, level); + } return find_stop_unused(parent, level + 1); } } diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index e0c139bd4c..be13cff8c3 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -9194,3 +9194,29 @@ issue_4918: { } expect_stdout: "PASS" } + +issue_4920: { + options = { + collapse_vars: true, + toplevel: true, + } + input: { + var a = "PASS", b; + ({ + get PASS() { + a = "FAIL"; + }, + })[b = a]; + console.log(b); + } + expect: { + var a = "PASS", b; + ({ + get PASS() { + a = "FAIL"; + }, + })[b = a]; + console.log(b); + } + expect_stdout: "PASS" +}