From 946598c0df24558a4a9025b90057b688cc63e6d6 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Mon, 22 Apr 2024 09:16:44 +0900 Subject: [PATCH] fix(language-core): reduce unnecessary props mapping (#4284) --- .../lib/codegen/template/element.ts | 8 +-- .../lib/codegen/template/elementProps.ts | 58 +++++++++++-------- .../lib/codegen/template/slotOutlet.ts | 4 +- 3 files changed, 41 insertions(+), 29 deletions(-) diff --git a/packages/language-core/lib/codegen/template/element.ts b/packages/language-core/lib/codegen/template/element.ts index 2e31674beb..50c4087619 100644 --- a/packages/language-core/lib/codegen/template/element.ts +++ b/packages/language-core/lib/codegen/template/element.ts @@ -118,7 +118,7 @@ export function* generateElement( } else { yield `const ${var_functionalComponent} = __VLS_asFunctionalComponent(${var_originalComponent}, new ${var_originalComponent}({`; - yield* generateElementProps(options, ctx, node, props, 'navigationOnly'); + yield* generateElementProps(options, ctx, node, props, false); yield `}))${endOfLine}`; } @@ -146,7 +146,7 @@ export function* generateElement( startTagOffset + tag.length, ctx.codeFeatures.verification, `{`, - ...generateElementProps(options, ctx, node, props, 'normal', propsFailedExps), + ...generateElementProps(options, ctx, node, props, true, propsFailedExps), `}`, ); yield `, ...__VLS_functionalComponentArgsRest(${var_functionalComponent}))${endOfLine}`; @@ -154,7 +154,7 @@ export function* generateElement( else { // without strictTemplates, this only for instacne type yield `const ${var_componentInstance} = ${var_functionalComponent}({`; - yield* generateElementProps(options, ctx, node, props, 'navigationOnly'); + yield* generateElementProps(options, ctx, node, props, false); yield `}, ...__VLS_functionalComponentArgsRest(${var_functionalComponent}))${endOfLine}`; // and this for props type-checking yield `({} as (props: __VLS_FunctionalComponentProps & Record) => void)(`; @@ -163,7 +163,7 @@ export function* generateElement( startTagOffset + tag.length, ctx.codeFeatures.verification, `{`, - ...generateElementProps(options, ctx, node, props, 'normal', propsFailedExps), + ...generateElementProps(options, ctx, node, props, true, propsFailedExps), `}`, ); yield `)${endOfLine}`; diff --git a/packages/language-core/lib/codegen/template/elementProps.ts b/packages/language-core/lib/codegen/template/elementProps.ts index c5e9f4472a..bc89699972 100644 --- a/packages/language-core/lib/codegen/template/elementProps.ts +++ b/packages/language-core/lib/codegen/template/elementProps.ts @@ -9,20 +9,19 @@ import type { TemplateCodegenContext } from './context'; import type { TemplateCodegenOptions } from './index'; import { generateInterpolation } from './interpolation'; import { generateObjectProperty } from './objectProperty'; +import { toString } from '@volar/language-core'; export function* generateElementProps( options: TemplateCodegenOptions, ctx: TemplateCodegenContext, node: CompilerDOM.ElementNode, props: CompilerDOM.ElementNode['props'], - mode: 'normal' | 'navigationOnly', + enableCodeFeatures: boolean, propsFailedExps?: CompilerDOM.SimpleExpressionNode[], ): Generator { let styleAttrNum = 0; let classAttrNum = 0; - let defaultCodeFeatures: VueCodeInformation = ctx.codeFeatures.all; - let attrCodeFeatures: VueCodeInformation = ctx.codeFeatures.withoutHighlightAndCompletion; const canCamelize = node.tagType === CompilerDOM.ElementTypes.COMPONENT; @@ -37,11 +36,6 @@ export function* generateElementProps( classAttrNum++; } - if (mode === 'navigationOnly') { - defaultCodeFeatures = ctx.codeFeatures.navigation; - attrCodeFeatures = ctx.codeFeatures.navigation; - } - yield `...{ `; for (const prop of props) { if ( @@ -90,7 +84,7 @@ export function* generateElementProps( && hyphenateAttr(propName) === propName && !options.vueCompilerOptions.htmlAttributes.some(pattern => minimatch(propName!, pattern)); - yield* wrapWith( + const codes = wrapWith( prop.loc.start.offset, prop.loc.end.offset, ctx.codeFeatures.verification, @@ -103,15 +97,15 @@ export function* generateElementProps( : prop.loc.start.offset, prop.arg ? { - ...attrCodeFeatures, - navigation: attrCodeFeatures.navigation + ...ctx.codeFeatures.withoutHighlightAndCompletion, + navigation: ctx.codeFeatures.withoutHighlightAndCompletion.navigation ? { resolveRenameNewName: camelize, resolveRenameEditText: shouldCamelize ? hyphenateAttr : undefined, } : false, } - : attrCodeFeatures, + : ctx.codeFeatures.withoutHighlightAndCompletion, (prop.loc as any).name_2 ?? ((prop.loc as any).name_2 = {}), shouldCamelize, ), @@ -120,12 +114,18 @@ export function* generateElementProps( options, ctx, prop.exp, - attrCodeFeatures, + ctx.codeFeatures.withoutHighlightAndCompletion, prop.arg?.loc.start.offset === prop.exp?.loc.start.offset, - mode === 'normal', + enableCodeFeatures, ), `)`, ); + if (!enableCodeFeatures) { + yield toString([...codes]); + } + else { + yield* codes; + } yield `, `; } else if (prop.type === CompilerDOM.NodeTypes.ATTRIBUTE) { @@ -151,8 +151,8 @@ export function* generateElementProps( && hyphenateAttr(prop.name) === prop.name && !options.vueCompilerOptions.htmlAttributes.some(pattern => minimatch(prop.name, pattern)); - yield* conditionWrapWith( - mode === 'normal', + const codes = conditionWrapWith( + enableCodeFeatures, prop.loc.start.offset, prop.loc.end.offset, ctx.codeFeatures.verification, @@ -163,26 +163,32 @@ export function* generateElementProps( prop.loc.start.offset, shouldCamelize ? { - ...attrCodeFeatures, - navigation: attrCodeFeatures.navigation + ...ctx.codeFeatures.withoutHighlightAndCompletion, + navigation: ctx.codeFeatures.withoutHighlightAndCompletion.navigation ? { resolveRenameNewName: camelize, resolveRenameEditText: hyphenateAttr, } : false, } - : attrCodeFeatures, + : ctx.codeFeatures.withoutHighlightAndCompletion, (prop.loc as any).name_1 ?? ((prop.loc as any).name_1 = {}), shouldCamelize, ), `: (`, ...( prop.value - ? generateAttrValue(prop.value, defaultCodeFeatures) + ? generateAttrValue(prop.value, ctx.codeFeatures.all) : [`true`] ), `)`, ); + if (!enableCodeFeatures) { + yield toString([...codes]); + } + else { + yield* codes; + } yield `, `; } else if ( @@ -191,8 +197,8 @@ export function* generateElementProps( && !prop.arg && prop.exp?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION ) { - yield* conditionWrapWith( - mode === 'normal', + const codes = conditionWrapWith( + enableCodeFeatures, prop.exp.loc.start.offset, prop.exp.loc.end.offset, ctx.codeFeatures.verification, @@ -203,11 +209,17 @@ export function* generateElementProps( prop.exp.content, prop.exp.loc, prop.exp.loc.start.offset, - defaultCodeFeatures, + ctx.codeFeatures.all, '(', ')', ), ); + if (!enableCodeFeatures) { + yield toString([...codes]); + } + else { + yield* codes; + } yield `, `; } else { diff --git a/packages/language-core/lib/codegen/template/slotOutlet.ts b/packages/language-core/lib/codegen/template/slotOutlet.ts index f58832fda8..44dcbb6444 100644 --- a/packages/language-core/lib/codegen/template/slotOutlet.ts +++ b/packages/language-core/lib/codegen/template/slotOutlet.ts @@ -54,7 +54,7 @@ export function* generateSlotOutlet( startTagOffset + node.tag.length, ctx.codeFeatures.verification, `{${newLine}`, - ...generateElementProps(options, ctx, node, node.props.filter(prop => prop !== nameProp), 'normal'), + ...generateElementProps(options, ctx, node, node.props.filter(prop => prop !== nameProp), true), `}`, ); yield `)${endOfLine}`; @@ -62,7 +62,7 @@ export function* generateSlotOutlet( } else { yield `var ${varSlot} = {${newLine}`; - yield* generateElementProps(options, ctx, node, node.props.filter(prop => prop !== nameProp), 'normal'); + yield* generateElementProps(options, ctx, node, node.props.filter(prop => prop !== nameProp), true); yield `}${endOfLine}`; }