diff --git a/lib/compress.js b/lib/compress.js index c34c76301e..f7c0af30e9 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1200,7 +1200,7 @@ merge(Compressor.prototype, { if (!hit) { if (node !== hit_stack[hit_index]) return node; hit_index++; - if (hit_index < hit_stack.length) return handle_custom_scan_order(node); + if (hit_index < hit_stack.length) return handle_custom_scan_order(node, scanner); hit = true; stop_after = (value_def ? find_stop_value : find_stop)(node, 0); if (stop_after === node) abort = true; @@ -1279,7 +1279,7 @@ merge(Compressor.prototype, { can_replace = replace; return node; } - return handle_custom_scan_order(node); + return handle_custom_scan_order(node, scanner); }, function(node) { if (abort) return; if (stop_after === node) abort = true; @@ -1398,12 +1398,12 @@ merge(Compressor.prototype, { } } - function handle_custom_scan_order(node) { + function handle_custom_scan_order(node, tt) { // Skip (non-executed) functions if (node instanceof AST_Scope) return node; // Scan case expressions first in a switch statement if (node instanceof AST_Switch) { - node.expression = node.expression.transform(scanner); + node.expression = node.expression.transform(tt); for (var i = 0; !abort && i < node.body.length; i++) { var branch = node.body[i]; if (branch instanceof AST_Case) { @@ -1411,7 +1411,7 @@ merge(Compressor.prototype, { if (branch !== hit_stack[hit_index]) continue; hit_index++; } - branch.expression = branch.expression.transform(scanner); + branch.expression = branch.expression.transform(tt); if (!replace_all) break; scan_rhs = false; } @@ -1930,12 +1930,14 @@ merge(Compressor.prototype, { }); return true; } - var found = false; - return statements[stat_index].transform(new TreeTransformer(function(node, descend, in_list) { - if (found) return node; - if (node instanceof AST_Scope) return node; - if (node !== expr && node.body !== expr) return; - found = true; + var end = hit_stack.length - 1; + if (hit_stack[end - 1].body === hit_stack[end]) end--; + var tt = new TreeTransformer(function(node, descend, in_list) { + if (hit) return node; + if (node !== hit_stack[hit_index]) return node; + hit_index++; + if (hit_index <= end) return handle_custom_scan_order(node, tt); + hit = true; if (node instanceof AST_VarDef) { node.value = null; declare_only[node.name.name] = (declare_only[node.name.name] || 0) + 1; @@ -1943,7 +1945,11 @@ merge(Compressor.prototype, { return node; } return in_list ? List.skip : null; - }, patch_sequence)); + }, patch_sequence); + abort = false; + hit = false; + hit_index = 0; + return statements[stat_index].transform(tt); } function patch_sequence(node) { diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index ff0837a2ec..dee370cf36 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -7979,3 +7979,39 @@ issue_3884: { } expect_stdout: "101 32" } + +issue_3891: { + options = { + collapse_vars: true, + passes: 2, + reduce_vars: true, + side_effects: true, + unused: true, + } + input: { + function log(a) { + console.log(typeof a); + } + log(function f() { + try { + do { + var b = function() {}(); + } while (f = 0, b.p); + } catch (e) { + var f; + b; + } + }); + } + expect: { + function log(a) { + console.log(typeof a); + } + log(function() { + try { + do {} while ((void 0).p); + } catch (e) {} + }); + } + expect_stdout: "function" +}