diff --git a/lib/compress.js b/lib/compress.js index 98661c765f7..d1b0fab9141 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -4222,16 +4222,48 @@ Compressor.prototype.compress = function(node) { if (value.left instanceof AST_SymbolRef) names.set(value.left.name, true); value = value.right; } - if (!(value instanceof AST_Object)) return; - var trimmed = false; - do { - if (!try_join(exprs[0])) break; - exprs.shift(); - trimmed = true; - } while (exprs.length); - return trimmed; + if (value instanceof AST_Array) { + var trimmed = false; + do { + if (!try_join_array(exprs[0])) break; + exprs.shift(); + trimmed = true; + } while (exprs.length); + return trimmed; + } else if (value instanceof AST_Object) { + var trimmed = false; + do { + if (!try_join_object(exprs[0])) break; + exprs.shift(); + trimmed = true; + } while (exprs.length); + return trimmed; + } + + function try_join_array(node) { + if (!(node instanceof AST_Assign)) return; + if (node.operator != "=") return; + if (!(node.left instanceof AST_PropAccess)) return; + var sym = node.left.expression; + if (!(sym instanceof AST_SymbolRef)) return; + if (!names.has(sym.name)) return; + if (!node.right.is_constant_expression(scope)) return; + var prop = node.left.property; + if (prop instanceof AST_Node) { + if (try_join_array(prop)) prop = node.left.property = prop.right.clone(); + prop = prop.evaluate(compressor); + } + if (prop instanceof AST_Node) return; + if (!RE_POSITIVE_INTEGER.test("" + prop)) return; + prop = +prop; + var len = value.elements.length; + if (prop > len + 4) return; + while (len < prop) value.elements[len++] = make_node(AST_Hole, value); + value.elements[prop] = node.right; + return true; + } - function try_join(node) { + function try_join_object(node) { if (!(node instanceof AST_Assign)) return; if (node.operator != "=") return; if (!(node.left instanceof AST_PropAccess)) return; @@ -4241,7 +4273,7 @@ Compressor.prototype.compress = function(node) { if (!node.right.is_constant_expression(scope)) return; var prop = node.left.property; if (prop instanceof AST_Node) { - if (try_join(prop)) prop = node.left.property = prop.right.clone(); + if (try_join_object(prop)) prop = node.left.property = prop.right.clone(); prop = prop.evaluate(compressor); } if (prop instanceof AST_Node) return; diff --git a/test/compress/join_vars.js b/test/compress/join_vars.js index 8e4445ec3a5..87b0371e5ad 100644 --- a/test/compress/join_vars.js +++ b/test/compress/join_vars.js @@ -16,6 +16,104 @@ join_vars_assign: { expect_stdout: "PASS" } +join_array_assignments_1: { + options = { + evaluate: true, + join_vars: true, + } + input: { + console.log(function () { + var a = ["foo", , "bar"]; + a[1] = "baz"; + a[7] = "moo"; + a[0] = "moz"; + return a; + }().join()); + } + expect: { + console.log(function () { + var a = ["moz", "baz", "bar", , , , , "moo"]; + return a; + }().join()); + } + expect_stdout: "moz,baz,bar,,,,,moo" +} + +join_array_assignments_2: { + options = { + evaluate: true, + join_vars: true, + } + input: { + console.log(function () { + var a = ["foo"]; + a[1] = "bar"; + a[7] = "baz"; + a[2] = "moo"; + return a; + }().join()); + } + expect: { + console.log(function () { + var a = ["foo", "bar"]; + a[7] = "baz"; + a[2] = "moo"; + return a; + }().join()); + } + expect_stdout: "foo,bar,moo,,,,,baz" +} + +join_array_assignments_3: { + options = { + evaluate: true, + join_vars: true, + } + input: { + console.log(function () { + var a = ["foo"]; + a[1] = "bar"; + a.b = "baz"; + a[2] = "moo"; + return a; + }().join()); + } + expect: { + console.log(function () { + var a = ["foo", "bar"]; + a.b = "baz"; + a[2] = "moo"; + return a; + }().join()); + } + expect_stdout: true +} + +join_array_assignments_4: { + options = { + evaluate: true, + join_vars: true, + } + input: { + console.log(function () { + var a = ["foo"]; + a[0] = "bar"; + a[1] = a; + a[2] = "baz"; + return a; + }().join()); + } + expect: { + console.log(function () { + var a = ["bar"]; + a[1] = a; + a[2] = "baz"; + return a; + }().join()); + } + expect_stdout: true +} + join_object_assignments_1: { options = { evaluate: true,