esdoc
Version:
Good Documentation Generator For JavaScript
185 lines (159 loc) • 5.25 kB
JavaScript
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;
;