fix(41736): tsserver should not crash if external file does not exist (#41737)

If a file does not exist, `projectService.getOrCreateScriptInfoNotOpenedByClient()`
will return `undefined`, but tsserver does not handle this case.

Fix https://github.com/microsoft/TypeScript/issues/41736
This commit is contained in:
Keen Yee Liau 2020-11-30 16:37:40 -08:00 committed by GitHub
parent 0c76803854
commit cf4df4e472
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 2 deletions

View File

@ -1188,8 +1188,8 @@ namespace ts.server {
// by the host for files in the program when the program is retrieved above but
// the program doesn't contain external files so this must be done explicitly.
inserted => {
const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(inserted, this.currentDirectory, this.directoryStructureHost)!;
scriptInfo.attachToProject(this);
const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(inserted, this.currentDirectory, this.directoryStructureHost);
scriptInfo?.attachToProject(this);
},
removed => this.detachScriptInfoFromProject(removed)
);

View File

@ -898,5 +898,44 @@ namespace ts.projectSystem {
const jsConfigProject = service.configuredProjects.get(jsConfig.path.toLowerCase())!;
checkProjectActualFiles(jsConfigProject, [jsConfig.path, jsFilePath, libFile.path]);
});
it("does not crash if external file does not exist", () => {
const f1 = {
path: "/a/file1.ts",
content: "let x = [1, 2];",
};
const p1 = {
projectFileName: "/a/proj1.csproj",
rootFiles: [toExternalFile(f1.path)],
options: {},
};
const host = createServerHost([f1]);
host.require = (_initialPath, moduleName) => {
assert.equal(moduleName, "myplugin");
return {
module: () => ({
create(info: server.PluginCreateInfo) {
return Harness.LanguageService.makeDefaultProxy(info);
},
getExternalFiles() {
return ["/does/not/exist"];
},
}),
error: undefined,
};
};
const session = createSession(host, {
globalPlugins: ["myplugin"],
});
const projectService = session.getProjectService();
// When the external project is opened, the graph will be updated,
// and in the process getExternalFiles() above will be called.
// Since the external file does not exist, there will not be a script
// info for it. If tsserver does not handle this case, the following
// method call will crash.
projectService.openExternalProject(p1);
checkNumberOfProjects(projectService, { externalProjects: 1 });
});
});
}