Skip to content

Commit d84be8e

Browse files
authored
fix(56602): JSDoc render with @param Sub-object properties (#56657)
1 parent 0b03c80 commit d84be8e

File tree

3 files changed

+252
-6
lines changed

3 files changed

+252
-6
lines changed

src/services/jsDoc.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
CompletionEntry,
99
CompletionEntryDetails,
1010
Completions,
11+
concatenate,
1112
ConstructorDeclaration,
1213
contains,
1314
Declaration,
@@ -258,17 +259,21 @@ export function getJsDocTagsFromDeclarations(declarations?: Declaration[], check
258259
}
259260
for (const tag of tags) {
260261
infos.push({ name: tag.tagName.text, text: getCommentDisplayParts(tag, checker) });
261-
262-
if (isJSDocPropertyLikeTag(tag) && tag.isNameFirst && tag.typeExpression && isJSDocTypeLiteral(tag.typeExpression.type)) {
263-
forEach(tag.typeExpression.type.jsDocPropertyTags, propTag => {
264-
infos.push({ name: propTag.tagName.text, text: getCommentDisplayParts(propTag, checker) });
265-
});
266-
}
262+
infos.push(...getJSDocPropertyTagsInfo(tryGetJSDocPropertyTags(tag), checker));
267263
}
268264
});
269265
return infos;
270266
}
271267

