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