typescript 7.1.0-dev.20261001.1 → 7.1.0-dev.20261003.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/async/api.d.ts +73 -42
- package/dist/api/async/api.d.ts.map +1 -1
- package/dist/api/async/api.js +224 -68
- package/dist/api/async/api.js.map +1 -1
- package/dist/api/async/client.d.ts.map +1 -1
- package/dist/api/async/client.js +73 -16
- package/dist/api/async/client.js.map +1 -1
- package/dist/api/async/types.d.ts +4 -3
- package/dist/api/async/types.d.ts.map +1 -1
- package/dist/api/compilerOptions.generated.d.ts +123 -0
- package/dist/api/compilerOptions.generated.d.ts.map +1 -0
- package/dist/api/compilerOptions.generated.js +8 -0
- package/dist/api/compilerOptions.generated.js.map +1 -0
- package/dist/api/diagnosticFormatter.d.ts.map +1 -1
- package/dist/api/diagnosticFormatter.js.map +1 -1
- package/dist/api/fs.d.ts +10 -8
- package/dist/api/fs.d.ts.map +1 -1
- package/dist/api/fs.js.map +1 -1
- package/dist/api/node/encoder.generated.js +1 -1
- package/dist/api/node/encoder.generated.js.map +1 -1
- package/dist/api/node/node.d.ts +18 -10
- package/dist/api/node/node.d.ts.map +1 -1
- package/dist/api/node/node.generated.js +1 -1
- package/dist/api/node/node.generated.js.map +1 -1
- package/dist/api/node/node.infrastructure.d.ts.map +1 -1
- package/dist/api/node/node.infrastructure.js.map +1 -1
- package/dist/api/node/node.js +39 -11
- package/dist/api/node/node.js.map +1 -1
- package/dist/api/path.d.ts +46 -9
- package/dist/api/path.d.ts.map +1 -1
- package/dist/api/path.js +365 -28
- package/dist/api/path.js.map +1 -1
- package/dist/api/prepareCompilerOptions.generated.d.ts +5 -0
- package/dist/api/prepareCompilerOptions.generated.d.ts.map +1 -0
- package/dist/api/prepareCompilerOptions.generated.js +24 -0
- package/dist/api/prepareCompilerOptions.generated.js.map +1 -0
- package/dist/api/proto.generated.d.ts +223 -172
- package/dist/api/proto.generated.d.ts.map +1 -1
- package/dist/api/proto.generated.js +3 -0
- package/dist/api/proto.generated.js.map +1 -1
- package/dist/api/sourceFileCache.d.ts +15 -9
- package/dist/api/sourceFileCache.d.ts.map +1 -1
- package/dist/api/sourceFileCache.js +30 -12
- package/dist/api/sourceFileCache.js.map +1 -1
- package/dist/api/sync/api.d.ts +101 -49
- package/dist/api/sync/api.d.ts.map +1 -1
- package/dist/api/sync/api.js +314 -86
- package/dist/api/sync/api.js.map +1 -1
- package/dist/api/sync/types.d.ts +4 -3
- package/dist/api/sync/types.d.ts.map +1 -1
- package/dist/api/typedPaths.d.ts +3 -0
- package/dist/api/typedPaths.d.ts.map +1 -0
- package/dist/api/typedPaths.js +2 -0
- package/dist/api/typedPaths.js.map +1 -0
- package/dist/ast/ast.d.ts +58 -7
- package/dist/ast/ast.d.ts.map +1 -1
- package/dist/ast/ast.generated.d.ts +3 -3
- package/dist/ast/ast.generated.d.ts.map +1 -1
- package/dist/ast/factory.generated.d.ts +2 -2
- package/dist/ast/factory.generated.d.ts.map +1 -1
- package/dist/ast/factory.generated.js.map +1 -1
- package/dist/ast/is.generated.d.ts.map +1 -1
- package/dist/ast/is.generated.js +2 -1
- package/dist/ast/is.generated.js.map +1 -1
- package/dist/ast/scanner.d.ts.map +1 -1
- package/dist/ast/scanner.js +1 -0
- package/dist/ast/scanner.js.map +1 -1
- package/dist/enums/caseSensitivity.d.ts +2 -0
- package/dist/enums/caseSensitivity.d.ts.map +1 -0
- package/dist/enums/caseSensitivity.enum.d.ts +5 -0
- package/dist/enums/caseSensitivity.enum.d.ts.map +1 -0
- package/dist/enums/caseSensitivity.enum.js +7 -0
- package/dist/enums/caseSensitivity.enum.js.map +1 -0
- package/dist/enums/caseSensitivity.js +7 -0
- package/dist/enums/caseSensitivity.js.map +1 -0
- package/dist/enums/jsxEmit.enum.js +1 -1
- package/dist/enums/jsxEmit.enum.js.map +1 -1
- package/dist/enums/jsxEmit.js +1 -1
- package/dist/enums/jsxEmit.js.map +1 -1
- package/dist/enums/moduleDetectionKind.enum.js +1 -1
- package/dist/enums/moduleDetectionKind.enum.js.map +1 -1
- package/dist/enums/moduleDetectionKind.js +1 -1
- package/dist/enums/moduleDetectionKind.js.map +1 -1
- package/dist/enums/moduleKind.enum.js +1 -1
- package/dist/enums/moduleKind.enum.js.map +1 -1
- package/dist/enums/moduleKind.js +1 -1
- package/dist/enums/moduleKind.js.map +1 -1
- package/dist/enums/moduleResolutionKind.enum.js +1 -1
- package/dist/enums/moduleResolutionKind.enum.js.map +1 -1
- package/dist/enums/moduleResolutionKind.js +1 -1
- package/dist/enums/moduleResolutionKind.js.map +1 -1
- package/dist/enums/newLineKind.enum.js +1 -1
- package/dist/enums/newLineKind.enum.js.map +1 -1
- package/dist/enums/newLineKind.js +1 -1
- package/dist/enums/newLineKind.js.map +1 -1
- package/dist/enums/scriptTarget.d.ts.map +1 -1
- package/dist/enums/scriptTarget.enum.d.ts.map +1 -1
- package/dist/enums/scriptTarget.enum.js +1 -0
- package/dist/enums/scriptTarget.enum.js.map +1 -1
- package/dist/enums/scriptTarget.js +1 -0
- package/dist/enums/scriptTarget.js.map +1 -1
- package/dist/enums/syntaxKind.enum.d.ts +198 -197
- package/dist/enums/syntaxKind.enum.d.ts.map +1 -1
- package/dist/enums/syntaxKind.enum.js +199 -198
- package/dist/enums/syntaxKind.enum.js.map +1 -1
- package/dist/enums/syntaxKind.js +199 -198
- package/dist/enums/syntaxKind.js.map +1 -1
- package/dist/vscode/extensionApi.d.ts +56 -0
- package/dist/vscode/extensionApi.d.ts.map +1 -0
- package/dist/vscode/extensionApi.js +2 -0
- package/dist/vscode/extensionApi.js.map +1 -0
- package/dist/vscode/protocol.generated.d.ts +2886 -0
- package/dist/vscode/protocol.generated.d.ts.map +1 -0
- package/dist/vscode/protocol.generated.js +4 -0
- package/dist/vscode/protocol.generated.js.map +1 -0
- package/package.json +16 -9
- package/schemas/jsconfig.schema.json +2207 -0
- package/schemas/tsconfig.schema.json +2206 -0
package/dist/api/async/api.js
CHANGED
|
@@ -21,9 +21,10 @@ import { TypePredicateKind } from "#enums/typePredicateKind";
|
|
|
21
21
|
import { ModifierFlags, unescapeLeadingUnderscores, } from "../../ast/index.js";
|
|
22
22
|
import { assertNever } from "../../internal/utils.js";
|
|
23
23
|
import { encodeNode, uint8ArrayToBase64, } from "../node/encoder.js";
|
|
24
|
-
import { decodeNode, getNodeId,
|
|
24
|
+
import { decodeNode, getNodeId, parseNodeHandleFromCompiler, readParseOptionsKey, readSourceFileHash, readSourceFileLease, RemoteNode, RemoteSourceFile, } from "../node/node.js";
|
|
25
25
|
import { Wtf8Decoder } from "../node/wtf8.js";
|
|
26
|
-
import {
|
|
26
|
+
import { canonicalize, CaseSensitivity, pathKey, toRootedDirectoryPath, toRootedPath, } from "../path.js";
|
|
27
|
+
import { prepareCompilerOptions } from "../prepareCompilerOptions.generated.js";
|
|
27
28
|
import { resolveFileName, toCreateSnapshotRequest, validateSymbolResponse, } from "../proto.js";
|
|
28
29
|
import { SourceFileCache, } from "../sourceFileCache.js";
|
|
29
30
|
import { Client, } from "./client.js";
|
|
@@ -52,12 +53,14 @@ function registerModuleResolutionCallback(client, callback, getSnapshot) {
|
|
|
52
53
|
// import { sourceFileResponseToUint8Array } from "../node/encoder.ts";
|
|
53
54
|
// @sync-only-end
|
|
54
55
|
export class API {
|
|
56
|
+
/** @internal */
|
|
55
57
|
client;
|
|
58
|
+
/** @internal */
|
|
56
59
|
sourceFileCache;
|
|
57
60
|
toPath;
|
|
58
|
-
currentDirectory;
|
|
59
61
|
decoder = new Wtf8Decoder();
|
|
60
|
-
|
|
62
|
+
currentDirectory;
|
|
63
|
+
caseSensitivity;
|
|
61
64
|
initialized = false;
|
|
62
65
|
initializing;
|
|
63
66
|
activeSnapshots = new Map();
|
|
@@ -71,6 +74,52 @@ export class API {
|
|
|
71
74
|
this.printer = new Printer(this.client);
|
|
72
75
|
this.internal = new InternalAPI(this.client, () => this.ensureInitialized()); // @sync: this.internal = new InternalAPI(this.client, this.ensureInitialized);
|
|
73
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Looks up a remote declaration's binder symbol. Throws for synthesized or configuration ASTs.
|
|
79
|
+
*/
|
|
80
|
+
async getSymbol(declaration) {
|
|
81
|
+
const file = getRemoteSourceFile(declaration);
|
|
82
|
+
if (!file)
|
|
83
|
+
throw new Error(`Source file not found for declaration`);
|
|
84
|
+
const record = file.symbolCache;
|
|
85
|
+
if (!record)
|
|
86
|
+
throw new Error(`Cached source file not found for declaration`);
|
|
87
|
+
const index = parseNodeHandleFromCompiler(getNodeId(declaration)).index;
|
|
88
|
+
const cached = record.symbolsByDeclarationNodeIndex.get(index);
|
|
89
|
+
if (cached)
|
|
90
|
+
return cached;
|
|
91
|
+
// @sync-only-start
|
|
92
|
+
// return this.fetchDeclarationSymbol(record, index);
|
|
93
|
+
// @sync-only-end
|
|
94
|
+
// @sync-skip-block-start
|
|
95
|
+
let request = record.declarationSymbolRequests.get(index);
|
|
96
|
+
if (!request) {
|
|
97
|
+
request = this.fetchDeclarationSymbol(record, index);
|
|
98
|
+
record.declarationSymbolRequests.set(index, request);
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
return await request;
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
record.declarationSymbolRequests.delete(index);
|
|
105
|
+
}
|
|
106
|
+
// @sync-skip-block-end
|
|
107
|
+
}
|
|
108
|
+
async fetchDeclarationSymbol(record, index) {
|
|
109
|
+
const data = await this.client.apiRequest("getSymbolOfDeclaration", {
|
|
110
|
+
file: record.descriptor,
|
|
111
|
+
index,
|
|
112
|
+
});
|
|
113
|
+
validateSymbolResponse(data);
|
|
114
|
+
const reference = data.reference;
|
|
115
|
+
if (reference.kind !== SymbolOwnerKind.File) {
|
|
116
|
+
throw new Error(`Symbol ${reference.id} is not file-owned`);
|
|
117
|
+
}
|
|
118
|
+
const fileOwner = { record, api: this };
|
|
119
|
+
const symbol = this.sourceFileCache.getOrCreateSymbol(record, reference.file, reference.id, () => new Symbol(data, { kind: SymbolOwnerKind.File, owner: fileOwner }));
|
|
120
|
+
record.symbolsByDeclarationNodeIndex.set(index, symbol);
|
|
121
|
+
return symbol;
|
|
122
|
+
}
|
|
74
123
|
/**
|
|
75
124
|
* Create an API instance from an existing LSP connection's API session.
|
|
76
125
|
* Use this when connecting to an API pipe provided by an LSP server via custom/initializeAPISession.
|
|
@@ -98,11 +147,9 @@ export class API {
|
|
|
98
147
|
async initializeWorker() {
|
|
99
148
|
try {
|
|
100
149
|
const response = await this.client.apiRequest("initialize", null);
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
this.
|
|
104
|
-
this.currentDirectory = currentDirectory;
|
|
105
|
-
this.toPath = (fileName) => toPath(fileName, currentDirectory, getCanonicalFileName);
|
|
150
|
+
this.currentDirectory = response.currentDirectory;
|
|
151
|
+
this.caseSensitivity = response.caseSensitivity;
|
|
152
|
+
this.toPath = (fileName, basePath = response.currentDirectory) => pathKey(toRootedPath(fileName, toRootedDirectoryPath(basePath, response.currentDirectory)), response.caseSensitivity);
|
|
106
153
|
this.initialized = true;
|
|
107
154
|
}
|
|
108
155
|
catch (error) {
|
|
@@ -117,10 +164,13 @@ export class API {
|
|
|
117
164
|
return this.currentDirectory;
|
|
118
165
|
}
|
|
119
166
|
getCanonicalFileName(fileName) {
|
|
120
|
-
|
|
167
|
+
return canonicalize(fileName, this.getCaseSensitivity());
|
|
168
|
+
}
|
|
169
|
+
getCaseSensitivity() {
|
|
170
|
+
if (this.caseSensitivity === undefined) {
|
|
121
171
|
throw new Error("API has not been initialized");
|
|
122
172
|
}
|
|
123
|
-
return this.
|
|
173
|
+
return this.caseSensitivity;
|
|
124
174
|
}
|
|
125
175
|
getNewLine() {
|
|
126
176
|
return "\n";
|
|
@@ -130,6 +180,9 @@ export class API {
|
|
|
130
180
|
const orchestratorResponse = await this.client.apiRequest("createBuildOrchestrator", {
|
|
131
181
|
...buildOrchestratorOptions,
|
|
132
182
|
...buildOrchestratorOptions.overrideCompilerOptions,
|
|
183
|
+
cwd: buildOrchestratorOptions.cwd === undefined
|
|
184
|
+
? undefined
|
|
185
|
+
: toRootedDirectoryPath(buildOrchestratorOptions.cwd, this.getCurrentDirectory()),
|
|
133
186
|
rootNames,
|
|
134
187
|
});
|
|
135
188
|
const orchestrator = new BuildOrchestrator(this.client, orchestratorResponse, () => {
|
|
@@ -197,7 +250,7 @@ export class API {
|
|
|
197
250
|
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
198
251
|
const lease = readSourceFileLease(view);
|
|
199
252
|
try {
|
|
200
|
-
const decoded = new RemoteSourceFile(data, this.decoder, this.client.getTimingCollector());
|
|
253
|
+
const decoded = new RemoteSourceFile(data, this.decoder, this.client.getTimingCollector(), this);
|
|
201
254
|
return this.addSourceFileLease(decoded, lease);
|
|
202
255
|
}
|
|
203
256
|
catch (error) {
|
|
@@ -215,7 +268,7 @@ export class API {
|
|
|
215
268
|
}
|
|
216
269
|
addSourceFileLease(sourceFile, lease) {
|
|
217
270
|
const cached = this.sourceFileCache.setForLease(sourceFile, lease);
|
|
218
|
-
const retained = new RetainedSourceFile(cached, lease,
|
|
271
|
+
const retained = new RetainedSourceFile(cached, lease, () => {
|
|
219
272
|
this.activeSourceFileLeases.delete(lease);
|
|
220
273
|
this.sourceFileCache.releaseLease(lease);
|
|
221
274
|
});
|
|
@@ -242,7 +295,7 @@ export class API {
|
|
|
242
295
|
await this.ensureInitialized();
|
|
243
296
|
const requestParams = toCreateSnapshotRequest(this.prepareCreateSnapshotParams(params));
|
|
244
297
|
const data = await this.client.apiRequest("createSnapshot", requestParams);
|
|
245
|
-
const snapshot = new Snapshot(data, this.
|
|
298
|
+
const snapshot = new Snapshot(data, this.toPath, this, () => {
|
|
246
299
|
this.activeSnapshots.delete(snapshot.id);
|
|
247
300
|
this.sourceFileCache.releaseSnapshot(snapshot.id);
|
|
248
301
|
}, this.createSnapshotUpdater(() => snapshot), undefined);
|
|
@@ -263,7 +316,7 @@ export class API {
|
|
|
263
316
|
return baseSnapshot;
|
|
264
317
|
}
|
|
265
318
|
this.sourceFileCache.retainForSnapshot(data.snapshot, baseSnapshot.id, data.changes);
|
|
266
|
-
const snapshot = new Snapshot(data, this.
|
|
319
|
+
const snapshot = new Snapshot(data, this.toPath, this, () => {
|
|
267
320
|
this.activeSnapshots.delete(snapshot.id);
|
|
268
321
|
this.sourceFileCache.releaseSnapshot(snapshot.id);
|
|
269
322
|
}, this.createSnapshotUpdater(() => snapshot), baseSnapshot);
|
|
@@ -276,11 +329,15 @@ export class API {
|
|
|
276
329
|
const prepareOptions = (options) => {
|
|
277
330
|
if (!options)
|
|
278
331
|
return undefined;
|
|
279
|
-
const { moduleResolver, ...rest } = options;
|
|
332
|
+
const { moduleResolver, projectReferences, ...rest } = options;
|
|
280
333
|
moduleResolver?.ensureNotDisposed();
|
|
281
334
|
return {
|
|
282
335
|
...rest,
|
|
283
336
|
moduleResolver: moduleResolver?.id,
|
|
337
|
+
projectReferences: projectReferences?.map(reference => ({
|
|
338
|
+
...reference,
|
|
339
|
+
path: toRootedPath(reference.path, this.getCurrentDirectory()),
|
|
340
|
+
})),
|
|
284
341
|
};
|
|
285
342
|
};
|
|
286
343
|
return {
|
|
@@ -317,7 +374,7 @@ export class API {
|
|
|
317
374
|
if (baseSnapshot) {
|
|
318
375
|
this.sourceFileCache.retainForSnapshot(data.snapshot, baseSnapshot.id, data.changes);
|
|
319
376
|
}
|
|
320
|
-
const snapshot = new Snapshot(data, this.
|
|
377
|
+
const snapshot = new Snapshot(data, this.toPath, this, () => {
|
|
321
378
|
this.activeSnapshots.delete(snapshot.id);
|
|
322
379
|
this.sourceFileCache.releaseSnapshot(snapshot.id);
|
|
323
380
|
}, this.createSnapshotUpdater(() => snapshot), baseSnapshot);
|
|
@@ -356,7 +413,7 @@ export class API {
|
|
|
356
413
|
: undefined;
|
|
357
414
|
try {
|
|
358
415
|
const id = await this.client.apiRequest("createModuleResolver", {
|
|
359
|
-
compilerOptions,
|
|
416
|
+
compilerOptions: prepareCompilerOptions(compilerOptions, this.getCurrentDirectory()),
|
|
360
417
|
moduleResolutions: options?.moduleResolutions,
|
|
361
418
|
resolveModuleNameCallback: callback?.name,
|
|
362
419
|
});
|
|
@@ -432,18 +489,47 @@ function sourceFileDescriptor(sourceFile) {
|
|
|
432
489
|
nodeId: sourceFile.nodeId,
|
|
433
490
|
};
|
|
434
491
|
}
|
|
492
|
+
function getRemoteSourceFile(node) {
|
|
493
|
+
if (!(node instanceof RemoteNode))
|
|
494
|
+
return undefined;
|
|
495
|
+
const file = node.getSourceFile();
|
|
496
|
+
return file instanceof RemoteSourceFile && file.api ? file : undefined;
|
|
497
|
+
}
|
|
498
|
+
function getNodeAPI(node) {
|
|
499
|
+
const api = getRemoteSourceFile(node)?.api;
|
|
500
|
+
if (!api)
|
|
501
|
+
return undefined;
|
|
502
|
+
if (!(api instanceof API))
|
|
503
|
+
throw new Error("Source file does not belong to the async API"); // @sync: if (!(api instanceof API)) throw new Error("Source file does not belong to the sync API");
|
|
504
|
+
return api;
|
|
505
|
+
}
|
|
506
|
+
/** Looks up a remote declaration's binder symbol through its API. Throws for non-remote declarations. */
|
|
507
|
+
export async function getSymbol(declaration) {
|
|
508
|
+
const api = getNodeAPI(declaration);
|
|
509
|
+
if (!api)
|
|
510
|
+
throw new Error("Source file not found for declaration");
|
|
511
|
+
return api.getSymbol(declaration);
|
|
512
|
+
}
|
|
513
|
+
// @sync-only-start
|
|
514
|
+
// export declare namespace getSymbol {
|
|
515
|
+
// function gen(declaration: Declaration): Generator<ProtocolRequest, Symbol, ProtocolResponse["result"]>;
|
|
516
|
+
// }
|
|
517
|
+
// getSymbol.gen = function* (declaration: Declaration): Generator<ProtocolRequest, Symbol, ProtocolResponse["result"]> {
|
|
518
|
+
// const api = getNodeAPI(declaration);
|
|
519
|
+
// if (!api) throw new Error("Source file not found for declaration");
|
|
520
|
+
// return yield* api.getSymbol.gen(declaration);
|
|
521
|
+
// };
|
|
522
|
+
// @sync-only-end
|
|
435
523
|
/** An independently retained source file and its disposable remote-lifetime lease. */
|
|
436
524
|
export class RetainedSourceFile {
|
|
437
525
|
sourceFile;
|
|
438
526
|
lease;
|
|
439
|
-
client;
|
|
440
527
|
onDispose;
|
|
441
528
|
disposed = false;
|
|
442
529
|
disposePromise;
|
|
443
|
-
constructor(sourceFile, lease,
|
|
530
|
+
constructor(sourceFile, lease, onDispose) {
|
|
444
531
|
this.sourceFile = sourceFile;
|
|
445
532
|
this.lease = lease;
|
|
446
|
-
this.client = client;
|
|
447
533
|
this.onDispose = onDispose;
|
|
448
534
|
}
|
|
449
535
|
[globalThis.Symbol.asyncDispose]() {
|
|
@@ -455,9 +541,12 @@ export class RetainedSourceFile {
|
|
|
455
541
|
async disposeWorker() {
|
|
456
542
|
if (this.disposed)
|
|
457
543
|
return;
|
|
544
|
+
const api = getNodeAPI(this.sourceFile);
|
|
545
|
+
if (!api)
|
|
546
|
+
throw new Error("Retained source file has no owning API");
|
|
458
547
|
this.disposed = true;
|
|
459
548
|
try {
|
|
460
|
-
await
|
|
549
|
+
await api.client.apiRequest("releaseSourceFile", { lease: this.lease });
|
|
461
550
|
}
|
|
462
551
|
finally {
|
|
463
552
|
this.onDispose();
|
|
@@ -492,7 +581,7 @@ export class Snapshot {
|
|
|
492
581
|
operation;
|
|
493
582
|
projectMap;
|
|
494
583
|
toPath;
|
|
495
|
-
|
|
584
|
+
api;
|
|
496
585
|
disposed = false;
|
|
497
586
|
disposePromise;
|
|
498
587
|
onDispose;
|
|
@@ -500,9 +589,12 @@ export class Snapshot {
|
|
|
500
589
|
projectDataMap;
|
|
501
590
|
updateSnapshot;
|
|
502
591
|
internal;
|
|
503
|
-
|
|
592
|
+
get client() {
|
|
593
|
+
return this.api.client;
|
|
594
|
+
}
|
|
595
|
+
constructor(data, toPath, api, onDispose, updateSnapshot, baseSnapshot) {
|
|
504
596
|
this.id = data.snapshot;
|
|
505
|
-
this.
|
|
597
|
+
this.api = api;
|
|
506
598
|
this.toPath = toPath;
|
|
507
599
|
this.onDispose = onDispose;
|
|
508
600
|
this.updateSnapshot = updateSnapshot;
|
|
@@ -517,14 +609,14 @@ export class Snapshot {
|
|
|
517
609
|
this.projectDataMap = new Map([...projectDataMap].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0));
|
|
518
610
|
this.snapshotRegistry = new SnapshotObjectRegistry(this.id);
|
|
519
611
|
for (const projData of this.projectDataMap.values()) {
|
|
520
|
-
const project = new Project(projData, this.id,
|
|
612
|
+
const project = new Project(projData, this.id, toPath, api, this.snapshotRegistry);
|
|
521
613
|
this.projectMap.set(projData.id, project);
|
|
522
614
|
}
|
|
523
615
|
this.operation = {
|
|
524
616
|
createdPrograms: data.operation.createdPrograms?.map(projectId => this.requireProject(projectId).program),
|
|
525
617
|
openedFiles: data.operation.openedFiles?.map(result => ({ project: this.requireProject(result.project) })),
|
|
526
618
|
};
|
|
527
|
-
this.internal = new SnapshotInternalAPI(this.id, client);
|
|
619
|
+
this.internal = new SnapshotInternalAPI(this.id, api.client);
|
|
528
620
|
}
|
|
529
621
|
getProjects() {
|
|
530
622
|
this.ensureNotDisposed();
|
|
@@ -532,7 +624,8 @@ export class Snapshot {
|
|
|
532
624
|
}
|
|
533
625
|
getConfiguredProject(configFileName) {
|
|
534
626
|
this.ensureNotDisposed();
|
|
535
|
-
|
|
627
|
+
const id = this.toPath(configFileName);
|
|
628
|
+
return this.projectMap.get(id);
|
|
536
629
|
}
|
|
537
630
|
getProject(projectId) {
|
|
538
631
|
this.ensureNotDisposed();
|
|
@@ -674,20 +767,22 @@ class SnapshotObjectRegistry {
|
|
|
674
767
|
}
|
|
675
768
|
}
|
|
676
769
|
class ProjectObjectRegistry {
|
|
677
|
-
client;
|
|
678
770
|
snapshotId;
|
|
679
771
|
project;
|
|
680
772
|
snapshotRegistry;
|
|
681
|
-
sourceFileCache;
|
|
682
773
|
types = new Map();
|
|
683
774
|
signatures = new Map();
|
|
684
775
|
disposed = false;
|
|
685
|
-
|
|
686
|
-
this.client
|
|
776
|
+
get client() {
|
|
777
|
+
return this.project.api.client;
|
|
778
|
+
}
|
|
779
|
+
get sourceFileCache() {
|
|
780
|
+
return this.project.api.sourceFileCache;
|
|
781
|
+
}
|
|
782
|
+
constructor(snapshotId, project, snapshotRegistry) {
|
|
687
783
|
this.snapshotId = snapshotId;
|
|
688
784
|
this.project = project;
|
|
689
785
|
this.snapshotRegistry = snapshotRegistry;
|
|
690
|
-
this.sourceFileCache = sourceFileCache;
|
|
691
786
|
snapshotRegistry.addProjectRegistry(this);
|
|
692
787
|
}
|
|
693
788
|
getOrCreateSymbol(data) {
|
|
@@ -700,7 +795,7 @@ class ProjectObjectRegistry {
|
|
|
700
795
|
const record = this.sourceFileCache.getOrCreateRecord(reference.file, this.snapshotId, this.project.id);
|
|
701
796
|
return this.sourceFileCache.getOrCreateSymbol(record, reference.file, reference.id, () => new Symbol(data, {
|
|
702
797
|
kind: SymbolOwnerKind.File,
|
|
703
|
-
owner: { record,
|
|
798
|
+
owner: { record, api: this.project.api },
|
|
704
799
|
}));
|
|
705
800
|
}
|
|
706
801
|
/** Find an already-interned symbol and retain its file record for this registry. */
|
|
@@ -710,7 +805,7 @@ class ProjectObjectRegistry {
|
|
|
710
805
|
return this.snapshotRegistry.getSymbol(reference.id);
|
|
711
806
|
}
|
|
712
807
|
const record = this.sourceFileCache.findRecord(reference.file);
|
|
713
|
-
const symbol = record?.
|
|
808
|
+
const symbol = record?.symbolsById.get(reference.id);
|
|
714
809
|
if (record && symbol) {
|
|
715
810
|
this.sourceFileCache.retainRecord(record, this.snapshotId, this.project.id);
|
|
716
811
|
}
|
|
@@ -926,6 +1021,8 @@ class ProjectObjectRegistry {
|
|
|
926
1021
|
}
|
|
927
1022
|
}
|
|
928
1023
|
export class Project {
|
|
1024
|
+
/** @internal */
|
|
1025
|
+
api;
|
|
929
1026
|
id;
|
|
930
1027
|
configFileName;
|
|
931
1028
|
currentDirectory;
|
|
@@ -938,10 +1035,10 @@ export class Project {
|
|
|
938
1035
|
program;
|
|
939
1036
|
checker;
|
|
940
1037
|
languageService;
|
|
941
|
-
client;
|
|
942
1038
|
snapshotId;
|
|
943
|
-
constructor(data, snapshotId,
|
|
1039
|
+
constructor(data, snapshotId, toPath, api, snapshotRegistry) {
|
|
944
1040
|
this.id = data.id;
|
|
1041
|
+
this.api = api;
|
|
945
1042
|
this.configFileName = data.configFileName;
|
|
946
1043
|
this.currentDirectory = data.currentDirectory;
|
|
947
1044
|
this.dirty = data.dirty;
|
|
@@ -951,12 +1048,11 @@ export class Project {
|
|
|
951
1048
|
this.parsedCommandLine = data.parsedCommandLine;
|
|
952
1049
|
this.compilerOptions = this.parsedCommandLine.options;
|
|
953
1050
|
this.rootFiles = this.parsedCommandLine.fileNames;
|
|
954
|
-
this.client = client;
|
|
955
1051
|
this.snapshotId = snapshotId;
|
|
956
|
-
this.program = new Program(snapshotId, this,
|
|
957
|
-
const objectRegistry = new ProjectObjectRegistry(
|
|
958
|
-
this.checker = new Checker(snapshotId, this,
|
|
959
|
-
this.languageService = new LanguageService(snapshotId, this,
|
|
1052
|
+
this.program = new Program(snapshotId, this, toPath);
|
|
1053
|
+
const objectRegistry = new ProjectObjectRegistry(snapshotId, this, snapshotRegistry);
|
|
1054
|
+
this.checker = new Checker(snapshotId, this, objectRegistry);
|
|
1055
|
+
this.languageService = new LanguageService(snapshotId, this, objectRegistry);
|
|
960
1056
|
}
|
|
961
1057
|
/** @deprecated Use `languageService.getImportAdderEdits`. */
|
|
962
1058
|
getImportAdderEdits(file, actions) {
|
|
@@ -973,12 +1069,13 @@ export class Project {
|
|
|
973
1069
|
export class LanguageService {
|
|
974
1070
|
snapshotId;
|
|
975
1071
|
project;
|
|
976
|
-
client;
|
|
977
1072
|
objectRegistry;
|
|
978
|
-
|
|
1073
|
+
get client() {
|
|
1074
|
+
return this.project.api.client;
|
|
1075
|
+
}
|
|
1076
|
+
constructor(snapshotId, project, objectRegistry) {
|
|
979
1077
|
this.snapshotId = snapshotId;
|
|
980
1078
|
this.project = project;
|
|
981
|
-
this.client = client;
|
|
982
1079
|
this.objectRegistry = objectRegistry;
|
|
983
1080
|
}
|
|
984
1081
|
async getImportAdderEdits(file, actions) {
|
|
@@ -1069,28 +1166,28 @@ export class Program {
|
|
|
1069
1166
|
snapshotId;
|
|
1070
1167
|
id;
|
|
1071
1168
|
project;
|
|
1072
|
-
client;
|
|
1073
|
-
sourceFileCache;
|
|
1074
1169
|
toPath;
|
|
1075
|
-
formatDiagnosticsHost;
|
|
1076
1170
|
decoder = new Wtf8Decoder();
|
|
1077
1171
|
sourceFileMetadataCache = new Map();
|
|
1078
1172
|
ownedSnapshot;
|
|
1079
1173
|
disposePromise;
|
|
1080
|
-
|
|
1174
|
+
get client() {
|
|
1175
|
+
return this.project.api.client;
|
|
1176
|
+
}
|
|
1177
|
+
get sourceFileCache() {
|
|
1178
|
+
return this.project.api.sourceFileCache;
|
|
1179
|
+
}
|
|
1180
|
+
constructor(snapshotId, project, toPath) {
|
|
1081
1181
|
this.snapshotId = snapshotId;
|
|
1082
1182
|
this.id = project.id;
|
|
1083
1183
|
this.project = project;
|
|
1084
|
-
this.client = client;
|
|
1085
|
-
this.sourceFileCache = sourceFileCache;
|
|
1086
1184
|
this.toPath = toPath;
|
|
1087
|
-
this.formatDiagnosticsHost = formatDiagnosticsHost;
|
|
1088
1185
|
}
|
|
1089
1186
|
getCurrentDirectory() {
|
|
1090
1187
|
return this.project.currentDirectory;
|
|
1091
1188
|
}
|
|
1092
1189
|
getCanonicalFileName(fileName) {
|
|
1093
|
-
return this.
|
|
1190
|
+
return this.project.api.getCanonicalFileName(fileName);
|
|
1094
1191
|
}
|
|
1095
1192
|
getNewLine() {
|
|
1096
1193
|
return this.project.compilerOptions.newLine === NewLineKind.CRLF ? "\r\n" : "\n";
|
|
@@ -1116,7 +1213,20 @@ export class Program {
|
|
|
1116
1213
|
}
|
|
1117
1214
|
async getSourceFile(file) {
|
|
1118
1215
|
const fileName = resolveFileName(file);
|
|
1119
|
-
const path = this.
|
|
1216
|
+
const path = this.pathKeyForFileName(fileName);
|
|
1217
|
+
return this.getSourceFileWorker(file, path);
|
|
1218
|
+
}
|
|
1219
|
+
/**
|
|
1220
|
+
* Returns the source file for an already-canonical path.
|
|
1221
|
+
*
|
|
1222
|
+
* @internal
|
|
1223
|
+
*/
|
|
1224
|
+
getSourceFileByPath(path) {
|
|
1225
|
+
// The wire format is a string, but the cache key remains the supplied
|
|
1226
|
+
// PathKey and is never treated as a RootedPath.
|
|
1227
|
+
return this.getSourceFileWorker(path, path);
|
|
1228
|
+
}
|
|
1229
|
+
async getSourceFileWorker(file, path) {
|
|
1120
1230
|
// Check if we already have a retained cache entry for this (snapshot, project) pair
|
|
1121
1231
|
const retained = this.sourceFileCache.getRetained(path, this.snapshotId, this.project.id);
|
|
1122
1232
|
if (retained) {
|
|
@@ -1132,7 +1242,7 @@ export class Program {
|
|
|
1132
1242
|
return undefined;
|
|
1133
1243
|
}
|
|
1134
1244
|
// Create a new RemoteSourceFile and cache it (set returns existing if hash matches)
|
|
1135
|
-
const decoded = new RemoteSourceFile(binaryData, this.decoder, this.client.getTimingCollector());
|
|
1245
|
+
const decoded = new RemoteSourceFile(binaryData, this.decoder, this.client.getTimingCollector(), this.project.api);
|
|
1136
1246
|
return this.sourceFileCache.set(decoded, this.snapshotId, this.project.id);
|
|
1137
1247
|
}
|
|
1138
1248
|
async getResolvedModule(file, moduleName, mode) {
|
|
@@ -1203,7 +1313,7 @@ export class Program {
|
|
|
1203
1313
|
* `Program` instance.
|
|
1204
1314
|
*/
|
|
1205
1315
|
getSourceFileMetadata(file) {
|
|
1206
|
-
return this.getSourceFileMetadataByPath(this.
|
|
1316
|
+
return this.getSourceFileMetadataByPath(this.pathKeyForFileName(resolveFileName(file)));
|
|
1207
1317
|
}
|
|
1208
1318
|
/**
|
|
1209
1319
|
* Returns program-stored metadata for the source file at the given path, or `undefined`
|
|
@@ -1220,6 +1330,8 @@ export class Program {
|
|
|
1220
1330
|
return metadata;
|
|
1221
1331
|
}
|
|
1222
1332
|
async fetchSourceFileMetadata(path) {
|
|
1333
|
+
// PathKey is serialized as a string; the server deliberately treats all
|
|
1334
|
+
// client-provided path text as untrusted input.
|
|
1223
1335
|
const data = await this.client.apiRequest("getSourceFileMetadata", {
|
|
1224
1336
|
snapshot: this.snapshotId,
|
|
1225
1337
|
project: this.project.id,
|
|
@@ -1227,6 +1339,9 @@ export class Program {
|
|
|
1227
1339
|
});
|
|
1228
1340
|
return data ?? undefined;
|
|
1229
1341
|
}
|
|
1342
|
+
pathKeyForFileName(fileName) {
|
|
1343
|
+
return this.toPath(fileName, this.project.currentDirectory);
|
|
1344
|
+
}
|
|
1230
1345
|
/**
|
|
1231
1346
|
* Returns whether the given source file was loaded as part of an external library
|
|
1232
1347
|
* (e.g. a dependency resolved from `node_modules`). The underlying program metadata is
|
|
@@ -1269,7 +1384,7 @@ export class Program {
|
|
|
1269
1384
|
if (!binaryData) {
|
|
1270
1385
|
return undefined;
|
|
1271
1386
|
}
|
|
1272
|
-
return new RemoteSourceFile(binaryData, this.decoder);
|
|
1387
|
+
return new RemoteSourceFile(binaryData, this.decoder, undefined, this.project.api);
|
|
1273
1388
|
}
|
|
1274
1389
|
/**
|
|
1275
1390
|
* Get syntactic (parse) diagnostics for specific files or all files.
|
|
@@ -1522,19 +1637,60 @@ function toEmitOutput(response) {
|
|
|
1522
1637
|
export class Checker {
|
|
1523
1638
|
snapshotId;
|
|
1524
1639
|
project;
|
|
1525
|
-
client;
|
|
1526
1640
|
objectRegistry;
|
|
1527
1641
|
wellKnownSymbols;
|
|
1528
1642
|
wellKnownSignatures;
|
|
1529
|
-
|
|
1643
|
+
get client() {
|
|
1644
|
+
return this.project.api.client;
|
|
1645
|
+
}
|
|
1646
|
+
constructor(snapshotId, project, objectRegistry) {
|
|
1530
1647
|
this.snapshotId = snapshotId;
|
|
1531
1648
|
this.project = project;
|
|
1532
|
-
this.client = client;
|
|
1533
1649
|
this.objectRegistry = objectRegistry;
|
|
1534
1650
|
}
|
|
1535
1651
|
dispose() {
|
|
1536
1652
|
this.objectRegistry.clear();
|
|
1537
1653
|
}
|
|
1654
|
+
/** Get the merged symbol, or the original symbol if it has not been merged. */
|
|
1655
|
+
async getMergedSymbol(symbol) {
|
|
1656
|
+
const data = await this.client.apiRequest("getMergedSymbol", {
|
|
1657
|
+
snapshot: this.snapshotId,
|
|
1658
|
+
project: this.project.id,
|
|
1659
|
+
symbol: symbol.reference,
|
|
1660
|
+
});
|
|
1661
|
+
return this.objectRegistry.getOrCreateSymbol(data);
|
|
1662
|
+
}
|
|
1663
|
+
/**
|
|
1664
|
+
* Get a node's merged symbol. For a declaration, prefer
|
|
1665
|
+
* {@link Checker.getSymbolOfDeclaration} for a non-nullable result.
|
|
1666
|
+
*/
|
|
1667
|
+
async getSymbolOfNode(node) {
|
|
1668
|
+
const data = await this.client.apiRequest("getSymbolOfNode", {
|
|
1669
|
+
snapshot: this.snapshotId,
|
|
1670
|
+
project: this.project.id,
|
|
1671
|
+
location: getNodeId(node),
|
|
1672
|
+
});
|
|
1673
|
+
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
1674
|
+
}
|
|
1675
|
+
/** Get a declaration's merged symbol. */
|
|
1676
|
+
async getSymbolOfDeclaration(node) {
|
|
1677
|
+
const data = await this.client.apiRequest("getSymbolOfDeclarationForChecker", {
|
|
1678
|
+
snapshot: this.snapshotId,
|
|
1679
|
+
project: this.project.id,
|
|
1680
|
+
location: getNodeId(node),
|
|
1681
|
+
});
|
|
1682
|
+
// Declarations normally have symbols, but preserve unexpected null results at runtime.
|
|
1683
|
+
return (data && this.objectRegistry.getOrCreateSymbol(data));
|
|
1684
|
+
}
|
|
1685
|
+
/** Get a symbol's merged parent, if any. */
|
|
1686
|
+
async getParentOfSymbol(symbol) {
|
|
1687
|
+
const data = await this.client.apiRequest("getParentOfSymbolForChecker", {
|
|
1688
|
+
snapshot: this.snapshotId,
|
|
1689
|
+
project: this.project.id,
|
|
1690
|
+
symbol: symbol.reference,
|
|
1691
|
+
});
|
|
1692
|
+
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
1693
|
+
}
|
|
1538
1694
|
async getSymbolAtLocation(nodeOrNodes) {
|
|
1539
1695
|
if (Array.isArray(nodeOrNodes)) {
|
|
1540
1696
|
const data = await this.client.apiRequest("getSymbolsAtLocations", {
|
|
@@ -2326,7 +2482,7 @@ export class NodeHandle {
|
|
|
2326
2482
|
kind;
|
|
2327
2483
|
path;
|
|
2328
2484
|
constructor(handle, canonicalProject, fileOwner) {
|
|
2329
|
-
const parsed =
|
|
2485
|
+
const parsed = parseNodeHandleFromCompiler(handle);
|
|
2330
2486
|
this.index = parsed.index;
|
|
2331
2487
|
this.kind = parsed.kind;
|
|
2332
2488
|
this.path = parsed.path;
|
|
@@ -2346,17 +2502,17 @@ export class NodeHandle {
|
|
|
2346
2502
|
}
|
|
2347
2503
|
if (!project)
|
|
2348
2504
|
throw new Error(`Node handle for '${this.path}' has no project context`);
|
|
2349
|
-
const sourceFile = await project.program.
|
|
2505
|
+
const sourceFile = await project.program.getSourceFileByPath(this.path);
|
|
2350
2506
|
if (!sourceFile) {
|
|
2351
2507
|
return undefined;
|
|
2352
2508
|
}
|
|
2353
2509
|
return sourceFile.getOrCreateNodeAtIndex(this.index);
|
|
2354
2510
|
}
|
|
2355
2511
|
async fetchOwnerFile(fileOwner) {
|
|
2356
|
-
const data = await fileOwner.client.apiRequestBinary("getCachedSourceFile", { file: fileOwner.record.descriptor });
|
|
2512
|
+
const data = await fileOwner.api.client.apiRequestBinary("getCachedSourceFile", { file: fileOwner.record.descriptor });
|
|
2357
2513
|
if (!data)
|
|
2358
2514
|
throw new Error(`Source file '${fileOwner.record.descriptor.fileName}' is not available`);
|
|
2359
|
-
return fileOwner.
|
|
2515
|
+
return fileOwner.api.sourceFileCache.attachFile(fileOwner.record, new RemoteSourceFile(data, new Wtf8Decoder(), fileOwner.api.client.getTimingCollector(), fileOwner.api));
|
|
2360
2516
|
}
|
|
2361
2517
|
}
|
|
2362
2518
|
export class Symbol {
|
|
@@ -2443,10 +2599,10 @@ export class Symbol {
|
|
|
2443
2599
|
}
|
|
2444
2600
|
const fileOwner = this.storage.owner;
|
|
2445
2601
|
// A file-owned symbol's relationships are always owned by the same file.
|
|
2446
|
-
const cached = reference.file === fileOwner.record.descriptor.nodeId ? fileOwner.record.
|
|
2602
|
+
const cached = reference.file === fileOwner.record.descriptor.nodeId ? fileOwner.record.symbolsById.get(reference.id) : undefined;
|
|
2447
2603
|
if (cached)
|
|
2448
2604
|
return cached;
|
|
2449
|
-
const data = await fileOwner.client.apiRequest(method, { symbol: this.reference });
|
|
2605
|
+
const data = await fileOwner.api.client.apiRequest(method, { symbol: this.reference });
|
|
2450
2606
|
if (!data)
|
|
2451
2607
|
throw new Error(`${method} returned null symbol for Symbol ${this.id}`);
|
|
2452
2608
|
return this.internFileSymbol(fileOwner, data);
|
|
@@ -2456,7 +2612,7 @@ export class Symbol {
|
|
|
2456
2612
|
return this.storage.registry.fetchSymbols(this, method);
|
|
2457
2613
|
}
|
|
2458
2614
|
const fileOwner = this.storage.owner;
|
|
2459
|
-
const data = await fileOwner.client.apiRequest(method, { symbol: this.reference });
|
|
2615
|
+
const data = await fileOwner.api.client.apiRequest(method, { symbol: this.reference });
|
|
2460
2616
|
return data?.map(symbol => this.internFileSymbol(fileOwner, symbol)) ?? [];
|
|
2461
2617
|
}
|
|
2462
2618
|
internFileSymbol(fileOwner, data) {
|
|
@@ -2464,7 +2620,7 @@ export class Symbol {
|
|
|
2464
2620
|
const reference = data.reference;
|
|
2465
2621
|
if (reference.kind !== SymbolOwnerKind.File)
|
|
2466
2622
|
throw new Error(`Symbol ${reference.id} is not file-owned`);
|
|
2467
|
-
return fileOwner.
|
|
2623
|
+
return fileOwner.api.sourceFileCache.getOrCreateSymbol(fileOwner.record, reference.file, reference.id, () => new Symbol(data, { kind: SymbolOwnerKind.File, owner: fileOwner }));
|
|
2468
2624
|
}
|
|
2469
2625
|
}
|
|
2470
2626
|
class TypeObject {
|