UNPKG

@babel/plugin-transform-flow-comments

Version:
266 lines (263 loc) 7.92 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _helperPluginUtils = require("@babel/helper-plugin-utils"); var _pluginSyntaxFlow = require("@babel/plugin-syntax-flow"); var _core = require("@babel/core"); var _generator = require("@babel/generator"); var _default = exports.default = (0, _helperPluginUtils.declare)(api => { api.assertVersion(7); function commentFromString(comment) { return typeof comment === "string" ? { type: "CommentBlock", value: comment } : comment; } function attachComment({ ofPath, toPath, where = "trailing", optional = false, comments = generateComment(ofPath, optional), keepType = false }) { var _toPath; if (!((_toPath = toPath) != null && _toPath.node)) { toPath = ofPath.getPrevSibling(); where = "trailing"; } if (!toPath.node) { toPath = ofPath.getNextSibling(); where = "leading"; } if (!toPath.node) { toPath = ofPath.parentPath; where = "inner"; } if (!Array.isArray(comments)) { comments = [comments]; } const newComments = comments.map(commentFromString); if (!keepType && ofPath != null && ofPath.node) { const node = ofPath.node; const parent = ofPath.parentPath; const prev = ofPath.getPrevSibling(); const next = ofPath.getNextSibling(); const isSingleChild = !(prev.node || next.node); const leading = node.leadingComments; const trailing = node.trailingComments; if (isSingleChild && leading) { parent.addComments("inner", leading); } toPath.addComments(where, newComments); ofPath.remove(); if (isSingleChild && trailing) { parent.addComments("inner", trailing); } } else { toPath.addComments(where, newComments); } } function wrapInFlowComment(path) { attachComment({ ofPath: path, comments: generateComment(path, path.parent.optional) }); } function generateComment(path, optional) { let comment = path.getSource().replace(/\*-\//g, "*-ESCAPED/").replace(/\*\//g, "*-/"); if (optional) comment = "?" + comment; if (comment[0] !== ":") comment = ":: " + comment; return comment; } function isTypeImport(importKind) { return importKind === "type" || importKind === "typeof"; } return { name: "transform-flow-comments", inherits: _pluginSyntaxFlow.default, visitor: { TypeCastExpression(path) { const { node } = path; attachComment({ ofPath: path.get("typeAnnotation"), toPath: path.get("expression"), keepType: true }); path.replaceWith(_core.types.parenthesizedExpression(node.expression)); }, Identifier(path) { if (path.parentPath.isFlow()) return; const { node } = path; if (node.typeAnnotation) { attachComment({ ofPath: path.get("typeAnnotation"), toPath: path, optional: node.optional || node.typeAnnotation.optional }); if (node.optional) { node.optional = false; } } else if (node.optional) { attachComment({ toPath: path, comments: ":: ?" }); node.optional = false; } }, AssignmentPattern: { exit({ node }) { const { left } = node; if (left.optional) { left.optional = false; } } }, Function(path) { if (path.isDeclareFunction()) return; const { node } = path; if (node.typeParameters) { attachComment({ ofPath: path.get("typeParameters"), toPath: path.get("id"), optional: node.typeParameters.optional }); } if (node.returnType) { attachComment({ ofPath: path.get("returnType"), toPath: path.get("body"), where: "leading", optional: node.returnType.typeAnnotation.optional }); } }, ClassProperty(path) { const { node } = path; if (!node.value) { wrapInFlowComment(path); } else if (node.typeAnnotation) { attachComment({ ofPath: path.get("typeAnnotation"), toPath: path.get("key"), optional: node.typeAnnotation.optional }); } }, ExportNamedDeclaration(path) { const { node } = path; if (node.exportKind !== "type" && !_core.types.isFlow(node.declaration)) { return; } wrapInFlowComment(path); }, ImportDeclaration(path) { const { node } = path; if (isTypeImport(node.importKind)) { wrapInFlowComment(path); return; } const typeSpecifiers = node.specifiers.filter(specifier => specifier.type === "ImportSpecifier" && isTypeImport(specifier.importKind)); const nonTypeSpecifiers = node.specifiers.filter(specifier => specifier.type !== "ImportSpecifier" || !isTypeImport(specifier.importKind)); node.specifiers = nonTypeSpecifiers; if (typeSpecifiers.length > 0) { const typeImportNode = _core.types.cloneNode(node); typeImportNode.specifiers = typeSpecifiers; const comment = `:: ${(0, _generator.default)(typeImportNode).code}`; if (nonTypeSpecifiers.length > 0) { attachComment({ toPath: path, comments: comment }); } else { attachComment({ ofPath: path, comments: comment }); } } }, ObjectPattern(path) { const { node } = path; if (node.typeAnnotation) { attachComment({ ofPath: path.get("typeAnnotation"), toPath: path, optional: node.optional || node.typeAnnotation.optional }); } }, Flow(path) { wrapInFlowComment(path); }, Class(path) { const { node } = path; let comments = []; if (node.typeParameters) { const typeParameters = path.get("typeParameters"); comments.push(generateComment(typeParameters, node.typeParameters.optional)); const trailingComments = node.typeParameters.trailingComments; if (trailingComments) { comments.push(...trailingComments); } typeParameters.remove(); } if (node.superClass) { if (comments.length > 0) { attachComment({ toPath: path.get("id"), comments: comments }); comments = []; } if (node.superTypeParameters) { const superTypeArguments = path.get("superTypeParameters"); comments.push(generateComment(superTypeArguments, superTypeArguments.node.optional)); superTypeArguments.remove(); } } if (node.implements) { const impls = path.get("implements"); const comment = "implements " + impls.map(impl => generateComment(impl).replace(/^:: /, "")).join(", "); delete node["implements"]; if (comments.length === 1) { comments[0] += ` ${comment}`; } else { comments.push(`:: ${comment}`); } } if (comments.length > 0) { attachComment({ toPath: path.get("body"), where: "leading", comments: comments }); } } } }; }); //# sourceMappingURL=index.js.map