From 62ba0acfb501c280dfd7cbcb06dccb28d41774a4 Mon Sep 17 00:00:00 2001 From: Keen Yee Liau Date: Tue, 28 Apr 2020 14:56:56 -0700 Subject: [PATCH] test(language-service): do not invalidate @angular/core (#36845) Fix typo and add test cases for https://github.com/angular/angular/pull/36783 PR closes https://github.com/angular/vscode-ng-language-service/issues/713 PR Close #36845 --- .../language-service/src/typescript_host.ts | 8 +++- .../test/typescript_host_spec.ts | 39 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/packages/language-service/src/typescript_host.ts b/packages/language-service/src/typescript_host.ts index cdf522a6e6..13ae098310 100644 --- a/packages/language-service/src/typescript_host.ts +++ b/packages/language-service/src/typescript_host.ts @@ -220,8 +220,12 @@ export class TypeScriptServiceHost implements LanguageServiceHost { const ANGULAR_CORE = '@angular/core'; const corePath = this.reflectorHost.moduleNameToFileName(ANGULAR_CORE); for (const {fileName} of program.getSourceFiles()) { - // If the `@angular/core` has been edited, the language service should be restart, - // so ignore the change of `@angular/core`. + // If `@angular/core` is edited, the language service would have to be + // restarted, so ignore changes to `@angular/core`. + // When the StaticReflector is initialized at startup, it loads core + // symbols from @angular/core by calling initializeConversionMap(). This + // is only done once. If the file is invalidated, some of the core symbols + // will be lost permanently. if (fileName === corePath) { continue; } diff --git a/packages/language-service/test/typescript_host_spec.ts b/packages/language-service/test/typescript_host_spec.ts index a8a724aa53..02978e0736 100644 --- a/packages/language-service/test/typescript_host_spec.ts +++ b/packages/language-service/test/typescript_host_spec.ts @@ -176,4 +176,43 @@ describe('TypeScriptServiceHost', () => { // files have changed. expect(newModules).toBe(oldModules); }); + + it('should not reload @angular/core on changes', () => { + const tsLSHost = new MockTypescriptHost(['/app/main.ts']); + const tsLS = ts.createLanguageService(tsLSHost); + const ngLSHost = new TypeScriptServiceHost(tsLSHost, tsLS); + const oldModules = ngLSHost.getAnalyzedModules(); + const ngCore = '/node_modules/@angular/core/core.d.ts'; + const originalContent = tsLSHost.readFile(ngCore); + const oldVersion = tsLSHost.getScriptVersion(ngCore); + tsLSHost.override(ngCore, originalContent + '\n\n'); + const newVersion = tsLSHost.getScriptVersion(ngCore); + expect(newVersion).not.toBe(oldVersion); + const newModules = ngLSHost.getAnalyzedModules(); + // Had @angular/core been invalidated, we'd get a different instance of + // analyzed modules, with one module missing - ApplicationModule + // The absence of this module will cause language service to stop working. + expect(newModules).toBe(oldModules); + const ApplicationModule = + newModules.ngModules.find(m => m.type.reference.name === 'ApplicationModule'); + expect(ApplicationModule).toBeDefined(); + }); + + it('should reload @angular/common on changes', () => { + const tsLSHost = new MockTypescriptHost(['/app/main.ts']); + const tsLS = ts.createLanguageService(tsLSHost); + const ngLSHost = new TypeScriptServiceHost(tsLSHost, tsLS); + const oldModules = ngLSHost.getAnalyzedModules(); + const ngCommon = '/node_modules/@angular/common/common.d.ts'; + const originalContent = tsLSHost.readFile(ngCommon); + const oldVersion = tsLSHost.getScriptVersion(ngCommon); + tsLSHost.override(ngCommon, originalContent + '\n\n'); + const newVersion = tsLSHost.getScriptVersion(ngCommon); + expect(newVersion).not.toBe(oldVersion); + const newModules = ngLSHost.getAnalyzedModules(); + // We get a new instance of analyzed modules + expect(newModules).not.toBe(oldModules); + // But the content should be exactly the same + expect(newModules).toEqual(oldModules); + }); });