From 0e0ffd974b6642fe74e6ac634999941b9757031c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=B1=E5=90=B9=E8=89=B2=E5=BE=A1=E5=AE=88?= <85992002+KazariEX@users.noreply.github.com> Date: Fri, 25 Jul 2025 02:23:18 +0800 Subject: [PATCH 01/25] fix(language-core): generate `modelModifiers` for explicitly declared default model name (#5558) --- packages/language-core/lib/codegen/script/scriptSetup.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/language-core/lib/codegen/script/scriptSetup.ts b/packages/language-core/lib/codegen/script/scriptSetup.ts index 83af4ed7ff..aa889d3cc3 100644 --- a/packages/language-core/lib/codegen/script/scriptSetup.ts +++ b/packages/language-core/lib/codegen/script/scriptSetup.ts @@ -509,7 +509,7 @@ function* generateComponentProps( yield `,${newLine}`; if (defineModel.modifierType) { - const modifierName = `${defineModel.name ? propName : 'model'}Modifiers`; + const modifierName = `${propName === 'modelValue' ? 'model' : propName}Modifiers`; const modifierType = getRangeText(scriptSetup, defineModel.modifierType); yield `'${modifierName}'?: Partial>,${newLine}`; } From 848d21a7a54d53026bb56ff0adcf6baeba4fb2a5 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Fri, 25 Jul 2025 05:40:45 +0800 Subject: [PATCH 02/25] refactor(language-service): rename 'pug' to 'jade' in template plugin --- packages/language-service/index.ts | 2 +- packages/language-service/lib/plugins/vue-template.ts | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/language-service/index.ts b/packages/language-service/index.ts index 9c249e2828..e9307189cd 100644 --- a/packages/language-service/index.ts +++ b/packages/language-service/index.ts @@ -55,7 +55,7 @@ export function createVueLanguageServicePlugins( createVueSfcPlugin(), createVueSuggestDefineAssignmentPlugin(), createVueTemplatePlugin('html', tsPluginClient), - createVueTemplatePlugin('pug', tsPluginClient), + createVueTemplatePlugin('jade', tsPluginClient), createVueTemplateRefLinksPlugin(), createVueTwoslashQueriesPlugin(tsPluginClient), createEmmetPlugin({ diff --git a/packages/language-service/lib/plugins/vue-template.ts b/packages/language-service/lib/plugins/vue-template.ts index 78a34cb2aa..14bf47a242 100644 --- a/packages/language-service/lib/plugins/vue-template.ts +++ b/packages/language-service/lib/plugins/vue-template.ts @@ -36,7 +36,7 @@ let builtInData: html.HTMLDataV1; let modelData: html.HTMLDataV1; export function create( - mode: 'html' | 'pug', + languageId: 'html' | 'jade', tsPluginClient: import('@vue/typescript-plugin/lib/requests').Requests | undefined, ): LanguageServicePlugin { let customData: html.IHTMLDataProvider[] = []; @@ -51,7 +51,7 @@ export function create( }, }; }; - const baseService = mode === 'pug' + const baseService = languageId === 'jade' ? createPugService({ useDefaultDataProvider: false, getCustomData() { @@ -74,10 +74,9 @@ export function create( onDidChangeCustomData, }); const htmlDataProvider = html.getDefaultHTMLDataProvider(); - const languageId = mode === 'pug' ? 'jade' : 'html'; return { - name: `vue-template (${mode})`, + name: `vue-template (${languageId})`, capabilities: { ...baseService.capabilities, completionProvider: { From 1d005d5aeaf3701b543104b7766db0c150326507 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Fri, 25 Jul 2025 05:57:04 +0800 Subject: [PATCH 03/25] refactor(language-service): update tsPluginClient usage to destructured requests in plugins --- packages/language-service/index.ts | 49 +++++++++++++------ .../lib/plugins/typescript-semantic-tokens.ts | 4 +- .../lib/plugins/vue-autoinsert-dotvalue.ts | 4 +- .../plugins/vue-component-semantic-tokens.ts | 6 +-- .../lib/plugins/vue-document-drop.ts | 6 +-- .../lib/plugins/vue-document-highlights.ts | 4 +- .../lib/plugins/vue-extract-file.ts | 4 +- .../lib/plugins/vue-missing-props-hints.ts | 8 +-- .../lib/plugins/vue-template.ts | 21 +++++--- .../lib/plugins/vue-twoslash-queries.ts | 4 +- .../language-service/tests/utils/format.ts | 2 +- .../typescript-plugin/lib/requests/index.ts | 35 +++++++------ 12 files changed, 87 insertions(+), 60 deletions(-) diff --git a/packages/language-service/index.ts b/packages/language-service/index.ts index e9307189cd..76f04a05df 100644 --- a/packages/language-service/index.ts +++ b/packages/language-service/index.ts @@ -31,39 +31,56 @@ import { create as createVueTwoslashQueriesPlugin } from './lib/plugins/vue-twos export function createVueLanguageServicePlugins( ts: typeof import('typescript'), - tsPluginClient: import('@vue/typescript-plugin/lib/requests').Requests | undefined, + tsPluginClient: import('@vue/typescript-plugin/lib/requests').Requests = { + collectExtractProps: () => undefined, + getImportPathForFile: () => undefined, + getPropertiesAtLocation: () => undefined, + getComponentDirectives: () => undefined, + getComponentEvents: () => undefined, + getComponentNames: () => undefined, + getComponentProps: () => undefined, + getComponentSlots: () => undefined, + getElementAttrs: () => undefined, + getElementNames: () => undefined, + getDocumentHighlights: () => undefined, + getEncodedSemanticClassifications: () => undefined, + getQuickInfoAtPosition: () => undefined, + }, ) { - const plugins = [ + return [ createCssPlugin(), createJsonPlugin(), createPugFormatPlugin(), - createTypeScriptDocCommentTemplatePlugin(ts), - createTypescriptSemanticTokensPlugin(tsPluginClient), - createTypeScriptSyntacticPlugin(ts), createVueAutoSpacePlugin(), - createVueAutoDotValuePlugin(ts, tsPluginClient), createVueCompilerDomErrorsPlugin(), - createVueComponentSemanticTokensPlugin(tsPluginClient), - createVueDocumentDropPlugin(ts, tsPluginClient), - createVueDocumentHighlightsPlugin(tsPluginClient), createVueDirectiveCommentsPlugin(), - createVueExtractFilePlugin(ts, tsPluginClient), createVueGlobalTypesErrorPlugin(), - createVueInlayHintsPlugin(ts), - createVueMissingPropsHintsPlugin(tsPluginClient), createVueScopedClassLinksPlugin(), createVueSfcPlugin(), createVueSuggestDefineAssignmentPlugin(), - createVueTemplatePlugin('html', tsPluginClient), - createVueTemplatePlugin('jade', tsPluginClient), createVueTemplateRefLinksPlugin(), - createVueTwoslashQueriesPlugin(tsPluginClient), createEmmetPlugin({ mappedLanguages: { 'vue-root-tags': 'html', 'postcss': 'scss', }, }), + + // TS related plugins + createTypeScriptDocCommentTemplatePlugin(ts), + createTypeScriptSyntacticPlugin(ts), + createVueInlayHintsPlugin(ts), + + // type aware plugins + createTypescriptSemanticTokensPlugin(tsPluginClient), + createVueAutoDotValuePlugin(ts, tsPluginClient), + createVueComponentSemanticTokensPlugin(tsPluginClient), + createVueDocumentDropPlugin(ts, tsPluginClient), + createVueDocumentHighlightsPlugin(tsPluginClient), + createVueExtractFilePlugin(ts, tsPluginClient), + createVueMissingPropsHintsPlugin(tsPluginClient), + createVueTemplatePlugin('html', tsPluginClient), + createVueTemplatePlugin('jade', tsPluginClient), + createVueTwoslashQueriesPlugin(tsPluginClient), ]; - return plugins; } diff --git a/packages/language-service/lib/plugins/typescript-semantic-tokens.ts b/packages/language-service/lib/plugins/typescript-semantic-tokens.ts index 58233dbe05..64374e2f53 100644 --- a/packages/language-service/lib/plugins/typescript-semantic-tokens.ts +++ b/packages/language-service/lib/plugins/typescript-semantic-tokens.ts @@ -3,7 +3,7 @@ import { convertClassificationsToSemanticTokens } from 'volar-service-typescript import { getEmbeddedInfo } from './utils'; export function create( - tsPluginClient: import('@vue/typescript-plugin/lib/requests').Requests | undefined, + { getEncodedSemanticClassifications }: import('@vue/typescript-plugin/lib/requests').Requests, ): LanguageServicePlugin { return { name: 'typescript-semantic-tokens', @@ -50,7 +50,7 @@ export function create( start: start, length: end - start, }; - const classifications = await tsPluginClient?.getEncodedSemanticClassifications( + const classifications = await getEncodedSemanticClassifications( root.fileName, span, ); diff --git a/packages/language-service/lib/plugins/vue-autoinsert-dotvalue.ts b/packages/language-service/lib/plugins/vue-autoinsert-dotvalue.ts index 46f2ddc681..199e7ae40e 100644 --- a/packages/language-service/lib/plugins/vue-autoinsert-dotvalue.ts +++ b/packages/language-service/lib/plugins/vue-autoinsert-dotvalue.ts @@ -5,7 +5,7 @@ import { getEmbeddedInfo, sleep } from './utils'; export function create( ts: typeof import('typescript'), - tsPluginClient: import('@vue/typescript-plugin/lib/requests').Requests | undefined, + { getPropertiesAtLocation }: import('@vue/typescript-plugin/lib/requests').Requests, ): LanguageServicePlugin { return { name: 'vue-autoinsert-dotvalue', @@ -73,7 +73,7 @@ export function create( } } - const props = await tsPluginClient?.getPropertiesAtLocation(root.fileName, sourceOffset) ?? []; + const props = await getPropertiesAtLocation(root.fileName, sourceOffset) ?? []; if (props.some(prop => prop === 'value')) { return '${1:.value}'; } diff --git a/packages/language-service/lib/plugins/vue-component-semantic-tokens.ts b/packages/language-service/lib/plugins/vue-component-semantic-tokens.ts index 1b973c22db..655a05c7c7 100644 --- a/packages/language-service/lib/plugins/vue-component-semantic-tokens.ts +++ b/packages/language-service/lib/plugins/vue-component-semantic-tokens.ts @@ -4,7 +4,7 @@ import type * as ts from 'typescript'; import { getEmbeddedInfo } from './utils'; export function create( - tsPluginClient: import('@vue/typescript-plugin/lib/requests').Requests | undefined, + { getComponentNames, getElementNames }: import('@vue/typescript-plugin/lib/requests').Requests, ): LanguageServicePlugin { return { name: 'vue-component-semantic-tokens', @@ -34,8 +34,8 @@ export function create( const start = document.offsetAt(range.start); const end = document.offsetAt(range.end); - const validComponentNames = await tsPluginClient?.getComponentNames(root.fileName) ?? []; - const elements = new Set(await tsPluginClient?.getElementNames(root.fileName) ?? []); + const validComponentNames = await getComponentNames(root.fileName) ?? []; + const elements = new Set(await getElementNames(root.fileName) ?? []); const components = new Set([ ...validComponentNames, ...validComponentNames.map(hyphenateTag), diff --git a/packages/language-service/lib/plugins/vue-document-drop.ts b/packages/language-service/lib/plugins/vue-document-drop.ts index 0382d31073..b38e3df399 100644 --- a/packages/language-service/lib/plugins/vue-document-drop.ts +++ b/packages/language-service/lib/plugins/vue-document-drop.ts @@ -10,7 +10,7 @@ import { getEmbeddedInfo } from './utils'; export function create( ts: typeof import('typescript'), - tsPluginClient: import('@vue/typescript-plugin/lib/requests').Requests | undefined, + { getImportPathForFile }: import('@vue/typescript-plugin/lib/requests').Requests, ): LanguageServicePlugin { return { name: 'vue-document-drop', @@ -56,7 +56,7 @@ export function create( let importPath: string | undefined; const serviceScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(root); - if (tsPluginClient && serviceScript) { + if (serviceScript) { const tsDocumentUri = context.encodeEmbeddedDocumentUri(sourceScript.id, serviceScript.code.id); const tsDocument = context.documents.get( tsDocumentUri, @@ -64,7 +64,7 @@ export function create( serviceScript.code.snapshot, ); const preferences = await getUserPreferences(context, tsDocument); - const importPathRequest = await tsPluginClient.getImportPathForFile( + const importPathRequest = await getImportPathForFile( root.fileName, incomingFileName, preferences, diff --git a/packages/language-service/lib/plugins/vue-document-highlights.ts b/packages/language-service/lib/plugins/vue-document-highlights.ts index 29efe66b2d..e2fe6cdc8f 100644 --- a/packages/language-service/lib/plugins/vue-document-highlights.ts +++ b/packages/language-service/lib/plugins/vue-document-highlights.ts @@ -2,7 +2,7 @@ import type { DocumentHighlightKind, LanguageServicePlugin } from '@volar/langua import { getEmbeddedInfo } from './utils'; export function create( - tsPluginClient: import('@vue/typescript-plugin/lib/requests').Requests | undefined, + { getDocumentHighlights }: import('@vue/typescript-plugin/lib/requests').Requests, ): LanguageServicePlugin { return { name: 'vue-document-highlights', @@ -18,7 +18,7 @@ export function create( } const { root } = info; - const result = await tsPluginClient?.getDocumentHighlights(root.fileName, document.offsetAt(position)); + const result = await getDocumentHighlights(root.fileName, document.offsetAt(position)); return result ?.filter(({ fileName }) => fileName === root.fileName) diff --git a/packages/language-service/lib/plugins/vue-extract-file.ts b/packages/language-service/lib/plugins/vue-extract-file.ts index 64656a78f8..0e49d7deba 100644 --- a/packages/language-service/lib/plugins/vue-extract-file.ts +++ b/packages/language-service/lib/plugins/vue-extract-file.ts @@ -15,7 +15,7 @@ const unicodeReg = /\\u/g; export function create( ts: typeof import('typescript'), - tsPluginClient: import('@vue/typescript-plugin/lib/requests').Requests | undefined, + { collectExtractProps }: import('@vue/typescript-plugin/lib/requests').Requests, ): LanguageServicePlugin { return { name: 'vue-extract-file', @@ -89,7 +89,7 @@ export function create( return codeAction; } - const toExtract = await tsPluginClient?.collectExtractProps(root.fileName, templateCodeRange) ?? []; + const toExtract = await collectExtractProps(root.fileName, templateCodeRange) ?? []; const templateInitialIndent = await context.env.getConfiguration!('vue.format.template.initialIndent') ?? true; diff --git a/packages/language-service/lib/plugins/vue-missing-props-hints.ts b/packages/language-service/lib/plugins/vue-missing-props-hints.ts index e7fd707956..0c41c383ef 100644 --- a/packages/language-service/lib/plugins/vue-missing-props-hints.ts +++ b/packages/language-service/lib/plugins/vue-missing-props-hints.ts @@ -11,7 +11,7 @@ import { AttrNameCasing, checkCasing } from '../nameCasing'; import { getEmbeddedInfo } from './utils'; export function create( - tsPluginClient: import('@vue/typescript-plugin/lib/requests').Requests | undefined, + { getComponentNames, getElementNames, getComponentProps }: import('@vue/typescript-plugin/lib/requests').Requests, ): LanguageServicePlugin { return { name: 'vue-missing-props-hints', @@ -41,11 +41,11 @@ export function create( const result: InlayHint[] = []; const casing = await checkCasing(context, sourceScript.id); - const components = await tsPluginClient?.getComponentNames(root.fileName) ?? []; + const components = await getComponentNames(root.fileName) ?? []; const componentProps: Record = {}; intrinsicElementNames ??= new Set( - await tsPluginClient?.getElementNames(root.fileName) ?? [], + await getElementNames(root.fileName) ?? [], ); let token: html.TokenType; @@ -76,7 +76,7 @@ export function create( if (cancellationToken.isCancellationRequested) { break; } - componentProps[checkTag] = (await tsPluginClient?.getComponentProps(root.fileName, checkTag) ?? []) + componentProps[checkTag] = (await getComponentProps(root.fileName, checkTag) ?? []) .filter(prop => prop.required) .map(prop => prop.name); } diff --git a/packages/language-service/lib/plugins/vue-template.ts b/packages/language-service/lib/plugins/vue-template.ts index 14bf47a242..a5636ac696 100644 --- a/packages/language-service/lib/plugins/vue-template.ts +++ b/packages/language-service/lib/plugins/vue-template.ts @@ -37,7 +37,14 @@ let modelData: html.HTMLDataV1; export function create( languageId: 'html' | 'jade', - tsPluginClient: import('@vue/typescript-plugin/lib/requests').Requests | undefined, + { + getComponentNames, + getElementAttrs, + getComponentProps, + getComponentEvents, + getComponentDirectives, + getComponentSlots, + }: import('@vue/typescript-plugin/lib/requests').Requests, ): LanguageServicePlugin { let customData: html.IHTMLDataProvider[] = []; let extraCustomData: html.IHTMLDataProvider[] = []; @@ -400,7 +407,7 @@ export function create( if (!components) { components = []; tasks.push((async () => { - components = (await tsPluginClient?.getComponentNames(root.fileName) ?? []) + components = (await getComponentNames(root.fileName) ?? []) .filter(name => name !== 'Transition' && name !== 'TransitionGroup' @@ -455,10 +462,10 @@ export function create( tagMap.set(tag, tagInfo); tasks.push((async () => { tagMap.set(tag, { - attrs: await tsPluginClient?.getElementAttrs(root.fileName, tag) ?? [], - propInfos: await tsPluginClient?.getComponentProps(root.fileName, tag) ?? [], - events: await tsPluginClient?.getComponentEvents(root.fileName, tag) ?? [], - directives: await tsPluginClient?.getComponentDirectives(root.fileName) ?? [], + attrs: await getElementAttrs(root.fileName, tag) ?? [], + propInfos: await getComponentProps(root.fileName, tag) ?? [], + events: await getComponentEvents(root.fileName, tag) ?? [], + directives: await getComponentDirectives(root.fileName) ?? [], }); version++; })()); @@ -607,7 +614,7 @@ export function create( values = []; tasks.push((async () => { if (tag === 'slot' && attr === 'name') { - values = await tsPluginClient?.getComponentSlots(root.fileName) ?? []; + values = await getComponentSlots(root.fileName) ?? []; } version++; })()); diff --git a/packages/language-service/lib/plugins/vue-twoslash-queries.ts b/packages/language-service/lib/plugins/vue-twoslash-queries.ts index bac7e85c75..c93e80bc34 100644 --- a/packages/language-service/lib/plugins/vue-twoslash-queries.ts +++ b/packages/language-service/lib/plugins/vue-twoslash-queries.ts @@ -5,7 +5,7 @@ const twoslashTemplateReg = //g; const twoslashScriptReg = /(?<=^|\n)\s*\/\/\s*\^\?/g; export function create( - tsPluginClient: import('@vue/typescript-plugin/lib/requests').Requests | undefined, + { getQuickInfoAtPosition }: import('@vue/typescript-plugin/lib/requests').Requests, ): LanguageServicePlugin { return { name: 'vue-twoslash-queries', @@ -45,7 +45,7 @@ export function create( for (const [pointerPosition, hoverOffset] of hoverOffsets) { const map = context.language.maps.get(virtualCode, sourceScript); for (const [sourceOffset] of map.toSourceLocation(hoverOffset)) { - const quickInfo = await tsPluginClient?.getQuickInfoAtPosition( + const quickInfo = await getQuickInfoAtPosition( root.fileName, sourceDocument.positionAt(sourceOffset), ); diff --git a/packages/language-service/tests/utils/format.ts b/packages/language-service/tests/utils/format.ts index 00e13d3a37..a590bdb389 100644 --- a/packages/language-service/tests/utils/format.ts +++ b/packages/language-service/tests/utils/format.ts @@ -12,7 +12,7 @@ const vueLanguagePlugin = createVueLanguagePlugin( resolvedVueOptions, () => '', ); -const vueServicePLugins = createVueLanguageServicePlugins(ts, undefined); +const vueServicePLugins = createVueLanguageServicePlugins(ts); const formatter = kit.createFormatter([vueLanguagePlugin], vueServicePLugins); export function defineFormatTest(options: { diff --git a/packages/typescript-plugin/lib/requests/index.ts b/packages/typescript-plugin/lib/requests/index.ts index 80e6f6a51e..5f71d49db8 100644 --- a/packages/typescript-plugin/lib/requests/index.ts +++ b/packages/typescript-plugin/lib/requests/index.ts @@ -1,19 +1,22 @@ import type * as ts from 'typescript'; -type ToRequest any> = (...args: Parameters) => Promise | null | undefined>; +type Request any> = ( + ...args: Parameters +) => MaybePromise | null | undefined>; +type MaybePromise = T | Promise; -export type Requests = { - collectExtractProps: ToRequest; - getImportPathForFile: ToRequest; - getPropertiesAtLocation: ToRequest; - getComponentDirectives: ToRequest; - getComponentEvents: ToRequest; - getComponentNames: ToRequest; - getComponentProps: ToRequest; - getComponentSlots: ToRequest; - getElementAttrs: ToRequest; - getElementNames: ToRequest; - getDocumentHighlights: ToRequest<(fileName: string, position: number) => ts.DocumentHighlights[]>; - getEncodedSemanticClassifications: ToRequest<(fileName: string, span: ts.TextSpan) => ts.Classifications>; - getQuickInfoAtPosition: ToRequest<(fileName: string, position: ts.LineAndCharacter) => string>; -}; +export interface Requests { + collectExtractProps: Request; + getImportPathForFile: Request; + getPropertiesAtLocation: Request; + getComponentDirectives: Request; + getComponentEvents: Request; + getComponentNames: Request; + getComponentProps: Request; + getComponentSlots: Request; + getElementAttrs: Request; + getElementNames: Request; + getDocumentHighlights: Request<(fileName: string, position: number) => ts.DocumentHighlights[]>; + getEncodedSemanticClassifications: Request<(fileName: string, span: ts.TextSpan) => ts.Classifications>; + getQuickInfoAtPosition: Request<(fileName: string, position: ts.LineAndCharacter) => string>; +} From 3e6393b7ecce6f3307b1872e6a6aad5ec555017d Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Fri, 25 Jul 2025 06:10:00 +0800 Subject: [PATCH 04/25] fix(language-service): more responsive .value insertion --- .../lib/{plugins => }/data.ts | 62 +++++++++---------- packages/language-service/lib/plugins/css.ts | 2 +- .../lib/plugins/typescript-semantic-tokens.ts | 2 +- .../lib/plugins/vue-autoinsert-dotvalue.ts | 28 +++------ .../lib/plugins/vue-autoinsert-space.ts | 9 +-- .../lib/plugins/vue-compiler-dom-errors.ts | 2 +- .../plugins/vue-component-semantic-tokens.ts | 2 +- .../lib/plugins/vue-document-drop.ts | 2 +- .../lib/plugins/vue-document-highlights.ts | 2 +- .../lib/plugins/vue-extract-file.ts | 2 +- .../lib/plugins/vue-global-types-error.ts | 2 +- .../lib/plugins/vue-inlayhints.ts | 2 +- .../lib/plugins/vue-missing-props-hints.ts | 2 +- .../lib/plugins/vue-scoped-class-links.ts | 2 +- .../language-service/lib/plugins/vue-sfc.ts | 4 +- .../plugins/vue-suggest-define-assignment.ts | 2 +- .../lib/plugins/vue-template-ref-links.ts | 2 +- .../lib/plugins/vue-template.ts | 4 +- .../lib/plugins/vue-twoslash-queries.ts | 2 +- .../lib/{plugins => }/utils.ts | 4 -- 20 files changed, 59 insertions(+), 80 deletions(-) rename packages/language-service/lib/{plugins => }/data.ts (60%) rename packages/language-service/lib/{plugins => }/utils.ts (92%) diff --git a/packages/language-service/lib/plugins/data.ts b/packages/language-service/lib/data.ts similarity index 60% rename from packages/language-service/lib/plugins/data.ts rename to packages/language-service/lib/data.ts index e227d57992..3fb47db74f 100644 --- a/packages/language-service/lib/plugins/data.ts +++ b/packages/language-service/lib/data.ts @@ -8,34 +8,34 @@ export function loadTemplateData(lang: string) { let data: html.HTMLDataV1; if (lang === 'ja') { - data = require('../../data/template/ja.json'); + data = require('../data/template/ja.json'); } else if (lang === 'fr') { - data = require('../../data/template/fr.json'); + data = require('../data/template/fr.json'); } else if (lang === 'ko') { - data = require('../../data/template/ko.json'); + data = require('../data/template/ko.json'); } else if (lang === 'pt-br') { - data = require('../../data/template/pt.json'); + data = require('../data/template/pt.json'); } else if (lang === 'zh-cn') { - data = require('../../data/template/zh-cn.json'); + data = require('../data/template/zh-cn.json'); } else if (lang === 'zh-tw') { - data = require('../../data/template/zh-hk.json'); + data = require('../data/template/zh-hk.json'); } else if (lang === 'it') { - data = require('../../data/template/it.json'); + data = require('../data/template/it.json'); } else if (lang === 'cs') { - data = require('../../data/template/cs.json'); + data = require('../data/template/cs.json'); } else if (lang === 'ru') { - data = require('../../data/template/ru.json'); + data = require('../data/template/ru.json'); } else { - data = require('../../data/template/en.json'); + data = require('../data/template/en.json'); } resolveReferences(data); @@ -73,34 +73,34 @@ export function loadLanguageBlocks(lang: string): html.HTMLDataV1 { let data: html.HTMLDataV1; if (lang === 'ja') { - data = require('../../data/language-blocks/ja.json'); + data = require('../data/language-blocks/ja.json'); } else if (lang === 'fr') { - data = require('../../data/language-blocks/fr.json'); + data = require('../data/language-blocks/fr.json'); } else if (lang === 'ko') { - data = require('../../data/language-blocks/ko.json'); + data = require('../data/language-blocks/ko.json'); } else if (lang === 'pt-br') { - data = require('../../data/language-blocks/pt.json'); + data = require('../data/language-blocks/pt.json'); } else if (lang === 'zh-cn') { - data = require('../../data/language-blocks/zh-cn.json'); + data = require('../data/language-blocks/zh-cn.json'); } else if (lang === 'zh-tw') { - data = require('../../data/language-blocks/zh-hk.json'); + data = require('../data/language-blocks/zh-hk.json'); } else if (lang === 'it') { - data = require('../../data/language-blocks/it.json'); + data = require('../data/language-blocks/it.json'); } else if (lang === 'cs') { - data = require('../../data/language-blocks/cs.json'); + data = require('../data/language-blocks/cs.json'); } else if (lang === 'ru') { - data = require('../../data/language-blocks/ru.json'); + data = require('../data/language-blocks/ru.json'); } else { - data = require('../../data/language-blocks/en.json'); + data = require('../data/language-blocks/en.json'); } resolveReferences(data); @@ -114,34 +114,34 @@ export function loadModelModifiersData(lang: string): html.HTMLDataV1 { let data: html.HTMLDataV1; if (lang === 'ja') { - data = require('../../data/model-modifiers/ja.json'); + data = require('../data/model-modifiers/ja.json'); } else if (lang === 'fr') { - data = require('../../data/model-modifiers/fr.json'); + data = require('../data/model-modifiers/fr.json'); } else if (lang === 'ko') { - data = require('../../data/model-modifiers/ko.json'); + data = require('../data/model-modifiers/ko.json'); } else if (lang === 'pt-br') { - data = require('../../data/model-modifiers/pt.json'); + data = require('../data/model-modifiers/pt.json'); } else if (lang === 'zh-cn') { - data = require('../../data/model-modifiers/zh-cn.json'); + data = require('../data/model-modifiers/zh-cn.json'); } else if (lang === 'zh-tw') { - data = require('../../data/model-modifiers/zh-hk.json'); + data = require('../data/model-modifiers/zh-hk.json'); } else if (lang === 'it') { - data = require('../../data/model-modifiers/it.json'); + data = require('../data/model-modifiers/it.json'); } else if (lang === 'cs') { - data = require('../../data/model-modifiers/cs.json'); + data = require('../data/model-modifiers/cs.json'); } else if (lang === 'ru') { - data = require('../../data/model-modifiers/ru.json'); + data = require('../data/model-modifiers/ru.json'); } else { - data = require('../../data/model-modifiers/en.json'); + data = require('../data/model-modifiers/en.json'); } resolveReferences(data); @@ -150,7 +150,7 @@ export function loadModelModifiersData(lang: string): html.HTMLDataV1 { } function resolveReferences(data: html.HTMLDataV1) { - locale ??= require('../../data/locale.json'); + locale ??= require('../data/locale.json'); for ( const item of [ diff --git a/packages/language-service/lib/plugins/css.ts b/packages/language-service/lib/plugins/css.ts index 68b2102959..fb168961a8 100644 --- a/packages/language-service/lib/plugins/css.ts +++ b/packages/language-service/lib/plugins/css.ts @@ -2,7 +2,7 @@ import type { LanguageServicePlugin, TextDocument, VirtualCode } from '@volar/la import { isRenameEnabled } from '@vue/language-core'; import { create as baseCreate, type Provide } from 'volar-service-css'; import type * as css from 'vscode-css-languageservice'; -import { getEmbeddedInfo } from './utils'; +import { getEmbeddedInfo } from '../utils'; export function create(): LanguageServicePlugin { const base = baseCreate({ scssDocumentSelector: ['scss', 'postcss'] }); diff --git a/packages/language-service/lib/plugins/typescript-semantic-tokens.ts b/packages/language-service/lib/plugins/typescript-semantic-tokens.ts index 64374e2f53..b1600f6ca5 100644 --- a/packages/language-service/lib/plugins/typescript-semantic-tokens.ts +++ b/packages/language-service/lib/plugins/typescript-semantic-tokens.ts @@ -1,6 +1,6 @@ import type { LanguageServicePlugin } from '@volar/language-service'; import { convertClassificationsToSemanticTokens } from 'volar-service-typescript/lib/semanticFeatures/semanticTokens'; -import { getEmbeddedInfo } from './utils'; +import { getEmbeddedInfo } from '../utils'; export function create( { getEncodedSemanticClassifications }: import('@vue/typescript-plugin/lib/requests').Requests, diff --git a/packages/language-service/lib/plugins/vue-autoinsert-dotvalue.ts b/packages/language-service/lib/plugins/vue-autoinsert-dotvalue.ts index 199e7ae40e..265d046b0b 100644 --- a/packages/language-service/lib/plugins/vue-autoinsert-dotvalue.ts +++ b/packages/language-service/lib/plugins/vue-autoinsert-dotvalue.ts @@ -1,7 +1,7 @@ import type { LanguageServicePlugin, TextDocument } from '@volar/language-service'; import { hyphenateAttr } from '@vue/language-core'; import type * as ts from 'typescript'; -import { getEmbeddedInfo, sleep } from './utils'; +import { getEmbeddedInfo } from '../utils'; export function create( ts: typeof import('typescript'), @@ -16,8 +16,6 @@ export function create( }, }, create(context) { - let currentReq = 0; - return { async provideAutoInsertSnippet(document, selection, change) { const info = getEmbeddedInfo(context, document, id => id.startsWith('script_')); @@ -34,37 +32,27 @@ export function create( return; } - const req = ++currentReq; - // Wait for tsserver to sync - await sleep(250); - if (req !== currentReq) { - return; - } - - const enabled = await context.env.getConfiguration?.('vue.autoInsert.dotValue') ?? true; - if (!enabled) { - return; - } + let sourceOffset: number | undefined; const { sourceScript, virtualCode, root } = info; - const { sfc } = root; - const blocks = [sfc.script, sfc.scriptSetup].filter(block => !!block); - if (!blocks.length) { + const scriptBlocks = [sfc.script, sfc.scriptSetup].filter(block => !!block); + const map = context.language.maps.get(virtualCode, sourceScript); + + if (!scriptBlocks.length) { return; } - let sourceOffset: number | undefined; - const map = context.language.maps.get(virtualCode, sourceScript); for (const [offset] of map.toSourceLocation(document.offsetAt(selection))) { sourceOffset = offset; break; } + if (sourceOffset === undefined) { return; } - for (const { ast, startTagEnd, endTagStart } of blocks) { + for (const { ast, startTagEnd, endTagStart } of scriptBlocks) { if (sourceOffset < startTagEnd || sourceOffset > endTagStart) { continue; } diff --git a/packages/language-service/lib/plugins/vue-autoinsert-space.ts b/packages/language-service/lib/plugins/vue-autoinsert-space.ts index 2de90a028d..e4fc4ea6b4 100644 --- a/packages/language-service/lib/plugins/vue-autoinsert-space.ts +++ b/packages/language-service/lib/plugins/vue-autoinsert-space.ts @@ -9,15 +9,10 @@ export function create(): LanguageServicePlugin { configurationSections: ['vue.autoInsert.bracketSpacing'], }, }, - create(context) { + create() { return { - async provideAutoInsertSnippet(document, selection, change) { + provideAutoInsertSnippet(document, selection, change) { if (document.languageId === 'html' || document.languageId === 'jade') { - const enabled = await context.env.getConfiguration?.('vue.autoInsert.bracketSpacing') ?? true; - if (!enabled) { - return; - } - if ( change.text === '{}' && document.getText().slice(change.rangeOffset - 1, change.rangeOffset + 3) === '{{}}' diff --git a/packages/language-service/lib/plugins/vue-compiler-dom-errors.ts b/packages/language-service/lib/plugins/vue-compiler-dom-errors.ts index 4721d69d32..e4581673da 100644 --- a/packages/language-service/lib/plugins/vue-compiler-dom-errors.ts +++ b/packages/language-service/lib/plugins/vue-compiler-dom-errors.ts @@ -1,5 +1,5 @@ import type { Diagnostic, DiagnosticSeverity, LanguageServicePlugin } from '@volar/language-service'; -import { getEmbeddedInfo } from './utils'; +import { getEmbeddedInfo } from '../utils'; export function create(): LanguageServicePlugin { return { diff --git a/packages/language-service/lib/plugins/vue-component-semantic-tokens.ts b/packages/language-service/lib/plugins/vue-component-semantic-tokens.ts index 655a05c7c7..1b301aed5c 100644 --- a/packages/language-service/lib/plugins/vue-component-semantic-tokens.ts +++ b/packages/language-service/lib/plugins/vue-component-semantic-tokens.ts @@ -1,7 +1,7 @@ import type { LanguageServicePlugin, SemanticToken } from '@volar/language-service'; import { forEachElementNode, hyphenateTag } from '@vue/language-core'; import type * as ts from 'typescript'; -import { getEmbeddedInfo } from './utils'; +import { getEmbeddedInfo } from '../utils'; export function create( { getComponentNames, getElementNames }: import('@vue/typescript-plugin/lib/requests').Requests, diff --git a/packages/language-service/lib/plugins/vue-document-drop.ts b/packages/language-service/lib/plugins/vue-document-drop.ts index b38e3df399..f556e01287 100644 --- a/packages/language-service/lib/plugins/vue-document-drop.ts +++ b/packages/language-service/lib/plugins/vue-document-drop.ts @@ -6,7 +6,7 @@ import { getUserPreferences } from 'volar-service-typescript/lib/configs/getUser import { URI } from 'vscode-uri'; import { checkCasing, TagNameCasing } from '../nameCasing'; import { createAddComponentToOptionEdit, getLastImportNode } from '../plugins/vue-extract-file'; -import { getEmbeddedInfo } from './utils'; +import { getEmbeddedInfo } from '../utils'; export function create( ts: typeof import('typescript'), diff --git a/packages/language-service/lib/plugins/vue-document-highlights.ts b/packages/language-service/lib/plugins/vue-document-highlights.ts index e2fe6cdc8f..452d6cf1cc 100644 --- a/packages/language-service/lib/plugins/vue-document-highlights.ts +++ b/packages/language-service/lib/plugins/vue-document-highlights.ts @@ -1,5 +1,5 @@ import type { DocumentHighlightKind, LanguageServicePlugin } from '@volar/language-service'; -import { getEmbeddedInfo } from './utils'; +import { getEmbeddedInfo } from '../utils'; export function create( { getDocumentHighlights }: import('@vue/typescript-plugin/lib/requests').Requests, diff --git a/packages/language-service/lib/plugins/vue-extract-file.ts b/packages/language-service/lib/plugins/vue-extract-file.ts index 0e49d7deba..06235d620b 100644 --- a/packages/language-service/lib/plugins/vue-extract-file.ts +++ b/packages/language-service/lib/plugins/vue-extract-file.ts @@ -3,7 +3,7 @@ import type { ExpressionNode, TemplateChildNode } from '@vue/compiler-dom'; import { type Sfc, tsCodegen } from '@vue/language-core'; import type * as ts from 'typescript'; import { URI } from 'vscode-uri'; -import { getEmbeddedInfo } from './utils'; +import { getEmbeddedInfo } from '../utils'; interface ActionData { uri: string; diff --git a/packages/language-service/lib/plugins/vue-global-types-error.ts b/packages/language-service/lib/plugins/vue-global-types-error.ts index 7bf78db634..557894ad76 100644 --- a/packages/language-service/lib/plugins/vue-global-types-error.ts +++ b/packages/language-service/lib/plugins/vue-global-types-error.ts @@ -1,5 +1,5 @@ import type { DiagnosticSeverity, LanguageServicePlugin } from '@volar/language-service'; -import { getEmbeddedInfo } from './utils'; +import { getEmbeddedInfo } from '../utils'; export function create(): LanguageServicePlugin { return { diff --git a/packages/language-service/lib/plugins/vue-inlayhints.ts b/packages/language-service/lib/plugins/vue-inlayhints.ts index 02f5f4bf73..4e75c68be4 100644 --- a/packages/language-service/lib/plugins/vue-inlayhints.ts +++ b/packages/language-service/lib/plugins/vue-inlayhints.ts @@ -1,7 +1,7 @@ import type { InlayHint, InlayHintKind, LanguageServicePlugin } from '@volar/language-service'; import { collectBindingIdentifiers, tsCodegen } from '@vue/language-core'; import type * as ts from 'typescript'; -import { getEmbeddedInfo } from './utils'; +import { getEmbeddedInfo } from '../utils'; export function create(ts: typeof import('typescript')): LanguageServicePlugin { return { diff --git a/packages/language-service/lib/plugins/vue-missing-props-hints.ts b/packages/language-service/lib/plugins/vue-missing-props-hints.ts index 0c41c383ef..12ad3b8563 100644 --- a/packages/language-service/lib/plugins/vue-missing-props-hints.ts +++ b/packages/language-service/lib/plugins/vue-missing-props-hints.ts @@ -8,7 +8,7 @@ import type { import { hyphenateAttr, hyphenateTag } from '@vue/language-core'; import * as html from 'vscode-html-languageservice'; import { AttrNameCasing, checkCasing } from '../nameCasing'; -import { getEmbeddedInfo } from './utils'; +import { getEmbeddedInfo } from '../utils'; export function create( { getComponentNames, getElementNames, getComponentProps }: import('@vue/typescript-plugin/lib/requests').Requests, diff --git a/packages/language-service/lib/plugins/vue-scoped-class-links.ts b/packages/language-service/lib/plugins/vue-scoped-class-links.ts index d02d655df1..8fc02c9e85 100644 --- a/packages/language-service/lib/plugins/vue-scoped-class-links.ts +++ b/packages/language-service/lib/plugins/vue-scoped-class-links.ts @@ -1,6 +1,6 @@ import type { LanguageServicePlugin } from '@volar/language-service'; import { tsCodegen } from '@vue/language-core'; -import { getEmbeddedInfo } from './utils'; +import { getEmbeddedInfo } from '../utils'; export function create(): LanguageServicePlugin { return { diff --git a/packages/language-service/lib/plugins/vue-sfc.ts b/packages/language-service/lib/plugins/vue-sfc.ts index 11584a39af..68095b32cd 100644 --- a/packages/language-service/lib/plugins/vue-sfc.ts +++ b/packages/language-service/lib/plugins/vue-sfc.ts @@ -10,8 +10,8 @@ import type { import { VueVirtualCode } from '@vue/language-core'; import { create as createHtmlService } from 'volar-service-html'; import * as html from 'vscode-html-languageservice'; -import { loadLanguageBlocks } from './data'; -import { getEmbeddedInfo } from './utils'; +import { loadLanguageBlocks } from '../data'; +import { getEmbeddedInfo } from '../utils'; let sfcDataProvider: html.IHTMLDataProvider | undefined; diff --git a/packages/language-service/lib/plugins/vue-suggest-define-assignment.ts b/packages/language-service/lib/plugins/vue-suggest-define-assignment.ts index e79b554bd5..46eda5ac48 100644 --- a/packages/language-service/lib/plugins/vue-suggest-define-assignment.ts +++ b/packages/language-service/lib/plugins/vue-suggest-define-assignment.ts @@ -1,6 +1,6 @@ import type { CompletionItem, CompletionItemKind, LanguageServicePlugin } from '@volar/language-service'; import { type TextRange, tsCodegen } from '@vue/language-core'; -import { getEmbeddedInfo } from './utils'; +import { getEmbeddedInfo } from '../utils'; export function create(): LanguageServicePlugin { return { diff --git a/packages/language-service/lib/plugins/vue-template-ref-links.ts b/packages/language-service/lib/plugins/vue-template-ref-links.ts index cd526386c3..73c74f72dc 100644 --- a/packages/language-service/lib/plugins/vue-template-ref-links.ts +++ b/packages/language-service/lib/plugins/vue-template-ref-links.ts @@ -1,6 +1,6 @@ import type { LanguageServicePlugin } from '@volar/language-service'; import { tsCodegen } from '@vue/language-core'; -import { getEmbeddedInfo } from './utils'; +import { getEmbeddedInfo } from '../utils'; export function create(): LanguageServicePlugin { return { diff --git a/packages/language-service/lib/plugins/vue-template.ts b/packages/language-service/lib/plugins/vue-template.ts index a5636ac696..42a73b4243 100644 --- a/packages/language-service/lib/plugins/vue-template.ts +++ b/packages/language-service/lib/plugins/vue-template.ts @@ -13,9 +13,9 @@ import { create as createHtmlService } from 'volar-service-html'; import { create as createPugService } from 'volar-service-pug'; import * as html from 'vscode-html-languageservice'; import { URI, Utils } from 'vscode-uri'; +import { loadModelModifiersData, loadTemplateData } from '../data'; import { AttrNameCasing, checkCasing, TagNameCasing } from '../nameCasing'; -import { loadModelModifiersData, loadTemplateData } from './data'; -import { getEmbeddedInfo } from './utils'; +import { getEmbeddedInfo } from '../utils'; const specialTags = new Set([ 'slot', diff --git a/packages/language-service/lib/plugins/vue-twoslash-queries.ts b/packages/language-service/lib/plugins/vue-twoslash-queries.ts index c93e80bc34..b67f327790 100644 --- a/packages/language-service/lib/plugins/vue-twoslash-queries.ts +++ b/packages/language-service/lib/plugins/vue-twoslash-queries.ts @@ -1,5 +1,5 @@ import type { InlayHint, LanguageServicePlugin, Position } from '@volar/language-service'; -import { getEmbeddedInfo } from './utils'; +import { getEmbeddedInfo } from '../utils'; const twoslashTemplateReg = //g; const twoslashScriptReg = /(?<=^|\n)\s*\/\/\s*\^\?/g; diff --git a/packages/language-service/lib/plugins/utils.ts b/packages/language-service/lib/utils.ts similarity index 92% rename from packages/language-service/lib/plugins/utils.ts rename to packages/language-service/lib/utils.ts index 60ddd36d42..f915843766 100644 --- a/packages/language-service/lib/plugins/utils.ts +++ b/packages/language-service/lib/utils.ts @@ -2,10 +2,6 @@ import { type LanguageServiceContext, type SourceScript, type TextDocument } fro import { VueVirtualCode } from '@vue/language-core'; import { URI } from 'vscode-uri'; -export function sleep(ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)); -} - export function getEmbeddedInfo( context: LanguageServiceContext, document: TextDocument, From dff519af4505d9935cbba80fe3ba5234571e23fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=B1=E5=90=B9=E8=89=B2=E5=BE=A1=E5=AE=88?= <85992002+KazariEX@users.noreply.github.com> Date: Fri, 25 Jul 2025 16:15:44 +0800 Subject: [PATCH 05/25] fix(vscode): add `class` scope fallback for `component` semantic tokens (#5559) --- extensions/vscode/package.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index 02609994fe..50a8c8f071 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -222,7 +222,8 @@ "language": "vue", "scopes": { "component": [ - "support.class.component.vue" + "support.class.component.vue", + "entity.name.type.class.vue" ] } }, @@ -230,7 +231,8 @@ "language": "markdown", "scopes": { "component": [ - "support.class.component.vue" + "support.class.component.vue", + "entity.name.type.class.vue" ] } }, @@ -238,7 +240,8 @@ "language": "html", "scopes": { "component": [ - "support.class.component.vue" + "support.class.component.vue", + "entity.name.type.class.vue" ] } } From d80cfee142fda34772286c1e4b7c35d92e9e7b38 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Fri, 25 Jul 2025 21:19:57 +0800 Subject: [PATCH 06/25] fix(vscode): make sure extension is loaded immediately close #5533 --- extensions/vscode/languages/stub.json | 1 + extensions/vscode/package.json | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 extensions/vscode/languages/stub.json diff --git a/extensions/vscode/languages/stub.json b/extensions/vscode/languages/stub.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/extensions/vscode/languages/stub.json @@ -0,0 +1 @@ +{} diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index 50a8c8f071..62e015bb65 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -67,6 +67,11 @@ { "id": "jade", "configuration": "./languages/sfc-template-language-configuration.json" + }, + { + "id": "plaintext", + "configuration": "./languages/stub.json", + "//": "Make sure Vue extension is loaded immediately when VSCode starts." } ], "typescriptServerPlugins": [ From d407159442b42bc3021b58834f829a83de3c571a Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Sat, 26 Jul 2025 05:35:26 +0800 Subject: [PATCH 07/25] fix(language-service): only check globalTypesPath for FS files --- .../language-service/lib/plugins/vue-global-types-error.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/language-service/lib/plugins/vue-global-types-error.ts b/packages/language-service/lib/plugins/vue-global-types-error.ts index 557894ad76..db1253b2e5 100644 --- a/packages/language-service/lib/plugins/vue-global-types-error.ts +++ b/packages/language-service/lib/plugins/vue-global-types-error.ts @@ -17,7 +17,10 @@ export function create(): LanguageServicePlugin { if (!info) { return; } - const { root } = info; + const { sourceScript, root } = info; + if (sourceScript.id.scheme !== 'file') { + return; + } const { vueCompilerOptions } = root; const globalTypesPath = vueCompilerOptions.globalTypesPath(root.fileName); From e3aa6d1dd50bf8fa22fc765aa2a7ffe841254934 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Sat, 26 Jul 2025 05:56:47 +0800 Subject: [PATCH 08/25] fix(vscode): handle fail tsserver requests to avlid memory leak --- extensions/vscode/index.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/extensions/vscode/index.ts b/extensions/vscode/index.ts index 98feb55257..fc15a96ebf 100644 --- a/extensions/vscode/index.ts +++ b/extensions/vscode/index.ts @@ -171,13 +171,16 @@ function launch(context: vscode.ExtensionContext) { ); client.onNotification('tsserver/request', async ([seq, command, args]) => { - const res = await vscode.commands.executeCommand<{ body: unknown } | undefined>( + vscode.commands.executeCommand<{ body: unknown } | undefined>( 'typescript.tsserverRequest', command, args, { isAsync: true, lowPriority: true }, - ); - client.sendNotification('tsserver/response', [seq, res?.body]); + ).then(res => { + client.sendNotification('tsserver/response', [seq, res?.body]); + }, () => { + client.sendNotification('tsserver/response', [seq, undefined]); + }); }); client.start(); From a2b2bb36cd892c6db215234ade856195fd8f736b Mon Sep 17 00:00:00 2001 From: KazariEX Date: Sat, 26 Jul 2025 23:42:37 +0800 Subject: [PATCH 09/25] fix(typescript-plugin): ensure all requests do not return void --- packages/language-service/index.ts | 22 +++------ .../lib/requests/collectExtractProps.ts | 14 ++---- .../lib/requests/getComponentDirectives.ts | 12 +++-- .../lib/requests/getComponentEvents.ts | 14 +++--- .../lib/requests/getComponentNames.ts | 21 +++----- .../lib/requests/getComponentProps.ts | 14 +++--- .../lib/requests/getComponentSlots.ts | 13 ++--- .../lib/requests/getElementAttrs.ts | 11 +++-- .../lib/requests/getElementNames.ts | 19 +++----- .../lib/requests/getPropertiesAtLocation.ts | 48 ++++++++++--------- 10 files changed, 87 insertions(+), 101 deletions(-) diff --git a/packages/language-service/index.ts b/packages/language-service/index.ts index 76f04a05df..a95353cb72 100644 --- a/packages/language-service/index.ts +++ b/packages/language-service/index.ts @@ -31,22 +31,14 @@ import { create as createVueTwoslashQueriesPlugin } from './lib/plugins/vue-twos export function createVueLanguageServicePlugins( ts: typeof import('typescript'), - tsPluginClient: import('@vue/typescript-plugin/lib/requests').Requests = { - collectExtractProps: () => undefined, - getImportPathForFile: () => undefined, - getPropertiesAtLocation: () => undefined, - getComponentDirectives: () => undefined, - getComponentEvents: () => undefined, - getComponentNames: () => undefined, - getComponentProps: () => undefined, - getComponentSlots: () => undefined, - getElementAttrs: () => undefined, - getElementNames: () => undefined, - getDocumentHighlights: () => undefined, - getEncodedSemanticClassifications: () => undefined, - getQuickInfoAtPosition: () => undefined, - }, + tsPluginClient?: import('@vue/typescript-plugin/lib/requests').Requests, ) { + tsPluginClient ??= new Proxy({}, { + get() { + return () => undefined; + }, + }) as NonNullable; + return [ createCssPlugin(), createJsonPlugin(), diff --git a/packages/typescript-plugin/lib/requests/collectExtractProps.ts b/packages/typescript-plugin/lib/requests/collectExtractProps.ts index d272872947..363457a095 100644 --- a/packages/typescript-plugin/lib/requests/collectExtractProps.ts +++ b/packages/typescript-plugin/lib/requests/collectExtractProps.ts @@ -9,13 +9,9 @@ export function collectExtractProps( const { typescript: ts, languageService, language } = this; const sourceScript = language.scripts.get(fileName); - if (!sourceScript?.generated) { - return; - } - - const root = sourceScript.generated.root; - if (!(root instanceof VueVirtualCode)) { - return; + const root = sourceScript?.generated?.root; + if (!sourceScript?.generated || !(root instanceof VueVirtualCode)) { + return []; } const result = new Map map) : []; + const script = sourceScript.generated.languagePlugin.typescript?.getServiceScript(root); + const maps = script ? [...language.maps.forEach(script.code)].map(([, map]) => map) : []; const { sfc } = root; sourceFile.forEachChild(function visit(node) { diff --git a/packages/typescript-plugin/lib/requests/getComponentDirectives.ts b/packages/typescript-plugin/lib/requests/getComponentDirectives.ts index c9b4dec522..f5181e44c1 100644 --- a/packages/typescript-plugin/lib/requests/getComponentDirectives.ts +++ b/packages/typescript-plugin/lib/requests/getComponentDirectives.ts @@ -16,12 +16,14 @@ export function getComponentDirectives( fileName: string, ) { const { typescript: ts, language, languageService } = this; - const volarFile = language.scripts.get(fileName); - if (!(volarFile?.generated?.root instanceof VueVirtualCode)) { - return; + + const sourceScript = language.scripts.get(fileName); + const root = sourceScript?.generated?.root; + if (!sourceScript?.generated || !(root instanceof VueVirtualCode)) { + return []; } - const vueCode = volarFile.generated.root; - const directives = getVariableType(ts, languageService, vueCode, '__VLS_directives'); + + const directives = getVariableType(ts, languageService, root, '__VLS_directives'); if (!directives) { return []; } diff --git a/packages/typescript-plugin/lib/requests/getComponentEvents.ts b/packages/typescript-plugin/lib/requests/getComponentEvents.ts index 4e5cecf15f..812feed769 100644 --- a/packages/typescript-plugin/lib/requests/getComponentEvents.ts +++ b/packages/typescript-plugin/lib/requests/getComponentEvents.ts @@ -8,19 +8,21 @@ export function getComponentEvents( tag: string, ) { const { typescript: ts, language, languageService } = this; - const volarFile = language.scripts.get(fileName); - if (!(volarFile?.generated?.root instanceof VueVirtualCode)) { - return; + + const sourceScript = language.scripts.get(fileName); + const root = sourceScript?.generated?.root; + if (!sourceScript?.generated || !(root instanceof VueVirtualCode)) { + return []; } - const vueCode = volarFile.generated.root; + const program = languageService.getProgram()!; const checker = program.getTypeChecker(); - const components = getVariableType(ts, languageService, vueCode, '__VLS_components'); + const components = getVariableType(ts, languageService, root, '__VLS_components'); if (!components) { return []; } - const componentType = getComponentType(ts, languageService, vueCode, components, fileName, tag); + const componentType = getComponentType(ts, languageService, root, components, fileName, tag); if (!componentType) { return []; } diff --git a/packages/typescript-plugin/lib/requests/getComponentNames.ts b/packages/typescript-plugin/lib/requests/getComponentNames.ts index e80a7ac659..a6e28f5e26 100644 --- a/packages/typescript-plugin/lib/requests/getComponentNames.ts +++ b/packages/typescript-plugin/lib/requests/getComponentNames.ts @@ -1,5 +1,4 @@ import { VueVirtualCode } from '@vue/language-core'; -import type * as ts from 'typescript'; import type { RequestContext } from './types'; import { getSelfComponentName, getVariableType } from './utils'; @@ -8,26 +7,20 @@ export function getComponentNames( fileName: string, ) { const { typescript: ts, language, languageService } = this; - const volarFile = language.scripts.get(fileName); - if (!(volarFile?.generated?.root instanceof VueVirtualCode)) { - return; + + const sourceScript = language.scripts.get(fileName); + const root = sourceScript?.generated?.root; + if (!sourceScript?.generated || !(root instanceof VueVirtualCode)) { + return []; } - const vueCode = volarFile.generated.root; - return _getComponentNames(ts, languageService, vueCode); -} -export function _getComponentNames( - ts: typeof import('typescript'), - tsLs: ts.LanguageService, - vueCode: VueVirtualCode, -) { - const names = getVariableType(ts, tsLs, vueCode, '__VLS_components') + const names = getVariableType(ts, languageService, root, '__VLS_components') ?.type ?.getProperties() .map(c => c.name) .filter(entry => !entry.includes('$') && !entry.startsWith('_')) ?? []; - names.push(getSelfComponentName(vueCode.fileName)); + names.push(getSelfComponentName(fileName)); return names; } diff --git a/packages/typescript-plugin/lib/requests/getComponentProps.ts b/packages/typescript-plugin/lib/requests/getComponentProps.ts index f8c88b25e6..ff4160437a 100644 --- a/packages/typescript-plugin/lib/requests/getComponentProps.ts +++ b/packages/typescript-plugin/lib/requests/getComponentProps.ts @@ -18,17 +18,19 @@ export function getComponentProps( tag: string, ) { const { typescript: ts, language, languageService } = this; - const volarFile = language.scripts.get(fileName); - if (!(volarFile?.generated?.root instanceof VueVirtualCode)) { - return; + + const sourceScript = language.scripts.get(fileName); + const root = sourceScript?.generated?.root; + if (!sourceScript?.generated || !(root instanceof VueVirtualCode)) { + return []; } - const vueCode = volarFile.generated.root; - const components = getVariableType(ts, languageService, vueCode, '__VLS_components'); + + const components = getVariableType(ts, languageService, root, '__VLS_components'); if (!components) { return []; } - const componentType = getComponentType(ts, languageService, vueCode, components, fileName, tag); + const componentType = getComponentType(ts, languageService, root, components, fileName, tag); if (!componentType) { return []; } diff --git a/packages/typescript-plugin/lib/requests/getComponentSlots.ts b/packages/typescript-plugin/lib/requests/getComponentSlots.ts index b48828b164..d00f2c9651 100644 --- a/packages/typescript-plugin/lib/requests/getComponentSlots.ts +++ b/packages/typescript-plugin/lib/requests/getComponentSlots.ts @@ -7,19 +7,20 @@ export function getComponentSlots( fileName: string, ) { const { typescript: ts, language, languageService } = this; - const volarFile = language.scripts.get(fileName); - if (!(volarFile?.generated?.root instanceof VueVirtualCode)) { - return; + + const sourceScript = language.scripts.get(fileName); + const root = sourceScript?.generated?.root; + if (!sourceScript?.generated || !(root instanceof VueVirtualCode)) { + return []; } - const vueCode = volarFile.generated.root; - const codegen = tsCodegen.get(vueCode.sfc); + const codegen = tsCodegen.get(root.sfc); if (!codegen) { return; } const assignName = codegen.getSetupSlotsAssignName() ?? `__VLS_slots`; - const slots = getVariableType(ts, languageService, vueCode, assignName); + const slots = getVariableType(ts, languageService, root, assignName); if (!slots) { return []; } diff --git a/packages/typescript-plugin/lib/requests/getElementAttrs.ts b/packages/typescript-plugin/lib/requests/getElementAttrs.ts index dee3f83373..f8fcd3b63e 100644 --- a/packages/typescript-plugin/lib/requests/getElementAttrs.ts +++ b/packages/typescript-plugin/lib/requests/getElementAttrs.ts @@ -8,15 +8,16 @@ export function getElementAttrs( tagName: string, ) { const { typescript: ts, language, languageService } = this; - const volarFile = language.scripts.get(fileName); - if (!(volarFile?.generated?.root instanceof VueVirtualCode)) { - return; + + const sourceScript = language.scripts.get(fileName); + const root = sourceScript?.generated?.root; + if (!sourceScript?.generated || !(root instanceof VueVirtualCode)) { + return []; } - const vueCode = volarFile.generated.root; const program = languageService.getProgram()!; const checker = program.getTypeChecker(); - const elements = getVariableType(ts, languageService, vueCode, '__VLS_elements'); + const elements = getVariableType(ts, languageService, root, '__VLS_elements'); if (!elements) { return []; } diff --git a/packages/typescript-plugin/lib/requests/getElementNames.ts b/packages/typescript-plugin/lib/requests/getElementNames.ts index 15ac70b8ee..13faeecfeb 100644 --- a/packages/typescript-plugin/lib/requests/getElementNames.ts +++ b/packages/typescript-plugin/lib/requests/getElementNames.ts @@ -1,5 +1,4 @@ import { VueVirtualCode } from '@vue/language-core'; -import type * as ts from 'typescript'; import type { RequestContext } from './types'; import { getVariableType } from './utils'; @@ -8,20 +7,14 @@ export function getElementNames( fileName: string, ) { const { typescript: ts, language, languageService } = this; - const volarFile = language.scripts.get(fileName); - if (!(volarFile?.generated?.root instanceof VueVirtualCode)) { - return; + + const sourceScript = language.scripts.get(fileName); + const root = sourceScript?.generated?.root; + if (!sourceScript?.generated || !(root instanceof VueVirtualCode)) { + return []; } - const vueCode = volarFile.generated.root; - return _getElementNames(ts, languageService, vueCode); -} -export function _getElementNames( - ts: typeof import('typescript'), - tsLs: ts.LanguageService, - vueCode: VueVirtualCode, -) { - return getVariableType(ts, tsLs, vueCode, '__VLS_elements') + return getVariableType(ts, languageService, root, '__VLS_elements') ?.type ?.getProperties() .map(c => c.name) diff --git a/packages/typescript-plugin/lib/requests/getPropertiesAtLocation.ts b/packages/typescript-plugin/lib/requests/getPropertiesAtLocation.ts index f6131f43d4..5315d2f3e4 100644 --- a/packages/typescript-plugin/lib/requests/getPropertiesAtLocation.ts +++ b/packages/typescript-plugin/lib/requests/getPropertiesAtLocation.ts @@ -1,6 +1,6 @@ /// -import { isCompletionEnabled } from '@vue/language-core'; +import { isCompletionEnabled, VueVirtualCode } from '@vue/language-core'; import type * as ts from 'typescript'; import type { RequestContext } from './types'; @@ -12,40 +12,44 @@ export function getPropertiesAtLocation( const { languageService, language, typescript: ts } = this; // mapping - const file = language.scripts.get(fileName); - if (file?.generated) { - const virtualScript = file.generated.languagePlugin.typescript?.getServiceScript(file.generated.root); - if (!virtualScript) { - return; - } - let mapped = false; - for (const [_sourceScript, map] of language.maps.forEach(virtualScript.code)) { - for (const [position2, mapping] of map.toGeneratedLocation(position)) { - if (isCompletionEnabled(mapping.data)) { - position = position2; - mapped = true; - break; - } - } - if (mapped) { + const sourceScript = language.scripts.get(fileName); + const root = sourceScript?.generated?.root; + if (!sourceScript?.generated || !(root instanceof VueVirtualCode)) { + return []; + } + + const virtualScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(root); + if (!virtualScript) { + return []; + } + + let mapped = false; + for (const [_sourceScript, map] of language.maps.forEach(virtualScript.code)) { + for (const [position2, mapping] of map.toGeneratedLocation(position)) { + if (isCompletionEnabled(mapping.data)) { + position = position2; + mapped = true; break; } } - if (!mapped) { - return; + if (mapped) { + break; } - position += file.snapshot.getLength(); } + if (!mapped) { + return []; + } + position += sourceScript.snapshot.getLength(); const program = languageService.getProgram()!; const sourceFile = program.getSourceFile(fileName); if (!sourceFile) { - return; + return []; } const node = findPositionIdentifier(sourceFile, sourceFile, position); if (!node) { - return; + return []; } const checker = program.getTypeChecker(); From ae8093a08b373831127cd8f59070d92013fdf0d5 Mon Sep 17 00:00:00 2001 From: KazariEX Date: Sat, 26 Jul 2025 23:52:38 +0800 Subject: [PATCH 10/25] refactor(typescript-plugin): explicitly annotate requests with type --- .../lib/plugins/vue-document-drop.ts | 15 +++++++-------- .../lib/requests/collectExtractProps.ts | 14 ++++++++------ .../lib/requests/getComponentDirectives.ts | 2 +- .../lib/requests/getComponentEvents.ts | 2 +- .../lib/requests/getComponentNames.ts | 2 +- .../lib/requests/getComponentProps.ts | 2 +- .../lib/requests/getComponentSlots.ts | 4 ++-- .../lib/requests/getElementAttrs.ts | 2 +- .../lib/requests/getElementNames.ts | 2 +- .../lib/requests/getImportPathForFile.ts | 12 ++++++------ .../lib/requests/getPropertiesAtLocation.ts | 2 +- 11 files changed, 30 insertions(+), 29 deletions(-) diff --git a/packages/language-service/lib/plugins/vue-document-drop.ts b/packages/language-service/lib/plugins/vue-document-drop.ts index f556e01287..dc4639c7ea 100644 --- a/packages/language-service/lib/plugins/vue-document-drop.ts +++ b/packages/language-service/lib/plugins/vue-document-drop.ts @@ -64,14 +64,13 @@ export function create( serviceScript.code.snapshot, ); const preferences = await getUserPreferences(context, tsDocument); - const importPathRequest = await getImportPathForFile( - root.fileName, - incomingFileName, - preferences, - ); - if (importPathRequest) { - importPath = importPathRequest; - } + importPath = ( + await getImportPathForFile( + root.fileName, + incomingFileName, + preferences, + ) ?? {} + ).path; } if (!importPath) { diff --git a/packages/typescript-plugin/lib/requests/collectExtractProps.ts b/packages/typescript-plugin/lib/requests/collectExtractProps.ts index 363457a095..4aa3548111 100644 --- a/packages/typescript-plugin/lib/requests/collectExtractProps.ts +++ b/packages/typescript-plugin/lib/requests/collectExtractProps.ts @@ -1,11 +1,17 @@ import { isSemanticTokensEnabled, VueVirtualCode } from '@vue/language-core'; import type { RequestContext } from './types'; +interface ExtractPropsInfo { + name: string; + type: string; + model: boolean; +} + export function collectExtractProps( this: RequestContext, fileName: string, templateCodeRange: [number, number], -) { +): ExtractPropsInfo[] { const { typescript: ts, languageService, language } = this; const sourceScript = language.scripts.get(fileName); @@ -14,11 +20,7 @@ export function collectExtractProps( return []; } - const result = new Map(); + const result = new Map(); const program = languageService.getProgram()!; const sourceFile = program.getSourceFile(fileName)!; const checker = program.getTypeChecker(); diff --git a/packages/typescript-plugin/lib/requests/getComponentDirectives.ts b/packages/typescript-plugin/lib/requests/getComponentDirectives.ts index f5181e44c1..24f204975c 100644 --- a/packages/typescript-plugin/lib/requests/getComponentDirectives.ts +++ b/packages/typescript-plugin/lib/requests/getComponentDirectives.ts @@ -14,7 +14,7 @@ const builtInDirectives = new Set([ export function getComponentDirectives( this: RequestContext, fileName: string, -) { +): string[] { const { typescript: ts, language, languageService } = this; const sourceScript = language.scripts.get(fileName); diff --git a/packages/typescript-plugin/lib/requests/getComponentEvents.ts b/packages/typescript-plugin/lib/requests/getComponentEvents.ts index 812feed769..ceea3992f7 100644 --- a/packages/typescript-plugin/lib/requests/getComponentEvents.ts +++ b/packages/typescript-plugin/lib/requests/getComponentEvents.ts @@ -6,7 +6,7 @@ export function getComponentEvents( this: RequestContext, fileName: string, tag: string, -) { +): string[] { const { typescript: ts, language, languageService } = this; const sourceScript = language.scripts.get(fileName); diff --git a/packages/typescript-plugin/lib/requests/getComponentNames.ts b/packages/typescript-plugin/lib/requests/getComponentNames.ts index a6e28f5e26..f4c4200b7c 100644 --- a/packages/typescript-plugin/lib/requests/getComponentNames.ts +++ b/packages/typescript-plugin/lib/requests/getComponentNames.ts @@ -5,7 +5,7 @@ import { getSelfComponentName, getVariableType } from './utils'; export function getComponentNames( this: RequestContext, fileName: string, -) { +): string[] { const { typescript: ts, language, languageService } = this; const sourceScript = language.scripts.get(fileName); diff --git a/packages/typescript-plugin/lib/requests/getComponentProps.ts b/packages/typescript-plugin/lib/requests/getComponentProps.ts index ff4160437a..e30130a259 100644 --- a/packages/typescript-plugin/lib/requests/getComponentProps.ts +++ b/packages/typescript-plugin/lib/requests/getComponentProps.ts @@ -16,7 +16,7 @@ export function getComponentProps( this: RequestContext, fileName: string, tag: string, -) { +): ComponentPropInfo[] { const { typescript: ts, language, languageService } = this; const sourceScript = language.scripts.get(fileName); diff --git a/packages/typescript-plugin/lib/requests/getComponentSlots.ts b/packages/typescript-plugin/lib/requests/getComponentSlots.ts index d00f2c9651..dce94857cb 100644 --- a/packages/typescript-plugin/lib/requests/getComponentSlots.ts +++ b/packages/typescript-plugin/lib/requests/getComponentSlots.ts @@ -5,7 +5,7 @@ import { getVariableType } from './utils'; export function getComponentSlots( this: RequestContext, fileName: string, -) { +): string[] { const { typescript: ts, language, languageService } = this; const sourceScript = language.scripts.get(fileName); @@ -16,7 +16,7 @@ export function getComponentSlots( const codegen = tsCodegen.get(root.sfc); if (!codegen) { - return; + return []; } const assignName = codegen.getSetupSlotsAssignName() ?? `__VLS_slots`; diff --git a/packages/typescript-plugin/lib/requests/getElementAttrs.ts b/packages/typescript-plugin/lib/requests/getElementAttrs.ts index f8fcd3b63e..0361f57030 100644 --- a/packages/typescript-plugin/lib/requests/getElementAttrs.ts +++ b/packages/typescript-plugin/lib/requests/getElementAttrs.ts @@ -6,7 +6,7 @@ export function getElementAttrs( this: RequestContext, fileName: string, tagName: string, -) { +): string[] { const { typescript: ts, language, languageService } = this; const sourceScript = language.scripts.get(fileName); diff --git a/packages/typescript-plugin/lib/requests/getElementNames.ts b/packages/typescript-plugin/lib/requests/getElementNames.ts index 13faeecfeb..3e384963b3 100644 --- a/packages/typescript-plugin/lib/requests/getElementNames.ts +++ b/packages/typescript-plugin/lib/requests/getElementNames.ts @@ -5,7 +5,7 @@ import { getVariableType } from './utils'; export function getElementNames( this: RequestContext, fileName: string, -) { +): string[] { const { typescript: ts, language, languageService } = this; const sourceScript = language.scripts.get(fileName); diff --git a/packages/typescript-plugin/lib/requests/getImportPathForFile.ts b/packages/typescript-plugin/lib/requests/getImportPathForFile.ts index 00c7afa428..1b92b07f95 100644 --- a/packages/typescript-plugin/lib/requests/getImportPathForFile.ts +++ b/packages/typescript-plugin/lib/requests/getImportPathForFile.ts @@ -6,13 +6,13 @@ export function getImportPathForFile( fileName: string, incomingFileName: string, preferences: ts.UserPreferences, -) { +): { path?: string } { const { typescript: ts, languageService, languageServiceHost } = this; const program = languageService.getProgram(); const incomingFile = program?.getSourceFile(incomingFileName); const sourceFile = program?.getSourceFile(fileName); if (!program || !sourceFile || !incomingFile) { - return; + return {}; } const getModuleSpecifiersWithCacheInfo: ( @@ -28,7 +28,7 @@ export function getImportPathForFile( computedWithoutCache: boolean; } = (ts as any).moduleSpecifiers.getModuleSpecifiersWithCacheInfo; const resolutionHost = (ts as any).createModuleSpecifierResolutionHost(program, languageServiceHost); - const moduleSpecifiers = getModuleSpecifiersWithCacheInfo( + const { moduleSpecifiers } = getModuleSpecifiersWithCacheInfo( (incomingFile as any).symbol, program.getTypeChecker(), languageServiceHost.getCompilationSettings(), @@ -37,7 +37,7 @@ export function getImportPathForFile( preferences, ); - for (const moduleSpecifier of moduleSpecifiers.moduleSpecifiers) { - return moduleSpecifier; - } + return { + path: moduleSpecifiers[0], + }; } diff --git a/packages/typescript-plugin/lib/requests/getPropertiesAtLocation.ts b/packages/typescript-plugin/lib/requests/getPropertiesAtLocation.ts index 5315d2f3e4..1d9e12e217 100644 --- a/packages/typescript-plugin/lib/requests/getPropertiesAtLocation.ts +++ b/packages/typescript-plugin/lib/requests/getPropertiesAtLocation.ts @@ -8,7 +8,7 @@ export function getPropertiesAtLocation( this: RequestContext, fileName: string, position: number, -) { +): string[] { const { languageService, language, typescript: ts } = this; // mapping From fba08b394c33295699b0ac01cd4d45d344824a6c Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Sun, 27 Jul 2025 08:47:09 +0800 Subject: [PATCH 11/25] fix(vscode): do not delay the execution of restartExtensionHost close #5544 --- extensions/vscode/index.ts | 40 ++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/extensions/vscode/index.ts b/extensions/vscode/index.ts index fc15a96ebf..4ba2152f8e 100644 --- a/extensions/vscode/index.ts +++ b/extensions/vscode/index.ts @@ -48,9 +48,7 @@ class _LanguageClient extends lsp.LanguageClient { } } -export const { activate, deactivate } = defineExtension(async () => { - await vscode.extensions.getExtension('vscode.typescript-language-features')?.activate(); - +export const { activate, deactivate } = defineExtension(() => { const context = extensionContext.value!; const volarLabs = createLabsInfo(); const activeTextEditor = useActiveTextEditor(); @@ -67,23 +65,18 @@ export const { activate, deactivate } = defineExtension(async () => { nextTick(() => stop()); if (needRestart) { - if (vscode.env.remoteName) { - vscode.window.showInformationMessage( - 'Please restart the extension host to activate Vue support in remote environments.', - 'Restart Extension Host', - 'Reload Window', - ).then(action => { - if (action === 'Restart Extension Host') { - vscode.commands.executeCommand('workbench.action.restartExtensionHost'); - } - else if (action === 'Reload Window') { - vscode.commands.executeCommand('workbench.action.reloadWindow'); - } - }); - } - else { - vscode.commands.executeCommand('workbench.action.restartExtensionHost'); - } + vscode.window.showInformationMessage( + 'Please restart the extension host to activate Vue support in remote environments.', + 'Restart Extension Host', + 'Reload Window', + ).then(action => { + if (action === 'Restart Extension Host') { + vscode.commands.executeCommand('workbench.action.restartExtensionHost'); + } + else if (action === 'Reload Window') { + vscode.commands.executeCommand('workbench.action.reloadWindow'); + } + }); return; } @@ -245,7 +238,12 @@ try { } if (tsExtension.isActive) { - needRestart = true; + if (!vscode.env.remoteName) { + vscode.commands.executeCommand('workbench.action.restartExtensionHost'); + } + else { + needRestart = true; + } } } catch {} From 403412a6ded3fac98d426109b7c0d53d10c2521b Mon Sep 17 00:00:00 2001 From: KazariEX Date: Sun, 27 Jul 2025 16:02:52 +0800 Subject: [PATCH 12/25] test(tsc): add missing project references --- .../passedFixtures/vue3.4_strictTemplate/tsconfig.json | 9 --------- .../#3718/main.vue | 0 test-workspace/tsc/tsconfig.json | 6 +++++- 3 files changed, 5 insertions(+), 10 deletions(-) delete mode 100644 test-workspace/tsc/passedFixtures/vue3.4_strictTemplate/tsconfig.json rename test-workspace/tsc/passedFixtures/{vue3.4_strictTemplate => vue3_strictTemplate}/#3718/main.vue (100%) diff --git a/test-workspace/tsc/passedFixtures/vue3.4_strictTemplate/tsconfig.json b/test-workspace/tsc/passedFixtures/vue3.4_strictTemplate/tsconfig.json deleted file mode 100644 index f4a3569427..0000000000 --- a/test-workspace/tsc/passedFixtures/vue3.4_strictTemplate/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "vueCompilerOptions": { - "target": 3.3, - "lib": "vue3.4", - "strictTemplates": true - }, - "include": ["**/*"] -} diff --git a/test-workspace/tsc/passedFixtures/vue3.4_strictTemplate/#3718/main.vue b/test-workspace/tsc/passedFixtures/vue3_strictTemplate/#3718/main.vue similarity index 100% rename from test-workspace/tsc/passedFixtures/vue3.4_strictTemplate/#3718/main.vue rename to test-workspace/tsc/passedFixtures/vue3_strictTemplate/#3718/main.vue diff --git a/test-workspace/tsc/tsconfig.json b/test-workspace/tsc/tsconfig.json index 740f6be87d..ab58c0bcb4 100644 --- a/test-workspace/tsc/tsconfig.json +++ b/test-workspace/tsc/tsconfig.json @@ -2,7 +2,7 @@ "include": [], "references": [ { "path": "./failureFixtures/#3632" }, - // { "path": "./failureFixtures/#4569" }, // TODO: not working with --build flag + { "path": "./failureFixtures/#4569" }, { "path": "./failureFixtures/#5071" }, { "path": "./failureFixtures/directives" }, @@ -14,6 +14,10 @@ { "path": "./passedFixtures/#3592" }, { "path": "./passedFixtures/#3819" }, { "path": "./passedFixtures/#4503" }, + { "path": "./passedFixtures/#5106" }, + { "path": "./passedFixtures/#5111" }, + { "path": "./passedFixtures/#5136" }, + { "path": "./passedFixtures/#5338" }, { "path": "./passedFixtures/core#9923" }, { "path": "./passedFixtures/fallthroughAttributes" }, { "path": "./passedFixtures/fallthroughAttributes_strictTemplate" }, From 6d59dee68699b5c36caffed462c96af4ebdb9210 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Sun, 27 Jul 2025 22:15:42 +0800 Subject: [PATCH 13/25] chore: update volar to 2.4.22 --- extensions/vscode/package.json | 2 +- packages/component-meta/package.json | 2 +- packages/language-core/package.json | 4 +- packages/language-plugin-pug/package.json | 2 +- packages/language-server/package.json | 4 +- packages/language-service/package.json | 6 +- packages/tsc/package.json | 2 +- packages/typescript-plugin/package.json | 2 +- pnpm-lock.yaml | 160 +++++++++++----------- 9 files changed, 92 insertions(+), 92 deletions(-) diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index 62e015bb65..d3fe8c4036 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -471,7 +471,7 @@ "@types/node": "^22.10.4", "@types/semver": "^7.5.3", "@types/vscode": "1.88.0", - "@volar/vscode": "2.4.20", + "@volar/vscode": "2.4.22", "@vscode/vsce": "^3.2.1", "@vue/compiler-sfc": "^3.5.0", "@vue/language-server": "3.0.4", diff --git a/packages/component-meta/package.json b/packages/component-meta/package.json index 504a2f739c..2c5e3c98bc 100644 --- a/packages/component-meta/package.json +++ b/packages/component-meta/package.json @@ -13,7 +13,7 @@ "directory": "packages/component-meta" }, "dependencies": { - "@volar/typescript": "2.4.20", + "@volar/typescript": "2.4.22", "@vue/language-core": "3.0.4", "path-browserify": "^1.0.1" }, diff --git a/packages/language-core/package.json b/packages/language-core/package.json index 24a78ae47d..1fa01c4148 100644 --- a/packages/language-core/package.json +++ b/packages/language-core/package.json @@ -13,7 +13,7 @@ "directory": "packages/language-core" }, "dependencies": { - "@volar/language-core": "2.4.20", + "@volar/language-core": "2.4.22", "@vue/compiler-dom": "^3.5.0", "@vue/compiler-vue2": "^2.7.16", "@vue/shared": "^3.5.0", @@ -26,7 +26,7 @@ "@types/node": "^22.10.4", "@types/path-browserify": "^1.0.1", "@types/picomatch": "^4.0.0", - "@volar/typescript": "2.4.20", + "@volar/typescript": "2.4.22", "@vue/compiler-sfc": "^3.5.0" }, "peerDependencies": { diff --git a/packages/language-plugin-pug/package.json b/packages/language-plugin-pug/package.json index 290f9f1b81..cbdedd9fa1 100644 --- a/packages/language-plugin-pug/package.json +++ b/packages/language-plugin-pug/package.json @@ -13,7 +13,7 @@ "directory": "packages/language-plugin-pug" }, "dependencies": { - "@volar/source-map": "2.4.20", + "@volar/source-map": "2.4.22", "volar-service-pug": "0.0.65" }, "devDependencies": { diff --git a/packages/language-server/package.json b/packages/language-server/package.json index 2c45282971..97bcf65a75 100644 --- a/packages/language-server/package.json +++ b/packages/language-server/package.json @@ -16,7 +16,7 @@ "directory": "packages/language-server" }, "dependencies": { - "@volar/language-server": "2.4.20", + "@volar/language-server": "2.4.22", "@vue/language-core": "3.0.4", "@vue/language-service": "3.0.4", "@vue/typescript-plugin": "3.0.4", @@ -27,6 +27,6 @@ }, "devDependencies": { "@typescript/server-harness": "latest", - "@volar/test-utils": "2.4.20" + "@volar/test-utils": "2.4.22" } } diff --git a/packages/language-service/package.json b/packages/language-service/package.json index 990ea50d2a..3923562bc2 100644 --- a/packages/language-service/package.json +++ b/packages/language-service/package.json @@ -17,7 +17,7 @@ "update-html-data": "node ./scripts/update-html-data.js" }, "dependencies": { - "@volar/language-service": "2.4.20", + "@volar/language-service": "2.4.22", "@vue/language-core": "3.0.4", "@vue/shared": "^3.5.0", "path-browserify": "^1.0.1", @@ -34,8 +34,8 @@ "devDependencies": { "@types/node": "^22.10.4", "@types/path-browserify": "^1.0.1", - "@volar/kit": "2.4.20", - "@volar/typescript": "2.4.20", + "@volar/kit": "2.4.22", + "@volar/typescript": "2.4.22", "@vue/compiler-dom": "^3.5.0", "@vue/typescript-plugin": "3.0.4", "vscode-css-languageservice": "^6.3.1" diff --git a/packages/tsc/package.json b/packages/tsc/package.json index 4bb8ee5818..0b546dfc7b 100644 --- a/packages/tsc/package.json +++ b/packages/tsc/package.json @@ -20,7 +20,7 @@ "typescript": ">=5.0.0" }, "dependencies": { - "@volar/typescript": "2.4.20", + "@volar/typescript": "2.4.22", "@vue/language-core": "3.0.4" }, "devDependencies": { diff --git a/packages/typescript-plugin/package.json b/packages/typescript-plugin/package.json index 3c402e5190..1d84ec05bf 100644 --- a/packages/typescript-plugin/package.json +++ b/packages/typescript-plugin/package.json @@ -13,7 +13,7 @@ "directory": "packages/typescript-plugin" }, "dependencies": { - "@volar/typescript": "2.4.20", + "@volar/typescript": "2.4.22", "@vue/language-core": "3.0.4", "@vue/shared": "^3.5.0", "path-browserify": "^1.0.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ef90bc2b68..1a58514491 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -51,8 +51,8 @@ importers: specifier: 1.88.0 version: 1.88.0 '@volar/vscode': - specifier: 2.4.20 - version: 2.4.20 + specifier: 2.4.22 + version: 2.4.22 '@vscode/vsce': specifier: ^3.2.1 version: 3.3.2 @@ -84,8 +84,8 @@ importers: packages/component-meta: dependencies: '@volar/typescript': - specifier: 2.4.20 - version: 2.4.20 + specifier: 2.4.22 + version: 2.4.22 '@vue/language-core': specifier: 3.0.4 version: link:../language-core @@ -111,8 +111,8 @@ importers: packages/language-core: dependencies: '@volar/language-core': - specifier: 2.4.20 - version: 2.4.20 + specifier: 2.4.22 + version: 2.4.22 '@vue/compiler-dom': specifier: ^3.5.0 version: 3.5.13 @@ -148,8 +148,8 @@ importers: specifier: ^4.0.0 version: 4.0.0 '@volar/typescript': - specifier: 2.4.20 - version: 2.4.20 + specifier: 2.4.22 + version: 2.4.22 '@vue/compiler-sfc': specifier: ^3.5.0 version: 3.5.13 @@ -157,8 +157,8 @@ importers: packages/language-plugin-pug: dependencies: '@volar/source-map': - specifier: 2.4.20 - version: 2.4.20 + specifier: 2.4.22 + version: 2.4.22 volar-service-pug: specifier: 0.0.65 version: 0.0.65 @@ -176,8 +176,8 @@ importers: packages/language-server: dependencies: '@volar/language-server': - specifier: 2.4.20 - version: 2.4.20 + specifier: 2.4.22 + version: 2.4.22 '@vue/language-core': specifier: 3.0.4 version: link:../language-core @@ -198,14 +198,14 @@ importers: specifier: latest version: 0.3.5 '@volar/test-utils': - specifier: 2.4.20 - version: 2.4.20 + specifier: 2.4.22 + version: 2.4.22 packages/language-service: dependencies: '@volar/language-service': - specifier: 2.4.20 - version: 2.4.20 + specifier: 2.4.22 + version: 2.4.22 '@vue/language-core': specifier: 3.0.4 version: link:../language-core @@ -217,25 +217,25 @@ importers: version: 1.0.1 volar-service-css: specifier: 0.0.65 - version: 0.0.65(@volar/language-service@2.4.20) + version: 0.0.65(@volar/language-service@2.4.22) volar-service-emmet: specifier: 0.0.65 - version: 0.0.65(@volar/language-service@2.4.20) + version: 0.0.65(@volar/language-service@2.4.22) volar-service-html: specifier: 0.0.65 - version: 0.0.65(@volar/language-service@2.4.20) + version: 0.0.65(@volar/language-service@2.4.22) volar-service-json: specifier: 0.0.65 - version: 0.0.65(@volar/language-service@2.4.20) + version: 0.0.65(@volar/language-service@2.4.22) volar-service-pug: specifier: 0.0.65 version: 0.0.65 volar-service-pug-beautify: specifier: 0.0.65 - version: 0.0.65(@volar/language-service@2.4.20) + version: 0.0.65(@volar/language-service@2.4.22) volar-service-typescript: specifier: 0.0.65 - version: 0.0.65(@volar/language-service@2.4.20) + version: 0.0.65(@volar/language-service@2.4.22) vscode-html-languageservice: specifier: ^5.2.0 version: 5.4.0 @@ -250,11 +250,11 @@ importers: specifier: ^1.0.1 version: 1.0.3 '@volar/kit': - specifier: 2.4.20 - version: 2.4.20(typescript@5.9.0-dev.20250425) + specifier: 2.4.22 + version: 2.4.22(typescript@5.9.0-dev.20250425) '@volar/typescript': - specifier: 2.4.20 - version: 2.4.20 + specifier: 2.4.22 + version: 2.4.22 '@vue/compiler-dom': specifier: ^3.5.0 version: 3.5.13 @@ -268,8 +268,8 @@ importers: packages/tsc: dependencies: '@volar/typescript': - specifier: 2.4.20 - version: 2.4.20 + specifier: 2.4.22 + version: 2.4.22 '@vue/language-core': specifier: 3.0.4 version: link:../language-core @@ -284,8 +284,8 @@ importers: packages/typescript-plugin: dependencies: '@volar/typescript': - specifier: 2.4.20 - version: 2.4.20 + specifier: 2.4.22 + version: 2.4.22 '@vue/language-core': specifier: 3.0.4 version: link:../language-core @@ -1467,31 +1467,31 @@ packages: '@vitest/utils@3.1.3': resolution: {integrity: sha512-2Ltrpht4OmHO9+c/nmHtF09HWiyWdworqnHIwjfvDyWjuwKbdkcS9AnhsDn+8E2RM4x++foD1/tNuLPVvWG1Rg==} - '@volar/kit@2.4.20': - resolution: {integrity: sha512-zC2uN3veE8uT5v+2FuwK2ocRoDpcuqbJpPNZR6jO/renewVVOleNTFv3gbk0hoG3qnAVENDGTw11bT49A9aefw==} + '@volar/kit@2.4.22': + resolution: {integrity: sha512-o2LhNb2PLCUJ6v2XSqN7m+pJt+SE0QW1U2E52jnS8yZ03ohcGOOuFJdH1VlZgCBk0RlwO4xp0OaDoTtyTvMTrw==} peerDependencies: typescript: '*' - '@volar/language-core@2.4.20': - resolution: {integrity: sha512-dRDF1G33xaAIDqR6+mXUIjXYdu9vzSxlMGfMEwBxQsfY/JMUEXSpLTR057oTKlUQ2nIvCmP9k94A8h8z2VrNSA==} + '@volar/language-core@2.4.22': + resolution: {integrity: sha512-gp4M7Di5KgNyIyO903wTClYBavRt6UyFNpc5LWfyZr1lBsTUY+QrVZfmbNF2aCyfklBOVk9YC4p+zkwoyT7ECg==} - '@volar/language-server@2.4.20': - resolution: {integrity: sha512-fNNFzEad0sO4pVZnpHggglbIeaKjLs4vH1JPPN+zd/4hSEI2u8+Qck10JhswCSO6xFTFbKxVquvWu2U2tT0EHQ==} + '@volar/language-server@2.4.22': + resolution: {integrity: sha512-THIGWcQsEJKZU7SjVKPcy4MIamX4qpusKErj33ru7fi2WcD+FmFjYY/F2LIk/C15xEcb34JT1uZBlbO2dfzYSQ==} - '@volar/language-service@2.4.20': - resolution: {integrity: sha512-LoCD4rEI1Bj5ld6b+2GH1SbDGnoisvJ5skHlrkFEtJWw0T2+bhqGUXwekFudV/bRtp8fPhvD5ZUtjWSW0VRztg==} + '@volar/language-service@2.4.22': + resolution: {integrity: sha512-8TmvOf/6uqaJMBVQIP9kgVpRzMrqLI3nCmWuSIPAldlmwjZTOiN17GA4AL4sTFJUg61xCSyMQWbProNFQ88yew==} - '@volar/source-map@2.4.20': - resolution: {integrity: sha512-mVjmFQH8mC+nUaVwmbxoYUy8cww+abaO8dWzqPUjilsavjxH0jCJ3Mp8HFuHsdewZs2c+SP+EO7hCd8Z92whJg==} + '@volar/source-map@2.4.22': + resolution: {integrity: sha512-L2nVr/1vei0xKRgO2tYVXtJYd09HTRjaZi418e85Q+QdbbqA8h7bBjfNyPPSsjnrOO4l4kaAo78c8SQUAdHvgA==} - '@volar/test-utils@2.4.20': - resolution: {integrity: sha512-xTRrNy7Q9udmJMzmS6VlqbPlm+R2Vnzfu9pN4zGskfuKKxsc6w0dby3y7HcWTv/5a2v15FctnVI99B+9LwhePQ==} + '@volar/test-utils@2.4.22': + resolution: {integrity: sha512-hSImBcIJkKqrE8txM+e4qKCBAwAU7PMlSNqitljuBwE1kztTpv4Szaaa7d5BnpIGlNsXdot0hYhpR8y3+BGJzg==} - '@volar/typescript@2.4.20': - resolution: {integrity: sha512-Oc4DczPwQyXcVbd+5RsNEqX6ia0+w3p+klwdZQ6ZKhFjWoBP9PCPQYlKYRi/tDemWphW93P/Vv13vcE9I9D2GQ==} + '@volar/typescript@2.4.22': + resolution: {integrity: sha512-6ZczlJW1/GWTrNnkmZxJp4qyBt/SGVlcTuCWpI5zLrdPdCZsj66Aff9ZsfFaT3TyjG8zVYgBMYPuCm/eRkpcpQ==} - '@volar/vscode@2.4.20': - resolution: {integrity: sha512-u69RZCsS+isskOihcY1th2B//v60mlVBkk6afvntmd81G0cFDUia1IXUhADWl0s8o4xN+aZIGFpWBq6QudEUCQ==} + '@volar/vscode@2.4.22': + resolution: {integrity: sha512-E5egfejA+3YvPqd37IeC676mJOgalQ/aAzGxVDnChdhR5+U5BtWAcILgIAf+T4/Cq12jPOV7KCn07mZ24DDp9w==} '@vscode/emmet-helper@2.11.0': resolution: {integrity: sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw==} @@ -4967,8 +4967,8 @@ snapshots: '@clack/prompts': 0.8.2 '@tsslint/config': 1.5.16(typescript@5.8.3) '@tsslint/core': 1.5.16 - '@volar/language-core': 2.4.20 - '@volar/typescript': 2.4.20 + '@volar/language-core': 2.4.22 + '@volar/typescript': 2.4.22 glob: 10.4.5 json5: 2.2.3 typescript: 5.8.3 @@ -5154,24 +5154,24 @@ snapshots: loupe: 3.1.3 tinyrainbow: 2.0.0 - '@volar/kit@2.4.20(typescript@5.9.0-dev.20250425)': + '@volar/kit@2.4.22(typescript@5.9.0-dev.20250425)': dependencies: - '@volar/language-service': 2.4.20 - '@volar/typescript': 2.4.20 + '@volar/language-service': 2.4.22 + '@volar/typescript': 2.4.22 typesafe-path: 0.2.2 typescript: 5.9.0-dev.20250425 vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.1.0 - '@volar/language-core@2.4.20': + '@volar/language-core@2.4.22': dependencies: - '@volar/source-map': 2.4.20 + '@volar/source-map': 2.4.22 - '@volar/language-server@2.4.20': + '@volar/language-server@2.4.22': dependencies: - '@volar/language-core': 2.4.20 - '@volar/language-service': 2.4.20 - '@volar/typescript': 2.4.20 + '@volar/language-core': 2.4.22 + '@volar/language-service': 2.4.22 + '@volar/typescript': 2.4.22 path-browserify: 1.0.1 request-light: 0.7.0 vscode-languageserver: 9.0.1 @@ -5179,29 +5179,29 @@ snapshots: vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.1.0 - '@volar/language-service@2.4.20': + '@volar/language-service@2.4.22': dependencies: - '@volar/language-core': 2.4.20 + '@volar/language-core': 2.4.22 vscode-languageserver-protocol: 3.17.5 vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.1.0 - '@volar/source-map@2.4.20': {} + '@volar/source-map@2.4.22': {} - '@volar/test-utils@2.4.20': + '@volar/test-utils@2.4.22': dependencies: - '@volar/language-core': 2.4.20 - '@volar/language-server': 2.4.20 + '@volar/language-core': 2.4.22 + '@volar/language-server': 2.4.22 vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.1.0 - '@volar/typescript@2.4.20': + '@volar/typescript@2.4.22': dependencies: - '@volar/language-core': 2.4.20 + '@volar/language-core': 2.4.22 path-browserify: 1.0.1 vscode-uri: 3.1.0 - '@volar/vscode@2.4.20': + '@volar/vscode@2.4.22': dependencies: path-browserify: 1.0.1 vscode-languageclient: 9.0.1 @@ -7628,55 +7628,55 @@ snapshots: - supports-color - terser - volar-service-css@0.0.65(@volar/language-service@2.4.20): + volar-service-css@0.0.65(@volar/language-service@2.4.22): dependencies: vscode-css-languageservice: 6.3.5 vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.1.0 optionalDependencies: - '@volar/language-service': 2.4.20 + '@volar/language-service': 2.4.22 - volar-service-emmet@0.0.65(@volar/language-service@2.4.20): + volar-service-emmet@0.0.65(@volar/language-service@2.4.22): dependencies: '@emmetio/css-parser': https://codeload.github.com/ramya-rao-a/css-parser/tar.gz/370c480ac103bd17c7bcfb34bf5d577dc40d3660 '@emmetio/html-matcher': 1.3.0 '@vscode/emmet-helper': 2.11.0 vscode-uri: 3.1.0 optionalDependencies: - '@volar/language-service': 2.4.20 + '@volar/language-service': 2.4.22 - volar-service-html@0.0.65(@volar/language-service@2.4.20): + volar-service-html@0.0.65(@volar/language-service@2.4.22): dependencies: vscode-html-languageservice: 5.4.0 vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.1.0 optionalDependencies: - '@volar/language-service': 2.4.20 + '@volar/language-service': 2.4.22 - volar-service-json@0.0.65(@volar/language-service@2.4.20): + volar-service-json@0.0.65(@volar/language-service@2.4.22): dependencies: vscode-json-languageservice: 5.6.1 vscode-uri: 3.1.0 optionalDependencies: - '@volar/language-service': 2.4.20 + '@volar/language-service': 2.4.22 - volar-service-pug-beautify@0.0.65(@volar/language-service@2.4.20): + volar-service-pug-beautify@0.0.65(@volar/language-service@2.4.22): dependencies: '@johnsoncodehk/pug-beautify': 0.2.2 optionalDependencies: - '@volar/language-service': 2.4.20 + '@volar/language-service': 2.4.22 volar-service-pug@0.0.65: dependencies: - '@volar/language-service': 2.4.20 + '@volar/language-service': 2.4.22 muggle-string: 0.4.1 pug-lexer: 5.0.1 pug-parser: 6.0.0 - volar-service-html: 0.0.65(@volar/language-service@2.4.20) + volar-service-html: 0.0.65(@volar/language-service@2.4.22) vscode-html-languageservice: 5.4.0 vscode-languageserver-textdocument: 1.0.12 - volar-service-typescript@0.0.65(@volar/language-service@2.4.20): + volar-service-typescript@0.0.65(@volar/language-service@2.4.22): dependencies: path-browserify: 1.0.1 semver: 7.7.2 @@ -7685,7 +7685,7 @@ snapshots: vscode-nls: 5.2.0 vscode-uri: 3.1.0 optionalDependencies: - '@volar/language-service': 2.4.20 + '@volar/language-service': 2.4.22 vscode-css-languageservice@6.3.5: dependencies: From 64f5da224ca4681330ae0af40edfa8e7aa9aa54a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=B1=E5=90=B9=E8=89=B2=E5=BE=A1=E5=AE=88?= <85992002+KazariEX@users.noreply.github.com> Date: Sun, 27 Jul 2025 23:15:52 +0800 Subject: [PATCH 14/25] fix(language-core): avoid references highlight of unrelated native element tags (#5563) --- packages/language-core/lib/codegen/codeFeatures.ts | 11 +++-------- .../language-core/lib/codegen/template/element.ts | 9 +++++++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/language-core/lib/codegen/codeFeatures.ts b/packages/language-core/lib/codegen/codeFeatures.ts index c7143649c7..72d4f896ad 100644 --- a/packages/language-core/lib/codegen/codeFeatures.ts +++ b/packages/language-core/lib/codegen/codeFeatures.ts @@ -24,13 +24,12 @@ const raw = { navigation: { navigation: true, }, + navigationWithoutHighlight: { + navigation: { shouldHighlight: () => false }, + }, navigationWithoutRename: { navigation: { shouldRename: () => false }, }, - navigationAndCompletion: { - navigation: true, - completion: true, - }, navigationAndAdditionalCompletion: { navigation: true, completion: { isAdditional: true }, @@ -63,10 +62,6 @@ const raw = { verification: true, navigation: true, }, - withoutHighlightAndCompletionAndNavigation: { - semantic: { shouldHighlight: () => false }, - verification: true, - }, withoutSemantic: { verification: true, navigation: true, diff --git a/packages/language-core/lib/codegen/template/element.ts b/packages/language-core/lib/codegen/template/element.ts index 55e28e1b0e..c20e0bb5d4 100644 --- a/packages/language-core/lib/codegen/template/element.ts +++ b/packages/language-core/lib/codegen/template/element.ts @@ -301,13 +301,18 @@ export function* generateElement( : undefined; const failedPropExps: FailedPropExpression[] = []; + const features = { + ...codeFeatures.semanticWithoutHighlight, + ...codeFeatures.navigationWithoutHighlight, + }; + yield `__VLS_asFunctionalElement(__VLS_elements`; yield* generatePropertyAccess( options, ctx, node.tag, startTagOffset, - ctx.codeFeatures.withoutHighlightAndCompletion, + features, ); if (endTagOffset !== undefined) { yield `, __VLS_elements`; @@ -316,7 +321,7 @@ export function* generateElement( ctx, node.tag, endTagOffset, - ctx.codeFeatures.withoutHighlightAndCompletion, + features, ); } yield `)(`; From aa3531f6e619e253b17592694b0ef5b9f765f229 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Sun, 27 Jul 2025 23:38:43 +0800 Subject: [PATCH 15/25] fix(language-core): tolerance for incomplete root template tag close #4893 --- .../language-core/lib/plugins/file-vue.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/language-core/lib/plugins/file-vue.ts b/packages/language-core/lib/plugins/file-vue.ts index 892ab1b5f8..4edc60baea 100644 --- a/packages/language-core/lib/plugins/file-vue.ts +++ b/packages/language-core/lib/plugins/file-vue.ts @@ -19,7 +19,24 @@ const plugin: VueLanguagePlugin = ({ vueCompilerOptions }) => { if (languageId !== 'vue') { return; } - return parse(content); + const sfc = parse(content); + for (const error of sfc.errors) { + // Handle 'Element is missing end tag.' error, see #4893 + if ( + 'code' in error && error.code === 24 && sfc.descriptor.template + && error.loc?.start.line === sfc.descriptor.template.loc.start.line + ) { + const template = sfc.descriptor.template; + const templateText = template.content; + const endTagOffset = templateText.lastIndexOf('<'); + const endTagText = templateText.slice(endTagOffset).trimEnd(); + if (''.startsWith(endTagText)) { + sfc.descriptor.template.loc.end.offset = template.loc.start.offset + endTagOffset; + template.content = templateText.slice(0, endTagOffset); + } + } + } + return sfc; }, updateSFC(sfc, change) { From b7a9bbb25ec843e9b1020044407cebf3792434ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=B1=E5=90=B9=E8=89=B2=E5=BE=A1=E5=AE=88?= <85992002+KazariEX@users.noreply.github.com> Date: Mon, 28 Jul 2025 01:59:24 +0800 Subject: [PATCH 16/25] refactor(language-core): decouple the usage of code features with template context (#5564) --- .../language-core/lib/codegen/script/index.ts | 9 ++-- .../lib/codegen/template/context.ts | 6 --- .../lib/codegen/template/element.ts | 26 ++++++------ .../lib/codegen/template/elementDirectives.ts | 23 +++++----- .../lib/codegen/template/elementEvents.ts | 13 +++--- .../lib/codegen/template/elementProps.ts | 33 +++++++-------- .../lib/codegen/template/index.ts | 20 ++++----- .../lib/codegen/template/interpolation.ts | 3 +- .../lib/codegen/template/slotOutlet.ts | 13 +++--- .../codegen/template/styleScopedClasses.ts | 7 ++-- .../lib/codegen/template/templateChild.ts | 3 +- .../lib/codegen/template/vFor.ts | 7 ++-- .../language-core/lib/codegen/template/vIf.ts | 3 +- .../lib/codegen/template/vSlot.ts | 16 +++---- packages/language-core/lib/plugins/vue-tsx.ts | 42 +++++++++---------- 15 files changed, 109 insertions(+), 115 deletions(-) diff --git a/packages/language-core/lib/codegen/script/index.ts b/packages/language-core/lib/codegen/script/index.ts index 19fcb2a789..c1c374c543 100644 --- a/packages/language-core/lib/codegen/script/index.ts +++ b/packages/language-core/lib/codegen/script/index.ts @@ -26,9 +26,10 @@ export interface ScriptCodegenOptions { templateRefNames: Set; } -export function* generateScript(options: ScriptCodegenOptions): Generator { - const ctx = createScriptCodegenContext(options); - +export function* generateScript( + options: ScriptCodegenOptions, + ctx: ScriptCodegenContext = createScriptCodegenContext(options), +): Generator { yield* generateGlobalTypesPath(options); if (options.sfc.script?.src) { @@ -148,8 +149,6 @@ export function* generateScript(options: ScriptCodegenOptions): Generator`, ); @@ -469,7 +469,7 @@ function* generateElementReference( ctx, content, startOffset, - ctx.codeFeatures.navigation, + codeFeatures.navigation, ); yield `} */${endOfLine}`; diff --git a/packages/language-core/lib/codegen/template/elementDirectives.ts b/packages/language-core/lib/codegen/template/elementDirectives.ts index 02bf57f3c7..9deaa1491e 100644 --- a/packages/language-core/lib/codegen/template/elementDirectives.ts +++ b/packages/language-core/lib/codegen/template/elementDirectives.ts @@ -41,9 +41,9 @@ export function* generateElementDirectives( yield* wrapWith( prop.loc.start.offset, prop.loc.end.offset, - ctx.codeFeatures.verification, + codeFeatures.verification, `__VLS_asFunctionalDirective(`, - ...generateIdentifier(options, ctx, prop), + ...generateIdentifier(options, prop), `)(null!, { ...__VLS_directiveBindingRestFields, `, ...generateArg(options, ctx, prop), ...generateModifiers(options, ctx, prop), @@ -56,23 +56,22 @@ export function* generateElementDirectives( function* generateIdentifier( options: TemplateCodegenOptions, - ctx: TemplateCodegenContext, prop: CompilerDOM.DirectiveNode, ): Generator { const rawName = 'v-' + prop.name; yield* wrapWith( prop.loc.start.offset, prop.loc.start.offset + rawName.length, - ctx.codeFeatures.verification, + codeFeatures.verification, `__VLS_directives.`, ...generateCamelized( rawName, 'template', prop.loc.start.offset, - ctx.resolveCodeFeatures({ + { ...codeFeatures.withoutHighlightAndCompletion, verification: options.vueCompilerOptions.checkUnknownDirectives && !builtInDirectives.has(prop.name), - }), + }, ), ); } @@ -92,7 +91,7 @@ function* generateArg( yield* wrapWith( startOffset, startOffset + arg.content.length, - ctx.codeFeatures.verification, + codeFeatures.verification, `arg`, ); yield `: `; @@ -100,7 +99,7 @@ function* generateArg( yield* generateStringLiteralKey( arg.content, startOffset, - ctx.codeFeatures.all, + codeFeatures.all, ); } else { @@ -108,7 +107,7 @@ function* generateArg( options, ctx, 'template', - ctx.codeFeatures.all, + codeFeatures.all, arg.content, startOffset, `(`, @@ -135,7 +134,7 @@ export function* generateModifiers( yield* wrapWith( startOffset, endOffset, - ctx.codeFeatures.verification, + codeFeatures.verification, propertyName, ); yield `: { `; @@ -145,7 +144,7 @@ export function* generateModifiers( ctx, mod.content, mod.loc.start.offset, - ctx.codeFeatures.withoutHighlightAndNavigation, + codeFeatures.withoutHighlightAndNavigation, ); yield `: true, `; } @@ -165,7 +164,7 @@ function* generateValue( yield* wrapWith( exp.loc.start.offset, exp.loc.end.offset, - ctx.codeFeatures.verification, + codeFeatures.verification, `value`, ); yield `: `; diff --git a/packages/language-core/lib/codegen/template/elementEvents.ts b/packages/language-core/lib/codegen/template/elementEvents.ts index 132fbe65a7..b38f1334c5 100644 --- a/packages/language-core/lib/codegen/template/elementEvents.ts +++ b/packages/language-core/lib/codegen/template/elementEvents.ts @@ -62,12 +62,12 @@ export function* generateElementEvents( yield `const ${ctx.getInternalVariable()}: __VLS_NormalizeComponentEvent = (${newLine}`; if (prop.name === 'on') { yield `{ `; - yield* generateEventArg(options, ctx, source, start!, emitPrefix.slice(0, -1), ctx.codeFeatures.navigation); + yield* generateEventArg(options, source, start!, emitPrefix.slice(0, -1), codeFeatures.navigation); yield `: {} as any } as typeof ${emitsVar},${newLine}`; } yield `{ `; if (prop.name === 'on') { - yield* generateEventArg(options, ctx, source, start!, propPrefix.slice(0, -1)); + yield* generateEventArg(options, source, start!, propPrefix.slice(0, -1)); yield `: `; yield* generateEventExpression(options, ctx, prop); } @@ -82,19 +82,18 @@ export function* generateElementEvents( export function* generateEventArg( options: TemplateCodegenOptions, - ctx: TemplateCodegenContext, name: string, start: number, directive = 'on', features?: VueCodeInformation, ): Generator { - features ??= ctx.resolveCodeFeatures({ + features ??= { ...codeFeatures.semanticWithoutHighlight, ...codeFeatures.navigationWithoutRename, ...options.vueCompilerOptions.checkUnknownEvents ? codeFeatures.verification : codeFeatures.doNotReportTs2353AndTs2561, - }); + }; if (directive.length) { name = capitalize(name); @@ -159,7 +158,7 @@ export function* generateEventExpression( ].join('\n\n'), }); } - return ctx.codeFeatures.all; + return codeFeatures.all; }, prop.exp.content, prop.exp.loc.start.offset, @@ -192,7 +191,7 @@ export function* generateModelEventExpression( options, ctx, 'template', - ctx.codeFeatures.verification, + codeFeatures.verification, prop.exp.content, prop.exp.loc.start.offset, ); diff --git a/packages/language-core/lib/codegen/template/elementProps.ts b/packages/language-core/lib/codegen/template/elementProps.ts index 57dc63eb40..4aa75ecbe8 100644 --- a/packages/language-core/lib/codegen/template/elementProps.ts +++ b/packages/language-core/lib/codegen/template/elementProps.ts @@ -46,7 +46,7 @@ export function* generateElementProps( ) { if (!isComponent) { yield `...{ `; - yield* generateEventArg(options, ctx, prop.arg.loc.source, prop.arg.loc.start.offset); + yield* generateEventArg(options, prop.arg.loc.source, prop.arg.loc.start.offset); yield `: `; yield* generateEventExpression(options, ctx, prop); yield `},`; @@ -113,7 +113,7 @@ export function* generateElementProps( const shouldSpread = propName === 'style' || propName === 'class'; const shouldCamelize = isComponent && getShouldCamelize(options, prop, propName); - const codeInfo = getPropsCodeInfo(ctx, strictPropsCheck); + const features = getPropsCodeFeatures(strictPropsCheck); if (shouldSpread) { yield `...{ `; @@ -121,7 +121,7 @@ export function* generateElementProps( const codes = [...wrapWith( prop.loc.start.offset, prop.loc.end.offset, - ctx.codeFeatures.verification, + codeFeatures.verification, ...( prop.arg ? generateObjectProperty( @@ -129,13 +129,13 @@ export function* generateElementProps( ctx, propName, prop.arg.loc.start.offset, - codeInfo, + features, shouldCamelize, ) : wrapWith( prop.loc.start.offset, prop.loc.start.offset + 'v-model'.length, - ctx.codeFeatures.withoutHighlightAndCompletion, + codeFeatures.withoutHighlightAndCompletion, propName, ) ), @@ -143,7 +143,7 @@ export function* generateElementProps( ...wrapWith( prop.arg?.loc.start.offset ?? prop.loc.start.offset, prop.arg?.loc.end.offset ?? prop.loc.end.offset, - ctx.codeFeatures.verification, + codeFeatures.verification, ...generatePropExp( options, ctx, @@ -200,7 +200,7 @@ export function* generateElementProps( const shouldSpread = prop.name === 'style' || prop.name === 'class'; const shouldCamelize = isComponent && getShouldCamelize(options, prop, prop.name); - const codeInfo = getPropsCodeInfo(ctx, strictPropsCheck); + const features = getPropsCodeFeatures(strictPropsCheck); if (shouldSpread) { yield `...{ `; @@ -208,19 +208,19 @@ export function* generateElementProps( const codes = [...wrapWith( prop.loc.start.offset, prop.loc.end.offset, - ctx.codeFeatures.verification, + codeFeatures.verification, ...generateObjectProperty( options, ctx, prop.name, prop.loc.start.offset, - codeInfo, + features, shouldCamelize, ), `: `, ...( prop.value - ? generateAttrValue(prop.value, ctx.codeFeatures.withoutNavigation) + ? generateAttrValue(prop.value, codeFeatures.withoutNavigation) : [`true`] ), )]; @@ -250,7 +250,7 @@ export function* generateElementProps( const codes = [...wrapWith( prop.exp.loc.start.offset, prop.exp.loc.end.offset, - ctx.codeFeatures.verification, + codeFeatures.verification, `...`, ...generatePropExp( options, @@ -281,8 +281,8 @@ export function* generatePropExp( ): Generator { const isShorthand = prop.arg?.loc.start.offset === prop.exp?.loc.start.offset; const features = isShorthand - ? ctx.codeFeatures.withoutHighlightAndCompletion - : ctx.codeFeatures.all; + ? codeFeatures.withoutHighlightAndCompletion + : codeFeatures.all; if (exp && exp.constType !== CompilerDOM.ConstantTypes.CAN_STRINGIFY) { // style='z-index: 2' will compile to {'z-index':'2'} if (!isShorthand) { // vue 3.4+ @@ -372,16 +372,15 @@ function getShouldCamelize( && !options.vueCompilerOptions.htmlAttributes.some(pattern => isMatch(propName, pattern)); } -function getPropsCodeInfo( - ctx: TemplateCodegenContext, +function getPropsCodeFeatures( strictPropsCheck: boolean, ): VueCodeInformation { - return ctx.resolveCodeFeatures({ + return { ...codeFeatures.withoutHighlightAndCompletion, ...strictPropsCheck ? codeFeatures.verification : codeFeatures.doNotReportTs2353AndTs2561, - }); + }; } function getModelPropName(node: CompilerDOM.ElementNode, vueCompilerOptions: VueCompilerOptions) { diff --git a/packages/language-core/lib/codegen/template/index.ts b/packages/language-core/lib/codegen/template/index.ts index c545c258e5..ace26767bb 100644 --- a/packages/language-core/lib/codegen/template/index.ts +++ b/packages/language-core/lib/codegen/template/index.ts @@ -2,9 +2,10 @@ import * as CompilerDOM from '@vue/compiler-dom'; import type * as ts from 'typescript'; import type { Code, Sfc, VueCompilerOptions } from '../../types'; import { getSlotsPropertyName } from '../../utils/shared'; +import { codeFeatures } from '../codeFeatures'; import { endOfLine, newLine } from '../utils'; import { wrapWith } from '../utils/wrapWith'; -import { createTemplateCodegenContext, type TemplateCodegenContext } from './context'; +import type { TemplateCodegenContext } from './context'; import { generateObjectProperty } from './objectProperty'; import { generateStyleScopedClassReferences } from './styleScopedClasses'; import { generateTemplateChild, getVForNode } from './templateChild'; @@ -25,9 +26,10 @@ export interface TemplateCodegenOptions { selfComponentName?: string; } -export function* generateTemplate(options: TemplateCodegenOptions): Generator { - const ctx = createTemplateCodegenContext(options, options.template.ast); - +export function* generateTemplate( + options: TemplateCodegenOptions, + ctx: TemplateCodegenContext, +): Generator { if (options.slotsAssignName) { ctx.addLocalVariable(options.slotsAssignName); } @@ -68,8 +70,6 @@ export function* generateTemplate(options: TemplateCodegenOptions): Generator {}`); slotBlockVars.push(...collectBindingNames(options.ts, slotAst, slotAst)); - yield* generateSlotParameters(options, ctx, slotAst, slotDir.exp, slotVar); + yield* generateSlotParameters(options, slotAst, slotDir.exp, slotVar); } for (const varName of slotBlockVars) { @@ -96,7 +97,7 @@ export function* generateVSlot( ? 'v-slot:'.length : 0 ), - ctx.codeFeatures.completion, + codeFeatures.completion, ]; yield `'/* empty slot name completion */]${endOfLine}`; } @@ -106,7 +107,6 @@ export function* generateVSlot( function* generateSlotParameters( options: TemplateCodegenOptions, - ctx: TemplateCodegenContext, ast: ts.SourceFile, exp: CompilerDOM.SimpleExpressionNode, slotVar: string, @@ -152,7 +152,7 @@ function* generateSlotParameters( yield* wrapWith( exp.loc.start.offset, exp.loc.end.offset, - ctx.codeFeatures.verification, + codeFeatures.verification, `(`, ...types.flatMap(type => type ? [`_: `, type, `, `] : `_, `), `) => [] as any`, @@ -165,7 +165,7 @@ function* generateSlotParameters( ast.text.slice(start, end), 'template', startOffset + start, - ctx.codeFeatures.all, + codeFeatures.all, ]; } } diff --git a/packages/language-core/lib/plugins/vue-tsx.ts b/packages/language-core/lib/plugins/vue-tsx.ts index 8f8315ebc1..1f4d8d7214 100644 --- a/packages/language-core/lib/plugins/vue-tsx.ts +++ b/packages/language-core/lib/plugins/vue-tsx.ts @@ -1,8 +1,10 @@ import { camelize, capitalize } from '@vue/shared'; import { computed } from 'alien-signals'; import * as path from 'path-browserify'; -import { generateScript } from '../codegen/script'; -import { generateTemplate } from '../codegen/template'; +import { generateScript, type ScriptCodegenOptions } from '../codegen/script'; +import { createScriptCodegenContext } from '../codegen/script/context'; +import { generateTemplate, type TemplateCodegenOptions } from '../codegen/template'; +import { createTemplateCodegenContext } from '../codegen/template/context'; import { parseScriptRanges } from '../parsers/scriptRanges'; import { parseScriptSetupRanges } from '../parsers/scriptSetupRanges'; import { parseVueCompilerOptions } from '../parsers/vueCompilerOptions'; @@ -179,8 +181,7 @@ function createTsx( return; } - const codes: Code[] = []; - const codegen = generateTemplate({ + const options: TemplateCodegenOptions = { ts, compilerOptions: ctx.compilerOptions, vueCompilerOptions: getResolvedOptions(), @@ -194,24 +195,26 @@ function createTsx( propsAssignName: getSetupPropsAssignName(), inheritAttrs: getSetupInheritAttrs(), selfComponentName: getComponentSelfName(), - }); + }; + const context = createTemplateCodegenContext(options, sfc.template.ast); + const codegen = generateTemplate(options, context); - let current = codegen.next(); - while (!current.done) { - const code = current.value; + const codes: Code[] = []; + for (const code of codegen) { + if (typeof code === 'object') { + code[3] = context.resolveCodeFeatures(code[3]); + } codes.push(code); - current = codegen.next(); } return { - ...current.value, + ...context, codes, }; }); const getGeneratedScript = computed(() => { - const codes: Code[] = []; - const codegen = generateScript({ + const options: ScriptCodegenOptions = { ts, compilerOptions: ctx.compilerOptions, vueCompilerOptions: getResolvedOptions(), @@ -223,18 +226,13 @@ function createTsx( templateCodegen: getGeneratedTemplate(), destructuredPropNames: getSetupDestructuredPropNames(), templateRefNames: getSetupTemplateRefNames(), - }); - - let current = codegen.next(); - while (!current.done) { - const code = current.value; - codes.push(code); - current = codegen.next(); - } + }; + const context = createScriptCodegenContext(options); + const codegen = generateScript(options, context); return { - ...current.value, - codes, + ...context, + codes: [...codegen], }; }); From 0ceba6ec40aee6581f6c828513d388d5970ebf0b Mon Sep 17 00:00:00 2001 From: KazariEX Date: Mon, 28 Jul 2025 02:43:59 +0800 Subject: [PATCH 17/25] fix(language-core): enable navigation code feature on directive modifiers --- packages/language-core/lib/codegen/codeFeatures.ts | 5 ----- .../language-core/lib/codegen/template/elementDirectives.ts | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/language-core/lib/codegen/codeFeatures.ts b/packages/language-core/lib/codegen/codeFeatures.ts index 72d4f896ad..2d576b926e 100644 --- a/packages/language-core/lib/codegen/codeFeatures.ts +++ b/packages/language-core/lib/codegen/codeFeatures.ts @@ -52,11 +52,6 @@ const raw = { navigation: true, completion: true, }, - withoutHighlightAndNavigation: { - semantic: { shouldHighlight: () => false }, - verification: true, - completion: true, - }, withoutHighlightAndCompletion: { semantic: { shouldHighlight: () => false }, verification: true, diff --git a/packages/language-core/lib/codegen/template/elementDirectives.ts b/packages/language-core/lib/codegen/template/elementDirectives.ts index 9deaa1491e..2dce0a93e6 100644 --- a/packages/language-core/lib/codegen/template/elementDirectives.ts +++ b/packages/language-core/lib/codegen/template/elementDirectives.ts @@ -144,7 +144,7 @@ export function* generateModifiers( ctx, mod.content, mod.loc.start.offset, - codeFeatures.withoutHighlightAndNavigation, + codeFeatures.withoutHighlight, ); yield `: true, `; } From 053aa3c4302904bd2c2bfe02a9b79edc58e65547 Mon Sep 17 00:00:00 2001 From: KazariEX Date: Mon, 28 Jul 2025 03:07:00 +0800 Subject: [PATCH 18/25] refactor(language-core): re-export `createTemplateCodegenContext` --- packages/language-core/lib/codegen/script/context.ts | 7 ------- packages/language-core/lib/codegen/script/index.ts | 6 ++++-- packages/language-core/lib/codegen/template/index.ts | 2 ++ packages/language-core/lib/plugins/vue-tsx.ts | 6 ++---- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/packages/language-core/lib/codegen/script/context.ts b/packages/language-core/lib/codegen/script/context.ts index 51a1375e6d..844f8b44e9 100644 --- a/packages/language-core/lib/codegen/script/context.ts +++ b/packages/language-core/lib/codegen/script/context.ts @@ -2,13 +2,6 @@ import type { InlayHintInfo } from '../inlayHints'; import { getLocalTypesGenerator } from '../localTypes'; import type { ScriptCodegenOptions } from './index'; -export interface HelperType { - name: string; - used?: boolean; - generated?: boolean; - code: string; -} - export type ScriptCodegenContext = ReturnType; export function createScriptCodegenContext(options: ScriptCodegenOptions) { diff --git a/packages/language-core/lib/codegen/script/index.ts b/packages/language-core/lib/codegen/script/index.ts index c1c374c543..69cf33c303 100644 --- a/packages/language-core/lib/codegen/script/index.ts +++ b/packages/language-core/lib/codegen/script/index.ts @@ -7,11 +7,13 @@ import { codeFeatures } from '../codeFeatures'; import type { TemplateCodegenContext } from '../template/context'; import { endOfLine, generateSfcBlockSection, newLine } from '../utils'; import { generateComponentSelf } from './componentSelf'; -import { createScriptCodegenContext, type ScriptCodegenContext } from './context'; +import { type ScriptCodegenContext } from './context'; import { generateScriptSetup, generateScriptSetupImports } from './scriptSetup'; import { generateSrc } from './src'; import { generateTemplate } from './template'; +export * from './context'; + export interface ScriptCodegenOptions { ts: typeof ts; compilerOptions: ts.CompilerOptions; @@ -28,7 +30,7 @@ export interface ScriptCodegenOptions { export function* generateScript( options: ScriptCodegenOptions, - ctx: ScriptCodegenContext = createScriptCodegenContext(options), + ctx: ScriptCodegenContext, ): Generator { yield* generateGlobalTypesPath(options); diff --git a/packages/language-core/lib/codegen/template/index.ts b/packages/language-core/lib/codegen/template/index.ts index ace26767bb..e21ae2f952 100644 --- a/packages/language-core/lib/codegen/template/index.ts +++ b/packages/language-core/lib/codegen/template/index.ts @@ -10,6 +10,8 @@ import { generateObjectProperty } from './objectProperty'; import { generateStyleScopedClassReferences } from './styleScopedClasses'; import { generateTemplateChild, getVForNode } from './templateChild'; +export * from './context'; + export interface TemplateCodegenOptions { ts: typeof ts; compilerOptions: ts.CompilerOptions; diff --git a/packages/language-core/lib/plugins/vue-tsx.ts b/packages/language-core/lib/plugins/vue-tsx.ts index 1f4d8d7214..eaad1aca98 100644 --- a/packages/language-core/lib/plugins/vue-tsx.ts +++ b/packages/language-core/lib/plugins/vue-tsx.ts @@ -1,10 +1,8 @@ import { camelize, capitalize } from '@vue/shared'; import { computed } from 'alien-signals'; import * as path from 'path-browserify'; -import { generateScript, type ScriptCodegenOptions } from '../codegen/script'; -import { createScriptCodegenContext } from '../codegen/script/context'; -import { generateTemplate, type TemplateCodegenOptions } from '../codegen/template'; -import { createTemplateCodegenContext } from '../codegen/template/context'; +import { createScriptCodegenContext, generateScript, type ScriptCodegenOptions } from '../codegen/script'; +import { createTemplateCodegenContext, generateTemplate, type TemplateCodegenOptions } from '../codegen/template'; import { parseScriptRanges } from '../parsers/scriptRanges'; import { parseScriptSetupRanges } from '../parsers/scriptSetupRanges'; import { parseVueCompilerOptions } from '../parsers/vueCompilerOptions'; From 5a79d397f3ba76aaa079f38fcbf2a4eb458422d4 Mon Sep 17 00:00:00 2001 From: KazariEX Date: Mon, 28 Jul 2025 20:21:17 +0800 Subject: [PATCH 19/25] chore: split changelogs --- CHANGELOG.md | 4826 +----------------------------------- changelogs/CHANGELOG-v0.md | 2616 +++++++++++++++++++ changelogs/CHANGELOG-v1.md | 1154 +++++++++ changelogs/CHANGELOG-v2.md | 1053 ++++++++ 4 files changed, 4830 insertions(+), 4819 deletions(-) create mode 100644 changelogs/CHANGELOG-v0.md create mode 100644 changelogs/CHANGELOG-v1.md create mode 100644 changelogs/CHANGELOG-v2.md diff --git a/CHANGELOG.md b/CHANGELOG.md index bddba05d3e..27c46883d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -162,4828 +162,16 @@ - refactor(vscode): remove split editor feature (#5446) - refactor(vscode): rename configuration keys from `complete` to `suggest` for clarity -## 2.2.10 official (2025-04-22) +## Previous Changelogs -## Bug Fixes +### 2.x.x (2024/3/2 - 2025-04-22) -- fix(language-core): generate condition guards for model events (#5225) - Thanks to @KazariEX! -- fix(language-core): prevent global types generation in declaration files (#5239) - Thanks to @KazariEX! -- fix(language-core): prevent eager inference of slot props from generics (#5247) - Thanks to @KazariEX! -- fix(typescript-plugin): prevent highlighting native element tags with same name as components (#5253) - Thanks to @KazariEX! - -## 2.2.8 official, 2.2.9 insiders (2025-03-02) - -### Bug Fixes - -- revert "fix(language-core): validate `v-model` variable against model type" - -## 2.2.6 official, 2.2.7 insiders (2025-03-01) - -### Features - -- feat(language-core): infer prop JSDoc from `defineModel`'s leading comments (#5211) - Thanks to @KazariEX! - -### Bug Fixes - -- fix(language-core): map camelized prop name correctly (#5207) - Thanks to @KazariEX! -- fix(component-meta): resolve `defineModel` options to collect `default` value (#5209) - Thanks to @KazariEX! -- fix(language-core): avoid duplicate generation of `defineExpose`'s codes - Thanks to @KazariEX! -- fix(language-core): generate camelized prop name for `defineModel` (#5213) - Thanks to @KazariEX! -- fix(language-core): validate `v-model` variable against model type (#5214) - Thanks to @KazariEX! -- fix(language-core): use keywords instead of semicolons to separate script sections (#5217) - Thanks to @KazariEX! - -### Other Changes - -- ci: auto close issues with `can't reproduce` label - Thanks to @KazariEX! -- refactor(language-core): defer the calculation of `linkedCodeMappings` offsets (#5220) - Thanks to @KazariEX! - -## 2.2.4 official, 2.2.5 insiders (2025-02-22) - -### Features - -- feat(language-service): map sfc compiler errors outside the template inner content (#5045) - Thanks to @KazariEX! -- feat(language-core): introduce options to control type inference of `$attrs`, `$el`, `$refs` and `$slots` (#5135) - Thanks to @KazariEX! -- feat(language-core): enhance single root nodes collection (#4819) - Thanks to @KazariEX! - -### Bug Fixes - -- fix(language-core): move `generateSfcBlockSection` to the end to fix missing comma errors (#5184) - Thanks to @zhiyuanzmj! -- fix(language-core): handle edge case of default slot name mismatch - Thanks to @KazariEX! -- fix(language-core): combine dollar variable keys from the upper level interface - Thanks to @KazariEX! -- fix(language-core): hoist the variables that may cause `TS4081` (#5192) - Thanks to @KazariEX! -- fix(language-core): adjust regex match for `@vue-generic` to improve offset calculation (#5193) - Thanks to @Gehbt! -- fix(language-core): correct codegen of native element refs - Thanks to @KazariEX! -- fix(language-core): ignore latex block content (#5151) - Thanks to @KazariEX! -- fix(language-core): do not emit `undefined` for model with default value (#5198) - Thanks to @RylanBueckert-Broadsign! -- fix(language-service): typescript-semantic renaming first in style blocks (#4685) - Thanks to @KazariEX! -- fix(typescript-plugin): prevent removed components from appearing in the completion list - Thanks to @KazariEX! - -### Other Changes - -- refactor(language-core): drop invalid `v-scope` implemention - Thanks to @KazariEX! -- refactor(language-core): improve type declaration of `v-for` - Thanks to @KazariEX! -- test: enable `declaration` to track more errors - Thanks to @KazariEX! -- refactor(language-core): remove semantic highlight of style module names - Thanks to @KazariEX! -- chore(language-core): add docs for `@vue-expect-error` support (#5176) - Thanks to @machty! -- ci: upload extension as artifact for each commit - Thanks to @KazariEX! - -## 2.2.2 official, 2.2.3 insiders (2025-02-15) - -### Features - -- feat(language-core): navigation support for `$attrs`, `$slots`, `$refs` and `$el` in the template (#5056) - Thanks to @KazariEX! -- feat(language-service): support global directives completion (#4989) - Thanks to @KazariEX! -- feat(language-core): type support of `useAttrs` (#5106) - Thanks to @KazariEX! -- feat(language-core): add options for fine-grained configuration of `strictTemplates` (#5138) -- feat(language-service): display deprecated info of props in completion (#5134) - Thanks to @KazariEX! -- feat(component-meta): collect destructured props defaults (#5101) - Thanks to @Akryum! -- feat(language-core): add `checkUnknownDirectives` option (#5141) - Thanks to @KazariEX! -- feat(language-core): support `