From 9bb5cfa60bcff6007ce0ec5b0b2bc1434fb231ee Mon Sep 17 00:00:00 2001 From: zhiyuanzmj <260480378@qq.com> Date: Wed, 28 May 2025 07:47:11 +0800 Subject: [PATCH 1/3] fix(compiler-vapor): typed expressions should be wrapped in parentheses --- .../transforms/__snapshots__/vOn.spec.ts.snap | 12 ++++++++++++ .../compiler-vapor/__tests__/transforms/vOn.spec.ts | 10 ++++++++++ packages/compiler-vapor/src/generators/expression.ts | 4 ++++ 3 files changed, 26 insertions(+) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap index cb1a05d2a43..c1d93f30310 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap @@ -123,6 +123,18 @@ export function render(_ctx, $props, $emit, $attrs, $slots) { }" `; +exports[`v-on > expression with type 1`] = ` +"import { delegateEvents as _delegateEvents, template as _template } from 'vue'; +const t0 = _template("
", true) +_delegateEvents("click") + +export function render(_ctx, $props, $emit, $attrs, $slots) { + const n0 = t0() + n0.$evtclick = e => (_ctx.handleClick as any)(e) + return n0 +}" +`; + exports[`v-on > function expression w/ prefixIdentifiers: true 1`] = ` "import { delegateEvents as _delegateEvents, template as _template } from 'vue'; const t0 = _template("
", true) diff --git a/packages/compiler-vapor/__tests__/transforms/vOn.spec.ts b/packages/compiler-vapor/__tests__/transforms/vOn.spec.ts index 1ce2169366c..65dd6274c3b 100644 --- a/packages/compiler-vapor/__tests__/transforms/vOn.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vOn.spec.ts @@ -682,4 +682,14 @@ describe('v-on', () => { '_delegate(n0, "click", _withModifiers(e => _ctx.test(e), ["stop"]))', ) }) + + test('expression with type', () => { + const { code } = compileWithVOn(`
`, { + bindingMetadata: { + handleClick: BindingTypes.SETUP_CONST, + }, + }) + expect(code).matchSnapshot() + expect(code).include('n0.$evtclick = e => (_ctx.handleClick as any)(e)') + }) }) diff --git a/packages/compiler-vapor/src/generators/expression.ts b/packages/compiler-vapor/src/generators/expression.ts index eedaeeb380a..494bdb304e3 100644 --- a/packages/compiler-vapor/src/generators/expression.ts +++ b/packages/compiler-vapor/src/generators/expression.ts @@ -10,6 +10,7 @@ import { NewlineType, type SimpleExpressionNode, type SourceLocation, + TS_NODE_TYPES, advancePositionWithClone, createSimpleExpression, isInDestructureAssignment, @@ -48,6 +49,7 @@ export function genExpression( return genIdentifier(content, context, loc, assignment) } + const shouldWrap = ast && TS_NODE_TYPES.includes(ast.type) const ids: Identifier[] = [] const parentStackMap = new Map() const parentStack: Node[] = [] @@ -85,6 +87,7 @@ export function genExpression( parent.type === 'OptionalMemberExpression') push( + shouldWrap ? '(' : '', ...genIdentifier( source, context, @@ -103,6 +106,7 @@ export function genExpression( if (i === ids.length - 1 && end < content.length) { push([content.slice(end), NewlineType.Unknown]) } + push(shouldWrap ? ')' : '') }) if (assignment && hasMemberExpression) { From adb0f93d614d3a9e6ce76b11205be79389e05b65 Mon Sep 17 00:00:00 2001 From: zhiyuanzmj <260480378@qq.com> Date: Wed, 28 May 2025 08:55:17 +0800 Subject: [PATCH 2/3] chore: update --- packages/compiler-vapor/src/generators/expression.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/compiler-vapor/src/generators/expression.ts b/packages/compiler-vapor/src/generators/expression.ts index 494bdb304e3..c93812df438 100644 --- a/packages/compiler-vapor/src/generators/expression.ts +++ b/packages/compiler-vapor/src/generators/expression.ts @@ -49,7 +49,6 @@ export function genExpression( return genIdentifier(content, context, loc, assignment) } - const shouldWrap = ast && TS_NODE_TYPES.includes(ast.type) const ids: Identifier[] = [] const parentStackMap = new Map() const parentStack: Node[] = [] @@ -66,6 +65,8 @@ export function genExpression( let hasMemberExpression = false if (ids.length) { const [frag, push] = buildCodeFragment() + const shouldWrap = ast && TS_NODE_TYPES.includes(ast.type) + if (shouldWrap) push('(') ids .sort((a, b) => a.start! - b.start!) .forEach((id, i) => { @@ -87,7 +88,6 @@ export function genExpression( parent.type === 'OptionalMemberExpression') push( - shouldWrap ? '(' : '', ...genIdentifier( source, context, @@ -106,8 +106,8 @@ export function genExpression( if (i === ids.length - 1 && end < content.length) { push([content.slice(end), NewlineType.Unknown]) } - push(shouldWrap ? ')' : '') }) + if (shouldWrap) push(')') if (assignment && hasMemberExpression) { push(` = ${assignment}`) From c14f1d455aa1785c92d9931c22c26eaa09dccffb Mon Sep 17 00:00:00 2001 From: zhiyuanzmj <260480378@qq.com> Date: Wed, 28 May 2025 11:26:57 +0800 Subject: [PATCH 3/3] chore: should removed --- .../transforms/__snapshots__/vOn.spec.ts.snap | 2 +- .../compiler-vapor/__tests__/transforms/vOn.spec.ts | 13 ++++++++----- .../compiler-vapor/src/generators/expression.ts | 12 ++++++------ 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap index c1d93f30310..dd00e552675 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap @@ -130,7 +130,7 @@ _delegateEvents("click") export function render(_ctx, $props, $emit, $attrs, $slots) { const n0 = t0() - n0.$evtclick = e => (_ctx.handleClick as any)(e) + n0.$evtclick = e => _ctx.handleClick(e) return n0 }" `; diff --git a/packages/compiler-vapor/__tests__/transforms/vOn.spec.ts b/packages/compiler-vapor/__tests__/transforms/vOn.spec.ts index 65dd6274c3b..aca88c791b8 100644 --- a/packages/compiler-vapor/__tests__/transforms/vOn.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vOn.spec.ts @@ -684,12 +684,15 @@ describe('v-on', () => { }) test('expression with type', () => { - const { code } = compileWithVOn(`
`, { - bindingMetadata: { - handleClick: BindingTypes.SETUP_CONST, + const { code } = compileWithVOn( + `
`, + { + bindingMetadata: { + handleClick: BindingTypes.SETUP_CONST, + }, }, - }) + ) expect(code).matchSnapshot() - expect(code).include('n0.$evtclick = e => (_ctx.handleClick as any)(e)') + expect(code).include('n0.$evtclick = e => _ctx.handleClick(e)') }) }) diff --git a/packages/compiler-vapor/src/generators/expression.ts b/packages/compiler-vapor/src/generators/expression.ts index c93812df438..f7e90ddcb7a 100644 --- a/packages/compiler-vapor/src/generators/expression.ts +++ b/packages/compiler-vapor/src/generators/expression.ts @@ -65,8 +65,7 @@ export function genExpression( let hasMemberExpression = false if (ids.length) { const [frag, push] = buildCodeFragment() - const shouldWrap = ast && TS_NODE_TYPES.includes(ast.type) - if (shouldWrap) push('(') + const isTSNode = ast && TS_NODE_TYPES.includes(ast.type) ids .sort((a, b) => a.start! - b.start!) .forEach((id, i) => { @@ -75,8 +74,10 @@ export function genExpression( const end = id.end! - 1 const last = ids[i - 1] - const leadingText = content.slice(last ? last.end! - 1 : 0, start) - if (leadingText.length) push([leadingText, NewlineType.Unknown]) + if (!(isTSNode && i === 0)) { + const leadingText = content.slice(last ? last.end! - 1 : 0, start) + if (leadingText.length) push([leadingText, NewlineType.Unknown]) + } const source = content.slice(start, end) const parentStack = parentStackMap.get(id)! @@ -103,11 +104,10 @@ export function genExpression( ), ) - if (i === ids.length - 1 && end < content.length) { + if (i === ids.length - 1 && end < content.length && !isTSNode) { push([content.slice(end), NewlineType.Unknown]) } }) - if (shouldWrap) push(')') if (assignment && hasMemberExpression) { push(` = ${assignment}`)