diff --git a/lib/compress.js b/lib/compress.js index aa97b13c..8a6a5f25 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -4996,7 +4996,7 @@ merge(Compressor.prototype, { && prop instanceof AST_Number && expr instanceof AST_Array) { var index = prop.getValue(); var elements = expr.elements; - if (index in elements) { + FLATTEN: if (index in elements) { var flatten = true; var values = []; for (var i = elements.length; --i > index;) { @@ -5007,10 +5007,13 @@ merge(Compressor.prototype, { } } var retValue = elements[index]; + if (retValue instanceof AST_Expansion) break FLATTEN; retValue = retValue instanceof AST_Hole ? make_node(AST_Undefined, retValue) : retValue; if (!flatten) values.unshift(retValue); while (--i >= 0) { - var value = elements[i].drop_side_effect_free(compressor); + var value = elements[i]; + if (value instanceof AST_Expansion) break FLATTEN; + value = value.drop_side_effect_free(compressor); if (value) values.unshift(value); else index--; } diff --git a/test/compress/harmony.js b/test/compress/harmony.js index 11b36b2d..ded16f09 100644 --- a/test/compress/harmony.js +++ b/test/compress/harmony.js @@ -975,3 +975,180 @@ shorthand_keywords: { expect_stdout: true node_version: ">=4" } + +array_literal_with_spread_1: { + options = { + properties: true, + side_effects: true, + } + input: { + var f = (x) => [...x][0]; + console.log(f(["PASS"])); + } + expect: { + var f = x => [ ...x ][0]; + console.log(f([ "PASS" ])); + } + expect_stdout: "PASS" + node_version: ">=6" +} + +array_literal_with_spread_2: { + options = { + properties: true, + side_effects: true, + } + input: { + console.log([10, ...[], 20, ...[30, 40], 50]["length"]); + console.log([10, ...[], 20, ...[30, 40], 50][0]); + console.log([10, ...[], 20, ...[30, 40], 50][1]); + console.log([10, ...[], 20, ...[30, 40], 50][2]); + console.log([10, ...[], 20, ...[30, 40], 50][3]); + console.log([10, ...[], 20, ...[30, 40], 50][4]); + console.log([10, ...[], 20, ...[30, 40], 50][5]); + } + expect: { + console.log([ 10, ...[], 20, ...[ 30, 40 ], 50 ]["length"]); + console.log(10); + console.log([ 10, ...[], 20, ...[ 30, 40 ], 50 ][1]); + console.log([ 10, ...[], 20, ...[ 30, 40 ], 50 ][2]); + console.log([ 10, ...[], 20, ...[ 30, 40 ], 50 ][3]); + console.log([ 10, ...[], 20, ...[ 30, 40 ], 50 ][4]); + console.log([ 10, ...[], 20, ...[ 30, 40 ], 50 ][5]); + } + expect_stdout: [ + "5", + "10", + "20", + "30", + "40", + "50", + "undefined", + ] + node_version: ">=6" +} + +array_literal_with_spread_3: { + options = { + properties: true, + side_effects: true, + } + input: { + console.log([10, 20][0]); + console.log([10, 20][1]); + console.log([10, 20][2]); + + console.log([...[], 10, 20][0]); + console.log([...[], 10, 20][1]); + console.log([...[], 10, 20][2]); + + console.log([10, ...[], 20][0]); + console.log([10, ...[], 20][1]); + console.log([10, ...[], 20][2]); + + console.log([10, 20, ...[]][0]); + console.log([10, 20, ...[]][1]); + console.log([10, 20, ...[]][2]); + } + expect: { + console.log(10); + console.log(20); + console.log([ 10, 20 ][2]); + + console.log([...[], 10, 20][0]); + console.log([...[], 10, 20][1]); + console.log([...[], 10, 20][2]); + + console.log(10); + console.log([10, ...[], 20][1]); + console.log([10, ...[], 20][2]); + + console.log(10); + console.log(20); + console.log([10, 20, ...[]][2]); + } + expect_stdout: [ + "10", + "20", + "undefined", + "10", + "20", + "undefined", + "10", + "20", + "undefined", + "10", + "20", + "undefined", + ] + node_version: ">=6" +} + +array_literal_with_spread_4: { + options = { + properties: true, + side_effects: true, + } + input: { + function t(x) { + console.log("(" + x + ")"); + return 10 * x; + } + + console.log([t(1), t(2)][0]); + console.log([t(1), t(2)][1]); + console.log([t(1), t(2)][2]); + + console.log([...[], t(1), t(2)][0]); + console.log([...[], t(1), t(2)][1]); + console.log([...[], t(1), t(2)][2]); + + console.log([t(1), ...[], t(2)][0]); + console.log([t(1), ...[], t(2)][1]); + console.log([t(1), ...[], t(2)][2]); + + console.log([t(1), t(2), ...[]][0]); + console.log([t(1), t(2), ...[]][1]); + console.log([t(1), t(2), ...[]][2]); + } + expect: { + function t(x) { + console.log("(" + x + ")"); + return 10 * x; + } + + console.log([ t(1), t(2) ][0]); + console.log((t(1), t(2))); + console.log([ t(1), t(2) ][2]); + + console.log([ ...[], t(1), t(2) ][0]); + console.log([ ...[], t(1), t(2) ][1]); + console.log([ ...[], t(1), t(2) ][2]); + + console.log([ t(1), t(2) ][0]); + console.log([ t(1), ...[], t(2) ][1]); + console.log([ t(1), ...[], t(2) ][2]); + + console.log([ t(1), t(2) ][0]); + console.log((t(1), t(2))); + console.log([ t(1), t(2), ...[] ][2]); + } + expect_stdout: [ + "(1)", "(2)", "10", + "(1)", "(2)", "20", + "(1)", "(2)", "undefined", + + "(1)", "(2)", "10", + "(1)", "(2)", "20", + "(1)", "(2)", "undefined", + + "(1)", "(2)", "10", + "(1)", "(2)", "20", + "(1)", "(2)", "undefined", + + "(1)", "(2)", "10", + "(1)", "(2)", "20", + "(1)", "(2)", "undefined", + ] + node_version: ">=6" +}