From 6b6820bdd29109caa0fbaf4c00b258a09c66ae2a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 17 Jul 2020 00:39:33 +0200 Subject: [PATCH] docgen: more docs --- packages/docgen/src/docgen/ApiDocGenerator.ts | 31 ++++++++++++++++++- packages/docgen/src/docgen/ApiDocsPrinter.ts | 6 ++++ .../src/docgen/GitHubMarkdownPrinter.ts | 2 +- .../src/docgen/TechdocsMarkdownPrinter.ts | 2 +- packages/docgen/src/docgen/TypeLocator.ts | 7 +++++ packages/docgen/src/docgen/types.ts | 3 ++ 6 files changed, 48 insertions(+), 3 deletions(-) diff --git a/packages/docgen/src/docgen/ApiDocGenerator.ts b/packages/docgen/src/docgen/ApiDocGenerator.ts index 8e697f42b0..bfe449155b 100644 --- a/packages/docgen/src/docgen/ApiDocGenerator.ts +++ b/packages/docgen/src/docgen/ApiDocGenerator.ts @@ -30,7 +30,7 @@ import { * describes a Backstage API and all of it's related types. * * It receives an exported instance that of the form - * `export name = new Api({id: ..., description: ...})`. + * `export name = createApiRef({id: ..., description: ...})`. * It will then traverse all fields and methods on the interface type, and also * types and declaration of all types that are used by those, both directly and indirectly. * While traversing, it collects information such as names, location in source, docs, etc. @@ -45,6 +45,9 @@ export default class ApiDocGenerator { private readonly basePath: string, ) {} + /** + * Generate documentation information for a given exported symbol. + */ toDoc(apiInstance: ExportedInstance): ApiDoc { const { name, source, args, typeArgs } = apiInstance; @@ -78,12 +81,18 @@ export default class ApiDocGenerator { }; } + /** + * Grab jsDoc and regular comments for a node + */ private getNodeDocs(node: ts.Node): string[] { const docNodes = ((node && (node as any).jsDoc) || []) as ts.JSDoc[]; const docs = docNodes.map(docNode => docNode.comment || '').filter(Boolean); return docs; } + /** + * Collect information about a top-level type. + */ private getInterfaceInfo(typeNode: ts.TypeNode): InterfaceInfo { if (ts.isTypeQueryNode(typeNode)) { throw new Error( @@ -120,6 +129,9 @@ export default class ApiDocGenerator { return { name, docs, file, lineInFile: line + 1, members, dependentTypes }; } + /** + * Grab primitive values from an object literal expression. + */ private getObjectPropertyLiteral( objectLiteral: ts.ObjectLiteralExpression, propertyName: string, @@ -143,6 +155,9 @@ export default class ApiDocGenerator { return initializer.text; } + /** + * Get field definitions for a given symbol. + */ private getMemberInfo( parentName: string, symbol: ts.Symbol, @@ -177,6 +192,9 @@ export default class ApiDocGenerator { }; } + /** + * Recursively search for references to types that we care about and want to include in the documentation. + */ private findAllTypeReferences = ( node: ts.Node | undefined, visited: Set = new Set(), @@ -242,6 +260,9 @@ export default class ApiDocGenerator { }; }; + /** + * Check if a given type declaration is one that we care about. + */ private validateTypeDeclaration( type: ts.Type | undefined, ): undefined | { symbol: ts.Symbol; declaration: ts.Declaration } { @@ -267,6 +288,10 @@ export default class ApiDocGenerator { return { symbol, declaration }; } + /** + * Flatten a tree of TypeInfos with children into a flat + * list of TypeInfos with duplicates removed. + */ private flattenTypes(descs: TypeInfo[]): TypeInfo[] { function getChildren(parent: TypeInfo): TypeInfo[] { return [ @@ -289,6 +314,10 @@ export default class ApiDocGenerator { }); } + /** + * Calculate link positions within a block of code, with 0 being + * the first character in the block. + */ private recalculateLinkOffsets( parent: ts.Node, links: TypeLink[], diff --git a/packages/docgen/src/docgen/ApiDocsPrinter.ts b/packages/docgen/src/docgen/ApiDocsPrinter.ts index d6c412d498..05fcfbd141 100644 --- a/packages/docgen/src/docgen/ApiDocsPrinter.ts +++ b/packages/docgen/src/docgen/ApiDocsPrinter.ts @@ -28,6 +28,9 @@ export default class ApiDocPrinter { this.printerFactory = printerFactory; } + /** + * Print an index file with all ApiRefs and what types they implement. + */ printApiIndex(apiDocs: ApiDoc[]): Buffer { const printer = this.printerFactory(); @@ -58,6 +61,9 @@ export default class ApiDocPrinter { return printer.toBuffer(); } + /** + * Print documentation page for a type implemented by an ApiRef and + */ printInterface(apiType: InterfaceInfo, apiDocs: ApiDoc[]): Buffer { const printer = this.printerFactory(); diff --git a/packages/docgen/src/docgen/GitHubMarkdownPrinter.ts b/packages/docgen/src/docgen/GitHubMarkdownPrinter.ts index 391f50a01d..eb8e10c102 100644 --- a/packages/docgen/src/docgen/GitHubMarkdownPrinter.ts +++ b/packages/docgen/src/docgen/GitHubMarkdownPrinter.ts @@ -26,7 +26,7 @@ const COMMIT_SHA = execSync('git rev-parse HEAD').toString('utf8').trim(); /** - * The MarkdownPrinter is a helper class for building markdown documents. + * The GithubMarkdownPrinter is a MarkdownPrinter for printing Github-flavored markdown documents. */ export default class GithubMarkdownPrinter implements MarkdownPrinter { private str: string = ''; diff --git a/packages/docgen/src/docgen/TechdocsMarkdownPrinter.ts b/packages/docgen/src/docgen/TechdocsMarkdownPrinter.ts index 3609e0526d..91fde3cd27 100644 --- a/packages/docgen/src/docgen/TechdocsMarkdownPrinter.ts +++ b/packages/docgen/src/docgen/TechdocsMarkdownPrinter.ts @@ -25,7 +25,7 @@ const COMMIT_SHA = process.env.COMMIT_SHA || execSync('git rev-parse HEAD').toString('utf8'); /** - * The MarkdownPrinter is a helper class for building markdown documents. + * The TechdocsMarkdownPrinter is a MarkdownPrinter for building TechDocs markdown documents. */ export default class TechdocsMarkdownPrinter implements MarkdownPrinter { private str: string = ''; diff --git a/packages/docgen/src/docgen/TypeLocator.ts b/packages/docgen/src/docgen/TypeLocator.ts index 164275b13f..6030258112 100644 --- a/packages/docgen/src/docgen/TypeLocator.ts +++ b/packages/docgen/src/docgen/TypeLocator.ts @@ -34,6 +34,9 @@ export default class TypeLocator { private readonly sourcePath: string, ) {} + /** + * Get the type of a symbol by export path and name + */ getExportedType(path: string, exportedName: string = 'default'): ts.Type { const source = this.program.getSourceFile(path); if (!source) { @@ -50,6 +53,10 @@ export default class TypeLocator { return type; } + /** + * Find exported instances and return values from calls using the types + * provided in the lookup table. + */ findExportedInstances( typeLookupTable: { [key in T]: ts.Type }, ): { [key in T]: ExportedInstance[] } { diff --git a/packages/docgen/src/docgen/types.ts b/packages/docgen/src/docgen/types.ts index d091e9673e..fae368b58d 100644 --- a/packages/docgen/src/docgen/types.ts +++ b/packages/docgen/src/docgen/types.ts @@ -96,6 +96,9 @@ export type Highlighter = { highlight(test: string): string; }; +/** + * Markdown printer is an abstraction for printing markdown documents of different flavors. + */ export type MarkdownPrinter = { text(text: string): void; header(level: number, text: string, id?: string): void;