UNPKG

esdoc

Version:

Good Documentation Generator For JavaScript

185 lines (159 loc) 5.25 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _babelTraverse = require('babel-traverse'); var _babelTraverse2 = _interopRequireDefault(_babelTraverse); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Utility for AST. */ class ASTUtil { /** * sanitize node. * change node type to `Identifier` and empty comment. * @param {ASTNode} node - target node. */ static sanitize(node) { if (!node) return; node.type = 'Identifier'; node.name = '_'; node.leadingComments = []; node.trailingComments = []; } /** * traverse ast nodes. * @param {AST} ast - target AST. * @param {function(node: Object, parent: Object, path: Object)} callback - this is called with each node. */ static traverse(ast, callback) { (0, _babelTraverse2.default)(ast, { noScope: true, enter: function (path) { callback(path.node, path.parent, path); } }); } /** * find file path in import declaration by name. * e.g. can find ``./foo/bar.js`` from ``import Bar from './foo/bar.js'`` by ``Bar``. * @param {AST} ast - target AST. * @param {string} name - identifier name. * @returns {string|null} file path. */ static findPathInImportDeclaration(ast, name) { let path = null; (0, _babelTraverse2.default)(ast, { noScope: true, enter: function (_path) { const node = _path.node; if (node.type !== 'ImportDeclaration') return; for (const spec of node.specifiers) { const localName = spec.local.name; if (localName === name) { path = node.source.value; _path.stop(); } } } }); return path; } /** * find VariableDeclaration node which has NewExpression. * @param {string} name - variable name. * @param {AST} ast - find in this ast. * @returns {ASTNode|null} found ast node. */ static findVariableDeclarationAndNewExpressionNode(name, ast) { if (!name) return null; for (const node of ast.program.body) { if (node.type === 'VariableDeclaration' && node.declarations[0].init && node.declarations[0].init.type === 'NewExpression' && node.declarations[0].id.name === name) { return node; } } return null; } /** * find ClassDeclaration node. * @param {string} name - class name. * @param {AST} ast - find in this ast. * @returns {{classNode: ASTNode|null, exported: boolean|null}} found ast node. */ static findClassDeclarationNode(name, ast) { if (!name) return { classNode: null, exported: null }; for (const node of ast.program.body) { if (node.type === 'ClassDeclaration' && node.id.name === name) return { classNode: node, exported: false }; if (node.type === 'ExportDefaultDeclaration' || node.type === 'ExportNamedDeclaration') { if (node.declaration && node.declaration.type === 'ClassDeclaration' && node.declaration.id && node.declaration.id.name === name) return { classNode: node, exported: true }; } } return { classNode: null, exported: null }; } /** * find FunctionDeclaration node. * @param {string} name - function name. * @param {AST} ast - find in this ast. * @returns {ASTNode|null} found ast node. */ static findFunctionDeclarationNode(name, ast) { if (!name) return null; for (const node of ast.program.body) { if (node.type === 'FunctionDeclaration' && node.id.name === name) return node; } return null; } /** * find VariableDeclaration node. * @param {string} name - variable name. * @param {AST} ast - find in this ast. * @returns {ASTNode|null} found ast node. */ static findVariableDeclarationNode(name, ast) { if (!name) return null; for (const node of ast.program.body) { if (node.type === 'VariableDeclaration' && node.declarations[0].id.name === name) return node; } return null; } /** * create VariableDeclaration node which has NewExpression. * @param {string} name - variable name. * @param {string} className - class name. * @param {Object} loc - location. * @returns {ASTNode} created node. */ static createVariableDeclarationAndNewExpressionNode(name, className, loc) { const node = { type: 'VariableDeclaration', kind: 'let', loc: loc, declarations: [{ type: 'VariableDeclarator', id: { type: 'Identifier', name: name }, init: { type: 'NewExpression', callee: { type: 'Identifier', name: className } } }] }; return node; } // /** // * flatten name of MemberExpression. // * @param {ASTNode} memberExpression - MemberExpression Node. // * @returns {string} flatten node name. // */ // static flattenMemberExpression(memberExpression) { // const names = []; // let object = memberExpression; // while (object) { // if (object.name) { // names.push(object.name); // break; // } else { // names.push(object.property.name); // object = object.object; // } // } // return names.reverse().join('.'); // } } exports.default = ASTUtil;