Repository: prettier/prettier (JavaScript)
Date: 2018-02-16 03:20:21+00:00
Task type: Bug Fix

Issue:
Semi is removed from `declare export default` statement in flow libdef
**Prettier 1.10.2**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEATOYA2BDATnAAjgA8AHCXGA9AM2wFdMqBWAbgB0oQAaECUmAEtoAZ2Sg8uCAHcACngRiU2AG4RBqHiGwiYyOphFxeAI1zYwAazgwAyqQuCoAc2Qxc9Y2ghh92Q15ORpSy5s4Atth+AbwAViLEAELmVja22OFwADJOcNFGvBD0MKTFAEz5Xg64wcggJtgmAJ6Y0FqkuE4wAOoaMAAWyAAcAAy8HRBG3eakdR1wwSp5vPgAjvSC+KHYEVFIBgUgRuGCbh5eIk7OmHAAivQQ8JW8MI29qAPIZS-mgphXAGEIOFInUoNBliB6EYACqNJQHOAAXyRQA)

(Not using `--no-semi`)

**Input:**
```jsx
declare export default 5;

```

**Output:**
```jsx
declare export default 5

```

**Expected behavior:**
```jsx
declare export default 5;

```



Issue discussion:
[Also reproducible using the Flow parser](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEATOYA2BDATnAAjgA8AHCXGA9AM2wFdMqBWAbgB0oQAaECUmAEtoAZ2Sg8uCAHcACngRiU2AG4RBqHiGwiYyOphFxeAI1zYwAazgwAyqQuCoAc2Qxc9Y2ghh92Q15ORpSy5s4Atth+AbwAViLEAELmVja22OFwADJOcNFGvBD0MKTFAEz5Xg64wcggNJgyWqS4TjAA6howABbIABwADLwtEEbt5qR1LXDBKnm8+ACO9IL4odgRUUgGBSBG4YJuHl4iTs6YcACK9BDwlbww2CadqD3IZQ-mgphnAMIQ4UidSg0HmIHoRgAKk8lDs4ABfeFAA).

