diff --git a/packages/vue-language-server/src/projects.ts b/packages/vue-language-server/src/projects.ts index fccb18a583..a216353500 100644 --- a/packages/vue-language-server/src/projects.ts +++ b/packages/vue-language-server/src/projects.ts @@ -31,6 +31,23 @@ export function createProjects( uri: string, time: number, } | undefined; + const fileExistsCache = shared.createPathMap(); + const directoryExistsCache = shared.createPathMap(); + const sys: ts.System = { + ...ts.sys, + fileExists(path: string) { + if (!fileExistsCache.fsPathHas(path)) { + fileExistsCache.fsPathSet(path, ts.sys.fileExists(path)); + } + return fileExistsCache.fsPathGet(path)!; + }, + directoryExists(path: string) { + if (!directoryExistsCache.fsPathHas(path)) { + directoryExistsCache.fsPathSet(path, ts.sys.directoryExists(path)); + } + return directoryExistsCache.fsPathGet(path)!; + }, + }; const workspaces = new Map>(); @@ -40,6 +57,7 @@ export function createProjects( languageConfigs, rootPath, ts, + sys, tsLocalized, options, documents, @@ -77,6 +95,15 @@ export function createProjects( }); connection.onDidChangeWatchedFiles(async handler => { + for (const change of handler.changes) { + if (change.type === vscode.FileChangeType.Created) { + fileExistsCache.uriSet(change.uri, true); + } + else if (change.type === vscode.FileChangeType.Deleted) { + fileExistsCache.uriSet(change.uri, false); + } + } + const tsConfigChanges: vscode.FileEvent[] = []; const scriptChanges: vscode.FileEvent[] = []; @@ -233,6 +260,7 @@ function createWorkspace( languageConfigs: LanguageConfigs, rootPath: string, ts: typeof import('typescript/lib/tsserverlibrary'), + sys: ts.System, tsLocalized: ts.MapLike | undefined, options: shared.ServerInitializationOptions, documents: vscode.TextDocuments, @@ -241,12 +269,12 @@ function createWorkspace( getInferredCompilerOptions: () => Promise, ) { - const rootTsConfigs = ts.sys.readDirectory(rootPath, rootTsConfigNames, undefined, ['**/*']); + const rootTsConfigs = sys.readDirectory(rootPath, rootTsConfigNames, undefined, ['**/*']); const projects = shared.createPathMap(); let inferredProject: Project | undefined; const getRootPath = () => rootPath; - const workspaceSys = ts.sys.getCurrentDirectory() === rootPath ? ts.sys : new Proxy(ts.sys, { + const workspaceSys = sys.getCurrentDirectory() === rootPath ? sys : new Proxy(sys, { get(target, prop) { const fn = target[prop as keyof typeof target]; if (typeof fn === 'function') { @@ -380,13 +408,13 @@ function createWorkspace( let tsConfigPath = projectReference.path; // fix https://github.com/johnsoncodehk/volar/issues/712 - if (!ts.sys.fileExists(tsConfigPath) && ts.sys.directoryExists(tsConfigPath)) { + if (!sys.fileExists(tsConfigPath) && sys.directoryExists(tsConfigPath)) { const newTsConfigPath = path.join(tsConfigPath, 'tsconfig.json'); const newJsConfigPath = path.join(tsConfigPath, 'jsconfig.json'); - if (ts.sys.fileExists(newTsConfigPath)) { + if (sys.fileExists(newTsConfigPath)) { tsConfigPath = newTsConfigPath; } - else if (ts.sys.fileExists(newJsConfigPath)) { + else if (sys.fileExists(newJsConfigPath)) { tsConfigPath = newJsConfigPath; } } diff --git a/packages/vue-language-service/src/languageService.ts b/packages/vue-language-service/src/languageService.ts index b43bb88f55..4d66736c76 100644 --- a/packages/vue-language-service/src/languageService.ts +++ b/packages/vue-language-service/src/languageService.ts @@ -270,9 +270,6 @@ export function createLanguageService( const failedLookupLocations: string[] = (resolveResult as any).failedLookupLocations; const dirs = new Set(); - const fileExists = vueLsHost.fileExists ?? ts.sys.fileExists; - const directoryExists = vueLsHost.directoryExists ?? ts.sys.directoryExists; - for (const failed of failedLookupLocations) { let path = failed; const fileName = upath.basename(path); @@ -285,12 +282,12 @@ export function createLanguageService( else { continue; } - if (fileExists(path)) { + if (vueLsHost.fileExists(path)) { return isUri ? shared.fsPathToUri(path) : path; } } for (const dir of dirs) { - if (directoryExists(dir)) { + if (vueLsHost.directoryExists?.(dir) ?? true) { return isUri ? shared.fsPathToUri(dir) : dir; } }