UNPKG

@webex/jsdoctrinetest

Version:
120 lines (104 loc) 2.85 kB
/*! * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file. */ import fs from 'fs'; import traverse from '@babel/traverse'; import doctrine from 'doctrine'; import {isProgram} from '@babel/types'; import parse from './parse'; /** * transform function which operates on each discovered example block * @callback transformCallback * @param {Object} options * @param {ast} options.comment * @param {string} options.name * @param {string} options.filename * @param {string} options.type */ /** * Extracts comment blocks from the source code in the specified file * @param {transformCallback} transform * @param {string} filename * @returns {Array<ast>} */ export default function extract(transform, filename) { // eslint-disable-next-line no-sync const code = fs.readFileSync(filename, {encoding: 'utf8'}); const ast = parse(code, {sourceFilename: filename}); const results = []; let done = false; traverse(ast, { enter(path) { if (path.node.leadingComments) { path.node.leadingComments.filter(isJSDocComment).forEach((comment) => { const result = doctrine.parse(comment.value, { unwrap: true, sloppy: true, recoverable: true, lineNumbers: true, }); if (result.tags) { result.tags.forEach((tag) => { if (tag.title === 'example') { results.push( transform({ comment: tag.description, name: getNodeName(path.node), filename: path.node.loc.filename, type: path.node.type, }) ); } }); } }); } }, Program: { exit(path) { if (isProgram(path)) { if (done) { return; } path.pushContainer('body', results); done = true; } }, }, }); return ast; } /** * Extracts the name from the specified node * @param {Node} node * @returns {string} */ function getNodeName(node) { if (node.id) { return node.id.name; } if (node.key) { return node.key.name; } throw new Error('Could not find name for node'); } /** * Indicates if the specified comment block is a doc block * @param {CommentBlock} comment * @returns {Boolean} */ function isJSDocComment(comment) { const asterisks = comment.value.match(/^(\*+)/); if (comment.value.startsWith('/*') && comment.value.endsWith('*/')) { return false; } // eslint-disable-next-line return ( (comment.type === 'CommentBlock' || // estree // eslint-disable-next-line comment.type === `Block`) && // get-comments / traditional // eslint-disable-next-line asterisks && asterisks[1].length === 1 ); }