Solution patch:
diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js
index 5c4515413777..a73586783909 100644
--- a/src/language-js/printer-estree.js
+++ b/src/language-js/printer-estree.js
@@ -3485,7 +3485,9 @@ function printExportDeclaration(path, options, print) {
   const semi = options.semi ? ";" : "";
   const parts = ["export "];
 
-  if (decl["default"] || decl.type === "ExportDefaultDeclaration") {
+  const isDefault = decl["default"] || decl.type === "ExportDefaultDeclaration";
+
+  if (isDefault) {
     parts.push("default ");
   }
 
@@ -3497,10 +3499,12 @@ function printExportDeclaration(path, options, print) {
     parts.push(path.call(print, "declaration"));
 
     if (
-      decl.type === "ExportDefaultDeclaration" &&
+      isDefault &&
       (decl.declaration.type !== "ClassDeclaration" &&
         decl.declaration.type !== "FunctionDeclaration" &&
-        decl.declaration.type !== "TSAbstractClassDeclaration")
+        decl.declaration.type !== "TSAbstractClassDeclaration" &&
+        decl.declaration.type !== "DeclareClass" &&
+        decl.declaration.type !== "DeclareFunction")
     ) {
       parts.push(semi);
     }


Test patch:
diff --git a/tests/flow/declare_export/__snapshots__/jsfmt.spec.js.snap b/tests/flow/declare_export/__snapshots__/jsfmt.spec.js.snap
index 6e430513e0c7..7de365958871 100644
--- a/tests/flow/declare_export/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow/declare_export/__snapshots__/jsfmt.spec.js.snap
@@ -142,7 +142,7 @@ declare export default () => number;
  * @flow
  */
 
-declare export default () => number
+declare export default () => number;
 
 `;
 
@@ -159,7 +159,7 @@ declare export default () =>number;
  * @flow
  */
 
-declare export default () => number
+declare export default () => number;
 
 `;
 
@@ -251,7 +251,7 @@ declare export var str: string;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 /* @flow */
 
-declare export default number
+declare export default number;
 declare export var str: string;
 
 `;
diff --git a/tests/flow_type_declarations/__snapshots__/jsfmt.spec.js.snap b/tests/flow_type_declarations/__snapshots__/jsfmt.spec.js.snap
index d934996626b0..20c36519c502 100644
--- a/tests/flow_type_declarations/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/flow_type_declarations/__snapshots__/jsfmt.spec.js.snap
@@ -1,5 +1,19 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`declare_export.js 1`] = `
+declare export default 5;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+declare export default 5;
+
+`;
+
+exports[`declare_export.js 2`] = `
+declare export default 5;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+declare export default 5
+
+`;
+
 exports[`declare_type.js 1`] = `
 declare type A = string;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -7,6 +21,13 @@ declare type A = string;
 
 `;
 
+exports[`declare_type.js 2`] = `
+declare type A = string;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+declare type A = string
+
+`;
+
 exports[`declare_var.js 1`] = `
 declare var bool: React$PropType$Primitive<boolean>;
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -14,6 +35,13 @@ declare var bool: React$PropType$Primitive<boolean>;
 
 `;
 
+exports[`declare_var.js 2`] = `
+declare var bool: React$PropType$Primitive<boolean>;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+declare var bool: React$PropType$Primitive<boolean>
+
+`;
+
 exports[`long.js 1`] = `
 export type AdamPlacementValidationSingleErrorKey =
   'SOME_FANCY_TARGETS.GLOBAL_TARGET';
@@ -35,6 +63,27 @@ type SomeOtherLongLongLongLongLongLongLongLongLongLongLongLongLongLongKey = Some
 
 `;
 
+exports[`long.js 2`] = `
+export type AdamPlacementValidationSingleErrorKey =
+  'SOME_FANCY_TARGETS.GLOBAL_TARGET';
+
+export type SomeReallyLongLongLongLongLongLongLongLongLongLongLongLongLongLongKey = true;
+
+export type SomeOtherLongLongLongLongLongLongLongLongLongLongLongLongLongLongKey = null;
+
+type SomeOtherLongLongLongLongLongLongLongLongLongLongLongLongLongLongKey = SomeReallyLongLongLongLongLongLongIdentifier;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+export type AdamPlacementValidationSingleErrorKey =
+  "SOME_FANCY_TARGETS.GLOBAL_TARGET"
+
+export type SomeReallyLongLongLongLongLongLongLongLongLongLongLongLongLongLongKey = true
+
+export type SomeOtherLongLongLongLongLongLongLongLongLongLongLongLongLongLongKey = null
+
+type SomeOtherLongLongLongLongLongLongLongLongLongLongLongLongLongLongKey = SomeReallyLongLongLongLongLongLongIdentifier
+
+`;
+
 exports[`opaque.js 1`] = `
 declare export opaque type Foo;
 declare export opaque type Bar<T>;
@@ -67,3 +116,36 @@ opaque type union = { type: "A" } | { type: "B" };
 opaque type overloads = ((x: string) => number) & ((x: number) => string);
 
 `;
+
+exports[`opaque.js 2`] = `
+declare export opaque type Foo;
+declare export opaque type Bar<T>;
+declare export opaque type Baz: Foo;
+declare export opaque type Foo<T>: Bar<T>;
+declare export opaque type Foo<T>: Bar;
+declare export opaque type Foo: Bar<T>;
+opaque type ID = string;
+opaque type Foo<T> = Bar<T>;
+opaque type Maybe<T> = _Maybe<T, *>;
+export opaque type Foo = number;
+opaque type union =
+ | {type: "A"}
+ | {type: "B"};
+opaque type overloads =
+  & ((x: string) => number)
+  & ((x: number) => string);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+declare export opaque type Foo
+declare export opaque type Bar<T>
+declare export opaque type Baz: Foo
+declare export opaque type Foo<T>: Bar<T>
+declare export opaque type Foo<T>: Bar
+declare export opaque type Foo: Bar<T>
+opaque type ID = string
+opaque type Foo<T> = Bar<T>
+opaque type Maybe<T> = _Maybe<T, *>
+export opaque type Foo = number
+opaque type union = { type: "A" } | { type: "B" }
+opaque type overloads = ((x: string) => number) & ((x: number) => string)
+
+`;
diff --git a/tests/flow_type_declarations/declare_export.js b/tests/flow_type_declarations/declare_export.js
new file mode 100644
index 000000000000..75b7fac8e24c
--- /dev/null
+++ b/tests/flow_type_declarations/declare_export.js
@@ -0,0 +1,1 @@
+declare export default 5;
diff --git a/tests/flow_type_declarations/jsfmt.spec.js b/tests/flow_type_declarations/jsfmt.spec.js
index c1ba82f46794..c5f8baf641f2 100644
--- a/tests/flow_type_declarations/jsfmt.spec.js
+++ b/tests/flow_type_declarations/jsfmt.spec.js
@@ -1,1 +1,2 @@
 run_spec(__dirname, ["flow", "babylon"]);
+run_spec(__dirname, ["flow", "babylon"], { semi: false });