From: Alex Lam S.L Date: Fri, 27 Jul 2018 11:34:44 +0000 (+0800) Subject: fix corner case in `join_vars` (#3224) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=d47547dc71a7e0ba717348995a02a0703ef8f149;p=UglifyJS.git fix corner case in `join_vars` (#3224) --- diff --git a/lib/compress.js b/lib/compress.js index ca868a92..4675b1cc 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -2000,7 +2000,7 @@ merge(Compressor.prototype, { statements.length = n; } - function join_object_assignments(defn, body) { + function join_assigns(defn, body) { var exprs; if (body instanceof AST_Assign) { exprs = [ body ]; @@ -2010,7 +2010,7 @@ merge(Compressor.prototype, { if (!exprs) return; if (defn instanceof AST_Definitions) { var def = defn.definitions[defn.definitions.length - 1]; - if (trim_object_assignments(def.name, def.value, exprs)) return exprs; + if (trim_assigns(def.name, def.value, exprs)) return exprs; } for (var i = exprs.length - 1; --i >= 0;) { var expr = exprs[i]; @@ -2018,12 +2018,12 @@ merge(Compressor.prototype, { if (expr.operator != "=") continue; if (!(expr.left instanceof AST_SymbolRef)) continue; var tail = exprs.slice(i + 1); - if (!trim_object_assignments(expr.left, expr.right, tail)) continue; + if (!trim_assigns(expr.left, expr.right, tail)) continue; return exprs.slice(0, i + 1).concat(tail); } } - function trim_object_assignments(name, value, exprs) { + function trim_assigns(name, value, exprs) { if (!(value instanceof AST_Object)) return; var trimmed = false; do { @@ -2074,9 +2074,9 @@ merge(Compressor.prototype, { defs = stat; } } else if (stat instanceof AST_Exit) { - stat.value = extract_object_assignments(stat.value); + stat.value = join_assigns_expr(stat.value); } else if (stat instanceof AST_For) { - var exprs = join_object_assignments(prev, stat.init); + var exprs = join_assigns(prev, stat.init); if (exprs) { CHANGED = true; stat.init = exprs.length ? make_sequence(stat.init, exprs) : null; @@ -2097,11 +2097,11 @@ merge(Compressor.prototype, { statements[++j] = stat; } } else if (stat instanceof AST_ForIn) { - stat.object = extract_object_assignments(stat.object); + stat.object = join_assigns_expr(stat.object); } else if (stat instanceof AST_If) { - stat.condition = extract_object_assignments(stat.condition); + stat.condition = join_assigns_expr(stat.condition); } else if (stat instanceof AST_SimpleStatement) { - var exprs = join_object_assignments(prev, stat.body); + var exprs = join_assigns(prev, stat.body); if (exprs) { CHANGED = true; if (!exprs.length) continue; @@ -2109,29 +2109,23 @@ merge(Compressor.prototype, { } statements[++j] = stat; } else if (stat instanceof AST_Switch) { - stat.expression = extract_object_assignments(stat.expression); + stat.expression = join_assigns_expr(stat.expression); } else if (stat instanceof AST_With) { - stat.expression = extract_object_assignments(stat.expression); + stat.expression = join_assigns_expr(stat.expression); } else { statements[++j] = stat; } } statements.length = j + 1; - function extract_object_assignments(value) { + function join_assigns_expr(value) { statements[++j] = stat; - var exprs = join_object_assignments(prev, value); - if (exprs) { - CHANGED = true; - if (exprs.length) { - return make_sequence(value, exprs); - } else if (value instanceof AST_Sequence) { - return value.tail_node().left; - } else { - return value.left; - } - } - return value; + var exprs = join_assigns(prev, value); + if (!exprs) return value; + CHANGED = true; + var tail = value.tail_node(); + if (exprs[exprs.length - 1] !== tail) exprs.push(tail.left); + return make_sequence(value, exprs); } } } diff --git a/test/compress/properties.js b/test/compress/properties.js index d36ae074..3a78d626 100644 --- a/test/compress/properties.js +++ b/test/compress/properties.js @@ -1832,3 +1832,33 @@ issue_3188_3: { } expect_stdout: "PASS" } + +join_expr: { + options = { + evaluate: true, + join_vars: true, + } + input: { + var c = "FAIL"; + (function() { + var a = 0; + switch ((a = {}) && (a.b = 0)) { + case 0: + c = "PASS"; + } + })(); + console.log(c); + } + expect: { + var c = "FAIL"; + (function() { + var a = 0; + switch (a = { b: 0 }, a.b) { + case 0: + c = "PASS"; + } + })(); + console.log(c); + } + expect_stdout: "PASS" +}