typescript 7.0.1-rc → 7.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.txt +1 -1
- package/README.md +39 -14
- package/dist/api/async/api.d.ts +274 -45
- package/dist/api/async/api.d.ts.map +1 -1
- package/dist/api/async/api.js +722 -137
- package/dist/api/async/api.js.map +1 -1
- package/dist/api/async/client.d.ts +17 -0
- package/dist/api/async/client.d.ts.map +1 -1
- package/dist/api/async/client.js +72 -1
- package/dist/api/async/client.js.map +1 -1
- package/dist/api/async/types.d.ts +108 -27
- package/dist/api/async/types.d.ts.map +1 -1
- package/dist/api/compilerOptions.d.ts +109 -0
- package/dist/api/compilerOptions.d.ts.map +1 -0
- package/dist/api/compilerOptions.js +2 -0
- package/dist/api/compilerOptions.js.map +1 -0
- package/dist/api/node/encoder.d.ts.map +1 -1
- package/dist/api/node/encoder.js +1 -18
- package/dist/api/node/encoder.js.map +1 -1
- package/dist/api/node/msgpack.d.ts.map +1 -1
- package/dist/api/node/msgpack.js +2 -1
- package/dist/api/node/msgpack.js.map +1 -1
- package/dist/api/node/node.d.ts +17 -3
- package/dist/api/node/node.d.ts.map +1 -1
- package/dist/api/node/node.generated.d.ts +11 -0
- package/dist/api/node/node.generated.d.ts.map +1 -1
- package/dist/api/node/node.generated.js +69 -48
- package/dist/api/node/node.generated.js.map +1 -1
- package/dist/api/node/node.infrastructure.d.ts +11 -0
- package/dist/api/node/node.infrastructure.d.ts.map +1 -1
- package/dist/api/node/node.infrastructure.js.map +1 -1
- package/dist/api/node/node.js +93 -9
- package/dist/api/node/node.js.map +1 -1
- package/dist/api/node/wtf8.d.ts +6 -0
- package/dist/api/node/wtf8.d.ts.map +1 -0
- package/dist/api/node/wtf8.js +61 -0
- package/dist/api/node/wtf8.js.map +1 -0
- package/dist/api/options.d.ts +8 -0
- package/dist/api/options.d.ts.map +1 -1
- package/dist/api/options.js.map +1 -1
- package/dist/api/proto.d.ts +58 -5
- package/dist/api/proto.d.ts.map +1 -1
- package/dist/api/proto.js +15 -0
- package/dist/api/proto.js.map +1 -1
- package/dist/api/sync/api.d.ts +274 -45
- package/dist/api/sync/api.d.ts.map +1 -1
- package/dist/api/sync/api.js +720 -135
- package/dist/api/sync/api.js.map +1 -1
- package/dist/api/sync/client.d.ts +17 -0
- package/dist/api/sync/client.d.ts.map +1 -1
- package/dist/api/sync/client.js +53 -1
- package/dist/api/sync/client.js.map +1 -1
- package/dist/api/sync/types.d.ts +108 -27
- package/dist/api/sync/types.d.ts.map +1 -1
- package/dist/api/syncChannel.d.ts +4 -1
- package/dist/api/syncChannel.d.ts.map +1 -1
- package/dist/api/syncChannel.js +21 -1
- package/dist/api/syncChannel.js.map +1 -1
- package/dist/api/timing.d.ts +175 -0
- package/dist/api/timing.d.ts.map +1 -0
- package/dist/api/timing.js +149 -0
- package/dist/api/timing.js.map +1 -0
- package/dist/ast/ast.d.ts +36 -2
- package/dist/ast/ast.d.ts.map +1 -1
- package/dist/ast/ast.generated.d.ts +3 -3
- package/dist/ast/ast.generated.d.ts.map +1 -1
- package/dist/ast/ast.js.map +1 -1
- package/dist/ast/factory.generated.d.ts +12 -4
- package/dist/ast/factory.generated.d.ts.map +1 -1
- package/dist/ast/factory.generated.js +36 -2
- package/dist/ast/factory.generated.js.map +1 -1
- package/dist/ast/index.d.ts +2 -0
- package/dist/ast/index.d.ts.map +1 -1
- package/dist/ast/index.js +2 -0
- package/dist/ast/index.js.map +1 -1
- package/dist/ast/is.d.ts +2 -1
- package/dist/ast/is.d.ts.map +1 -1
- package/dist/ast/is.generated.d.ts +2 -2
- package/dist/ast/is.generated.d.ts.map +1 -1
- package/dist/ast/is.generated.js +3 -4
- package/dist/ast/is.generated.js.map +1 -1
- package/dist/ast/is.js +8 -1
- package/dist/ast/is.js.map +1 -1
- package/dist/ast/jsdoc.d.ts +11 -0
- package/dist/ast/jsdoc.d.ts.map +1 -0
- package/dist/ast/jsdoc.js +202 -0
- package/dist/ast/jsdoc.js.map +1 -0
- package/dist/ast/utils.d.ts +12 -0
- package/dist/ast/utils.d.ts.map +1 -1
- package/dist/ast/utils.js +40 -0
- package/dist/ast/utils.js.map +1 -1
- package/dist/enums/internalSymbolName.d.ts +2 -0
- package/dist/enums/internalSymbolName.d.ts.map +1 -0
- package/dist/enums/internalSymbolName.enum.d.ts +23 -0
- package/dist/enums/internalSymbolName.enum.d.ts.map +1 -0
- package/dist/enums/internalSymbolName.enum.js +25 -0
- package/dist/enums/internalSymbolName.enum.js.map +1 -0
- package/dist/enums/internalSymbolName.js +25 -0
- package/dist/enums/internalSymbolName.js.map +1 -0
- package/dist/enums/jsxEmit.d.ts +2 -0
- package/dist/enums/jsxEmit.d.ts.map +1 -0
- package/dist/enums/jsxEmit.enum.d.ts +9 -0
- package/dist/enums/jsxEmit.enum.d.ts.map +1 -0
- package/dist/enums/jsxEmit.enum.js +11 -0
- package/dist/enums/jsxEmit.enum.js.map +1 -0
- package/dist/enums/jsxEmit.js +11 -0
- package/dist/enums/jsxEmit.js.map +1 -0
- package/dist/enums/moduleDetectionKind.d.ts +2 -0
- package/dist/enums/moduleDetectionKind.d.ts.map +1 -0
- package/dist/enums/moduleDetectionKind.enum.d.ts +7 -0
- package/dist/enums/moduleDetectionKind.enum.d.ts.map +1 -0
- package/dist/enums/moduleDetectionKind.enum.js +9 -0
- package/dist/enums/moduleDetectionKind.enum.js.map +1 -0
- package/dist/enums/moduleDetectionKind.js +9 -0
- package/dist/enums/moduleDetectionKind.js.map +1 -0
- package/dist/enums/moduleKind.d.ts +2 -0
- package/dist/enums/moduleKind.d.ts.map +1 -0
- package/dist/enums/moduleKind.enum.d.ts +17 -0
- package/dist/enums/moduleKind.enum.d.ts.map +1 -0
- package/dist/enums/moduleKind.enum.js +19 -0
- package/dist/enums/moduleKind.enum.js.map +1 -0
- package/dist/enums/moduleKind.js +19 -0
- package/dist/enums/moduleKind.js.map +1 -0
- package/dist/enums/moduleResolutionKind.d.ts +2 -0
- package/dist/enums/moduleResolutionKind.d.ts.map +1 -0
- package/dist/enums/moduleResolutionKind.enum.d.ts +9 -0
- package/dist/enums/moduleResolutionKind.enum.d.ts.map +1 -0
- package/dist/enums/moduleResolutionKind.enum.js +11 -0
- package/dist/enums/moduleResolutionKind.enum.js.map +1 -0
- package/dist/enums/moduleResolutionKind.js +11 -0
- package/dist/enums/moduleResolutionKind.js.map +1 -0
- package/dist/enums/newLineKind.d.ts +2 -0
- package/dist/enums/newLineKind.d.ts.map +1 -0
- package/dist/enums/newLineKind.enum.d.ts +6 -0
- package/dist/enums/newLineKind.enum.d.ts.map +1 -0
- package/dist/enums/newLineKind.enum.js +8 -0
- package/dist/enums/newLineKind.enum.js.map +1 -0
- package/dist/enums/newLineKind.js +8 -0
- package/dist/enums/newLineKind.js.map +1 -0
- package/dist/enums/outerExpressionKinds.enum.d.ts +5 -1
- package/dist/enums/outerExpressionKinds.enum.d.ts.map +1 -1
- package/dist/enums/outerExpressionKinds.enum.js +4 -0
- package/dist/enums/outerExpressionKinds.enum.js.map +1 -1
- package/dist/enums/outerExpressionKinds.js +4 -0
- package/dist/enums/outerExpressionKinds.js.map +1 -1
- package/dist/internal/utils.d.ts +23 -0
- package/dist/internal/utils.d.ts.map +1 -0
- package/dist/internal/utils.js +25 -0
- package/dist/internal/utils.js.map +1 -0
- package/lib/getExePath.js +6 -3
- package/lib/tsc.js +1 -1
- package/lib/version.cjs +3 -0
- package/lib/version.d.cts +2 -0
- package/package.json +31 -30
- package/dist/api/objectRegistry.d.ts +0 -40
- package/dist/api/objectRegistry.d.ts.map +0 -1
- package/dist/api/objectRegistry.js +0 -61
- package/dist/api/objectRegistry.js.map +0 -1
package/dist/api/async/api.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { CompletionItemKind } from "#enums/completionItemKind";
|
|
3
3
|
import { DiagnosticCategory } from "#enums/diagnosticCategory";
|
|
4
4
|
import { ElementFlags } from "#enums/elementFlags";
|
|
5
|
+
import { ModuleKind } from "#enums/moduleKind";
|
|
5
6
|
import { NodeBuilderFlags } from "#enums/nodeBuilderFlags";
|
|
6
7
|
import { ObjectFlags } from "#enums/objectFlags";
|
|
7
8
|
import { SignatureFlags } from "#enums/signatureFlags";
|
|
@@ -9,16 +10,16 @@ import { SignatureKind } from "#enums/signatureKind";
|
|
|
9
10
|
import { SymbolFlags } from "#enums/symbolFlags";
|
|
10
11
|
import { TypeFlags } from "#enums/typeFlags";
|
|
11
12
|
import { TypePredicateKind } from "#enums/typePredicateKind";
|
|
12
|
-
import { ModifierFlags, } from "../../ast/index.js";
|
|
13
|
+
import { ModifierFlags, unescapeLeadingUnderscores, } from "../../ast/index.js";
|
|
13
14
|
import { encodeNode, uint8ArrayToBase64, } from "../node/encoder.js";
|
|
14
15
|
import { decodeNode, getNodeId, parseNodeHandle, readParseOptionsKey, readSourceFileHash, RemoteSourceFile, } from "../node/node.js";
|
|
15
|
-
import {
|
|
16
|
+
import { Wtf8Decoder } from "../node/wtf8.js";
|
|
16
17
|
import { createGetCanonicalFileName, toPath, } from "../path.js";
|
|
17
|
-
import { resolveFileName } from "../proto.js";
|
|
18
|
+
import { resolveFileName, toUpdateSnapshotRequest, } from "../proto.js";
|
|
18
19
|
import { SourceFileCache } from "../sourceFileCache.js";
|
|
19
20
|
import { Client, } from "./client.js";
|
|
20
|
-
export { CompletionItemKind, DiagnosticCategory, ElementFlags, ModifierFlags, NodeBuilderFlags, ObjectFlags, SignatureFlags, SignatureKind, SymbolFlags, TypeFlags, TypePredicateKind };
|
|
21
21
|
export { documentURIToFileName, fileNameToDocumentURI } from "../path.js";
|
|
22
|
+
export { CompletionItemKind, DiagnosticCategory, ElementFlags, ModifierFlags, ModuleKind, NodeBuilderFlags, ObjectFlags, SignatureFlags, SignatureKind, SymbolFlags, TypeFlags, TypePredicateKind };
|
|
22
23
|
export class API {
|
|
23
24
|
client;
|
|
24
25
|
sourceFileCache;
|
|
@@ -27,7 +28,7 @@ export class API {
|
|
|
27
28
|
activeSnapshots = new Set();
|
|
28
29
|
latestSnapshot;
|
|
29
30
|
internal;
|
|
30
|
-
constructor(options) {
|
|
31
|
+
constructor(options = {}) {
|
|
31
32
|
this.client = new Client(options);
|
|
32
33
|
this.sourceFileCache = new SourceFileCache();
|
|
33
34
|
this.internal = new InternalAPI(this.client, () => this.ensureInitialized());
|
|
@@ -56,10 +57,7 @@ export class API {
|
|
|
56
57
|
}
|
|
57
58
|
async updateSnapshot(params) {
|
|
58
59
|
await this.ensureInitialized();
|
|
59
|
-
const requestParams = params
|
|
60
|
-
if (requestParams.openProject) {
|
|
61
|
-
requestParams.openProject = resolveFileName(requestParams.openProject);
|
|
62
|
-
}
|
|
60
|
+
const requestParams = toUpdateSnapshotRequest(params);
|
|
63
61
|
const data = await this.client.apiRequest("updateSnapshot", requestParams);
|
|
64
62
|
// Retain cached source files from previous snapshot for unchanged files
|
|
65
63
|
if (this.latestSnapshot) {
|
|
@@ -94,6 +92,24 @@ export class API {
|
|
|
94
92
|
clearSourceFileCache() {
|
|
95
93
|
this.sourceFileCache.clear();
|
|
96
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Returns a snapshot of collected timing information for requests made
|
|
97
|
+
* through this API instance: client-measured round-trip latency and bytes
|
|
98
|
+
* transferred, folded together with the server's own per-request processing
|
|
99
|
+
* time and an estimated transport overhead (round-trip minus server time).
|
|
100
|
+
*
|
|
101
|
+
* Fetching the snapshot issues a lightweight request to the server to
|
|
102
|
+
* retrieve its timing collection. Collection must be enabled via the
|
|
103
|
+
* `collectTiming` option; when it is not, the returned snapshot has
|
|
104
|
+
* `enabled: false` and zeroed totals.
|
|
105
|
+
*/
|
|
106
|
+
getTimingInfo() {
|
|
107
|
+
return this.client.getTimingInfo();
|
|
108
|
+
}
|
|
109
|
+
/** Clears all accumulated timing totals and recent-request history, on both the client and the server. */
|
|
110
|
+
resetTimingInfo() {
|
|
111
|
+
return this.client.resetTimingInfo();
|
|
112
|
+
}
|
|
97
113
|
}
|
|
98
114
|
export class InternalAPI {
|
|
99
115
|
client;
|
|
@@ -123,23 +139,18 @@ export class Snapshot {
|
|
|
123
139
|
projectMap;
|
|
124
140
|
toPath;
|
|
125
141
|
client;
|
|
126
|
-
objectRegistry;
|
|
127
142
|
disposed = false;
|
|
128
143
|
onDispose;
|
|
144
|
+
snapshotRegistry;
|
|
129
145
|
constructor(data, client, sourceFileCache, toPath, onDispose) {
|
|
130
146
|
this.id = data.snapshot;
|
|
131
147
|
this.client = client;
|
|
132
148
|
this.toPath = toPath;
|
|
133
149
|
this.onDispose = onDispose;
|
|
134
|
-
this.objectRegistry = new SnapshotObjectRegistry({
|
|
135
|
-
createSymbol: symbolData => new Symbol(symbolData, this.objectRegistry),
|
|
136
|
-
createType: typeData => new TypeObject(typeData, this.objectRegistry),
|
|
137
|
-
createSignature: sigData => new Signature(sigData, this.objectRegistry),
|
|
138
|
-
}, client, this.id);
|
|
139
|
-
// Create projects
|
|
140
150
|
this.projectMap = new Map();
|
|
151
|
+
this.snapshotRegistry = new SnapshotObjectRegistry(client, this.id, projectId => this.projectMap.get(projectId));
|
|
141
152
|
for (const projData of data.projects) {
|
|
142
|
-
const project = new Project(projData, this.id, client,
|
|
153
|
+
const project = new Project(projData, this.id, client, sourceFileCache, toPath, this.snapshotRegistry);
|
|
143
154
|
this.projectMap.set(toPath(projData.configFileName), project);
|
|
144
155
|
}
|
|
145
156
|
}
|
|
@@ -168,7 +179,11 @@ export class Snapshot {
|
|
|
168
179
|
if (this.disposed)
|
|
169
180
|
return;
|
|
170
181
|
this.disposed = true;
|
|
171
|
-
this.
|
|
182
|
+
for (const project of this.projectMap.values()) {
|
|
183
|
+
project.dispose();
|
|
184
|
+
}
|
|
185
|
+
this.projectMap.clear();
|
|
186
|
+
this.snapshotRegistry.clear();
|
|
172
187
|
this.onDispose();
|
|
173
188
|
await this.client.apiRequest("release", { snapshot: this.id });
|
|
174
189
|
}
|
|
@@ -181,41 +196,139 @@ export class Snapshot {
|
|
|
181
196
|
}
|
|
182
197
|
}
|
|
183
198
|
}
|
|
184
|
-
class SnapshotObjectRegistry
|
|
199
|
+
class SnapshotObjectRegistry {
|
|
200
|
+
symbols = new Map();
|
|
185
201
|
client;
|
|
186
202
|
snapshotId;
|
|
187
|
-
|
|
188
|
-
|
|
203
|
+
resolveProject;
|
|
204
|
+
constructor(client, snapshotId, resolveProject) {
|
|
189
205
|
this.client = client;
|
|
190
206
|
this.snapshotId = snapshotId;
|
|
207
|
+
this.resolveProject = resolveProject;
|
|
191
208
|
}
|
|
192
|
-
|
|
209
|
+
/** Resolve a project id (a config file path) to its Project within this snapshot. */
|
|
210
|
+
getProject(projectId) {
|
|
211
|
+
return this.resolveProject(projectId);
|
|
212
|
+
}
|
|
213
|
+
getOrCreateSymbol(data) {
|
|
214
|
+
let symbol = this.symbols.get(data.id);
|
|
215
|
+
if (!symbol) {
|
|
216
|
+
symbol = new Symbol(data, this);
|
|
217
|
+
this.symbols.set(data.id, symbol);
|
|
218
|
+
}
|
|
219
|
+
return symbol;
|
|
220
|
+
}
|
|
221
|
+
getSymbol(id) {
|
|
222
|
+
return this.symbols.get(id);
|
|
223
|
+
}
|
|
224
|
+
clear() {
|
|
225
|
+
this.symbols.clear();
|
|
226
|
+
}
|
|
227
|
+
async fetchSymbol(source, method, handle, projectId) {
|
|
193
228
|
if (!handle)
|
|
194
229
|
return undefined;
|
|
195
|
-
const cached = this.
|
|
230
|
+
const cached = this.getSymbol(handle);
|
|
196
231
|
if (cached)
|
|
197
232
|
return cached;
|
|
198
233
|
const data = await this.client.apiRequest(method, {
|
|
199
234
|
snapshot: this.snapshotId,
|
|
235
|
+
project: projectId,
|
|
200
236
|
objectId: source.id,
|
|
201
237
|
});
|
|
202
238
|
if (!data)
|
|
203
|
-
throw new Error(`${method} returned null
|
|
204
|
-
return this.
|
|
239
|
+
throw new Error(`${method} returned null symbol for ${source.constructor.name} ${source.id}`);
|
|
240
|
+
return this.getOrCreateSymbol(data);
|
|
205
241
|
}
|
|
206
|
-
async
|
|
207
|
-
if (
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
242
|
+
async fetchSymbols(source, method, handles, projectId) {
|
|
243
|
+
if (handles) {
|
|
244
|
+
const result = new Array(handles.length);
|
|
245
|
+
let allCached = true;
|
|
246
|
+
for (let i = 0; i < handles.length; i++) {
|
|
247
|
+
const cached = this.getSymbol(handles[i]);
|
|
248
|
+
if (!cached) {
|
|
249
|
+
allCached = false;
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
result[i] = cached;
|
|
253
|
+
}
|
|
254
|
+
if (allCached)
|
|
255
|
+
return result;
|
|
256
|
+
}
|
|
257
|
+
const symbolData = await this.client.apiRequest(method, {
|
|
258
|
+
snapshot: this.snapshotId,
|
|
259
|
+
project: projectId,
|
|
260
|
+
objectId: source.id,
|
|
261
|
+
});
|
|
262
|
+
if (symbolData == null)
|
|
263
|
+
return [];
|
|
264
|
+
else
|
|
265
|
+
return symbolData.map(data => this.getOrCreateSymbol(data));
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
class ProjectObjectRegistry {
|
|
269
|
+
client;
|
|
270
|
+
snapshotId;
|
|
271
|
+
project;
|
|
272
|
+
snapshotRegistry;
|
|
273
|
+
types = new Map();
|
|
274
|
+
signatures = new Map();
|
|
275
|
+
constructor(client, snapshotId, project, snapshotRegistry) {
|
|
276
|
+
this.client = client;
|
|
277
|
+
this.snapshotId = snapshotId;
|
|
278
|
+
this.project = project;
|
|
279
|
+
this.snapshotRegistry = snapshotRegistry;
|
|
280
|
+
}
|
|
281
|
+
getOrCreateSymbol(data) {
|
|
282
|
+
return this.snapshotRegistry.getOrCreateSymbol(data);
|
|
283
|
+
}
|
|
284
|
+
getSymbol(id) {
|
|
285
|
+
return this.snapshotRegistry.getSymbol(id);
|
|
286
|
+
}
|
|
287
|
+
getOrCreateType(data) {
|
|
288
|
+
let type = this.types.get(data.id);
|
|
289
|
+
if (!type) {
|
|
290
|
+
type = new TypeObject(data, this);
|
|
291
|
+
this.types.set(data.id, type);
|
|
292
|
+
}
|
|
293
|
+
return type;
|
|
294
|
+
}
|
|
295
|
+
getType(id) {
|
|
296
|
+
return this.types.get(id);
|
|
297
|
+
}
|
|
298
|
+
getOrCreateSignature(data) {
|
|
299
|
+
let sig = this.signatures.get(data.id);
|
|
300
|
+
if (!sig) {
|
|
301
|
+
sig = new Signature(data, this.project, this);
|
|
302
|
+
this.signatures.set(data.id, sig);
|
|
303
|
+
}
|
|
304
|
+
return sig;
|
|
305
|
+
}
|
|
306
|
+
getSignature(id) {
|
|
307
|
+
return this.signatures.get(id);
|
|
308
|
+
}
|
|
309
|
+
clear() {
|
|
310
|
+
this.types.clear();
|
|
311
|
+
this.signatures.clear();
|
|
312
|
+
}
|
|
313
|
+
async fetchType(source, method, handle) {
|
|
314
|
+
if (handle !== false) {
|
|
315
|
+
if (!handle)
|
|
316
|
+
return undefined;
|
|
317
|
+
const cached = this.getType(handle);
|
|
318
|
+
if (cached)
|
|
319
|
+
return cached;
|
|
320
|
+
}
|
|
212
321
|
const data = await this.client.apiRequest(method, {
|
|
213
322
|
snapshot: this.snapshotId,
|
|
323
|
+
project: this.project.id,
|
|
214
324
|
objectId: source.id,
|
|
215
325
|
});
|
|
216
326
|
if (!data)
|
|
217
|
-
throw new Error(`${method} returned null
|
|
218
|
-
return this.
|
|
327
|
+
throw new Error(`${method} returned null type for ${source.constructor.name} ${source.id}`);
|
|
328
|
+
return this.getOrCreateType(data);
|
|
329
|
+
}
|
|
330
|
+
async fetchSymbol(source, method, handle) {
|
|
331
|
+
return this.snapshotRegistry.fetchSymbol(source, method, handle, this.project.id);
|
|
219
332
|
}
|
|
220
333
|
async fetchSignature(source, method, handle) {
|
|
221
334
|
if (!handle)
|
|
@@ -225,6 +338,7 @@ class SnapshotObjectRegistry extends ObjectRegistry {
|
|
|
225
338
|
return cached;
|
|
226
339
|
const data = await this.client.apiRequest(method, {
|
|
227
340
|
snapshot: this.snapshotId,
|
|
341
|
+
project: this.project.id,
|
|
228
342
|
objectId: source.id,
|
|
229
343
|
});
|
|
230
344
|
if (!data)
|
|
@@ -248,6 +362,7 @@ class SnapshotObjectRegistry extends ObjectRegistry {
|
|
|
248
362
|
}
|
|
249
363
|
const typesData = await this.client.apiRequest(method, {
|
|
250
364
|
snapshot: this.snapshotId,
|
|
365
|
+
project: this.project.id,
|
|
251
366
|
objectId: source.id,
|
|
252
367
|
});
|
|
253
368
|
if (typesData == null)
|
|
@@ -256,28 +371,19 @@ class SnapshotObjectRegistry extends ObjectRegistry {
|
|
|
256
371
|
return typesData.map(data => this.getOrCreateType(data));
|
|
257
372
|
}
|
|
258
373
|
async fetchSymbols(source, method, handles) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
allCached = false;
|
|
266
|
-
break;
|
|
267
|
-
}
|
|
268
|
-
result[i] = cached;
|
|
269
|
-
}
|
|
270
|
-
if (allCached)
|
|
271
|
-
return result;
|
|
272
|
-
}
|
|
273
|
-
const symbolData = await this.client.apiRequest(method, {
|
|
374
|
+
return this.snapshotRegistry.fetchSymbols(source, method, handles, this.project.id);
|
|
375
|
+
}
|
|
376
|
+
// getBaseTypes is a checker-level endpoint keyed by `type` (not `objectId`),
|
|
377
|
+
// so it cannot go through fetchTypes. This helper reuses that server method.
|
|
378
|
+
async fetchBaseTypes(source) {
|
|
379
|
+
const typesData = await this.client.apiRequest("getBaseTypes", {
|
|
274
380
|
snapshot: this.snapshotId,
|
|
275
|
-
|
|
381
|
+
project: this.project.id,
|
|
382
|
+
type: source.id,
|
|
276
383
|
});
|
|
277
|
-
if (
|
|
384
|
+
if (typesData == null)
|
|
278
385
|
return [];
|
|
279
|
-
|
|
280
|
-
return symbolData.map(data => this.getOrCreateSymbol(data));
|
|
386
|
+
return typesData.map(data => this.getOrCreateType(data));
|
|
281
387
|
}
|
|
282
388
|
}
|
|
283
389
|
export class Project {
|
|
@@ -289,43 +395,51 @@ export class Project {
|
|
|
289
395
|
checker;
|
|
290
396
|
emitter;
|
|
291
397
|
client;
|
|
292
|
-
constructor(data, snapshotId, client,
|
|
398
|
+
constructor(data, snapshotId, client, sourceFileCache, toPath, snapshotRegistry) {
|
|
293
399
|
this.id = data.id;
|
|
294
400
|
this.configFileName = data.configFileName;
|
|
295
401
|
this.compilerOptions = data.compilerOptions;
|
|
296
402
|
this.rootFiles = data.rootFiles;
|
|
297
403
|
this.client = client;
|
|
298
|
-
this.program = new Program(snapshotId, this
|
|
299
|
-
|
|
404
|
+
this.program = new Program(snapshotId, this, client, sourceFileCache, toPath);
|
|
405
|
+
const objectRegistry = new ProjectObjectRegistry(client, snapshotId, this, snapshotRegistry);
|
|
406
|
+
this.checker = new Checker(snapshotId, this, client, objectRegistry);
|
|
300
407
|
this.emitter = new Emitter(client);
|
|
301
408
|
}
|
|
409
|
+
dispose() {
|
|
410
|
+
this.checker.dispose();
|
|
411
|
+
}
|
|
302
412
|
}
|
|
303
413
|
export class Program {
|
|
304
414
|
snapshotId;
|
|
305
|
-
|
|
415
|
+
project;
|
|
306
416
|
client;
|
|
307
417
|
sourceFileCache;
|
|
308
418
|
toPath;
|
|
309
|
-
decoder = new
|
|
310
|
-
|
|
419
|
+
decoder = new Wtf8Decoder();
|
|
420
|
+
sourceFileMetadataCache = new Map();
|
|
421
|
+
constructor(snapshotId, project, client, sourceFileCache, toPath) {
|
|
311
422
|
this.snapshotId = snapshotId;
|
|
312
|
-
this.
|
|
423
|
+
this.project = project;
|
|
313
424
|
this.client = client;
|
|
314
425
|
this.sourceFileCache = sourceFileCache;
|
|
315
426
|
this.toPath = toPath;
|
|
316
427
|
}
|
|
428
|
+
getCompilerOptions() {
|
|
429
|
+
return this.project.compilerOptions;
|
|
430
|
+
}
|
|
317
431
|
async getSourceFile(file) {
|
|
318
432
|
const fileName = resolveFileName(file);
|
|
319
433
|
const path = this.toPath(fileName);
|
|
320
434
|
// Check if we already have a retained cache entry for this (snapshot, project) pair
|
|
321
|
-
const retained = this.sourceFileCache.getRetained(path, this.snapshotId, this.
|
|
435
|
+
const retained = this.sourceFileCache.getRetained(path, this.snapshotId, this.project.id);
|
|
322
436
|
if (retained) {
|
|
323
437
|
return retained;
|
|
324
438
|
}
|
|
325
439
|
// Fetch from server
|
|
326
440
|
const binaryData = await this.client.apiRequestBinary("getSourceFile", {
|
|
327
441
|
snapshot: this.snapshotId,
|
|
328
|
-
project: this.
|
|
442
|
+
project: this.project.id,
|
|
329
443
|
file,
|
|
330
444
|
});
|
|
331
445
|
if (!binaryData) {
|
|
@@ -335,8 +449,63 @@ export class Program {
|
|
|
335
449
|
const contentHash = readSourceFileHash(view);
|
|
336
450
|
const parseOptionsKey = readParseOptionsKey(view);
|
|
337
451
|
// Create a new RemoteSourceFile and cache it (set returns existing if hash matches)
|
|
338
|
-
const sourceFile = new RemoteSourceFile(binaryData, this.decoder);
|
|
339
|
-
return this.sourceFileCache.set(path, sourceFile, parseOptionsKey, contentHash, this.snapshotId, this.
|
|
452
|
+
const sourceFile = new RemoteSourceFile(binaryData, this.decoder, this.client.getTimingCollector());
|
|
453
|
+
return this.sourceFileCache.set(path, sourceFile, parseOptionsKey, contentHash, this.snapshotId, this.project.id);
|
|
454
|
+
}
|
|
455
|
+
async getSourceFileNames() {
|
|
456
|
+
const data = await this.client.apiRequest("getSourceFileNames", {
|
|
457
|
+
snapshot: this.snapshotId,
|
|
458
|
+
project: this.project.id,
|
|
459
|
+
});
|
|
460
|
+
return data ?? [];
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Returns program-stored metadata for the given source file, or `undefined` if the file
|
|
464
|
+
* is not part of the program. Metadata is fetched lazily per file and cached on this
|
|
465
|
+
* `Program` instance.
|
|
466
|
+
*/
|
|
467
|
+
getSourceFileMetadata(fileName) {
|
|
468
|
+
return this.getSourceFileMetadataByPath(this.toPath(fileName));
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Returns program-stored metadata for the source file at the given path, or `undefined`
|
|
472
|
+
* if the file is not part of the program. Like {@link getSourceFileMetadata}, but skips
|
|
473
|
+
* the file name to path conversion. Metadata is fetched lazily per file and cached on
|
|
474
|
+
* this `Program` instance.
|
|
475
|
+
*/
|
|
476
|
+
getSourceFileMetadataByPath(path) {
|
|
477
|
+
let metadata = this.sourceFileMetadataCache.get(path);
|
|
478
|
+
if (metadata === undefined) {
|
|
479
|
+
metadata = this.fetchSourceFileMetadata(path);
|
|
480
|
+
this.sourceFileMetadataCache.set(path, metadata);
|
|
481
|
+
}
|
|
482
|
+
return metadata;
|
|
483
|
+
}
|
|
484
|
+
async fetchSourceFileMetadata(path) {
|
|
485
|
+
const data = await this.client.apiRequest("getSourceFileMetadata", {
|
|
486
|
+
snapshot: this.snapshotId,
|
|
487
|
+
project: this.project.id,
|
|
488
|
+
file: path,
|
|
489
|
+
});
|
|
490
|
+
return data ?? undefined;
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Returns whether the given source file was loaded as part of an external library
|
|
494
|
+
* (e.g. a dependency resolved from `node_modules`). The underlying program metadata is
|
|
495
|
+
* fetched lazily per file and cached on this `Program` instance.
|
|
496
|
+
*/
|
|
497
|
+
async isSourceFileFromExternalLibrary(file) {
|
|
498
|
+
const metadata = await this.getSourceFileMetadataByPath(file.path);
|
|
499
|
+
return metadata?.isFromExternalLibrary ?? false;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Returns whether the given source file is a default library file (e.g. `lib.d.ts`).
|
|
503
|
+
* The underlying program metadata is fetched lazily per file and cached on this
|
|
504
|
+
* `Program` instance.
|
|
505
|
+
*/
|
|
506
|
+
async isSourceFileDefaultLibrary(file) {
|
|
507
|
+
const metadata = await this.getSourceFileMetadataByPath(file.path);
|
|
508
|
+
return metadata?.isDefaultLibrary ?? false;
|
|
340
509
|
}
|
|
341
510
|
/**
|
|
342
511
|
* Get syntactic (parse) diagnostics for a specific file or all files.
|
|
@@ -345,7 +514,19 @@ export class Program {
|
|
|
345
514
|
async getSyntacticDiagnostics(file) {
|
|
346
515
|
const data = await this.client.apiRequest("getSyntacticDiagnostics", {
|
|
347
516
|
snapshot: this.snapshotId,
|
|
348
|
-
project: this.
|
|
517
|
+
project: this.project.id,
|
|
518
|
+
...(file !== undefined ? { file } : {}),
|
|
519
|
+
});
|
|
520
|
+
return data ?? [];
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Get binder diagnostics for a specific file or all files.
|
|
524
|
+
* @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.
|
|
525
|
+
*/
|
|
526
|
+
async getBindDiagnostics(file) {
|
|
527
|
+
const data = await this.client.apiRequest("getBindDiagnostics", {
|
|
528
|
+
snapshot: this.snapshotId,
|
|
529
|
+
project: this.project.id,
|
|
349
530
|
...(file !== undefined ? { file } : {}),
|
|
350
531
|
});
|
|
351
532
|
return data ?? [];
|
|
@@ -357,7 +538,7 @@ export class Program {
|
|
|
357
538
|
async getSemanticDiagnostics(file) {
|
|
358
539
|
const data = await this.client.apiRequest("getSemanticDiagnostics", {
|
|
359
540
|
snapshot: this.snapshotId,
|
|
360
|
-
project: this.
|
|
541
|
+
project: this.project.id,
|
|
361
542
|
...(file !== undefined ? { file } : {}),
|
|
362
543
|
});
|
|
363
544
|
return data ?? [];
|
|
@@ -369,7 +550,7 @@ export class Program {
|
|
|
369
550
|
async getSuggestionDiagnostics(file) {
|
|
370
551
|
const data = await this.client.apiRequest("getSuggestionDiagnostics", {
|
|
371
552
|
snapshot: this.snapshotId,
|
|
372
|
-
project: this.
|
|
553
|
+
project: this.project.id,
|
|
373
554
|
...(file !== undefined ? { file } : {}),
|
|
374
555
|
});
|
|
375
556
|
return data ?? [];
|
|
@@ -381,45 +562,69 @@ export class Program {
|
|
|
381
562
|
async getDeclarationDiagnostics(file) {
|
|
382
563
|
const data = await this.client.apiRequest("getDeclarationDiagnostics", {
|
|
383
564
|
snapshot: this.snapshotId,
|
|
384
|
-
project: this.
|
|
565
|
+
project: this.project.id,
|
|
385
566
|
...(file !== undefined ? { file } : {}),
|
|
386
567
|
});
|
|
387
568
|
return data ?? [];
|
|
388
569
|
}
|
|
570
|
+
/**
|
|
571
|
+
* Get program-wide diagnostics for the project, including compiler options diagnostics.
|
|
572
|
+
*/
|
|
573
|
+
async getProgramDiagnostics() {
|
|
574
|
+
const data = await this.client.apiRequest("getProgramDiagnostics", {
|
|
575
|
+
snapshot: this.snapshotId,
|
|
576
|
+
project: this.project.id,
|
|
577
|
+
});
|
|
578
|
+
return data ?? [];
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Get global (non-file-specific) semantic diagnostics for the project.
|
|
582
|
+
*/
|
|
583
|
+
async getGlobalDiagnostics() {
|
|
584
|
+
const data = await this.client.apiRequest("getGlobalDiagnostics", {
|
|
585
|
+
snapshot: this.snapshotId,
|
|
586
|
+
project: this.project.id,
|
|
587
|
+
});
|
|
588
|
+
return data ?? [];
|
|
589
|
+
}
|
|
389
590
|
/**
|
|
390
591
|
* Get config file parsing diagnostics for the project.
|
|
391
592
|
*/
|
|
392
593
|
async getConfigFileParsingDiagnostics() {
|
|
393
594
|
const data = await this.client.apiRequest("getConfigFileParsingDiagnostics", {
|
|
394
595
|
snapshot: this.snapshotId,
|
|
395
|
-
project: this.
|
|
596
|
+
project: this.project.id,
|
|
396
597
|
});
|
|
397
598
|
return data ?? [];
|
|
398
599
|
}
|
|
399
600
|
}
|
|
400
601
|
export class Checker {
|
|
401
602
|
snapshotId;
|
|
402
|
-
|
|
603
|
+
project;
|
|
403
604
|
client;
|
|
404
605
|
objectRegistry;
|
|
405
|
-
|
|
606
|
+
wellKnownSymbols;
|
|
607
|
+
constructor(snapshotId, project, client, objectRegistry) {
|
|
406
608
|
this.snapshotId = snapshotId;
|
|
407
|
-
this.
|
|
609
|
+
this.project = project;
|
|
408
610
|
this.client = client;
|
|
409
611
|
this.objectRegistry = objectRegistry;
|
|
410
612
|
}
|
|
613
|
+
dispose() {
|
|
614
|
+
this.objectRegistry.clear();
|
|
615
|
+
}
|
|
411
616
|
async getSymbolAtLocation(nodeOrNodes) {
|
|
412
617
|
if (Array.isArray(nodeOrNodes)) {
|
|
413
618
|
const data = await this.client.apiRequest("getSymbolsAtLocations", {
|
|
414
619
|
snapshot: this.snapshotId,
|
|
415
|
-
project: this.
|
|
620
|
+
project: this.project.id,
|
|
416
621
|
locations: nodeOrNodes.map(node => getNodeId(node)),
|
|
417
622
|
});
|
|
418
623
|
return data.map(d => d ? this.objectRegistry.getOrCreateSymbol(d) : undefined);
|
|
419
624
|
}
|
|
420
625
|
const data = await this.client.apiRequest("getSymbolAtLocation", {
|
|
421
626
|
snapshot: this.snapshotId,
|
|
422
|
-
project: this.
|
|
627
|
+
project: this.project.id,
|
|
423
628
|
location: getNodeId(nodeOrNodes),
|
|
424
629
|
});
|
|
425
630
|
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
@@ -428,7 +633,7 @@ export class Checker {
|
|
|
428
633
|
if (typeof positionOrPositions === "number") {
|
|
429
634
|
const data = await this.client.apiRequest("getSymbolAtPosition", {
|
|
430
635
|
snapshot: this.snapshotId,
|
|
431
|
-
project: this.
|
|
636
|
+
project: this.project.id,
|
|
432
637
|
file,
|
|
433
638
|
position: positionOrPositions,
|
|
434
639
|
});
|
|
@@ -436,7 +641,7 @@ export class Checker {
|
|
|
436
641
|
}
|
|
437
642
|
const data = await this.client.apiRequest("getSymbolsAtPositions", {
|
|
438
643
|
snapshot: this.snapshotId,
|
|
439
|
-
project: this.
|
|
644
|
+
project: this.project.id,
|
|
440
645
|
file,
|
|
441
646
|
positions: positionOrPositions,
|
|
442
647
|
});
|
|
@@ -446,63 +651,70 @@ export class Checker {
|
|
|
446
651
|
if (Array.isArray(symbolOrSymbols)) {
|
|
447
652
|
const data = await this.client.apiRequest("getTypesOfSymbols", {
|
|
448
653
|
snapshot: this.snapshotId,
|
|
449
|
-
project: this.
|
|
654
|
+
project: this.project.id,
|
|
450
655
|
symbols: symbolOrSymbols.map(s => s.id),
|
|
451
656
|
});
|
|
452
657
|
return data.map(d => d ? this.objectRegistry.getOrCreateType(d) : undefined);
|
|
453
658
|
}
|
|
454
659
|
const data = await this.client.apiRequest("getTypeOfSymbol", {
|
|
455
660
|
snapshot: this.snapshotId,
|
|
456
|
-
project: this.
|
|
661
|
+
project: this.project.id,
|
|
457
662
|
symbol: symbolOrSymbols.id,
|
|
458
663
|
});
|
|
459
664
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
460
665
|
}
|
|
666
|
+
/**
|
|
667
|
+
* Get the declared type of a symbol. Always returns a type; for symbols whose
|
|
668
|
+
* declared type cannot be determined the checker yields the error type (use
|
|
669
|
+
* {@link Type.isErrorType} to detect it).
|
|
670
|
+
*/
|
|
461
671
|
async getDeclaredTypeOfSymbol(symbol) {
|
|
462
672
|
const data = await this.client.apiRequest("getDeclaredTypeOfSymbol", {
|
|
463
673
|
snapshot: this.snapshotId,
|
|
464
|
-
project: this.
|
|
674
|
+
project: this.project.id,
|
|
465
675
|
symbol: symbol.id,
|
|
466
676
|
});
|
|
467
|
-
|
|
677
|
+
if (!data)
|
|
678
|
+
throw new Error(`getDeclaredTypeOfSymbol returned no type for symbol ${symbol.id}`);
|
|
679
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
468
680
|
}
|
|
469
681
|
async getReferencesToSymbolInFile(file, symbol) {
|
|
470
682
|
const data = await this.client.apiRequest("getReferencesToSymbolInFile", {
|
|
471
683
|
snapshot: this.snapshotId,
|
|
472
|
-
project: this.
|
|
684
|
+
project: this.project.id,
|
|
473
685
|
file,
|
|
474
686
|
symbol: symbol.id,
|
|
475
687
|
});
|
|
476
|
-
return (data ?? []).map(h => new NodeHandle(h));
|
|
688
|
+
return (data ?? []).map(h => new NodeHandle(h, this.project));
|
|
477
689
|
}
|
|
478
690
|
async getReferencedSymbolsForNode(node, position) {
|
|
479
691
|
const data = await this.client.apiRequest("getReferencedSymbolsForNode", {
|
|
480
692
|
snapshot: this.snapshotId,
|
|
481
|
-
project: this.
|
|
693
|
+
project: this.project.id,
|
|
482
694
|
node: getNodeId(node),
|
|
483
695
|
position,
|
|
484
696
|
});
|
|
485
697
|
return (data ?? []).map(entry => ({
|
|
486
|
-
definition: new NodeHandle(entry.definition),
|
|
698
|
+
definition: new NodeHandle(entry.definition, this.project),
|
|
487
699
|
symbol: entry.symbol ? this.objectRegistry.getOrCreateSymbol(entry.symbol) : undefined,
|
|
488
|
-
references: (entry.references ?? []).map(h => new NodeHandle(h)),
|
|
700
|
+
references: (entry.references ?? []).map(h => new NodeHandle(h, this.project)),
|
|
489
701
|
}));
|
|
490
702
|
}
|
|
491
703
|
async getSignatureUsage(signatureDecl) {
|
|
492
704
|
const data = await this.client.apiRequest("getSignatureUsages", {
|
|
493
705
|
snapshot: this.snapshotId,
|
|
494
|
-
project: this.
|
|
706
|
+
project: this.project.id,
|
|
495
707
|
signatureDecl: getNodeId(signatureDecl),
|
|
496
708
|
});
|
|
497
709
|
return (data ?? []).map(entry => ({
|
|
498
|
-
name: new NodeHandle(entry.name),
|
|
499
|
-
call: entry.call ? new NodeHandle(entry.call) : undefined,
|
|
710
|
+
name: new NodeHandle(entry.name, this.project),
|
|
711
|
+
call: entry.call ? new NodeHandle(entry.call, this.project) : undefined,
|
|
500
712
|
}));
|
|
501
713
|
}
|
|
502
714
|
async getCompletionsAtPosition(document, position, options) {
|
|
503
715
|
const data = await this.client.apiRequest("getCompletionsAtPosition", {
|
|
504
716
|
snapshot: this.snapshotId,
|
|
505
|
-
project: this.
|
|
717
|
+
project: this.project.id,
|
|
506
718
|
file: document,
|
|
507
719
|
position,
|
|
508
720
|
triggerCharacter: options?.triggerCharacter,
|
|
@@ -522,14 +734,14 @@ export class Checker {
|
|
|
522
734
|
if (Array.isArray(nodeOrNodes)) {
|
|
523
735
|
const data = await this.client.apiRequest("getTypeAtLocations", {
|
|
524
736
|
snapshot: this.snapshotId,
|
|
525
|
-
project: this.
|
|
737
|
+
project: this.project.id,
|
|
526
738
|
locations: nodeOrNodes.map(node => getNodeId(node)),
|
|
527
739
|
});
|
|
528
740
|
return data.map(d => d ? this.objectRegistry.getOrCreateType(d) : undefined);
|
|
529
741
|
}
|
|
530
742
|
const data = await this.client.apiRequest("getTypeAtLocation", {
|
|
531
743
|
snapshot: this.snapshotId,
|
|
532
|
-
project: this.
|
|
744
|
+
project: this.project.id,
|
|
533
745
|
location: getNodeId(nodeOrNodes),
|
|
534
746
|
});
|
|
535
747
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
@@ -537,7 +749,7 @@ export class Checker {
|
|
|
537
749
|
async getSignaturesOfType(type, kind) {
|
|
538
750
|
const data = await this.client.apiRequest("getSignaturesOfType", {
|
|
539
751
|
snapshot: this.snapshotId,
|
|
540
|
-
project: this.
|
|
752
|
+
project: this.project.id,
|
|
541
753
|
type: type.id,
|
|
542
754
|
kind,
|
|
543
755
|
});
|
|
@@ -546,7 +758,7 @@ export class Checker {
|
|
|
546
758
|
async getResolvedSignature(node) {
|
|
547
759
|
const data = await this.client.apiRequest("getResolvedSignature", {
|
|
548
760
|
snapshot: this.snapshotId,
|
|
549
|
-
project: this.
|
|
761
|
+
project: this.project.id,
|
|
550
762
|
location: getNodeId(node),
|
|
551
763
|
});
|
|
552
764
|
return data ? this.objectRegistry.getOrCreateSignature(data) : undefined;
|
|
@@ -555,7 +767,7 @@ export class Checker {
|
|
|
555
767
|
if (typeof positionOrPositions === "number") {
|
|
556
768
|
const data = await this.client.apiRequest("getTypeAtPosition", {
|
|
557
769
|
snapshot: this.snapshotId,
|
|
558
|
-
project: this.
|
|
770
|
+
project: this.project.id,
|
|
559
771
|
file,
|
|
560
772
|
position: positionOrPositions,
|
|
561
773
|
});
|
|
@@ -563,7 +775,7 @@ export class Checker {
|
|
|
563
775
|
}
|
|
564
776
|
const data = await this.client.apiRequest("getTypesAtPositions", {
|
|
565
777
|
snapshot: this.snapshotId,
|
|
566
|
-
project: this.
|
|
778
|
+
project: this.project.id,
|
|
567
779
|
file,
|
|
568
780
|
positions: positionOrPositions,
|
|
569
781
|
});
|
|
@@ -574,7 +786,7 @@ export class Checker {
|
|
|
574
786
|
const isNode = location && "kind" in location;
|
|
575
787
|
const data = await this.client.apiRequest("resolveName", {
|
|
576
788
|
snapshot: this.snapshotId,
|
|
577
|
-
project: this.
|
|
789
|
+
project: this.project.id,
|
|
578
790
|
name,
|
|
579
791
|
meaning,
|
|
580
792
|
location: isNode ? getNodeId(location) : undefined,
|
|
@@ -593,7 +805,7 @@ export class Checker {
|
|
|
593
805
|
async getContextualType(node) {
|
|
594
806
|
const data = await this.client.apiRequest("getContextualType", {
|
|
595
807
|
snapshot: this.snapshotId,
|
|
596
|
-
project: this.
|
|
808
|
+
project: this.project.id,
|
|
597
809
|
location: getNodeId(node),
|
|
598
810
|
});
|
|
599
811
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
@@ -601,7 +813,7 @@ export class Checker {
|
|
|
601
813
|
async getBaseTypeOfLiteralType(type) {
|
|
602
814
|
const data = await this.client.apiRequest("getBaseTypeOfLiteralType", {
|
|
603
815
|
snapshot: this.snapshotId,
|
|
604
|
-
project: this.
|
|
816
|
+
project: this.project.id,
|
|
605
817
|
type: type.id,
|
|
606
818
|
});
|
|
607
819
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
@@ -609,7 +821,7 @@ export class Checker {
|
|
|
609
821
|
async getNonNullableType(type) {
|
|
610
822
|
const data = await this.client.apiRequest("getNonNullableType", {
|
|
611
823
|
snapshot: this.snapshotId,
|
|
612
|
-
project: this.
|
|
824
|
+
project: this.project.id,
|
|
613
825
|
type: type.id,
|
|
614
826
|
});
|
|
615
827
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
@@ -617,7 +829,7 @@ export class Checker {
|
|
|
617
829
|
async getTypeFromTypeNode(node) {
|
|
618
830
|
const data = await this.client.apiRequest("getTypeFromTypeNode", {
|
|
619
831
|
snapshot: this.snapshotId,
|
|
620
|
-
project: this.
|
|
832
|
+
project: this.project.id,
|
|
621
833
|
location: getNodeId(node),
|
|
622
834
|
});
|
|
623
835
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
@@ -625,7 +837,7 @@ export class Checker {
|
|
|
625
837
|
async getWidenedType(type) {
|
|
626
838
|
const data = await this.client.apiRequest("getWidenedType", {
|
|
627
839
|
snapshot: this.snapshotId,
|
|
628
|
-
project: this.
|
|
840
|
+
project: this.project.id,
|
|
629
841
|
type: type.id,
|
|
630
842
|
});
|
|
631
843
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
@@ -633,7 +845,7 @@ export class Checker {
|
|
|
633
845
|
async getParameterType(signature, index) {
|
|
634
846
|
const data = await this.client.apiRequest("getParameterType", {
|
|
635
847
|
snapshot: this.snapshotId,
|
|
636
|
-
project: this.
|
|
848
|
+
project: this.project.id,
|
|
637
849
|
signature: signature.id,
|
|
638
850
|
index,
|
|
639
851
|
});
|
|
@@ -642,14 +854,14 @@ export class Checker {
|
|
|
642
854
|
async isArrayLikeType(type) {
|
|
643
855
|
return this.client.apiRequest("isArrayLikeType", {
|
|
644
856
|
snapshot: this.snapshotId,
|
|
645
|
-
project: this.
|
|
857
|
+
project: this.project.id,
|
|
646
858
|
type: type.id,
|
|
647
859
|
});
|
|
648
860
|
}
|
|
649
861
|
async isTypeAssignableTo(source, target) {
|
|
650
862
|
return this.client.apiRequest("isTypeAssignableTo", {
|
|
651
863
|
snapshot: this.snapshotId,
|
|
652
|
-
project: this.
|
|
864
|
+
project: this.project.id,
|
|
653
865
|
source: source.id,
|
|
654
866
|
target: target.id,
|
|
655
867
|
});
|
|
@@ -657,24 +869,31 @@ export class Checker {
|
|
|
657
869
|
async getShorthandAssignmentValueSymbol(node) {
|
|
658
870
|
const data = await this.client.apiRequest("getShorthandAssignmentValueSymbol", {
|
|
659
871
|
snapshot: this.snapshotId,
|
|
660
|
-
project: this.
|
|
872
|
+
project: this.project.id,
|
|
661
873
|
location: getNodeId(node),
|
|
662
874
|
});
|
|
663
875
|
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
664
876
|
}
|
|
877
|
+
/**
|
|
878
|
+
* Get the type of a symbol as narrowed at a specific location. Always returns
|
|
879
|
+
* a type; for symbols whose type cannot be determined the checker yields the
|
|
880
|
+
* error type (use {@link Type.isErrorType} to detect it).
|
|
881
|
+
*/
|
|
665
882
|
async getTypeOfSymbolAtLocation(symbol, location) {
|
|
666
883
|
const data = await this.client.apiRequest("getTypeOfSymbolAtLocation", {
|
|
667
884
|
snapshot: this.snapshotId,
|
|
668
|
-
project: this.
|
|
885
|
+
project: this.project.id,
|
|
669
886
|
symbol: symbol.id,
|
|
670
887
|
location: getNodeId(location),
|
|
671
888
|
});
|
|
672
|
-
|
|
889
|
+
if (!data)
|
|
890
|
+
throw new Error(`getTypeOfSymbolAtLocation returned no type for symbol ${symbol.id}`);
|
|
891
|
+
return this.objectRegistry.getOrCreateType(data);
|
|
673
892
|
}
|
|
674
893
|
async getIntrinsicType(method) {
|
|
675
894
|
const data = await this.client.apiRequest(method, {
|
|
676
895
|
snapshot: this.snapshotId,
|
|
677
|
-
project: this.
|
|
896
|
+
project: this.project.id,
|
|
678
897
|
});
|
|
679
898
|
return this.objectRegistry.getOrCreateType(data);
|
|
680
899
|
}
|
|
@@ -714,7 +933,7 @@ export class Checker {
|
|
|
714
933
|
async typeToTypeNode(type, enclosingDeclaration, flags) {
|
|
715
934
|
const binaryData = await this.client.apiRequestBinary("typeToTypeNode", {
|
|
716
935
|
snapshot: this.snapshotId,
|
|
717
|
-
project: this.
|
|
936
|
+
project: this.project.id,
|
|
718
937
|
type: type.id,
|
|
719
938
|
location: enclosingDeclaration ? getNodeId(enclosingDeclaration) : undefined,
|
|
720
939
|
flags,
|
|
@@ -726,7 +945,7 @@ export class Checker {
|
|
|
726
945
|
async signatureToSignatureDeclaration(signature, kind, enclosingDeclaration, flags) {
|
|
727
946
|
const binaryData = await this.client.apiRequestBinary("signatureToSignatureDeclaration", {
|
|
728
947
|
snapshot: this.snapshotId,
|
|
729
|
-
project: this.
|
|
948
|
+
project: this.project.id,
|
|
730
949
|
signature: signature.id,
|
|
731
950
|
kind,
|
|
732
951
|
location: enclosingDeclaration ? getNodeId(enclosingDeclaration) : undefined,
|
|
@@ -739,7 +958,7 @@ export class Checker {
|
|
|
739
958
|
async typeToString(type, enclosingDeclaration, flags) {
|
|
740
959
|
return this.client.apiRequest("typeToString", {
|
|
741
960
|
snapshot: this.snapshotId,
|
|
742
|
-
project: this.
|
|
961
|
+
project: this.project.id,
|
|
743
962
|
type: type.id,
|
|
744
963
|
location: enclosingDeclaration ? getNodeId(enclosingDeclaration) : undefined,
|
|
745
964
|
flags,
|
|
@@ -748,14 +967,28 @@ export class Checker {
|
|
|
748
967
|
async isContextSensitive(node) {
|
|
749
968
|
return this.client.apiRequest("isContextSensitive", {
|
|
750
969
|
snapshot: this.snapshotId,
|
|
751
|
-
project: this.
|
|
970
|
+
project: this.project.id,
|
|
752
971
|
location: getNodeId(node),
|
|
753
972
|
});
|
|
754
973
|
}
|
|
974
|
+
async isArrayType(type) {
|
|
975
|
+
return this.client.apiRequest("isArrayType", {
|
|
976
|
+
snapshot: this.snapshotId,
|
|
977
|
+
project: this.project.id,
|
|
978
|
+
type: type.id,
|
|
979
|
+
});
|
|
980
|
+
}
|
|
981
|
+
async isTupleType(type) {
|
|
982
|
+
return this.client.apiRequest("isTupleType", {
|
|
983
|
+
snapshot: this.snapshotId,
|
|
984
|
+
project: this.project.id,
|
|
985
|
+
type: type.id,
|
|
986
|
+
});
|
|
987
|
+
}
|
|
755
988
|
async getReturnTypeOfSignature(signature) {
|
|
756
989
|
const data = await this.client.apiRequest("getReturnTypeOfSignature", {
|
|
757
990
|
snapshot: this.snapshotId,
|
|
758
|
-
project: this.
|
|
991
|
+
project: this.project.id,
|
|
759
992
|
signature: signature.id,
|
|
760
993
|
});
|
|
761
994
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
@@ -763,7 +996,7 @@ export class Checker {
|
|
|
763
996
|
async getRestTypeOfSignature(signature) {
|
|
764
997
|
const data = await this.client.apiRequest("getRestTypeOfSignature", {
|
|
765
998
|
snapshot: this.snapshotId,
|
|
766
|
-
project: this.
|
|
999
|
+
project: this.project.id,
|
|
767
1000
|
signature: signature.id,
|
|
768
1001
|
});
|
|
769
1002
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
@@ -771,7 +1004,7 @@ export class Checker {
|
|
|
771
1004
|
async getTypePredicateOfSignature(signature) {
|
|
772
1005
|
const data = await this.client.apiRequest("getTypePredicateOfSignature", {
|
|
773
1006
|
snapshot: this.snapshotId,
|
|
774
|
-
project: this.
|
|
1007
|
+
project: this.project.id,
|
|
775
1008
|
signature: signature.id,
|
|
776
1009
|
});
|
|
777
1010
|
if (!data)
|
|
@@ -783,18 +1016,30 @@ export class Checker {
|
|
|
783
1016
|
type: data.type ? this.objectRegistry.getOrCreateType(data.type) : undefined,
|
|
784
1017
|
};
|
|
785
1018
|
}
|
|
1019
|
+
/**
|
|
1020
|
+
* Get the base types of a class or interface type. A type with no base types
|
|
1021
|
+
* yields an empty array.
|
|
1022
|
+
*/
|
|
786
1023
|
async getBaseTypes(type) {
|
|
787
1024
|
const data = await this.client.apiRequest("getBaseTypes", {
|
|
788
1025
|
snapshot: this.snapshotId,
|
|
789
|
-
project: this.
|
|
1026
|
+
project: this.project.id,
|
|
790
1027
|
type: type.id,
|
|
791
1028
|
});
|
|
792
1029
|
return data ? data.map(d => this.objectRegistry.getOrCreateType(d)) : [];
|
|
793
1030
|
}
|
|
1031
|
+
async getApparentType(type) {
|
|
1032
|
+
const data = await this.client.apiRequest("getApparentType", {
|
|
1033
|
+
snapshot: this.snapshotId,
|
|
1034
|
+
project: this.project.id,
|
|
1035
|
+
type: type.id,
|
|
1036
|
+
});
|
|
1037
|
+
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
1038
|
+
}
|
|
794
1039
|
async getPropertiesOfType(type) {
|
|
795
1040
|
const data = await this.client.apiRequest("getPropertiesOfType", {
|
|
796
1041
|
snapshot: this.snapshotId,
|
|
797
|
-
project: this.
|
|
1042
|
+
project: this.project.id,
|
|
798
1043
|
type: type.id,
|
|
799
1044
|
});
|
|
800
1045
|
return data ? data.map(d => this.objectRegistry.getOrCreateSymbol(d)) : [];
|
|
@@ -802,7 +1047,7 @@ export class Checker {
|
|
|
802
1047
|
async getIndexInfosOfType(type) {
|
|
803
1048
|
const data = await this.client.apiRequest("getIndexInfosOfType", {
|
|
804
1049
|
snapshot: this.snapshotId,
|
|
805
|
-
project: this.
|
|
1050
|
+
project: this.project.id,
|
|
806
1051
|
type: type.id,
|
|
807
1052
|
});
|
|
808
1053
|
if (!data)
|
|
@@ -811,21 +1056,155 @@ export class Checker {
|
|
|
811
1056
|
keyType: this.objectRegistry.getOrCreateType(d.keyType),
|
|
812
1057
|
valueType: this.objectRegistry.getOrCreateType(d.valueType),
|
|
813
1058
|
isReadonly: d.isReadonly ?? false,
|
|
814
|
-
declaration: d.declaration ? new NodeHandle(d.declaration) : undefined,
|
|
1059
|
+
declaration: d.declaration ? new NodeHandle(d.declaration, this.project) : undefined,
|
|
815
1060
|
}));
|
|
816
1061
|
}
|
|
1062
|
+
/**
|
|
1063
|
+
* Get the constraint of a type parameter (the `T` in `<U extends T>`), or
|
|
1064
|
+
* undefined if it has none.
|
|
1065
|
+
*/
|
|
817
1066
|
async getConstraintOfTypeParameter(type) {
|
|
818
1067
|
const data = await this.client.apiRequest("getConstraintOfTypeParameter", {
|
|
819
1068
|
snapshot: this.snapshotId,
|
|
820
|
-
project: this.
|
|
1069
|
+
project: this.project.id,
|
|
821
1070
|
type: type.id,
|
|
822
1071
|
});
|
|
823
1072
|
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
824
1073
|
}
|
|
1074
|
+
async getBaseConstraintOfType(type) {
|
|
1075
|
+
const data = await this.client.apiRequest("getBaseConstraintOfType", {
|
|
1076
|
+
snapshot: this.snapshotId,
|
|
1077
|
+
project: this.project.id,
|
|
1078
|
+
type: type.id,
|
|
1079
|
+
});
|
|
1080
|
+
return data ? this.objectRegistry.getOrCreateType(data) : undefined;
|
|
1081
|
+
}
|
|
1082
|
+
async getPropertyOfType(type, name) {
|
|
1083
|
+
const data = await this.client.apiRequest("getPropertyOfType", {
|
|
1084
|
+
snapshot: this.snapshotId,
|
|
1085
|
+
project: this.project.id,
|
|
1086
|
+
type: type.id,
|
|
1087
|
+
name,
|
|
1088
|
+
});
|
|
1089
|
+
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
1090
|
+
}
|
|
1091
|
+
async getConstantValue(node) {
|
|
1092
|
+
const data = await this.client.apiRequest("getConstantValue", {
|
|
1093
|
+
snapshot: this.snapshotId,
|
|
1094
|
+
project: this.project.id,
|
|
1095
|
+
location: getNodeId(node),
|
|
1096
|
+
});
|
|
1097
|
+
return data ?? undefined;
|
|
1098
|
+
}
|
|
1099
|
+
async getSignatureFromDeclaration(node) {
|
|
1100
|
+
const data = await this.client.apiRequest("getSignatureFromDeclaration", {
|
|
1101
|
+
snapshot: this.snapshotId,
|
|
1102
|
+
project: this.project.id,
|
|
1103
|
+
location: getNodeId(node),
|
|
1104
|
+
});
|
|
1105
|
+
return data ? this.objectRegistry.getOrCreateSignature(data) : undefined;
|
|
1106
|
+
}
|
|
1107
|
+
async getExportSpecifierLocalTargetSymbol(node) {
|
|
1108
|
+
const data = await this.client.apiRequest("getExportSpecifierLocalTargetSymbol", {
|
|
1109
|
+
snapshot: this.snapshotId,
|
|
1110
|
+
project: this.project.id,
|
|
1111
|
+
location: getNodeId(node),
|
|
1112
|
+
});
|
|
1113
|
+
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
1114
|
+
}
|
|
1115
|
+
/**
|
|
1116
|
+
* Follow all aliases to get the original symbol. Always returns a symbol; for
|
|
1117
|
+
* an unresolved alias the checker yields the unknown symbol (use
|
|
1118
|
+
* {@link Checker.isUnknownSymbol} to detect it).
|
|
1119
|
+
*/
|
|
1120
|
+
async getAliasedSymbol(symbol) {
|
|
1121
|
+
const data = await this.client.apiRequest("getAliasedSymbol", {
|
|
1122
|
+
snapshot: this.snapshotId,
|
|
1123
|
+
project: this.project.id,
|
|
1124
|
+
symbol: symbol.id,
|
|
1125
|
+
});
|
|
1126
|
+
if (!data)
|
|
1127
|
+
throw new Error(`getAliasedSymbol returned no symbol for symbol ${symbol.id}`);
|
|
1128
|
+
return this.objectRegistry.getOrCreateSymbol(data);
|
|
1129
|
+
}
|
|
1130
|
+
async getImmediateAliasedSymbol(symbol) {
|
|
1131
|
+
const data = await this.client.apiRequest("getImmediateAliasedSymbol", {
|
|
1132
|
+
snapshot: this.snapshotId,
|
|
1133
|
+
project: this.project.id,
|
|
1134
|
+
symbol: symbol.id,
|
|
1135
|
+
});
|
|
1136
|
+
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
1137
|
+
}
|
|
1138
|
+
/**
|
|
1139
|
+
* Fetch (once, then cache) the handle ids of the per-checker singleton
|
|
1140
|
+
* symbols (unknown, undefined, arguments). These ids are stable for the life
|
|
1141
|
+
* of the project's checker, so identity checks against them are local after
|
|
1142
|
+
* the first call.
|
|
1143
|
+
*/
|
|
1144
|
+
getWellKnownSymbols() {
|
|
1145
|
+
return this.wellKnownSymbols ??= this.client.apiRequest("getWellKnownSymbols", {
|
|
1146
|
+
snapshot: this.snapshotId,
|
|
1147
|
+
project: this.project.id,
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Returns `true` if the symbol is the checker's "unknown" symbol (e.g. the
|
|
1152
|
+
* result of {@link Checker.getAliasedSymbol} on an unresolved alias).
|
|
1153
|
+
*/
|
|
1154
|
+
async isUnknownSymbol(symbol) {
|
|
1155
|
+
return symbol.id === (await this.getWellKnownSymbols()).unknown;
|
|
1156
|
+
}
|
|
1157
|
+
/**
|
|
1158
|
+
* Returns `true` if the symbol is the checker's "undefined" symbol.
|
|
1159
|
+
*/
|
|
1160
|
+
async isUndefinedSymbol(symbol) {
|
|
1161
|
+
return symbol.id === (await this.getWellKnownSymbols()).undefined;
|
|
1162
|
+
}
|
|
1163
|
+
/**
|
|
1164
|
+
* Returns `true` if the symbol is the checker's "arguments" symbol.
|
|
1165
|
+
*/
|
|
1166
|
+
async isArgumentsSymbol(symbol) {
|
|
1167
|
+
return symbol.id === (await this.getWellKnownSymbols()).arguments;
|
|
1168
|
+
}
|
|
1169
|
+
async getExportsOfModule(symbol) {
|
|
1170
|
+
const data = await this.client.apiRequest("getExportsOfModule", {
|
|
1171
|
+
snapshot: this.snapshotId,
|
|
1172
|
+
project: this.project.id,
|
|
1173
|
+
symbol: symbol.id,
|
|
1174
|
+
});
|
|
1175
|
+
return data ? data.map(d => this.objectRegistry.getOrCreateSymbol(d)) : [];
|
|
1176
|
+
}
|
|
1177
|
+
async getMemberInModuleExports(symbol, name) {
|
|
1178
|
+
const data = await this.client.apiRequest("getMemberInModuleExports", {
|
|
1179
|
+
snapshot: this.snapshotId,
|
|
1180
|
+
project: this.project.id,
|
|
1181
|
+
symbol: symbol.id,
|
|
1182
|
+
name,
|
|
1183
|
+
});
|
|
1184
|
+
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
1185
|
+
}
|
|
1186
|
+
async getJsDocTagsOfSymbol(symbol) {
|
|
1187
|
+
const data = await this.client.apiRequest("getJsDocTags", {
|
|
1188
|
+
snapshot: this.snapshotId,
|
|
1189
|
+
project: this.project.id,
|
|
1190
|
+
symbol: symbol.id,
|
|
1191
|
+
});
|
|
1192
|
+
return data ?? [];
|
|
1193
|
+
}
|
|
1194
|
+
async getDocumentationCommentOfSymbol(symbol) {
|
|
1195
|
+
return this.client.apiRequest("getDocumentationComment", {
|
|
1196
|
+
snapshot: this.snapshotId,
|
|
1197
|
+
project: this.project.id,
|
|
1198
|
+
symbol: symbol.id,
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Get the type arguments of a type reference (e.g. the `string` in `Array<string>`).
|
|
1203
|
+
*/
|
|
825
1204
|
async getTypeArguments(type) {
|
|
826
1205
|
const data = await this.client.apiRequest("getTypeArguments", {
|
|
827
1206
|
snapshot: this.snapshotId,
|
|
828
|
-
project: this.
|
|
1207
|
+
project: this.project.id,
|
|
829
1208
|
type: type.id,
|
|
830
1209
|
});
|
|
831
1210
|
return data ? data.map(d => this.objectRegistry.getOrCreateType(d)) : [];
|
|
@@ -846,20 +1225,28 @@ export class Emitter {
|
|
|
846
1225
|
}
|
|
847
1226
|
}
|
|
848
1227
|
export class NodeHandle {
|
|
1228
|
+
/**
|
|
1229
|
+
* The project this handle was produced in, used as the default for {@link resolve}.
|
|
1230
|
+
* Node handles are only meaningful within a project's program, so the producing project
|
|
1231
|
+
* is remembered so callers don't have to pass it explicitly.
|
|
1232
|
+
*/
|
|
1233
|
+
canonicalProject;
|
|
849
1234
|
index;
|
|
850
1235
|
kind;
|
|
851
1236
|
path;
|
|
852
|
-
constructor(handle) {
|
|
1237
|
+
constructor(handle, canonicalProject) {
|
|
853
1238
|
const parsed = parseNodeHandle(handle);
|
|
854
1239
|
this.index = parsed.index;
|
|
855
1240
|
this.kind = parsed.kind;
|
|
856
1241
|
this.path = parsed.path;
|
|
1242
|
+
this.canonicalProject = canonicalProject;
|
|
857
1243
|
}
|
|
858
1244
|
/**
|
|
859
|
-
* Resolve this handle to the actual AST node by fetching the source file
|
|
860
|
-
*
|
|
1245
|
+
* Resolve this handle to the actual AST node by fetching the source file from a project
|
|
1246
|
+
* and looking up the node by index. If no project is passed, the project that produced
|
|
1247
|
+
* the handle is used.
|
|
861
1248
|
*/
|
|
862
|
-
async resolve(project) {
|
|
1249
|
+
async resolve(project = this.canonicalProject) {
|
|
863
1250
|
const sourceFile = await project.program.getSourceFile(this.path);
|
|
864
1251
|
if (!sourceFile) {
|
|
865
1252
|
return undefined;
|
|
@@ -869,7 +1256,16 @@ export class NodeHandle {
|
|
|
869
1256
|
}
|
|
870
1257
|
export class Symbol {
|
|
871
1258
|
objectRegistry;
|
|
1259
|
+
/**
|
|
1260
|
+
* The project this symbol was first observed in, used as the default project for
|
|
1261
|
+
* lookups that need a project context (members/exports/parent). Symbols are shared
|
|
1262
|
+
* snapshot-wide, so these lookups can otherwise be ambiguous about which project to use.
|
|
1263
|
+
*/
|
|
1264
|
+
canonicalProject;
|
|
872
1265
|
id;
|
|
1266
|
+
/** The escaped (`__String`) name, used as the key in member/export tables. */
|
|
1267
|
+
escapedName;
|
|
1268
|
+
/** The display name (escaped underscores removed). */
|
|
873
1269
|
name;
|
|
874
1270
|
flags;
|
|
875
1271
|
checkFlags;
|
|
@@ -877,32 +1273,62 @@ export class Symbol {
|
|
|
877
1273
|
valueDeclaration;
|
|
878
1274
|
parent;
|
|
879
1275
|
exportSymbol;
|
|
1276
|
+
membersCache;
|
|
1277
|
+
exportsCache;
|
|
880
1278
|
constructor(data, objectRegistry) {
|
|
881
1279
|
this.objectRegistry = objectRegistry;
|
|
882
1280
|
this.id = data.id;
|
|
883
|
-
this.
|
|
1281
|
+
this.escapedName = data.name;
|
|
1282
|
+
this.name = unescapeLeadingUnderscores(data.name);
|
|
884
1283
|
this.flags = data.flags;
|
|
885
1284
|
this.checkFlags = data.checkFlags;
|
|
886
|
-
|
|
887
|
-
|
|
1285
|
+
const canonicalProject = objectRegistry.getProject(data.project);
|
|
1286
|
+
if (!canonicalProject) {
|
|
1287
|
+
throw new Error(`Symbol ${data.id} references unknown canonical project '${data.project}'`);
|
|
1288
|
+
}
|
|
1289
|
+
this.canonicalProject = canonicalProject;
|
|
1290
|
+
this.declarations = (data.declarations ?? []).map(d => new NodeHandle(d, canonicalProject));
|
|
1291
|
+
this.valueDeclaration = data.valueDeclaration ? new NodeHandle(data.valueDeclaration, canonicalProject) : undefined;
|
|
888
1292
|
if (data.parent !== undefined)
|
|
889
1293
|
this.parent = data.parent;
|
|
890
1294
|
if (data.exportSymbol !== undefined)
|
|
891
1295
|
this.exportSymbol = data.exportSymbol;
|
|
892
1296
|
}
|
|
893
1297
|
async getParent() {
|
|
894
|
-
return this.objectRegistry.fetchSymbol(this, "getParentOfSymbol", this.parent);
|
|
1298
|
+
return this.objectRegistry.fetchSymbol(this, "getParentOfSymbol", this.parent, this.canonicalProject.id);
|
|
895
1299
|
}
|
|
896
|
-
|
|
897
|
-
|
|
1300
|
+
/**
|
|
1301
|
+
* Get this symbol's members keyed by escaped name. The result is cached on
|
|
1302
|
+
* the symbol, so repeated calls do not round-trip to the server.
|
|
1303
|
+
*/
|
|
1304
|
+
getMembers() {
|
|
1305
|
+
return this.membersCache ??= this.fetchSymbolTable("getMembersOfSymbol");
|
|
898
1306
|
}
|
|
899
|
-
|
|
900
|
-
|
|
1307
|
+
/**
|
|
1308
|
+
* Get this symbol's exports keyed by escaped name. The result is cached on
|
|
1309
|
+
* the symbol, so repeated calls do not round-trip to the server.
|
|
1310
|
+
*/
|
|
1311
|
+
getExports() {
|
|
1312
|
+
return this.exportsCache ??= this.fetchSymbolTable("getExportsOfSymbol");
|
|
1313
|
+
}
|
|
1314
|
+
async fetchSymbolTable(method) {
|
|
1315
|
+
const symbols = await this.objectRegistry.fetchSymbols(this, method, undefined, this.canonicalProject.id);
|
|
1316
|
+
const table = new Map();
|
|
1317
|
+
for (const symbol of symbols) {
|
|
1318
|
+
table.set(symbol.escapedName, symbol);
|
|
1319
|
+
}
|
|
1320
|
+
return table;
|
|
901
1321
|
}
|
|
902
1322
|
async getExportSymbol() {
|
|
903
1323
|
if (!this.exportSymbol)
|
|
904
1324
|
return this;
|
|
905
|
-
return this.objectRegistry.fetchSymbol(this, "getExportSymbolOfSymbol", this.exportSymbol);
|
|
1325
|
+
return this.objectRegistry.fetchSymbol(this, "getExportSymbolOfSymbol", this.exportSymbol, this.canonicalProject.id);
|
|
1326
|
+
}
|
|
1327
|
+
async getJsDocTags(checker) {
|
|
1328
|
+
return checker.getJsDocTagsOfSymbol(this);
|
|
1329
|
+
}
|
|
1330
|
+
async getDocumentationComment(checker) {
|
|
1331
|
+
return checker.getDocumentationCommentOfSymbol(this);
|
|
906
1332
|
}
|
|
907
1333
|
}
|
|
908
1334
|
class TypeObject {
|
|
@@ -932,6 +1358,8 @@ class TypeObject {
|
|
|
932
1358
|
extendsType;
|
|
933
1359
|
baseType;
|
|
934
1360
|
substConstraint;
|
|
1361
|
+
trueType; // false if not yet loaded
|
|
1362
|
+
falseType; // false if not yet loaded
|
|
935
1363
|
constructor(data, objectRegistry) {
|
|
936
1364
|
this.objectRegistry = objectRegistry;
|
|
937
1365
|
this.id = data.id;
|
|
@@ -940,8 +1368,11 @@ class TypeObject {
|
|
|
940
1368
|
this.objectFlags = data.objectFlags;
|
|
941
1369
|
if (data.symbol !== undefined)
|
|
942
1370
|
this.symbol = data.symbol;
|
|
943
|
-
if (data.value
|
|
944
|
-
|
|
1371
|
+
if (data.value != null) {
|
|
1372
|
+
// BigInt literal values are serialized as decimal strings (e.g. "-123") because
|
|
1373
|
+
// JSON cannot represent bigint. Decode them back into a real bigint here.
|
|
1374
|
+
this.value = (data.flags & TypeFlags.BigIntLiteral) ? BigInt(data.value) : data.value;
|
|
1375
|
+
}
|
|
945
1376
|
if (data.intrinsicName !== undefined)
|
|
946
1377
|
this.intrinsicName = data.intrinsicName;
|
|
947
1378
|
if (data.isThisType !== undefined)
|
|
@@ -978,6 +1409,8 @@ class TypeObject {
|
|
|
978
1409
|
this.baseType = data.baseType;
|
|
979
1410
|
if (data.substConstraint !== undefined)
|
|
980
1411
|
this.substConstraint = data.substConstraint;
|
|
1412
|
+
this.trueType = false;
|
|
1413
|
+
this.falseType = false;
|
|
981
1414
|
}
|
|
982
1415
|
async getSymbol() {
|
|
983
1416
|
return this.objectRegistry.fetchSymbol(this, "getSymbolOfType", this.symbol);
|
|
@@ -995,6 +1428,12 @@ class TypeObject {
|
|
|
995
1428
|
return this.objectRegistry.fetchType(this, "getRegularTypeOfType", this.regularType);
|
|
996
1429
|
}
|
|
997
1430
|
async getTypes() {
|
|
1431
|
+
// Only union, intersection, and template literal types have constituent
|
|
1432
|
+
// types; any other kind has none, so return undefined rather than sending
|
|
1433
|
+
// a request the server cannot satisfy.
|
|
1434
|
+
if (!(this.flags & (TypeFlags.UnionOrIntersection | TypeFlags.TemplateLiteral))) {
|
|
1435
|
+
return undefined;
|
|
1436
|
+
}
|
|
998
1437
|
return this.objectRegistry.fetchTypes(this, "getTypesOfType");
|
|
999
1438
|
}
|
|
1000
1439
|
async getTypeParameters() {
|
|
@@ -1027,6 +1466,152 @@ class TypeObject {
|
|
|
1027
1466
|
async getConstraint() {
|
|
1028
1467
|
return this.objectRegistry.fetchType(this, "getConstraintOfType", this.substConstraint);
|
|
1029
1468
|
}
|
|
1469
|
+
async getTrueType() {
|
|
1470
|
+
const result = await this.objectRegistry.fetchType(this, "getTrueTypeOfConditionalType", this.trueType);
|
|
1471
|
+
this.trueType = result.id;
|
|
1472
|
+
return result;
|
|
1473
|
+
}
|
|
1474
|
+
async getFalseType() {
|
|
1475
|
+
const result = await this.objectRegistry.fetchType(this, "getFalseTypeOfConditionalType", this.falseType);
|
|
1476
|
+
this.falseType = result.id;
|
|
1477
|
+
return result;
|
|
1478
|
+
}
|
|
1479
|
+
/**
|
|
1480
|
+
* Get the base types of this type. Returns `undefined` for any type that is
|
|
1481
|
+
* not a class or interface.
|
|
1482
|
+
*/
|
|
1483
|
+
async getBaseTypes() {
|
|
1484
|
+
if (!this.isClassOrInterface()) {
|
|
1485
|
+
return undefined;
|
|
1486
|
+
}
|
|
1487
|
+
return this.objectRegistry.fetchBaseTypes(this);
|
|
1488
|
+
}
|
|
1489
|
+
isClassOrInterface() {
|
|
1490
|
+
return isClassOrInterfaceType(this);
|
|
1491
|
+
}
|
|
1492
|
+
isUnionType() {
|
|
1493
|
+
return isUnionType(this);
|
|
1494
|
+
}
|
|
1495
|
+
isIntersectionType() {
|
|
1496
|
+
return isIntersectionType(this);
|
|
1497
|
+
}
|
|
1498
|
+
isObjectType() {
|
|
1499
|
+
return isObjectType(this);
|
|
1500
|
+
}
|
|
1501
|
+
isIntrinsicType() {
|
|
1502
|
+
return isIntrinsicType(this);
|
|
1503
|
+
}
|
|
1504
|
+
isErrorType() {
|
|
1505
|
+
return isErrorType(this);
|
|
1506
|
+
}
|
|
1507
|
+
isLiteralType() {
|
|
1508
|
+
return isLiteralType(this);
|
|
1509
|
+
}
|
|
1510
|
+
isStringLiteralType() {
|
|
1511
|
+
return isStringLiteralType(this);
|
|
1512
|
+
}
|
|
1513
|
+
isNumberLiteralType() {
|
|
1514
|
+
return isNumberLiteralType(this);
|
|
1515
|
+
}
|
|
1516
|
+
isBigIntLiteralType() {
|
|
1517
|
+
return isBigIntLiteralType(this);
|
|
1518
|
+
}
|
|
1519
|
+
isBooleanLiteralType() {
|
|
1520
|
+
return isBooleanLiteralType(this);
|
|
1521
|
+
}
|
|
1522
|
+
isTypeReference() {
|
|
1523
|
+
return isTypeReference(this);
|
|
1524
|
+
}
|
|
1525
|
+
isTupleType() {
|
|
1526
|
+
return isTupleType(this);
|
|
1527
|
+
}
|
|
1528
|
+
isIndexType() {
|
|
1529
|
+
return isIndexType(this);
|
|
1530
|
+
}
|
|
1531
|
+
isIndexedAccessType() {
|
|
1532
|
+
return isIndexedAccessType(this);
|
|
1533
|
+
}
|
|
1534
|
+
isConditionalType() {
|
|
1535
|
+
return isConditionalType(this);
|
|
1536
|
+
}
|
|
1537
|
+
isSubstitutionType() {
|
|
1538
|
+
return isSubstitutionType(this);
|
|
1539
|
+
}
|
|
1540
|
+
isTemplateLiteralType() {
|
|
1541
|
+
return isTemplateLiteralType(this);
|
|
1542
|
+
}
|
|
1543
|
+
isStringMappingType() {
|
|
1544
|
+
return isStringMappingType(this);
|
|
1545
|
+
}
|
|
1546
|
+
isTypeParameter() {
|
|
1547
|
+
return isTypeParameter(this);
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
export function isUnionType(type) {
|
|
1551
|
+
return (type.flags & TypeFlags.Union) !== 0;
|
|
1552
|
+
}
|
|
1553
|
+
export function isIntersectionType(type) {
|
|
1554
|
+
return (type.flags & TypeFlags.Intersection) !== 0;
|
|
1555
|
+
}
|
|
1556
|
+
export function isObjectType(type) {
|
|
1557
|
+
return (type.flags & TypeFlags.Object) !== 0;
|
|
1558
|
+
}
|
|
1559
|
+
export function isClassOrInterfaceType(type) {
|
|
1560
|
+
return isObjectType(type) && (type.objectFlags & ObjectFlags.ClassOrInterface) !== 0;
|
|
1561
|
+
}
|
|
1562
|
+
export function isIntrinsicType(type) {
|
|
1563
|
+
return (type.flags & TypeFlags.Intrinsic) !== 0;
|
|
1564
|
+
}
|
|
1565
|
+
/**
|
|
1566
|
+
* Whether this is the error type — the placeholder the checker produces when a
|
|
1567
|
+
* type cannot be determined (e.g. an unresolved reference). It is an intrinsic
|
|
1568
|
+
* type named `"error"` (this covers both the singleton error type and the
|
|
1569
|
+
* per-alias error types manufactured for unresolved type alias references).
|
|
1570
|
+
*/
|
|
1571
|
+
export function isErrorType(type) {
|
|
1572
|
+
return isIntrinsicType(type) && type.intrinsicName === "error";
|
|
1573
|
+
}
|
|
1574
|
+
export function isLiteralType(type) {
|
|
1575
|
+
return (type.flags & TypeFlags.Literal) !== 0;
|
|
1576
|
+
}
|
|
1577
|
+
export function isStringLiteralType(type) {
|
|
1578
|
+
return (type.flags & TypeFlags.StringLiteral) !== 0;
|
|
1579
|
+
}
|
|
1580
|
+
export function isNumberLiteralType(type) {
|
|
1581
|
+
return (type.flags & TypeFlags.NumberLiteral) !== 0;
|
|
1582
|
+
}
|
|
1583
|
+
export function isBigIntLiteralType(type) {
|
|
1584
|
+
return (type.flags & TypeFlags.BigIntLiteral) !== 0;
|
|
1585
|
+
}
|
|
1586
|
+
export function isBooleanLiteralType(type) {
|
|
1587
|
+
return (type.flags & TypeFlags.BooleanLiteral) !== 0;
|
|
1588
|
+
}
|
|
1589
|
+
export function isTypeReference(type) {
|
|
1590
|
+
return isObjectType(type) && (type.objectFlags & ObjectFlags.Reference) !== 0;
|
|
1591
|
+
}
|
|
1592
|
+
export function isTupleType(type) {
|
|
1593
|
+
return isObjectType(type) && (type.objectFlags & ObjectFlags.Tuple) !== 0;
|
|
1594
|
+
}
|
|
1595
|
+
export function isIndexType(type) {
|
|
1596
|
+
return (type.flags & TypeFlags.Index) !== 0;
|
|
1597
|
+
}
|
|
1598
|
+
export function isIndexedAccessType(type) {
|
|
1599
|
+
return (type.flags & TypeFlags.IndexedAccess) !== 0;
|
|
1600
|
+
}
|
|
1601
|
+
export function isConditionalType(type) {
|
|
1602
|
+
return (type.flags & TypeFlags.Conditional) !== 0;
|
|
1603
|
+
}
|
|
1604
|
+
export function isSubstitutionType(type) {
|
|
1605
|
+
return (type.flags & TypeFlags.Substitution) !== 0;
|
|
1606
|
+
}
|
|
1607
|
+
export function isTemplateLiteralType(type) {
|
|
1608
|
+
return (type.flags & TypeFlags.TemplateLiteral) !== 0;
|
|
1609
|
+
}
|
|
1610
|
+
export function isStringMappingType(type) {
|
|
1611
|
+
return (type.flags & TypeFlags.StringMapping) !== 0;
|
|
1612
|
+
}
|
|
1613
|
+
export function isTypeParameter(type) {
|
|
1614
|
+
return (type.flags & TypeFlags.TypeParameter) !== 0;
|
|
1030
1615
|
}
|
|
1031
1616
|
export class Signature {
|
|
1032
1617
|
flags;
|
|
@@ -1037,11 +1622,11 @@ export class Signature {
|
|
|
1037
1622
|
parameters;
|
|
1038
1623
|
thisParameter;
|
|
1039
1624
|
target;
|
|
1040
|
-
constructor(data, objectRegistry) {
|
|
1625
|
+
constructor(data, project, objectRegistry) {
|
|
1041
1626
|
this.id = data.id;
|
|
1042
1627
|
this.flags = data.flags;
|
|
1043
1628
|
this.objectRegistry = objectRegistry;
|
|
1044
|
-
this.declaration = data.declaration ? new NodeHandle(data.declaration) : undefined;
|
|
1629
|
+
this.declaration = data.declaration ? new NodeHandle(data.declaration, project) : undefined;
|
|
1045
1630
|
this.typeParameters = data.typeParameters ?? [];
|
|
1046
1631
|
this.parameters = data.parameters ?? [];
|
|
1047
1632
|
this.thisParameter = data.thisParameter;
|