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.
Files changed (158) hide show
  1. package/NOTICE.txt +1 -1
  2. package/README.md +39 -14
  3. package/dist/api/async/api.d.ts +274 -45
  4. package/dist/api/async/api.d.ts.map +1 -1
  5. package/dist/api/async/api.js +722 -137
  6. package/dist/api/async/api.js.map +1 -1
  7. package/dist/api/async/client.d.ts +17 -0
  8. package/dist/api/async/client.d.ts.map +1 -1
  9. package/dist/api/async/client.js +72 -1
  10. package/dist/api/async/client.js.map +1 -1
  11. package/dist/api/async/types.d.ts +108 -27
  12. package/dist/api/async/types.d.ts.map +1 -1
  13. package/dist/api/compilerOptions.d.ts +109 -0
  14. package/dist/api/compilerOptions.d.ts.map +1 -0
  15. package/dist/api/compilerOptions.js +2 -0
  16. package/dist/api/compilerOptions.js.map +1 -0
  17. package/dist/api/node/encoder.d.ts.map +1 -1
  18. package/dist/api/node/encoder.js +1 -18
  19. package/dist/api/node/encoder.js.map +1 -1
  20. package/dist/api/node/msgpack.d.ts.map +1 -1
  21. package/dist/api/node/msgpack.js +2 -1
  22. package/dist/api/node/msgpack.js.map +1 -1
  23. package/dist/api/node/node.d.ts +17 -3
  24. package/dist/api/node/node.d.ts.map +1 -1
  25. package/dist/api/node/node.generated.d.ts +11 -0
  26. package/dist/api/node/node.generated.d.ts.map +1 -1
  27. package/dist/api/node/node.generated.js +69 -48
  28. package/dist/api/node/node.generated.js.map +1 -1
  29. package/dist/api/node/node.infrastructure.d.ts +11 -0
  30. package/dist/api/node/node.infrastructure.d.ts.map +1 -1
  31. package/dist/api/node/node.infrastructure.js.map +1 -1
  32. package/dist/api/node/node.js +93 -9
  33. package/dist/api/node/node.js.map +1 -1
  34. package/dist/api/node/wtf8.d.ts +6 -0
  35. package/dist/api/node/wtf8.d.ts.map +1 -0
  36. package/dist/api/node/wtf8.js +61 -0
  37. package/dist/api/node/wtf8.js.map +1 -0
  38. package/dist/api/options.d.ts +8 -0
  39. package/dist/api/options.d.ts.map +1 -1
  40. package/dist/api/options.js.map +1 -1
  41. package/dist/api/proto.d.ts +58 -5
  42. package/dist/api/proto.d.ts.map +1 -1
  43. package/dist/api/proto.js +15 -0
  44. package/dist/api/proto.js.map +1 -1
  45. package/dist/api/sync/api.d.ts +274 -45
  46. package/dist/api/sync/api.d.ts.map +1 -1
  47. package/dist/api/sync/api.js +720 -135
  48. package/dist/api/sync/api.js.map +1 -1
  49. package/dist/api/sync/client.d.ts +17 -0
  50. package/dist/api/sync/client.d.ts.map +1 -1
  51. package/dist/api/sync/client.js +53 -1
  52. package/dist/api/sync/client.js.map +1 -1
  53. package/dist/api/sync/types.d.ts +108 -27
  54. package/dist/api/sync/types.d.ts.map +1 -1
  55. package/dist/api/syncChannel.d.ts +4 -1
  56. package/dist/api/syncChannel.d.ts.map +1 -1
  57. package/dist/api/syncChannel.js +21 -1
  58. package/dist/api/syncChannel.js.map +1 -1
  59. package/dist/api/timing.d.ts +175 -0
  60. package/dist/api/timing.d.ts.map +1 -0
  61. package/dist/api/timing.js +149 -0
  62. package/dist/api/timing.js.map +1 -0
  63. package/dist/ast/ast.d.ts +36 -2
  64. package/dist/ast/ast.d.ts.map +1 -1
  65. package/dist/ast/ast.generated.d.ts +3 -3
  66. package/dist/ast/ast.generated.d.ts.map +1 -1
  67. package/dist/ast/ast.js.map +1 -1
  68. package/dist/ast/factory.generated.d.ts +12 -4
  69. package/dist/ast/factory.generated.d.ts.map +1 -1
  70. package/dist/ast/factory.generated.js +36 -2
  71. package/dist/ast/factory.generated.js.map +1 -1
  72. package/dist/ast/index.d.ts +2 -0
  73. package/dist/ast/index.d.ts.map +1 -1
  74. package/dist/ast/index.js +2 -0
  75. package/dist/ast/index.js.map +1 -1
  76. package/dist/ast/is.d.ts +2 -1
  77. package/dist/ast/is.d.ts.map +1 -1
  78. package/dist/ast/is.generated.d.ts +2 -2
  79. package/dist/ast/is.generated.d.ts.map +1 -1
  80. package/dist/ast/is.generated.js +3 -4
  81. package/dist/ast/is.generated.js.map +1 -1
  82. package/dist/ast/is.js +8 -1
  83. package/dist/ast/is.js.map +1 -1
  84. package/dist/ast/jsdoc.d.ts +11 -0
  85. package/dist/ast/jsdoc.d.ts.map +1 -0
  86. package/dist/ast/jsdoc.js +202 -0
  87. package/dist/ast/jsdoc.js.map +1 -0
  88. package/dist/ast/utils.d.ts +12 -0
  89. package/dist/ast/utils.d.ts.map +1 -1
  90. package/dist/ast/utils.js +40 -0
  91. package/dist/ast/utils.js.map +1 -1
  92. package/dist/enums/internalSymbolName.d.ts +2 -0
  93. package/dist/enums/internalSymbolName.d.ts.map +1 -0
  94. package/dist/enums/internalSymbolName.enum.d.ts +23 -0
  95. package/dist/enums/internalSymbolName.enum.d.ts.map +1 -0
  96. package/dist/enums/internalSymbolName.enum.js +25 -0
  97. package/dist/enums/internalSymbolName.enum.js.map +1 -0
  98. package/dist/enums/internalSymbolName.js +25 -0
  99. package/dist/enums/internalSymbolName.js.map +1 -0
  100. package/dist/enums/jsxEmit.d.ts +2 -0
  101. package/dist/enums/jsxEmit.d.ts.map +1 -0
  102. package/dist/enums/jsxEmit.enum.d.ts +9 -0
  103. package/dist/enums/jsxEmit.enum.d.ts.map +1 -0
  104. package/dist/enums/jsxEmit.enum.js +11 -0
  105. package/dist/enums/jsxEmit.enum.js.map +1 -0
  106. package/dist/enums/jsxEmit.js +11 -0
  107. package/dist/enums/jsxEmit.js.map +1 -0
  108. package/dist/enums/moduleDetectionKind.d.ts +2 -0
  109. package/dist/enums/moduleDetectionKind.d.ts.map +1 -0
  110. package/dist/enums/moduleDetectionKind.enum.d.ts +7 -0
  111. package/dist/enums/moduleDetectionKind.enum.d.ts.map +1 -0
  112. package/dist/enums/moduleDetectionKind.enum.js +9 -0
  113. package/dist/enums/moduleDetectionKind.enum.js.map +1 -0
  114. package/dist/enums/moduleDetectionKind.js +9 -0
  115. package/dist/enums/moduleDetectionKind.js.map +1 -0
  116. package/dist/enums/moduleKind.d.ts +2 -0
  117. package/dist/enums/moduleKind.d.ts.map +1 -0
  118. package/dist/enums/moduleKind.enum.d.ts +17 -0
  119. package/dist/enums/moduleKind.enum.d.ts.map +1 -0
  120. package/dist/enums/moduleKind.enum.js +19 -0
  121. package/dist/enums/moduleKind.enum.js.map +1 -0
  122. package/dist/enums/moduleKind.js +19 -0
  123. package/dist/enums/moduleKind.js.map +1 -0
  124. package/dist/enums/moduleResolutionKind.d.ts +2 -0
  125. package/dist/enums/moduleResolutionKind.d.ts.map +1 -0
  126. package/dist/enums/moduleResolutionKind.enum.d.ts +9 -0
  127. package/dist/enums/moduleResolutionKind.enum.d.ts.map +1 -0
  128. package/dist/enums/moduleResolutionKind.enum.js +11 -0
  129. package/dist/enums/moduleResolutionKind.enum.js.map +1 -0
  130. package/dist/enums/moduleResolutionKind.js +11 -0
  131. package/dist/enums/moduleResolutionKind.js.map +1 -0
  132. package/dist/enums/newLineKind.d.ts +2 -0
  133. package/dist/enums/newLineKind.d.ts.map +1 -0
  134. package/dist/enums/newLineKind.enum.d.ts +6 -0
  135. package/dist/enums/newLineKind.enum.d.ts.map +1 -0
  136. package/dist/enums/newLineKind.enum.js +8 -0
  137. package/dist/enums/newLineKind.enum.js.map +1 -0
  138. package/dist/enums/newLineKind.js +8 -0
  139. package/dist/enums/newLineKind.js.map +1 -0
  140. package/dist/enums/outerExpressionKinds.enum.d.ts +5 -1
  141. package/dist/enums/outerExpressionKinds.enum.d.ts.map +1 -1
  142. package/dist/enums/outerExpressionKinds.enum.js +4 -0
  143. package/dist/enums/outerExpressionKinds.enum.js.map +1 -1
  144. package/dist/enums/outerExpressionKinds.js +4 -0
  145. package/dist/enums/outerExpressionKinds.js.map +1 -1
  146. package/dist/internal/utils.d.ts +23 -0
  147. package/dist/internal/utils.d.ts.map +1 -0
  148. package/dist/internal/utils.js +25 -0
  149. package/dist/internal/utils.js.map +1 -0
  150. package/lib/getExePath.js +6 -3
  151. package/lib/tsc.js +1 -1
  152. package/lib/version.cjs +3 -0
  153. package/lib/version.d.cts +2 -0
  154. package/package.json +31 -30
  155. package/dist/api/objectRegistry.d.ts +0 -40
  156. package/dist/api/objectRegistry.d.ts.map +0 -1
  157. package/dist/api/objectRegistry.js +0 -61
  158. package/dist/api/objectRegistry.js.map +0 -1
