2016-02-14 23:25:14 +00:00

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);
}
}
};
}