Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(export): Handle NamedExports of Imports, export * from and export as #511

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/Doc/AbstractDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ASTUtil from '../Util/ASTUtil.js';
import InvalidCodeLogger from '../Util/InvalidCodeLogger.js';
import ASTNodeContainer from '../Util/ASTNodeContainer.js';
import babelGenerator from 'babel-generator';
import {name} from '../Factory/DocFactory';

/**
* Abstract Doc Class.
Expand Down Expand Up @@ -97,9 +98,12 @@ export default class AbstractDoc {

/**
* decide `name`
* @abstract
*/
_$name() {}
_$name() {
if (this._node[name]) {
this._value.name = this._node[name];
}
}

/**
* decide `memberof`.
Expand Down
6 changes: 4 additions & 2 deletions src/Doc/AssignmentDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ export default class AssignmentDoc extends AbstractDoc {
*/
_$name() {
super._$name();
const name = this._flattenMemberExpression(this._node.left).replace(/^this\./, '');
this._value.name = name;
if (!this._value.name) {
const name = this._flattenMemberExpression(this._node.left).replace(/^this\./, '');
this._value.name = name;
}
}

/**
Expand Down
11 changes: 6 additions & 5 deletions src/Doc/ClassDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ export default class ClassDoc extends AbstractDoc {
/** 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.filePathToName(this._pathResolver.filePath);
if (!this._value.name) {
if (this._node.id) {
this._value.name = this._node.id.name;
} else {
this._value.name = NamingUtil.filePathToName(this._pathResolver.filePath);
}
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/Doc/ClassPropertyDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ export default class ClassPropertyDoc extends AbstractDoc {
/** take out self name from self node */
_$name() {
super._$name();
this._value.name = this._node.key.name;
if (!this._value.name) {
this._value.name = this._node.key.name;
}
}

