Repository: prettier/prettier (JavaScript)
Date: 2017-12-09 14:18:41+00:00
Task type: Bug Fix

Issue:
Babylon misplaces comments around class constructors
**Prettier 1.9.1**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEcAeAHCAnGACMAGwEMBnUvAZSmI1IAsIYAZCAczbmz2AB0ZeUPAWikY2AK5gYOABT9Bw4djjxYAS2gAFLpoAmSPFAkBbAEZc8AXjwBWPACo8ANgAMjvAEZXPgDR4AegC8FRhidSEMMnwAM3UANzg8EwiJeFIFISVSGjpGGABJWC544kJDY3NLGwBmdydvP0DgnNoGJiMIZJwkmHpiIThE7ABPPDqMgSyASh5M4QBfTKWoEF8QCAwYTShSZFBibGwIAHctQ4Q9lGJ4iHU9NZBo5Biy0jh1s2xiMABrVUoUTAETYyHEEg+ID0EDALzekIi71wWm+bBMxDhhHe6wAVqQ0AAhb5-AHEExwZgROCY7EbNIYNIAJhpkKi2CRyBAZmIZhGhGgjww2AiMAA6vc+sgAByudZCiDvUXfDCcoVwJGJR4qACOEnUKhRxDRGKQryxkPeKTBkgtIMIcAAihImNTTfD1mEzOK9JKkIyPd91IQQQBhCAmdGcqDQanrCTvAAqPKuZveCwWQA)

**Input:**
```jsx
export class SnapshotLogger {	
  constructor(	
    retentionPeriod: number = 5 * 60 * 1000, // retain past five minutes	
    snapshotInterval: number = 30 * 1000, // snapshot no more than every 30s	
  ) {	
  }	
}

```

**Output:**
```jsx
export class SnapshotLogger {
  constructor(
    retentionPeriod: number = 5 * 60 * 1000,
    snapshotInterval: number = 30 * 1000 // snapshot no more than every 30s
  ) {} // retain past five minutes
}

```

**Expected behavior:**

Note that if you run it through the flow parser it works fine.

For context, I'm trying to figure out if we could use babylon on Facebook codebase. I've ran prettier on the Nuclide codebase with babylon instead of flow and there's only a few files that are not the same and it's always because of some comments that were misplaced like this.


Issue discussion:
And the other case where it seems to happen:

**Prettier 1.9.1**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEMAWBLAzgOizAQ3gAIBeY4AHSmOIDMMAbBAgWzgCU4BzOADyTVatAPQj6jCAHdGGWAFoo-GPNlLiWANZwYYNAE9FAV0aN5+AE5zuSCHTpDhcjDAwFGAZTgELegAo+bLgMzFBsnDz8xAA+0Y60vDAAYkws7CmM8BYAFAAOFhAAVnBgMDg+YH4FxaUANMT5RSVlWEYARgAmGBbNEBb6AJS11AC+1CC1IBC5rtBYyKA+BVIBPVDzKAQAbhAYHRMgBPjIdO5YcJNtFgRg2jAeuTfWyDAWRhcgHRBgJ2cfcucLDAqgRuKwCL9GOdJoUsHwAELXW46DzhAAycjgkOhUyMMFyeIATNiPo8LIDkCA2gQ2vpJFADvk5DAAOp7dDIAAcAAZJo1zizrrlKfk4ICtljJj0AI5GbpwEFgiFIU5Qj7nVgYF5vdXWZgARSMEHgJMmhDabI6HKQhLN1yY1gAwhBWODKVBoJKQEZzgAVGkbVXnEYjIA)

**Input:**
```jsx
this.state = {
  filenameRegex:
    // flowlint-next-line sketchy-null-string:off
    initialSearchParams.filenameRegex ||
    getFilenameFilter(project.arcProject, project.subdirectory),
}

```

**Output:**
```jsx
this.state = {
  // flowlint-next-line sketchy-null-string:off
  filenameRegex:
    initialSearchParams.filenameRegex ||
    getFilenameFilter(project.arcProject, project.subdirectory)
};

```
Good news is that I've ran babylon through more code and those two issues seem to be the only one. This is really exciting :)
FTR the comment misplace happens for any class method, not just constructor

