From ee0a0972b54b73305733aad6f62ea9dd158f57ce Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Wed, 23 Mar 2022 11:29:52 +0800 Subject: [PATCH] chore: dts function generator and comments --- .../src/tsgenerator.ts | 48 +++++++++++++++++-- .../test/demo/index.ts | 7 +++ 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/packages/plugin-declaration-generator/src/tsgenerator.ts b/packages/plugin-declaration-generator/src/tsgenerator.ts index 2b746c71..27d0d3a5 100644 --- a/packages/plugin-declaration-generator/src/tsgenerator.ts +++ b/packages/plugin-declaration-generator/src/tsgenerator.ts @@ -1,6 +1,15 @@ import ts from 'typescript'; import fs from 'fs-extra'; +/** + * Tools: https://ts-ast-viewer.com/ + */ + +interface ExportModuleItem { + name: string; + comment?: string; +} + /** * 解析文件 */ @@ -10,20 +19,53 @@ export function parseFile(filePath: string, options: ts.CompilerOptions) { const service = ts.createLanguageService(host, ts.createDocumentRegistry()); const program = service.getProgram(); - const exportModules: string[] = []; - program?.getSourceFile(filePath)?.forEachChild((node) => { + const exportModules: ExportModuleItem[] = []; + const sourceFile = program?.getSourceFile(filePath); + sourceFile?.forEachChild((node) => { if (ts.isExportDeclaration(node)) { + // 如果为导出声明: export { foo } from 'foo' node.exportClause?.forEachChild((exportSpec) => { if (ts.isExportSpecifier(exportSpec)) { - exportModules.push(exportSpec.name.text); + exportModules.push({ + name: exportSpec.name.text, + // comment: + }); } }); + } else if (isExportFunc(node)) { + // 如果是方法导出: export function foo() {} + if (node.name) { + exportModules.push({ + name: node.name.text, + comment: getNodeComments(node), + }); + } } }); return { exportModules }; } +function isExportFunc(node: ts.Node): node is ts.FunctionDeclaration { + if (ts.isFunctionDeclaration(node)) { + if (node.modifiers) { + return node.modifiers.some((m) => m.kind === ts.SyntaxKind.ExportKeyword); + } + } + + return false; +} + +function getNodeComments(node: ts.Node): string | undefined { + const comments = ts.getSyntheticLeadingComments(node); + + if (!comments) { + return undefined; + } + + return comments.map((c) => c.text).join('\n'); +} + class FileServiceHost implements ts.LanguageServiceHost { constructor(public filePath: string, private options: ts.CompilerOptions) {} diff --git a/packages/plugin-declaration-generator/test/demo/index.ts b/packages/plugin-declaration-generator/test/demo/index.ts index d5c9e72a..a90b8b13 100644 --- a/packages/plugin-declaration-generator/test/demo/index.ts +++ b/packages/plugin-declaration-generator/test/demo/index.ts @@ -1,2 +1,9 @@ export { foo } from '@/foo'; export { bar } from '@/bar'; + +/** + * Root export + */ +export function main() { + console.log('main'); +}