Repository: prettier/prettier (JavaScript)
Date: 2018-09-12 01:47:07+00:00
Task type: Bug Fix

Issue:
--no-semi got ignored on typescript indexed class property annotation
**Prettier 1.14.2**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuc0DOMAEBrAQgVwDNC4AnTAXkwGUBPAWwCMIAbACgHJGiTSOBKADpRIUDDgDyxNHCxU6TVpwjTZA4cLAsAhmjSYASnG0ATMpmDDMmAA6kAlgDdt8TAG08PMgF0kmAsTmAPRBmAA8ALQRmAAWZHBWtg7Orh5ShDIwvphQ+ExkwgC+IAA0IBA2MPboyKDapKQQAO4ACvUIaMgg2o4Q9ialIIyk2mDYstQ2o-ZQAObIMKT4cGUzMqQwLSOz9NrIhNosMmUAVmgAHrgjYxPa9HAAMjNw+4fHIFOk610wtDZwaDADkqgzsMxgAHV+jAYsgABwABjKdggMghIxsXTsALIjheZVIcAAjvh7ISttodnskAcjisQDJ6PZXnSymgZrMWHAAIr4CDwBZLekwbSMKEmGHIABMZUW2nsLA5AGEIPRdl0oNB8SB8DIACqizo0t5wQqFIA)
```sh
--parser typescript
--no-semi
--single-quote
```

**Input:**
```tsx
const kBuffer = Symbol('buffer')
const kOffset = Symbol('offset')

class Reader {
  private [kBuffer]: Buffer // <-- here
  private [kOffset]: number
}
```

**Output:**
```tsx
const kBuffer = Symbol('buffer')
const kOffset = Symbol('offset')

class Reader {
  private [kBuffer]: Buffer; // <-- here
  private [kOffset]: number
}

```

**Expected behavior:**
```tsx
const kBuffer = Symbol('buffer')
const kOffset = Symbol('offset')

class Reader {
  private [kBuffer]: Buffer // <-- here
  private [kOffset]: number
}

```

Without semi colon there, it compiles just fine.


Issue discussion:
Minimal repro:

**Prettier 1.14.2**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAucAbAhgZ0wAgGIQQ7AA6UOOARugE5I4CCZFADjQJYBu68OA2tQBeAXTIBfEABoQEFjHbRMyULRoQA7gAVaCJSnScI7ACZSQlGujABrODADKLK+ygBzZDBoBXONJeY4GhhNS1cAW3RkADN0VADpACtMAA8AIUsbO3t0MLgAGRc4aNj4kCcaAJpkEBgATxY4TDAOOTM2FxgAdRMYAAtkAA4ABmk2CADOyxZqtkbAziLpGjgARy92ZZD0cMikGLjfEACw9mKD6UwXV1Q4AEUvCHgPb0OYdEpu4z7kACZpT3Q7FQVwAwhAwhFqlBoIsQF4AgAVd56fYBMRiIA)
```sh
--parser typescript
--no-semi
--single-quote
```

**Input:**
```tsx
class Foo {
  bar: A
  private [baz]
}
```

**Output:**
```tsx
class Foo {
  bar: A;
  private [baz]
}

```

Solution patch:
diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js
index 9ee0c68983c0..4e7f9476af38 100644
--- a/src/language-js/printer-estree.js
+++ b/src/language-js/printer-estree.js
@@ -5529,6 +5529,13 @@ function classChildNeedsASIProtection(node) {
     return;
   }
 
+  if (
+    node.static ||
+    node.accessibility // TypeScript
+  ) {
+    return false;
+  }
+
   if (!node.computed) {
     const name = node.key && node.key.name;
     if (name === "in" || name === "instanceof") {
@@ -5545,12 +5552,7 @@ function classChildNeedsASIProtection(node) {
       // Babylon
       const isAsync = node.value ? node.value.async : node.async;
       const isGenerator = node.value ? node.value.generator : node.generator;
-      if (
-        isAsync ||
-        node.static ||
-        node.kind === "get" ||
-        node.kind === "set"
-      ) {
+      if (isAsync || node.kind === "get" || node.kind === "set") {
         return false;
       }
       if (node.computed || isGenerator) {


Test patch:
diff --git a/tests/no-semi-typescript/__snapshots__/jsfmt.spec.js.snap b/tests/no-semi-typescript/__snapshots__/jsfmt.spec.js.snap
new file mode 100644
index 000000000000..b75f2ba1ffad
--- /dev/null
+++ b/tests/no-semi-typescript/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,51 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`no-semi.ts - typescript-verify 1`] = `
+class A {
+  bar: A;
+  [baz]
+
+  // none of the semicolons above this comment can be omitted.
+  // none of the semicolons below this comment are necessary.
+
+  bar: A;
+  private [baz]
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class A {
+  bar: A;
+  [baz];
+
+  // none of the semicolons above this comment can be omitted.
+  // none of the semicolons below this comment are necessary.
+
+  bar: A;
+  private [baz];
+}
+
+`;
+
+exports[`no-semi.ts - typescript-verify 2`] = `
+class A {
+  bar: A;
+  [baz]
+
+  // none of the semicolons above this comment can be omitted.
+  // none of the semicolons below this comment are necessary.
+
+  bar: A;
+  private [baz]
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class A {
+  bar: A;
+  [baz]
+
+  // none of the semicolons above this comment can be omitted.
+  // none of the semicolons below this comment are necessary.
+
+  bar: A
+  private [baz]
+}
+
+`;
diff --git a/tests/no-semi-typescript/jsfmt.spec.js b/tests/no-semi-typescript/jsfmt.spec.js
new file mode 100644
index 000000000000..ba52aeb62efa
--- /dev/null
+++ b/tests/no-semi-typescript/jsfmt.spec.js
@@ -0,0 +1,2 @@
+run_spec(__dirname, ["typescript"]);
+run_spec(__dirname, ["typescript"], { semi: false });
diff --git a/tests/no-semi-typescript/no-semi.ts b/tests/no-semi-typescript/no-semi.ts
new file mode 100644
index 000000000000..19134b85802c
--- /dev/null
+++ b/tests/no-semi-typescript/no-semi.ts
@@ -0,0 +1,10 @@
+class A {
+  bar: A;
+  [baz]
+
+  // none of the semicolons above this comment can be omitted.
+  // none of the semicolons below this comment are necessary.
+
+  bar: A;
+  private [baz]
+}