• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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