Solution patch:
diff --git a/src/comments.js b/src/comments.js
index 260b0a17de08..af39c59177ec 100644
--- a/src/comments.js
+++ b/src/comments.js
@@ -207,7 +207,6 @@ function attach(comments, ast, text, options) {
           comment
         ) ||
         handleImportSpecifierComments(enclosingNode, comment) ||
-        handleObjectPropertyComments(enclosingNode, comment) ||
         handleForComments(enclosingNode, precedingNode, comment) ||
         handleUnionTypeComments(
           precedingNode,
@@ -273,7 +272,6 @@ function attach(comments, ast, text, options) {
         handlePropertyComments(enclosingNode, comment) ||
         handleExportNamedDeclarationComments(enclosingNode, comment) ||
         handleOnlyComments(enclosingNode, ast, comment, isLastComment) ||
-        handleClassMethodComments(enclosingNode, comment) ||
         handleTypeAliasComments(enclosingNode, followingNode, comment) ||
         handleVariableDeclaratorComments(enclosingNode, followingNode, comment)
       ) {
@@ -756,14 +754,6 @@ function handleImportSpecifierComments(enclosingNode, comment) {
   return false;
 }
 
-function handleObjectPropertyComments(enclosingNode, comment) {
-  if (enclosingNode && enclosingNode.type === "ObjectProperty") {
-    addLeadingComment(enclosingNode, comment);
-    return true;
-  }
-  return false;
-}
-
 function handleLabeledStatementComments(enclosingNode, comment) {
   if (enclosingNode && enclosingNode.type === "LabeledStatement") {
     addLeadingComment(enclosingNode, comment);
@@ -887,14 +877,6 @@ function handleAssignmentPatternComments(enclosingNode, comment) {
   return false;
 }
 
-function handleClassMethodComments(enclosingNode, comment) {
-  if (enclosingNode && enclosingNode.type === "ClassMethod") {
-    addTrailingComment(enclosingNode, comment);
-    return true;
-  }
-  return false;
-}
-
 function handleTypeAliasComments(enclosingNode, followingNode, comment) {
   if (enclosingNode && enclosingNode.type === "TypeAlias") {
     addLeadingComment(enclosingNode, comment);


Test patch:
diff --git a/tests/class_comment/__snapshots__/jsfmt.spec.js.snap b/tests/class_comment/__snapshots__/jsfmt.spec.js.snap
index d7a7c3ac20cb..3216c3ee11b6 100644
--- a/tests/class_comment/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/class_comment/__snapshots__/jsfmt.spec.js.snap
@@ -41,6 +41,14 @@ class X {
     '<div class="ag-large-textarea"></div>' +
     '</div>';
 }
+
+export class SnapshotLogger {
+  constructor(
+    retentionPeriod: number = 5 * 60 * 1000, // retain past five minutes
+    snapshotInterval: number = 30 * 1000, // snapshot no more than every 30s
+  ) {
+  }
+}
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class A // comment 1
 // comment 2
@@ -87,4 +95,11 @@ class X {
       "</div>";
 }
 
+export class SnapshotLogger {
+  constructor(
+    retentionPeriod: number = 5 * 60 * 1000, // retain past five minutes
+    snapshotInterval: number = 30 * 1000 // snapshot no more than every 30s
+  ) {}
+}
+
 `;
diff --git a/tests/class_comment/comments.js b/tests/class_comment/comments.js
index 659a3f4a78d9..97352298d507 100644
--- a/tests/class_comment/comments.js
+++ b/tests/class_comment/comments.js
@@ -38,3 +38,11 @@ class X {
     '<div class="ag-large-textarea"></div>' +
     '</div>';
 }
+
+export class SnapshotLogger {
+  constructor(
+    retentionPeriod: number = 5 * 60 * 1000, // retain past five minutes
+    snapshotInterval: number = 30 * 1000, // snapshot no more than every 30s
+  ) {
+  }
+}
diff --git a/tests/object_property_comment/jsfmt.spec.js b/tests/object_property_comment/jsfmt.spec.js
index b9a908981a50..c1ba82f46794 100644
--- a/tests/object_property_comment/jsfmt.spec.js
+++ b/tests/object_property_comment/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["flow"]);
+run_spec(__dirname, ["flow", "babylon"]);