From 95c46a16747de1d387e9735934762f481c92fcfc Mon Sep 17 00:00:00 2001 From: Juan Miguel Besada Date: Mon, 15 Feb 2021 21:09:51 +0100 Subject: [PATCH] chore(): Use tsdoc to generate enhanced introspect comments --- lib/plugin/utils/ast-utils.ts | 25 +++++++++ .../visitors/controller-class.visitor.ts | 56 +++++++++++++------ 2 files changed, 64 insertions(+), 17 deletions(-) diff --git a/lib/plugin/utils/ast-utils.ts b/lib/plugin/utils/ast-utils.ts index 9383477dc..70383efa4 100644 --- a/lib/plugin/utils/ast-utils.ts +++ b/lib/plugin/utils/ast-utils.ts @@ -18,6 +18,7 @@ import { TypeFormatFlags } from 'typescript'; import { isDynamicallyAdded } from './plugin-utils'; +import { DocComment, DocExcerpt, DocNode, ParserContext, TSDocParser } from '@microsoft/tsdoc'; export function isArray(type: Type) { const symbol = type.getSymbol(); @@ -102,6 +103,30 @@ export function getDefaultTypeFormatFlags(enclosingNode: Node) { return formatFlags; } +export function getNodeDocs( + node: Node +): DocComment { + const tsdocParser: TSDocParser = new TSDocParser(); + const parserContext: ParserContext = tsdocParser.parseString(node.getFullText()); + return parserContext.docComment; +} + +export function docNodeToString(docNode: DocNode): string { + let result = ''; + + if (docNode) { + if (docNode instanceof DocExcerpt) { + result += docNode.content.toString(); + } + + for(const childNode of docNode.getChildNodes()) { + result += docNodeToString(childNode); + } + } + + return result.trim(); +} + export function getMainCommentAndExamplesOfNode( node: Node, sourceFile: SourceFile, diff --git a/lib/plugin/visitors/controller-class.visitor.ts b/lib/plugin/visitors/controller-class.visitor.ts index ebeddcf87..21f9782d6 100644 --- a/lib/plugin/visitors/controller-class.visitor.ts +++ b/lib/plugin/visitors/controller-class.visitor.ts @@ -4,8 +4,9 @@ import { ApiOperation, ApiResponse } from '../../decorators'; import { PluginOptions } from '../merge-options'; import { OPENAPI_NAMESPACE } from '../plugin-constants'; import { + docNodeToString, getDecoratorArguments, - getMainCommentAndExamplesOfNode + getMainCommentAndExamplesOfNode, getNodeDocs } from '../utils/ast-utils'; import { getDecoratorOrUndefinedByNames, @@ -116,25 +117,46 @@ export class ControllerClassVisitor extends AbstractFileVisitor { !apiOperationExprProperties || !hasPropertyKey(keyToGenerate, apiOperationExprProperties) ) { - const [extractedComments] = getMainCommentAndExamplesOfNode( - node, - sourceFile, - typeChecker - ); - if (!extractedComments) { - // Node does not have any comments - return []; + const properties = []; + + if (keyToGenerate) { + const [extractedComments] = getMainCommentAndExamplesOfNode( + node, + sourceFile, + typeChecker + ); + + if (!extractedComments) { + // Node does not have any comments + return []; + } + + properties.push(ts.createPropertyAssignment(keyToGenerate, ts.createLiteral(extractedComments))); + } else { + const docs = getNodeDocs(node); + + if (!docs) { + return []; + } + + const summary = docNodeToString(docs.summarySection); + if (summary && (!apiOperationExprProperties || !hasPropertyKey("summary", apiOperationExprProperties))) { + properties.push(ts.createPropertyAssignment("summary", ts.createLiteral(summary))); + } + + const remarks = docNodeToString(docs.remarksBlock.content); + if (remarks && (!apiOperationExprProperties || !hasPropertyKey("description", apiOperationExprProperties))) { + properties.push(ts.createPropertyAssignment("description", ts.createLiteral(remarks))); + } } - const properties = [ - ts.createPropertyAssignment( - keyToGenerate, - ts.createLiteral(extractedComments) - ), - ...(apiOperationExprProperties ?? ts.createNodeArray()) - ]; + const apiOperationDecoratorArguments: ts.NodeArray = ts.createNodeArray( - [ts.createObjectLiteral(compact(properties))] + [ts.createObjectLiteral(compact([ + ...properties, + ...(apiOperationExprProperties ?? ts.createNodeArray()) + ]))] ); + if (apiOperationDecorator) { ((apiOperationDecorator.expression as ts.CallExpression) as any).arguments = apiOperationDecoratorArguments; } else {