diff --git a/lib/compress.js b/lib/compress.js index c7c1e5cf..3cd632c2 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -3166,47 +3166,45 @@ Compressor.prototype.compress = function(node) { return; } var end = hit_stack.length - 1; - if (hit_stack[end - 1].body === hit_stack[end]) end--; + var last = hit_stack[end]; + if (last instanceof AST_VarDef || hit_stack[end - 1].body === last) 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) { - declare_only.set(node.name.name, (declare_only.get(node.name.name) || 0) + 1); + if (node instanceof AST_Definitions) { + declare_only.set(last.name.name, (declare_only.get(last.name.name) || 0) + 1); if (value_def) value_def.replaced++; - node = node.clone(); - node.value = null; - return value ? List.splice([ value, node ]) : node; + var defns = node.definitions; + var index = defns.indexOf(last); + var defn = last.clone(); + defn.value = null; + if (!value) { + node = node.clone(); + node.definitions = defns.slice(); + node.definitions[index] = defn; + return node; + } + var body = [ + make_node(AST_SimpleStatement, value, { body: value }), + node.clone(), + ]; + body[1].definitions = defns.slice(index); + body[1].definitions[0] = defn; + if (index > 0) { + node = node.clone(); + node.definitions = defns.slice(0, index); + body.unshift(node); + } + return in_list ? List.splice(body) : make_node(AST_BlockStatement, node, { body: body }); } if (!value) return in_list ? List.skip : null; return is_statement(node) ? make_node(AST_SimpleStatement, value, { body: value }) : value; }, function(node, in_list) { - if (node instanceof AST_Definitions) { - var body = [], defns = node.definitions; - for (var index = 0, pos = 0; index < defns.length; index++) { - var defn = defns[index]; - if (defn instanceof AST_VarDef) continue; - flush(); - pos = index + 1; - body.push(make_node(AST_SimpleStatement, defn, { body: defn })); - } - if (pos == 0) return; - flush(); - if (body.length == 1) return body[0]; - return in_list ? List.splice(body) : make_node(AST_BlockStatement, node, { body: body }); - } if (node instanceof AST_For) return patch_for_init(node, in_list); - return patch_sequence(node, this); - - function flush() { - if (pos < index) { - var cropped = node.clone(); - cropped.definitions = defns.slice(pos, index); - body.push(cropped); - } - } + return patch_sequence(node, tt); }); abort = false; hit = false; diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index 379d8cb6..b16450d7 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -9947,3 +9947,35 @@ issue_5394: { } expect_stdout: "object" } + +issue_5396: { + options = { + collapse_vars: true, + merge_vars: true, + reduce_vars: true, + side_effects: true, + unused: true, + } + input: { + var a, b; + function f() {} + b = 0; + new function g(c) { + var d = a && g(e), e = ++d, i = [ 42 ]; + for (var j in i) + console.log("PASS"), + i; + }(); + } + expect: { + var a, b; + function f() {} + b = 0; + (function g(c) { + a && g(); + for (var j in [ 42 ]) + console.log("PASS"); + })(); + } + expect_stdout: "PASS" +}