diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 7a19aa9167f..37bc454d614 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -2205,8 +2205,9 @@ namespace ts.projectSystem { projectService.checkNumberOfProjects({}); for (const f of [f2, f3]) { + // There shouldnt be any script info as we closed the file that resulted in creation of it const scriptInfo = projectService.getScriptInfoForNormalizedPath(server.toNormalizedPath(f.path)); - assert.equal(scriptInfo.containingProjects.length, 0, `expect 0 containing projects for '${f.path}'`); + assert.equal(scriptInfo, undefined, `expected script info to be closed: '${f.path}'`); } }); diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 7c0e0a0fb92..ad237bc0337 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -827,10 +827,20 @@ namespace ts.server { this.assignScriptInfoToInferredProjectIfNecessary(f, /*addToListOfOpenFiles*/ false); } } + + // Cleanup script infos that are not open and not part of any project + this.deleteOrphanScriptInfoNotInAnyProject(); } - if (info.containingProjects.length === 0) { - // if there are not projects that include this script info - delete it - this.filenameToScriptInfo.remove(info.path); + } + + private deleteOrphanScriptInfoNotInAnyProject() { + for (const path of this.filenameToScriptInfo.getKeys()) { + const info = this.filenameToScriptInfo.get(path); + if (!info.isScriptOpen() && info.containingProjects.length === 0) { + // if there are not projects that include this script info - delete it + info.stopWatcher(); + this.filenameToScriptInfo.remove(info.path); + } } } @@ -1418,6 +1428,8 @@ namespace ts.server { for (const p of this.inferredProjects) { p.updateGraph(); } + + this.deleteOrphanScriptInfoNotInAnyProject(); this.printProjects(); } diff --git a/src/server/lsHost.ts b/src/server/lsHost.ts index ec655c545ea..79429737240 100644 --- a/src/server/lsHost.ts +++ b/src/server/lsHost.ts @@ -11,11 +11,11 @@ namespace ts.server { private filesWithChangedSetOfUnresolvedImports: Path[]; - private readonly resolveModuleName: typeof resolveModuleName; + private resolveModuleName: typeof resolveModuleName; readonly trace: (s: string) => void; readonly realpath?: (path: string) => string; - constructor(private readonly host: ServerHost, private readonly project: Project, private readonly cancellationToken: HostCancellationToken) { + constructor(private readonly host: ServerHost, private project: Project, private readonly cancellationToken: HostCancellationToken) { this.cancellationToken = new ThrottledCancellationToken(cancellationToken, project.projectService.throttleWaitMilliseconds); this.getCanonicalFileName = ts.createGetCanonicalFileName(this.host.useCaseSensitiveFileNames); @@ -47,6 +47,11 @@ namespace ts.server { } } + dispose() { + this.project = undefined; + this.resolveModuleName = undefined; + } + public startRecordingFilesWithChangedResolutions() { this.filesWithChangedSetOfUnresolvedImports = []; } @@ -238,4 +243,4 @@ namespace ts.server { this.compilationSettings = opt; } } -} \ No newline at end of file +} diff --git a/src/server/project.ts b/src/server/project.ts index be854f948ea..33b345af833 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -116,7 +116,7 @@ namespace ts.server { public languageServiceEnabled = true; - protected readonly lsHost: LSHost; + protected lsHost: LSHost; builder: Builder; /** @@ -297,9 +297,15 @@ namespace ts.server { this.rootFiles = undefined; this.rootFilesMap = undefined; this.program = undefined; + this.builder = undefined; + this.cachedUnresolvedImportsPerFile = undefined; + this.projectErrors = undefined; + this.lsHost.dispose(); + this.lsHost = undefined; // signal language service to release source files acquired from document registry this.languageService.dispose(); + this.languageService = undefined; } getCompilerOptions() { @@ -1043,6 +1049,7 @@ namespace ts.server { if (this.projectFileWatcher) { this.projectFileWatcher.close(); + this.projectFileWatcher = undefined; } if (this.typeRootsWatchers) { @@ -1132,4 +1139,4 @@ namespace ts.server { this.typeAcquisition = newTypeAcquisition; } } -} \ No newline at end of file +} diff --git a/src/services/services.ts b/src/services/services.ts index 9e17e9a45e1..7adce648a62 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1311,7 +1311,9 @@ namespace ts { if (program) { forEach(program.getSourceFiles(), f => documentRegistry.releaseDocument(f.fileName, program.getCompilerOptions())); + program = undefined; } + host = undefined; } /// Diagnostics