Repository: prettier/prettier (JavaScript)
Date: 2022-12-19 10:39:42+00:00
Task type: Bug Fix

Issue:
Incorrect formatting for auto-accessors with comments
<!--

BEFORE SUBMITTING AN ISSUE:

1.  Search for your issue on GitHub: https://github.com/prettier/prettier/issues
    A large number of opened issues are duplicates of existing issues.
    If someone has already opened an issue for what you are experiencing,
    you do not need to open a new issue — please add a 👍 reaction to the
    existing issue instead.

2.  We get a lot of requests for adding options, but Prettier is
    built on the principle of being opinionated about code formatting.
    This means we add options only in the case of strict technical necessity.
    Find out more: https://prettier.io/docs/en/option-philosophy.html

Don't fill the form below manually! Let a program create a report for you:

1. Go to https://prettier.io/playground
2. Paste your code and set options
3. Press the "Report issue" button in the lower right

-->

**Prettier 2.8.1**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAucAbAhgZ0wAgII7AA6UOOAAgCZxgAUAlCWQPTM5yaoCWsAtJV0zoARqji8ocAB4xe3SRRgBPAA4cwAJy4rZHeTGbD0UXjEy9IAW0sIYTHK0XmuAcygQNce+jBgOmDxxhAG4SAF8QABoQCB0uaExkUHQNDQgAdwAFFIRElHRUdPQlROjhDR8AazgYAGV0GwAZHjhkADMCzDgyirBqupUfHhdkGA0AV26QOEthOEpqSkbjF3H0FzgAMQ9LdBgYYeQQdHGYCCiQAAsYS1QAdUuueExBv1rcp64ANyelI7BsBceF0NDBMhUXLt2p0pgArTBSWrDMQARXGEHg0NQXWigw0IKORjmqAuKi0sDuXEoMEuyAAHAAGXFpLp3CoqI5kjhwDRfVrRACO6Pg4NieWO5kk83mF08Qq4nnB6yhSA62KmXUsXFGEw1yLgeH2WmEpzgmR5zUkWJxIEw+rRGNaqph0RgIkp1NpSAATK6Klx5C4AMIQazoI4cACsF3GXQAKiI8mqbV9JgBJKDUWC1TTaGB4TO1ZRia1wMJhIA)

```sh
# Options (if any):
```

**Input:**

```js
class A {
  @dec()
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  accessor b;
}
```

**Output:**

```js
class A {
  @dec()
  accessor // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  b;
}
```

**Expected behavior:**
The comments should not be placed between the keyword `accessor` and  the identifier `b`, which causes the `accessor` to be treated as a class field instead of a keyword. Expected:

```js
class A {
  @dec()
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  accessor b;
}
```



Issue discussion:
This is actually bug in TypeScript https://github.com/microsoft/TypeScript/issues/51707
But I think here the issue has nothing todo with that bug in TypeScript.

My input is `accessor b` with no line terminators. The prettier formatted that into separated lines, which according to the spec draft, is not matching with accessor syntax, but two separated field properties.

