Repository: jlongster/prettier
Pull request #742 (2017-02-19 22:15:10)

Fix missing dangling comments in for loop
This should solve #697.


Patch:
diff --git a/src/fast-path.js b/src/fast-path.js
index 84afe6be3..f98277420 100644
--- a/src/fast-path.js
+++ b/src/fast-path.js
@@ -354,12 +354,14 @@ FPp.needsParens = function(assumeExpressionContext) {
       }
 
     case "YieldExpression":
+      if (parent.type === "UnaryExpression") {
+        return true;
+      }
     case "AwaitExpression":
       switch (parent.type) {
         case "TaggedTemplateExpression":
         case "BinaryExpression":
         case "LogicalExpression":
-        case "UnaryExpression":
         case "SpreadElement":
         case "SpreadProperty":
         case "NewExpression":
@@ -419,6 +421,7 @@ FPp.needsParens = function(assumeExpressionContext) {
         case "LogicalExpression":
         case "NewExpression":
         case "ExportDefaultDeclaration":
+        case "AwaitExpression":
           return true;
 
         case "CallExpression":
diff --git a/src/printer.js b/src/printer.js
index 80b59eb91..a4e368cb7 100644
--- a/src/printer.js
+++ b/src/printer.js
@@ -814,6 +814,7 @@ function genericPrintNoParens(path, options, print) {
                   ? ","
                   : ""
               ),
+              comments.printDanglingComments(path, options, /* sameIndent */ true),
               softline,
               "]"
             ])
