diff --git a/packages/typescript-vue-plugin/src/index.ts b/packages/typescript-vue-plugin/src/index.ts index e799f555d..f7265037d 100644 --- a/packages/typescript-vue-plugin/src/index.ts +++ b/packages/typescript-vue-plugin/src/index.ts @@ -35,7 +35,7 @@ const init: ts.server.PluginModuleFactory = (modules) => { }; } - const vueTsLsHost: vue.VueLanguageServiceHost = { + const vueTsLsHost: vue.LanguageServiceHost = { getNewLine: () => info.project.getNewLine(), useCaseSensitiveFileNames: () => info.project.useCaseSensitiveFileNames(), readFile: path => info.project.readFile(path), @@ -46,7 +46,6 @@ const init: ts.server.PluginModuleFactory = (modules) => { readDirectory: (path, extensions, exclude, include, depth) => info.project.readDirectory(path, extensions, exclude, include, depth), realpath: info.project.realpath ? path => info.project.realpath!(path) : undefined, getCompilationSettings: () => info.project.getCompilationSettings(), - getVueCompilationSettings: () => parsed.vueOptions, getCurrentDirectory: () => info.project.getCurrentDirectory(), getDefaultLibFileName: () => info.project.getDefaultLibFileName(), getProjectVersion: () => info.project.getProjectVersion(), @@ -58,7 +57,7 @@ const init: ts.server.PluginModuleFactory = (modules) => { getScriptVersion: (fileName) => info.project.getScriptVersion(fileName), getScriptSnapshot: (fileName) => info.project.getScriptSnapshot(fileName), }; - const vueTsLs = vueTs.createLanguageService(vueTsLsHost); + const vueTsLs = vueTs.createLanguageService(vueTsLsHost, parsed.vueOptions, ts); return new Proxy(info.languageService, { get: (target: any, property: keyof ts.LanguageService) => { diff --git a/packages/vue-component-meta/src/index.ts b/packages/vue-component-meta/src/index.ts index 65a56ec32..2e84faadc 100644 --- a/packages/vue-component-meta/src/index.ts +++ b/packages/vue-component-meta/src/index.ts @@ -63,7 +63,7 @@ function createComponentMetaCheckerWorker( const scriptSnapshots = new Map(); const scriptVersions = new Map(); - const _host: vue.VueLanguageServiceHost = { + const _host: vue.LanguageServiceHost = { ...ts.sys, getProjectVersion: () => projectVersion.toString(), getDefaultLibFileName: (options) => ts.getDefaultLibFilePath(options), // should use ts.getDefaultLibFilePath not ts.getDefaultLibFileName @@ -81,11 +81,10 @@ function createComponentMetaCheckerWorker( } return scriptSnapshots.get(fileName); }, - getVueCompilationSettings: () => parsedCommandLine.vueOptions, }; return { - ...baseCreate(_host, checkerOptions, globalComponentName, ts), + ...baseCreate(_host, parsedCommandLine.vueOptions, checkerOptions, globalComponentName, ts), updateFile(fileName: string, text: string) { fileName = (fileName as path.OsPath).replace(/\\/g, '/') as path.PosixPath; scriptSnapshots.set(fileName, ts.ScriptSnapshot.fromString(text)); @@ -111,14 +110,15 @@ function createComponentMetaCheckerWorker( } export function baseCreate( - _host: vue.VueLanguageServiceHost, + _host: vue.LanguageServiceHost, + vueCompilerOptions: vue.VueCompilerOptions, checkerOptions: MetaCheckerOptions, globalComponentName: string, ts: typeof import('typescript/lib/tsserverlibrary'), ) { const globalComponentSnapshot = ts.ScriptSnapshot.fromString(''); const metaSnapshots: Record = {}; - const host = new Proxy>({ + const host = new Proxy>({ getScriptFileNames: () => { const names = _host.getScriptFileNames(); return [ @@ -149,8 +149,7 @@ export function baseCreate( } return _host[prop as keyof typeof _host]; }, - }) as vue.VueLanguageServiceHost; - const vueCompilerOptions = host.getVueCompilationSettings() ?? vue.resolveVueCompilerOptions({}); + }) as vue.LanguageServiceHost; const vueLanguages = ts ? vue.createLanguages( host.getCompilationSettings(), vueCompilerOptions, diff --git a/packages/vue-language-core/src/types.ts b/packages/vue-language-core/src/types.ts index fe2e681a9..7bd7750af 100644 --- a/packages/vue-language-core/src/types.ts +++ b/packages/vue-language-core/src/types.ts @@ -1,4 +1,3 @@ -import * as embedded from '@volar/language-core'; import type { SFCParseResult } from '@vue/compiler-sfc'; import * as CompilerDom from '@vue/compiler-dom'; @@ -7,10 +6,6 @@ import { VueEmbeddedFile } from './sourceFile'; export type { SFCParseResult } from '@vue/compiler-sfc'; -export interface VueLanguageServiceHost extends embedded.LanguageServiceHost { - getVueCompilationSettings(): VueCompilerOptions | undefined; -} - export type RawVueCompilerOptions = Partial> & { target?: 'auto' | 2 | 2.7 | 3 | 3.3; plugins?: string[]; diff --git a/packages/vue-language-server/src/languageServerPlugin.ts b/packages/vue-language-server/src/languageServerPlugin.ts index b7661447a..e6e43f46d 100644 --- a/packages/vue-language-server/src/languageServerPlugin.ts +++ b/packages/vue-language-server/src/languageServerPlugin.ts @@ -133,10 +133,8 @@ export function createServerPlugin(connection: Connection) { let checker = checkers.get(languageService.context.host); if (!checker) { checker = componentMeta.baseCreate( - { - ...languageService.context.host, - getVueCompilationSettings: () => hostToVueOptions.get(languageService.context.host)!, - }, + languageService.context.host, + hostToVueOptions.get(languageService.context.host)!, {}, languageService.context.host.getCurrentDirectory() + '/tsconfig.json.global.vue', ts, diff --git a/packages/vue-language-service/tests/utils/createTester.ts b/packages/vue-language-service/tests/utils/createTester.ts index 902c82b57..0be495d34 100644 --- a/packages/vue-language-service/tests/utils/createTester.ts +++ b/packages/vue-language-service/tests/utils/createTester.ts @@ -1,4 +1,4 @@ -import { resolveConfig, VueLanguageServiceHost } from '../..'; +import { resolveConfig, LanguageServiceHost } from '../..'; import * as ts from 'typescript'; import * as path from 'path'; import { URI } from 'vscode-uri'; @@ -26,7 +26,7 @@ function createTester(root: string) { parsedCommandLine.fileNames = parsedCommandLine.fileNames.map(fileName => fileName.replace(/\\/g, '/')); const scriptVersions = new Map(); const scriptSnapshots = new Map(); - const host: VueLanguageServiceHost = { + const host: LanguageServiceHost = { // ts getNewLine: () => ts.sys.newLine, useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames, @@ -45,7 +45,6 @@ function createTester(root: string) { getCompilationSettings: () => parsedCommandLine.options, getScriptVersion, getScriptSnapshot, - getVueCompilationSettings: () => undefined, }; const defaultVSCodeSettings: any = { 'typescript.preferences.quoteStyle': 'single', diff --git a/packages/vue-tsc/src/index.ts b/packages/vue-tsc/src/index.ts index 80c0be424..1036874a5 100644 --- a/packages/vue-tsc/src/index.ts +++ b/packages/vue-tsc/src/index.ts @@ -10,7 +10,8 @@ export type _Program = ts.Program & { __vue: ProgramContext; }; interface ProgramContext { projectVersion: number, options: ts.CreateProgramOptions, - languageServiceHost: vue.VueLanguageServiceHost, + languageServiceHost: vue.LanguageServiceHost, + vueCompilerOptions: vue.VueCompilerOptions | undefined, languageService: ReturnType, } @@ -42,6 +43,9 @@ export function createProgram(options: ts.CreateProgramOptions) { get languageServiceHost() { return vueLsHost; }, + get vueCompilerOptions() { + return vueCompilerOptions; + }, get languageService() { return vueTsLs; }, @@ -53,7 +57,7 @@ export function createProgram(options: ts.CreateProgramOptions) { scriptSnapshot: ts.IScriptSnapshot, version: string, }>(); - const vueLsHost = new Proxy({ + const vueLsHost = new Proxy({ // avoid failed with tsc built-in fileExists resolveModuleNames: undefined, resolveModuleNameLiterals: undefined, @@ -64,7 +68,6 @@ export function createProgram(options: ts.CreateProgramOptions) { } }, getCompilationSettings: () => ctx.options.options, - getVueCompilationSettings: () => vueCompilerOptions, getScriptFileNames: () => { return ctx.options.rootNames as string[]; }, @@ -78,12 +81,12 @@ export function createProgram(options: ts.CreateProgramOptions) { }, { get: (target, property) => { if (property in target) { - return target[property as keyof vue.VueLanguageServiceHost]; + return target[property as keyof vue.LanguageServiceHost]; } return ctx.options.host![property as keyof ts.CompilerHost]; }, }); - const vueTsLs = vueTs.createLanguageService(vueLsHost); + const vueTsLs = vueTs.createLanguageService(vueLsHost, vueCompilerOptions); program = vueTsLs.getProgram() as (ts.Program & { __vue: ProgramContext; }); program.__vue = ctx; @@ -133,7 +136,7 @@ export function createProgram(options: ts.CreateProgramOptions) { ctx.projectVersion++; } - const vueCompilerOptions = program.__vue.languageServiceHost.getVueCompilationSettings(); + const vueCompilerOptions = program.__vue.vueCompilerOptions; if (vueCompilerOptions?.hooks) { const index = (state.hook?.index ?? -1) + 1; if (index < vueCompilerOptions.hooks.length) { diff --git a/packages/vue-typescript/src/index.ts b/packages/vue-typescript/src/index.ts index 6ce8d5926..423273901 100644 --- a/packages/vue-typescript/src/index.ts +++ b/packages/vue-typescript/src/index.ts @@ -2,14 +2,15 @@ import * as base from '@volar/typescript'; import * as vue from '@vue/language-core'; export function createLanguageService( - host: vue.VueLanguageServiceHost, - ts: typeof import('typescript/lib/tsserverlibrary') = require('typescript'), + host: vue.LanguageServiceHost, + vueCompilerOptions?: vue.VueCompilerOptions, + ts?: typeof import('typescript/lib/tsserverlibrary'), ) { const languageService = base.createLanguageService( host, vue.createLanguages( host.getCompilationSettings(), - host.getVueCompilationSettings(), + vueCompilerOptions, ts, ), ); diff --git a/tsconfig.json b/tsconfig.json index d247ec5c2..040be3e71 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -38,6 +38,9 @@ "@vue/language-service": [ "packages/vue-language-service/src" ], + "@vue/typescript": [ + "packages/vue-typescript/src" + ], "vue-tsc": [ "packages/vue-tsc/src" ],