From 2b84882ab01b8b9769515ded75880f1af9fce736 Mon Sep 17 00:00:00 2001 From: Keen Yee Liau Date: Mon, 30 Nov 2020 16:49:06 -0800 Subject: [PATCH] fix(language-service): do not return external template that does not exist (#39898) There is a bug in tsserver that causes it to crash when it tries to create script info for an external template that does not exist. I've submitted an upstream PR https://github.com/microsoft/TypeScript/pull/41737 to fix this, but before the commit lands in the stable release, we'll have to workaround the issue in language service. Close https://github.com/angular/vscode-ng-language-service/issues/1001 PR Close #39898 --- packages/language-service/src/ts_plugin.ts | 12 ++++++++++-- packages/language-service/test/ts_plugin_spec.ts | 7 +++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/language-service/src/ts_plugin.ts b/packages/language-service/src/ts_plugin.ts index a8da1e47a881b..fbf21b0b21a22 100644 --- a/packages/language-service/src/ts_plugin.ts +++ b/packages/language-service/src/ts_plugin.ts @@ -29,8 +29,16 @@ export function getExternalFiles(project: tss.server.Project): string[] { return []; } const ngLsHost = PROJECT_MAP.get(project); - ngLsHost?.getAnalyzedModules(); - return ngLsHost?.getExternalTemplates() || []; + if (ngLsHost === undefined) { + return []; + } + ngLsHost.getAnalyzedModules(); + return ngLsHost.getExternalTemplates().filter(fileName => { + // TODO(kyliau): Remove this when the following PR lands on the version of + // TypeScript used in this repo. + // https://github.com/microsoft/TypeScript/pull/41737 + return project.fileExists(fileName); + }); } export function create(info: tss.server.PluginCreateInfo): tss.LanguageService { diff --git a/packages/language-service/test/ts_plugin_spec.ts b/packages/language-service/test/ts_plugin_spec.ts index a57b9af930924..099146c6aedd7 100644 --- a/packages/language-service/test/ts_plugin_spec.ts +++ b/packages/language-service/test/ts_plugin_spec.ts @@ -21,6 +21,7 @@ const mockProject = { }, }, hasRoots: () => true, + fileExists: () => true, } as any; describe('plugin', () => { @@ -136,6 +137,12 @@ describe('plugin', () => { '/app/test.ng', ]); }); + + it('should not return external template that does not exist', () => { + spyOn(mockProject, 'fileExists').and.returnValue(false); + const externalTemplates = getExternalFiles(mockProject); + expect(externalTemplates.length).toBe(0); + }); }); describe(`with config 'angularOnly = true`, () => {