@@ -988,11 +989,15 @@ function genericPrintNoParens(path, options, print) {
     case "ForStatement": {
       const body = adjustClause(path.call(print, "body"), options);
 
+      const dangling = comments.printDanglingComments(path, options, /* sameLine */ true);
+      const printedComments = dangling ? concat([dangling, softline]) : "";
+
       if (!n.init && !n.test && !n.update) {
-        return concat(["for (;;)", body]);
+        return concat([printedComments, "for (;;)", body]);
       }
 
       return concat([
+        printedComments,
         "for (",
         group(
           concat([
@@ -2025,6 +2030,8 @@ function printExportDeclaration(path, options, print) {
     parts.push("default ");
   }
 
+  parts.push(comments.printDanglingComments(path, options, /* sameIndent */ true));
+
   if (decl.declaration) {
     parts.push(path.call(print, "declaration"));
 


Test patch:
diff --git a/tests/async/__snapshots__/jsfmt.spec.js.snap b/tests/async/__snapshots__/jsfmt.spec.js.snap
index 208c7fca7..5f48fac00 100644
--- a/tests/async/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/async/__snapshots__/jsfmt.spec.js.snap
@@ -4,13 +4,26 @@ async function g() {
   invariant(
     (await driver.navigator.getUrl()).substr(-7)
   );
-}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+}
+function *f(){
+  !(yield a);
+}
+async function f() {
+  a = !(await f());
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 async function f() {
   (await f()).length;
 }
 async function g() {
   invariant((await driver.navigator.getUrl()).substr(-7));
 }
+function* f() {
+  !(yield a);
+}
+async function f() {
+  a = !await f();
+}
 "
 `;
 
@@ -18,9 +31,19 @@ exports[`test conditional-expression.js 1`] = `
 "async function f() {
   const result = typeof fn === \'function\' ? await fn() : null;
 }
+
+(async function() {
+  console.log(
+    await (true ? Promise.resolve(\"A\") : Promise.resolve(\"B\"))
+  );
+})()
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 async function f() {
   const result = typeof fn === \"function\" ? await fn() : null;
 }
+
+(async function() {
+  console.log(await (true ? Promise.resolve(\"A\") : Promise.resolve(\"B\")));
+})();
 "
 `;
diff --git a/tests/async/await_parse.js b/tests/async/await_parse.js
index 96ebb82e5..dd2de424b 100644
--- a/tests/async/await_parse.js
+++ b/tests/async/await_parse.js
@@ -3,4 +3,10 @@ async function g() {
   invariant(
     (await driver.navigator.getUrl()).substr(-7)
   );
-}
\ No newline at end of file
+}
+function *f(){
+  !(yield a);
+}
+async function f() {
+  a = !(await f());
+}
diff --git a/tests/async/conditional-expression.js b/tests/async/conditional-expression.js
index 532c66d6a..73d846394 100644
--- a/tests/async/conditional-expression.js
+++ b/tests/async/conditional-expression.js
@@ -1,3 +1,9 @@
 async function f() {
   const result = typeof fn === 'function' ? await fn() : null;
 }
+
+(async function() {
+  console.log(
+    await (true ? Promise.resolve("A") : Promise.resolve("B"))
+  );
+})()
diff --git a/tests/comments/__snapshots__/jsfmt.spec.js.snap b/tests/comments/__snapshots__/jsfmt.spec.js.snap
index d70983ab8..89f716961 100644
--- a/tests/comments/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/comments/__snapshots__/jsfmt.spec.js.snap
@@ -38,6 +38,7 @@ function x() {
   /* dangling */
 }
 declare class Foo extends Qux<string> {/* dangling */}
+export /* dangling */{};
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 var x = {
   /* dangling */
@@ -54,6 +55,7 @@ function x() {
 declare class Foo extends Qux<string> {
   /* dangling */
 }
+export /* dangling */{};
 "
 `;
 
@@ -67,6 +69,7 @@ function x() {
   /* dangling */
 }
 declare class Foo extends Qux<string> {/* dangling */}
+export /* dangling */{};
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 var x = {
   /* dangling */
@@ -83,6 +86,7 @@ function x() {
 declare class Foo extends Qux<string> {
   /* dangling */
 }
+export /* dangling */{};
 "
 `;
 
@@ -90,12 +94,16 @@ exports[`test dangling_array.js 1`] = `
 "expect(() => {}).toTriggerReadyStateChanges([
   // Nothing.
 ]);
+
+[1 /* first comment */, 2 /* second comment */, 3];
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 expect(() => {}).toTriggerReadyStateChanges(
   [
     // Nothing.
   ]
 );
+
+[1 /* first comment */, 2 /* second comment */, 3];
 "
 `;
 
@@ -103,12 +111,44 @@ exports[`test dangling_array.js 2`] = `
 "expect(() => {}).toTriggerReadyStateChanges([
   // Nothing.
 ]);
+
+[1 /* first comment */, 2 /* second comment */, 3];
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 expect(() => {}).toTriggerReadyStateChanges(
   [
     // Nothing.
   ]
 );
+
+[1 /* first comment */, 2 /* second comment */, 3];
+"
+`;
+
+exports[`test dangling_for.js 1`] = `
+"for // comment
+(;;);
+
+for /* comment */(;;);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// comment
+for (;;);
+
+/* comment */
+for (;;);
+"
+`;
+
+exports[`test dangling_for.js 2`] = `
+"for // comment
+(;;);
+
+for /* comment */(;;);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// comment
+for (;;);
+
+/* comment */
+for (;;);
 "
 `;
 
diff --git a/tests/comments/dangling.js b/tests/comments/dangling.js
index 22208dee5..f041ce3dc 100644
--- a/tests/comments/dangling.js
+++ b/tests/comments/dangling.js
@@ -7,3 +7,4 @@ function x() {
   /* dangling */
 }
 declare class Foo extends Qux<string> {/* dangling */}
+export /* dangling */{};
diff --git a/tests/comments/dangling_array.js b/tests/comments/dangling_array.js
index 599897d57..6559ed64a 100644
--- a/tests/comments/dangling_array.js
+++ b/tests/comments/dangling_array.js
@@ -1,3 +1,5 @@
 expect(() => {}).toTriggerReadyStateChanges([
   // Nothing.
 ]);
+
+[1 /* first comment */, 2 /* second comment */, 3];
diff --git a/tests/comments/dangling_for.js b/tests/comments/dangling_for.js
new file mode 100644
index 000000000..047f46929
--- /dev/null
+++ b/tests/comments/dangling_for.js
@@ -0,0 +1,4 @@
+for // comment
+(;;);
+
+for /* comment */(;;);