Skip to content

Commit c93f20b

Browse files
authored
Fix(50161): Instantiation expressions trigger incorrect error messages (#52373)
1 parent 7c22023 commit c93f20b

File tree

9 files changed

+286
-15
lines changed

9 files changed

+286
-15
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44708,7 +44708,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4470844708
return node.parent.kind === SyntaxKind.TypeReference;
4470944709
}
4471044710

44711-
function isHeritageClauseElementIdentifier(node: Node): boolean {
44711+
function isInNameOfExpressionWithTypeArguments(node: Node): boolean {
4471244712
while (node.parent.kind === SyntaxKind.PropertyAccessExpression) {
4471344713
node = node.parent;
4471444714
}
@@ -44834,11 +44834,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4483444834
name = name.parent as QualifiedName | PropertyAccessEntityNameExpression | JSDocMemberName;
4483544835
}
4483644836

44837-
if (isHeritageClauseElementIdentifier(name)) {
44837+
if (isInNameOfExpressionWithTypeArguments(name)) {
4483844838
let meaning = SymbolFlags.None;
44839-
// In an interface or class, we're definitely interested in a type.
4484044839
if (name.parent.kind === SyntaxKind.ExpressionWithTypeArguments) {
44841-
meaning = SymbolFlags.Type;
44840+
// An 'ExpressionWithTypeArguments' may appear in type space (interface Foo extends Bar<T>),
44841+
// value space (return foo<T>), or both(class Foo extends Bar<T>); ensure the meaning matches.
44842+
meaning = isPartOfTypeNode(name) ? SymbolFlags.Type : SymbolFlags.Value;
4484244843

4484344844
// In a class 'extends' clause we are also looking for a value.
4484444845
if (isExpressionWithTypeArgumentsInClassExtendsClause(name.parent)) {

src/testRunner/tests.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,4 @@ import "./unittests/tsserver/typingsInstaller";
190190
import "./unittests/tsserver/versionCache";
191191
import "./unittests/tsserver/watchEnvironment";
192192
import "./unittests/debugDeprecation";
193+
import "./unittests/tsserver/inconsistentErrorInEditor";
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import * as ts from "../../_namespaces/ts";
2+
import {
3+
createServerHost,
4+
} from "../virtualFileSystemWithWatch";
5+
import {
6+
baselineTsserverLogs,
7+
createLoggerWithInMemoryLogs,
8+
createSession,
9+
verifyGetErrRequest,
10+
} from "./helpers";
11+
describe("unittests:: tsserver:: inconsistentErrorInEditor", () => {
12+
it("should not error", () => {
13+
const host = createServerHost([]);
14+
const session = createSession(host, { canUseEvents: true, noGetErrOnBackgroundUpdate: true, logger: createLoggerWithInMemoryLogs(host) });
15+
session.executeCommandSeq<ts.server.protocol.UpdateOpenRequest>({
16+
command: ts.server.protocol.CommandTypes.UpdateOpen,
17+
arguments: {
18+
changedFiles: [],
19+
closedFiles: [],
20+
openFiles: [
21+
{
22+
file: "^/untitled/ts-nul-authority/Untitled-1",
23+
fileContent: "export function foo<U>() {\r\n /*$*/return bar<U>;\r\n}\r\n\r\nexport function bar<T>(x: T) {\r\n return x;\r\n}\r\n\r\nlet x = foo()(42);",
24+
scriptKindName: "TS"
25+
}
26+
]
27+
}
28+
});
29+
session.executeCommandSeq<ts.server.protocol.EncodedSemanticClassificationsRequest>({
30+
command: ts.server.protocol.CommandTypes.EncodedSemanticClassificationsFull,
31+
arguments: {
32+
file: "^/untitled/ts-nul-authority/Untitled-1",
33+
start: 0,
34+
length: 128,
35+
format: "2020"
36+
}
37+
});
38+
verifyGetErrRequest({ session, host, files: ["^/untitled/ts-nul-authority/Untitled-1"] });
39+
baselineTsserverLogs("inconsistentErrorInEditor", "should not error", session);
40+
});
41+
});

tests/baselines/reference/classExtendingClassLikeType.symbols

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ interface Base<T, U> {
1616
// Error, no Base constructor function
1717
class D0 extends Base<string, string> {
1818
>D0 : Symbol(D0, Decl(classExtendingClassLikeType.ts, 3, 1))
19-
>Base : Symbol(Base, Decl(classExtendingClassLikeType.ts, 0, 0))
2019
}
2120

2221
interface BaseConstructor {

tests/baselines/reference/classExtendsEveryObjectType.symbols

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ interface I {
77
}
88
class C extends I { } // error
99
>C : Symbol(C, Decl(classExtendsEveryObjectType.ts, 2, 1))
10-
>I : Symbol(I, Decl(classExtendsEveryObjectType.ts, 0, 0))
1110

1211
class C2 extends { foo: string; } { } // error
1312
>C2 : Symbol(C2, Decl(classExtendsEveryObjectType.ts, 3, 21))

tests/baselines/reference/classExtendsInterface.symbols

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ interface Comparable {}
44

55
class A extends Comparable {}
66
>A : Symbol(A, Decl(classExtendsInterface.ts, 0, 23))
7-
>Comparable : Symbol(Comparable, Decl(classExtendsInterface.ts, 0, 0))
87

98
class B implements Comparable {}
109
>B : Symbol(B, Decl(classExtendsInterface.ts, 1, 29))
@@ -17,7 +16,6 @@ interface Comparable2<T> {}
1716
class A2<T> extends Comparable2<T> {}
1817
>A2 : Symbol(A2, Decl(classExtendsInterface.ts, 4, 27))
1918
>T : Symbol(T, Decl(classExtendsInterface.ts, 5, 9))
20-
>Comparable2 : Symbol(Comparable2, Decl(classExtendsInterface.ts, 2, 32))
2119
>T : Symbol(T, Decl(classExtendsInterface.ts, 5, 9))
2220

2321
class B2<T> implements Comparable2<T> {}

tests/baselines/reference/classExtendsInterfaceInModule.symbols

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,12 @@ module M {
1111
}
1212
class C1 extends M.I1 {}
1313
>C1 : Symbol(C1, Decl(classExtendsInterfaceInModule.ts, 3, 1))
14-
>M.I1 : Symbol(M.I1, Decl(classExtendsInterfaceInModule.ts, 0, 10))
1514
>M : Symbol(M, Decl(classExtendsInterfaceInModule.ts, 0, 0))
16-
>I1 : Symbol(M.I1, Decl(classExtendsInterfaceInModule.ts, 0, 10))
1715

1816
class C2<T> extends M.I2<T> {}
1917
>C2 : Symbol(C2, Decl(classExtendsInterfaceInModule.ts, 4, 24))
2018
>T : Symbol(T, Decl(classExtendsInterfaceInModule.ts, 5, 9))
21-
>M.I2 : Symbol(M.I2, Decl(classExtendsInterfaceInModule.ts, 1, 24))
2219
>M : Symbol(M, Decl(classExtendsInterfaceInModule.ts, 0, 0))
23-
>I2 : Symbol(M.I2, Decl(classExtendsInterfaceInModule.ts, 1, 24))
2420
>T : Symbol(T, Decl(classExtendsInterfaceInModule.ts, 5, 9))
2521

2622
module Mod {
@@ -36,9 +32,7 @@ module Mod {
3632

3733
class D extends Mod.Nested.I {}
3834
>D : Symbol(D, Decl(classExtendsInterfaceInModule.ts, 11, 1))
39-
>Mod.Nested.I : Symbol(Mod.Nested.I, Decl(classExtendsInterfaceInModule.ts, 8, 26))
4035
>Mod.Nested : Symbol(Mod.Nested, Decl(classExtendsInterfaceInModule.ts, 7, 12))
4136
>Mod : Symbol(Mod, Decl(classExtendsInterfaceInModule.ts, 5, 30))
4237
>Nested : Symbol(Mod.Nested, Decl(classExtendsInterfaceInModule.ts, 7, 12))
43-
>I : Symbol(Mod.Nested.I, Decl(classExtendsInterfaceInModule.ts, 8, 26))
4438

tests/baselines/reference/genericTypeReferenceWithoutTypeArgument2.symbols

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ var g = function f(x: I): I { var y: I; return y; }
6161

6262
class D extends I {
6363
>D : Symbol(D, Decl(genericTypeReferenceWithoutTypeArgument2.ts, 17, 51))
64-
>I : Symbol(I, Decl(genericTypeReferenceWithoutTypeArgument2.ts, 0, 0))
6564
}
6665

6766
interface U extends I {}
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
Info 0 [00:00:02.000] Provided types map file "/a/lib/typesMap.json" doesn't exist
2+
Info 1 [00:00:03.000] request:
3+
{
4+
"command": "updateOpen",
5+
"arguments": {
6+
"changedFiles": [],
7+
"closedFiles": [],
8+
"openFiles": [
9+
{
10+
"file": "^/untitled/ts-nul-authority/Untitled-1",
11+
"fileContent": "export function foo<U>() {\r\n /*$*/return bar<U>;\r\n}\r\n\r\nexport function bar<T>(x: T) {\r\n return x;\r\n}\r\n\r\nlet x = foo()(42);",
12+
"scriptKindName": "TS"
13+
}
14+
]
15+
},
16+
"seq": 1,
17+
"type": "request"
18+
}
19+
Before request
20+
21+
PolledWatches::
22+
23+
FsWatches::
24+
25+
FsWatchesRecursive::
26+
27+
Info 2 [00:00:04.000] Search path: ^/untitled/ts-nul-authority
28+
Info 3 [00:00:05.000] For info: ^/untitled/ts-nul-authority/Untitled-1 :: No config files found.
29+
Info 4 [00:00:06.000] Starting updateGraphWorker: Project: /dev/null/inferredProject1*
30+
Info 5 [00:00:07.000] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /dev/null/inferredProject1* WatchType: Missing file
31+
Info 6 [00:00:08.000] Finishing updateGraphWorker: Project: /dev/null/inferredProject1* Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms
32+
Info 7 [00:00:09.000] Project '/dev/null/inferredProject1*' (Inferred)
33+
Info 8 [00:00:10.000] Files (1)
34+
^/untitled/ts-nul-authority/Untitled-1
35+
36+
37+
^/untitled/ts-nul-authority/Untitled-1
38+
Root file specified for compilation
39+
40+
Info 9 [00:00:11.000] -----------------------------------------------
41+
Info 10 [00:00:12.000] Project '/dev/null/inferredProject1*' (Inferred)
42+
Info 10 [00:00:13.000] Files (1)
43+
44+
Info 10 [00:00:14.000] -----------------------------------------------
45+
Info 10 [00:00:15.000] Open files:
46+
Info 10 [00:00:16.000] FileName: ^/untitled/ts-nul-authority/Untitled-1 ProjectRootPath: undefined
47+
Info 10 [00:00:17.000] Projects: /dev/null/inferredProject1*
48+
After request
49+
50+
PolledWatches::
51+
/a/lib/lib.d.ts:
52+
{"pollingInterval":500}
53+
54+
FsWatches::
55+
56+
FsWatchesRecursive::
57+
58+
Info 10 [00:00:18.000] response:
59+
{
60+
"response": true,
61+
"responseRequired": true
62+
}
63+
Info 11 [00:00:19.000] request:
64+
{
65+
"command": "encodedSemanticClassifications-full",
66+
"arguments": {
67+
"file": "^/untitled/ts-nul-authority/Untitled-1",
68+
"start": 0,
69+
"length": 128,
70+
"format": "2020"
71+
},
72+
"seq": 2,
73+
"type": "request"
74+
}
75+
Before request
76+
77+
PolledWatches::
78+
/a/lib/lib.d.ts:
79+
{"pollingInterval":500}
80+
81+
FsWatches::
82+
83+
FsWatchesRecursive::
84+
85+
After request
86+
87+
PolledWatches::
88+
/a/lib/lib.d.ts:
89+
{"pollingInterval":500}
90+
91+
FsWatches::
92+
93+
FsWatchesRecursive::
94+
95+
Info 12 [00:00:20.000] response:
96+
{
97+
"response": {
98+
"spans": [
99+
16,
100+
3,
101+
2817,
102+
20,
103+
1,
104+
1281,
105+
44,
106+
3,
107+
2816,
108+
48,
109+
1,
110+
1280,
111+
74,
112+
3,
113+
2817,
114+
78,
115+
1,
116+
1281,
117+
81,
118+
1,
119+
1793,
120+
84,
121+
1,
122+
1280,
123+
101,
124+
1,
125+
1792,
126+
114,
127+
1,
128+
2049,
129+
118,
130+
3,
131+
2816
132+
],
133+
"endOfLineState": 0
134+
},
135+
"responseRequired": true
136+
}
137+
Info 13 [00:00:21.000] request:
138+
{
139+
"command": "geterr",
140+
"arguments": {
141+
"delay": 0,
142+
"files": [
143+
"^/untitled/ts-nul-authority/Untitled-1"
144+
]
145+
},
146+
"seq": 3,
147+
"type": "request"
148+
}
149+
Before request
150+
151+
PolledWatches::
152+
/a/lib/lib.d.ts:
153+
{"pollingInterval":500}
154+
155+
FsWatches::
156+
157+
FsWatchesRecursive::
158+
159+
After request
160+
161+
PolledWatches::
162+
/a/lib/lib.d.ts:
163+
{"pollingInterval":500}
164+
165+
FsWatches::
166+
167+
FsWatchesRecursive::
168+
169+
Info 14 [00:00:22.000] response:
170+
{
171+
"responseRequired": false
172+
}
173+
Before checking timeout queue length (1) and running
174+
175+
PolledWatches::
176+
/a/lib/lib.d.ts:
177+
{"pollingInterval":500}
178+
179+
FsWatches::
180+
181+
FsWatchesRecursive::
182+
183+
Info 15 [00:00:23.000] event:
184+
{"seq":0,"type":"event","event":"syntaxDiag","body":{"file":"^/untitled/ts-nul-authority/Untitled-1","diagnostics":[]}}
185+
After checking timeout queue length (1) and running
186+
187+
PolledWatches::
188+
/a/lib/lib.d.ts:
189+
{"pollingInterval":500}
190+
191+
FsWatches::
192+
193+
FsWatchesRecursive::
194+
195+
Before running immediate callbacks and checking length (1)
196+
197+
PolledWatches::
198+
/a/lib/lib.d.ts:
199+
{"pollingInterval":500}
200+
201+
FsWatches::
202+
203+
FsWatchesRecursive::
204+
205+
Info 16 [00:00:24.000] event:
206+
{"seq":0,"type":"event","event":"semanticDiag","body":{"file":"^/untitled/ts-nul-authority/Untitled-1","diagnostics":[]}}
207+
Before running immediate callbacks and checking length (1)
208+
209+
PolledWatches::
210+
/a/lib/lib.d.ts:
211+
{"pollingInterval":500}
212+
213+
FsWatches::
214+
215+
FsWatchesRecursive::
216+
217+
Before running immediate callbacks and checking length (1)
218+
219+
PolledWatches::
220+
/a/lib/lib.d.ts:
221+
{"pollingInterval":500}
222+
223+
FsWatches::
224+
225+
FsWatchesRecursive::
226+
227+
Info 17 [00:00:25.000] event:
228+
{"seq":0,"type":"event","event":"suggestionDiag","body":{"file":"^/untitled/ts-nul-authority/Untitled-1","diagnostics":[{"start":{"line":9,"offset":5},"end":{"line":9,"offset":6},"text":"'x' is declared but its value is never read.","code":6133,"category":"suggestion","reportsUnnecessary":true}]}}
229+
Info 18 [00:00:26.000] event:
230+
{"seq":0,"type":"event","event":"requestCompleted","body":{"request_seq":3}}
231+
Before running immediate callbacks and checking length (1)
232+
233+
PolledWatches::
234+
/a/lib/lib.d.ts:
235+
{"pollingInterval":500}
236+
237+
FsWatches::
238+
239+
FsWatchesRecursive::

0 commit comments

Comments
 (0)