Handle if project for open file will get recollected because of pending cleanup from closed script info (#50908)

* Handle if project for open file will get recollected because of pending cleanup from closed script info
Fixes #50868

* Rename
This commit is contained in:
Sheetal Nandi
2022-09-26 12:40:23 -07:00
committed by GitHub
parent c81bf4d8b0
commit 09368bcbae
6 changed files with 966 additions and 46 deletions

View File

@@ -1167,20 +1167,22 @@ namespace ts.server {
}
/* @internal */
tryGetDefaultProjectForFile(fileName: NormalizedPath): Project | undefined {
const scriptInfo = this.getScriptInfoForNormalizedPath(fileName);
tryGetDefaultProjectForFile(fileNameOrScriptInfo: NormalizedPath | ScriptInfo): Project | undefined {
const scriptInfo = isString(fileNameOrScriptInfo) ? this.getScriptInfoForNormalizedPath(fileNameOrScriptInfo) : fileNameOrScriptInfo;
return scriptInfo && !scriptInfo.isOrphan() ? scriptInfo.getDefaultProject() : undefined;
}
/* @internal */
ensureDefaultProjectForFile(fileName: NormalizedPath): Project {
return this.tryGetDefaultProjectForFile(fileName) || this.doEnsureDefaultProjectForFile(fileName);
ensureDefaultProjectForFile(fileNameOrScriptInfo: NormalizedPath | ScriptInfo): Project {
return this.tryGetDefaultProjectForFile(fileNameOrScriptInfo) || this.doEnsureDefaultProjectForFile(fileNameOrScriptInfo);
}
private doEnsureDefaultProjectForFile(fileName: NormalizedPath): Project {
private doEnsureDefaultProjectForFile(fileNameOrScriptInfo: NormalizedPath | ScriptInfo): Project {
this.ensureProjectStructuresUptoDate();
const scriptInfo = this.getScriptInfoForNormalizedPath(fileName);
return scriptInfo ? scriptInfo.getDefaultProject() : (this.logErrorForScriptInfoNotFound(fileName), Errors.ThrowNoProject());
const scriptInfo = isString(fileNameOrScriptInfo) ? this.getScriptInfoForNormalizedPath(fileNameOrScriptInfo) : fileNameOrScriptInfo;
return scriptInfo ?
scriptInfo.getDefaultProject() :
(this.logErrorForScriptInfoNotFound(isString(fileNameOrScriptInfo) ? fileNameOrScriptInfo : fileNameOrScriptInfo.fileName), Errors.ThrowNoProject());
}
getScriptInfoEnsuringProjectsUptoDate(uncheckedFileName: string) {
@@ -3648,7 +3650,7 @@ namespace ts.server {
return;
}
const project = scriptInfo.getDefaultProject();
const project = this.ensureDefaultProjectForFile(scriptInfo);
if (!project.languageServiceEnabled) {
return;
}

View File

@@ -1719,6 +1719,10 @@ namespace ts.server {
this.projectService.logErrorForScriptInfoNotFound(args.file);
return Errors.ThrowNoProject();
}
else if (!getScriptInfoEnsuringProjectsUptoDate) {
// Ensure there are containing projects are present
this.projectService.ensureDefaultProjectForFile(scriptInfo);
}
projects = scriptInfo.containingProjects;
symLinkedProjects = this.projectService.getSymlinkedProjects(scriptInfo);
}
@@ -1867,13 +1871,7 @@ namespace ts.server {
}
private getFileAndLanguageServiceForSyntacticOperation(args: protocol.FileRequestArgs) {
// Since this is syntactic operation, there should always be project for the file
// throw if we dont get project
const file = toNormalizedPath(args.file);
const project = this.getProject(args.projectFileName) || this.projectService.ensureDefaultProjectForFile(file);
if (!project) {
return Errors.ThrowNoProject();
}
const { file, project } = this.getFileAndProject(args);
return {
file,
languageService: project.getLanguageService(/*ensureSynchronized*/ false)