Skip to content

Commit 9f479f1

Browse files
sandersnmprobst
authored andcommitted
@link parses trailing <...> as part of linkName (microsoft#46450)
Similar to microsoft#46428. Fixes microsoft#44818
1 parent 76b5562 commit 9f479f1

File tree

3 files changed

+261
-4
lines changed

3 files changed

+261
-4
lines changed

src/services/utilities.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2315,22 +2315,36 @@ namespace ts {
23152315
}
23162316
else {
23172317
const symbol = checker?.getSymbolAtLocation(link.name);
2318-
const trailingParen = link.text.indexOf("()") === 0;
2319-
const name = getTextOfNode(link.name) + (trailingParen ? "()" : "");
2320-
const text = trailingParen ? link.text.slice(2) : link.text;
2318+
const suffix = findLinkNameEnd(link.text);
2319+
const name = getTextOfNode(link.name) + link.text.slice(0, suffix);
2320+
const text = link.text.slice(suffix);
23212321
const decl = symbol?.valueDeclaration || symbol?.declarations?.[0];
23222322
if (decl) {
23232323
parts.push(linkNamePart(name, decl));
23242324
if (text) parts.push(linkTextPart(text));
23252325
}
23262326
else {
2327-
parts.push(linkTextPart(name + (trailingParen ? "" : " ") + text));
2327+
parts.push(linkTextPart(name + (suffix ? "" : " ") + text));
23282328
}
23292329
}
23302330
parts.push(linkPart("}"));
23312331
return parts;
23322332
}
23332333

