Repository: jlongster/prettier (js)

Issue:
Invalid trailing commas with rest as last argument
```js
[
  ...a
] = [];
```

outputs with trailing comma

```js
[
  ...a,
] = [];
```

which is invalid. We shouldn't output trailing commas when there's a rest argument at the end.

https://jlongster.github.io/prettier/#%7B%22content%22%3A%22%5B%5Cn%20%20...a%5Cn%5D%20%3D%20%5B%5D%3B%5Cn%22%2C%22options%22%3A%7B%22printWidth%22%3A0%2C%22tabWidth%22%3A2%2C%22singleQuote%22%3Afalse%2C%22trailingComma%22%3Atrue%2C%22bracketSpacing%22%3Atrue%2C%22doc%22%3Afalse%7D%7D

Pull request description:
Remove trailing comma for array destructuring with rest
Fixes #394

Patch:
diff --git a/src/printer.js b/src/printer.js
index 1f7f503d4..8b197e5b9 100644
--- a/src/printer.js
+++ b/src/printer.js
@@ -613,6 +613,9 @@ function genericPrintNoParens(path, options, print) {
       if (n.elements.length === 0) {
         parts.push("[]");
       } else {
+        const lastElem = util.getLast(n.elements);
+        const canHaveTrailingComma = !(lastElem && lastElem.type === "RestElement");
+
         // 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
@@ -623,7 +626,7 @@ function genericPrintNoParens(path, options, print) {
         //
         // 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;
+        const needsForcedTrailingComma = canHaveTrailingComma && lastElem === null;
 
         parts.push(
           multilineGroup(
@@ -637,7 +640,11 @@ function genericPrintNoParens(path, options, print) {
                 ])
               ),
               needsForcedTrailingComma ? "," : "",
-              ifBreak(!needsForcedTrailingComma && options.trailingComma ? "," : ""),
+              ifBreak(
+                canHaveTrailingComma &&
+                !needsForcedTrailingComma &&
+                options.trailingComma ? "," : ""
+              ),
               options.bracketSpacing ? line : softline,
               "]"
             ])


Test patch:
diff --git a/tests/rest/__snapshots__/jsfmt.spec.js.snap b/tests/rest/__snapshots__/jsfmt.spec.js.snap
index aaf012afd..362d5b2a6 100644
--- a/tests/rest/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/rest/__snapshots__/jsfmt.spec.js.snap
@@ -13,7 +13,9 @@ function f(
 
 declare class C { f(...superSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperLong): void; }
 
-[superSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperLong,,]
+[superSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperLong,,];
+
+[veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong, ...a] = [];
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 declare class C {
   f(
@@ -38,5 +40,10 @@ declare class C {
   superSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperLong,
   ,
 ];
+
+[
+  veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong,
+  ...a
+] = [];
 "
 `;
diff --git a/tests/rest/trailing-commas.js b/tests/rest/trailing-commas.js
index 8fabb7268..ab3e69284 100644
--- a/tests/rest/trailing-commas.js
+++ b/tests/rest/trailing-commas.js
@@ -12,4 +12,6 @@ function f(
 
 declare class C { f(...superSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperLong): void; }
 
-[superSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperLong,,]
+[superSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperLong,,];
+
+[veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLong, ...a] = [];