typescript 7.1.0-dev.20260929.1 → 7.1.0-dev.20260930.4
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 +58 -35
- package/dist/api/async/api.d.ts.map +1 -1
- package/dist/api/async/api.js +219 -117
- 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 +21 -35
- package/dist/api/async/client.js.map +1 -1
- package/dist/api/fs.d.ts +39 -13
- package/dist/api/fs.d.ts.map +1 -1
- package/dist/api/fs.js +13 -108
- package/dist/api/fs.js.map +1 -1
- package/dist/api/fsCallbacks.d.ts +27 -0
- package/dist/api/fsCallbacks.d.ts.map +1 -0
- package/dist/api/fsCallbacks.js +111 -0
- package/dist/api/fsCallbacks.js.map +1 -0
- package/dist/api/node/node.d.ts +8 -2
- package/dist/api/node/node.d.ts.map +1 -1
- package/dist/api/node/node.infrastructure.d.ts +1 -0
- package/dist/api/node/node.infrastructure.d.ts.map +1 -1
- package/dist/api/node/node.infrastructure.js +8 -1
- package/dist/api/node/node.infrastructure.js.map +1 -1
- package/dist/api/node/node.js +14 -2
- package/dist/api/node/node.js.map +1 -1
- package/dist/api/options.d.ts +5 -3
- package/dist/api/options.d.ts.map +1 -1
- package/dist/api/options.js +10 -0
- package/dist/api/options.js.map +1 -1
- package/dist/api/path.d.ts +1 -0
- package/dist/api/path.d.ts.map +1 -1
- package/dist/api/path.js +3 -0
- package/dist/api/path.js.map +1 -1
- package/dist/api/proto.d.ts +26 -3
- package/dist/api/proto.d.ts.map +1 -1
- package/dist/api/proto.generated.d.ts +72 -34
- package/dist/api/proto.generated.d.ts.map +1 -1
- package/dist/api/proto.generated.js +2 -0
- package/dist/api/proto.generated.js.map +1 -1
- package/dist/api/proto.js +20 -0
- package/dist/api/proto.js.map +1 -1
- package/dist/api/sourceFileCache.d.ts +29 -13
- package/dist/api/sourceFileCache.d.ts.map +1 -1
- package/dist/api/sourceFileCache.js +97 -16
- package/dist/api/sourceFileCache.js.map +1 -1
- package/dist/api/sync/api.d.ts +64 -44
- package/dist/api/sync/api.d.ts.map +1 -1
- package/dist/api/sync/api.js +339 -191
- package/dist/api/sync/api.js.map +1 -1
- package/dist/api/sync/client.d.ts.map +1 -1
- package/dist/api/sync/client.js +11 -26
- package/dist/api/sync/client.js.map +1 -1
- package/dist/enums/symbolOwnerKind.d.ts +2 -0
- package/dist/enums/symbolOwnerKind.d.ts.map +1 -0
- package/dist/enums/symbolOwnerKind.enum.d.ts +5 -0
- package/dist/enums/symbolOwnerKind.enum.d.ts.map +1 -0
- package/dist/enums/symbolOwnerKind.enum.js +7 -0
- package/dist/enums/symbolOwnerKind.enum.js.map +1 -0
- package/dist/enums/symbolOwnerKind.js +7 -0
- package/dist/enums/symbolOwnerKind.js.map +1 -0
- package/package.json +9 -9
package/dist/api/async/api.js
CHANGED
|
@@ -14,21 +14,22 @@ import { ScriptKind } from "#enums/scriptKind";
|
|
|
14
14
|
import { SignatureFlags } from "#enums/signatureFlags";
|
|
15
15
|
import { SignatureKind } from "#enums/signatureKind";
|
|
16
16
|
import { SymbolFlags } from "#enums/symbolFlags";
|
|
17
|
+
import { SymbolOwnerKind } from "#enums/symbolOwnerKind";
|
|
17
18
|
import { TypeFlags } from "#enums/typeFlags";
|
|
18
19
|
import { TypeFormatFlags } from "#enums/typeFormatFlags";
|
|
19
20
|
import { TypePredicateKind } from "#enums/typePredicateKind";
|
|
20
21
|
import { ModifierFlags, unescapeLeadingUnderscores, } from "../../ast/index.js";
|
|
21
22
|
import { assertNever } from "../../internal/utils.js";
|
|
22
23
|
import { encodeNode, uint8ArrayToBase64, } from "../node/encoder.js";
|
|
23
|
-
import { decodeNode, getNodeId, parseNodeHandle,
|
|
24
|
+
import { decodeNode, getNodeId, parseNodeHandle, readSourceFileLease, RemoteSourceFile, } from "../node/node.js";
|
|
24
25
|
import { Wtf8Decoder } from "../node/wtf8.js";
|
|
25
26
|
import { createGetCanonicalFileName, toPath, } from "../path.js";
|
|
26
|
-
import { resolveFileName, toCreateSnapshotRequest, } from "../proto.js";
|
|
27
|
-
import { SourceFileCache } from "../sourceFileCache.js";
|
|
27
|
+
import { resolveFileName, toCreateSnapshotRequest, validateSymbolResponse, } from "../proto.js";
|
|
28
|
+
import { SourceFileCache, } from "../sourceFileCache.js";
|
|
28
29
|
import { Client, } from "./client.js";
|
|
29
30
|
export { formatDiagnostics, formatDiagnosticsWithColorAndContext } from "../diagnosticFormatter.js";
|
|
30
31
|
export { documentURIToFileName, fileNameToDocumentURI } from "../path.js";
|
|
31
|
-
export { CheckFlags, CompletionItemKind, DiagnosticCategory, ElementFlags, EmitOnly, IndexKind, JsxEmit, ModifierFlags, ModuleKind, ModuleResolutionKind, NodeBuilderFlags, ObjectFlags, ScriptKind, SignatureFlags, SignatureKind, SymbolFlags, TypeFlags, TypeFormatFlags, TypePredicateKind };
|
|
32
|
+
export { CheckFlags, CompletionItemKind, DiagnosticCategory, ElementFlags, EmitOnly, IndexKind, JsxEmit, ModifierFlags, ModuleKind, ModuleResolutionKind, NodeBuilderFlags, ObjectFlags, ScriptKind, SignatureFlags, SignatureKind, SymbolFlags, SymbolOwnerKind, TypeFlags, TypeFormatFlags, TypePredicateKind };
|
|
32
33
|
let nextModuleResolutionCallbackId = 0;
|
|
33
34
|
function registerModuleResolutionCallback(client, callback, getSnapshot) {
|
|
34
35
|
const name = `resolveModuleName/${++nextModuleResolutionCallbackId}`;
|
|
@@ -177,18 +178,27 @@ export class API {
|
|
|
177
178
|
}
|
|
178
179
|
return this.retainSourceFileResponse(data);
|
|
179
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* Retain an ordinary remote source file independently of the snapshot or lease that produced it.
|
|
183
|
+
*/
|
|
184
|
+
async retainSourceFile(sourceFile) {
|
|
185
|
+
await this.ensureInitialized();
|
|
186
|
+
if (!(sourceFile instanceof RemoteSourceFile)) {
|
|
187
|
+
throw new TypeError("Only remote source files can be retained");
|
|
188
|
+
}
|
|
189
|
+
const cached = this.sourceFileCache.get(sourceFile);
|
|
190
|
+
if (cached && cached !== sourceFile) {
|
|
191
|
+
throw new Error("Source file is no longer the canonical cached instance");
|
|
192
|
+
}
|
|
193
|
+
const result = await this.client.apiRequest("retainSourceFile", { file: sourceFileDescriptor(sourceFile) });
|
|
194
|
+
return this.addSourceFileLease(sourceFile, result.lease);
|
|
195
|
+
}
|
|
180
196
|
retainSourceFileResponse(data) {
|
|
181
197
|
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
182
198
|
const lease = readSourceFileLease(view);
|
|
183
199
|
try {
|
|
184
200
|
const decoded = new RemoteSourceFile(data, this.decoder, this.client.getTimingCollector());
|
|
185
|
-
|
|
186
|
-
const retained = new RetainedSourceFile(sourceFile, lease, this.client, () => {
|
|
187
|
-
this.activeSourceFileLeases.delete(lease);
|
|
188
|
-
this.sourceFileCache.releaseLease(lease);
|
|
189
|
-
});
|
|
190
|
-
this.activeSourceFileLeases.set(lease, retained);
|
|
191
|
-
return retained;
|
|
201
|
+
return this.addSourceFileLease(decoded, lease);
|
|
192
202
|
}
|
|
193
203
|
catch (error) {
|
|
194
204
|
// @sync-skip-block-start
|
|
@@ -203,6 +213,15 @@ export class API {
|
|
|
203
213
|
throw error;
|
|
204
214
|
}
|
|
205
215
|
}
|
|
216
|
+
addSourceFileLease(sourceFile, lease) {
|
|
217
|
+
const cached = this.sourceFileCache.setForLease(sourceFile, lease);
|
|
218
|
+
const retained = new RetainedSourceFile(cached, lease, this.client, () => {
|
|
219
|
+
this.activeSourceFileLeases.delete(lease);
|
|
220
|
+
this.sourceFileCache.releaseLease(lease);
|
|
221
|
+
});
|
|
222
|
+
this.activeSourceFileLeases.set(lease, retained);
|
|
223
|
+
return retained;
|
|
224
|
+
}
|
|
206
225
|
async transpileModule(input, options = {}) {
|
|
207
226
|
await this.ensureInitialized();
|
|
208
227
|
return this.client.apiRequest("transpileModule", { input, options });
|
|
@@ -403,6 +422,16 @@ export class API {
|
|
|
403
422
|
return program;
|
|
404
423
|
}
|
|
405
424
|
}
|
|
425
|
+
function sourceFileDescriptor(sourceFile) {
|
|
426
|
+
return {
|
|
427
|
+
fileName: sourceFile.fileName,
|
|
428
|
+
path: sourceFile.path,
|
|
429
|
+
contentHash: sourceFile.contentHash,
|
|
430
|
+
parseOptionsKey: sourceFile.parseOptionsKey,
|
|
431
|
+
scriptKind: sourceFile.scriptKind,
|
|
432
|
+
nodeId: sourceFile.nodeId,
|
|
433
|
+
};
|
|
434
|
+
}
|
|
406
435
|
/** An independently retained source file and its disposable remote-lifetime lease. */
|
|
407
436
|
export class RetainedSourceFile {
|
|
408
437
|
sourceFile;
|
|
@@ -486,7 +515,7 @@ export class Snapshot {
|
|
|
486
515
|
projectDataMap.set(projectData.id, projectData);
|
|
487
516
|
}
|
|
488
517
|
this.projectDataMap = new Map([...projectDataMap].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0));
|
|
489
|
-
this.snapshotRegistry = new SnapshotObjectRegistry(
|
|
518
|
+
this.snapshotRegistry = new SnapshotObjectRegistry(this.id);
|
|
490
519
|
for (const projData of this.projectDataMap.values()) {
|
|
491
520
|
const project = new Project(projData, this.id, client, sourceFileCache, toPath, formatDiagnosticsHost, this.snapshotRegistry);
|
|
492
521
|
this.projectMap.set(projData.id, project);
|
|
@@ -612,23 +641,28 @@ export class ModuleResolver {
|
|
|
612
641
|
}
|
|
613
642
|
class SnapshotObjectRegistry {
|
|
614
643
|
symbols = new Map();
|
|
615
|
-
|
|
644
|
+
projectRegistries = new Map();
|
|
616
645
|
snapshotId;
|
|
617
|
-
|
|
618
|
-
constructor(client, snapshotId, resolveProject) {
|
|
619
|
-
this.client = client;
|
|
646
|
+
constructor(snapshotId) {
|
|
620
647
|
this.snapshotId = snapshotId;
|
|
621
|
-
this.resolveProject = resolveProject;
|
|
622
648
|
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
return this.resolveProject(projectId);
|
|
649
|
+
addProjectRegistry(registry) {
|
|
650
|
+
this.projectRegistries.set(registry.project.id, registry);
|
|
626
651
|
}
|
|
627
652
|
getOrCreateSymbol(data) {
|
|
628
|
-
|
|
653
|
+
const reference = data.reference;
|
|
654
|
+
if (reference.kind !== SymbolOwnerKind.Snapshot)
|
|
655
|
+
throw new Error(`Symbol ${reference.id} is not snapshot-owned`);
|
|
656
|
+
let symbol = this.symbols.get(reference.id);
|
|
629
657
|
if (!symbol) {
|
|
630
|
-
|
|
631
|
-
|
|
658
|
+
if (reference.snapshot !== this.snapshotId) {
|
|
659
|
+
throw new Error(`Symbol ${reference.id} belongs to snapshot ${reference.snapshot}, not ${this.snapshotId}`);
|
|
660
|
+
}
|
|
661
|
+
const registry = this.projectRegistries.get(reference.project);
|
|
662
|
+
if (!registry)
|
|
663
|
+
throw new Error(`Symbol ${reference.id} references unknown project '${reference.project}'`);
|
|
664
|
+
symbol = new Symbol(data, { kind: SymbolOwnerKind.Snapshot, registry });
|
|
665
|
+
this.symbols.set(reference.id, symbol);
|
|
632
666
|
}
|
|
633
667
|
return symbol;
|
|
634
668
|
}
|
|
@@ -638,65 +672,49 @@ class SnapshotObjectRegistry {
|
|
|
638
672
|
clear() {
|
|
639
673
|
this.symbols.clear();
|
|
640
674
|
}
|
|
641
|
-
async fetchSymbol(source, method, handle, projectId) {
|
|
642
|
-
if (!handle)
|
|
643
|
-
return undefined;
|
|
644
|
-
const cached = this.getSymbol(handle);
|
|
645
|
-
if (cached)
|
|
646
|
-
return cached;
|
|
647
|
-
const data = await this.client.apiRequest(method, {
|
|
648
|
-
snapshot: this.snapshotId,
|
|
649
|
-
project: projectId,
|
|
650
|
-
objectId: source.id,
|
|
651
|
-
});
|
|
652
|
-
if (!data)
|
|
653
|
-
throw new Error(`${method} returned null symbol for ${source.constructor.name} ${source.id}`);
|
|
654
|
-
return this.getOrCreateSymbol(data);
|
|
655
|
-
}
|
|
656
|
-
async fetchSymbols(source, method, handles, projectId) {
|
|
657
|
-
if (handles) {
|
|
658
|
-
const result = new Array(handles.length);
|
|
659
|
-
let allCached = true;
|
|
660
|
-
for (let i = 0; i < handles.length; i++) {
|
|
661
|
-
const cached = this.getSymbol(handles[i]);
|
|
662
|
-
if (!cached) {
|
|
663
|
-
allCached = false;
|
|
664
|
-
break;
|
|
665
|
-
}
|
|
666
|
-
result[i] = cached;
|
|
667
|
-
}
|
|
668
|
-
if (allCached)
|
|
669
|
-
return result;
|
|
670
|
-
}
|
|
671
|
-
const symbolData = await this.client.apiRequest(method, {
|
|
672
|
-
snapshot: this.snapshotId,
|
|
673
|
-
project: projectId,
|
|
674
|
-
objectId: source.id,
|
|
675
|
-
});
|
|
676
|
-
if (symbolData == null)
|
|
677
|
-
return [];
|
|
678
|
-
else
|
|
679
|
-
return symbolData.map(data => this.getOrCreateSymbol(data));
|
|
680
|
-
}
|
|
681
675
|
}
|
|
682
676
|
class ProjectObjectRegistry {
|
|
683
677
|
client;
|
|
684
678
|
snapshotId;
|
|
685
679
|
project;
|
|
686
680
|
snapshotRegistry;
|
|
681
|
+
sourceFileCache;
|
|
687
682
|
types = new Map();
|
|
688
683
|
signatures = new Map();
|
|
689
|
-
|
|
684
|
+
disposed = false;
|
|
685
|
+
constructor(client, snapshotId, project, snapshotRegistry, sourceFileCache) {
|
|
690
686
|
this.client = client;
|
|
691
687
|
this.snapshotId = snapshotId;
|
|
692
688
|
this.project = project;
|
|
693
689
|
this.snapshotRegistry = snapshotRegistry;
|
|
690
|
+
this.sourceFileCache = sourceFileCache;
|
|
691
|
+
snapshotRegistry.addProjectRegistry(this);
|
|
694
692
|
}
|
|
695
693
|
getOrCreateSymbol(data) {
|
|
696
|
-
|
|
694
|
+
this.ensureNotDisposed();
|
|
695
|
+
validateSymbolResponse(data);
|
|
696
|
+
const reference = data.reference;
|
|
697
|
+
if (reference.kind === SymbolOwnerKind.Snapshot) {
|
|
698
|
+
return this.snapshotRegistry.getOrCreateSymbol(data);
|
|
699
|
+
}
|
|
700
|
+
const record = this.sourceFileCache.getOrCreateRecord(reference.file, this.snapshotId, this.project.id);
|
|
701
|
+
return this.sourceFileCache.getOrCreateSymbol(record, reference.file, reference.id, () => new Symbol(data, {
|
|
702
|
+
kind: SymbolOwnerKind.File,
|
|
703
|
+
owner: { record, cache: this.sourceFileCache, client: this.client },
|
|
704
|
+
}));
|
|
697
705
|
}
|
|
698
|
-
|
|
699
|
-
|
|
706
|
+
/** Find an already-interned symbol and retain its file record for this registry. */
|
|
707
|
+
getCachedSymbol(reference) {
|
|
708
|
+
this.ensureNotDisposed();
|
|
709
|
+
if (reference.file === undefined) {
|
|
710
|
+
return this.snapshotRegistry.getSymbol(reference.id);
|
|
711
|
+
}
|
|
712
|
+
const record = this.sourceFileCache.findRecord(reference.file);
|
|
713
|
+
const symbol = record?.symbols.get(reference.id);
|
|
714
|
+
if (record && symbol) {
|
|
715
|
+
this.sourceFileCache.retainRecord(record, this.snapshotId, this.project.id);
|
|
716
|
+
}
|
|
717
|
+
return symbol;
|
|
700
718
|
}
|
|
701
719
|
getOrCreateType(data) {
|
|
702
720
|
let type = this.types.get(data.id);
|
|
@@ -724,9 +742,14 @@ class ProjectObjectRegistry {
|
|
|
724
742
|
return this.signatures.get(id);
|
|
725
743
|
}
|
|
726
744
|
clear() {
|
|
745
|
+
this.disposed = true;
|
|
727
746
|
this.types.clear();
|
|
728
747
|
this.signatures.clear();
|
|
729
748
|
}
|
|
749
|
+
ensureNotDisposed() {
|
|
750
|
+
if (this.disposed)
|
|
751
|
+
throw new Error("Project object registry is disposed");
|
|
752
|
+
}
|
|
730
753
|
async fetchOptionalType(source, method, handle) {
|
|
731
754
|
if (handle !== false) {
|
|
732
755
|
if (!handle)
|
|
@@ -750,8 +773,22 @@ class ProjectObjectRegistry {
|
|
|
750
773
|
throw new Error(`${method} returned no type for ${source.constructor.name} ${source.id}`);
|
|
751
774
|
return result;
|
|
752
775
|
}
|
|
753
|
-
async fetchSymbol(source, method,
|
|
754
|
-
|
|
776
|
+
async fetchSymbol(source, method, reference) {
|
|
777
|
+
if (!reference)
|
|
778
|
+
return undefined;
|
|
779
|
+
const cached = this.getCachedSymbol(reference);
|
|
780
|
+
if (cached)
|
|
781
|
+
return cached;
|
|
782
|
+
const data = source instanceof Symbol
|
|
783
|
+
? await this.client.apiRequest(method, { symbol: source.reference })
|
|
784
|
+
: await this.client.apiRequest(method, {
|
|
785
|
+
snapshot: this.snapshotId,
|
|
786
|
+
project: this.project.id,
|
|
787
|
+
objectId: source.id,
|
|
788
|
+
});
|
|
789
|
+
if (!data)
|
|
790
|
+
throw new Error(`${method} returned null symbol for ${source.constructor.name} ${source.id}`);
|
|
791
|
+
return this.getOrCreateSymbol(data);
|
|
755
792
|
}
|
|
756
793
|
async fetchSignature(source, method, handle) {
|
|
757
794
|
if (!handle)
|
|
@@ -793,8 +830,29 @@ class ProjectObjectRegistry {
|
|
|
793
830
|
else
|
|
794
831
|
return typesData.map(data => this.getOrCreateType(data));
|
|
795
832
|
}
|
|
796
|
-
async fetchSymbols(source, method,
|
|
797
|
-
|
|
833
|
+
async fetchSymbols(source, method, references) {
|
|
834
|
+
if (references) {
|
|
835
|
+
const result = new Array(references.length);
|
|
836
|
+
for (let i = 0; i < references.length; i++) {
|
|
837
|
+
const cached = this.getCachedSymbol(references[i]);
|
|
838
|
+
if (!cached) {
|
|
839
|
+
return this.fetchSymbolsFromServer(source, method);
|
|
840
|
+
}
|
|
841
|
+
result[i] = cached;
|
|
842
|
+
}
|
|
843
|
+
return result;
|
|
844
|
+
}
|
|
845
|
+
return this.fetchSymbolsFromServer(source, method);
|
|
846
|
+
}
|
|
847
|
+
async fetchSymbolsFromServer(source, method) {
|
|
848
|
+
const data = source instanceof Symbol
|
|
849
|
+
? await this.client.apiRequest(method, { symbol: source.reference })
|
|
850
|
+
: await this.client.apiRequest(method, {
|
|
851
|
+
snapshot: this.snapshotId,
|
|
852
|
+
project: this.project.id,
|
|
853
|
+
objectId: source.id,
|
|
854
|
+
});
|
|
855
|
+
return data?.map(symbol => this.getOrCreateSymbol(symbol)) ?? [];
|
|
798
856
|
}
|
|
799
857
|
// getBaseTypes is a checker-level endpoint keyed by `type` (not `objectId`),
|
|
800
858
|
// so it cannot go through fetchTypes. This helper reuses that server method.
|
|
@@ -896,7 +954,7 @@ export class Project {
|
|
|
896
954
|
this.client = client;
|
|
897
955
|
this.snapshotId = snapshotId;
|
|
898
956
|
this.program = new Program(snapshotId, this, client, sourceFileCache, toPath, formatDiagnosticsHost);
|
|
899
|
-
const objectRegistry = new ProjectObjectRegistry(client, snapshotId, this, snapshotRegistry);
|
|
957
|
+
const objectRegistry = new ProjectObjectRegistry(client, snapshotId, this, snapshotRegistry, sourceFileCache);
|
|
900
958
|
this.checker = new Checker(snapshotId, this, client, objectRegistry);
|
|
901
959
|
this.languageService = new LanguageService(snapshotId, this, client, objectRegistry);
|
|
902
960
|
}
|
|
@@ -929,7 +987,7 @@ export class LanguageService {
|
|
|
929
987
|
case "importSymbol":
|
|
930
988
|
const importSymbolAction = {
|
|
931
989
|
kind: "importSymbol",
|
|
932
|
-
symbol: action.symbol.
|
|
990
|
+
symbol: action.symbol.reference,
|
|
933
991
|
};
|
|
934
992
|
if (action.isValidTypeOnlyUseSite !== undefined) {
|
|
935
993
|
importSymbolAction.isValidTypeOnlyUseSite = action.isValidTypeOnlyUseSite;
|
|
@@ -1073,12 +1131,9 @@ export class Program {
|
|
|
1073
1131
|
if (!binaryData) {
|
|
1074
1132
|
return undefined;
|
|
1075
1133
|
}
|
|
1076
|
-
const view = new DataView(binaryData.buffer, binaryData.byteOffset, binaryData.byteLength);
|
|
1077
|
-
const contentHash = readSourceFileHash(view);
|
|
1078
|
-
const parseOptionsKey = readParseOptionsKey(view);
|
|
1079
1134
|
// Create a new RemoteSourceFile and cache it (set returns existing if hash matches)
|
|
1080
|
-
const
|
|
1081
|
-
return this.sourceFileCache.set(
|
|
1135
|
+
const decoded = new RemoteSourceFile(binaryData, this.decoder, this.client.getTimingCollector());
|
|
1136
|
+
return this.sourceFileCache.set(decoded, this.snapshotId, this.project.id);
|
|
1082
1137
|
}
|
|
1083
1138
|
async getResolvedModule(file, moduleName, mode) {
|
|
1084
1139
|
const result = await this.client.apiRequest("getResolvedModule", {
|
|
@@ -1535,14 +1590,14 @@ export class Checker {
|
|
|
1535
1590
|
const data = await this.client.apiRequest("getTypesOfSymbols", {
|
|
1536
1591
|
snapshot: this.snapshotId,
|
|
1537
1592
|
project: this.project.id,
|
|
1538
|
-
symbols: symbolOrSymbols.map(
|
|
1593
|
+
symbols: symbolOrSymbols.map(symbol => symbol.reference),
|
|
1539
1594
|
});
|
|
1540
1595
|
return data.map(d => this.objectRegistry.getOrCreateType(d));
|
|
1541
1596
|
}
|
|
1542
1597
|
const data = await this.client.apiRequest("getTypeOfSymbol", {
|
|
1543
1598
|
snapshot: this.snapshotId,
|
|
1544
1599
|
project: this.project.id,
|
|
1545
|
-
symbol: symbolOrSymbols.
|
|
1600
|
+
symbol: symbolOrSymbols.reference,
|
|
1546
1601
|
});
|
|
1547
1602
|
return this.objectRegistry.getOrCreateType(data);
|
|
1548
1603
|
}
|
|
@@ -1555,7 +1610,7 @@ export class Checker {
|
|
|
1555
1610
|
const data = await this.client.apiRequest("getDeclaredTypeOfSymbol", {
|
|
1556
1611
|
snapshot: this.snapshotId,
|
|
1557
1612
|
project: this.project.id,
|
|
1558
|
-
symbol: symbol.
|
|
1613
|
+
symbol: symbol.reference,
|
|
1559
1614
|
});
|
|
1560
1615
|
return this.objectRegistry.getOrCreateType(data);
|
|
1561
1616
|
}
|
|
@@ -1569,7 +1624,7 @@ export class Checker {
|
|
|
1569
1624
|
const data = await this.client.apiRequest("getNonMissingTypeOfSymbol", {
|
|
1570
1625
|
snapshot: this.snapshotId,
|
|
1571
1626
|
project: this.project.id,
|
|
1572
|
-
symbol: symbol.
|
|
1627
|
+
symbol: symbol.reference,
|
|
1573
1628
|
});
|
|
1574
1629
|
return this.objectRegistry.getOrCreateType(data);
|
|
1575
1630
|
}
|
|
@@ -1578,7 +1633,7 @@ export class Checker {
|
|
|
1578
1633
|
snapshot: this.snapshotId,
|
|
1579
1634
|
project: this.project.id,
|
|
1580
1635
|
file,
|
|
1581
|
-
symbol: symbol.
|
|
1636
|
+
symbol: symbol.reference,
|
|
1582
1637
|
});
|
|
1583
1638
|
return (data ?? []).map(h => new NodeHandle(h, this.project));
|
|
1584
1639
|
}
|
|
@@ -1786,7 +1841,7 @@ export class Checker {
|
|
|
1786
1841
|
const data = await this.client.apiRequest("getTypeOfSymbolAtLocation", {
|
|
1787
1842
|
snapshot: this.snapshotId,
|
|
1788
1843
|
project: this.project.id,
|
|
1789
|
-
symbol: symbol.
|
|
1844
|
+
symbol: symbol.reference,
|
|
1790
1845
|
location: getNodeId(location),
|
|
1791
1846
|
});
|
|
1792
1847
|
return this.objectRegistry.getOrCreateType(data);
|
|
@@ -1904,7 +1959,7 @@ export class Checker {
|
|
|
1904
1959
|
return this.client.apiRequest("isReadonlySymbol", {
|
|
1905
1960
|
snapshot: this.snapshotId,
|
|
1906
1961
|
project: this.project.id,
|
|
1907
|
-
symbol: symbol.
|
|
1962
|
+
symbol: symbol.reference,
|
|
1908
1963
|
});
|
|
1909
1964
|
}
|
|
1910
1965
|
/** Get the return type of a signature. Always returns a type. */
|
|
@@ -2058,7 +2113,7 @@ export class Checker {
|
|
|
2058
2113
|
const data = await this.client.apiRequest("getAliasedSymbol", {
|
|
2059
2114
|
snapshot: this.snapshotId,
|
|
2060
2115
|
project: this.project.id,
|
|
2061
|
-
symbol: symbol.
|
|
2116
|
+
symbol: symbol.reference,
|
|
2062
2117
|
});
|
|
2063
2118
|
return this.objectRegistry.getOrCreateSymbol(data);
|
|
2064
2119
|
}
|
|
@@ -2070,14 +2125,14 @@ export class Checker {
|
|
|
2070
2125
|
return this.client.apiRequest("getFullyQualifiedName", {
|
|
2071
2126
|
snapshot: this.snapshotId,
|
|
2072
2127
|
project: this.project.id,
|
|
2073
|
-
symbol: symbol.
|
|
2128
|
+
symbol: symbol.reference,
|
|
2074
2129
|
});
|
|
2075
2130
|
}
|
|
2076
2131
|
async getImmediateAliasedSymbol(symbol) {
|
|
2077
2132
|
const data = await this.client.apiRequest("getImmediateAliasedSymbol", {
|
|
2078
2133
|
snapshot: this.snapshotId,
|
|
2079
2134
|
project: this.project.id,
|
|
2080
|
-
symbol: symbol.
|
|
2135
|
+
symbol: symbol.reference,
|
|
2081
2136
|
});
|
|
2082
2137
|
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
2083
2138
|
}
|
|
@@ -2089,7 +2144,7 @@ export class Checker {
|
|
|
2089
2144
|
const data = await this.client.apiRequest("getTargetSymbol", {
|
|
2090
2145
|
snapshot: this.snapshotId,
|
|
2091
2146
|
project: this.project.id,
|
|
2092
|
-
symbol: symbol.
|
|
2147
|
+
symbol: symbol.reference,
|
|
2093
2148
|
});
|
|
2094
2149
|
return this.objectRegistry.getOrCreateSymbol(data);
|
|
2095
2150
|
}
|
|
@@ -2099,7 +2154,7 @@ export class Checker {
|
|
|
2099
2154
|
const data = await this.client.apiRequest("getExportSymbolOfSymbolForChecker", {
|
|
2100
2155
|
snapshot: this.snapshotId,
|
|
2101
2156
|
project: this.project.id,
|
|
2102
|
-
symbol: symbol.
|
|
2157
|
+
symbol: symbol.reference,
|
|
2103
2158
|
});
|
|
2104
2159
|
return this.objectRegistry.getOrCreateSymbol(data);
|
|
2105
2160
|
}
|
|
@@ -2157,7 +2212,7 @@ export class Checker {
|
|
|
2157
2212
|
const data = await this.client.apiRequest("getExportsOfModule", {
|
|
2158
2213
|
snapshot: this.snapshotId,
|
|
2159
2214
|
project: this.project.id,
|
|
2160
|
-
symbol: symbol.
|
|
2215
|
+
symbol: symbol.reference,
|
|
2161
2216
|
});
|
|
2162
2217
|
return data ? data.map(d => this.objectRegistry.getOrCreateSymbol(d)) : [];
|
|
2163
2218
|
}
|
|
@@ -2165,7 +2220,7 @@ export class Checker {
|
|
|
2165
2220
|
const data = await this.client.apiRequest("getMemberInModuleExports", {
|
|
2166
2221
|
snapshot: this.snapshotId,
|
|
2167
2222
|
project: this.project.id,
|
|
2168
|
-
symbol: symbol.
|
|
2223
|
+
symbol: symbol.reference,
|
|
2169
2224
|
name,
|
|
2170
2225
|
});
|
|
2171
2226
|
return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
|
|
@@ -2174,7 +2229,7 @@ export class Checker {
|
|
|
2174
2229
|
const data = await this.client.apiRequest("getJsDocTags", {
|
|
2175
2230
|
snapshot: this.snapshotId,
|
|
2176
2231
|
project: this.project.id,
|
|
2177
|
-
symbol: symbol.
|
|
2232
|
+
symbol: symbol.reference,
|
|
2178
2233
|
});
|
|
2179
2234
|
return data ?? [];
|
|
2180
2235
|
}
|
|
@@ -2182,7 +2237,7 @@ export class Checker {
|
|
|
2182
2237
|
return this.client.apiRequest("getDocumentationComment", {
|
|
2183
2238
|
snapshot: this.snapshotId,
|
|
2184
2239
|
project: this.project.id,
|
|
2185
|
-
symbol: symbol.
|
|
2240
|
+
symbol: symbol.reference,
|
|
2186
2241
|
});
|
|
2187
2242
|
}
|
|
2188
2243
|
/**
|
|
@@ -2265,71 +2320,89 @@ export class NodeHandle {
|
|
|
2265
2320
|
* is remembered so callers don't have to pass it explicitly.
|
|
2266
2321
|
*/
|
|
2267
2322
|
canonicalProject;
|
|
2323
|
+
/** The owning source file of a file-owned symbol's declaration. */
|
|
2324
|
+
fileOwner;
|
|
2268
2325
|
index;
|
|
2269
2326
|
kind;
|
|
2270
2327
|
path;
|
|
2271
|
-
constructor(handle, canonicalProject) {
|
|
2328
|
+
constructor(handle, canonicalProject, fileOwner) {
|
|
2272
2329
|
const parsed = parseNodeHandle(handle);
|
|
2273
2330
|
this.index = parsed.index;
|
|
2274
2331
|
this.kind = parsed.kind;
|
|
2275
2332
|
this.path = parsed.path;
|
|
2276
2333
|
this.canonicalProject = canonicalProject;
|
|
2334
|
+
this.fileOwner = fileOwner;
|
|
2277
2335
|
}
|
|
2278
2336
|
/**
|
|
2279
2337
|
* Resolve this handle to the actual AST node by fetching the source file from a project
|
|
2280
2338
|
* and looking up the node by index. If no project is passed, the project that produced
|
|
2281
|
-
* the handle is used.
|
|
2339
|
+
* the handle is used. Declarations of file-owned symbols identify an exact source file and
|
|
2340
|
+
* resolve through it, independently of any project.
|
|
2282
2341
|
*/
|
|
2283
2342
|
async resolve(project = this.canonicalProject) {
|
|
2343
|
+
if (this.fileOwner) {
|
|
2344
|
+
const sourceFile = this.fileOwner.record.file ?? await this.fetchOwnerFile(this.fileOwner);
|
|
2345
|
+
return sourceFile.getOrCreateNodeAtIndex(this.index);
|
|
2346
|
+
}
|
|
2347
|
+
if (!project)
|
|
2348
|
+
throw new Error(`Node handle for '${this.path}' has no project context`);
|
|
2284
2349
|
const sourceFile = await project.program.getSourceFile(this.path);
|
|
2285
2350
|
if (!sourceFile) {
|
|
2286
2351
|
return undefined;
|
|
2287
2352
|
}
|
|
2288
2353
|
return sourceFile.getOrCreateNodeAtIndex(this.index);
|
|
2289
2354
|
}
|
|
2355
|
+
async fetchOwnerFile(fileOwner) {
|
|
2356
|
+
const data = await fileOwner.client.apiRequestBinary("getCachedSourceFile", { file: fileOwner.record.descriptor });
|
|
2357
|
+
if (!data)
|
|
2358
|
+
throw new Error(`Source file '${fileOwner.record.descriptor.fileName}' is not available`);
|
|
2359
|
+
return fileOwner.cache.attachFile(fileOwner.record, new RemoteSourceFile(data, new Wtf8Decoder(), fileOwner.client.getTimingCollector()));
|
|
2360
|
+
}
|
|
2290
2361
|
}
|
|
2291
2362
|
export class Symbol {
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
* snapshot-wide, so these lookups can otherwise be ambiguous about which project to use.
|
|
2297
|
-
*/
|
|
2298
|
-
canonicalProject;
|
|
2299
|
-
id;
|
|
2363
|
+
storage;
|
|
2364
|
+
get id() {
|
|
2365
|
+
return this.reference.id;
|
|
2366
|
+
}
|
|
2300
2367
|
/** The escaped (`__String`) name, used as the key in member/export tables. */
|
|
2301
2368
|
escapedName;
|
|
2302
2369
|
/** The display name (escaped underscores removed). */
|
|
2303
2370
|
name;
|
|
2304
2371
|
flags;
|
|
2305
2372
|
checkFlags;
|
|
2373
|
+
/** @internal */
|
|
2374
|
+
reference;
|
|
2306
2375
|
declarations;
|
|
2307
2376
|
valueDeclaration;
|
|
2308
2377
|
parent;
|
|
2309
2378
|
exportSymbol;
|
|
2310
2379
|
membersCache;
|
|
2311
2380
|
exportsCache;
|
|
2312
|
-
constructor(data,
|
|
2313
|
-
|
|
2314
|
-
|
|
2381
|
+
constructor(data, storage) {
|
|
2382
|
+
if (data.reference.kind !== storage.kind)
|
|
2383
|
+
throw new Error(`Symbol ${data.reference.id} has mismatched ownership and storage`);
|
|
2384
|
+
this.storage = storage;
|
|
2385
|
+
this.reference = data.reference;
|
|
2315
2386
|
this.escapedName = data.name;
|
|
2316
2387
|
this.name = unescapeLeadingUnderscores(data.name);
|
|
2317
2388
|
this.flags = data.flags;
|
|
2318
2389
|
this.checkFlags = data.checkFlags;
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
this.
|
|
2324
|
-
|
|
2325
|
-
|
|
2390
|
+
// A file-owned symbol has no canonical project; its declarations resolve through its file.
|
|
2391
|
+
const project = storage.kind === SymbolOwnerKind.Snapshot ? storage.registry.project : undefined;
|
|
2392
|
+
const fileOwner = storage.kind === SymbolOwnerKind.File ? storage.owner : undefined;
|
|
2393
|
+
this.declarations = (data.declarations ?? []).map(handle => new NodeHandle(handle, project, fileOwner));
|
|
2394
|
+
this.valueDeclaration = data.valueDeclaration
|
|
2395
|
+
? new NodeHandle(data.valueDeclaration, project, fileOwner)
|
|
2396
|
+
: undefined;
|
|
2326
2397
|
if (data.parent !== undefined)
|
|
2327
2398
|
this.parent = data.parent;
|
|
2328
2399
|
if (data.exportSymbol !== undefined)
|
|
2329
2400
|
this.exportSymbol = data.exportSymbol;
|
|
2330
2401
|
}
|
|
2331
2402
|
async getParent() {
|
|
2332
|
-
|
|
2403
|
+
if (!this.parent)
|
|
2404
|
+
return undefined;
|
|
2405
|
+
return this.fetchSymbol("getParentOfSymbol", this.parent);
|
|
2333
2406
|
}
|
|
2334
2407
|
/**
|
|
2335
2408
|
* Get this symbol's members keyed by escaped name. The result is cached on
|
|
@@ -2346,7 +2419,7 @@ export class Symbol {
|
|
|
2346
2419
|
return this.exportsCache ??= this.fetchSymbolTable("getExportsOfSymbol");
|
|
2347
2420
|
}
|
|
2348
2421
|
async fetchSymbolTable(method) {
|
|
2349
|
-
const symbols = await this.
|
|
2422
|
+
const symbols = await this.fetchSymbols(method);
|
|
2350
2423
|
const table = new Map();
|
|
2351
2424
|
for (const symbol of symbols) {
|
|
2352
2425
|
table.set(symbol.escapedName, symbol);
|
|
@@ -2356,7 +2429,7 @@ export class Symbol {
|
|
|
2356
2429
|
async getExportSymbol() {
|
|
2357
2430
|
if (!this.exportSymbol)
|
|
2358
2431
|
return this;
|
|
2359
|
-
return this.
|
|
2432
|
+
return this.fetchSymbol("getExportSymbolOfSymbol", this.exportSymbol);
|
|
2360
2433
|
}
|
|
2361
2434
|
async getJsDocTags(checker) {
|
|
2362
2435
|
return checker.getJsDocTagsOfSymbol(this);
|
|
@@ -2364,6 +2437,35 @@ export class Symbol {
|
|
|
2364
2437
|
async getDocumentationComment(checker) {
|
|
2365
2438
|
return checker.getDocumentationCommentOfSymbol(this);
|
|
2366
2439
|
}
|
|
2440
|
+
async fetchSymbol(method, reference) {
|
|
2441
|
+
if (this.storage.kind === SymbolOwnerKind.Snapshot) {
|
|
2442
|
+
return this.storage.registry.fetchSymbol(this, method, reference);
|
|
2443
|
+
}
|
|
2444
|
+
const fileOwner = this.storage.owner;
|
|
2445
|
+
// A file-owned symbol's relationships are always owned by the same file.
|
|
2446
|
+
const cached = reference.file === fileOwner.record.descriptor.nodeId ? fileOwner.record.symbols.get(reference.id) : undefined;
|
|
2447
|
+
if (cached)
|
|
2448
|
+
return cached;
|
|
2449
|
+
const data = await fileOwner.client.apiRequest(method, { symbol: this.reference });
|
|
2450
|
+
if (!data)
|
|
2451
|
+
throw new Error(`${method} returned null symbol for Symbol ${this.id}`);
|
|
2452
|
+
return this.internFileSymbol(fileOwner, data);
|
|
2453
|
+
}
|
|
2454
|
+
async fetchSymbols(method) {
|
|
2455
|
+
if (this.storage.kind === SymbolOwnerKind.Snapshot) {
|
|
2456
|
+
return this.storage.registry.fetchSymbols(this, method);
|
|
2457
|
+
}
|
|
2458
|
+
const fileOwner = this.storage.owner;
|
|
2459
|
+
const data = await fileOwner.client.apiRequest(method, { symbol: this.reference });
|
|
2460
|
+
return data?.map(symbol => this.internFileSymbol(fileOwner, symbol)) ?? [];
|
|
2461
|
+
}
|
|
2462
|
+
internFileSymbol(fileOwner, data) {
|
|
2463
|
+
validateSymbolResponse(data);
|
|
2464
|
+
const reference = data.reference;
|
|
2465
|
+
if (reference.kind !== SymbolOwnerKind.File)
|
|
2466
|
+
throw new Error(`Symbol ${reference.id} is not file-owned`);
|
|
2467
|
+
return fileOwner.cache.getOrCreateSymbol(fileOwner.record, reference.file, reference.id, () => new Symbol(data, { kind: SymbolOwnerKind.File, owner: fileOwner }));
|
|
2468
|
+
}
|
|
2367
2469
|
}
|
|
2368
2470
|
class TypeObject {
|
|
2369
2471
|
objectRegistry;
|