Repository: jlongster/prettier (js)

Issue:
Extra newline and indent for JSXExpressionContainer with a dangling comment
Notice the extra indent and an extra newline.

```js
<div>
  {
    /* mimic the table layout */
  }
</div>
```

prints

```js
<div>
  {

      /* mimic the table layout */
  }
</div>;
```

https://jlongster.github.io/prettier/#%7B%22content%22%3A%22%3Cdiv%3E%5Cn%20%20%7B%5Cn%20%20%20%20%2F*%20mimic%20the%20table%20layout%20*%2F%5Cn%20%20%7D%5Cn%3C%2Fdiv%3E%22%2C%22options%22%3A%7B%22printWidth%22%3A80%2C%22tabWidth%22%3A2%2C%22singleQuote%22%3Afalse%2C%22trailingComma%22%3Afalse%2C%22bracketSpacing%22%3Atrue%2C%22doc%22%3Afalse%7D%7D

Pull request description:
Fix single indented JSX comment
This one was pretty annoying to figure out but now it's working. All the crazy comments I could throw at jsx seems to be working fine now :)

Fixes #543

Patch:
diff --git a/index.js b/index.js
index 651ad87eb..c135b2dd7 100644
--- a/index.js
+++ b/index.js
@@ -39,9 +39,10 @@ function parse(text, opts) {
 }
 
 function attachComments(text, ast, opts) {
-  if (ast.comments) {
-    comments.attach(ast.comments, ast, text);
-    ast.comments = [];
+  const astComments = ast.comments;
+  if (astComments) {
+    delete ast.comments;
+    comments.attach(astComments, ast, text);
   }
   ast.tokens = [];
   opts.originalText = text;
diff --git a/src/comments.js b/src/comments.js
index bd5c25d7f..b18943739 100644
--- a/src/comments.js
+++ b/src/comments.js
@@ -28,7 +28,7 @@ function getSortedChildNodes(node, text, resultArray) {
   util.fixFaultyLocations(node, text);
 
   if (resultArray) {
-    if (n.Node.check(node)) {
+    if (n.Node.check(node) && node.type !== "EmptyStatement") {
       // This reverse insertion sort almost always takes constant
       // time because we almost always (maybe always?) append the
       // nodes in order anyway.
@@ -135,17 +135,16 @@ function attach(comments, ast, text) {
     const precedingNode = comment.precedingNode;
     const enclosingNode = comment.enclosingNode;
     const followingNode = comment.followingNode;
-    const isStartOfFile = comment.loc.start.line === 1;
 
     if (
-      util.hasNewline(text, locStart(comment), { backwards: true }) ||
-        isStartOfFile
+      util.hasNewline(text, locStart(comment), { backwards: true })
     ) {
       // If a comment exists on its own line, prefer a leading comment.
       // We also need to check if it's the first line of the file.
       if (
         handleMemberExpressionComment(enclosingNode, followingNode, comment) ||
-          handleIfStatementComments(enclosingNode, followingNode, comment)
+          handleIfStatementComments(enclosingNode, followingNode, comment) ||
+          handleTryStatementComments(enclosingNode, followingNode, comment)
       ) {
         // We're good
       } else if (followingNode) {
@@ -156,8 +155,8 @@ function attach(comments, ast, text) {
       } else if (enclosingNode) {
         addDanglingComment(enclosingNode, comment);
       } else {
-        // TODO: If there are no nodes at all, we should still somehow
-        // print the comment.
+        // There are no nodes, let's attach it to the root of the ast
+        addDanglingComment(ast, comment);
       }
     } else if (util.hasNewline(text, locEnd(comment))) {
       // There is content before this comment on the same line, but
@@ -286,6 +285,14 @@ function addBlockStatementFirstComment(node, comment) {
   }
 }
 
+function addBlockOrNotComment(node, comment) {
+  if (node.type === "BlockStatement") {
+    addBlockStatementFirstComment(node, comment);
+  } else {
+    addLeadingComment(node, comment);
+  }
+}
+
 // There are often comments before the else clause of if statements like
 //
 //   if (1) { ... }
@@ -315,11 +322,33 @@ function handleIfStatementComments(enclosingNode, followingNode, comment) {
   }
 
   if (followingNode.type === "IfStatement") {
-    if (followingNode.consequent.type === "BlockStatement") {
-      addBlockStatementFirstComment(followingNode.consequent, comment);
-    } else {
-      addLeadingComment(followingNode.consequent, comment);
-    }
+    addBlockOrNotComment(followingNode.consequent, comment);
+    return true;
+  }
+
+  return false;
+}
+
+// Same as IfStatement but for TryStatement
+function handleTryStatementComments(enclosingNode, followingNode, comment) {
+  if (
+    !enclosingNode || enclosingNode.type !== "TryStatement" || !followingNode
+  ) {
+    return false;
+  }
+
+  if (followingNode.type === "BlockStatement") {
+    addBlockStatementFirstComment(followingNode, comment);
+    return true;
+  }
+
+  if (followingNode.type === "TryStatement") {
+    addBlockOrNotComment(followingNode.finalizer, comment);
+    return true;
+  }
+
+  if (followingNode.type === "CatchClause") {
+    addBlockOrNotComment(followingNode.body, comment);
     return true;
   }
 
diff --git a/src/fast-path.js b/src/fast-path.js
index 53ef717c2..d4dbca3a3 100644
--- a/src/fast-path.js
+++ b/src/fast-path.js
@@ -497,6 +497,11 @@ FPp.needsParens = function(assumeExpressionContext) {
         return name === "object" && parent.object === node;
       }
 
+    case "StringLiteral":
+      if (parent.type === "ExpressionStatement") {
+        return true;
+      }
+
     default:
       if (
         parent.type === "NewExpression" &&
diff --git a/src/printer.js b/src/printer.js
index 6eff3025c..7bc8c4091 100644
--- a/src/printer.js
+++ b/src/printer.js
@@ -1131,12 +1131,13 @@ function genericPrintNoParens(path, options, print) {
         n.expression.type === "ArrowFunctionExpression" ||
         n.expression.type === "CallExpression" ||
         n.expression.type === "FunctionExpression" ||
+        n.expression.type === "JSXEmptyExpression" ||
         parent.type === "JSXElement" &&
           (n.expression.type === "ConditionalExpression" ||
             n.expression.type === "LogicalExpression");
 
       if (shouldInline) {
-        return concat(["{", path.call(print, "expression"), "}"]);
+        return group(concat(["{", path.call(print, "expression"), "}"]));
       }
 
       return group(
@@ -1198,7 +1199,7 @@ function genericPrintNoParens(path, options, print) {
     case "JSXText":
       throw new Error("JSXTest should be handled by JSXElement");
     case "JSXEmptyExpression":
-      return comments.printDanglingComments(path, options);
+      return concat([comments.printDanglingComments(path, options), softline]);
     case "TypeAnnotatedIdentifier":
       return concat([
         path.call(print, "annotation"),
@@ -1377,9 +1378,15 @@ function genericPrintNoParens(path, options, print) {
         namedTypes.ObjectTypeProperty.check(parent) ||
         namedTypes.ObjectTypeCallProperty.check(parent) ||
         namedTypes.DeclareFunction.check(path.getParentNode(2)));
+
       var needsColon = isArrowFunctionTypeAnnotation &&
         namedTypes.TypeAnnotation.check(parent);
 
+      if (isObjectTypePropertyAFunction(parent)) {
+        isArrowFunctionTypeAnnotation = true;
+        needsColon = true;
+      }
+
       if (needsColon) {
         parts.push(": ");
       }
@@ -1499,6 +1506,11 @@ function genericPrintNoParens(path, options, print) {
       var isFunction = !n.variance &&
         !n.optional &&
         n.value.type === "FunctionTypeAnnotation";
+
+      if (isObjectTypePropertyAFunction(n)) {
+        isFunction = true;
+      }
+
       return concat([
         n.static ? "static " : "",
         variance,
@@ -2077,7 +2089,11 @@ function printMemberChain(path, options, print) {
     if (node.type === "CallExpression") {
       printedNodes.unshift({
         node: node,
-        printed: printArgumentsList(path, options, print)
+        printed: comments.printComments(
+          path,
+          p => printArgumentsList(path, options, print),
+          options
+        )
       });
       path.call(callee => rec(callee), "callee");
     } else if (node.type === "MemberExpression") {
@@ -2097,7 +2113,14 @@ function printMemberChain(path, options, print) {
       });
     }
   }
-  rec(path);
+  // Note: the comments of the root node have already been printed, so we
+  // need to extract this first call without printing them as they would
+  // if handled inside of the recursive call.
+  printedNodes.unshift({
+    node: path.getValue(),
+    printed: printArgumentsList(path, options, print)
+  });
+  path.call(callee => rec(callee), "callee");
 
   // Once we have a linear list of printed nodes, we want to create groups out
   // of it.
@@ -2673,6 +2696,16 @@ function isLastStatement(path) {
   return body && body[body.length - 1] === node;
 }
 
+// Hack to differentiate between the following two which have the same ast
+// type T = { method: () => void };
+// type T = { method(): void };
+function isObjectTypePropertyAFunction(node) {
+  return node.type === "ObjectTypeProperty" &&
+    node.value.type === "FunctionTypeAnnotation" &&
+    !node.static &&
+    util.locStart(node.key) !== util.locStart(node.value);
+}
+
 function shouldPrintSameLine(node) {
   const type = node.type;
   return namedTypes.Literal.check(node) ||


Test patch:
diff --git a/tests/comments/__snapshots__/jsfmt.spec.js.snap b/tests/comments/__snapshots__/jsfmt.spec.js.snap
index 4627eed57..e7a30b239 100644
--- a/tests/comments/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/comments/__snapshots__/jsfmt.spec.js.snap
@@ -5,7 +5,11 @@ exports[`test blank.js 1`] = `
 //
 // when printed.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+// This file only
+// has comments. This comment
+// should still exist
+//
+// when printed.
 "
 `;
 
@@ -70,6 +74,24 @@ declare class Foo extends Qux<string> {/* dangling */}
 "
 `;
 
+exports[`test first-line.js 1`] = `
+"a // comment
+b
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+a; // comment
+b;
+"
+`;
+
+exports[`test first-line.js 2`] = `
+"a // comment
+b
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+a; // comment
+b;
+"
+`;
+
 exports[`test if.js 1`] = `
 "if (1)
 // comment
@@ -618,6 +640,12 @@ foo(
 
 exports[`test jsx.js 1`] = `
 "<div>
+  {
+    /* comment */
+  }
+</div>;
+
+<div>
   {/* comment */
   }
 </div>;
@@ -650,6 +678,12 @@ exports[`test jsx.js 1`] = `
   {/* comment */}
 </div>;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<div>
+  {
+    /* comment */
+  }
+</div>;
+
 <div>
   {/* comment */}
 </div>;
@@ -684,6 +718,12 @@ exports[`test jsx.js 1`] = `
 
 exports[`test jsx.js 2`] = `
 "<div>
+  {
+    /* comment */
+  }
+</div>;
+
+<div>
   {/* comment */
   }
 </div>;
@@ -716,6 +756,12 @@ exports[`test jsx.js 2`] = `
   {/* comment */}
 </div>;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<div>
+  {
+    /* comment */
+  }
+</div>;
+
 <div>
   {/* comment */}
 </div>;
@@ -747,3 +793,59 @@ exports[`test jsx.js 2`] = `
 </div>;
 "
 `;
+
+exports[`test try.js 1`] = `
+"// comment 1
+try {
+  // comment 2
+}
+// comment 3
+catch(e) {
+  // comment 4
+}
+// comment 5
+finally // comment 6
+{
+  // comment 7
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// comment 1
+try {
+  // comment 2
+} catch (e) {
+  // comment 3
+  // comment 4
+} finally { // comment 6
+  // comment 5
+  // comment 7
+}
+"
+`;
+
+exports[`test try.js 2`] = `
+"// comment 1
+try {
+  // comment 2
+}
+// comment 3
+catch(e) {
+  // comment 4
+}
+// comment 5
+finally // comment 6
+{
+  // comment 7
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// comment 1
+try {
+  // comment 2
+} catch (e) {
+  // comment 3
+  // comment 4
+} finally { // comment 6
+  // comment 5
+  // comment 7
+}
+"
+`;
diff --git a/tests/comments/first-line.js b/tests/comments/first-line.js
new file mode 100644
index 000000000..4c01d05a2
--- /dev/null
+++ b/tests/comments/first-line.js
@@ -0,0 +1,2 @@
+a // comment
+b
diff --git a/tests/comments/jsx.js b/tests/comments/jsx.js
index a28b9b0a1..01fe296a2 100644
--- a/tests/comments/jsx.js
+++ b/tests/comments/jsx.js
@@ -1,3 +1,9 @@
+<div>
+  {
+    /* comment */
+  }
+</div>;
+
 <div>
   {/* comment */
   }
diff --git a/tests/comments/try.js b/tests/comments/try.js
new file mode 100644
index 000000000..1c9205765
--- /dev/null
+++ b/tests/comments/try.js
@@ -0,0 +1,13 @@
+// comment 1
+try {
+  // comment 2
+}
+// comment 3
+catch(e) {
+  // comment 4
+}
+// comment 5
+finally // comment 6
+{
+  // comment 7
+}
diff --git a/tests/expression_statement/__snapshots__/jsfmt.spec.js.snap b/tests/expression_statement/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000..54a281bd1
--- /dev/null
+++ b/tests/expression_statement/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,18 @@
+exports[`test no_regression.js 1`] = `
+"// Ensure no regression.
+\"use strict\";
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Ensure no regression.
+\"use strict\";
+
+"
+`;
+
+exports[`test use_strict.js 1`] = `
+"// Parentheses around expression statement should be preserved in this case.
+(\"use strict\");
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Parentheses around expression statement should be preserved in this case.
+(\"use strict\");
+"
+`;
diff --git a/tests/expression_statement/jsfmt.spec.js b/tests/expression_statement/jsfmt.spec.js
new file mode 100755
index 000000000..67caec390
--- /dev/null
+++ b/tests/expression_statement/jsfmt.spec.js
@@ -0,0 +1,2 @@
+// TODO: Re-enable Flow when the following fix is merged facebook/flow#3234.
+run_spec(__dirname, {parser: 'babylon'});
diff --git a/tests/expression_statement/no_regression.js b/tests/expression_statement/no_regression.js
new file mode 100644
index 000000000..8a5e0f44d
--- /dev/null
+++ b/tests/expression_statement/no_regression.js
@@ -0,0 +1,2 @@
+// Ensure no regression.
+"use strict";
diff --git a/tests/expression_statement/use_strict.js b/tests/expression_statement/use_strict.js
new file mode 100755
index 000000000..31bce8687
--- /dev/null
+++ b/tests/expression_statement/use_strict.js
@@ -0,0 +1,2 @@
+// Parentheses around expression statement should be preserved in this case.
+("use strict");
diff --git a/tests/flow/annot/__snapshots__/jsfmt.spec.js.snap b/tests/flow/annot/__snapshots__/jsfmt.spec.js.snap
index 76159fc45..194b4f92a 100644
--- a/tests/flow/annot/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/annot/__snapshots__/jsfmt.spec.js.snap
@@ -148,9 +148,7 @@ function foo() {
   class MyClass { } // looked up above
 }
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-let myClassInstance: MyClass = null;
-
-// forward ref ok, null ~> class error
+let myClassInstance: MyClass = null; // forward ref ok, null ~> class error
 
 function bar(): MyClass {
   return null; // forward ref ok, null ~> class error
diff --git a/tests/flow/annot2/__snapshots__/jsfmt.spec.js.snap b/tests/flow/annot2/__snapshots__/jsfmt.spec.js.snap
index 9952c89ba..6f24ee06a 100644
--- a/tests/flow/annot2/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/annot2/__snapshots__/jsfmt.spec.js.snap
@@ -59,6 +59,8 @@ exports[`test T.js 1`] = `
  * @providesModule T
  */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/**
+ * @providesModule T
+ */
 "
 `;
diff --git a/tests/flow/binding/__snapshots__/jsfmt.spec.js.snap b/tests/flow/binding/__snapshots__/jsfmt.spec.js.snap
index 239ca9dc4..495adf455 100644
--- a/tests/flow/binding/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/binding/__snapshots__/jsfmt.spec.js.snap
@@ -416,13 +416,13 @@ function var_var() {
 
 function function_toplevel() {
   function a() {}
-  function a() {}
+  function a() {} // OK
 }
 
 function function_block() {
   {
     function a() {}
-    function a() {}
+    function a() {} // error: name already bound
   }
 }
 
diff --git a/tests/flow/constructor_annots/__snapshots__/jsfmt.spec.js.snap b/tests/flow/constructor_annots/__snapshots__/jsfmt.spec.js.snap
index e3ff68427..d1f66e222 100644
--- a/tests/flow/constructor_annots/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/constructor_annots/__snapshots__/jsfmt.spec.js.snap
@@ -38,7 +38,7 @@ exports.Foo = Foo;
 
 // so you want to type Foo, by declaring it as a class
 interface IFooPrototype {
-  m(): number
+  m: () => number
 }
 interface IFoo extends IFooPrototype {
   static (): void,
diff --git a/tests/flow/declaration_files_haste/__snapshots__/jsfmt.spec.js.snap b/tests/flow/declaration_files_haste/__snapshots__/jsfmt.spec.js.snap
index 5fda14628..113cd6882 100644
--- a/tests/flow/declaration_files_haste/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/declaration_files_haste/__snapshots__/jsfmt.spec.js.snap
@@ -52,7 +52,7 @@ module.exports.fun = (): string => \"hello there\";
 exports[`test md5.js 1`] = `
 "/* @providesModule md5 */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/* @providesModule md5 */
 "
 `;
 
diff --git a/tests/flow/declaration_files_incremental_haste/__snapshots__/jsfmt.spec.js.snap b/tests/flow/declaration_files_incremental_haste/__snapshots__/jsfmt.spec.js.snap
index 8d6837dae..5895f278d 100644
--- a/tests/flow/declaration_files_incremental_haste/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/declaration_files_incremental_haste/__snapshots__/jsfmt.spec.js.snap
@@ -71,7 +71,7 @@ module.exports.fun = (): Implementation => new Implementation();
 exports[`test md5.js 1`] = `
 "/* @providesModule md5 */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/* @providesModule md5 */
 "
 `;
 
diff --git a/tests/flow/declare_export/__snapshots__/jsfmt.spec.js.snap b/tests/flow/declare_export/__snapshots__/jsfmt.spec.js.snap
index 31618f076..ecbe3ebe6 100644
--- a/tests/flow/declare_export/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/declare_export/__snapshots__/jsfmt.spec.js.snap
@@ -12,7 +12,7 @@ exports.numberValue = 42;
 exports[`test C.js 1`] = `
 "/* @flow */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/* @flow */
 "
 `;
 
@@ -561,7 +561,10 @@ exports[`test ProvidesModuleD.js 1`] = `
  * @flow
  */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/**
+ * @providesModule D
+ * @flow
+ */
 "
 `;
 
@@ -577,14 +580,22 @@ export default {
 };
 */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/**
+ * @providesModule ES6Default
+ * @flow
+ */
+/*
+export default {
+  numberValue: 42,
+};
+*/
 "
 `;
 
 exports[`test SideEffects.js 1`] = `
 "/* @flow */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/* @flow */
 "
 `;
 
diff --git a/tests/flow/deps/__snapshots__/jsfmt.spec.js.snap b/tests/flow/deps/__snapshots__/jsfmt.spec.js.snap
index 426fb295f..2034af1ac 100644
--- a/tests/flow/deps/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/deps/__snapshots__/jsfmt.spec.js.snap
@@ -42,7 +42,7 @@ require(\"./I\");
 exports[`test F.js 1`] = `
 "// empty
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+// empty
 "
 `;
 
@@ -56,7 +56,7 @@ require(\"./H\");
 exports[`test H.js 1`] = `
 "// empty
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+// empty
 "
 `;
 
diff --git a/tests/flow/docblock_flow/__snapshots__/jsfmt.spec.js.snap b/tests/flow/docblock_flow/__snapshots__/jsfmt.spec.js.snap
index 57051efa9..af6a16406 100644
--- a/tests/flow/docblock_flow/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/docblock_flow/__snapshots__/jsfmt.spec.js.snap
@@ -21,7 +21,14 @@ exports[`test max_header_tokens.js 1`] = `
  * @flow
  */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/* @flow */
+/* second token */
+/* third token */
+/**
+ * After max_header_tokens (in .flowconfig), we no longer care:
+ *
+ * @flow
+ */
 "
 `;
 
@@ -29,7 +36,8 @@ exports[`test multiple_flows_1.js 1`] = `
 "/* @flow */
 /* @flow */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/* @flow */
+/* @flow */
 "
 `;
 
@@ -39,7 +47,10 @@ exports[`test multiple_flows_2.js 1`] = `
  * @noflow
  */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/**
+ * @flow
+ * @noflow
+ */
 "
 `;
 
@@ -50,7 +61,11 @@ exports[`test multiple_providesModule_1.js 1`] = `
  * @flow
  */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/**
+ * @providesModule Foo
+ * @providesModule Bar
+ * @flow
+ */
 "
 `;
 
@@ -63,7 +78,13 @@ exports[`test multiple_providesModule_2.js 1`] = `
  * @providesModule Bar
  */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/**
+ * @providesModule Foo
+ * @flow
+ */
+/**
+ * @providesModule Bar
+ */
 "
 `;
 
diff --git a/tests/flow/es6modules/__snapshots__/jsfmt.spec.js.snap b/tests/flow/es6modules/__snapshots__/jsfmt.spec.js.snap
index 1209f0279..595f5abab 100644
--- a/tests/flow/es6modules/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/es6modules/__snapshots__/jsfmt.spec.js.snap
@@ -12,7 +12,7 @@ exports.numberValue = 42;
 exports[`test C.js 1`] = `
 "/* @flow */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/* @flow */
 "
 `;
 
@@ -661,7 +661,10 @@ exports[`test ProvidesModuleD.js 1`] = `
  * @flow
  */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/**
+ * @providesModule D
+ * @flow
+ */
 "
 `;
 
@@ -677,14 +680,22 @@ export default {
 };
 */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/**
+ * @providesModule ES6Default
+ * @flow
+ */
+/*
+export default {
+  numberValue: 42,
+};
+*/
 "
 `;
 
 exports[`test SideEffects.js 1`] = `
 "/* @flow */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/* @flow */
 "
 `;
 
diff --git a/tests/flow/get-def2/lib/__snapshots__/jsfmt.spec.js.snap b/tests/flow/get-def2/lib/__snapshots__/jsfmt.spec.js.snap
index 501df81a4..db39ea781 100644
--- a/tests/flow/get-def2/lib/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/get-def2/lib/__snapshots__/jsfmt.spec.js.snap
@@ -7,8 +7,7 @@ type $JSXIntrinsics = {
   span: $JSXIntrinsic<{id: string, class: string}>,
 };
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-declare var $React: $Exports<\"react\">;
-// fake import
+declare var $React: $Exports<\"react\">; // fake import
 type $JSXIntrinsic<T> = Class<$React.Component<void, T, mixed>>;
 
 type $JSXIntrinsics = {
diff --git a/tests/flow/get-imports-and-importers/__snapshots__/jsfmt.spec.js.snap b/tests/flow/get-imports-and-importers/__snapshots__/jsfmt.spec.js.snap
index 3a9c5bec6..92b6ffc1d 100644
--- a/tests/flow/get-imports-and-importers/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/get-imports-and-importers/__snapshots__/jsfmt.spec.js.snap
@@ -1,7 +1,7 @@
 exports[`test a.js 1`] = `
 "// @flow
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+// @flow
 "
 `;
 
diff --git a/tests/flow/incremental/__snapshots__/jsfmt.spec.js.snap b/tests/flow/incremental/__snapshots__/jsfmt.spec.js.snap
index 253f04644..8ee563e01 100644
--- a/tests/flow/incremental/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/incremental/__snapshots__/jsfmt.spec.js.snap
@@ -1,7 +1,7 @@
 exports[`test a.js 1`] = `
 "/* @providesModule IncrModuleA */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/* @providesModule IncrModuleA */
 "
 `;
 
diff --git a/tests/flow/incremental_duplicate_delete/__snapshots__/jsfmt.spec.js.snap b/tests/flow/incremental_duplicate_delete/__snapshots__/jsfmt.spec.js.snap
index baad951fe..6ff6488f1 100644
--- a/tests/flow/incremental_duplicate_delete/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/incremental_duplicate_delete/__snapshots__/jsfmt.spec.js.snap
@@ -4,6 +4,9 @@ exports[`test A.js 1`] = `
  * @flow
  */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/**
+ * @providesModule A
+ * @flow
+ */
 "
 `;
diff --git a/tests/flow/incremental_non_flow_move/__snapshots__/jsfmt.spec.js.snap b/tests/flow/incremental_non_flow_move/__snapshots__/jsfmt.spec.js.snap
index 9c3d85fe2..d312b9c9f 100644
--- a/tests/flow/incremental_non_flow_move/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/incremental_non_flow_move/__snapshots__/jsfmt.spec.js.snap
@@ -3,7 +3,9 @@ exports[`test foo.js 1`] = `
  * @providesModule Foo
  */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/*
+ * @providesModule Foo
+ */
 "
 `;
 
diff --git a/tests/flow/integration/__snapshots__/jsfmt.spec.js.snap b/tests/flow/integration/__snapshots__/jsfmt.spec.js.snap
index f4ad8d578..024c8dc10 100644
--- a/tests/flow/integration/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/integration/__snapshots__/jsfmt.spec.js.snap
@@ -1,7 +1,7 @@
 exports[`test bar.js 1`] = `
 "// @flow
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+// @flow
 "
 `;
 
diff --git a/tests/flow/jsx_intrinsics.custom/lib/__snapshots__/jsfmt.spec.js.snap b/tests/flow/jsx_intrinsics.custom/lib/__snapshots__/jsfmt.spec.js.snap
index 501df81a4..db39ea781 100644
--- a/tests/flow/jsx_intrinsics.custom/lib/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/jsx_intrinsics.custom/lib/__snapshots__/jsfmt.spec.js.snap
@@ -7,8 +7,7 @@ type $JSXIntrinsics = {
   span: $JSXIntrinsic<{id: string, class: string}>,
 };
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-declare var $React: $Exports<\"react\">;
-// fake import
+declare var $React: $Exports<\"react\">; // fake import
 type $JSXIntrinsic<T> = Class<$React.Component<void, T, mixed>>;
 
 type $JSXIntrinsics = {
diff --git a/tests/flow/name_prop/__snapshots__/jsfmt.spec.js.snap b/tests/flow/name_prop/__snapshots__/jsfmt.spec.js.snap
index 674f144c0..d073de91b 100644
--- a/tests/flow/name_prop/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/name_prop/__snapshots__/jsfmt.spec.js.snap
@@ -29,6 +29,9 @@ exports[`test function.js 1`] = `
  * know that .name exists
  */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/* TODO - we currently say that a function\'s statics are an AnyObjT and
+ * anything goes. When we start enforcing the statics properly, we\'ll need to
+ * know that .name exists
+ */
 "
 `;
diff --git a/tests/flow/new_react/fakelib/__snapshots__/jsfmt.spec.js.snap b/tests/flow/new_react/fakelib/__snapshots__/jsfmt.spec.js.snap
index afd9ad152..386be1228 100644
--- a/tests/flow/new_react/fakelib/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/new_react/fakelib/__snapshots__/jsfmt.spec.js.snap
@@ -6,8 +6,7 @@ exports[`test type_aliases.js 1`] = `
 type _ReactElement<DefaultProps, Props, Config: $Diff<Props, DefaultProps>, C: $React.Component<DefaultProps, Props, any>> = $React.Element<Config>;
 type $jsx<C> = _ReactElement<*, *, *, C>;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-declare var $React: $Exports<\"react\">;
-// fake import
+declare var $React: $Exports<\"react\">; // fake import
 // Strawman: revised definition of $jsx (alternatively, React.Element).
 // Using bounded poly to specify a constraint on a type parameter, and
 // existentials to elide type arguments.
diff --git a/tests/flow/node_haste/__snapshots__/jsfmt.spec.js.snap b/tests/flow/node_haste/__snapshots__/jsfmt.spec.js.snap
index 0821cb5e4..760de36ab 100644
--- a/tests/flow/node_haste/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/node_haste/__snapshots__/jsfmt.spec.js.snap
@@ -8,6 +8,6 @@ var md5 = require(\"./md5\");
 exports[`test md5.js 1`] = `
 "/* @providesModule md5 */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/* @providesModule md5 */
 "
 `;
diff --git a/tests/flow/node_tests/basic_file/__snapshots__/jsfmt.spec.js.snap b/tests/flow/node_tests/basic_file/__snapshots__/jsfmt.spec.js.snap
index 0b97ddb4b..cfa42aa79 100644
--- a/tests/flow/node_tests/basic_file/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/node_tests/basic_file/__snapshots__/jsfmt.spec.js.snap
@@ -9,8 +9,7 @@ exports[`test foo.js 1`] = `
 "var x = require(\'./bar\'); // bar.js does not work
 console.log(x);
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-var x = require(\"./bar\");
-// bar.js does not work
+var x = require(\"./bar\"); // bar.js does not work
 console.log(x);
 "
 `;
diff --git a/tests/flow/node_tests/basic_package/__snapshots__/jsfmt.spec.js.snap b/tests/flow/node_tests/basic_package/__snapshots__/jsfmt.spec.js.snap
index e2a82d3b3..68d3d5387 100644
--- a/tests/flow/node_tests/basic_package/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/node_tests/basic_package/__snapshots__/jsfmt.spec.js.snap
@@ -2,8 +2,7 @@ exports[`test foo.js 1`] = `
 "var x = require(\'./bar_lib\'); // \'bar_lib\' does not work!
 console.log(x);
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-var x = require(\"./bar_lib\");
-// \'bar_lib\' does not work!
+var x = require(\"./bar_lib\"); // \'bar_lib\' does not work!
 console.log(x);
 "
 `;
diff --git a/tests/flow/node_tests/package_file/__snapshots__/jsfmt.spec.js.snap b/tests/flow/node_tests/package_file/__snapshots__/jsfmt.spec.js.snap
index cf9e4dca2..91c60d46b 100644
--- a/tests/flow/node_tests/package_file/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/node_tests/package_file/__snapshots__/jsfmt.spec.js.snap
@@ -9,8 +9,7 @@ exports[`test foo.js 1`] = `
 "var x: string = require(\'./bar_lib\'); // \'bar_lib\' does not work!
 console.log(x);
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-var x: string = require(\"./bar_lib\");
-// \'bar_lib\' does not work!
+var x: string = require(\"./bar_lib\"); // \'bar_lib\' does not work!
 console.log(x);
 "
 `;
diff --git a/tests/flow/node_tests/package_file_node_modules/foo/__snapshots__/jsfmt.spec.js.snap b/tests/flow/node_tests/package_file_node_modules/foo/__snapshots__/jsfmt.spec.js.snap
index b47f3c573..c478de1f6 100644
--- a/tests/flow/node_tests/package_file_node_modules/foo/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/node_tests/package_file_node_modules/foo/__snapshots__/jsfmt.spec.js.snap
@@ -2,8 +2,7 @@ exports[`test foo.js 1`] = `
 "var x: string = require(\'bar_lib\'); // \'bar_lib\' does not work!
 console.log(x);
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-var x: string = require(\"bar_lib\");
-// \'bar_lib\' does not work!
+var x: string = require(\"bar_lib\"); // \'bar_lib\' does not work!
 console.log(x);
 "
 `;
diff --git a/tests/flow/object-method/__snapshots__/jsfmt.spec.js.snap b/tests/flow/object-method/__snapshots__/jsfmt.spec.js.snap
index ba57ea5cc..13d76e253 100644
--- a/tests/flow/object-method/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/object-method/__snapshots__/jsfmt.spec.js.snap
@@ -129,7 +129,7 @@ function bar(f: () => void) {
 
 bar(foo); // error, since \`this\` is used non-trivially in \`foo\`
 
-function qux(o: { f(): void }) {
+function qux(o: { f: () => void }) {
   o.f(); // passing o as \`this\`
 }
 
diff --git a/tests/flow/rec/__snapshots__/jsfmt.spec.js.snap b/tests/flow/rec/__snapshots__/jsfmt.spec.js.snap
index c254b820e..c384a6371 100644
--- a/tests/flow/rec/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/rec/__snapshots__/jsfmt.spec.js.snap
@@ -93,9 +93,7 @@ pstar = (new P: P<P<number>>); // OK
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class P<X> {
   x: X;
-}
-
-// this is like Promise
+} // this is like Promise
 
 type Pstar<X> = X | Pstar<P<X>>; // this is like Promise*
 
@@ -146,8 +144,7 @@ class B<X> extends D<X> { }
 class C<X> extends B<X> { }
 ((new C: C<number>): D<string>) // error: number ~/~ string
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-var a = [];
-// Array<X> ~> a
+var a = []; // Array<X> ~> a
 function bar() {
   a = a.concat([]); // terminate despite expanding types:
   // a ~> .concat(Array<Y>)
diff --git a/tests/flow/recheck-haste/__snapshots__/jsfmt.spec.js.snap b/tests/flow/recheck-haste/__snapshots__/jsfmt.spec.js.snap
index 087b0eaf2..20f2fcbc8 100644
--- a/tests/flow/recheck-haste/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/recheck-haste/__snapshots__/jsfmt.spec.js.snap
@@ -4,7 +4,10 @@ exports[`test A1.js 1`] = `
  * @flow
  */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/**
+ * @providesModule A
+ * @flow
+ */
 "
 `;
 
diff --git a/tests/flow/recheck-haste/tmp1A/__snapshots__/jsfmt.spec.js.snap b/tests/flow/recheck-haste/tmp1A/__snapshots__/jsfmt.spec.js.snap
index 309aed97b..4fcf0c3b3 100644
--- a/tests/flow/recheck-haste/tmp1A/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/recheck-haste/tmp1A/__snapshots__/jsfmt.spec.js.snap
@@ -4,6 +4,9 @@ exports[`test A2.js 1`] = `
  * @flow
  */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/**
+ * @providesModule B
+ * @flow
+ */
 "
 `;
diff --git a/tests/flow/record/__snapshots__/jsfmt.spec.js.snap b/tests/flow/record/__snapshots__/jsfmt.spec.js.snap
index 5db3f33b7..14bd118fa 100644
--- a/tests/flow/record/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/record/__snapshots__/jsfmt.spec.js.snap
@@ -24,8 +24,7 @@ class D extends C<{foo: number, bar: string}> {
 type AnyKey = $Keys<Object>;
 var o3: {[key: AnyKey]: number} = { foo: 0 };
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-type Key1 = \"foo\" | \"bar\";
-// make an enum type with known key set
+type Key1 = \"foo\" | \"bar\"; // make an enum type with known key set
 var o1: { [key: Key1]: number } = {
   foo: 0,
   bar: \"\" // error: string ~/~ number
diff --git a/tests/flow/refinements/__snapshots__/jsfmt.spec.js.snap b/tests/flow/refinements/__snapshots__/jsfmt.spec.js.snap
index 5d8d537ba..e569f13dd 100644
--- a/tests/flow/refinements/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/refinements/__snapshots__/jsfmt.spec.js.snap
@@ -43,7 +43,7 @@ function foo(x: ?number) {
 
 type Bar = {
   parent: ?Bar,
-  doStuff(): void
+  doStuff: () => void
 };
 
 function bar0(x: Bar) {
diff --git a/tests/flow/require/__snapshots__/jsfmt.spec.js.snap b/tests/flow/require/__snapshots__/jsfmt.spec.js.snap
index fde01fe35..26293ad86 100644
--- a/tests/flow/require/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/require/__snapshots__/jsfmt.spec.js.snap
@@ -12,7 +12,7 @@ exports.numberValue = 42;
 exports[`test C.js 1`] = `
 "/* @flow */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/* @flow */
 "
 `;
 
@@ -64,7 +64,10 @@ exports[`test ProvidesModuleD.js 1`] = `
  * @flow
  */
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
+/**
+ * @providesModule D
+ * @flow
+ */
 "
 `;
 
diff --git a/tests/flow/taint/__snapshots__/jsfmt.spec.js.snap b/tests/flow/taint/__snapshots__/jsfmt.spec.js.snap
index 856977b2f..5a9b44db6 100644
--- a/tests/flow/taint/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/taint/__snapshots__/jsfmt.spec.js.snap
@@ -151,13 +151,13 @@ function foo(x: $Tainted<string>, o: Object) {
   // Error
   o.f(x);
 }
-function foo1(x: $Tainted<string>, o: { f(y: $Tainted<string>): void }) {
+function foo1(x: $Tainted<string>, o: { f: (y: $Tainted<string>) => void }) {
   o.f(x);
 }
 function foo2(o1: Object, o2: { t: $Tainted<string> }) {
   o1.f(o2.t);
 }
-function foo3<T>(x: $Tainted<T>, o: { f(y: $Tainted<T>): void }) {
+function foo3<T>(x: $Tainted<T>, o: { f: (y: $Tainted<T>) => void }) {
   o.f(x);
 }
 function f_foo1(x: $Tainted<string>, f: Function) {
diff --git a/tests/flow/type-destructors/__snapshots__/jsfmt.spec.js.snap b/tests/flow/type-destructors/__snapshots__/jsfmt.spec.js.snap
index e5d639ae3..ddbf4f683 100644
--- a/tests/flow/type-destructors/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/type-destructors/__snapshots__/jsfmt.spec.js.snap
@@ -62,8 +62,7 @@ var x1: $NonMaybeType<number|string> = true; // err, boolean ~> number|string
 var x2: $PropertyType<{p:number}|{p:string},\'p\'> = 0; // ok, number ~> number|string
 var x3: $PropertyType<{p:number}|{p:string},\'p\'> = true; // err, boolean ~> number|string
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-var x0: $NonMaybeType<number | string> = 0;
-// ok, number ~> number|string
+var x0: $NonMaybeType<number | string> = 0; // ok, number ~> number|string
 var x1: $NonMaybeType<number | string> = true; // err, boolean ~> number|string
 var x2: $PropertyType<{ p: number } | { p: string }, \"p\"> = 0; // ok, number ~> number|string
 var x3: $PropertyType<{ p: number } | { p: string }, \"p\"> = true; // err, boolean ~> number|string
diff --git a/tests/flow/type_only_vars/__snapshots__/jsfmt.spec.js.snap b/tests/flow/type_only_vars/__snapshots__/jsfmt.spec.js.snap
index 119c8288b..bedfebb27 100644
--- a/tests/flow/type_only_vars/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/type_only_vars/__snapshots__/jsfmt.spec.js.snap
@@ -57,7 +57,7 @@ import typeof A from \"./A.js\";
 import type { Foo, Bar as Baz } from \"./A.js\";
 
 type duck = {
-  quack(): string
+  quack: () => string
 };
 
 // These string types should confict with the imported types
diff --git a/tests/flow_method/__snapshots__/jsfmt.spec.js.snap b/tests/flow_method/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000..59d94ddce
--- /dev/null
+++ b/tests/flow_method/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,14 @@
+exports[`test method.js 1`] = `
+"type T = { method: () => void };
+type T = { method(): void };
+declare class X { method(): void }
+declare function f(): void;
+var f: () => void;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+type T = { method: () => void };
+type T = { method(): void };
+declare class X { method(): void }
+declare function f(): void;
+var f: () => void;
+"
+`;
diff --git a/tests/flow_method/jsfmt.spec.js b/tests/flow_method/jsfmt.spec.js
new file mode 100644
index 000000000..989047bcc
--- /dev/null
+++ b/tests/flow_method/jsfmt.spec.js
@@ -0,0 +1,1 @@
+run_spec(__dirname);
diff --git a/tests/flow_method/method.js b/tests/flow_method/method.js
new file mode 100644
index 000000000..405f3fe2b
--- /dev/null
+++ b/tests/flow_method/method.js
@@ -0,0 +1,5 @@
+type T = { method: () => void };
+type T = { method(): void };
+declare class X { method(): void }
+declare function f(): void;
+var f: () => void;
diff --git a/tests/last_argument_expansion/__snapshots__/jsfmt.spec.js.snap b/tests/last_argument_expansion/__snapshots__/jsfmt.spec.js.snap
index d298b8359..773b687b3 100644
--- a/tests/last_argument_expansion/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/last_argument_expansion/__snapshots__/jsfmt.spec.js.snap
@@ -21,7 +21,7 @@ export default function searchUsers(action$) {
     .map(action => action.payload.query)
     .filter(q => !!q)
     .switchMap(q =>
-      Observable.timer(800)
+      Observable.timer(800) // debounce
         .takeUntil(action$.ofType(ActionTypes.CLEARED_SEARCH_RESULTS))
         .mergeMap(() =>
           Observable.merge(