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); diff --git a/packages/language-server/src/plugins/typescript/service.ts b/packages/language-server/src/plugins/typescript/service.ts index dfa2f0ea7..008ae99fc 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 { @@ -239,6 +246,7 @@ async function createLanguageService( } function updateProjectFiles(): void { + projectVersion++; const projectFileCountBefore = snapshotManager.getProjectFileNames().length; snapshotManager.updateProjectFiles(); const projectFileCountAfter = snapshotManager.getProjectFileNames().length; 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