From 5c9c0a1f7e6c97ce5878c4afb962f350d546e92a Mon Sep 17 00:00:00 2001 From: "Lyu, Wei Da" Date: Fri, 5 Nov 2021 18:06:23 +0800 Subject: [PATCH 1/4] (perf) implement typescript project version --- .../src/plugins/typescript/service.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/language-server/src/plugins/typescript/service.ts b/packages/language-server/src/plugins/typescript/service.ts index dfa2f0ea7..5a39e3ddb 100644 --- a/packages/language-server/src/plugins/typescript/service.ts +++ b/packages/language-server/src/plugins/typescript/service.ts @@ -127,6 +127,7 @@ async function createLanguageService( ].map((f) => ts.sys.resolvePath(resolve(svelteTsPath, f))); let languageServiceReducedMode = false; + let projectVersion = 0; const host: ts.LanguageServiceHost = { getCompilationSettings: () => compilerOptions, @@ -148,13 +149,19 @@ async function createLanguageService( readDirectory: svelteModuleLoader.readDirectory, getDirectories: ts.sys.getDirectories, useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames, - getScriptKind: (fileName: string) => getSnapshot(fileName).scriptKind + getScriptKind: (fileName: string) => getSnapshot(fileName).scriptKind, + getProjectVersion: () => projectVersion.toString() }; + let languageService = ts.createLanguageService(host); const transformationConfig = { transformOnTemplateError: docContext.transformOnTemplateError }; + docContext.globalSnapshotsManager.onChange(() => { + projectVersion++; + }); + reduceLanguageServiceCapabilityIfFileSizeTooBig(); return { @@ -171,6 +178,7 @@ async function createLanguageService( }; function deleteSnapshot(filePath: string): void { + projectVersion++; svelteModuleLoader.deleteFromModuleCache(filePath); snapshotManager.delete(filePath); } @@ -188,6 +196,7 @@ async function createLanguageService( return prevSnapshot; } + projectVersion++; if (!prevSnapshot) { svelteModuleLoader.deleteUnresolvedResolutionsFromCache(filePath); } @@ -210,6 +219,7 @@ async function createLanguageService( return prevSnapshot; } + projectVersion++; svelteModuleLoader.deleteUnresolvedResolutionsFromCache(filePath); const newSnapshot = DocumentSnapshot.fromFilePath( filePath, @@ -239,6 +249,7 @@ async function createLanguageService( } function updateProjectFiles(): void { + projectVersion++; const projectFileCountBefore = snapshotManager.getProjectFileNames().length; snapshotManager.updateProjectFiles(); const projectFileCountAfter = snapshotManager.getProjectFileNames().length; From fd6b7ccbc5ab72c413a7e6f821d7df952af28af0 Mon Sep 17 00:00:00 2001 From: "Lyu, Wei Da" Date: Tue, 9 Nov 2021 13:53:42 +0800 Subject: [PATCH 2/4] simplify As these are also being covered by globalSnapshotManager change event --- packages/language-server/src/plugins/typescript/service.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/language-server/src/plugins/typescript/service.ts b/packages/language-server/src/plugins/typescript/service.ts index 5a39e3ddb..008ae99fc 100644 --- a/packages/language-server/src/plugins/typescript/service.ts +++ b/packages/language-server/src/plugins/typescript/service.ts @@ -178,7 +178,6 @@ async function createLanguageService( }; function deleteSnapshot(filePath: string): void { - projectVersion++; svelteModuleLoader.deleteFromModuleCache(filePath); snapshotManager.delete(filePath); } @@ -196,7 +195,6 @@ async function createLanguageService( return prevSnapshot; } - projectVersion++; if (!prevSnapshot) { svelteModuleLoader.deleteUnresolvedResolutionsFromCache(filePath); } @@ -219,7 +217,6 @@ async function createLanguageService( return prevSnapshot; } - projectVersion++; svelteModuleLoader.deleteUnresolvedResolutionsFromCache(filePath); const newSnapshot = DocumentSnapshot.fromFilePath( filePath, From 7ccf59b88aece45e8fd6607c2dbca722022ab7c3 Mon Sep 17 00:00:00 2001 From: "Lyu, Wei Da" Date: Wed, 10 Nov 2021 15:45:29 +0800 Subject: [PATCH 3/4] detect project version change in updateTsOrJsFile --- .../language-server/src/plugins/typescript/SnapshotManager.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/language-server/src/plugins/typescript/SnapshotManager.ts b/packages/language-server/src/plugins/typescript/SnapshotManager.ts index 8b95b2a5f..d7b19c0ce 100644 --- a/packages/language-server/src/plugins/typescript/SnapshotManager.ts +++ b/packages/language-server/src/plugins/typescript/SnapshotManager.ts @@ -48,6 +48,7 @@ export class GlobalSnapshotsManager { return; } previousSnapshot.update(changes); + this.emitter.emit('change', fileName, previousSnapshot); return previousSnapshot; } else { const newSnapshot = DocumentSnapshot.fromNonSvelteFilePath(fileName); From 169e27460ad8edd14a5690cf3d98601f3e4a582e Mon Sep 17 00:00:00 2001 From: "Lyu, Wei Da" Date: Wed, 10 Nov 2021 17:12:47 +0800 Subject: [PATCH 4/4] add a test for update ts/js --- .../features/DiagnosticsProvider.test.ts | 26 +++++++++++++++++++ .../diagnostics-imported-js-update.svelte | 5 ++++ .../testfiles/diagnostics/empty-export.ts | 1 + 3 files changed, 32 insertions(+) create mode 100644 packages/language-server/test/plugins/typescript/testfiles/diagnostics/diagnostics-imported-js-update.svelte create mode 100644 packages/language-server/test/plugins/typescript/testfiles/diagnostics/empty-export.ts diff --git a/packages/language-server/test/plugins/typescript/features/DiagnosticsProvider.test.ts b/packages/language-server/test/plugins/typescript/features/DiagnosticsProvider.test.ts index c3b9ffe84..959368aa0 100644 --- a/packages/language-server/test/plugins/typescript/features/DiagnosticsProvider.test.ts +++ b/packages/language-server/test/plugins/typescript/features/DiagnosticsProvider.test.ts @@ -1023,6 +1023,32 @@ describe('DiagnosticsProvider', () => { assert.deepStrictEqual(diagnostics3.length, 1); }).timeout(5000); + it('notices update of imported module', async () => { + const { plugin, document, lsAndTsDocResolver } = setup( + 'diagnostics-imported-js-update.svelte' + ); + + const newFilePath = normalizePath(path.join(testDir, 'empty-export.ts')) || ''; + await lsAndTsDocResolver.getSnapshot(newFilePath); + + const diagnostics1 = await plugin.getDiagnostics(document); + assert.deepStrictEqual( + diagnostics1[0]?.message, + "Module '\"./empty-export\"' has no exported member 'foo'." + ); + + await lsAndTsDocResolver.updateExistingTsOrJsFile(newFilePath, [ + { + range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } }, + text: 'export function foo() {}' + } + ]); + + const diagnostics2 = await plugin.getDiagnostics(document); + assert.deepStrictEqual(diagnostics2.length, 0); + await lsAndTsDocResolver.deleteSnapshot(newFilePath); + }).timeout(5000); + it('notices file changes in all services that reference that file', async () => { const { plugin, document, docManager, lsAndTsDocResolver } = setup( 'different-ts-service.svelte' diff --git a/packages/language-server/test/plugins/typescript/testfiles/diagnostics/diagnostics-imported-js-update.svelte b/packages/language-server/test/plugins/typescript/testfiles/diagnostics/diagnostics-imported-js-update.svelte new file mode 100644 index 000000000..7882f3b5f --- /dev/null +++ b/packages/language-server/test/plugins/typescript/testfiles/diagnostics/diagnostics-imported-js-update.svelte @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/packages/language-server/test/plugins/typescript/testfiles/diagnostics/empty-export.ts b/packages/language-server/test/plugins/typescript/testfiles/diagnostics/empty-export.ts new file mode 100644 index 000000000..8cec2e9ce --- /dev/null +++ b/packages/language-server/test/plugins/typescript/testfiles/diagnostics/empty-export.ts @@ -0,0 +1 @@ +export {}; \ No newline at end of file