Repository: jlongster/prettier
Pull request #232 (2017-01-16 04:43:55)

Fix last element of an array being null
This appears in so many of the test262. https://gist.github.com/vjeux/9154b18c76892c958a71dbb123dde00c

vjeux: Added comment and using getLast

Patch:
diff --git a/src/fast-path.js b/src/fast-path.js
index dd4b2b55e..cc195dc92 100644
--- a/src/fast-path.js
+++ b/src/fast-path.js
@@ -366,6 +366,7 @@ FPp.needsParens = function(assumeExpressionContext) {
           return n.ObjectPattern.check(node.left) && this.firstInStatement();
       }
 
+    case "FunctionExpression":
     case "ArrowFunctionExpression":
       if (parent.type === "CallExpression" && name === "callee") {
         return true;
diff --git a/src/printer.js b/src/printer.js
index 8d1392974..62b5d7df5 100644
--- a/src/printer.js
+++ b/src/printer.js
@@ -641,6 +641,18 @@ function genericPrintNoParens(path, options, print) {
       if (n.elements.length === 0) {
         parts.push("[]");
       } else {
+        // JavaScript allows you to have empty elements in an array which
+        // changes its length based on the number of commas. The algorithm
+        // is that if the last argument is null, we need to force insert
+        // a comma to ensure JavaScript recognizes it.
+        //   [,].length === 1
+        //   [1,].length === 1
+        //   [1,,].length === 2
+        //
+        // Note that util.getLast returns null if the array is empty, but
+        // we already check for an empty array just above so we are safe
+        const needsForcedTrailingComma = util.getLast(n.elements) === null;
+
         parts.push(
           multilineGroup(
             concat([
@@ -652,6 +664,7 @@ function genericPrintNoParens(path, options, print) {
                   join(concat([ ",", line ]), path.map(print, "elements"))
                 ])
               ),
+              needsForcedTrailingComma ? "," : "",
               ifBreak(options.trailingComma ? "," : ""),
               options.bracketSpacing ? line : softline,
               "]"


Test patch:
diff --git a/tests/arrays/__snapshots__/jsfmt.spec.js.snap b/tests/arrays/__snapshots__/jsfmt.spec.js.snap
index 8b9f6b5ec..0dd5cc49b 100644
--- a/tests/arrays/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/arrays/__snapshots__/jsfmt.spec.js.snap
@@ -81,6 +81,19 @@ module.exports = \"arrays\";
 "
 `;
 
+exports[`test last.js 1`] = `
+"[,];
+[,,];
+[,,1,];
+[,,1,1];
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[ , ];
+[ , , ];
+[ , , 1 ];
+[ , , 1, 1 ];
+"
+`;
+
 exports[`test numeric_elem.js 1`] = `
 "var arr = [];
 var day = new Date;
diff --git a/tests/arrays/last.js b/tests/arrays/last.js
new file mode 100644
index 000000000..12af7b6a6
--- /dev/null
+++ b/tests/arrays/last.js
@@ -0,0 +1,4 @@
+[,];
+[,,];
+[,,1,];
+[,,1,1];
diff --git a/tests/arrows/__snapshots__/jsfmt.spec.js.snap b/tests/arrows/__snapshots__/jsfmt.spec.js.snap
index bf224ddd7..3e6449a4b 100644
--- a/tests/arrows/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/arrows/__snapshots__/jsfmt.spec.js.snap
@@ -28,11 +28,17 @@ var ident = <T>(x: T): T => x;
 exports[`test arrow_function_expression.js 1`] = `
 "(a => {}).length
 typeof (() => {});
+export default (() => {})();
+(() => {})()\`\`;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 (a => {
 }).length;
 typeof (() => {
 });
+export default (() => {
+})()
+(() => {
+})()\`\`;
 "
 `;
 
diff --git a/tests/arrows/arrow_function_expression.js b/tests/arrows/arrow_function_expression.js
index 57a6e9209..f0309346f 100644
--- a/tests/arrows/arrow_function_expression.js
+++ b/tests/arrows/arrow_function_expression.js
@@ -1,2 +1,4 @@
 (a => {}).length
 typeof (() => {});
+export default (() => {})();
+(() => {})()``;
diff --git a/tests/function/__snapshots__/jsfmt.spec.js.snap b/tests/function/__snapshots__/jsfmt.spec.js.snap
index e33bd50d5..a776342cc 100644
--- a/tests/function/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/function/__snapshots__/jsfmt.spec.js.snap
@@ -351,6 +351,23 @@ var e = (d.bind(1): Function)();
 "
 `;
 
+exports[`test function_expression.js 1`] = `
+"(function() {}).length
+typeof (function() {});
+export default (function() {})();
+(function() {})()\`\`;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+(function() {
+}).length;
+typeof (function() {
+});
+export default (function() {
+})()
+(function() {
+})()\`\`;
+"
+`;
+
 exports[`test rest.js 1`] = `
 "/* regression tests */
 
diff --git a/tests/function/function_expression.js b/tests/function/function_expression.js
new file mode 100644
index 000000000..786e8bdb5
--- /dev/null
+++ b/tests/function/function_expression.js
@@ -0,0 +1,4 @@
+(function() {}).length
+typeof (function() {});
+export default (function() {})();
+(function() {})()``;