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