Solution patch:
diff --git a/changelog_unreleased/javascript/14038.md b/changelog_unreleased/javascript/14038.md
new file mode 100644
index 000000000000..b52a5aa34d96
--- /dev/null
+++ b/changelog_unreleased/javascript/14038.md
@@ -0,0 +1,32 @@
+#### Fix formatting for auto-accessors with comments (#14038 by @fisker)
+
+<!-- prettier-ignore -->
+```jsx
+// Input
+class A {
+  @dec()
+  // comment
+  accessor b;
+}
+
+// Prettier stable
+class A {
+  @dec()
+  accessor // comment
+  b;
+}
+
+// Prettier stable (second format)
+class A {
+  @dec()
+  accessor; // comment
+  b;
+}
+
+// Prettier main
+class A {
+  @dec()
+  // comment
+  accessor b;
+}
+```
diff --git a/src/language-js/comments.js b/src/language-js/comments.js
index cb32c25a13f0..560c278192b9 100644
--- a/src/language-js/comments.js
+++ b/src/language-js/comments.js
@@ -453,6 +453,9 @@ const propertyLikeNodeTypes = new Set([
   "TSAbstractMethodDefinition",
   "TSDeclareMethod",
   "MethodDefinition",
+  "ClassAccessorProperty",
+  "AccessorProperty",
+  "TSAbstractAccessorProperty",
 ]);
 function handleMethodNameComments({
   comment,


Test patch:
diff --git a/tests/config/format-test.js b/tests/config/format-test.js
index 3574fddf1e40..90a11e752bbe 100644
--- a/tests/config/format-test.js
+++ b/tests/config/format-test.js
@@ -72,6 +72,7 @@ const meriyahDisabledTests = new Set([
     "static.js",
     "with-semicolon-1.js",
     "with-semicolon-2.js",
+    "comments.js",
   ].map((filename) =>
     path.join(__dirname, "../format/js/decorator-auto-accessors", filename)
   ),
diff --git a/tests/format/js/decorator-auto-accessors/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/decorator-auto-accessors/__snapshots__/jsfmt.spec.js.snap
index a6850f56f69b..2263bc534b61 100644
--- a/tests/format/js/decorator-auto-accessors/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/js/decorator-auto-accessors/__snapshots__/jsfmt.spec.js.snap
@@ -73,6 +73,91 @@ class Foo {
 ================================================================================
 `;
 
+exports[`comments.js [acorn] format 1`] = `
+"Unexpected character '@' (2:3)
+  1 | class A {
+> 2 |   @dec()
+    |   ^
+  3 |   // comment
+  4 |   accessor b;
+  5 | }"
+`;
+
+exports[`comments.js [espree] format 1`] = `
+"Unexpected character '@' (2:3)
+  1 | class A {
+> 2 |   @dec()
+    |   ^
+  3 |   // comment
+  4 |   accessor b;
+  5 | }"
+`;
+
+exports[`comments.js - {"semi":false} [acorn] format 1`] = `
+"Unexpected character '@' (2:3)
+  1 | class A {
+> 2 |   @dec()
+    |   ^
+  3 |   // comment
+  4 |   accessor b;
+  5 | }"
+`;
+
+exports[`comments.js - {"semi":false} [espree] format 1`] = `
+"Unexpected character '@' (2:3)
+  1 | class A {
+> 2 |   @dec()
+    |   ^
+  3 |   // comment
+  4 |   accessor b;
+  5 | }"
+`;
+
+exports[`comments.js - {"semi":false} format 1`] = `
+====================================options=====================================
+parsers: ["babel", "typescript", "babel-flow"]
+printWidth: 80
+semi: false
+                                                                                | printWidth
+=====================================input======================================
+class A {
+  @dec()
+  // comment
+  accessor b;
+}
+
+=====================================output=====================================
+class A {
+  @dec()
+  // comment
+  accessor b
+}
+
+================================================================================
+`;
+
+exports[`comments.js format 1`] = `
+====================================options=====================================
+parsers: ["babel", "typescript", "babel-flow"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+class A {
+  @dec()
+  // comment
+  accessor b;
+}
+
+=====================================output=====================================
+class A {
+  @dec()
+  // comment
+  accessor b;
+}
+
+================================================================================
+`;
+
 exports[`computed.js [acorn] format 1`] = `
 "Unexpected token (2:12)
   1 | class Foo {
diff --git a/tests/format/js/decorator-auto-accessors/comments.js b/tests/format/js/decorator-auto-accessors/comments.js
new file mode 100644
index 000000000000..73640ec2a1a4
--- /dev/null
+++ b/tests/format/js/decorator-auto-accessors/comments.js
@@ -0,0 +1,5 @@
+class A {
+  @dec()
+  // comment
+  accessor b;
+}
diff --git a/tests/format/js/decorator-auto-accessors/jsfmt.spec.js b/tests/format/js/decorator-auto-accessors/jsfmt.spec.js
index 85acc64686de..8c402a09ea0b 100644
--- a/tests/format/js/decorator-auto-accessors/jsfmt.spec.js
+++ b/tests/format/js/decorator-auto-accessors/jsfmt.spec.js
@@ -9,6 +9,7 @@ const errors = {
     "static.js",
     "with-semicolon-1.js",
     "with-semicolon-2.js",
+    "comments.js",
   ],
   acorn: [
     "basic.js",
@@ -19,6 +20,7 @@ const errors = {
     "static.js",
     "with-semicolon-1.js",
     "with-semicolon-2.js",
+    "comments.js",
   ],
 };
 run_spec(__dirname, parsers, { errors });