diff --git a/packages/language-server/src/plugins/typescript/service.ts b/packages/language-server/src/plugins/typescript/service.ts index 0e0d0f27a..caf8f0350 100644 --- a/packages/language-server/src/plugins/typescript/service.ts +++ b/packages/language-server/src/plugins/typescript/service.ts @@ -40,7 +40,7 @@ export interface LanguageServiceContainer { deleteSnapshot(filePath: string): void; invalidateModuleCache(filePath: string[]): void; scheduleProjectFileUpdate(watcherNewFiles: string[]): void; - ensureProjectFileUpdates(): void; + ensureProjectFileUpdates(newFile?: string): void; updateTsOrJsFile(fileName: string, changes?: TextDocumentContentChangeEvent[]): void; /** * Checks if a file is present in the project. @@ -225,7 +225,7 @@ export async function getService( service: LanguageServiceContainer, triedTsConfig: Set ): Promise { - service.ensureProjectFileUpdates(); + service.ensureProjectFileUpdates(path); if (service.snapshotManager.isProjectFile(path)) { return service; } @@ -648,9 +648,23 @@ async function createLanguageService( } } - function ensureProjectFileUpdates(): void { + function ensureProjectFileUpdates(newFile?: string): void { const info = parsedTsConfigInfo.get(tsconfigPath); - if (!info || !info.pendingProjectFileUpdate) { + if (!info) { + return; + } + + if ( + newFile && + !info.pendingProjectFileUpdate && + // no global snapshots yet when initial load pending + !snapshotManager.isProjectFile(newFile) && + !docContext.globalSnapshotsManager.get(newFile) + ) { + scheduleProjectFileUpdate([newFile]); + } + + if (!info.pendingProjectFileUpdate) { return; } const projectFileCountBefore = snapshotManager.getProjectFileNames().length; diff --git a/packages/language-server/test/plugins/typescript/service.test.ts b/packages/language-server/test/plugins/typescript/service.test.ts index 71db7f064..e0aa9ffd4 100644 --- a/packages/language-server/test/plugins/typescript/service.test.ts +++ b/packages/language-server/test/plugins/typescript/service.test.ts @@ -657,6 +657,33 @@ describe('service', () => { assert.deepStrictEqual(findError(ls2), undefined); }); + it('assigns newly created files to the right service before the watcher trigger', async () => { + const dirPath = getRandomVirtualDirPath(testDir); + const { virtualSystem, lsDocumentContext, rootUris } = setup(); + + const tsconfigPath = path.join(dirPath, 'tsconfig.json'); + virtualSystem.writeFile( + tsconfigPath, + JSON.stringify({ + compilerOptions: {} + }) + ); + + const svelteFilePath = path.join(dirPath, 'random.svelte'); + + virtualSystem.writeFile(svelteFilePath, ''); + + const ls = await getService(svelteFilePath, rootUris, lsDocumentContext); + + assert.equal(normalizePath(ls.tsconfigPath), normalizePath(tsconfigPath)); + + const svelteFilePath2 = path.join(dirPath, 'random2.svelte'); + virtualSystem.writeFile(svelteFilePath2, ''); + + const ls2 = await getService(svelteFilePath2, rootUris, lsDocumentContext); + assert.equal(normalizePath(ls2.tsconfigPath), normalizePath(tsconfigPath)); + }); + function getSemanticDiagnosticsMessages(ls: LanguageServiceContainer, filePath: string) { return ls .getService()