Jelajahi Sumber

fix(compiler-vapor): fix circular reference in repeated call expression cache (#14567)

bab 1 bulan lalu
induk
melakukan
62f2ab4ab3

+ 29 - 0
packages/compiler-vapor/__tests__/transforms/__snapshots__/expression.spec.ts.snap

@@ -217,6 +217,35 @@ export function render(_ctx) {
 }"
 `;
 
+exports[`compiler: expression > cache expressions > repeated simple function calls 1`] = `
+"import { setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue';
+const t0 = _template("<div>")
+
+export function render(_ctx) {
+  const n0 = t0()
+  const n1 = t0()
+  _renderEffect(() => {
+    const _foo = _ctx.foo()
+    _setProp(n0, "id", _foo)
+    _setProp(n1, "id", _foo)
+  })
+  return [n0, n1]
+}"
+`;
+
+exports[`compiler: expression > cache expressions > repeated simple function calls with setup-const binding 1`] = `
+"
+  const n0 = t0()
+  const n1 = t0()
+  _renderEffect(() => {
+    const _foo = foo()
+    _setProp(n0, "id", _foo)
+    _setProp(n1, "id", _foo)
+  })
+  return [n0, n1]
+"
+`;
+
 exports[`compiler: expression > cache expressions > repeated variable in expressions 1`] = `
 "import { setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue';
 const t0 = _template("<div>")

+ 21 - 0
packages/compiler-vapor/__tests__/transforms/expression.spec.ts

@@ -115,6 +115,27 @@ describe('compiler: expression', () => {
       expect(code).contains('_setProp(n2, "id", _foo + _foo_bar)')
     })
 
+    test('repeated simple function calls', () => {
+      const { code } = compileWithExpression(`
+        <div :id="foo()"></div>
+        <div :id="foo()"></div>
+      `)
+      expect(code).matchSnapshot()
+      expect(code).contains('const _foo = _ctx.foo()')
+    })
+
+    test('repeated simple function calls with setup-const binding', () => {
+      const { code } = compileWithExpression(
+        `
+        <div :id="foo()"></div>
+        <div :id="foo()"></div>
+      `,
+        { bindingMetadata: { foo: BindingTypes.SETUP_CONST }, inline: true },
+      )
+      expect(code).matchSnapshot()
+      expect(code).contains('const _foo = foo()')
+    })
+
     test('function calls with arguments', () => {
       const { code } = compileWithExpression(`
         <div :id="foo[bar(baz)]"></div>

+ 2 - 1
packages/compiler-vapor/src/generators/expression.ts

@@ -638,7 +638,7 @@ function genDeclarations(
   // process expressions
   declarations.forEach(({ name, isIdentifier, value }) => {
     if (!isIdentifier) {
-      const varName = (ids[name] = `_${name}`)
+      const varName = `_${name}`
       varNames.add(varName)
       if (shouldDeclare) {
         push(`const `)
@@ -648,6 +648,7 @@ function genDeclarations(
         ...context.withId(() => genExpression(value, context), ids),
         NEWLINE,
       )
+      ids[name] = varName
     }
   })