1//// [tests/cases/compiler/APISample_jsdoc.ts] //// 2 3//// [package.json] 4{ 5 "name": "typescript", 6 "types": "/.ts/typescript.d.ts" 7} 8 9//// [APISample_jsdoc.ts] 10/* 11 * Note: This test is a public API sample. The original sources can be found 12 * at: https://github.com/YousefED/typescript-json-schema 13 * https://github.com/vega/ts-json-schema-generator 14 * Please log a "breaking change" issue for any API breaking change affecting this issue 15 */ 16 17declare var console: any; 18 19import * as ts from "typescript"; 20 21// excerpted from https://github.com/YousefED/typescript-json-schema 22// (converted from a method and modified; for example, `this: any` to compensate, among other changes) 23function parseCommentsIntoDefinition(this: any, 24 symbol: ts.Symbol, 25 definition: {description?: string, [s: string]: string | undefined}, 26 otherAnnotations: { [s: string]: true}): void { 27 if (!symbol) { 28 return; 29 } 30 31 // the comments for a symbol 32 let comments = symbol.getDocumentationComment(undefined); 33 34 if (comments.length) { 35 definition.description = comments.map(comment => comment.kind === "lineBreak" ? comment.text : comment.text.trim().replace(/\r\n/g, "\n")).join(""); 36 } 37 38 // jsdocs are separate from comments 39 const jsdocs = symbol.getJsDocTags(this.checker); 40 jsdocs.forEach(doc => { 41 // if we have @TJS-... annotations, we have to parse them 42 const { name, text } = doc; 43 if (this.userValidationKeywords[name]) { 44 definition[name] = this.parseValue(text); 45 } else { 46 // special annotations 47 otherAnnotations[doc.name] = true; 48 } 49 }); 50} 51 52 53// excerpted from https://github.com/vega/ts-json-schema-generator 54export interface Annotations { 55 [name: string]: any; 56} 57function getAnnotations(this: any, node: ts.Node): Annotations | undefined { 58 const symbol: ts.Symbol = (node as any).symbol; 59 if (!symbol) { 60 return undefined; 61 } 62 63 const jsDocTags: ts.JSDocTagInfo[] = symbol.getJsDocTags(this.checker); 64 if (!jsDocTags || !jsDocTags.length) { 65 return undefined; 66 } 67 68 const annotations: Annotations = jsDocTags.reduce((result: Annotations, jsDocTag: ts.JSDocTagInfo) => { 69 const value = this.parseJsDocTag(jsDocTag); 70 if (value !== undefined) { 71 result[jsDocTag.name] = value; 72 } 73 74 return result; 75 }, {}); 76 return Object.keys(annotations).length ? annotations : undefined; 77} 78 79// these examples are artificial and mostly nonsensical 80function parseSpecificTags(node: ts.Node) { 81 if (node.kind === ts.SyntaxKind.Parameter) { 82 return ts.getJSDocParameterTags(node as ts.ParameterDeclaration); 83 } 84 if (node.kind === ts.SyntaxKind.FunctionDeclaration) { 85 const func = node as ts.FunctionDeclaration; 86 if (ts.hasJSDocParameterTags(func)) { 87 const flat: ts.JSDocTag[] = []; 88 for (const tags of func.parameters.map(ts.getJSDocParameterTags)) { 89 if (tags) flat.push(...tags); 90 } 91 return flat; 92 } 93 } 94} 95 96function getReturnTypeFromJSDoc(node: ts.Node) { 97 if (node.kind === ts.SyntaxKind.FunctionDeclaration) { 98 return ts.getJSDocReturnType(node); 99 } 100 let type = ts.getJSDocType(node); 101 if (type && type.kind === ts.SyntaxKind.FunctionType) { 102 return (type as ts.FunctionTypeNode).type; 103 } 104} 105 106function getAllTags(node: ts.Node) { 107 ts.getJSDocTags(node); 108} 109 110function getSomeOtherTags(node: ts.Node) { 111 const tags: (ts.JSDocTag | undefined)[] = []; 112 tags.push(ts.getJSDocAugmentsTag(node)); 113 tags.push(ts.getJSDocClassTag(node)); 114 tags.push(ts.getJSDocReturnTag(node)); 115 const type = ts.getJSDocTypeTag(node); 116 if (type) { 117 tags.push(type); 118 } 119 tags.push(ts.getJSDocTemplateTag(node)); 120 return tags; 121} 122 123 124//// [APISample_jsdoc.js] 125"use strict"; 126/* 127 * Note: This test is a public API sample. The original sources can be found 128 * at: https://github.com/YousefED/typescript-json-schema 129 * https://github.com/vega/ts-json-schema-generator 130 * Please log a "breaking change" issue for any API breaking change affecting this issue 131 */ 132exports.__esModule = true; 133var ts = require("typescript"); 134// excerpted from https://github.com/YousefED/typescript-json-schema 135// (converted from a method and modified; for example, `this: any` to compensate, among other changes) 136function parseCommentsIntoDefinition(symbol, definition, otherAnnotations) { 137 var _this = this; 138 if (!symbol) { 139 return; 140 } 141 // the comments for a symbol 142 var comments = symbol.getDocumentationComment(undefined); 143 if (comments.length) { 144 definition.description = comments.map(function (comment) { return comment.kind === "lineBreak" ? comment.text : comment.text.trim().replace(/\r\n/g, "\n"); }).join(""); 145 } 146 // jsdocs are separate from comments 147 var jsdocs = symbol.getJsDocTags(this.checker); 148 jsdocs.forEach(function (doc) { 149 // if we have @TJS-... annotations, we have to parse them 150 var name = doc.name, text = doc.text; 151 if (_this.userValidationKeywords[name]) { 152 definition[name] = _this.parseValue(text); 153 } 154 else { 155 // special annotations 156 otherAnnotations[doc.name] = true; 157 } 158 }); 159} 160function getAnnotations(node) { 161 var _this = this; 162 var symbol = node.symbol; 163 if (!symbol) { 164 return undefined; 165 } 166 var jsDocTags = symbol.getJsDocTags(this.checker); 167 if (!jsDocTags || !jsDocTags.length) { 168 return undefined; 169 } 170 var annotations = jsDocTags.reduce(function (result, jsDocTag) { 171 var value = _this.parseJsDocTag(jsDocTag); 172 if (value !== undefined) { 173 result[jsDocTag.name] = value; 174 } 175 return result; 176 }, {}); 177 return Object.keys(annotations).length ? annotations : undefined; 178} 179// these examples are artificial and mostly nonsensical 180function parseSpecificTags(node) { 181 if (node.kind === ts.SyntaxKind.Parameter) { 182 return ts.getJSDocParameterTags(node); 183 } 184 if (node.kind === ts.SyntaxKind.FunctionDeclaration) { 185 var func = node; 186 if (ts.hasJSDocParameterTags(func)) { 187 var flat = []; 188 for (var _i = 0, _a = func.parameters.map(ts.getJSDocParameterTags); _i < _a.length; _i++) { 189 var tags = _a[_i]; 190 if (tags) 191 flat.push.apply(flat, tags); 192 } 193 return flat; 194 } 195 } 196} 197function getReturnTypeFromJSDoc(node) { 198 if (node.kind === ts.SyntaxKind.FunctionDeclaration) { 199 return ts.getJSDocReturnType(node); 200 } 201 var type = ts.getJSDocType(node); 202 if (type && type.kind === ts.SyntaxKind.FunctionType) { 203 return type.type; 204 } 205} 206function getAllTags(node) { 207 ts.getJSDocTags(node); 208} 209function getSomeOtherTags(node) { 210 var tags = []; 211 tags.push(ts.getJSDocAugmentsTag(node)); 212 tags.push(ts.getJSDocClassTag(node)); 213 tags.push(ts.getJSDocReturnTag(node)); 214 var type = ts.getJSDocTypeTag(node); 215 if (type) { 216 tags.push(type); 217 } 218 tags.push(ts.getJSDocTemplateTag(node)); 219 return tags; 220} 221