From af9ca0fc7867dc3097fd49d39851bc976e51a79e 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: Tue, 17 Dec 2024 14:33:40 +0800 Subject: [PATCH 01/27] refactor(language-core): remove unnecessary linked code mappings of `defineProp` (#5058) --- .../lib/codegen/script/scriptSetup.ts | 45 +++++-------------- .../passedFixtures/vue3/defineModel/main.vue | 9 ++-- .../vue3/defineModel/script-setup.vue | 16 +++---- 3 files changed, 23 insertions(+), 47 deletions(-) diff --git a/packages/language-core/lib/codegen/script/scriptSetup.ts b/packages/language-core/lib/codegen/script/scriptSetup.ts index 8b21666f86..6c1fa47f34 100644 --- a/packages/language-core/lib/codegen/script/scriptSetup.ts +++ b/packages/language-core/lib/codegen/script/scriptSetup.ts @@ -26,8 +26,6 @@ export function* generateScriptSetup( scriptSetup: NonNullable, scriptSetupRanges: ScriptSetupRanges ): Generator { - const definePropMirrors = new Map(); - if (scriptSetup.generic) { if (!options.scriptRanges?.exportDefault) { if (options.sfc.scriptSetup) { @@ -56,7 +54,7 @@ export function* generateScriptSetup( + ` __VLS_ctx?: ${ctx.localTypes.PrettifyLocal}>, 'attrs' | 'emit' | 'slots'>>,${newLine}` // use __VLS_Prettify for less dts code + ` __VLS_expose?: NonNullable>['expose'],${newLine}` + ` __VLS_setup = (async () => {${newLine}`; - yield* generateSetupFunction(options, ctx, scriptSetup, scriptSetupRanges, undefined, definePropMirrors); + yield* generateSetupFunction(options, ctx, scriptSetup, scriptSetupRanges, undefined); const emitTypes: string[] = []; @@ -79,34 +77,16 @@ export function* generateScriptSetup( } else if (!options.sfc.script) { // no script block, generate script setup code at root - yield* generateSetupFunction(options, ctx, scriptSetup, scriptSetupRanges, 'export default', definePropMirrors); + yield* generateSetupFunction(options, ctx, scriptSetup, scriptSetupRanges, 'export default'); } else { if (!options.scriptRanges?.exportDefault) { yield `export default `; } yield `await (async () => {${newLine}`; - yield* generateSetupFunction(options, ctx, scriptSetup, scriptSetupRanges, 'return', definePropMirrors); + yield* generateSetupFunction(options, ctx, scriptSetup, scriptSetupRanges, 'return'); yield `})()`; } - - if (ctx.scriptSetupGeneratedOffset !== undefined) { - for (const defineProp of scriptSetupRanges.defineProp) { - if (!defineProp.localName) { - continue; - } - const [_, localName] = getPropAndLocalName(scriptSetup, defineProp); - const propMirror = definePropMirrors.get(localName!); - if (propMirror !== undefined) { - options.linkedCodeMappings.push({ - sourceOffsets: [defineProp.localName.start + ctx.scriptSetupGeneratedOffset], - generatedOffsets: [propMirror], - lengths: [defineProp.localName.end - defineProp.localName.start], - data: undefined, - }); - } - } - } } function* generateSetupFunction( @@ -114,8 +94,7 @@ function* generateSetupFunction( ctx: ScriptCodegenContext, scriptSetup: NonNullable, scriptSetupRanges: ScriptSetupRanges, - syntax: 'return' | 'export default' | undefined, - definePropMirrors: Map + syntax: 'return' | 'export default' | undefined ): Generator { if (options.vueCompilerOptions.target >= 3.3) { yield `const { `; @@ -305,7 +284,7 @@ function* generateSetupFunction( yield `)${endOfLine}`; } - yield* generateComponentProps(options, ctx, scriptSetup, scriptSetupRanges, definePropMirrors); + yield* generateComponentProps(options, ctx, scriptSetup, scriptSetupRanges); yield* generateModelEmit(scriptSetup, scriptSetupRanges); yield `function __VLS_template() {${newLine}`; const templateCodegenCtx = yield* generateTemplate(options, ctx); @@ -378,8 +357,7 @@ function* generateComponentProps( options: ScriptCodegenOptions, ctx: ScriptCodegenContext, scriptSetup: NonNullable, - scriptSetupRanges: ScriptSetupRanges, - definePropMirrors: Map + scriptSetupRanges: ScriptSetupRanges ): Generator { yield `const __VLS_fnComponent = (await import('${options.vueCompilerOptions.lib}')).defineComponent({${newLine}`; @@ -456,12 +434,10 @@ function* generateComponentProps( yield propName!; } else if (defineProp.name) { - // renaming support yield generateSfcBlockSection(scriptSetup, defineProp.name.start, defineProp.name.end, codeFeatures.navigation); } else if (defineProp.localName) { - definePropMirrors.set(localName!, options.getGeneratedLength()); - yield localName!; + yield generateSfcBlockSection(scriptSetup, defineProp.localName.start, defineProp.localName.end, codeFeatures.navigation); } else { continue; @@ -474,13 +450,12 @@ function* generateComponentProps( yield `,${newLine}`; if (defineProp.modifierType) { - let propModifierName = 'modelModifiers'; + let modifierName = `modelModifiers`; if (defineProp.name) { - propModifierName = `${getRangeName(scriptSetup, defineProp.name, true)}Modifiers`; + modifierName = `${getRangeName(scriptSetup, defineProp.name, true)}Modifiers`; } const modifierType = getRangeName(scriptSetup, defineProp.modifierType); - definePropMirrors.set(propModifierName, options.getGeneratedLength()); - yield `${propModifierName}?: Partial>,${endOfLine}`; + yield `${modifierName}?: Partial>,${newLine}`; } } yield `}`; diff --git a/test-workspace/tsc/passedFixtures/vue3/defineModel/main.vue b/test-workspace/tsc/passedFixtures/vue3/defineModel/main.vue index 22d1ff9e86..a693d5f8ac 100644 --- a/test-workspace/tsc/passedFixtures/vue3/defineModel/main.vue +++ b/test-workspace/tsc/passedFixtures/vue3/defineModel/main.vue @@ -1,6 +1,6 @@ From d34ea593ce7644840cabea3e4e87b331ddb46813 Mon Sep 17 00:00:00 2001 From: KazariEX <1364035137@qq.com> Date: Tue, 17 Dec 2024 19:51:59 +0800 Subject: [PATCH 02/27] fix(language-core): avoid clipping prop name using `.prop` or `.attr` on `v-model` --- packages/language-core/lib/codegen/template/elementProps.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/language-core/lib/codegen/template/elementProps.ts b/packages/language-core/lib/codegen/template/elementProps.ts index 74512d60f8..b5381794d6 100644 --- a/packages/language-core/lib/codegen/template/elementProps.ts +++ b/packages/language-core/lib/codegen/template/elementProps.ts @@ -100,7 +100,10 @@ export function* generateElementProps( continue; } - if (prop.modifiers.some(m => m.content === 'prop' || m.content === 'attr')) { + if ( + prop.name === 'bind' + && prop.modifiers.some(m => m.content === 'prop' || m.content === 'attr') + ) { propName = propName.slice(1); } From 06b98f50104925b616a0a582b1bbade4f3ef167c 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: Wed, 18 Dec 2024 03:03:23 +0800 Subject: [PATCH 03/27] feat(language-core): type support of `v-model` modifiers (#5061) --- .../lib/codegen/script/scriptSetup.ts | 50 +++-- .../lib/codegen/template/context.ts | 5 + .../lib/codegen/template/element.ts | 6 +- .../lib/codegen/template/elementDirectives.ts | 66 ++++--- .../lib/codegen/template/elementProps.ts | 174 +++++++++++------- .../language-core/lib/codegen/utils/index.ts | 4 +- .../tsc/tests/__snapshots__/dts.spec.ts.snap | 2 +- .../passedFixtures/vue3/defineModel/main.vue | 3 +- .../vue3/defineModel/script-setup.vue | 3 +- .../vue3/defineModelModifiers/comp.vue | 9 + .../vue3/defineModelModifiers/main.vue | 12 ++ 11 files changed, 201 insertions(+), 133 deletions(-) create mode 100644 test-workspace/tsc/passedFixtures/vue3/defineModelModifiers/comp.vue create mode 100644 test-workspace/tsc/passedFixtures/vue3/defineModelModifiers/main.vue diff --git a/packages/language-core/lib/codegen/script/scriptSetup.ts b/packages/language-core/lib/codegen/script/scriptSetup.ts index 6c1fa47f34..4f8a973244 100644 --- a/packages/language-core/lib/codegen/script/scriptSetup.ts +++ b/packages/language-core/lib/codegen/script/scriptSetup.ts @@ -393,22 +393,25 @@ function* generateComponentProps( if (scriptSetupRanges.defineProp.length) { yield `const __VLS_defaults = {${newLine}`; for (const defineProp of scriptSetupRanges.defineProp) { - if (defineProp.defaultValue) { - const [propName, localName] = getPropAndLocalName(scriptSetup, defineProp); - - if (defineProp.name || defineProp.isModel) { - yield propName!; - } - else if (defineProp.localName) { - yield localName!; - } - else { - continue; - } - yield `: `; - yield getRangeName(scriptSetup, defineProp.defaultValue); - yield `,${newLine}`; + if (!defineProp.defaultValue) { + continue; + } + + const [propName, localName] = getPropAndLocalName(scriptSetup, defineProp); + + if (defineProp.name || defineProp.isModel) { + yield `'${propName}'`; + } + else if (defineProp.localName) { + yield localName!; } + else { + continue; + } + + yield `: `; + yield getRangeName(scriptSetup, defineProp.defaultValue); + yield `,${newLine}`; } yield `}${endOfLine}`; } @@ -450,12 +453,9 @@ function* generateComponentProps( yield `,${newLine}`; if (defineProp.modifierType) { - let modifierName = `modelModifiers`; - if (defineProp.name) { - modifierName = `${getRangeName(scriptSetup, defineProp.name, true)}Modifiers`; - } + const modifierName = `${defineProp.name ? propName : 'model'}Modifiers`; const modifierType = getRangeName(scriptSetup, defineProp.modifierType); - yield `${modifierName}?: Partial>,${newLine}`; + yield `'${modifierName}'?: Partial>,${newLine}`; } } yield `}`; @@ -529,14 +529,12 @@ function getPropAndLocalName( if (defineProp.name) { propName = propName!.replace(/['"]+/g, ''); } - return [propName, localName]; + return [propName, localName] as const; } function getRangeName( scriptSetup: NonNullable, - range: TextRange, - unwrap = false + range: TextRange ) { - const offset = unwrap ? 1 : 0; - return scriptSetup.content.slice(range.start + offset, range.end - offset); -} \ No newline at end of file + return scriptSetup.content.slice(range.start, range.end); +} diff --git a/packages/language-core/lib/codegen/template/context.ts b/packages/language-core/lib/codegen/template/context.ts index e204d791f3..bf219f05b7 100644 --- a/packages/language-core/lib/codegen/template/context.ts +++ b/packages/language-core/lib/codegen/template/context.ts @@ -38,6 +38,11 @@ const _codeFeatures = { navigation: true, completion: { isAdditional: true }, } as VueCodeInformation, + withoutNavigation: { + verification: true, + completion: true, + semantic: true, + } as VueCodeInformation, withoutHighlight: { semantic: { shouldHighlight: () => false }, verification: true, diff --git a/packages/language-core/lib/codegen/template/element.ts b/packages/language-core/lib/codegen/template/element.ts index 9fdf951cd9..62edd30bd5 100644 --- a/packages/language-core/lib/codegen/template/element.ts +++ b/packages/language-core/lib/codegen/template/element.ts @@ -200,7 +200,7 @@ export function* generateComponent( } yield `// @ts-ignore${newLine}`; - yield `const ${var_functionalComponent} = __VLS_asFunctionalComponent(${var_originalComponent}, new ${var_originalComponent}({`; + yield `const ${var_functionalComponent} = __VLS_asFunctionalComponent(${var_originalComponent}, new ${var_originalComponent}({${newLine}`; yield* generateElementProps(options, ctx, node, props, options.vueCompilerOptions.strictTemplates, false); yield `}))${endOfLine}`; @@ -211,7 +211,7 @@ export function* generateComponent( startTagOffset, startTagOffset + node.tag.length, ctx.codeFeatures.verification, - `{`, + `{${newLine}`, ...generateElementProps(options, ctx, node, props, options.vueCompilerOptions.strictTemplates, true, failedPropExps), `}` ); @@ -314,7 +314,7 @@ export function* generateElement( startTagOffset, startTagOffset + node.tag.length, ctx.codeFeatures.verification, - `{`, + `{${newLine}`, ...generateElementProps(options, ctx, node, node.props, options.vueCompilerOptions.strictTemplates, true, failedPropExps), `}` ); diff --git a/packages/language-core/lib/codegen/template/elementDirectives.ts b/packages/language-core/lib/codegen/template/elementDirectives.ts index 831bfe901a..973abd9a6c 100644 --- a/packages/language-core/lib/codegen/template/elementDirectives.ts +++ b/packages/language-core/lib/codegen/template/elementDirectives.ts @@ -39,7 +39,7 @@ export function* generateElementDirectives( ...generateArg(options, ctx, prop), ...generateModifiers(options, ctx, prop), ...generateValue(options, ctx, prop), - `}, null!, null!)` + ` }, null!, null!)` ); yield endOfLine; } @@ -90,14 +90,14 @@ function* generateArg( startOffset, startOffset + arg.content.length, ctx.codeFeatures.verification, - 'arg' + `arg` ); - yield ': '; + yield `: `; if (arg.isStatic) { yield* generateStringLiteralKey( arg.content, startOffset, - ctx.codeFeatures.withoutHighlight + ctx.codeFeatures.all ); } else { @@ -109,34 +109,45 @@ function* generateArg( arg.content, startOffset, arg.loc, - '(', - ')' + `(`, + `)` ); } - yield ', '; + yield `, `; } -function* generateModifiers( +export function* generateModifiers( options: TemplateCodegenOptions, ctx: TemplateCodegenContext, - prop: CompilerDOM.DirectiveNode + prop: CompilerDOM.DirectiveNode, + propertyName: string = 'modifiers' ): Generator { - if (options.vueCompilerOptions.target < 3.5) { + const { modifiers } = prop; + if (!modifiers.length) { return; } - yield 'modifiers: { '; - for (const mod of prop.modifiers) { + const startOffset = modifiers[0].loc.start.offset - 1; + const endOffset = modifiers.at(-1)!.loc.end.offset; + + yield* wrapWith( + startOffset, + endOffset, + ctx.codeFeatures.verification, + propertyName + ); + yield `: { `; + for (const mod of modifiers) { yield* generateObjectProperty( options, ctx, mod.content, mod.loc.start.offset, - ctx.codeFeatures.withoutHighlight + ctx.codeFeatures.withoutNavigation ); - yield ': true, '; + yield `: true, `; } - yield '}, '; + yield `}, `; } function* generateValue( @@ -144,31 +155,32 @@ function* generateValue( ctx: TemplateCodegenContext, prop: CompilerDOM.DirectiveNode ): Generator { - if (prop.exp?.type !== CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) { + const { exp } = prop; + if (exp?.type !== CompilerDOM.NodeTypes.SIMPLE_EXPRESSION) { return; } yield* wrapWith( - prop.exp.loc.start.offset, - prop.exp.loc.end.offset, + exp.loc.start.offset, + exp.loc.end.offset, ctx.codeFeatures.verification, - 'value' + `value` ); - yield ': '; + yield `: `; yield* wrapWith( - prop.exp.loc.start.offset, - prop.exp.loc.end.offset, + exp.loc.start.offset, + exp.loc.end.offset, ctx.codeFeatures.verification, ...generateInterpolation( options, ctx, 'template', ctx.codeFeatures.all, - prop.exp.content, - prop.exp.loc.start.offset, - prop.exp.loc, - '(', - ')' + exp.content, + exp.loc.start.offset, + exp.loc, + `(`, + `)` ) ); } diff --git a/packages/language-core/lib/codegen/template/elementProps.ts b/packages/language-core/lib/codegen/template/elementProps.ts index b5381794d6..18d2c28ba5 100644 --- a/packages/language-core/lib/codegen/template/elementProps.ts +++ b/packages/language-core/lib/codegen/template/elementProps.ts @@ -5,10 +5,11 @@ import { toString } from 'muggle-string'; import type { Code, VueCodeInformation, VueCompilerOptions } from '../../types'; import { hyphenateAttr, hyphenateTag } from '../../utils/shared'; import { createVBindShorthandInlayHintInfo } from '../inlayHints'; -import { conditionWrapWith, variableNameRegex, wrapWith } from '../utils'; +import { conditionWrapWith, newLine, variableNameRegex, wrapWith } from '../utils'; import { generateCamelized } from '../utils/camelized'; import { generateUnicode } from '../utils/unicode'; import type { TemplateCodegenContext } from './context'; +import { generateModifiers } from './elementDirectives'; import { generateEventArg, generateEventExpression } from './elementEvents'; import type { TemplateCodegenOptions } from './index'; import { generateInterpolation } from './interpolation'; @@ -46,11 +47,12 @@ export function* generateElementProps( yield* generateEventArg(ctx, prop.arg, true); yield `: `; yield* generateEventExpression(options, ctx, prop); - yield `}, `; + yield `},`; } else { - yield `...{ '${camelize('on-' + prop.arg.loc.source)}': {} as any }, `; + yield `...{ '${camelize('on-' + prop.arg.loc.source)}': {} as any },`; } + yield newLine; } else if ( prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION @@ -87,7 +89,7 @@ export function* generateElementProps( : prop.arg.loc.source; } else { - propName = getModelValuePropName(node, options.vueCompilerOptions.target, options.vueCompilerOptions); + propName = getModelPropName(node, options.vueCompilerOptions); } if ( @@ -108,16 +110,14 @@ export function* generateElementProps( } const shouldSpread = propName === 'style' || propName === 'class'; - const shouldCamelize = isComponent - && (!prop.arg || (prop.arg.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION && prop.arg.isStatic)) // isStatic - && hyphenateAttr(propName) === propName - && !options.vueCompilerOptions.htmlAttributes.some(pattern => minimatch(propName, pattern)); + const shouldCamelize = isComponent && getShouldCamelize(options, prop, propName); + const codeInfo = getPropsCodeInfo(ctx, strictPropsCheck, shouldCamelize); if (shouldSpread) { yield `...{ `; } - const codeInfo = getPropsCodeInfo(ctx, strictPropsCheck, shouldCamelize); - const codes = wrapWith( + const codes = conditionWrapWith( + enableCodeFeatures, prop.loc.start.offset, prop.loc.end.offset, ctx.codeFeatures.verification, @@ -151,16 +151,37 @@ export function* generateElementProps( ), `)` ); - if (!enableCodeFeatures) { - yield toString([...codes]); + if (enableCodeFeatures) { + yield* codes; } else { - yield* codes; + yield toString([...codes]); } if (shouldSpread) { yield ` }`; } - yield `, `; + yield `,${newLine}`; + + if (prop.name === 'model' && prop.modifiers.length) { + const propertyName = prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION + ? !prop.arg.isStatic + ? `[__VLS_tryAsConstant(\`$\{${prop.arg.content}\}Modifiers\`)]` + : camelize(propName) + `Modifiers` + : `modelModifiers`; + const codes = generateModifiers( + options, + ctx, + prop, + propertyName + ); + if (enableCodeFeatures) { + yield* codes; + } + else { + yield toString([...codes]); + } + yield newLine; + } } else if (prop.type === CompilerDOM.NodeTypes.ATTRIBUTE) { if ( @@ -176,14 +197,12 @@ export function* generateElementProps( } const shouldSpread = prop.name === 'style' || prop.name === 'class'; - const shouldCamelize = isComponent - && hyphenateAttr(prop.name) === prop.name - && !options.vueCompilerOptions.htmlAttributes.some(pattern => minimatch(prop.name, pattern)); + const shouldCamelize = isComponent && getShouldCamelize(options, prop, prop.name); + const codeInfo = getPropsCodeInfo(ctx, strictPropsCheck, true); if (shouldSpread) { yield `...{ `; } - const codeInfo = getPropsCodeInfo(ctx, strictPropsCheck, true); const codes = conditionWrapWith( enableCodeFeatures, prop.loc.start.offset, @@ -206,16 +225,16 @@ export function* generateElementProps( ), `)` ); - if (!enableCodeFeatures) { - yield toString([...codes]); + if (enableCodeFeatures) { + yield* codes; } else { - yield* codes; + yield toString([...codes]); } if (shouldSpread) { yield ` }`; } - yield `, `; + yield `,${newLine}`; } else if ( prop.type === CompilerDOM.NodeTypes.DIRECTIVE @@ -229,58 +248,27 @@ export function* generateElementProps( prop.exp.loc.end.offset, ctx.codeFeatures.verification, `...`, - ...generateInterpolation( + ...generatePropExp( options, ctx, - 'template', + prop, + prop.exp, ctx.codeFeatures.all, - prop.exp.content, - prop.exp.loc.start.offset, - prop.exp.loc, - '(', - ')' + false, + enableCodeFeatures ) ); - if (!enableCodeFeatures) { - yield toString([...codes]); + if (enableCodeFeatures) { + yield* codes; } else { - yield* codes; + yield toString([...codes]); } - yield `, `; + yield `,${newLine}`; } } } -function getPropsCodeInfo( - ctx: TemplateCodegenContext, - strictPropsCheck: boolean, - shouldCamelize: boolean -): VueCodeInformation { - const codeInfo = ctx.codeFeatures.withoutHighlightAndCompletion; - return { - ...codeInfo, - navigation: codeInfo.navigation - ? { - resolveRenameNewName: camelize, - resolveRenameEditText: shouldCamelize ? hyphenateAttr : undefined, - } - : false, - verification: strictPropsCheck - ? codeInfo.verification - : { - shouldReport(_source, code) { - if (String(code) === '2353' || String(code) === '2561') { - return false; - } - return typeof codeInfo.verification === 'object' - ? codeInfo.verification.shouldReport?.(_source, code) ?? true - : true; - }, - } - }; -} - function* generatePropExp( options: TemplateCodegenOptions, ctx: TemplateCodegenContext, @@ -333,7 +321,10 @@ function* generatePropExp( } } -function* generateAttrValue(attrNode: CompilerDOM.TextNode, features: VueCodeInformation): Generator { +function* generateAttrValue( + attrNode: CompilerDOM.TextNode, + features: VueCodeInformation +): Generator { const quote = attrNode.loc.source.startsWith("'") ? "'" : '"'; yield quote; let start = attrNode.loc.start.offset; @@ -349,19 +340,64 @@ function* generateAttrValue(attrNode: CompilerDOM.TextNode, features: VueCodeInf yield quote; } -function getModelValuePropName(node: CompilerDOM.ElementNode, vueVersion: number, vueCompilerOptions: VueCompilerOptions) { +function getShouldCamelize( + options: TemplateCodegenOptions, + prop: CompilerDOM.AttributeNode | CompilerDOM.DirectiveNode, + propName: string +) { + return ( + prop.type !== CompilerDOM.NodeTypes.DIRECTIVE + || !prop.arg + || (prop.arg?.type === CompilerDOM.NodeTypes.SIMPLE_EXPRESSION && prop.arg.isStatic) + ) + && hyphenateAttr(propName) === propName + && !options.vueCompilerOptions.htmlAttributes.some(pattern => minimatch(propName, pattern)); +} + +function getPropsCodeInfo( + ctx: TemplateCodegenContext, + strictPropsCheck: boolean, + shouldCamelize: boolean +): VueCodeInformation { + const codeInfo = ctx.codeFeatures.withoutHighlightAndCompletion; + return { + ...codeInfo, + navigation: codeInfo.navigation + ? { + resolveRenameNewName: camelize, + resolveRenameEditText: shouldCamelize ? hyphenateAttr : undefined, + } + : false, + verification: strictPropsCheck + ? codeInfo.verification + : { + shouldReport(_source, code) { + if (String(code) === '2353' || String(code) === '2561') { + return false; + } + return typeof codeInfo.verification === 'object' + ? codeInfo.verification.shouldReport?.(_source, code) ?? true + : true; + }, + } + }; +} + +function getModelPropName(node: CompilerDOM.ElementNode, vueCompilerOptions: VueCompilerOptions) { for (const modelName in vueCompilerOptions.experimentalModelPropName) { const tags = vueCompilerOptions.experimentalModelPropName[modelName]; for (const tag in tags) { if (node.tag === tag || node.tag === hyphenateTag(tag)) { - const v = tags[tag]; - if (typeof v === 'object') { - const arr = Array.isArray(v) ? v : [v]; + const val = tags[tag]; + if (typeof val === 'object') { + const arr = Array.isArray(val) ? val : [val]; for (const attrs of arr) { let failed = false; for (const attr in attrs) { - const attrNode = node.props.find(prop => prop.type === CompilerDOM.NodeTypes.ATTRIBUTE && prop.name === attr) as CompilerDOM.AttributeNode | undefined; + const attrNode = node.props.find( + prop => prop.type === CompilerDOM.NodeTypes.ATTRIBUTE && prop.name === attr + ) as CompilerDOM.AttributeNode | undefined; if (!attrNode || attrNode.value?.content !== attrs[attr]) { failed = true; break; @@ -389,5 +425,5 @@ function getModelValuePropName(node: CompilerDOM.ElementNode, vueVersion: number } } - return vueVersion < 3 ? 'value' : 'modelValue'; + return vueCompilerOptions.target < 3 ? 'value' : 'modelValue'; } diff --git a/packages/language-core/lib/codegen/utils/index.ts b/packages/language-core/lib/codegen/utils/index.ts index e404e73c9a..abcb590ec7 100644 --- a/packages/language-core/lib/codegen/utils/index.ts +++ b/packages/language-core/lib/codegen/utils/index.ts @@ -18,9 +18,7 @@ export function* conditionWrapWith( yield* wrapWith(startOffset, endOffset, features, ...wrapCodes); } else { - for (const wrapCode of wrapCodes) { - yield wrapCode; - } + yield* wrapCodes; } } diff --git a/packages/tsc/tests/__snapshots__/dts.spec.ts.snap b/packages/tsc/tests/__snapshots__/dts.spec.ts.snap index b6d0bb7f7c..7c6e412db5 100644 --- a/packages/tsc/tests/__snapshots__/dts.spec.ts.snap +++ b/packages/tsc/tests/__snapshots__/dts.spec.ts.snap @@ -310,7 +310,7 @@ exports[`vue-tsc-dts > Input: reference-type-model/component.vue, Output: refere "foo"?: number; "bar"?: string[]; "qux"?: string; - quxModifiers?: Partial>; + 'quxModifiers'?: Partial>; }; declare const _default: import("vue").DefineComponent>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, { "update:foo": (value: number) => void; diff --git a/test-workspace/tsc/passedFixtures/vue3/defineModel/main.vue b/test-workspace/tsc/passedFixtures/vue3/defineModel/main.vue index a693d5f8ac..d1f2c600ba 100644 --- a/test-workspace/tsc/passedFixtures/vue3/defineModel/main.vue +++ b/test-workspace/tsc/passedFixtures/vue3/defineModel/main.vue @@ -11,7 +11,6 @@ const ScriptSetupExact = defineComponent({ 'e': string, 'f'?: string, 'g'?: string, - gModifiers?: Partial>, }, __typeEmits: {} as { 'update:modelValue': [modelValue:string]; @@ -30,7 +29,7 @@ exactType(ScriptSetup, ScriptSetupExact);