UNPKG

alm

Version:

The best IDE for TypeScript

137 lines (121 loc) 4.28 kB
/** * NOTE: Pulled straight out of typedoc 🌹 * https://github.com/TypeStrong/typedoc/blob/2e855cf8c62c7813ac62cb1ef911c9a0c5e034c2/src/lib/converter/factories/comment.ts */ /** * Returns the parsed comment for a given node. */ export function getParsedComment(node: ts.Node, sourceFile: ts.SourceFile): string | null { const rawComment = getRawComment(node, sourceFile); if (!rawComment) { return rawComment; } return parseComment(rawComment); } /** * Resurected from * https://github.com/Microsoft/TypeScript/commit/bffde588cc60c524ba120413681871c6d969274b */ export function getCommentsFromJSDoc(node: ts.Node): string[] { // return ts.map(ts.getAllJSDocs(node), doc => doc.comment); // Its dead jim. Let it go. return ['Feature disabled as it was deleted from TS https://github.com/Microsoft/TypeScript/pull/21119#discussion_r160754254']; } /** * Return the raw comment string for the given node. * * @param node The node whose comment should be resolved. * @returns The raw comment string or NULL if no comment could be found. */ export function getRawComment(node: ts.Node, sourceFile: ts.SourceFile): string | null { if (node.parent && node.parent.kind === ts.SyntaxKind.VariableDeclarationList) { node = node.parent.parent; } else if (node.kind === ts.SyntaxKind.ModuleDeclaration) { if (!isTopmostModuleDeclaration(<ts.ModuleDeclaration>node)) { return null; } else { node = getRootModuleDeclaration(<ts.ModuleDeclaration>node); } } var comments = getCommentsFromJSDoc(node); if (comments && comments.length) { var comment: string; if (node.kind == ts.SyntaxKind.SourceFile) { if (comments.length == 1) return null; comment = comments[0]; } else { comment = comments[comments.length - 1]; } return comment; } else { return null; } } /** * Return the root module declaration of the given module declaration. * * In the following example this function would always return module * <code>A</code> no matter which of the modules was passed in. * * ``` * module A.B.C { } * ``` */ function getRootModuleDeclaration(node: ts.ModuleDeclaration): ts.Node { while (node.parent && node.parent.kind == ts.SyntaxKind.ModuleDeclaration) { let parent = <ts.ModuleDeclaration>node.parent; if (node.name.pos == parent.name.end + 1) { node = parent; } else { break; } } return node; } /** * Check whether the given module declaration is the topmost. * * This funtion returns TRUE if there is no trailing module defined, in * the following example this would be the case only for module <code>C</code>. * * ``` * module A.B.C { } * ``` * * @param node The module definition that should be tested. * @return TRUE if the given node is the topmost module declaration, FALSE otherwise. */ function isTopmostModuleDeclaration(node: ts.ModuleDeclaration): boolean { if (node.nextContainer && node.nextContainer.kind == ts.SyntaxKind.ModuleDeclaration) { let next = <ts.ModuleDeclaration>node.nextContainer; if (node.name.end + 1 == next.name.pos) { return false; } } return true; } /** * Modified from original to return `string` instead of `Comment` class * We lose `tag` information, but that is fine by me for now. */ export function parseComment(text: string): string { let comment = ''; function consumeTypeData(line: string): string { line = line.replace(/^\{[^\}]*\}+/, ''); line = line.replace(/^\[[^\[][^\]]*\]+/, ''); return line.trim(); } function readBareLine(line: string) { comment += (comment == '' ? '' : '\n') + line; } function readLine(line: string) { line = line.replace(/^\s*\*? ?/, ''); line = line.replace(/\s*$/, ''); readBareLine(line); } // text = text.replace(/^\s*\/\*+\s*(\r\n?|\n)/, ''); // text = text.replace(/(\r\n?|\n)\s*\*+\/\s*$/, ''); text = text.replace(/^\s*\/\*+/, ''); text = text.replace(/\*+\/\s*$/, ''); text.split(/\r\n?|\n/).forEach(readLine); return comment; }