diff --git a/packages/babel-plugin-flow-comments/.npmignore b/packages/babel-plugin-flow-comments/.npmignore new file mode 100644 index 0000000000..31852902b1 --- /dev/null +++ b/packages/babel-plugin-flow-comments/.npmignore @@ -0,0 +1,4 @@ +node_modules +*.log +src +test diff --git a/packages/babel-plugin-flow-comments/README.md b/packages/babel-plugin-flow-comments/README.md new file mode 100644 index 0000000000..a8dd93e4ef --- /dev/null +++ b/packages/babel-plugin-flow-comments/README.md @@ -0,0 +1,71 @@ +# babel-plugin-flow-comments + +Turn flow type annotations into comments. + +You should be able to use this plugin instead of `babel-plugin-flow-strip-types` to preserve the `/* @flow */` directive and still use flow. + +http://flowtype.org/blog/2015/02/20/Flow-Comments.html + +## Example + +**In** + +```javascript +function foo(bar?) {} +function foo2(bar?: string) {} +function foo(x: number): string {} +type B = { + name: string; +}; +export type GraphQLFormattedError = number; +import type A, { B, C } from './types'; +import typeof D, { E, F } from './types'; +``` + +**Out** + +```javascript +"use strict"; + +function foo(bar /*:: ?*/) {} +function foo2(bar /*:: ?: string*/) {} +function foo(x /*: number*/) /*: string*/ {} +/*:: type B = { + name: string; +};*/ +/*:: export type GraphQLFormattedError = number;*/ +/*:: import type A, { B, C } from './types';*/ +/*:: import typeof D, { E, F } from './types';*/ +``` + +## Installation + +```sh +$ npm install babel-plugin-flow-comments +``` + +## Usage + +### Via `.babelrc` (Recommended) + +**.babelrc** + +```json +{ + "plugins": ["flow-comments"] +} +``` + +### Via CLI + +```sh +$ babel --plugins flow-comments script.js +``` + +### Via Node API + +```javascript +require("babel-core").transform("code", { + plugins: ["flow-comments"] +}); +``` diff --git a/packages/babel-plugin-flow-comments/package.json b/packages/babel-plugin-flow-comments/package.json new file mode 100644 index 0000000000..950f61a001 --- /dev/null +++ b/packages/babel-plugin-flow-comments/package.json @@ -0,0 +1,18 @@ +{ + "name": "babel-plugin-flow-comments", + "version": "1.0.9", + "description": "Turn flow type annotations into comments", + "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-flow-comments", + "license": "MIT", + "main": "lib/index.js", + "keywords": [ + "babel-plugin" + ], + "dependencies": { + "babel-runtime": "^5.0.0", + "babel-plugin-syntax-flow": "^6.3.13" + }, + "devDependencies": { + "babel-helper-plugin-test-runner": "^6.3.13" + } +} diff --git a/packages/babel-plugin-flow-comments/src/index.js b/packages/babel-plugin-flow-comments/src/index.js new file mode 100644 index 0000000000..a44283c395 --- /dev/null +++ b/packages/babel-plugin-flow-comments/src/index.js @@ -0,0 +1,59 @@ +export default function ({ types: t }) { + function wrapInFlowComment(path, parent) { + path.addComment("trailing", generateComment(path, parent)); + path.replaceWith(t.noop()); + } + + function generateComment(path, parent) { + let comment = path.getSource().replace(/\*-\//g, "*-ESCAPED/").replace(/\*\//g, "*-/"); + if (parent && parent.optional) comment = "?" + comment; + if (comment[0] !== ":") comment = ":: " + comment; + return comment; + } + + return { + inherits: require("babel-plugin-syntax-flow"), + + visitor: { + TypeCastExpression(path) { + let { node } = path; + path.get("expression").addComment("trailing", generateComment(path.get("typeAnnotation"))); + path.replaceWith(t.parenthesizedExpression(node.expression)); + }, + + // support function a(b?) {} + Identifier(path) { + let { node } = path; + if (!node.optional || node.typeAnnotation) { + return; + } + path.addComment("trailing", ":: ?"); + }, + + // strip optional property from function params - facebook/fbjs#17 + Function: { + exit({ node }) { + node.params.forEach(param => param.optional = false); + } + }, + + // support `export type a = {}` - #8 Error: You passed path.replaceWith() a falsy node + "ExportNamedDeclaration|Flow"(path) { + let { node, parent } = path; + if (t.isExportNamedDeclaration(node) && !t.isFlow(node.declaration)) { + return; + } + wrapInFlowComment(path, parent); + }, + + // support `import type A` and `import typeof A` #10 + ImportDeclaration(path) { + let { node, parent } = path; + if (t.isImportDeclaration(node) && node.importKind !== "type" && node.importKind !== "typeof") { + return; + } + wrapInFlowComment(path, parent); + } + } + }; +} diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/export-type-alias/actual.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/export-type-alias/actual.js new file mode 100644 index 0000000000..d6cfe05632 --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/export-type-alias/actual.js @@ -0,0 +1,8 @@ +export type GraphQLFormattedError = number; +export type GraphQLFormattedError = { + message: string, + locations?: Array<{ + line: number, + column: number + }> +}; \ No newline at end of file diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/export-type-alias/expected.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/export-type-alias/expected.js new file mode 100644 index 0000000000..6f072c7a6c --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/export-type-alias/expected.js @@ -0,0 +1,8 @@ +/*:: export type GraphQLFormattedError = number;*/ +/*:: export type GraphQLFormattedError = { + message: string, + locations?: Array<{ + line: number, + column: number + }> +};*/ diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/import-type-alias/actual.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/import-type-alias/actual.js new file mode 100644 index 0000000000..11934d8c50 --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/import-type-alias/actual.js @@ -0,0 +1,3 @@ +import lib from 'library'; +import type A, { B, C } from './types'; +import typeof D, { E, F } from './types'; diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/import-type-alias/expected.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/import-type-alias/expected.js new file mode 100644 index 0000000000..6cd8953601 --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/import-type-alias/expected.js @@ -0,0 +1,3 @@ +import lib from 'library'; +/*:: import type A, { B, C } from './types';*/ +/*:: import typeof D, { E, F } from './types';*/ diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/optional-parameters/actual.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/optional-parameters/actual.js new file mode 100644 index 0000000000..7867942f63 --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/optional-parameters/actual.js @@ -0,0 +1 @@ +function multiply(num?: number) {} diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/optional-parameters/expected.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/optional-parameters/expected.js new file mode 100644 index 0000000000..b969f8d3a7 --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/optional-parameters/expected.js @@ -0,0 +1 @@ +function multiply(num /*:: ?: number*/) {} diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/optional-type/actual.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/optional-type/actual.js new file mode 100644 index 0000000000..9cd75df01d --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/optional-type/actual.js @@ -0,0 +1,2 @@ +function foo(bar?) {} +function foo2(bar?: string) {} diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/optional-type/expected.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/optional-type/expected.js new file mode 100644 index 0000000000..556c1ea95f --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/optional-type/expected.js @@ -0,0 +1,2 @@ +function foo(bar /*:: ?*/) {} +function foo2(bar /*:: ?: string*/) {} diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/options.json b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/options.json new file mode 100644 index 0000000000..e3fdfb4934 --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["flow-comments"] +} diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-alias-with-comment/actual.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-alias-with-comment/actual.js new file mode 100644 index 0000000000..a5cde7812d --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-alias-with-comment/actual.js @@ -0,0 +1,6 @@ +type T = /*test*/ number; +type T2 = /* *-/ */ number; +type CustomType = { +/** This is some documentation. */ +name: string; +}; diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-alias-with-comment/expected.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-alias-with-comment/expected.js new file mode 100644 index 0000000000..6fa86e739d --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-alias-with-comment/expected.js @@ -0,0 +1,6 @@ +/*:: type T = /*test*-/ number;*/ +/*:: type T2 = /* *-ESCAPED/ *-/ number;*/ +/*:: type CustomType = { +/** This is some documentation. *-/ +name: string; +};*/ diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-alias/actual.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-alias/actual.js new file mode 100644 index 0000000000..ad452150bc --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-alias/actual.js @@ -0,0 +1,5 @@ +function a() {} +type A = number; +type B = { + name: string; +}; diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-alias/expected.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-alias/expected.js new file mode 100644 index 0000000000..59cf6c2adc --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-alias/expected.js @@ -0,0 +1,5 @@ +function a() {} +/*:: type A = number;*/ +/*:: type B = { + name: string; +};*/ diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-cast/actual.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-cast/actual.js new file mode 100644 index 0000000000..e6323a9faa --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-cast/actual.js @@ -0,0 +1,2 @@ +var a = (y: any); +var a = ((y: foo): any); diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-cast/expected.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-cast/expected.js new file mode 100644 index 0000000000..1b2c5f2b1f --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type-cast/expected.js @@ -0,0 +1,2 @@ +var a = (y /*: any*/); +var a = ((y /*: foo*/) /*: any*/); diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type/actual.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type/actual.js new file mode 100644 index 0000000000..4c8531cc47 --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type/actual.js @@ -0,0 +1 @@ +function foo(x: number): string {} diff --git a/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type/expected.js b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type/expected.js new file mode 100644 index 0000000000..1525b83e9a --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/fixtures/flow-comments/type/expected.js @@ -0,0 +1 @@ +function foo(x /*: number*/) /*: string*/ {} diff --git a/packages/babel-plugin-flow-comments/test/index.js b/packages/babel-plugin-flow-comments/test/index.js new file mode 100644 index 0000000000..1f6634aabd --- /dev/null +++ b/packages/babel-plugin-flow-comments/test/index.js @@ -0,0 +1 @@ +require("babel-helper-plugin-test-runner")(__dirname);