From fb9edd28f27b0918e9ab0ad4ca169be81529fda2 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: Thu, 6 Mar 2025 01:55:32 +0800 Subject: [PATCH] refactor(language-core, typescript-plugin): use inline `__VLS_elements` to simplify code (#5255) --- .../language-core/lib/codegen/globalTypes.ts | 1 - .../language-core/lib/codegen/script/index.ts | 1 - .../lib/codegen/script/template.ts | 5 ++ .../lib/codegen/template/element.ts | 6 +-- packages/typescript-plugin/lib/common.ts | 3 +- .../lib/requests/getComponentNames.ts | 12 +++++ .../lib/requests/getElementAttrs.ts | 52 +++++-------------- 7 files changed, 34 insertions(+), 46 deletions(-) diff --git a/packages/language-core/lib/codegen/globalTypes.ts b/packages/language-core/lib/codegen/globalTypes.ts index f61ca33258..b68942a112 100644 --- a/packages/language-core/lib/codegen/globalTypes.ts +++ b/packages/language-core/lib/codegen/globalTypes.ts @@ -35,7 +35,6 @@ export function generateGlobalTypes({ } text += ` ; declare global { - const __VLS_intrinsicElements: __VLS_IntrinsicElements; const __VLS_directiveBindingRestFields: { instance: null, oldValue: null, modifiers: any, dir: any }; const __VLS_unref: typeof import('${lib}').unref; const __VLS_placeholder: any; diff --git a/packages/language-core/lib/codegen/script/index.ts b/packages/language-core/lib/codegen/script/index.ts index 74e44db4cf..c94bbdea5f 100644 --- a/packages/language-core/lib/codegen/script/index.ts +++ b/packages/language-core/lib/codegen/script/index.ts @@ -127,7 +127,6 @@ export function* generateScript(options: ScriptCodegenOptions): Generator { } } +function* generateTemplateElements(): Generator { + yield `let __VLS_elements!: __VLS_IntrinsicElements${endOfLine}`; +} + function* generateTemplateComponents(options: ScriptCodegenOptions): Generator { const types: Code[] = []; diff --git a/packages/language-core/lib/codegen/template/element.ts b/packages/language-core/lib/codegen/template/element.ts index 9b72c7a956..792a7b2463 100644 --- a/packages/language-core/lib/codegen/template/element.ts +++ b/packages/language-core/lib/codegen/template/element.ts @@ -320,7 +320,7 @@ export function* generateElement( : undefined; const failedPropExps: FailedPropExpression[] = []; - yield `__VLS_asFunctionalElement(__VLS_intrinsicElements`; + yield `__VLS_asFunctionalElement(__VLS_elements`; yield* generatePropertyAccess( options, ctx, @@ -329,7 +329,7 @@ export function* generateElement( ctx.codeFeatures.withoutHighlightAndCompletion ); if (endTagOffset !== undefined) { - yield `, __VLS_intrinsicElements`; + yield `, __VLS_elements`; yield* generatePropertyAccess( options, ctx, @@ -376,7 +376,7 @@ export function* generateElement( } if (hasVBindAttrs(options, ctx, node)) { - ctx.inheritedAttrVars.add(`__VLS_intrinsicElements.${node.tag}`); + ctx.inheritedAttrVars.add(`__VLS_elements.${node.tag}`); } collectStyleScopedClassReferences(options, ctx, node); diff --git a/packages/typescript-plugin/lib/common.ts b/packages/typescript-plugin/lib/common.ts index 50765d9aa7..85c2cf008e 100644 --- a/packages/typescript-plugin/lib/common.ts +++ b/packages/typescript-plugin/lib/common.ts @@ -1,8 +1,7 @@ import { forEachElementNode, hyphenateTag, Language, VueCompilerOptions, VueVirtualCode } from '@vue/language-core'; import { capitalize } from '@vue/shared'; import type * as ts from 'typescript'; -import { _getComponentNames } from './requests/getComponentNames'; -import { _getElementNames } from './requests/getElementAttrs'; +import { _getComponentNames, _getElementNames } from './requests/getComponentNames'; import type { RequestContext } from './requests/types'; const windowsPathReg = /\\/g; diff --git a/packages/typescript-plugin/lib/requests/getComponentNames.ts b/packages/typescript-plugin/lib/requests/getComponentNames.ts index 8cc1040c17..39f2951193 100644 --- a/packages/typescript-plugin/lib/requests/getComponentNames.ts +++ b/packages/typescript-plugin/lib/requests/getComponentNames.ts @@ -31,3 +31,15 @@ export function _getComponentNames( names.push(getSelfComponentName(vueCode.fileName)); return names; } + +export function _getElementNames( + ts: typeof import('typescript'), + tsLs: ts.LanguageService, + vueCode: VueVirtualCode +) { + return getVariableType(ts, tsLs, vueCode, '__VLS_elements') + ?.type + ?.getProperties() + .map(c => c.name) + ?? []; +} diff --git a/packages/typescript-plugin/lib/requests/getElementAttrs.ts b/packages/typescript-plugin/lib/requests/getElementAttrs.ts index cbf6b391fd..c1341967b7 100644 --- a/packages/typescript-plugin/lib/requests/getElementAttrs.ts +++ b/packages/typescript-plugin/lib/requests/getElementAttrs.ts @@ -1,6 +1,6 @@ import { VueVirtualCode } from '@vue/language-core'; -import type * as ts from 'typescript'; import type { RequestContext } from './types'; +import { getVariableType } from './utils'; export function getElementAttrs( this: RequestContext, @@ -12,46 +12,20 @@ export function getElementAttrs( if (!(volarFile?.generated?.root instanceof VueVirtualCode)) { return; } - const program = languageService.getProgram()!; - - const tsSourceFile = program.getSourceFile(fileName); - if (tsSourceFile) { - const checker = program.getTypeChecker(); - const typeNode = tsSourceFile.statements - .filter(ts.isTypeAliasDeclaration) - .find(node => node.name.getText() === '__VLS_IntrinsicElementsCompletion'); - - if (typeNode) { - const type = checker.getTypeFromTypeNode(typeNode.type); - const el = type.getProperty(tagName); + const vueCode = volarFile.generated.root; - if (el) { - const attrs = checker.getTypeOfSymbolAtLocation(el, typeNode).getProperties(); - return attrs.map(c => c.name); - } - } + const program = languageService.getProgram()!; + const checker = program.getTypeChecker(); + const elements = getVariableType(ts, languageService, vueCode, '__VLS_elements'); + if (!elements) { + return []; } - return []; -} -export function _getElementNames( - ts: typeof import('typescript'), - tsLs: ts.LanguageService, - vueCode: VueVirtualCode -) { - const program = tsLs.getProgram()!; - - const tsSourceFile = program.getSourceFile(vueCode.fileName); - if (tsSourceFile) { - const checker = program.getTypeChecker(); - const typeNode = tsSourceFile.statements - .filter(ts.isTypeAliasDeclaration) - .find(node => node.name.getText() === '__VLS_IntrinsicElementsCompletion'); - - if (typeNode) { - const type = checker.getTypeFromTypeNode(typeNode.type); - return type.getProperties().map(c => c.name); - } + const elementType = elements.type.getProperty(tagName); + if (!elementType) { + return []; } - return []; + + const attrs = checker.getTypeOfSymbol(elementType).getProperties(); + return attrs.map(c => c.name); }