Permalink
Browse files

fix: error when export has complex value.

  • Loading branch information...
h13i32maru committed Jun 28, 2015
1 parent 579811e commit 957d61a8febb4fe3dda4d65bae8dc1cbc210250c
View
@@ -55,6 +55,7 @@ export default class AbstractDoc {
this['@version']();
this['@todo']();
this['@ignore']();
+ this['@instanceExport']();
this['@undocument']();
this['@unknown']();
@@ -207,7 +208,7 @@ export default class AbstractDoc {
}
let parent = this._node.parent;
- let name = this._value.name;
+ let name = this._node.__esdoc__instance_name || this._value.name;
while (parent) {
if (parent.type === 'ExportDefaultDeclaration') {
this._value.importStyle = name;
@@ -324,6 +325,19 @@ export default class AbstractDoc {
}
}
+ /** for @instanceExport, does not need to use this tag. */
+ ['@instanceExport'](){
+ let tag = this._find(['@instanceExport']);
+ if (tag) {
+ this._value.instanceExport = ['', 'true', true].includes(tag.tagValue);
+ return;
+ }
+
+ if (this._node.__esdoc__instance_export) {
+ this._value.instanceExport = true;
+ }
+ }
+
/** for @undocument, does not need to use this tag */
['@undocument']() {
let tag = this._find(['@undocument']);
View
@@ -212,6 +212,7 @@ export default class ESDoc {
* @private
*/
static _traverse(inDirPath, filePath, packageName, mainFilePath, pathPrefix) {
+ logger.i(`parsing: ${filePath}`);
let ast;
try {
ast = ESParser.parse(filePath);
View
@@ -40,7 +40,8 @@ export default class DocFactory {
this._results = [];
this._processedClassNodes = [];
- this._joinSeparatedExport();
+ this._inspectExportDefaultDeclaration();
+ this._inspectExportNamedDeclaration();
// file doc
let doc = new FileDoc(ast, ast, pathResolver, []);
@@ -54,34 +55,143 @@ export default class DocFactory {
}
/**
- * join separated export declaration in AST internal.
+ * inspect ExportDefaultDeclaration.
+ *
+ * case1: separated export
*
* ```javascript
* class Foo {}
- *
* export default Foo;
* ```
- * ↓
+ *
+ * case2: export instance(directly).
+ *
* ```javascript
- * export default class Foo {}
+ * class Foo {}
+ * export default new Foo();
+ * ```
+ *
+ * case3: export instance(indirectly).
+ *
+ * ```javascript
+ * class Foo {}
+ * let foo = new Foo();
+ * export default foo;
* ```
*
* @private
+ * @todo support function export.
*/
- _joinSeparatedExport() {
- for (let node1 of this._ast.body) {
- if (!['ExportDefaultDeclaration', 'ExportNamedDeclaration'].includes(node1.type)) continue;
+ _inspectExportDefaultDeclaration() {
+ for (let exportNode of this._ast.body) {
+ if (exportNode.type !== 'ExportDefaultDeclaration') continue;
+
+ let targetClassName = null;
+ let isInstanceExport = false;
+
+ switch(exportNode.declaration.type) {
+ case 'NewExpression':
+ targetClassName = exportNode.declaration.callee.name;
+ isInstanceExport = true;
+ break;
+ case 'Identifier':
+ for (let node2 of this._ast.body) {
+ if (node2.type === 'VariableDeclaration' &&
+ node2.declarations[0].init.type === 'NewExpression' &&
+ node2.declarations[0].id.name === exportNode.declaration.name) {
+ targetClassName = node2.declarations[0].init.callee.name;
+ isInstanceExport = true;
+ break;
+ }
+ }
+
+ if (!targetClassName) targetClassName = exportNode.declaration.name;
+ break;
+ default:
+ break;
+ }
for (let node2 of this._ast.body) {
- if (!node2.id) continue;
- if (node2.id.type !== 'Identifier') continue;
- if (node2.id.name !== node1.declaration.name) continue;
+ if (node2.type === 'ClassDeclaration' && node2.id.name === targetClassName) {
+ let exportedName = exportNode.declaration.name;
+ exportNode.declaration = this._copy(node2);
+ if (isInstanceExport) {
+ exportNode.declaration.__esdoc__instance_export = true;
+ exportNode.declaration.__esdoc__instance_name = exportedName;
+ }
+ node2.type = 'Identifier'; // to ignore
+ }
+ }
+ }
+ }
- node1.declaration = this._copy(node2);
- node2.type = 'Identifier'; // to ignore node2
- break;
+ /**
+ * inspect ExportNamedDeclaration.
+ *
+ * case1: separated export
+ *
+ * ```javascript
+ * class Foo {}
+ * export {Foo};
+ * ```
+ *
+ * case2: export instance(indirectly).
+ *
+ * ```javascript
+ * class Foo {}
+ * let foo = new Foo();
+ * export {foo};
+ * ```
+ *
+ * @private
+ * @todo support function export.
+ */
+ _inspectExportNamedDeclaration() {
+ let pseudoExportNodes = [];
+
+ for (let exportNode of this._ast.body) {
+ if (exportNode.type !== 'ExportNamedDeclaration') continue;
+
+ if (exportNode.declaration) continue;
+
+ for (let specifier of exportNode.specifiers) {
+ if (specifier.type !== 'ExportSpecifier') continue;
+
+ let targetClassName = null;
+ let isInstanceExport = false;
+
+ for (let node2 of this._ast.body) {
+ if (node2.type === 'VariableDeclaration' &&
+ node2.declarations[0].init.type === 'NewExpression' &&
+ node2.declarations[0].id.name === specifier.exported.name) {
+ targetClassName = node2.declarations[0].init.callee.name;
+ isInstanceExport = true;
+ break;
+ }
+ }
+
+ if (!targetClassName) targetClassName = specifier.exported.name;
+
+ for (let node2 of this._ast.body) {
+ if (node2.type === 'ClassDeclaration' && node2.id.name === targetClassName) {
+ let pseudoExportNode = this._copy(exportNode);
+ pseudoExportNode.declaration = this._copy(node2);
+ pseudoExportNode.specifiers = null;
+ if (isInstanceExport) {
+ pseudoExportNode.declaration.__esdoc__instance_export = true;
+ pseudoExportNode.declaration.__esdoc__instance_name = specifier.exported.name;
+ }
+ pseudoExportNodes.push(pseudoExportNode);
+ node2.type = 'Identifier'; // to ignore
+ break;
+ }
+ }
}
+
+ exportNode.type = 'Identifier'; // to ignore
}
+
+ this._ast.body.push(...pseudoExportNodes);
}
/**
@@ -62,6 +62,7 @@ export default class ClassDocBuilder extends DocBuilder {
// self
ice.text('name', doc.name);
+ ice.drop('instanceExport', !doc.instanceExport);
ice.load('description', doc.description);
ice.load('deprecated', this._buildDeprecatedHTML(doc));
ice.load('experimental', this._buildExperimentalHTML(doc));
@@ -11,6 +11,8 @@
<div class="self-detail detail">
<h1 data-ice="name"></h1>
+ <div class="instance-export" data-ice="instanceExport">This class has been exported at instantiated state. So, you can not use directly this class.</div>
+
<div class="flat-list" data-ice="extendsChain"><h4>Extends:</h4></div>
<div class="flat-list" data-ice="directSubclass"><h4>Direct Subclass:</h4></div>
<div class="flat-list" data-ice="indirectSubclass"><h4>Indirect Subclass:</h4></div>
@@ -366,7 +366,7 @@ table.params td p {
margin: 0;
}
-.deprecated, .experimental {
+.deprecated, .experimental, .instance-export {
border-left: solid 5px orange;
padding-left: 4px;
margin: 4px 0;

0 comments on commit 957d61a

Please sign in to comment.