@typescript/native-preview 7.0.0-dev.20260630.1 → 7.0.0-dev.20260702.3

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 (121) hide show
  1. package/dist/api/async/api.d.ts +144 -33
  2. package/dist/api/async/api.d.ts.map +1 -1
  3. package/dist/api/async/api.js +309 -115
  4. package/dist/api/async/api.js.map +1 -1
  5. package/dist/api/async/types.d.ts +31 -19
  6. package/dist/api/async/types.d.ts.map +1 -1
  7. package/dist/api/compilerOptions.d.ts +109 -0
  8. package/dist/api/compilerOptions.d.ts.map +1 -0
  9. package/dist/api/compilerOptions.js +2 -0
  10. package/dist/api/compilerOptions.js.map +1 -0
  11. package/dist/api/node/encoder.d.ts.map +1 -1
  12. package/dist/api/node/encoder.js +1 -18
  13. package/dist/api/node/encoder.js.map +1 -1
  14. package/dist/api/node/msgpack.d.ts.map +1 -1
  15. package/dist/api/node/msgpack.js +2 -1
  16. package/dist/api/node/msgpack.js.map +1 -1
  17. package/dist/api/node/node.d.ts +1 -1
  18. package/dist/api/node/node.d.ts.map +1 -1
  19. package/dist/api/node/node.generated.d.ts +1 -0
  20. package/dist/api/node/node.generated.d.ts.map +1 -1
  21. package/dist/api/node/node.generated.js +5 -36
  22. package/dist/api/node/node.generated.js.map +1 -1
  23. package/dist/api/node/node.infrastructure.d.ts +3 -0
  24. package/dist/api/node/node.infrastructure.d.ts.map +1 -1
  25. package/dist/api/node/node.infrastructure.js.map +1 -1
  26. package/dist/api/node/node.js +2 -1
  27. package/dist/api/node/node.js.map +1 -1
  28. package/dist/api/node/wtf8.d.ts +6 -0
  29. package/dist/api/node/wtf8.d.ts.map +1 -0
  30. package/dist/api/node/wtf8.js +61 -0
  31. package/dist/api/node/wtf8.js.map +1 -0
  32. package/dist/api/proto.d.ts +20 -3
  33. package/dist/api/proto.d.ts.map +1 -1
  34. package/dist/api/proto.js.map +1 -1
  35. package/dist/api/sync/api.d.ts +144 -33
  36. package/dist/api/sync/api.d.ts.map +1 -1
  37. package/dist/api/sync/api.js +307 -113
  38. package/dist/api/sync/api.js.map +1 -1
  39. package/dist/api/sync/types.d.ts +31 -19
  40. package/dist/api/sync/types.d.ts.map +1 -1
  41. package/dist/ast/ast.d.ts +16 -2
  42. package/dist/ast/ast.d.ts.map +1 -1
  43. package/dist/ast/ast.generated.d.ts +3 -3
  44. package/dist/ast/ast.generated.d.ts.map +1 -1
  45. package/dist/ast/ast.js.map +1 -1
  46. package/dist/ast/factory.generated.d.ts +4 -4
  47. package/dist/ast/factory.generated.d.ts.map +1 -1
  48. package/dist/ast/factory.generated.js.map +1 -1
  49. package/dist/ast/index.d.ts +2 -0
  50. package/dist/ast/index.d.ts.map +1 -1
  51. package/dist/ast/index.js +2 -0
  52. package/dist/ast/index.js.map +1 -1
  53. package/dist/ast/is.d.ts +2 -1
  54. package/dist/ast/is.d.ts.map +1 -1
  55. package/dist/ast/is.generated.d.ts +1 -2
  56. package/dist/ast/is.generated.d.ts.map +1 -1
  57. package/dist/ast/is.generated.js +0 -4
  58. package/dist/ast/is.generated.js.map +1 -1
  59. package/dist/ast/is.js +8 -1
  60. package/dist/ast/is.js.map +1 -1
  61. package/dist/ast/jsdoc.d.ts +11 -0
  62. package/dist/ast/jsdoc.d.ts.map +1 -0
  63. package/dist/ast/jsdoc.js +202 -0
  64. package/dist/ast/jsdoc.js.map +1 -0
  65. package/dist/ast/utils.d.ts +11 -1
  66. package/dist/ast/utils.d.ts.map +1 -1
  67. package/dist/ast/utils.js +20 -0
  68. package/dist/ast/utils.js.map +1 -1
  69. package/dist/enums/internalSymbolName.d.ts +2 -0
  70. package/dist/enums/internalSymbolName.d.ts.map +1 -0
  71. package/dist/enums/internalSymbolName.enum.d.ts +23 -0
  72. package/dist/enums/internalSymbolName.enum.d.ts.map +1 -0
  73. package/dist/enums/internalSymbolName.enum.js +25 -0
  74. package/dist/enums/internalSymbolName.enum.js.map +1 -0
  75. package/dist/enums/internalSymbolName.js +25 -0
  76. package/dist/enums/internalSymbolName.js.map +1 -0
  77. package/dist/enums/jsxEmit.d.ts +2 -0
  78. package/dist/enums/jsxEmit.d.ts.map +1 -0
  79. package/dist/enums/jsxEmit.enum.d.ts +9 -0
  80. package/dist/enums/jsxEmit.enum.d.ts.map +1 -0
  81. package/dist/enums/jsxEmit.enum.js +11 -0
  82. package/dist/enums/jsxEmit.enum.js.map +1 -0
  83. package/dist/enums/jsxEmit.js +11 -0
  84. package/dist/enums/jsxEmit.js.map +1 -0
  85. package/dist/enums/moduleDetectionKind.d.ts +2 -0
  86. package/dist/enums/moduleDetectionKind.d.ts.map +1 -0
  87. package/dist/enums/moduleDetectionKind.enum.d.ts +7 -0
  88. package/dist/enums/moduleDetectionKind.enum.d.ts.map +1 -0
  89. package/dist/enums/moduleDetectionKind.enum.js +9 -0
  90. package/dist/enums/moduleDetectionKind.enum.js.map +1 -0
  91. package/dist/enums/moduleDetectionKind.js +9 -0
  92. package/dist/enums/moduleDetectionKind.js.map +1 -0
  93. package/dist/enums/moduleKind.d.ts +2 -0
  94. package/dist/enums/moduleKind.d.ts.map +1 -0
  95. package/dist/enums/moduleKind.enum.d.ts +17 -0
  96. package/dist/enums/moduleKind.enum.d.ts.map +1 -0
  97. package/dist/enums/moduleKind.enum.js +19 -0
  98. package/dist/enums/moduleKind.enum.js.map +1 -0
  99. package/dist/enums/moduleKind.js +19 -0
  100. package/dist/enums/moduleKind.js.map +1 -0
  101. package/dist/enums/moduleResolutionKind.d.ts +2 -0
  102. package/dist/enums/moduleResolutionKind.d.ts.map +1 -0
  103. package/dist/enums/moduleResolutionKind.enum.d.ts +9 -0
  104. package/dist/enums/moduleResolutionKind.enum.d.ts.map +1 -0
  105. package/dist/enums/moduleResolutionKind.enum.js +11 -0
  106. package/dist/enums/moduleResolutionKind.enum.js.map +1 -0
  107. package/dist/enums/moduleResolutionKind.js +11 -0
  108. package/dist/enums/moduleResolutionKind.js.map +1 -0
  109. package/dist/enums/newLineKind.d.ts +2 -0
  110. package/dist/enums/newLineKind.d.ts.map +1 -0
  111. package/dist/enums/newLineKind.enum.d.ts +6 -0
  112. package/dist/enums/newLineKind.enum.d.ts.map +1 -0
  113. package/dist/enums/newLineKind.enum.js +8 -0
  114. package/dist/enums/newLineKind.enum.js.map +1 -0
  115. package/dist/enums/newLineKind.js +8 -0
  116. package/dist/enums/newLineKind.js.map +1 -0
  117. package/dist/internal/utils.d.ts +23 -0
  118. package/dist/internal/utils.d.ts.map +1 -0
  119. package/dist/internal/utils.js +25 -0
  120. package/dist/internal/utils.js.map +1 -0
  121. package/package.json +9 -9
