diff --git a/packages/babel-plugin-transform-flow-comments/package.json b/packages/babel-plugin-transform-flow-comments/package.json index 35772e6bb25c..365b64331122 100644 --- a/packages/babel-plugin-transform-flow-comments/package.json +++ b/packages/babel-plugin-transform-flow-comments/package.json @@ -12,6 +12,7 @@ "babel-plugin" ], "dependencies": { + "@babel/generator": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-flow": "^7.2.0" }, diff --git a/packages/babel-plugin-transform-flow-comments/src/index.js b/packages/babel-plugin-transform-flow-comments/src/index.js index 0389a046e9c5..2d54ae9d9854 100644 --- a/packages/babel-plugin-transform-flow-comments/src/index.js +++ b/packages/babel-plugin-transform-flow-comments/src/index.js @@ -1,21 +1,26 @@ import { declare } from "@babel/helper-plugin-utils"; import syntaxFlow from "@babel/plugin-syntax-flow"; import { types as t } from "@babel/core"; +import generateCode from "@babel/generator"; export default declare(api => { api.assertVersion(7); - function wrapInFlowComment(path, parent) { + function attachComment(path, comment) { let attach = path.getPrevSibling(); let where = "trailing"; if (!attach.node) { attach = path.parentPath; where = "inner"; } - attach.addComment(where, generateComment(path, parent)); + attach.addComment(where, comment); path.remove(); } + function wrapInFlowComment(path, parent) { + attachComment(path, generateComment(path, parent)); + } + function generateComment(path, parent) { let comment = path .getSource() @@ -26,6 +31,10 @@ export default declare(api => { return comment; } + function isTypeImport(importKind) { + return importKind === "type" || importKind === "typeof"; + } + return { name: "transform-flow-comments", inherits: syntaxFlow, @@ -122,10 +131,33 @@ export default declare(api => { // support `import type A` and `import typeof A` #10 ImportDeclaration(path) { const { node, parent } = path; - if (node.importKind !== "type" && node.importKind !== "typeof") { + if (isTypeImport(node.importKind)) { + wrapInFlowComment(path, parent); return; } - wrapInFlowComment(path, parent); + + const typeSpecifiers = node.specifiers.filter(specifier => + isTypeImport(specifier.importKind), + ); + + const nonTypeSpecifiers = node.specifiers.filter( + specifier => !isTypeImport(specifier.importKind), + ); + node.specifiers = nonTypeSpecifiers; + + if (typeSpecifiers.length > 0) { + const typeImportNode = t.cloneNode(node); + typeImportNode.specifiers = typeSpecifiers; + + if (nonTypeSpecifiers.length > 0) { + path.addComment( + "trailing", + `:: ${generateCode(typeImportNode).code}`, + ); + } else { + attachComment(path, `:: ${generateCode(typeImportNode).code}`); + } + } }, ObjectPattern(path) { const { node } = path; diff --git a/packages/babel-plugin-transform-flow-comments/test/fixtures/flow-comments/import-type-alias-2/input.mjs b/packages/babel-plugin-transform-flow-comments/test/fixtures/flow-comments/import-type-alias-2/input.mjs new file mode 100644 index 000000000000..a68a3a9af8cb --- /dev/null +++ b/packages/babel-plugin-transform-flow-comments/test/fixtures/flow-comments/import-type-alias-2/input.mjs @@ -0,0 +1,5 @@ +import A, { B, type C, type D, E } from './types'; +import F, { typeof G, H, type I } from './types'; +import { type J } from './types'; +import K, { L, M } from './types'; +import './types'; \ No newline at end of file diff --git a/packages/babel-plugin-transform-flow-comments/test/fixtures/flow-comments/import-type-alias-2/output.mjs b/packages/babel-plugin-transform-flow-comments/test/fixtures/flow-comments/import-type-alias-2/output.mjs new file mode 100644 index 000000000000..aec6406ae2e1 --- /dev/null +++ b/packages/babel-plugin-transform-flow-comments/test/fixtures/flow-comments/import-type-alias-2/output.mjs @@ -0,0 +1,10 @@ +import A, { B, E } from './types'; +/*:: import { type C, type D } from './types';*/ + +import F, { H } from './types'; +/*:: import { typeof G, type I } from './types';*/ + +/*:: import { type J } from './types';*/ + +import K, { L, M } from './types'; +import './types';