From: edison Date: Thu, 25 Dec 2025 13:30:40 +0000 (+0800) Subject: fix(compiler-vapor): cache optional call expression (#14246) X-Git-Tag: v3.6.0-beta.2~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7a0cbc0e059dc47108e987755a2ed9d9d328baf8;p=thirdparty%2Fvuejs%2Fcore.git fix(compiler-vapor): cache optional call expression (#14246) --- diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap index bddf5544cc..0594b0037c 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -286,6 +286,22 @@ export function render(_ctx) { }" `; +exports[`cache multiple access > should cache optional call expression with same arguments 1`] = ` +"import { setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue'; +const t0 = _template("
") + +export function render(_ctx) { + const n0 = t0() + const n1 = t0() + _renderEffect(() => { + const _obj_foo_bar = _ctx.obj[_ctx.foo?.(_ctx.bar)] + _setProp(n0, "id", _obj_foo_bar) + _setProp(n1, "id", _obj_foo_bar) + }) + return [n0, n1] +}" +`; + exports[`cache multiple access > should not cache method call with different arguments 1`] = ` "import { setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
") diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index 7195e52afc..2e459a8a41 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -974,4 +974,13 @@ describe('cache multiple access', () => { expect(code).contains(`const _msg_replace_1_2 = _ctx.msg.replace('1', '2')`) expect(code).not.contains('const _msg = _ctx.msg') }) + + test('should cache optional call expression with same arguments', () => { + const { code } = compileWithVBind(` +
+
+ `) + expect(code).matchSnapshot() + expect(code).contains(`const _obj_foo_bar = _ctx.obj[_ctx.foo?.(_ctx.bar)]`) + }) }) diff --git a/packages/compiler-vapor/src/generators/expression.ts b/packages/compiler-vapor/src/generators/expression.ts index 3893282d6f..7dca94d557 100644 --- a/packages/compiler-vapor/src/generators/expression.ts +++ b/packages/compiler-vapor/src/generators/expression.ts @@ -677,6 +677,8 @@ function extractMemberExpression( return `${extractMemberExpression(exp.left, onIdentifier)} ${exp.operator} ${extractMemberExpression(exp.right, onIdentifier)}` case 'CallExpression': // foo[bar(baz)] return `${extractMemberExpression(exp.callee, onIdentifier)}(${exp.arguments.map(arg => extractMemberExpression(arg, onIdentifier)).join(', ')})` + case 'OptionalCallExpression': // foo[bar?.(baz)] + return `${extractMemberExpression(exp.callee, onIdentifier)}?.(${exp.arguments.map(arg => extractMemberExpression(arg, onIdentifier)).join(', ')})` case 'MemberExpression': // foo[bar.baz] case 'OptionalMemberExpression': // foo?.bar const object = extractMemberExpression(exp.object, onIdentifier)