@@ -10,6 +10,7 @@
10
10
  import { CompletionItemKind } from "#enums/completionItemKind";
11
11
  import { DiagnosticCategory } from "#enums/diagnosticCategory";
12
12
  import { ElementFlags } from "#enums/elementFlags";
13
+ import { ModuleKind } from "#enums/moduleKind";
13
14
  import { NodeBuilderFlags } from "#enums/nodeBuilderFlags";
14
15
  import { ObjectFlags } from "#enums/objectFlags";
15
16
  import { SignatureFlags } from "#enums/signatureFlags";
@@ -17,14 +18,15 @@ import { SignatureKind } from "#enums/signatureKind";
17
18
  import { SymbolFlags } from "#enums/symbolFlags";
18
19
  import { TypeFlags } from "#enums/typeFlags";
19
20
  import { TypePredicateKind } from "#enums/typePredicateKind";
20
- import { ModifierFlags, } from "../../ast/index.js";
21
+ import { ModifierFlags, unescapeLeadingUnderscores, } from "../../ast/index.js";
21
22
  import { encodeNode, uint8ArrayToBase64, } from "../node/encoder.js";
22
23
  import { decodeNode, getNodeId, parseNodeHandle, readParseOptionsKey, readSourceFileHash, RemoteSourceFile, } from "../node/node.js";
24
+ import { Wtf8Decoder } from "../node/wtf8.js";
23
25
  import { createGetCanonicalFileName, toPath, } from "../path.js";
24
26
  import { resolveFileName, toUpdateSnapshotRequest, } from "../proto.js";
25
27
  import { SourceFileCache } from "../sourceFileCache.js";
26
28
  import { Client, } from "./client.js";
27
- export { CompletionItemKind, DiagnosticCategory, ElementFlags, ModifierFlags, NodeBuilderFlags, ObjectFlags, SignatureFlags, SignatureKind, SymbolFlags, TypeFlags, TypePredicateKind };
29
+ export { CompletionItemKind, DiagnosticCategory, ElementFlags, ModifierFlags, ModuleKind, NodeBuilderFlags, ObjectFlags, SignatureFlags, SignatureKind, SymbolFlags, TypeFlags, TypePredicateKind };
28
30
  export { documentURIToFileName, fileNameToDocumentURI } from "../path.js";
