esdoc
Version:
Good Documentation Generator For JavaScript
162 lines (135 loc) • 4.67 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _fsExtra = require('fs-extra');
var _fsExtra2 = _interopRequireDefault(_fsExtra);
var _AbstractDoc = require('./AbstractDoc.js');
var _AbstractDoc2 = _interopRequireDefault(_AbstractDoc);
var _ParamParser = require('../Parser/ParamParser.js');
var _ParamParser2 = _interopRequireDefault(_ParamParser);
var _NamingUtil = require('../Util/NamingUtil.js');
var _NamingUtil2 = _interopRequireDefault(_NamingUtil);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Doc Class from Class Declaration AST node.
*/
class ClassDoc extends _AbstractDoc2.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 = _NamingUtil2.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 } = _ParamParser2.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 } = _ParamParser2.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 = _fsExtra2.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;