From: edison Date: Tue, 18 Nov 2025 00:56:02 +0000 (+0800) Subject: fix(compiler-vapor): prevent duplicate processing of member expressions in expression... X-Git-Tag: v3.6.0-alpha.5~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=35d135ee14195f26257b46b8c46831dc9facc724;p=thirdparty%2Fvuejs%2Fcore.git fix(compiler-vapor): prevent duplicate processing of member expressions in expression analysis (#14105) --- 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 228dbc0c54..e2579c9ff7 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -57,6 +57,21 @@ export function render(_ctx) { }" `; +exports[`cache multiple access > dynamic property access with parentheses 1`] = ` +"import { setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue'; +const t0 = _template("
", true) + +export function render(_ctx) { + const n0 = t0() + _renderEffect(() => { + const _foo_bar = _ctx.foo[_ctx.bar] + _setProp(n0, "x", (_foo_bar).x) + _setProp(n0, "bar", (_foo_bar)) + }) + return n0 +}" +`; + exports[`cache multiple access > function calls with 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 e30a54f203..63744c2ad7 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -801,6 +801,16 @@ describe('cache multiple access', () => { expect(code).contains('_setProp(n0, "id", _obj[1][_ctx.baz] + _obj.bar)') }) + test('dynamic property access with parentheses', () => { + const { code } = compileWithVBind(` +
+ `) + expect(code).matchSnapshot() + expect(code).contains('const _foo_bar = _ctx.foo[_ctx.bar]') + expect(code).contains('_setProp(n0, "x", (_foo_bar).x)') + expect(code).contains('_setProp(n0, "bar", (_foo_bar))') + }) + test('variable name substring edge cases', () => { const { code } = compileWithVBind( `
`, diff --git a/packages/compiler-vapor/src/generators/expression.ts b/packages/compiler-vapor/src/generators/expression.ts index 8362c6f940..75803d5629 100644 --- a/packages/compiler-vapor/src/generators/expression.ts +++ b/packages/compiler-vapor/src/generators/expression.ts @@ -327,8 +327,10 @@ function analyzeExpressions(expressions: SimpleExpressionNode[]) { continue } + const seenParents = new Set() walkIdentifiers(exp.ast, (currentNode, parent, parentStack) => { - if (parent && isMemberExpression(parent)) { + if (parent && isMemberExpression(parent) && !seenParents.has(parent)) { + seenParents.add(parent) const memberExp = extractMemberExpression(parent, id => { registerVariable(id.name, exp, true, { start: id.start!,