29
31
  export class API {
30
32
  client;
@@ -34,7 +36,7 @@ export class API {
34
36
  activeSnapshots = new Set();
35
37
  latestSnapshot;
36
38
  internal;
37
- constructor(options) {
39
+ constructor(options = {}) {
38
40
  this.client = new Client(options);
39
41
  this.sourceFileCache = new SourceFileCache();
40
42
  this.internal = new InternalAPI(this.client, () => this.ensureInitialized());
@@ -135,8 +137,8 @@ export class Snapshot {
135
137
  this.client = client;
136
138
  this.toPath = toPath;
137
139
  this.onDispose = onDispose;
138
- this.snapshotRegistry = new SnapshotObjectRegistry(client, this.id);
139
140
  this.projectMap = new Map();
141
+ this.snapshotRegistry = new SnapshotObjectRegistry(client, this.id, projectId => this.projectMap.get(projectId));
140
142
  for (const projData of data.projects) {
141
143
  const project = new Project(projData, this.id, client, sourceFileCache, toPath, this.snapshotRegistry);
142
144
  this.projectMap.set(toPath(projData.configFileName), project);
@@ -188,9 +190,15 @@ class SnapshotObjectRegistry {
188
190
  symbols = new Map();
189
191
  client;
190
192
  snapshotId;
191
- constructor(client, snapshotId) {
193
+ resolveProject;
194
+ constructor(client, snapshotId, resolveProject) {
192
195
  this.client = client;
193
196
  this.snapshotId = snapshotId;
197
+ this.resolveProject = resolveProject;
198
+ }
199
+ /** Resolve a project id (a config file path) to its Project within this snapshot. */
200
+ getProject(projectId) {
201
+ return this.resolveProject(projectId);
194
202
  }
195
203
  getOrCreateSymbol(data) {
196
204
  let symbol = this.symbols.get(data.id);
@@ -250,14 +258,14 @@ class SnapshotObjectRegistry {
250
258
  class ProjectObjectRegistry {
251
259
  client;
252
260
  snapshotId;
253
- projectId;
261
+ project;
254
262
  snapshotRegistry;
255
263
  types = new Map();
256
264
  signatures = new Map();
257
- constructor(client, snapshotId, projectId, snapshotRegistry) {
265
+ constructor(client, snapshotId, project, snapshotRegistry) {
258
266
  this.client = client;
259
267
  this.snapshotId = snapshotId;
260
- this.projectId = projectId;
268
+ this.project = project;
261
269
  this.snapshotRegistry = snapshotRegistry;
262
270
  }
263
271
  getOrCreateSymbol(data) {
@@ -280,7 +288,7 @@ class ProjectObjectRegistry {
280
288
  getOrCreateSignature(data) {
281
289
  let sig = this.signatures.get(data.id);
282
290
  if (!sig) {
283
- sig = new Signature(data, this);
291
+ sig = new Signature(data, this.project, this);
284
292
  this.signatures.set(data.id, sig);
285
293
  }
286
294
  return sig;
@@ -302,7 +310,7 @@ class ProjectObjectRegistry {
302
310
  }
303
311
  const data = this.client.apiRequest(method, {
304
312
  snapshot: this.snapshotId,
305
- project: this.projectId,
313
+ project: this.project.id,
306
314
  objectId: source.id,
307
315
  });
308
316
  if (!data)
@@ -310,7 +318,7 @@ class ProjectObjectRegistry {
310
318
  return this.getOrCreateType(data);
311
319
  }
312
320
  fetchSymbol(source, method, handle) {
313
- return this.snapshotRegistry.fetchSymbol(source, method, handle, this.projectId);
321
+ return this.snapshotRegistry.fetchSymbol(source, method, handle, this.project.id);
314
322
  }
315
323
  fetchSignature(source, method, handle) {
316
324
  if (!handle)
@@ -320,7 +328,7 @@ class ProjectObjectRegistry {
320
328
  return cached;
321
329
  const data = this.client.apiRequest(method, {
322
330
  snapshot: this.snapshotId,
323
- project: this.projectId,
331
+ project: this.project.id,
324
332
  objectId: source.id,
325
333
  });
326
334
  if (!data)
@@ -344,7 +352,7 @@ class ProjectObjectRegistry {
344
352
  }
345
353
  const typesData = this.client.apiRequest(method, {
346
354
  snapshot: this.snapshotId,
347
- project: this.projectId,
355
+ project: this.project.id,
348
356
  objectId: source.id,
349
357
  });
350
358
  if (typesData == null)
@@ -353,7 +361,19 @@ class ProjectObjectRegistry {
353
361
  return typesData.map(data => this.getOrCreateType(data));
354
362
  }
355
363
  fetchSymbols(source, method, handles) {
356
- return this.snapshotRegistry.fetchSymbols(source, method, handles, this.projectId);
364
+ return this.snapshotRegistry.fetchSymbols(source, method, handles, this.project.id);
365
+ }
366
+ // getBaseTypes is a checker-level endpoint keyed by `type` (not `objectId`),
367
+ // so it cannot go through fetchTypes. This helper reuses that server method.
368
+ fetchBaseTypes(source) {
369
+ const typesData = this.client.apiRequest("getBaseTypes", {
370
+ snapshot: this.snapshotId,
371
+ project: this.project.id,
372
+ type: source.id,
373
+ });
374
+ if (typesData == null)
375
+ return [];
376
+ return typesData.map(data => this.getOrCreateType(data));
357
377
  }
358
378
  }
359
379
  export class Project {
@@ -371,9 +391,9 @@ export class Project {
371
391
  this.compilerOptions = data.compilerOptions;
372
392
  this.rootFiles = data.rootFiles;
373
393
  this.client = client;
374
- this.program = new Program(snapshotId, this.id, client, sourceFileCache, toPath);
375
- const objectRegistry = new ProjectObjectRegistry(client, snapshotId, this.id, snapshotRegistry);
376
- this.checker = new Checker(snapshotId, this.id, client, objectRegistry);
394
+ this.program = new Program(snapshotId, this, client, sourceFileCache, toPath);
395
+ const objectRegistry = new ProjectObjectRegistry(client, snapshotId, this, snapshotRegistry);
396
+ this.checker = new Checker(snapshotId, this, client, objectRegistry);
377
397
  this.emitter = new Emitter(client);
378
398
  }
379
399
  dispose() {
@@ -382,30 +402,34 @@ export class Project {
382
402
  }
383
403
  export class Program {
384
404
  snapshotId;
385
- projectId;
405
+ project;
386
406
  client;
387
407
  sourceFileCache;
388
408
  toPath;
389
- decoder = new TextDecoder();
390
- constructor(snapshotId, projectId, client, sourceFileCache, toPath) {
409
+ decoder = new Wtf8Decoder();
410
+ sourceFileMetadataCache = new Map();
411
+ constructor(snapshotId, project, client, sourceFileCache, toPath) {
391
412
  this.snapshotId = snapshotId;
392
- this.projectId = projectId;
413
+ this.project = project;
393
414
  this.client = client;
394
415
  this.sourceFileCache = sourceFileCache;
395
416
  this.toPath = toPath;
396
417
  }
418
+ getCompilerOptions() {
419
+ return this.project.compilerOptions;
420
+ }
397
421
  getSourceFile(file) {
398
422
  const fileName = resolveFileName(file);
399
423
  const path = this.toPath(fileName);
400
424
  // Check if we already have a retained cache entry for this (snapshot, project) pair
401
- const retained = this.sourceFileCache.getRetained(path, this.snapshotId, this.projectId);
425
+ const retained = this.sourceFileCache.getRetained(path, this.snapshotId, this.project.id);
402
426
  if (retained) {
403
427
  return retained;
404
428
  }
405
429
  // Fetch from server
406
430
  const binaryData = this.client.apiRequestBinary("getSourceFile", {
407
431
  snapshot: this.snapshotId,
408
- project: this.projectId,
432
+ project: this.project.id,
409
433
  file,
410
434
  });
411
435
  if (!binaryData) {
@@ -416,15 +440,63 @@ export class Program {
416
440
  const parseOptionsKey = readParseOptionsKey(view);
417
441
  // Create a new RemoteSourceFile and cache it (set returns existing if hash matches)
418
442
  const sourceFile = new RemoteSourceFile(binaryData, this.decoder);
419
- return this.sourceFileCache.set(path, sourceFile, parseOptionsKey, contentHash, this.snapshotId, this.projectId);
443
+ return this.sourceFileCache.set(path, sourceFile, parseOptionsKey, contentHash, this.snapshotId, this.project.id);
420
444
  }
421
445
  getSourceFileNames() {
422
446
  const data = this.client.apiRequest("getSourceFileNames", {
423
447
  snapshot: this.snapshotId,
424
- project: this.projectId,
448
+ project: this.project.id,
425
449
  });
426
450
  return data ?? [];
427
451
  }
452
+ /**
453
+ * Returns program-stored metadata for the given source file, or `undefined` if the file
454
+ * is not part of the program. Metadata is fetched lazily per file and cached on this
455
+ * `Program` instance.
456
+ */
457
+ getSourceFileMetadata(fileName) {
458
+ return this.getSourceFileMetadataByPath(this.toPath(fileName));
459
+ }
460
+ /**
461
+ * Returns program-stored metadata for the source file at the given path, or `undefined`
462
+ * if the file is not part of the program. Like {@link getSourceFileMetadata}, but skips
463
+ * the file name to path conversion. Metadata is fetched lazily per file and cached on
464
+ * this `Program` instance.
465
+ */
466
+ getSourceFileMetadataByPath(path) {
467
+ let metadata = this.sourceFileMetadataCache.get(path);
468
+ if (metadata === undefined) {
469
+ metadata = this.fetchSourceFileMetadata(path);
470
+ this.sourceFileMetadataCache.set(path, metadata);
471
+ }
472
+ return metadata;
473
+ }
474
+ fetchSourceFileMetadata(path) {
475
+ const data = this.client.apiRequest("getSourceFileMetadata", {
476
+ snapshot: this.snapshotId,
477
+ project: this.project.id,
478
+ file: path,
479
+ });
480
+ return data ?? undefined;
481
+ }
482
+ /**
483
+ * Returns whether the given source file was loaded as part of an external library
484
+ * (e.g. a dependency resolved from `node_modules`). The underlying program metadata is
485
+ * fetched lazily per file and cached on this `Program` instance.
486
+ */
487
+ isSourceFileFromExternalLibrary(file) {
488
+ const metadata = this.getSourceFileMetadataByPath(file.path);
489
+ return metadata?.isFromExternalLibrary ?? false;
490
+ }
491
+ /**
492
+ * Returns whether the given source file is a default library file (e.g. `lib.d.ts`).
493
+ * The underlying program metadata is fetched lazily per file and cached on this
494
+ * `Program` instance.
495
+ */
496
+ isSourceFileDefaultLibrary(file) {
497
+ const metadata = this.getSourceFileMetadataByPath(file.path);
498
+ return metadata?.isDefaultLibrary ?? false;
499
+ }
428
500
  /**
429
501
  * Get syntactic (parse) diagnostics for a specific file or all files.
430
502
  * @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.
@@ -432,7 +504,7 @@ export class Program {
432
504
  getSyntacticDiagnostics(file) {
433
505
  const data = this.client.apiRequest("getSyntacticDiagnostics", {
434
506
  snapshot: this.snapshotId,
435
- project: this.projectId,
507
+ project: this.project.id,
436
508
  ...(file !== undefined ? { file } : {}),
437
509
  });
438
510
  return data ?? [];
@@ -444,7 +516,7 @@ export class Program {
444
516
  getBindDiagnostics(file) {
445
517
  const data = this.client.apiRequest("getBindDiagnostics", {
446
518
  snapshot: this.snapshotId,
447
- project: this.projectId,
519
+ project: this.project.id,
448
520
  ...(file !== undefined ? { file } : {}),
449
521
  });
450
522
  return data ?? [];
@@ -456,7 +528,7 @@ export class Program {
456
528
  getSemanticDiagnostics(file) {
457
529
  const data = this.client.apiRequest("getSemanticDiagnostics", {
458
530
  snapshot: this.snapshotId,
459
- project: this.projectId,
531
+ project: this.project.id,
460
532
  ...(file !== undefined ? { file } : {}),
461
533
  });
462
534
  return data ?? [];
@@ -468,7 +540,7 @@ export class Program {
468
540
  getSuggestionDiagnostics(file) {
469
541
  const data = this.client.apiRequest("getSuggestionDiagnostics", {
470
542
  snapshot: this.snapshotId,
471
- project: this.projectId,
543
+ project: this.project.id,
472
544
  ...(file !== undefined ? { file } : {}),
473
545
  });
474
546
  return data ?? [];
@@ -480,7 +552,7 @@ export class Program {
480
552
  getDeclarationDiagnostics(file) {
481
553
  const data = this.client.apiRequest("getDeclarationDiagnostics", {
482
554
  snapshot: this.snapshotId,
483
- project: this.projectId,
555
+ project: this.project.id,
484
556
  ...(file !== undefined ? { file } : {}),
485
557
  });
486
558
  return data ?? [];
@@ -491,7 +563,7 @@ export class Program {
491
563
  getProgramDiagnostics() {
492
564
  const data = this.client.apiRequest("getProgramDiagnostics", {
493
565
  snapshot: this.snapshotId,
494
- project: this.projectId,
566
+ project: this.project.id,
495
567
  });
496
568
  return data ?? [];
497
569
  }
@@ -501,7 +573,7 @@ export class Program {
501
573
  getGlobalDiagnostics() {
502
574
  const data = this.client.apiRequest("getGlobalDiagnostics", {
503
575
  snapshot: this.snapshotId,
504
- project: this.projectId,
576
+ project: this.project.id,
505
577
  });
506
578
  return data ?? [];
507
579
  }
@@ -511,19 +583,20 @@ export class Program {
511
583
  getConfigFileParsingDiagnostics() {
512
584
  const data = this.client.apiRequest("getConfigFileParsingDiagnostics", {
513
585
  snapshot: this.snapshotId,
514
- project: this.projectId,
586
+ project: this.project.id,
515
587
  });
516
588
  return data ?? [];
517
589
  }
518
590
  }
519
591
  export class Checker {
520
592
  snapshotId;
521
- projectId;
593
+ project;
522
594
  client;
523
595
  objectRegistry;
524
- constructor(snapshotId, projectId, client, objectRegistry) {
596
+ wellKnownSymbols;
597
+ constructor(snapshotId, project, client, objectRegistry) {
525
598
  this.snapshotId = snapshotId;
526
- this.projectId = projectId;
599
+ this.project = project;
527
600
  this.client = client;
528
601
  this.objectRegistry = objectRegistry;
529
602
  }
@@ -534,14 +607,14 @@ export class Checker {
534
607
  if (Array.isArray(nodeOrNodes)) {
535
608
  const data = this.client.apiRequest("getSymbolsAtLocations", {
536
609
  snapshot: this.snapshotId,
537
- project: this.projectId,
610
+ project: this.project.id,
538
611
  locations: nodeOrNodes.map(node => getNodeId(node)),
539
612
  });
540
613
  return data.map(d => d ? this.objectRegistry.getOrCreateSymbol(d) : undefined);
541
614
  }
542
615
  const data = this.client.apiRequest("getSymbolAtLocation", {
543
616
  snapshot: this.snapshotId,
544
- project: this.projectId,
617
+ project: this.project.id,
545
618
  location: getNodeId(nodeOrNodes),
546
619
  });
547
620
  return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
@@ -550,7 +623,7 @@ export class Checker {
550
623
  if (typeof positionOrPositions === "number") {
551
624
  const data = this.client.apiRequest("getSymbolAtPosition", {
552
625
  snapshot: this.snapshotId,
553
- project: this.projectId,
626
+ project: this.project.id,
554
627
  file,
555
628
  position: positionOrPositions,
556
629
  });
@@ -558,7 +631,7 @@ export class Checker {
558
631
  }
559
632
  const data = this.client.apiRequest("getSymbolsAtPositions", {
560
633
  snapshot: this.snapshotId,
561
- project: this.projectId,
634
+ project: this.project.id,
562
635
  file,
563
636
  positions: positionOrPositions,
564
637
  });
@@ -568,63 +641,70 @@ export class Checker {
568
641
  if (Array.isArray(symbolOrSymbols)) {
569
642
  const data = this.client.apiRequest("getTypesOfSymbols", {
570
643
  snapshot: this.snapshotId,
571
- project: this.projectId,
644
+ project: this.project.id,
572
645
  symbols: symbolOrSymbols.map(s => s.id),
573
646
  });
574
647
  return data.map(d => d ? this.objectRegistry.getOrCreateType(d) : undefined);
575
648
  }
576
649
  const data = this.client.apiRequest("getTypeOfSymbol", {
577
650
  snapshot: this.snapshotId,
578
- project: this.projectId,
651
+ project: this.project.id,
579
652
  symbol: symbolOrSymbols.id,
580
653
  });
581
654
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
582
655
  }
656
+ /**
657
+ * Get the declared type of a symbol. Always returns a type; for symbols whose
658
+ * declared type cannot be determined the checker yields the error type (use
659
+ * {@link Type.isErrorType} to detect it).
660
+ */
583
661
  getDeclaredTypeOfSymbol(symbol) {
584
662
  const data = this.client.apiRequest("getDeclaredTypeOfSymbol", {
585
663
  snapshot: this.snapshotId,
586
- project: this.projectId,
664
+ project: this.project.id,
587
665
  symbol: symbol.id,
588
666
  });
589
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
667
+ if (!data)
668
+ throw new Error(`getDeclaredTypeOfSymbol returned no type for symbol ${symbol.id}`);
669
+ return this.objectRegistry.getOrCreateType(data);
590
670
  }
591
671
  getReferencesToSymbolInFile(file, symbol) {
592
672
  const data = this.client.apiRequest("getReferencesToSymbolInFile", {
593
673
  snapshot: this.snapshotId,
594
- project: this.projectId,
674
+ project: this.project.id,
595
675
  file,
596
676
  symbol: symbol.id,
597
677
  });
598
- return (data ?? []).map(h => new NodeHandle(h));
678
+ return (data ?? []).map(h => new NodeHandle(h, this.project));
599
679
  }
600
680
  getReferencedSymbolsForNode(node, position) {
601
681
  const data = this.client.apiRequest("getReferencedSymbolsForNode", {
602
682
  snapshot: this.snapshotId,
603
- project: this.projectId,
683
+ project: this.project.id,
604
684
  node: getNodeId(node),
605
685
  position,
606
686
  });
607
687
  return (data ?? []).map(entry => ({
608
- definition: new NodeHandle(entry.definition),
688
+ definition: new NodeHandle(entry.definition, this.project),
609
689
  symbol: entry.symbol ? this.objectRegistry.getOrCreateSymbol(entry.symbol) : undefined,
610
- references: (entry.references ?? []).map(h => new NodeHandle(h)),
690
+ references: (entry.references ?? []).map(h => new NodeHandle(h, this.project)),
611
691
  }));
612
692
  }
613
693
  getSignatureUsage(signatureDecl) {
614
694
  const data = this.client.apiRequest("getSignatureUsages", {
615
695
  snapshot: this.snapshotId,
616
- project: this.projectId,
696
+ project: this.project.id,
617
697
  signatureDecl: getNodeId(signatureDecl),
618
698
  });
619
699
  return (data ?? []).map(entry => ({
620
- name: new NodeHandle(entry.name),
621
- call: entry.call ? new NodeHandle(entry.call) : undefined,
700
+ name: new NodeHandle(entry.name, this.project),
701
+ call: entry.call ? new NodeHandle(entry.call, this.project) : undefined,
622
702
  }));
623
703
  }
624
704
  getCompletionsAtPosition(document, position, options) {
625
705
  const data = this.client.apiRequest("getCompletionsAtPosition", {
626
706
  snapshot: this.snapshotId,
627
- project: this.projectId,
707
+ project: this.project.id,
628
708
  file: document,
629
709
  position,
630
710
  triggerCharacter: options?.triggerCharacter,
@@ -644,14 +724,14 @@ export class Checker {
644
724
  if (Array.isArray(nodeOrNodes)) {
645
725
  const data = this.client.apiRequest("getTypeAtLocations", {
646
726
  snapshot: this.snapshotId,
647
- project: this.projectId,
727
+ project: this.project.id,
648
728
  locations: nodeOrNodes.map(node => getNodeId(node)),
649
729
  });
650
730
  return data.map(d => d ? this.objectRegistry.getOrCreateType(d) : undefined);
651
731
  }
652
732
  const data = this.client.apiRequest("getTypeAtLocation", {
653
733
  snapshot: this.snapshotId,
654
- project: this.projectId,
734
+ project: this.project.id,
655
735
  location: getNodeId(nodeOrNodes),
656
736
  });
657
737
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
@@ -659,7 +739,7 @@ export class Checker {
659
739
  getSignaturesOfType(type, kind) {
660
740
  const data = this.client.apiRequest("getSignaturesOfType", {
661
741
  snapshot: this.snapshotId,
662
- project: this.projectId,
742
+ project: this.project.id,
663
743
  type: type.id,
664
744
  kind,
665
745
  });
@@ -668,7 +748,7 @@ export class Checker {
668
748
  getResolvedSignature(node) {
669
749
  const data = this.client.apiRequest("getResolvedSignature", {
670
750
  snapshot: this.snapshotId,
671
- project: this.projectId,
751
+ project: this.project.id,
672
752
  location: getNodeId(node),
673
753
  });
674
754
  return data ? this.objectRegistry.getOrCreateSignature(data) : undefined;
@@ -677,7 +757,7 @@ export class Checker {
677
757
  if (typeof positionOrPositions === "number") {
678
758
  const data = this.client.apiRequest("getTypeAtPosition", {
679
759
  snapshot: this.snapshotId,
680
- project: this.projectId,
760
+ project: this.project.id,
681
761
  file,
682
762
  position: positionOrPositions,
683
763
  });
@@ -685,7 +765,7 @@ export class Checker {
685
765
  }
686
766
  const data = this.client.apiRequest("getTypesAtPositions", {
687
767
  snapshot: this.snapshotId,
688
- project: this.projectId,
768
+ project: this.project.id,
689
769
  file,
690
770
  positions: positionOrPositions,
691
771
  });
@@ -696,7 +776,7 @@ export class Checker {
696
776
  const isNode = location && "kind" in location;
697
777
  const data = this.client.apiRequest("resolveName", {
698
778
  snapshot: this.snapshotId,
699
- project: this.projectId,
779
+ project: this.project.id,
700
780
  name,
701
781
  meaning,
702
782
  location: isNode ? getNodeId(location) : undefined,
@@ -715,7 +795,7 @@ export class Checker {
715
795
  getContextualType(node) {
716
796
  const data = this.client.apiRequest("getContextualType", {
717
797
  snapshot: this.snapshotId,
718
- project: this.projectId,
798
+ project: this.project.id,
719
799
  location: getNodeId(node),
720
800
  });
721
801
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
@@ -723,7 +803,7 @@ export class Checker {
723
803
  getBaseTypeOfLiteralType(type) {
724
804
  const data = this.client.apiRequest("getBaseTypeOfLiteralType", {
725
805
  snapshot: this.snapshotId,
726
- project: this.projectId,
806
+ project: this.project.id,
727
807
  type: type.id,
728
808
  });
729
809
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
@@ -731,7 +811,7 @@ export class Checker {
731
811
  getNonNullableType(type) {
732
812
  const data = this.client.apiRequest("getNonNullableType", {
733
813
  snapshot: this.snapshotId,
734
- project: this.projectId,
814
+ project: this.project.id,
735
815
  type: type.id,
736
816
  });
737
817
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
@@ -739,7 +819,7 @@ export class Checker {
739
819
  getTypeFromTypeNode(node) {
740
820
  const data = this.client.apiRequest("getTypeFromTypeNode", {
741
821
  snapshot: this.snapshotId,
742
- project: this.projectId,
822
+ project: this.project.id,
743
823
  location: getNodeId(node),
744
824
  });
745
825
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
@@ -747,7 +827,7 @@ export class Checker {
747
827
  getWidenedType(type) {
748
828
  const data = this.client.apiRequest("getWidenedType", {
749
829
  snapshot: this.snapshotId,
750
- project: this.projectId,
830
+ project: this.project.id,
751
831
  type: type.id,
752
832
  });
753
833
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
@@ -755,7 +835,7 @@ export class Checker {
755
835
  getParameterType(signature, index) {
756
836
  const data = this.client.apiRequest("getParameterType", {
757
837
  snapshot: this.snapshotId,
758
- project: this.projectId,
838
+ project: this.project.id,
759
839
  signature: signature.id,
760
840
  index,
761
841
  });
@@ -764,14 +844,14 @@ export class Checker {
764
844
  isArrayLikeType(type) {
765
845
  return this.client.apiRequest("isArrayLikeType", {
766
846
  snapshot: this.snapshotId,
767
- project: this.projectId,
847
+ project: this.project.id,
768
848
  type: type.id,
769
849
  });
770
850
  }
771
851
  isTypeAssignableTo(source, target) {
772
852
  return this.client.apiRequest("isTypeAssignableTo", {
773
853
  snapshot: this.snapshotId,
774
- project: this.projectId,
854
+ project: this.project.id,
775
855
  source: source.id,
776
856
  target: target.id,
777
857
  });
@@ -779,24 +859,31 @@ export class Checker {
779
859
  getShorthandAssignmentValueSymbol(node) {
780
860
  const data = this.client.apiRequest("getShorthandAssignmentValueSymbol", {
781
861
  snapshot: this.snapshotId,
782
- project: this.projectId,
862
+ project: this.project.id,
783
863
  location: getNodeId(node),
784
864
  });
785
865
  return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
786
866
  }
867
+ /**
868
+ * Get the type of a symbol as narrowed at a specific location. Always returns
869
+ * a type; for symbols whose type cannot be determined the checker yields the
870
+ * error type (use {@link Type.isErrorType} to detect it).
871
+ */
787
872
  getTypeOfSymbolAtLocation(symbol, location) {
788
873
  const data = this.client.apiRequest("getTypeOfSymbolAtLocation", {
789
874
  snapshot: this.snapshotId,
790
- project: this.projectId,
875
+ project: this.project.id,
791
876
  symbol: symbol.id,
792
877
  location: getNodeId(location),
793
878
  });
794
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
879
+ if (!data)
880
+ throw new Error(`getTypeOfSymbolAtLocation returned no type for symbol ${symbol.id}`);
881
+ return this.objectRegistry.getOrCreateType(data);
795
882
  }
796
883
  getIntrinsicType(method) {
797
884
  const data = this.client.apiRequest(method, {
798
885
  snapshot: this.snapshotId,
799
- project: this.projectId,
886
+ project: this.project.id,
800
887
  });
801
888
  return this.objectRegistry.getOrCreateType(data);
802
889
  }
@@ -836,7 +923,7 @@ export class Checker {
836
923
  typeToTypeNode(type, enclosingDeclaration, flags) {
837
924
  const binaryData = this.client.apiRequestBinary("typeToTypeNode", {
838
925
  snapshot: this.snapshotId,
839
- project: this.projectId,
926
+ project: this.project.id,
840
927
  type: type.id,
841
928
  location: enclosingDeclaration ? getNodeId(enclosingDeclaration) : undefined,
842
929
  flags,
@@ -848,7 +935,7 @@ export class Checker {
848
935
  signatureToSignatureDeclaration(signature, kind, enclosingDeclaration, flags) {
849
936
  const binaryData = this.client.apiRequestBinary("signatureToSignatureDeclaration", {
850
937
  snapshot: this.snapshotId,
851
- project: this.projectId,
938
+ project: this.project.id,
852
939
  signature: signature.id,
853
940
  kind,
854
941
  location: enclosingDeclaration ? getNodeId(enclosingDeclaration) : undefined,
@@ -861,7 +948,7 @@ export class Checker {
861
948
  typeToString(type, enclosingDeclaration, flags) {
862
949
  return this.client.apiRequest("typeToString", {
863
950
  snapshot: this.snapshotId,
864
- project: this.projectId,
951
+ project: this.project.id,
865
952
  type: type.id,
866
953
  location: enclosingDeclaration ? getNodeId(enclosingDeclaration) : undefined,
867
954
  flags,
@@ -870,28 +957,28 @@ export class Checker {
870
957
  isContextSensitive(node) {
871
958
  return this.client.apiRequest("isContextSensitive", {
872
959
  snapshot: this.snapshotId,
873
- project: this.projectId,
960
+ project: this.project.id,
874
961
  location: getNodeId(node),
875
962
  });
876
963
  }
877
964
  isArrayType(type) {
878
965
  return this.client.apiRequest("isArrayType", {
879
966
  snapshot: this.snapshotId,
880
- project: this.projectId,
967
+ project: this.project.id,
881
968
  type: type.id,
882
969
  });
883
970
  }
884
971
  isTupleType(type) {
885
972
  return this.client.apiRequest("isTupleType", {
886
973
  snapshot: this.snapshotId,
887
- project: this.projectId,
974
+ project: this.project.id,
888
975
  type: type.id,
889
976
  });
890
977
  }
891
978
  getReturnTypeOfSignature(signature) {
892
979
  const data = this.client.apiRequest("getReturnTypeOfSignature", {
893
980
  snapshot: this.snapshotId,
894
- project: this.projectId,
981
+ project: this.project.id,
895
982
  signature: signature.id,
896
983
  });
897
984
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
@@ -899,7 +986,7 @@ export class Checker {
899
986
  getRestTypeOfSignature(signature) {
900
987
  const data = this.client.apiRequest("getRestTypeOfSignature", {
901
988
  snapshot: this.snapshotId,
902
- project: this.projectId,
989
+ project: this.project.id,
903
990
  signature: signature.id,
904
991
  });
905
992
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
@@ -907,7 +994,7 @@ export class Checker {
907
994
  getTypePredicateOfSignature(signature) {
908
995
  const data = this.client.apiRequest("getTypePredicateOfSignature", {
909
996
  snapshot: this.snapshotId,
910
- project: this.projectId,
997
+ project: this.project.id,
911
998
  signature: signature.id,
912
999
  });
913
1000
  if (!data)
@@ -926,7 +1013,7 @@ export class Checker {
926
1013
  getBaseTypes(type) {
927
1014
  const data = this.client.apiRequest("getBaseTypes", {
928
1015
  snapshot: this.snapshotId,
929
- project: this.projectId,
1016
+ project: this.project.id,
930
1017
  type: type.id,
931
1018
  });
932
1019
  return data ? data.map(d => this.objectRegistry.getOrCreateType(d)) : [];
@@ -934,7 +1021,7 @@ export class Checker {
934
1021
  getApparentType(type) {
935
1022
  const data = this.client.apiRequest("getApparentType", {
936
1023
  snapshot: this.snapshotId,
937
- project: this.projectId,
1024
+ project: this.project.id,
938
1025
  type: type.id,
939
1026
  });
940
1027
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
@@ -942,7 +1029,7 @@ export class Checker {
942
1029
  getPropertiesOfType(type) {
943
1030
  const data = this.client.apiRequest("getPropertiesOfType", {
944
1031
  snapshot: this.snapshotId,
945
- project: this.projectId,
1032
+ project: this.project.id,
946
1033
  type: type.id,
947
1034
  });
948
1035
  return data ? data.map(d => this.objectRegistry.getOrCreateSymbol(d)) : [];
@@ -950,7 +1037,7 @@ export class Checker {
950
1037
  getIndexInfosOfType(type) {
951
1038
  const data = this.client.apiRequest("getIndexInfosOfType", {
952
1039
  snapshot: this.snapshotId,
953
- project: this.projectId,
1040
+ project: this.project.id,
954
1041
  type: type.id,
955
1042
  });
956
1043
  if (!data)
@@ -959,7 +1046,7 @@ export class Checker {
959
1046
  keyType: this.objectRegistry.getOrCreateType(d.keyType),
960
1047
  valueType: this.objectRegistry.getOrCreateType(d.valueType),
961
1048
  isReadonly: d.isReadonly ?? false,
962
- declaration: d.declaration ? new NodeHandle(d.declaration) : undefined,
1049
+ declaration: d.declaration ? new NodeHandle(d.declaration, this.project) : undefined,
963
1050
  }));
964
1051
  }
965
1052
  /**
@@ -969,7 +1056,7 @@ export class Checker {
969
1056
  getConstraintOfTypeParameter(type) {
970
1057
  const data = this.client.apiRequest("getConstraintOfTypeParameter", {
971
1058
  snapshot: this.snapshotId,
972
- project: this.projectId,
1059
+ project: this.project.id,
973
1060
  type: type.id,
974
1061
  });
975
1062
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
@@ -977,7 +1064,7 @@ export class Checker {
977
1064
  getBaseConstraintOfType(type) {
978
1065
  const data = this.client.apiRequest("getBaseConstraintOfType", {
979
1066
  snapshot: this.snapshotId,
980
- project: this.projectId,
1067
+ project: this.project.id,
981
1068
  type: type.id,
982
1069
  });
983
1070
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
@@ -985,7 +1072,7 @@ export class Checker {
985
1072
  getPropertyOfType(type, name) {
986
1073
  const data = this.client.apiRequest("getPropertyOfType", {
987
1074
  snapshot: this.snapshotId,
988
- project: this.projectId,
1075
+ project: this.project.id,
989
1076
  type: type.id,
990
1077
  name,
991
1078
  });
@@ -994,7 +1081,7 @@ export class Checker {
994
1081
  getConstantValue(node) {
995
1082
  const data = this.client.apiRequest("getConstantValue", {
996
1083
  snapshot: this.snapshotId,
997
- project: this.projectId,
1084
+ project: this.project.id,
998
1085
  location: getNodeId(node),
999
1086
  });
1000
1087
  return data ?? undefined;
@@ -1002,7 +1089,7 @@ export class Checker {
1002
1089
  getSignatureFromDeclaration(node) {
1003
1090
  const data = this.client.apiRequest("getSignatureFromDeclaration", {
1004
1091
  snapshot: this.snapshotId,
1005
- project: this.projectId,
1092
+ project: this.project.id,
1006
1093
  location: getNodeId(node),
1007
1094
  });
1008
1095
  return data ? this.objectRegistry.getOrCreateSignature(data) : undefined;
@@ -1010,31 +1097,69 @@ export class Checker {
1010
1097
  getExportSpecifierLocalTargetSymbol(node) {
1011
1098
  const data = this.client.apiRequest("getExportSpecifierLocalTargetSymbol", {
1012
1099
  snapshot: this.snapshotId,
1013
- project: this.projectId,
1100
+ project: this.project.id,
1014
1101
  location: getNodeId(node),
1015
1102
  });
1016
1103
  return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
1017
1104
  }
1105
+ /**
1106
+ * Follow all aliases to get the original symbol. Always returns a symbol; for
1107
+ * an unresolved alias the checker yields the unknown symbol (use
1108
+ * {@link Checker.isUnknownSymbol} to detect it).
1109
+ */
1018
1110
  getAliasedSymbol(symbol) {
1019
1111
  const data = this.client.apiRequest("getAliasedSymbol", {
1020
1112
  snapshot: this.snapshotId,
1021
- project: this.projectId,
1113
+ project: this.project.id,
1022
1114
  symbol: symbol.id,
1023
1115
  });
1024
- return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
1116
+ if (!data)
1117
+ throw new Error(`getAliasedSymbol returned no symbol for symbol ${symbol.id}`);
1118
+ return this.objectRegistry.getOrCreateSymbol(data);
1025
1119
  }
1026
1120
  getImmediateAliasedSymbol(symbol) {
1027
1121
  const data = this.client.apiRequest("getImmediateAliasedSymbol", {
1028
1122
  snapshot: this.snapshotId,
1029
- project: this.projectId,
1123
+ project: this.project.id,
1030
1124
  symbol: symbol.id,
1031
1125
  });
1032
1126
  return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
1033
1127
  }
1128
+ /**
1129
+ * Fetch (once, then cache) the handle ids of the per-checker singleton
1130
+ * symbols (unknown, undefined, arguments). These ids are stable for the life
1131
+ * of the project's checker, so identity checks against them are local after
1132
+ * the first call.
1133
+ */
1134
+ getWellKnownSymbols() {
1135
+ return this.wellKnownSymbols ??= this.client.apiRequest("getWellKnownSymbols", {
1136
+ snapshot: this.snapshotId,
1137
+ project: this.project.id,
1138
+ });
1139
+ }
1140
+ /**
1141
+ * Returns `true` if the symbol is the checker's "unknown" symbol (e.g. the
1142
+ * result of {@link Checker.getAliasedSymbol} on an unresolved alias).
1143
+ */
1144
+ isUnknownSymbol(symbol) {
1145
+ return symbol.id === (this.getWellKnownSymbols()).unknown;
1146
+ }
1147
+ /**
1148
+ * Returns `true` if the symbol is the checker's "undefined" symbol.
1149
+ */
1150
+ isUndefinedSymbol(symbol) {
1151
+ return symbol.id === (this.getWellKnownSymbols()).undefined;
1152
+ }
1153
+ /**
1154
+ * Returns `true` if the symbol is the checker's "arguments" symbol.
1155
+ */
1156
+ isArgumentsSymbol(symbol) {
1157
+ return symbol.id === (this.getWellKnownSymbols()).arguments;
1158
+ }
1034
1159
  getExportsOfModule(symbol) {
1035
1160
  const data = this.client.apiRequest("getExportsOfModule", {
1036
1161
  snapshot: this.snapshotId,
1037
- project: this.projectId,
1162
+ project: this.project.id,
1038
1163
  symbol: symbol.id,
1039
1164
  });
1040
1165
  return data ? data.map(d => this.objectRegistry.getOrCreateSymbol(d)) : [];
@@ -1042,7 +1167,7 @@ export class Checker {
1042
1167
  getMemberInModuleExports(symbol, name) {
1043
1168
  const data = this.client.apiRequest("getMemberInModuleExports", {
1044
1169
  snapshot: this.snapshotId,
1045
- project: this.projectId,
1170
+ project: this.project.id,
1046
1171
  symbol: symbol.id,
1047
1172
  name,
1048
1173
  });
@@ -1051,7 +1176,7 @@ export class Checker {
1051
1176
  getJsDocTagsOfSymbol(symbol) {
1052
1177
  const data = this.client.apiRequest("getJsDocTags", {
1053
1178
  snapshot: this.snapshotId,
1054
- project: this.projectId,
1179
+ project: this.project.id,
1055
1180
  symbol: symbol.id,
1056
1181
  });
1057
1182
  return data ?? [];
@@ -1059,7 +1184,7 @@ export class Checker {
1059
1184
  getDocumentationCommentOfSymbol(symbol) {
1060
1185
  return this.client.apiRequest("getDocumentationComment", {
1061
1186
  snapshot: this.snapshotId,
1062
- project: this.projectId,
1187
+ project: this.project.id,
1063
1188
  symbol: symbol.id,
1064
1189
  });
1065
1190
  }
@@ -1069,7 +1194,7 @@ export class Checker {
1069
1194
  getTypeArguments(type) {
1070
1195
  const data = this.client.apiRequest("getTypeArguments", {
1071
1196
  snapshot: this.snapshotId,
1072
- project: this.projectId,
1197
+ project: this.project.id,
1073
1198
  type: type.id,
1074
1199
  });
1075
1200
  return data ? data.map(d => this.objectRegistry.getOrCreateType(d)) : [];
@@ -1090,20 +1215,28 @@ export class Emitter {
1090
1215
  }
1091
1216
  }
1092
1217
  export class NodeHandle {
1218
+ /**
1219
+ * The project this handle was produced in, used as the default for {@link resolve}.
1220
+ * Node handles are only meaningful within a project's program, so the producing project
1221
+ * is remembered so callers don't have to pass it explicitly.
1222
+ */
1223
+ canonicalProject;
1093
1224
  index;
1094
1225
  kind;
1095
1226
  path;
1096
- constructor(handle) {
1227
+ constructor(handle, canonicalProject) {
1097
1228
  const parsed = parseNodeHandle(handle);
1098
1229
  this.index = parsed.index;
1099
1230
  this.kind = parsed.kind;
1100
1231
  this.path = parsed.path;
1232
+ this.canonicalProject = canonicalProject;
1101
1233
  }
1102
1234
  /**
1103
- * Resolve this handle to the actual AST node by fetching the source file
1104
- * from the given project and looking up the node by index.
1235
+ * Resolve this handle to the actual AST node by fetching the source file from a project
1236
+ * and looking up the node by index. If no project is passed, the project that produced
1237
+ * the handle is used.
1105
1238
  */
1106
- resolve(project) {
1239
+ resolve(project = this.canonicalProject) {
1107
1240
  const sourceFile = project.program.getSourceFile(this.path);
1108
1241
  if (!sourceFile) {
1109
1242
  return undefined;
@@ -1113,7 +1246,16 @@ export class NodeHandle {
1113
1246
  }
1114
1247
  export class Symbol {
1115
1248
  objectRegistry;
1249
+ /**
1250
+ * The project this symbol was first observed in, used as the default project for
1251
+ * lookups that need a project context (members/exports/parent). Symbols are shared
1252
+ * snapshot-wide, so these lookups can otherwise be ambiguous about which project to use.
1253
+ */
1254
+ canonicalProject;
1116
1255
  id;
1256
+ /** The escaped (`__String`) name, used as the key in member/export tables. */
1257
+ escapedName;
1258
+ /** The display name (escaped underscores removed). */
1117
1259
  name;
1118
1260
  flags;
1119
1261
  checkFlags;
@@ -1121,32 +1263,56 @@ export class Symbol {
1121
1263
  valueDeclaration;
1122
1264
  parent;
1123
1265
  exportSymbol;
1266
+ membersCache;
1267
+ exportsCache;
1124
1268
  constructor(data, objectRegistry) {
1125
1269
  this.objectRegistry = objectRegistry;
1126
1270
  this.id = data.id;
1127
- this.name = data.name;
1271
+ this.escapedName = data.name;
1272
+ this.name = unescapeLeadingUnderscores(data.name);
1128
1273
  this.flags = data.flags;
1129
1274
  this.checkFlags = data.checkFlags;
1130
- this.declarations = (data.declarations ?? []).map(d => new NodeHandle(d));
1131
- this.valueDeclaration = data.valueDeclaration ? new NodeHandle(data.valueDeclaration) : undefined;
1275
+ const canonicalProject = objectRegistry.getProject(data.project);
1276
+ if (!canonicalProject) {
1277
+ throw new Error(`Symbol ${data.id} references unknown canonical project '${data.project}'`);
1278
+ }
1279
+ this.canonicalProject = canonicalProject;
1280
+ this.declarations = (data.declarations ?? []).map(d => new NodeHandle(d, canonicalProject));
1281
+ this.valueDeclaration = data.valueDeclaration ? new NodeHandle(data.valueDeclaration, canonicalProject) : undefined;
1132
1282
  if (data.parent !== undefined)
1133
1283
  this.parent = data.parent;
1134
1284
  if (data.exportSymbol !== undefined)
1135
1285
  this.exportSymbol = data.exportSymbol;
1136
1286
  }
1137
1287
  getParent() {
1138
- return this.objectRegistry.fetchSymbol(this, "getParentOfSymbol", this.parent);
1288
+ return this.objectRegistry.fetchSymbol(this, "getParentOfSymbol", this.parent, this.canonicalProject.id);
1139
1289
  }
1290
+ /**
1291
+ * Get this symbol's members keyed by escaped name. The result is cached on
1292
+ * the symbol, so repeated calls do not round-trip to the server.
1293
+ */
1140
1294
  getMembers() {
1141
- return this.objectRegistry.fetchSymbols(this, "getMembersOfSymbol");
1295
+ return this.membersCache ??= this.fetchSymbolTable("getMembersOfSymbol");
1142
1296
  }
1297
+ /**
1298
+ * Get this symbol's exports keyed by escaped name. The result is cached on
1299
+ * the symbol, so repeated calls do not round-trip to the server.
1300
+ */
1143
1301
  getExports() {
1144
- return this.objectRegistry.fetchSymbols(this, "getExportsOfSymbol");
1302
+ return this.exportsCache ??= this.fetchSymbolTable("getExportsOfSymbol");
1303
+ }
1304
+ fetchSymbolTable(method) {
1305
+ const symbols = this.objectRegistry.fetchSymbols(this, method, undefined, this.canonicalProject.id);
1306
+ const table = new Map();
1307
+ for (const symbol of symbols) {
1308
+ table.set(symbol.escapedName, symbol);
1309
+ }
1310
+ return table;
1145
1311
  }
1146
1312
  getExportSymbol() {
1147
1313
  if (!this.exportSymbol)
1148
1314
  return this;
1149
- return this.objectRegistry.fetchSymbol(this, "getExportSymbolOfSymbol", this.exportSymbol);
1315
+ return this.objectRegistry.fetchSymbol(this, "getExportSymbolOfSymbol", this.exportSymbol, this.canonicalProject.id);
1150
1316
  }
1151
1317
  getJsDocTags(checker) {
1152
1318
  return checker.getJsDocTagsOfSymbol(this);
@@ -1300,6 +1466,19 @@ class TypeObject {
1300
1466
  this.falseType = result.id;
1301
1467
  return result;
1302
1468
  }
1469
+ /**
1470
+ * Get the base types of this type. Returns `undefined` for any type that is
1471
+ * not a class or interface.
1472
+ */
1473
+ getBaseTypes() {
1474
+ if (!this.isClassOrInterface()) {
1475
+ return undefined;
1476
+ }
1477
+ return this.objectRegistry.fetchBaseTypes(this);
1478
+ }
1479
+ isClassOrInterface() {
1480
+ return isClassOrInterfaceType(this);
1481
+ }
1303
1482
  isUnionType() {
1304
1483
  return isUnionType(this);
1305
1484
  }
@@ -1312,6 +1491,9 @@ class TypeObject {
1312
1491
  isIntrinsicType() {
1313
1492
  return isIntrinsicType(this);
1314
1493
  }
1494
+ isErrorType() {
1495
+ return isErrorType(this);
1496
+ }
1315
1497
  isLiteralType() {
1316
1498
  return isLiteralType(this);
1317
1499
  }
@@ -1364,9 +1546,21 @@ export function isIntersectionType(type) {
1364
1546
  export function isObjectType(type) {
1365
1547
  return (type.flags & TypeFlags.Object) !== 0;
1366
1548
  }
1549
+ export function isClassOrInterfaceType(type) {
1550
+ return isObjectType(type) && (type.objectFlags & ObjectFlags.ClassOrInterface) !== 0;
1551
+ }
1367
1552
  export function isIntrinsicType(type) {
1368
1553
  return (type.flags & TypeFlags.Intrinsic) !== 0;
1369
1554
  }
1555
+ /**
1556
+ * Whether this is the error type — the placeholder the checker produces when a
1557
+ * type cannot be determined (e.g. an unresolved reference). It is an intrinsic
1558
+ * type named `"error"` (this covers both the singleton error type and the
1559
+ * per-alias error types manufactured for unresolved type alias references).
1560
+ */
1561
+ export function isErrorType(type) {
1562
+ return isIntrinsicType(type) && type.intrinsicName === "error";
1563
+ }
1370
1564
  export function isLiteralType(type) {
1371
1565
  return (type.flags & TypeFlags.Literal) !== 0;
1372
1566
  }
@@ -1418,11 +1612,11 @@ export class Signature {
1418
1612
  parameters;
1419
1613
  thisParameter;
1420
1614
  target;
1421
- constructor(data, objectRegistry) {
1615
+ constructor(data, project, objectRegistry) {
1422
1616
  this.id = data.id;
1423
1617
  this.flags = data.flags;
1424
1618
  this.objectRegistry = objectRegistry;
1425
- this.declaration = data.declaration ? new NodeHandle(data.declaration) : undefined;
1619
+ this.declaration = data.declaration ? new NodeHandle(data.declaration, project) : undefined;
1426
1620
  this.typeParameters = data.typeParameters ?? [];
1427
1621
  this.parameters = data.parameters ?? [];
1428
1622
  this.thisParameter = data.thisParameter;