|
| 1 | +import {DocCollection, Document, Processor} from 'dgeni'; |
| 2 | +import {ClassLikeExportDoc} from 'dgeni-packages/typescript/api-doc-types/ClassLikeExportDoc'; |
| 3 | +import * as ts from 'typescript'; |
| 4 | +import {getInheritedDocsOfClass, isInheritanceCreatedDoc} from '../common/class-inheritance'; |
| 5 | +import {ClassExportDoc} from 'dgeni-packages/typescript/api-doc-types/ClassExportDoc'; |
| 6 | +import {ApiDoc} from 'dgeni-packages/typescript/api-doc-types/ApiDoc'; |
| 7 | + |
| 8 | +/** |
| 9 | + * Factory function for the "ResolvedInheritedDocs" processor. Dgeni does not support |
| 10 | + * dependency injection for classes. The symbol docs map is provided by the TypeScript |
| 11 | + * dgeni package. |
| 12 | + */ |
| 13 | +export function resolveInheritedDocs( |
| 14 | + exportSymbolsToDocsMap: Map<ts.Symbol, ClassLikeExportDoc>) { |
| 15 | + return new ResolveInheritedDocs(exportSymbolsToDocsMap); |
| 16 | +} |
| 17 | + |
| 18 | +/** |
| 19 | + * Processor that resolves inherited API docs from class API documents. The resolved |
| 20 | + * API documents will be added to the Dgeni document collection so that they can be |
| 21 | + * processed by other standard processors in the Dgeni pipeline. This is helpful as |
| 22 | + * API documents for inheritance are created manually if not exported, and we'd want |
| 23 | + * such docs to be processed by the Dgeni JSDoc processor for example. |
| 24 | + */ |
| 25 | +export class ResolveInheritedDocs implements Processor { |
| 26 | + $runBefore = ['docs-private-filter', 'parsing-tags']; |
| 27 | + |
| 28 | + constructor( |
| 29 | + /** Shared map that can be used to resolve docs through symbols. */ |
| 30 | + private _exportSymbolsToDocsMap: Map<ts.Symbol, ClassLikeExportDoc>) {} |
| 31 | + |
| 32 | + $process(docs: DocCollection) { |
| 33 | + const newDocs = new Set<Document>(docs); |
| 34 | + |
| 35 | + docs.forEach(doc => { |
| 36 | + if (doc.docType !== 'class') { |
| 37 | + return; |
| 38 | + } |
| 39 | + |
| 40 | + getInheritedDocsOfClass(doc, this._exportSymbolsToDocsMap).forEach(apiDoc => { |
| 41 | + // If the API document has not been resolved through inheritance, then it is already |
| 42 | + // part of the Dgeni doc collection. i.e. The doc already been resolved through Dgeni |
| 43 | + // itself (which happens if the doc is exported through an entry-point). |
| 44 | + if (!isInheritanceCreatedDoc(apiDoc)) { |
| 45 | + return; |
| 46 | + } |
| 47 | + // Add the member docs for the inherited doc to the Dgeni doc collection. |
| 48 | + this._getContainingMemberDocs(apiDoc).forEach(d => newDocs.add(d)); |
| 49 | + // Add the class-like export doc to the Dgeni doc collection. |
| 50 | + newDocs.add(apiDoc); |
| 51 | + }); |
| 52 | + }); |
| 53 | + |
| 54 | + return Array.from(newDocs); |
| 55 | + } |
| 56 | + |
| 57 | + /** |
| 58 | + * Gets the nested API documents of the given class-like API document. This |
| 59 | + * follows the logic as per: |
| 60 | + * dgeni-packages/blob/master/typescript/src/processors/readTypeScriptModules/index.ts#L110-L121 |
| 61 | + */ |
| 62 | + private _getContainingMemberDocs(doc: ClassLikeExportDoc): ApiDoc[] { |
| 63 | + const nestedDocs: ApiDoc[] = [...doc.members]; |
| 64 | + |
| 65 | + // For classes, also add the static member docs and optional constructor doc. |
| 66 | + if (doc instanceof ClassExportDoc) { |
| 67 | + nestedDocs.push(...doc.statics); |
| 68 | + |
| 69 | + if (doc.constructorDoc !== undefined) { |
| 70 | + nestedDocs.push(doc.constructorDoc); |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 74 | + return nestedDocs; |
| 75 | + } |
| 76 | +} |
0 commit comments