@@ -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 { ObjectRegistry, } from "../objectRegistry.js";
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, this.objectRegistry, sourceFileCache, toPath);
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.objectRegistry.clear();
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 extends ObjectRegistry {
199
+ class SnapshotObjectRegistry {
200
+ symbols = new Map();
185
201
  client;
186
202
  snapshotId;
187
- constructor(factories, client, snapshotId) {
188
- super(factories);
203
+ resolveProject;
204
+ constructor(client, snapshotId, resolveProject) {
189
205
  this.client = client;
190
206
  this.snapshotId = snapshotId;
207
+ this.resolveProject = resolveProject;
191
208
  }
192
- async fetchType(source, method, handle) {
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.getType(handle);
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 type for ${source.constructor.name} ${source.id}`);
204
- return this.getOrCreateType(data);
239
+ throw new Error(`${method} returned null symbol for ${source.constructor.name} ${source.id}`);
240
+ return this.getOrCreateSymbol(data);
205
241
  }
206
- async fetchSymbol(source, method, handle) {
207
- if (!handle)
208
- return undefined;
209
- const cached = this.getSymbol(handle);
210
- if (cached)
211
- return cached;
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 symbol for ${source.constructor.name} ${source.id}`);
218
- return this.getOrCreateSymbol(data);
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
- if (handles) {
260
- const result = new Array(handles.length);
261
- let allCached = true;
262
- for (let i = 0; i < handles.length; i++) {
263
- const cached = this.getSymbol(handles[i]);
264
- if (!cached) {
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
- objectId: source.id,
381
+ project: this.project.id,
382
+ type: source.id,
276
383
  });
277
- if (symbolData == null)
384
+ if (typesData == null)
278
385
  return [];
279
- else
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, objectRegistry, sourceFileCache, toPath) {
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.id, client, sourceFileCache, toPath);
299
- this.checker = new Checker(snapshotId, this.id, client, objectRegistry);
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
- projectId;
415
+ project;
306
416
  client;
307
417
  sourceFileCache;
308
418
  toPath;
309
- decoder = new TextDecoder();
310
- constructor(snapshotId, projectId, client, sourceFileCache, toPath) {
419
+ decoder = new Wtf8Decoder();
420
+ sourceFileMetadataCache = new Map();
421
+ constructor(snapshotId, project, client, sourceFileCache, toPath) {
311
422
  this.snapshotId = snapshotId;
312
- this.projectId = projectId;
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.projectId);
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.projectId,
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.projectId);
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
596
+ project: this.project.id,
396
597
  });
397
598
  return data ?? [];
398
599
  }
