60 lines
1.8 KiB
JavaScript
60 lines
1.8 KiB
JavaScript
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);
|
|
}
|
|
}
|
|
};
|
|
}
|