Repository: prettier/prettier (JavaScript) — Bug Fix

Issue:
Unstable comments before `extends`
```js
class A // comment 1
  // comment 2
  extends B {}
```

[turns into](https://jlongster.github.io/prettier/#%7B%22content%22%3A%22class%20A%20%2F%2F%20comment%201%5Cn%20%20%2F%2F%20comment%202%5Cn%20%20extends%20B%20%7B%7D%5Cn%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%22jsxBracketSameLine%22%3Afalse%2C%22doc%22%3Afalse%7D%7D)

```js
class A // comment 1
  extends // comment 2
  B {}
```

[turns into](https://jlongster.github.io/prettier/#%7B%22content%22%3A%22class%20A%20%2F%2F%20comment%201%5Cn%20%20extends%20%2F%2F%20comment%202%5Cn%20%20B%20%7B%7D%5Cn%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%22jsxBracketSameLine%22%3Afalse%2C%22doc%22%3Afalse%7D%7D)

```js
class A extends B {} // comment 1 // comment 2
```



Discussion:

Resolving patch:
diff --git a/src/comments.js b/src/comments.js
index 24e94a10d864..89d318fdb7b6 100644
--- a/src/comments.js
+++ b/src/comments.js
@@ -145,7 +145,8 @@ function attach(comments, ast, text, options) {
       if (
         handleMemberExpressionComments(enclosingNode, followingNode, comment) ||
         handleIfStatementComments(enclosingNode, followingNode, comment) ||
-        handleTryStatementComments(enclosingNode, followingNode, comment)
+        handleTryStatementComments(enclosingNode, followingNode, comment) ||
+        handleClassComments(enclosingNode, comment)
       ) {
         // We're good
       } else if (followingNode) {
@@ -168,7 +169,8 @@ function attach(comments, ast, text, options) {
           comment,
           text
         ) ||
-        handleTemplateLiteralComments(enclosingNode, comment)
+        handleTemplateLiteralComments(enclosingNode, comment) ||
+        handleClassComments(enclosingNode, comment)
       ) {
         // We're good
       } else if (precedingNode) {
@@ -454,6 +456,16 @@ function handleFunctionDeclarationComments(enclosingNode, comment) {
   return false;
 }
 
+function handleClassComments(enclosingNode, comment) {
+  if (enclosingNode &&
+      (enclosingNode.type === "ClassDeclaration" ||
+        enclosingNode.type === "ClassExpression")) {
+    addLeadingComment(enclosingNode, comment);
+    return true;
+  }
+  return false;
+}
+
 function printComment(commentPath) {
   const comment = commentPath.getValue();
   comment.printed = true;


Test patch:
diff --git a/tests/class_comment/__snapshots__/jsfmt.spec.js.snap b/tests/class_comment/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000000..0fb2c394fa6c
--- /dev/null
+++ b/tests/class_comment/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,58 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`comments.js 1`] = `
+"class A // comment 1
+  // comment 2
+  extends B {}
+
+class A extends B // comment1
+// comment2
+// comment3
+{}
+
+class A /* a */ extends B {}
+class A extends B /* a */ {}
+class A extends /* a */ B {}
+
+(class A // comment 1
+  // comment 2
+  extends B {});
+
+(class A extends B // comment1
+// comment2
+// comment3
+{});
+
+(class A /* a */ extends B {});
+(class A extends B /* a */ {});
+(class A extends /* a */ B {});
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// comment 1
+// comment 2
+class A extends B {}
+
+// comment1
+// comment2
+// comment3
+class A extends B {}
+
+class A /* a */ extends B {}
+class A extends B /* a */ {
+}
+class A extends /* a */ B {}
+
+// comment 1
+// comment 2
+(class A extends B {});
+
+// comment1
+// comment2
+// comment3
+(class A extends B {});
+
+(class A /* a */ extends B {});
+(class A extends B /* a */ {
+});
+(class A extends /* a */ B {});
+"
+`;
diff --git a/tests/class_comment/comments.js b/tests/class_comment/comments.js
new file mode 100644
index 000000000000..133245cc3315
--- /dev/null
+++ b/tests/class_comment/comments.js
@@ -0,0 +1,25 @@
+class A // comment 1
+  // comment 2
+  extends B {}
+
+class A extends B // comment1
+// comment2
+// comment3
+{}
+
+class A /* a */ extends B {}
+class A extends B /* a */ {}
+class A extends /* a */ B {}
+
+(class A // comment 1
+  // comment 2
+  extends B {});
+
+(class A extends B // comment1
+// comment2
+// comment3
+{});
+
+(class A /* a */ extends B {});
+(class A extends B /* a */ {});
+(class A extends /* a */ B {});
diff --git a/tests/class_comment/jsfmt.spec.js b/tests/class_comment/jsfmt.spec.js
new file mode 100644
index 000000000000..989047bccc52
--- /dev/null
+++ b/tests/class_comment/jsfmt.spec.js
@@ -0,0 +1,1 @@
+run_spec(__dirname);