UNPKG

@sebastianwessel/esdoc

Version:

Fork of ESDoc - A Good Documentation Generator For JavaScript

185 lines (136 loc) 4.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _fsExtra = _interopRequireDefault(require("fs-extra")); var _AbstractDoc = _interopRequireDefault(require("./AbstractDoc.js")); var _ParamParser = _interopRequireDefault(require("../Parser/ParamParser.js")); var _NamingUtil = _interopRequireDefault(require("../Util/NamingUtil.js")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Doc Class from Class Declaration AST node. */ class ClassDoc extends _AbstractDoc.default { /** * apply own tag. * @private */ _apply() { super._apply(); this._$interface(); this._$extends(); this._$implements(); } /** specify ``class`` to kind. */ _$kind() { super._$kind(); this._value.kind = 'class'; } /** take out self name from self node */ _$name() { super._$name(); if (this._node.id) { this._value.name = this._node.id.name; } else { this._value.name = _NamingUtil.default.filePathToName(this._pathResolver.filePath); } } /** take out self memberof from file path. */ _$memberof() { super._$memberof(); this._value.memberof = this._pathResolver.filePath; } /** for @interface */ _$interface() { const tag = this._find(['@interface']); if (tag) { this._value.interface = ['', 'true', true].includes(tag.tagValue); } else { this._value.interface = false; } } /** for @extends, does not need to use this tag. */ _$extends() { const values = this._findAllTagValues(['@extends', '@extend']); if (values) { this._value.extends = []; for (const value of values) { const { typeText } = _ParamParser.default.parseParamValue(value, true, false, false); this._value.extends.push(typeText); } return; } if (this._node.superClass) { const node = this._node; let longnames = []; const targets = []; if (node.superClass.type === 'CallExpression') { targets.push(node.superClass.callee, ...node.superClass.arguments); } else { targets.push(node.superClass); } for (const target of targets) { /* eslint-disable default-case */ switch (target.type) { case 'Identifier': longnames.push(this._resolveLongname(target.name)); break; case 'MemberExpression': { const fullIdentifier = this._flattenMemberExpression(target); const rootIdentifier = fullIdentifier.split('.')[0]; const rootLongname = this._resolveLongname(rootIdentifier); const filePath = rootLongname.replace(/~.*/, ''); longnames.push(`${filePath}~${fullIdentifier}`); } break; } } if (node.superClass.type === 'CallExpression') { // expression extends may have non-class, so filter only class by name rule. longnames = longnames.filter(v => v.match(/^[A-Z]|^[$_][A-Z]/)); const filePath = this._pathResolver.fileFullPath; const line = node.superClass.loc.start.line; const start = node.superClass.loc.start.column; const end = node.superClass.loc.end.column; this._value.expressionExtends = this._readSelection(filePath, line, start, end); } if (longnames.length) this._value.extends = longnames; } } /** for @implements */ _$implements() { const values = this._findAllTagValues(['@implements', '@implement']); if (!values) return; this._value.implements = []; for (const value of values) { const { typeText } = _ParamParser.default.parseParamValue(value, true, false, false); this._value.implements.push(typeText); } } /** * read selection text in file. * @param {string} filePath - target file full path. * @param {number} line - line number (one origin). * @param {number} startColumn - start column number (one origin). * @param {number} endColumn - end column number (one origin). * @returns {string} selection text * @private */ _readSelection(filePath, line, startColumn, endColumn) { const code = _fsExtra.default.readFileSync(filePath).toString(); const lines = code.split('\n'); const selectionLine = lines[line - 1]; const tmp = []; for (let i = startColumn; i < endColumn; i++) { tmp.push(selectionLine.charAt(i)); } return tmp.join(''); } } exports.default = ClassDoc;