From 519e916354fee59f8d80be63264ce3dc3c222bfc Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Tue, 9 Jul 2024 20:34:46 +0800 Subject: [PATCH] fix(language-core): getProjectVersion param has no effect --- packages/component-meta/lib/base.ts | 13 ++++----- packages/language-core/lib/languageModule.ts | 27 ++++++++++++++----- packages/language-server/lib/initialize.ts | 15 +++++------ packages/language-server/node.ts | 1 - .../tests/utils/createTester.ts | 17 +++++------- .../language-service/tests/utils/format.ts | 1 - packages/tsc/index.ts | 13 ++++----- packages/tsc/tests/dts.spec.ts | 13 ++++----- packages/typescript-plugin/index.ts | 13 ++++----- 9 files changed, 53 insertions(+), 60 deletions(-) diff --git a/packages/component-meta/lib/base.ts b/packages/component-meta/lib/base.ts index f83a497cce..d2e7302560 100644 --- a/packages/component-meta/lib/base.ts +++ b/packages/component-meta/lib/base.ts @@ -147,14 +147,11 @@ export function baseCreate( const vueLanguagePlugin = vue.createVueLanguagePlugin( ts, id => id, - () => projectHost.getProjectVersion?.() ?? '', - fileName => { - const fileMap = new vue.FileMap(ts.sys.useCaseSensitiveFileNames); - for (const vueFileName of projectHost.getScriptFileNames()) { - fileMap.set(vueFileName, undefined); - } - return fileMap.has(fileName); - }, + vue.createRootFileChecker( + projectHost.getProjectVersion ? () => projectHost.getProjectVersion!() : undefined, + () => projectHost.getScriptFileNames(), + ts.sys.useCaseSensitiveFileNames + ), projectHost.getCompilationSettings(), vueCompilerOptions ); diff --git a/packages/language-core/lib/languageModule.ts b/packages/language-core/lib/languageModule.ts index 2586c82465..8588b67bd3 100644 --- a/packages/language-core/lib/languageModule.ts +++ b/packages/language-core/lib/languageModule.ts @@ -1,6 +1,6 @@ /// -import { forEachEmbeddedCode, type LanguagePlugin } from '@volar/language-core'; +import { FileMap, forEachEmbeddedCode, type LanguagePlugin } from '@volar/language-core'; import * as CompilerDOM from '@vue/compiler-dom'; import type * as ts from 'typescript'; import { getBasePlugins } from './plugins'; @@ -53,10 +53,28 @@ function getFileRegistryKey( return JSON.stringify(values); } +export function createRootFileChecker( + getProjectVersion: (() => string) | undefined, + getRootFileNames: () => string[], + caseSensitive: boolean +) { + const fileNames = new FileMap(caseSensitive); + let projectVersion: string | undefined; + return (fileName: string) => { + if (!getProjectVersion || projectVersion !== getProjectVersion()) { + projectVersion = getProjectVersion?.(); + fileNames.clear(); + for (const rootFileName of getRootFileNames()) { + fileNames.set(rootFileName, undefined); + } + } + return fileNames.has(fileName); + }; +} + export function createVueLanguagePlugin( ts: typeof import('typescript'), asFileName: (scriptId: T) => string, - getProjectVersion: () => string, isRootFile: (fileName: string) => boolean, compilerOptions: ts.CompilerOptions, vueCompilerOptions: VueCompilerOptions @@ -80,8 +98,6 @@ export function createVueLanguagePlugin( const vitePressSfcPlugin = useMdFilePlugin(pluginContext); const petiteVueSfcPlugin = useHtmlFilePlugin(pluginContext); - let canonicalRootFileNamesVersion: string | undefined; - return { getLanguageId(scriptId) { if (vueCompilerOptions.extensions.some(ext => asFileName(scriptId).endsWith(ext))) { @@ -97,9 +113,6 @@ export function createVueLanguagePlugin( createVirtualCode(scriptId, languageId, snapshot) { if (languageId === 'vue' || languageId === 'markdown' || languageId === 'html') { const fileName = asFileName(scriptId); - if (getProjectVersion() !== canonicalRootFileNamesVersion) { - canonicalRootFileNamesVersion = getProjectVersion(); - } if (!pluginContext.globalTypesHolder && isRootFile(fileName)) { pluginContext.globalTypesHolder = fileName; } diff --git a/packages/language-server/lib/initialize.ts b/packages/language-server/lib/initialize.ts index 34def32f86..30dca84741 100644 --- a/packages/language-server/lib/initialize.ts +++ b/packages/language-server/lib/initialize.ts @@ -1,6 +1,6 @@ import type { LanguageServer } from '@volar/language-server'; import { createTypeScriptProject } from '@volar/language-server/node'; -import { createParsedCommandLine, createVueLanguagePlugin, FileMap, resolveVueCompilerOptions, VueCompilerOptions } from '@vue/language-core'; +import { createParsedCommandLine, createRootFileChecker, createVueLanguagePlugin, resolveVueCompilerOptions, VueCompilerOptions } from '@vue/language-core'; import { Disposable, getFullLanguageServicePlugins, InitializeParams } from '@vue/language-service'; import type * as ts from 'typescript'; @@ -42,14 +42,11 @@ export function initialize( languagePlugins: [createVueLanguagePlugin( ts, s => uriConverter.asFileName(s), - () => projectHost.getProjectVersion?.() ?? '', - fileName => { - const fileMap = new FileMap(sys.useCaseSensitiveFileNames ?? false); - for (const vueFileName of projectHost.getScriptFileNames() ?? []) { - fileMap.set(vueFileName, undefined); - } - return fileMap.has(fileName); - }, + createRootFileChecker( + projectHost.getProjectVersion ? () => projectHost.getProjectVersion!() : undefined, + () => projectHost.getScriptFileNames(), + sys.useCaseSensitiveFileNames + ), compilerOptions, vueCompilerOptions )], diff --git a/packages/language-server/node.ts b/packages/language-server/node.ts index 888926236c..c1c6652f62 100644 --- a/packages/language-server/node.ts +++ b/packages/language-server/node.ts @@ -30,7 +30,6 @@ connection.onInitialize(params => { languagePlugins: [createVueLanguagePlugin( ts, asFileName, - () => '', () => false, commandLine.options, commandLine.vueOptions diff --git a/packages/language-service/tests/utils/createTester.ts b/packages/language-service/tests/utils/createTester.ts index 5fe69e8487..d79c3a5614 100644 --- a/packages/language-service/tests/utils/createTester.ts +++ b/packages/language-service/tests/utils/createTester.ts @@ -1,9 +1,9 @@ -import { FileMap, ProjectContext, createLanguage, createLanguageService, createUriMap } from '@volar/language-service'; +import { ProjectContext, createLanguage, createLanguageService, createUriMap } from '@volar/language-service'; import { TypeScriptProjectHost, createLanguageServiceHost, resolveFileLanguageId } from '@volar/typescript'; import * as path from 'path'; import * as ts from 'typescript'; import { URI } from 'vscode-uri'; -import { createParsedCommandLine, createVueLanguagePlugin, getFullLanguageServicePlugins } from '../..'; +import { createParsedCommandLine, createRootFileChecker, createVueLanguagePlugin, getFullLanguageServicePlugins } from '../..'; import { createMockServiceEnv, fileNameToUri, uriToFileName } from './mockEnv'; export const rootUri = URI.file(path.resolve(__dirname, '../../../../test-workspace/language-service')); @@ -27,14 +27,11 @@ function createTester(rootUri: URI) { const vueLanguagePlugin = createVueLanguagePlugin( ts, uriToFileName, - () => projectHost.getProjectVersion?.() ?? '', - fileName => { - const fileMap = new FileMap(ts.sys.useCaseSensitiveFileNames); - for (const vueFileName of projectHost.getScriptFileNames()) { - fileMap.set(vueFileName, undefined); - } - return fileMap.has(fileName); - }, + createRootFileChecker( + projectHost.getProjectVersion ? () => projectHost.getProjectVersion!() : undefined, + () => projectHost.getScriptFileNames(), + ts.sys.useCaseSensitiveFileNames + ), parsedCommandLine.options, parsedCommandLine.vueOptions ); diff --git a/packages/language-service/tests/utils/format.ts b/packages/language-service/tests/utils/format.ts index 8b62801b82..1f236f21fa 100644 --- a/packages/language-service/tests/utils/format.ts +++ b/packages/language-service/tests/utils/format.ts @@ -8,7 +8,6 @@ const resolvedVueOptions = resolveVueCompilerOptions({}); const vueLanguagePlugin = createVueLanguagePlugin( ts, () => '', - () => '', () => false, {}, resolvedVueOptions diff --git a/packages/tsc/index.ts b/packages/tsc/index.ts index 96f216d061..0889132792 100644 --- a/packages/tsc/index.ts +++ b/packages/tsc/index.ts @@ -32,14 +32,11 @@ export function run() { const vueLanguagePlugin = vue.createVueLanguagePlugin( ts, id => id, - () => '', - fileName => { - const fileMap = new vue.FileMap(options.host?.useCaseSensitiveFileNames?.() ?? false); - for (const vueFileName of options.rootNames.map(rootName => rootName.replace(windowsPathReg, '/'))) { - fileMap.set(vueFileName, undefined); - } - return fileMap.has(fileName); - }, + vue.createRootFileChecker( + undefined, + () => options.rootNames.map(rootName => rootName.replace(windowsPathReg, '/')), + options.host?.useCaseSensitiveFileNames?.() ?? false + ), options.options, vueOptions ); diff --git a/packages/tsc/tests/dts.spec.ts b/packages/tsc/tests/dts.spec.ts index efb4fb6f30..d0ac81b6fc 100644 --- a/packages/tsc/tests/dts.spec.ts +++ b/packages/tsc/tests/dts.spec.ts @@ -34,14 +34,11 @@ describe('vue-tsc-dts', () => { const vueLanguagePlugin = vue.createVueLanguagePlugin( ts, id => id, - () => '', - fileName => { - const fileMap = new vue.FileMap(options.host?.useCaseSensitiveFileNames?.() ?? false); - for (const vueFileName of options.rootNames.map(rootName => rootName.replace(windowsPathReg, '/'))) { - fileMap.set(vueFileName, undefined); - } - return fileMap.has(fileName); - }, + vue.createRootFileChecker( + undefined, + () => options.rootNames.map(rootName => rootName.replace(windowsPathReg, '/')), + options.host?.useCaseSensitiveFileNames?.() ?? false + ), options.options, vueOptions ); diff --git a/packages/typescript-plugin/index.ts b/packages/typescript-plugin/index.ts index 7269ab7f5e..37abdb3dd1 100644 --- a/packages/typescript-plugin/index.ts +++ b/packages/typescript-plugin/index.ts @@ -11,16 +11,13 @@ const plugin = createLanguageServicePlugin( const languagePlugin = vue.createVueLanguagePlugin( ts, id => id, - () => info.languageServiceHost.getProjectVersion?.() ?? '', info.project.projectKind === ts.server.ProjectKind.Inferred ? () => true - : fileName => { - const fileMap = new vue.FileMap(info.languageServiceHost.useCaseSensitiveFileNames?.() ?? false); - for (const vueFileName of externalFiles.get(info.project) ?? []) { - fileMap.set(vueFileName, undefined); - } - return fileMap.has(fileName); - }, + : vue.createRootFileChecker( + info.languageServiceHost.getProjectVersion ? () => info.languageServiceHost.getProjectVersion!() : undefined, + () => externalFiles.get(info.project) ?? [], + info.languageServiceHost.useCaseSensitiveFileNames?.() ?? false + ), info.languageServiceHost.getCompilationSettings(), vueOptions );