268+
function getJSDocPropertyTagsInfo(nodes: readonly JSDocTag[] | undefined, checker: TypeChecker | undefined): readonly JSDocTagInfo[] {
269+
return flatMap(nodes, propTag => concatenate([{ name: propTag.tagName.text, text: getCommentDisplayParts(propTag, checker) }], getJSDocPropertyTagsInfo(tryGetJSDocPropertyTags(propTag), checker)));
270+
}
271+
272+
function tryGetJSDocPropertyTags(node: JSDocTag) {
273+
return isJSDocPropertyLikeTag(node) && node.isNameFirst && node.typeExpression &&
274+
isJSDocTypeLiteral(node.typeExpression.type) ? node.typeExpression.type.jsDocPropertyTags : undefined;
275+
}
276+
272277
function getDisplayPartsFromComment(comment: string | readonly JSDocComment[], checker: TypeChecker | undefined): SymbolDisplayPart[] {
273278
if (typeof comment === "string") {
274279
return [textPart(comment)];
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
// === QuickInfo ===
2+
=== /tests/cases/fourslash/quickInfoJsDocTags14.ts ===
3+
// /**
4+
// * @param {Object} options the args object
5+
// * @param {number} options.a first number
6+
// * @param {number} options.b second number
7+
// * @param {Object} options.c sub-object
8+
// * @param {number} options.c.d third number
9+
// * @param {Function} callback the callback function
10+
// * @returns {number}
11+
// */
12+
// function fn(options, callback = null) { }
13+
// ^^
14+
// | ----------------------------------------------------------------------
15+
// | function fn(options: any, callback?: any): void
16+
// | @param options the args object
17+
// | @param options.a first number
18+
// | @param options.b second number
19+
// | @param options.c sub-object
20+
// | @param options.c.d third number
21+
// | @param callback the callback function
22+
// | @returns
23+
// | ----------------------------------------------------------------------
24+
25+
[
26+
{
27+
"marker": {
28+
"fileName": "/tests/cases/fourslash/quickInfoJsDocTags14.ts",
29+
"position": 302,
30+
"name": ""
31+
},
32+
"item": {
33+
"kind": "function",
34+
"kindModifiers": "",
35+
"textSpan": {
36+
"start": 302,
37+
"length": 2
38+
},
39+
"displayParts": [
40+
{
41+
"text": "function",
42+
"kind": "keyword"
43+
},
44+
{
45+
"text": " ",
46+
"kind": "space"
47+
},
48+
{
49+
"text": "fn",
50+
"kind": "functionName"
51+
},
52+
{
53+
"text": "(",
54+
"kind": "punctuation"
55+
},
56+
{
57+
"text": "options",
58+
"kind": "parameterName"
59+
},
60+
{
61+
"text": ":",
62+
"kind": "punctuation"
63+
},
64+
{
65+
"text": " ",
66+
"kind": "space"
67+
},
68+
{
69+
"text": "any",
70+
"kind": "keyword"
71+
},
72+
{
73+
"text": ",",
74+
"kind": "punctuation"
75+
},
76+
{
77+
"text": " ",
78+
"kind": "space"
79+
},
80+
{
81+
"text": "callback",
82+
"kind": "parameterName"
83+
},
84+
{
85+
"text": "?",
86+
"kind": "punctuation"
87+
},
88+
{
89+
"text": ":",
90+
"kind": "punctuation"
91+
},
92+
{
93+
"text": " ",
94+
"kind": "space"
95+
},
96+
{
97+
"text": "any",
98+
"kind": "keyword"
99+
},
100+
{
101+
"text": ")",
102+
"kind": "punctuation"
103+
},
104+
{
105+
"text": ":",
106+
"kind": "punctuation"
107+
},
108+
{
109+
"text": " ",
110+
"kind": "space"
111+
},
112+
{
113+
"text": "void",
114+
"kind": "keyword"
115+
}
116+
],
117+
"documentation": [],
118+
"tags": [
119+
{
120+
"name": "param",
121+
"text": [
122+
{
123+
"text": "options",
124+
"kind": "parameterName"
125+
},
126+
{
127+
"text": " ",
128+
"kind": "space"
129+
},
130+
{
131+
"text": "the args object",
132+
"kind": "text"
133+
}
134+
]
135+
},
136+
{
137+
"name": "param",
138+
"text": [
139+
{
140+
"text": "options.a",
141+
"kind": "parameterName"
142+
},
143+
{
144+
"text": " ",
145+
"kind": "space"
146+
},
147+
{
148+
"text": "first number",
149+
"kind": "text"
150+
}
151+
]
152+
},
153+
{
154+
"name": "param",
155+
"text": [
156+
{
157+
"text": "options.b",
158+
"kind": "parameterName"
159+
},
160+
{
161+
"text": " ",
162+
"kind": "space"
163+
},
164+
{
165+
"text": "second number",
166+
"kind": "text"
167+
}
168+
]
169+
},
170+
{
171+
"name": "param",
172+
"text": [
173+
{
174+
"text": "options.c",
175+
"kind": "parameterName"
176+
},
177+
{
178+
"text": " ",
179+
"kind": "space"
180+
},
181+
{
182+
"text": "sub-object",
183+
"kind": "text"
184+
}
185+
]
186+
},
187+
{
188+
"name": "param",
189+
"text": [
190+
{
191+
"text": "options.c.d",
192+
"kind": "parameterName"
193+
},
194+
{
195+
"text": " ",
196+
"kind": "space"
197+
},
198+
{
199+
"text": "third number",
200+
"kind": "text"
201+
}
202+
]
203+
},
204+
{
205+
"name": "param",
206+
"text": [
207+
{
208+
"text": "callback",
209+
"kind": "parameterName"
210+
},
211+
{
212+
"text": " ",
213+
"kind": "space"
214+
},
215+
{
216+
"text": "the callback function",
217+
"kind": "text"
218+
}
219+
]
220+
},
221+
{
222+
"name": "returns"
223+
}
224+
]
225+
}
226+
}
227+
]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
/////**
4+
//// * @param {Object} options the args object
5+
//// * @param {number} options.a first number
6+
//// * @param {number} options.b second number
7+
//// * @param {Object} options.c sub-object
8+
//// * @param {number} options.c.d third number
9+
//// * @param {Function} callback the callback function
10+
//// * @returns {number}
11+
//// */
12+
////function /**/fn(options, callback = null) { }
13+
14+
verify.baselineQuickInfo();

0 commit comments

Comments
 (0)