From 36ab72f095cb281415b8bd0d2f0fdf9d0794435c Mon Sep 17 00:00:00 2001 From: Daniel Tschinder Date: Thu, 8 Jun 2017 23:15:54 +0200 Subject: [PATCH] Support declare export statements (#5589) * Add definition of declare export statements * Add more codecoverage --- .../babel-generator/src/generators/flow.js | 77 ++++++++++++++++--- .../fixtures/flow/declare-exports/actual.js | 24 ++++++ .../fixtures/flow/declare-exports/expected.js | 24 ++++++ .../strip-declare-exports/actual.js | 15 ++++ .../strip-declare-statements/actual.js | 1 + packages/babel-types/src/definitions/flow.js | 16 ++++ 6 files changed, 148 insertions(+), 9 deletions(-) create mode 100644 packages/babel-generator/test/fixtures/flow/declare-exports/actual.js create mode 100644 packages/babel-generator/test/fixtures/flow/declare-exports/expected.js create mode 100644 packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-declare-exports/actual.js diff --git a/packages/babel-generator/src/generators/flow.js b/packages/babel-generator/src/generators/flow.js index 4fc45faeda..2425fa15df 100644 --- a/packages/babel-generator/src/generators/flow.js +++ b/packages/babel-generator/src/generators/flow.js @@ -1,3 +1,5 @@ +import * as t from "babel-types"; + export function AnyTypeAnnotation() { this.word("any"); } @@ -20,17 +22,21 @@ export function NullLiteralTypeAnnotation() { this.word("null"); } -export function DeclareClass(node: Object) { - this.word("declare"); - this.space(); +export function DeclareClass(node: Object, parent: Object) { + if (!t.isDeclareExportDeclaration(parent)) { + this.word("declare"); + this.space(); + } this.word("class"); this.space(); this._interfaceish(node); } -export function DeclareFunction(node: Object) { - this.word("declare"); - this.space(); +export function DeclareFunction(node: Object, parent: Object) { + if (!t.isDeclareExportDeclaration(parent)) { + this.word("declare"); + this.space(); + } this.word("function"); this.space(); this.print(node.id, node); @@ -69,9 +75,11 @@ export function DeclareTypeAlias(node: Object) { this.TypeAlias(node); } -export function DeclareVariable(node: Object) { - this.word("declare"); - this.space(); +export function DeclareVariable(node: Object, parent: Object) { + if (!t.isDeclareExportDeclaration(parent)) { + this.word("declare"); + this.space(); + } this.word("var"); this.space(); this.print(node.id, node); @@ -79,6 +87,57 @@ export function DeclareVariable(node: Object) { this.semicolon(); } +export function DeclareExportDeclaration(node: Object) { + this.word("declare"); + this.space(); + this.word("export"); + this.space(); + if (node.default) { + this.word("default"); + this.space(); + } + + FlowExportDeclaration.apply(this, arguments); +} + +export function DeclareExportAllDeclaration(node: Object) { + this.word("declare"); + this.space(); + this.word("export"); + this.space(); + this.token("*"); + this.space(); + this.word("from"); + this.space(); + this.print(node.source, node); + this.semicolon(); +} + +function FlowExportDeclaration(node: Object) { + if (node.declaration) { + const declar = node.declaration; + this.print(declar, node); + if (!t.isStatement(declar)) this.semicolon(); + } else { + this.token("{"); + if (node.specifiers.length) { + this.space(); + this.printList(node.specifiers, node); + this.space(); + } + this.token("}"); + + if (node.source) { + this.space(); + this.word("from"); + this.space(); + this.print(node.source, node); + } + + this.semicolon(); + } +} + export function ExistsTypeAnnotation() { this.token("*"); } diff --git a/packages/babel-generator/test/fixtures/flow/declare-exports/actual.js b/packages/babel-generator/test/fixtures/flow/declare-exports/actual.js new file mode 100644 index 0000000000..8cc628e464 --- /dev/null +++ b/packages/babel-generator/test/fixtures/flow/declare-exports/actual.js @@ -0,0 +1,24 @@ +declare export var foo +declare export var foo; +declare export function foo(): void +declare export function foo(): void; +declare export function foo(): void; +declare export function foo(x: number, y: string): void; +declare export class A {} +declare export class A extends B { x: number } +declare export class A { static foo(): number; static x : string } +declare export class A { static [ indexer: number]: string } +declare export class A { static () : number } +declare export class A mixins B, C {} +declare export default class A {} +declare export default function foo(): void; +declare export default string +declare export * from 'asd'; +declare export { a, b }; +declare export {}; +declare export { c, d } from 'bar'; + +declare module B { + declare export type B = {}; + declare export interface Moon {} +} diff --git a/packages/babel-generator/test/fixtures/flow/declare-exports/expected.js b/packages/babel-generator/test/fixtures/flow/declare-exports/expected.js new file mode 100644 index 0000000000..4a2e68ebfc --- /dev/null +++ b/packages/babel-generator/test/fixtures/flow/declare-exports/expected.js @@ -0,0 +1,24 @@ +declare export var foo; +declare export var foo; +declare export function foo(): void; +declare export function foo(): void; +declare export function foo(): void; +declare export function foo(x: number, y: string): void; +declare export class A {} +declare export class A extends B { x: number } +declare export class A { static foo: () => number, static x: string, } +declare export class A { static [indexer: number]: string } +declare export class A { static (): number } +declare export class A mixins B, C {} +declare export default class A {} +declare export default function foo(): void; +declare export default string; +declare export * from 'asd'; +declare export { a, b }; +declare export {}; +declare export { c, d } from 'bar'; + +declare module B { + declare export type B = {}; + declare export interface Moon {} +} diff --git a/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-declare-exports/actual.js b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-declare-exports/actual.js new file mode 100644 index 0000000000..bf8f624350 --- /dev/null +++ b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-declare-exports/actual.js @@ -0,0 +1,15 @@ +declare export var foo +declare export var foo; +declare export function foo(): void +declare export function foo(): void; +declare export function foo(): void; +declare export function foo(x: number, y: string): void; +declare export class A {} +declare export class A extends B { x: number } +declare export class A { static foo(): number; static x : string } +declare export class A { static [ indexer: number]: string } +declare export class A { static () : number } +declare export class A mixins B, C {} +declare export default class A {} +declare export default function foo(): void; +declare export default string \ No newline at end of file diff --git a/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-declare-statements/actual.js b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-declare-statements/actual.js index 1c62d8ee90..75b2482839 100644 --- a/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-declare-statements/actual.js +++ b/packages/babel-plugin-transform-flow-strip-types/test/fixtures/strip-types/strip-declare-statements/actual.js @@ -14,3 +14,4 @@ declare type A = string declare type T = { [k:string]: U } declare interface I { foo: string } declare interface I { foo: T } +declare module.exports: string; diff --git a/packages/babel-types/src/definitions/flow.js b/packages/babel-types/src/definitions/flow.js index 3781435e26..2bb5d372b2 100644 --- a/packages/babel-types/src/definitions/flow.js +++ b/packages/babel-types/src/definitions/flow.js @@ -111,6 +111,22 @@ defineType("DeclareVariable", { }, }); +defineType("DeclareExportDeclaration", { + visitor: ["declaration", "specifiers", "source"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + // todo + }, +}); + +defineType("DeclareExportAllDeclaration", { + visitor: ["source"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + // todo + }, +}); + defineType("ExistsTypeAnnotation", { aliases: ["Flow"], });