399
600
  }
400
601
  export class Checker {
401
602
  snapshotId;
402
- projectId;
603
+ project;
403
604
  client;
404
605
  objectRegistry;
405
- constructor(snapshotId, projectId, client, objectRegistry) {
606
+ wellKnownSymbols;
607
+ constructor(snapshotId, project, client, objectRegistry) {
406
608
  this.snapshotId = snapshotId;
407
- this.projectId = projectId;
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
674
+ project: this.project.id,
465
675
  symbol: symbol.id,
466
676
  });
467
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
885
+ project: this.project.id,
669
886
  symbol: symbol.id,
670
887
  location: getNodeId(location),
671
888
  });
672
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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.projectId,
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
- * from the given project and looking up the node by index.
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.name = data.name;
1281
+ this.escapedName = data.name;
1282
+ this.name = unescapeLeadingUnderscores(data.name);
884
1283
  this.flags = data.flags;
885
1284
  this.checkFlags = data.checkFlags;
886
- this.declarations = (data.declarations ?? []).map(d => new NodeHandle(d));
887
- this.valueDeclaration = data.valueDeclaration ? new NodeHandle(data.valueDeclaration) : undefined;
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
- async getMembers() {
897
- return this.objectRegistry.fetchSymbols(this, "getMembersOfSymbol");
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
- async getExports() {
900
- return this.objectRegistry.fetchSymbols(this, "getExportsOfSymbol");
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 !== undefined)
944
- this.value = data.value;
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;