2334+
function findLinkNameEnd(text: string) {
2335+
if (text.indexOf("()") === 0) return 2;
2336+
if (text[0] !== "<") return 0;
2337+
let brackets = 0;
2338+
let i = 0;
2339+
while (i < text.length) {
2340+
if (text[i] === "<") brackets++;
2341+
if (text[i] === ">") brackets--;
2342+
i++;
2343+
if (!brackets) return i;
2344+
}
2345+
return 0;
2346+
}
2347+
23342348
const carriageReturnLineFeed = "\r\n";
23352349
/**
23362350
* The default is CRLF.
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
[
2+
{
3+
"marker": {
4+
"fileName": "/tests/cases/fourslash/quickInfoLink3.ts",
5+
"position": 169,
6+
"name": ""
7+
},
8+
"quickInfo": {
9+
"kind": "method",
10+
"kindModifiers": "",
11+
"textSpan": {
12+
"start": 166,
13+
"length": 3
14+
},
15+
"displayParts": [
16+
{
17+
"text": "(",
18+
"kind": "punctuation"
19+
},
20+
{
21+
"text": "method",
22+
"kind": "text"
23+
},
24+
{
25+
"text": ")",
26+
"kind": "punctuation"
27+
},
28+
{
29+
"text": " ",
30+
"kind": "space"
31+
},
32+
{
33+
"text": "Foo",
34+
"kind": "className"
35+
},
36+
{
37+
"text": "<",
38+
"kind": "punctuation"
39+
},
40+
{
41+
"text": "T",
42+
"kind": "typeParameterName"
43+
},
44+
{
45+
"text": ">",
46+
"kind": "punctuation"
47+
},
48+
{
49+
"text": ".",
50+
"kind": "punctuation"
51+
},
52+
{
53+
"text": "bar",
54+
"kind": "methodName"
55+
},
56+
{
57+
"text": "(",
58+
"kind": "punctuation"
59+
},
60+
{
61+
"text": ")",
62+
"kind": "punctuation"
63+
},
64+
{
65+
"text": ":",
66+
"kind": "punctuation"
67+
},
68+
{
69+
"text": " ",
70+
"kind": "space"
71+
},
72+
{
73+
"text": "void",
74+
"kind": "keyword"
75+
}
76+
],
77+
"documentation": [
78+
{
79+
"text": "",
80+
"kind": "text"
81+
},
82+
{
83+
"text": "{@link ",
84+
"kind": "link"
85+
},
86+
{
87+
"text": "Foo",
88+
"kind": "linkName",
89+
"target": {
90+
"fileName": "/tests/cases/fourslash/quickInfoLink3.ts",
91+
"textSpan": {
92+
"start": 0,
93+
"length": 175
94+
}
95+
}
96+
},
97+
{
98+
"text": "}",
99+
"kind": "link"
100+
},
101+
{
102+
"text": "\n",
103+
"kind": "text"
104+
},
105+
{
106+
"text": "{@link ",
107+
"kind": "link"
108+
},
109+
{
110+
"text": "Foo<T>",
111+
"kind": "linkName",
112+
"target": {
113+
"fileName": "/tests/cases/fourslash/quickInfoLink3.ts",
114+
"textSpan": {
115+
"start": 0,
116+
"length": 175
117+
}
118+
}
119+
},
120+
{
121+
"text": "}",
122+
"kind": "link"
123+
},
124+
{
125+
"text": "\n",
126+
"kind": "text"
127+
},
128+
{
129+
"text": "{@link ",
130+
"kind": "link"
131+
},
132+
{
133+
"text": "Foo<Array<X>>",
134+
"kind": "linkName",
135+
"target": {
136+
"fileName": "/tests/cases/fourslash/quickInfoLink3.ts",
137+
"textSpan": {
138+
"start": 0,
139+
"length": 175
140+
}
141+
}
142+
},
143+
{
144+
"text": "}",
145+
"kind": "link"
146+
},
147+
{
148+
"text": "\n",
149+
"kind": "text"
150+
},
151+
{
152+
"text": "{@link ",
153+
"kind": "link"
154+
},
155+
{
156+
"text": "Foo<>",
157+
"kind": "linkName",
158+
"target": {
159+
"fileName": "/tests/cases/fourslash/quickInfoLink3.ts",
160+
"textSpan": {
161+
"start": 0,
162+
"length": 175
163+
}
164+
}
165+
},
166+
{
167+
"text": "}",
168+
"kind": "link"
169+
},
170+
{
171+
"text": "\n",
172+
"kind": "text"
173+
},
174+
{
175+
"text": "{@link ",
176+
"kind": "link"
177+
},
178+
{
179+
"text": "Foo",
180+
"kind": "linkName",
181+
"target": {
182+
"fileName": "/tests/cases/fourslash/quickInfoLink3.ts",
183+
"textSpan": {
184+
"start": 0,
185+
"length": 175
186+
}
187+
}
188+
},
189+
{
190+
"text": ">",
191+
"kind": "linkText"
192+
},
193+
{
194+
"text": "}",
195+
"kind": "link"
196+
},
197+
{
198+
"text": "\n",
199+
"kind": "text"
200+
},
201+
{
202+
"text": "{@link ",
203+
"kind": "link"
204+
},
205+
{
206+
"text": "Foo",
207+
"kind": "linkName",
208+
"target": {
209+
"fileName": "/tests/cases/fourslash/quickInfoLink3.ts",
210+
"textSpan": {
211+
"start": 0,
212+
"length": 175
213+
}
214+
}
215+
},
216+
{
217+
"text": "<",
218+
"kind": "linkText"
219+
},
220+
{
221+
"text": "}",
222+
"kind": "link"
223+
}
224+
]
225+
}
226+
}
227+
]
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
///<reference path="fourslash.ts" />
2+
3+
//// class Foo<T> {
4+
//// /**
5+
//// * {@link Foo}
6+
//// * {@link Foo<T>}
7+
//// * {@link Foo<Array<X>>}
8+
//// * {@link Foo<>}
9+
//// * {@link Foo>}
10+
//// * {@link Foo<}
11+
//// */
12+
//// bar/**/(){}
13+
//// }
14+
15+
verify.noErrors()
16+
verify.baselineQuickInfo();

0 commit comments

Comments
 (0)