Skip to content

Commit 792e6d6

Browse files
authored
Fix symbol display exception when handling incomplete class (microsoft#44936)
When a class declaration lacks a name, don't throw an exception when producing the display parts (e.g. for QuickInfo). Remaining issues: 1. The name shows as "__missing", the name of the underlying symbol, rather than "(Missing)", as it is for the corresponding function declaration case (because the parse constructs a missing identifier node for the function declaration). 2. "(Missing)" is hard-coded, rather than being a localizable resource string. 3. When an anonymous class declaration is a default export, the corresponding symbol is named "default", resulting in the confusing display string "class default". Since display parts are built using existing `symbolToString` functionality, it wasn't clear whether detecting special symbol names and replacing them with user-friendly strings could be done without breaking other functionality. Similarly, changing the shape of the parse tree seemed riskier than the problem justified (the user experience is just not getting QuickInfo for the incomplete declaration, which seems acceptable).
1 parent 7753efa commit 792e6d6

9 files changed

+452
-1
lines changed

src/services/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ namespace ts {
758758
if (isClassDeclaration(node)) {
759759
// for class and function declarations, use the `default` modifier
760760
// when the declaration is unnamed.
761-
const defaultModifier = find(node.modifiers!, isDefaultModifier);
761+
const defaultModifier = node.modifiers && find(node.modifiers, isDefaultModifier);
762762
if (defaultModifier) return defaultModifier;
763763
}
764764
if (isClassExpression(node)) {
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
[
2+
{
3+
"marker": {
4+
"fileName": "/tests/cases/fourslash/quickInfoDisplayPartsClassDefaultAnonymous.ts",
5+
"position": 0,
6+
"name": "1"
7+
}
8+
},
9+
{
10+
"marker": {
11+
"fileName": "/tests/cases/fourslash/quickInfoDisplayPartsClassDefaultAnonymous.ts",
12+
"position": 7,
13+
"name": "2"
14+
},
15+
"quickInfo": {
16+
"kind": "class",
17+
"kindModifiers": "export",
18+
"textSpan": {
19+
"start": 7,
20+
"length": 7
21+
},
22+
"displayParts": [
23+
{
24+
"text": "class",
25+
"kind": "keyword"
26+
},
27+
{
28+
"text": " ",
29+
"kind": "space"
30+
},
31+
{
32+
"text": "default",
33+
"kind": "className"
34+
}
35+
],
36+
"documentation": []
37+
}
38+
},
39+
{
40+
"marker": {
41+
"fileName": "/tests/cases/fourslash/quickInfoDisplayPartsClassDefaultAnonymous.ts",
42+
"position": 15,
43+
"name": "3"
44+
},
45+
"quickInfo": {
46+
"kind": "class",
47+
"kindModifiers": "export",
48+
"textSpan": {
49+
"start": 15,
50+
"length": 5
51+
},
52+
"displayParts": [
53+
{
54+
"text": "class",
55+
"kind": "keyword"
56+
},
57+
{
58+
"text": " ",
59+
"kind": "space"
60+
},
61+
{
62+
"text": "default",
63+
"kind": "className"
64+
}
65+
],
66+
"documentation": []
67+
}
68+
},
69+
{
70+
"marker": {
71+
"fileName": "/tests/cases/fourslash/quickInfoDisplayPartsClassDefaultAnonymous.ts",
72+
"position": 21,
73+
"name": "4"
74+
}
75+
}
76+
]
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
[
2+
{
3+
"marker": {
4+
"fileName": "/tests/cases/fourslash/quickInfoDisplayPartsClassDefaultNamed.ts",
5+
"position": 0,
6+
"name": "1"
7+
}
8+
},
9+
{
10+
"marker": {
11+
"fileName": "/tests/cases/fourslash/quickInfoDisplayPartsClassDefaultNamed.ts",
12+
"position": 7,
13+
"name": "2"
14+
},
15+
"quickInfo": {
16+
"kind": "class",
17+
"kindModifiers": "export",
18+
"textSpan": {
19+
"start": 7,
20+
"length": 7
21+
},
22+
"displayParts": [
23+
{
24+
"text": "class",
25+
"kind": "keyword"
26+
},
27+
{
28+
"text": " ",
29+
"kind": "space"
30+
},
31+
{
32+
"text": "C",
33+
"kind": "className"
34+
}
35+
],
36+
"documentation": []
37+
}
38+
},
39+
{
40+
"marker": {
41+
"fileName": "/tests/cases/fourslash/quickInfoDisplayPartsClassDefaultNamed.ts",
42+
"position": 15,
43+
"name": "3"
44+
},
45+
"quickInfo": {
46+
"kind": "class",
47+
"kindModifiers": "export",
48+
"textSpan": {
49+
"start": 15,
50+
"length": 5
51+
},
52+
"displayParts": [
53+
{
54+
"text": "class",
55+
"kind": "keyword"
56+
},
57+
{
58+
"text": " ",
59+
"kind": "space"
60+
},
61+
{
62+
"text": "C",
63+
"kind": "className"
64+
}
65+
],
66+
"documentation": []
67+
}
68+
},
69+
{
70+
"marker": {
71+
"fileName": "/tests/cases/fourslash/quickInfoDisplayPartsClassDefaultNamed.ts",
72+
"position": 21,
73+
"name": "4"
74+
},
75+
"quickInfo": {
76+
"kind": "class",
77+
"kindModifiers": "export",
78+
"textSpan": {
79+
"start": 21,
80+
"length": 1
81+
},
82+
"displayParts": [
83+
{
84+
"text": "class",
85+
"kind": "keyword"
86+
},
87+
{
88+
"text": " ",
89+
"kind": "space"
90+
},
91+
{
92+
"text": "C",
93+
"kind": "className"
94+
}
95+
],
96+
"documentation": []
97+
}
98+
},
99+
{
100+
"marker": {
101+
"fileName": "/tests/cases/fourslash/quickInfoDisplayPartsClassDefaultNamed.ts",
102+
"position": 23,
103+
"name": "5"
104+
}
105+
}
106+
]
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
[
2+
{
3+
"marker": {
4+
"fileName": "/tests/cases/fourslash/quickInfoDisplayPartsClassIncomplete.ts",
5+
"position": 0,
6+
"name": "1"
7+
},
8+
"quickInfo": {
9+
"kind": "class",
10+
"kindModifiers": "",
11+
"textSpan": {
12+
"start": 0,
13+
"length": 5
14+
},
15+
"displayParts": [
16+
{
17+
"text": "class",
18+
"kind": "keyword"
19+
},
20+
{
21+
"text": " ",
22+
"kind": "space"
23+
},
24+
{
25+
"text": "__missing",
26+
"kind": "className"
27+
}
28+
],
29+
"documentation": []
30+
}
31+
},
32+
{
33+
"marker": {
34+
"fileName": "/tests/cases/fourslash/quickInfoDisplayPartsClassIncomplete.ts",
35+
"position": 6,
36+
"name": "2"
37+
}
38+
}
39+
]

0 commit comments

Comments
 (0)