Skip to content

Commit 7c76ec5

Browse files
authored
fix: check project files update more aggressively before assigning service (#2518)
#2516 Most of the time, the didOpen request is earlier than the watcher event. So if the file doesn't exist in the GlobalSnapshotManager we manually invoke the project file update check. This won't cause 2 project files check because if the file already is a project file we won't check project files.
1 parent 837b61f commit 7c76ec5

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

packages/language-server/src/plugins/typescript/service.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export interface LanguageServiceContainer {
4040
deleteSnapshot(filePath: string): void;
4141
invalidateModuleCache(filePath: string[]): void;
4242
scheduleProjectFileUpdate(watcherNewFiles: string[]): void;
43-
ensureProjectFileUpdates(): void;
43+
ensureProjectFileUpdates(newFile?: string): void;
4444
updateTsOrJsFile(fileName: string, changes?: TextDocumentContentChangeEvent[]): void;
4545
/**
4646
* Checks if a file is present in the project.
@@ -225,7 +225,7 @@ export async function getService(
225225
service: LanguageServiceContainer,
226226
triedTsConfig: Set<string>
227227
): Promise<LanguageServiceContainer | undefined> {
228-
service.ensureProjectFileUpdates();
228+
service.ensureProjectFileUpdates(path);
229229
if (service.snapshotManager.isProjectFile(path)) {
230230
return service;
231231
}
@@ -648,9 +648,23 @@ async function createLanguageService(
648648
}
649649
}
650650

651-
function ensureProjectFileUpdates(): void {
651+
function ensureProjectFileUpdates(newFile?: string): void {
652652
const info = parsedTsConfigInfo.get(tsconfigPath);
653-
if (!info || !info.pendingProjectFileUpdate) {
653+
if (!info) {
654+
return;
655+
}
656+
657+
if (
658+
newFile &&
659+
!info.pendingProjectFileUpdate &&
660+
// no global snapshots yet when initial load pending
661+
!snapshotManager.isProjectFile(newFile) &&
662+
!docContext.globalSnapshotsManager.get(newFile)
663+
) {
664+
scheduleProjectFileUpdate([newFile]);
665+
}
666+
667+
if (!info.pendingProjectFileUpdate) {
654668
return;
655669
}
656670
const projectFileCountBefore = snapshotManager.getProjectFileNames().length;

packages/language-server/test/plugins/typescript/service.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,33 @@ describe('service', () => {
657657
assert.deepStrictEqual(findError(ls2), undefined);
658658
});
659659

660+
it('assigns newly created files to the right service before the watcher trigger', async () => {
661+
const dirPath = getRandomVirtualDirPath(testDir);
662+
const { virtualSystem, lsDocumentContext, rootUris } = setup();
663+
664+
const tsconfigPath = path.join(dirPath, 'tsconfig.json');
665+
virtualSystem.writeFile(
666+
tsconfigPath,
667+
JSON.stringify({
668+
compilerOptions: {}
669+
})
670+
);
671+
672+
const svelteFilePath = path.join(dirPath, 'random.svelte');
673+
674+
virtualSystem.writeFile(svelteFilePath, '');
675+
676+
const ls = await getService(svelteFilePath, rootUris, lsDocumentContext);
677+
678+
assert.equal(normalizePath(ls.tsconfigPath), normalizePath(tsconfigPath));
679+
680+
const svelteFilePath2 = path.join(dirPath, 'random2.svelte');
681+
virtualSystem.writeFile(svelteFilePath2, '');
682+
683+
const ls2 = await getService(svelteFilePath2, rootUris, lsDocumentContext);
684+
assert.equal(normalizePath(ls2.tsconfigPath), normalizePath(tsconfigPath));
685+
});
686+
660687
function getSemanticDiagnosticsMessages(ls: LanguageServiceContainer, filePath: string) {
661688
return ls
662689
.getService()

0 commit comments

Comments
 (0)