Skip to content

Commit 9f3e5ea

Browse files
committed
Use different cache for the ScriptInfoVersion
1 parent b155a71 commit 9f3e5ea

File tree

2 files changed

+17
-14
lines changed

2 files changed

+17
-14
lines changed

src/server/editorServices.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -334,11 +334,6 @@ namespace ts.server {
334334
return project.dirty && project.updateGraph();
335335
}
336336

337-
type ScriptInfoOrVersion = ScriptInfo | ScriptInfoVersion;
338-
function isScriptInfoVersion(infoOrVersion: ScriptInfoOrVersion): infoOrVersion is ScriptInfoVersion {
339-
return (infoOrVersion as ScriptInfoVersion).svc !== undefined;
340-
}
341-
342337
export class ProjectService {
343338

344339
/*@internal*/
@@ -350,7 +345,13 @@ namespace ts.server {
350345
/**
351346
* Container of all known scripts
352347
*/
353-
private readonly filenameToScriptInfo = createMap<ScriptInfoOrVersion>();
348+
private readonly filenameToScriptInfo = createMap<ScriptInfo>();
349+
/**
350+
* Contains all the deleted script info's version information so that
351+
* it does not reset when creating script info again
352+
* (and could have potentially collided with version where contents mismatch)
353+
*/
354+
private readonly filenameToScriptInfoVersion = createMap<ScriptInfoVersion>();
354355
// Set of all '.js' files ever opened.
355356
private readonly allJsFilesForOpenFileTelemetry = createMap<true>();
356357

@@ -889,7 +890,7 @@ namespace ts.server {
889890

890891
project.close();
891892
if (Debug.shouldAssert(AssertionLevel.Normal)) {
892-
this.filenameToScriptInfo.forEach(info => Debug.assert(isScriptInfoVersion(info) || !info.isAttached(project)));
893+
this.filenameToScriptInfo.forEach(info => Debug.assert(!info.isAttached(project)));
893894
}
894895
// Remove the project from pending project updates
895896
this.pendingProjectUpdates.delete(project.getProjectName());
@@ -1026,7 +1027,8 @@ namespace ts.server {
10261027
}
10271028

10281029
private deleteScriptInfo(info: ScriptInfo) {
1029-
this.filenameToScriptInfo.set(info.path, info.getVersion());
1030+
this.filenameToScriptInfo.delete(info.path);
1031+
this.filenameToScriptInfoVersion.set(info.path, info.getVersion());
10301032
const realpath = info.getRealpathIfDifferent();
10311033
if (realpath) {
10321034
this.realpathToScriptInfos!.remove(realpath, info); // TODO: GH#18217
@@ -1855,8 +1857,8 @@ namespace ts.server {
18551857
private getOrCreateScriptInfoWorker(fileName: NormalizedPath, currentDirectory: string, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, hostToQueryFileExistsOn?: { fileExists(path: string): boolean; }) {
18561858
Debug.assert(fileContent === undefined || openedByClient, "ScriptInfo needs to be opened by client to be able to set its user defined content");
18571859
const path = normalizedPathToPath(fileName, currentDirectory, this.toCanonicalFileName);
1858-
let info = this.filenameToScriptInfo.get(path);
1859-
if (!info || isScriptInfoVersion(info)) {
1860+
let info = this.getScriptInfoForPath(path);
1861+
if (!info) {
18601862
const isDynamic = isDynamicFileName(fileName);
18611863
Debug.assert(isRootedDiskPath(fileName) || isDynamic || openedByClient, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nScript info with non-dynamic relative file name can only be open script info`);
18621864
Debug.assert(!isRootedDiskPath(fileName) || this.currentDirectory === currentDirectory || !this.openFilesWithNonRootedDiskPath.has(this.toCanonicalFileName(fileName)), "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nOpen script files with non rooted disk path opened with current directory context cannot have same canonical names`);
@@ -1865,8 +1867,9 @@ namespace ts.server {
18651867
if (!openedByClient && !isDynamic && !(hostToQueryFileExistsOn || this.host).fileExists(fileName)) {
18661868
return;
18671869
}
1868-
info = new ScriptInfo(this.host, fileName, scriptKind!, !!hasMixedContent, path, info); // TODO: GH#18217
1870+
info = new ScriptInfo(this.host, fileName, scriptKind!, !!hasMixedContent, path, this.filenameToScriptInfoVersion.get(path)); // TODO: GH#18217
18691871
this.filenameToScriptInfo.set(info.path, info);
1872+
this.filenameToScriptInfoVersion.delete(info.path);
18701873
if (!openedByClient) {
18711874
this.watchClosedScriptInfo(info);
18721875
}
@@ -1899,8 +1902,7 @@ namespace ts.server {
18991902
}
19001903

19011904
getScriptInfoForPath(fileName: Path) {
1902-
const info = this.filenameToScriptInfo.get(fileName);
1903-
return info && isScriptInfoVersion(info) ? undefined : info;
1905+
return this.filenameToScriptInfo.get(fileName);
19041906
}
19051907

19061908
setHostConfiguration(args: protocol.ConfigureRequestArguments) {
@@ -2151,7 +2153,7 @@ namespace ts.server {
21512153
// It was then postponed to cleanup these script infos so that they can be reused if
21522154
// the file from that old project is reopened because of opening file from here.
21532155
this.filenameToScriptInfo.forEach(info => {
2154-
if (!isScriptInfoVersion(info) && !info.isScriptOpen() && info.isOrphan()) {
2156+
if (!info.isScriptOpen() && info.isOrphan()) {
21552157
// if there are not projects that include this script info - delete it
21562158
this.stopWatchingScriptInfo(info);
21572159
this.deleteScriptInfo(info);

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13784,6 +13784,7 @@ declare namespace ts.server {
1378413784
readonly typingsCache: TypingsCache;
1378513785
readonly documentRegistry: DocumentRegistry;
1378613786
private readonly filenameToScriptInfo;
13787+
private readonly filenameToScriptInfoVersion;
1378713788
private readonly allJsFilesForOpenFileTelemetry;
1378813789
readonly realpathToScriptInfos: MultiMap<ScriptInfo> | undefined;
1378913790
private readonly externalProjectToConfiguredProjectMap;

0 commit comments

Comments
 (0)