From: edison Date: Mon, 17 Nov 2025 00:35:53 +0000 (+0800) Subject: fix(compiler-vapor): handle TSNonNullExpression and improve expression processing... X-Git-Tag: v3.6.0-alpha.5~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=092c73ae28486ca8746fdcef2da41f4fdd8c73f9;p=thirdparty%2Fvuejs%2Fcore.git fix(compiler-vapor): handle TSNonNullExpression and improve expression processing (#14097) --- 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 6fecc45962..228dbc0c54 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -1,5 +1,19 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`cache multiple access > TSNonNullExpression 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 _obj = _ctx.obj + _setProp(n0, "id", _obj.foo + _obj.bar) + }) + return n0 +}" +`; + exports[`cache multiple access > cache variable used in both property shorthand and normal binding 1`] = ` "import { setStyle as _setStyle, setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue'; const t0 = _template("
", true) diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index f14cf29499..e30a54f203 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -836,6 +836,13 @@ describe('cache multiple access', () => { expect(code).contains('_setProp(n0, "id", _obj?.foo + _obj?.bar)') }) + test('TSNonNullExpression', () => { + const { code } = compileWithVBind(`
`) + expect(code).matchSnapshot() + expect(code).contains('const _obj = _ctx.obj') + expect(code).contains('_setProp(n0, "id", _obj.foo + _obj.bar)') + }) + test('not cache variable only used in property shorthand', () => { const { code } = compileWithVBind(`
diff --git a/packages/compiler-vapor/src/generators/expression.ts b/packages/compiler-vapor/src/generators/expression.ts index 2faaa13ff5..8362c6f940 100644 --- a/packages/compiler-vapor/src/generators/expression.ts +++ b/packages/compiler-vapor/src/generators/expression.ts @@ -513,7 +513,10 @@ function processRepeatedExpressions( const declarations: DeclarationValue[] = [] const seenExp = expressions.reduce( (acc, exp) => { - const variables = expToVariableMap.get(exp)!.map(v => v.name) + const vars = expToVariableMap.get(exp) + if (!vars) return acc + + const variables = vars.map(v => v.name) // only handle expressions that are not identifiers if ( exp.ast && @@ -673,6 +676,8 @@ function extractMemberExpression( ? `[${extractMemberExpression(exp.property, onIdentifier)}]` : `.${extractMemberExpression(exp.property, NOOP)}` return `${object}${prop}` + case 'TSNonNullExpression': // foo!.bar + return `${extractMemberExpression(exp.expression, onIdentifier)}!` default: return '' } @@ -680,6 +685,8 @@ function extractMemberExpression( const isMemberExpression = (node: Node) => { return ( - node.type === 'MemberExpression' || node.type === 'OptionalMemberExpression' + node.type === 'MemberExpression' || + node.type === 'OptionalMemberExpression' || + node.type === 'TSNonNullExpression' ) }