/** borrow {@link MethodDoc#@_memberof} */
Expand Down
37 changes: 20 additions & 17 deletions src/Doc/ExternalDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,30 @@ export default class ExternalDoc extends AbstractDoc {

/** take out self name from tag */
_$name() {
const value = this._findTagValue(['@external']);
if (!value) {
logger.w('can not resolve name.');
}
super._$name();
if (!this._value.name) {
const value = this._findTagValue(['@external']);
if (!value) {
logger.w('can not resolve name.');
}

this._value.name = value;
this._value.name = value;

const tags = this._findAll(['@external']);
if (!tags) {
logger.w('can not resolve name.');
return;
}
const tags = this._findAll(['@external']);
if (!tags) {
logger.w('can not resolve name.');
return;
}

let name;
for (const tag of tags) {
const {typeText, paramDesc} = ParamParser.parseParamValue(tag.tagValue, true, false, true);
name = typeText;
this._value.externalLink = paramDesc;
}
let name;
for (const tag of tags) {
const {typeText, paramDesc} = ParamParser.parseParamValue(tag.tagValue, true, false, true);
name = typeText;
this._value.externalLink = paramDesc;
}

this._value.name = name;
this._value.name = name;
}
}

/** take out self memberof from file path. */
Expand Down
4 changes: 3 additions & 1 deletion src/Doc/FileDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ export default class FileDoc extends AbstractDoc {
/** take out self name from file path */
_$name() {
super._$name();
this._value.name = this._pathResolver.filePath;
if (!this._value.name) {
this._value.name = this._pathResolver.filePath;
}
}

/** specify name to longname */
Expand Down
19 changes: 10 additions & 9 deletions src/Doc/FunctionDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,18 @@ export default class FunctionDoc extends AbstractDoc {
/** take out self name from self node */
_$name() {
super._$name();

if (this._node.id) {
if (this._node.id.type === 'MemberExpression') {
// e.g. foo[bar.baz] = function bal(){}
const expression = babelGenerator(this._node.id).code;
this._value.name = `[${expression}]`;
if (!this._value.name) {
if (this._node.id) {
if (this._node.id.type === 'MemberExpression') {
// e.g. foo[bar.baz] = function bal(){}
const expression = babelGenerator(this._node.id).code;
this._value.name = `[${expression}]`;
} else {
this._value.name = this._node.id.name;
}
} else {
this._value.name = this._node.id.name;
this._value.name = NamingUtil.filePathToName(this._pathResolver.filePath);
}
} else {
this._value.name = NamingUtil.filePathToName(this._pathResolver.filePath);
}
}

Expand Down
17 changes: 10 additions & 7 deletions src/Doc/MemberDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,17 @@ export default class MemberDoc extends AbstractDoc {

/** take out self name from self node */
_$name() {
let name;
if (this._node.left.computed) {
const expression = babelGenerator(this._node.left.property).code.replace(/^this/, '');
name = `[${expression}]`;
} else {
name = this._flattenMemberExpression(this._node.left).replace(/^this\./, '');
super._$name();
if (!this._value.name) {
let name;
if (this._node.left.computed) {
const expression = babelGenerator(this._node.left.property).code.replace(/^this/, '');
name = `[${expression}]`;
} else {
name = this._flattenMemberExpression(this._node.left).replace(/^this\./, '');
}
this._value.name = name;
}
this._value.name = name;
}

/** borrow {@link MethodDoc#@_memberof} */
Expand Down
13 changes: 7 additions & 6 deletions src/Doc/MethodDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ export default class MethodDoc extends AbstractDoc {
/** take out self name from self node */
_$name() {
super._$name();

if (this._node.computed) {
const expression = babelGenerator(this._node.key).code;
this._value.name = `[${expression}]`;
} else {
this._value.name = this._node.key.name;
if (!this._value.name) {
if (this._node.computed) {
const expression = babelGenerator(this._node.key).code;
this._value.name = `[${expression}]`;
} else {
this._value.name = this._node.key.name;
}
}
}

Expand Down
25 changes: 14 additions & 11 deletions src/Doc/TypedefDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,22 @@ export default class TypedefDoc extends AbstractDoc {

/** set name by using tag. */
_$name() {
const tags = this._findAll(['@typedef']);
if (!tags) {
logger.w('can not resolve name.');
return;
}
super._$name();
if (!this._value.name) {
const tags = this._findAll(['@typedef']);
if (!tags) {
logger.w('can not resolve name.');
return;
}

let name;
for (const tag of tags) {
const {paramName} = ParamParser.parseParamValue(tag.tagValue, true, true, false);
name = paramName;
}
let name;
for (const tag of tags) {
const {paramName} = ParamParser.parseParamValue(tag.tagValue, true, true, false);
name = paramName;
}

this._value.name = name;
this._value.name = name;
}
}

/** set memberof by using file path. */
Expand Down
37 changes: 19 additions & 18 deletions src/Doc/VariableDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,25 @@ export default class VariableDoc extends AbstractDoc {
/** set name by using self node. */
_$name() {
super._$name();

const type = this._node.declarations[0].id.type;
switch (type) {
case 'Identifier':
this._value.name = this._node.declarations[0].id.name;
break;
case 'ObjectPattern':
// TODO: optimize for multi variables.
// e.g. export const {a, b} = obj
this._value.name = this._node.declarations[0].id.properties[0].key.name;
break;
case 'ArrayPattern':
// TODO: optimize for multi variables.
// e.g. export cont [a, b] = arr
this._value.name = this._node.declarations[0].id.elements.find(v => v).name;
break;
default:
throw new Error(`unknown declarations type: ${type}`);
if (!this._value.name) {
const type = this._node.declarations[0].id.type;
switch (type) {
case 'Identifier':
this._value.name = this._node.declarations[0].id.name;
break;
case 'ObjectPattern':
// TODO: optimize for multi variables.
// e.g. export const {a, b} = obj
this._value.name = this._node.declarations[0].id.properties[0].key.name;
break;
case 'ArrayPattern':
// TODO: optimize for multi variables.
// e.g. export cont [a, b] = arr
this._value.name = this._node.declarations[0].id.elements.find(v => v).name;
break;
default:
throw new Error(`unknown declarations type: ${type}`);
}
}
}

Expand Down
30 changes: 26 additions & 4 deletions src/ESDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export default class ESDoc {
}

/**
* traverse doc comment in JavaScript file.
* Get DocFactory for Javascript File.
* @param {string} inDirPath - root directory path.
* @param {string} filePath - target JavaScript file path.
* @param {string} [packageName] - npm package name of target.
Expand All @@ -197,18 +197,40 @@ export default class ESDoc {
* @property {AST} ast - this is AST of JavaScript file.
* @private
*/
static _traverse(inDirPath, filePath, packageName, mainFilePath) {
static _getFactory(inDirPath, filePath, packageName, mainFilePath) {
logger.i(`parsing: ${filePath}`);
let ast;
try {
ast = ESParser.parse(filePath);
} catch (e) {
InvalidCodeLogger.showFile(filePath, e);
return null;
return {factory: null, ast: null};
}

const pathResolver = new PathResolver(inDirPath, filePath, packageName, mainFilePath);
const factory = new DocFactory(ast, pathResolver);
return {
factory: new DocFactory(ast, pathResolver, (filePath) => this._getFactory(inDirPath, filePath, packageName, mainFilePath)),
ast: ast
};
}

/**
* traverse doc comment in JavaScript file.
* @param {string} inDirPath - root directory path.
* @param {string} filePath - target JavaScript file path.
* @param {string} [packageName] - npm package name of target.
* @param {string} [mainFilePath] - npm main file path of target.
* @returns {Object} - return document that is traversed.
* @property {DocObject[]} results - this is contained JavaScript file.
* @property {AST} ast - this is AST of JavaScript file.
* @private
*/
static _traverse(inDirPath, filePath, packageName, mainFilePath) {
const {factory, ast} = this._getFactory(inDirPath, filePath, packageName, mainFilePath);

if (!factory) {
return null;
}

ASTUtil.traverse(ast, (node, parent)=>{
try {
Expand Down