]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor(compiler): move patchFlag text generation to codegen phase
authorEvan You <evan@vuejs.org>
Sat, 13 Jul 2024 10:21:02 +0000 (18:21 +0800)
committerEvan You <evan@vuejs.org>
Sat, 13 Jul 2024 11:40:04 +0000 (19:40 +0800)
18 files changed:
packages/compiler-core/__tests__/__snapshots__/codegen.spec.ts.snap
packages/compiler-core/__tests__/codegen.spec.ts
packages/compiler-core/__tests__/transform.spec.ts
packages/compiler-core/__tests__/transforms/hoistStatic.spec.ts
packages/compiler-core/__tests__/transforms/transformElement.spec.ts
packages/compiler-core/__tests__/transforms/vFor.spec.ts
packages/compiler-core/__tests__/transforms/vSlot.spec.ts
packages/compiler-core/src/ast.ts
packages/compiler-core/src/codegen.ts
packages/compiler-core/src/transform.ts
packages/compiler-core/src/transforms/hoistStatic.ts
packages/compiler-core/src/transforms/transformElement.ts
packages/compiler-core/src/transforms/vFor.ts
packages/compiler-core/src/transforms/vIf.ts
packages/compiler-dom/__tests__/transforms/vHtml.spec.ts
packages/compiler-dom/__tests__/transforms/vOn.spec.ts
packages/compiler-dom/__tests__/transforms/vText.spec.ts
packages/runtime-core/__tests__/hydration.spec.ts

index 2bdb4afa4c0c76d303d97348deaf6b429054d143..a9591f922b44ae54d8324c7fd4b65c79c57d48e3 100644 (file)
@@ -54,7 +54,7 @@ return function render(_ctx, _cache) {
       [foo + bar]: bar
     }, [
       _createElementVNode("p", { "some-key": "foo" })
-    ], 16)
+    ], 16 /* FULL_PROPS */)
   }
 }"
 `;
@@ -98,7 +98,7 @@ exports[`compiler: codegen > forNode 1`] = `
 "
 return function render(_ctx, _cache) {
   with (_ctx) {
-    return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(), 1))
+    return (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(), 1 /* TEXT */))
   }
 }"
 `;
index 9c9230756343d0867a176df82a6b580ac016a8b7..4a5ba7d5c6160820502fc9c6249376c76f78810c 100644 (file)
@@ -267,7 +267,7 @@ describe('compiler: codegen', () => {
             disableTracking: true,
             props: undefined,
             children: createCallExpression(RENDER_LIST),
-            patchFlag: '1',
+            patchFlag: PatchFlags.TEXT,
             dynamicProps: undefined,
             directives: undefined,
             loc: locStub,
@@ -303,7 +303,7 @@ describe('compiler: codegen', () => {
             disableTracking: false,
             props: undefined,
             children: createCallExpression(RENDER_LIST),
-            patchFlag: genFlagText(PatchFlags.STABLE_FRAGMENT),
+            patchFlag: PatchFlags.STABLE_FRAGMENT,
             dynamicProps: undefined,
             directives: undefined,
             loc: locStub,
@@ -364,7 +364,7 @@ describe('compiler: codegen', () => {
             ),
           ],
           // flag
-          PatchFlags.FULL_PROPS + '',
+          PatchFlags.FULL_PROPS,
         ),
       }),
     )
@@ -375,7 +375,7 @@ describe('compiler: codegen', () => {
       [foo + bar]: bar
     }, [
       _${helperNameMap[CREATE_ELEMENT_VNODE]}("p", { "some-key": "foo" })
-    ], ${PatchFlags.FULL_PROPS})`)
+    ], ${genFlagText(PatchFlags.FULL_PROPS)})`)
     expect(code).toMatchSnapshot()
   })
 
@@ -666,11 +666,14 @@ describe('compiler: codegen', () => {
     })
 
     test('with patchFlag and no children/props', () => {
-      expect(genCode(createVNodeCall(null, `"div"`, undefined, undefined, '1')))
-        .toMatchInlineSnapshot(`
-          "return _createElementVNode("div", null, null, 1)
-           "
-        `)
+      expect(
+        genCode(
+          createVNodeCall(null, `"div"`, undefined, undefined, PatchFlags.TEXT),
+        ),
+      ).toMatchInlineSnapshot(`
+        "return _createElementVNode("div", null, null, 1 /* TEXT */)
+         "
+      `)
     })
 
     test('as block', () => {
index a56be51bc5c906b5fc0797ed3c7762d9f6670dd1..0946d36483890a120d4e16fb2bec2986f913820a 100644 (file)
@@ -19,7 +19,6 @@ import { transformFor } from '../src/transforms/vFor'
 import { transformElement } from '../src/transforms/transformElement'
 import { transformSlotOutlet } from '../src/transforms/transformSlotOutlet'
 import { transformText } from '../src/transforms/transformText'
-import { genFlagText } from './testUtils'
 import { PatchFlags } from '@vue/shared'
 
 describe('compiler: transform', () => {
@@ -358,7 +357,7 @@ describe('compiler: transform', () => {
             { type: NodeTypes.ELEMENT, tag: `div` },
             { type: NodeTypes.ELEMENT, tag: `div` },
           ] as any,
-          genFlagText(PatchFlags.STABLE_FRAGMENT),
+          PatchFlags.STABLE_FRAGMENT,
         ),
       )
     })
@@ -374,10 +373,7 @@ describe('compiler: transform', () => {
             { type: NodeTypes.ELEMENT, tag: `div` },
             { type: NodeTypes.COMMENT },
           ] as any,
-          genFlagText([
-            PatchFlags.STABLE_FRAGMENT,
-            PatchFlags.DEV_ROOT_FRAGMENT,
-          ]),
+          PatchFlags.STABLE_FRAGMENT | PatchFlags.DEV_ROOT_FRAGMENT,
         ),
       )
     })
index d6c46b52eb3a3cb04f784f62cb4d329d09e4f578..d5a34243bcaaf55960f896a0a60f26a14919f869 100644 (file)
@@ -21,7 +21,7 @@ import { transformIf } from '../../src/transforms/vIf'
 import { transformFor } from '../../src/transforms/vFor'
 import { transformBind } from '../../src/transforms/vBind'
 import { transformOn } from '../../src/transforms/vOn'
-import { createObjectMatcher, genFlagText } from '../testUtils'
+import { createObjectMatcher } from '../testUtils'
 import { transformText } from '../../src/transforms/transformText'
 import { PatchFlags } from '@vue/shared'
 
@@ -180,7 +180,7 @@ describe('compiler: hoistStatic transform', () => {
             id: `[foo]`,
           }),
           children: undefined,
-          patchFlag: genFlagText(PatchFlags.PROPS),
+          patchFlag: PatchFlags.PROPS,
           dynamicProps: {
             type: NodeTypes.SIMPLE_EXPRESSION,
             content: `_hoisted_1`,
@@ -242,7 +242,7 @@ describe('compiler: hoistStatic transform', () => {
             ref: `[foo]`,
           }),
           children: undefined,
-          patchFlag: genFlagText(PatchFlags.NEED_PATCH),
+          patchFlag: PatchFlags.NEED_PATCH,
         },
       },
     ])
@@ -263,7 +263,7 @@ describe('compiler: hoistStatic transform', () => {
             content: `_hoisted_1`,
           },
           children: undefined,
-          patchFlag: genFlagText(PatchFlags.NEED_PATCH),
+          patchFlag: PatchFlags.NEED_PATCH,
           directives: {
             type: NodeTypes.JS_ARRAY_EXPRESSION,
           },
@@ -286,7 +286,7 @@ describe('compiler: hoistStatic transform', () => {
           tag: `"div"`,
           props: { content: `_hoisted_1` },
           children: { type: NodeTypes.INTERPOLATION },
-          patchFlag: genFlagText(PatchFlags.TEXT),
+          patchFlag: PatchFlags.TEXT,
         },
       },
     ])
@@ -365,7 +365,7 @@ describe('compiler: hoistStatic transform', () => {
         type: NodeTypes.JS_CALL_EXPRESSION,
         callee: RENDER_LIST,
       },
-      patchFlag: genFlagText(PatchFlags.UNKEYED_FRAGMENT),
+      patchFlag: PatchFlags.UNKEYED_FRAGMENT,
     })
     const innerBlockCodegen = forBlockCodegen!.children.arguments[1]
     expect(innerBlockCodegen.returns).toMatchObject({
@@ -496,7 +496,7 @@ describe('compiler: hoistStatic transform', () => {
                   constType: ConstantTypes.NOT_CONSTANT,
                 },
               },
-              patchFlag: `1 /* TEXT */`,
+              patchFlag: PatchFlags.TEXT,
             },
           },
         ],
index 10b9747d1eef710749c051aba3fba2cc2b790d98..bf3510a052d3b540466e188289c1261986f023df 100644 (file)
@@ -37,7 +37,7 @@ import { transformStyle } from '../../../compiler-dom/src/transforms/transformSt
 import { transformOn } from '../../src/transforms/vOn'
 import { transformBind } from '../../src/transforms/vBind'
 import { PatchFlags } from '@vue/shared'
-import { createObjectMatcher, genFlagText } from '../testUtils'
+import { createObjectMatcher } from '../testUtils'
 import { transformText } from '../../src/transforms/transformText'
 import { parseWithForTransform } from './vFor.spec'
 
@@ -521,7 +521,7 @@ describe('compiler: element transform', () => {
         // keep-alive should not compile content to slots
         children: [{ type: NodeTypes.ELEMENT, tag: 'span' }],
         // should get a dynamic slots flag to force updates
-        patchFlag: genFlagText(PatchFlags.DYNAMIC_SLOTS),
+        patchFlag: PatchFlags.DYNAMIC_SLOTS,
       })
     }
 
@@ -588,7 +588,7 @@ describe('compiler: element transform', () => {
     })
     // should factor in props returned by custom directive transforms
     // in patchFlag analysis
-    expect(node.patchFlag).toMatch(PatchFlags.PROPS + '')
+    expect(node.patchFlag).toBe(PatchFlags.PROPS)
     expect(node.dynamicProps).toMatch(`"bar"`)
   })
 
@@ -612,7 +612,7 @@ describe('compiler: element transform', () => {
       tag: `"div"`,
       props: undefined,
       children: undefined,
-      patchFlag: genFlagText(PatchFlags.NEED_PATCH), // should generate appropriate flag
+      patchFlag: PatchFlags.NEED_PATCH, // should generate appropriate flag
       directives: {
         type: NodeTypes.JS_ARRAY_EXPRESSION,
         elements: [
@@ -945,26 +945,26 @@ describe('compiler: element transform', () => {
       expect(node.patchFlag).toBeUndefined()
 
       const { node: node2 } = parseWithBind(`<div>{{ foo }}</div>`)
-      expect(node2.patchFlag).toBe(genFlagText(PatchFlags.TEXT))
+      expect(node2.patchFlag).toBe(PatchFlags.TEXT)
 
       // multiple nodes, merged with optimize text
       const { node: node3 } = parseWithBind(`<div>foo {{ bar }} baz</div>`)
-      expect(node3.patchFlag).toBe(genFlagText(PatchFlags.TEXT))
+      expect(node3.patchFlag).toBe(PatchFlags.TEXT)
     })
 
     test('CLASS', () => {
       const { node } = parseWithBind(`<div :class="foo" />`)
-      expect(node.patchFlag).toBe(genFlagText(PatchFlags.CLASS))
+      expect(node.patchFlag).toBe(PatchFlags.CLASS)
     })
 
     test('STYLE', () => {
       const { node } = parseWithBind(`<div :style="foo" />`)
-      expect(node.patchFlag).toBe(genFlagText(PatchFlags.STYLE))
+      expect(node.patchFlag).toBe(PatchFlags.STYLE)
     })
 
     test('PROPS', () => {
       const { node } = parseWithBind(`<div id="foo" :foo="bar" :baz="qux" />`)
-      expect(node.patchFlag).toBe(genFlagText(PatchFlags.PROPS))
+      expect(node.patchFlag).toBe(PatchFlags.PROPS)
       expect(node.dynamicProps).toBe(`["foo", "baz"]`)
     })
 
@@ -973,7 +973,7 @@ describe('compiler: element transform', () => {
         `<div id="foo" :class="cls" :style="styl" :foo="bar" :baz="qux"/>`,
       )
       expect(node.patchFlag).toBe(
-        genFlagText([PatchFlags.CLASS, PatchFlags.STYLE, PatchFlags.PROPS]),
+        PatchFlags.CLASS | PatchFlags.STYLE | PatchFlags.PROPS,
       )
       expect(node.dynamicProps).toBe(`["foo", "baz"]`)
     })
@@ -983,40 +983,40 @@ describe('compiler: element transform', () => {
       const { node } = parseWithBind(
         `<Foo :id="foo" :class="cls" :style="styl" />`,
       )
-      expect(node.patchFlag).toBe(genFlagText(PatchFlags.PROPS))
+      expect(node.patchFlag).toBe(PatchFlags.PROPS)
       expect(node.dynamicProps).toBe(`["id", "class", "style"]`)
     })
 
     test('FULL_PROPS (v-bind)', () => {
       const { node } = parseWithBind(`<div v-bind="foo" />`)
-      expect(node.patchFlag).toBe(genFlagText(PatchFlags.FULL_PROPS))
+      expect(node.patchFlag).toBe(PatchFlags.FULL_PROPS)
     })
 
     test('FULL_PROPS (dynamic key)', () => {
       const { node } = parseWithBind(`<div :[foo]="bar" />`)
-      expect(node.patchFlag).toBe(genFlagText(PatchFlags.FULL_PROPS))
+      expect(node.patchFlag).toBe(PatchFlags.FULL_PROPS)
     })
 
     test('FULL_PROPS (w/ others)', () => {
       const { node } = parseWithBind(
         `<div id="foo" v-bind="bar" :class="cls" />`,
       )
-      expect(node.patchFlag).toBe(genFlagText(PatchFlags.FULL_PROPS))
+      expect(node.patchFlag).toBe(PatchFlags.FULL_PROPS)
     })
 
     test('NEED_PATCH (static ref)', () => {
       const { node } = parseWithBind(`<div ref="foo" />`)
-      expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
+      expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH)
     })
 
     test('NEED_PATCH (dynamic ref)', () => {
       const { node } = parseWithBind(`<div :ref="foo" />`)
-      expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
+      expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH)
     })
 
     test('NEED_PATCH (custom directives)', () => {
       const { node } = parseWithBind(`<div v-foo />`)
-      expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
+      expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH)
     })
 
     test('NEED_PATCH (vnode hooks)', () => {
@@ -1025,7 +1025,7 @@ describe('compiler: element transform', () => {
         cacheHandlers: true,
       }).ast
       const node = (root as any).children[0].codegenNode
-      expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
+      expect(node.patchFlag).toBe(PatchFlags.NEED_PATCH)
     })
 
     test('script setup inline mode template ref (binding exists)', () => {
@@ -1120,7 +1120,7 @@ describe('compiler: element transform', () => {
         },
       })
       // should only have props flag
-      expect(node.patchFlag).toBe(genFlagText(PatchFlags.PROPS))
+      expect(node.patchFlag).toBe(PatchFlags.PROPS)
 
       const { node: node2 } = parseWithElementTransform(
         `<div @keyup="foo" />`,
@@ -1130,21 +1130,15 @@ describe('compiler: element transform', () => {
           },
         },
       )
-      expect(node2.patchFlag).toBe(
-        genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION]),
-      )
+      expect(node2.patchFlag).toBe(PatchFlags.PROPS | PatchFlags.NEED_HYDRATION)
     })
 
     test('NEED_HYDRATION for v-bind.prop', () => {
       const { node } = parseWithBind(`<div v-bind:id.prop="id" />`)
-      expect(node.patchFlag).toBe(
-        genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION]),
-      )
+      expect(node.patchFlag).toBe(PatchFlags.PROPS | PatchFlags.NEED_HYDRATION)
 
       const { node: node2 } = parseWithBind(`<div .id="id" />`)
-      expect(node2.patchFlag).toBe(
-        genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION]),
-      )
+      expect(node2.patchFlag).toBe(PatchFlags.PROPS | PatchFlags.NEED_HYDRATION)
     })
 
     // #5870
@@ -1157,9 +1151,7 @@ describe('compiler: element transform', () => {
           },
         },
       )
-      expect(node.patchFlag).toBe(
-        genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION]),
-      )
+      expect(node.patchFlag).toBe(PatchFlags.PROPS | PatchFlags.NEED_HYDRATION)
     })
 
     test('should not have PROPS patchflag for constant v-on handlers', () => {
@@ -1173,7 +1165,7 @@ describe('compiler: element transform', () => {
         },
       })
       // should only have hydration flag
-      expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_HYDRATION))
+      expect(node.patchFlag).toBe(PatchFlags.NEED_HYDRATION)
     })
   })
 
index 94f75f2a63b0f0be17169cd53f1a95a50c8bbf1f..d0e95fcbcb3eb09d7b2eb052d615b419de6759ea 100644 (file)
@@ -18,8 +18,8 @@ import {
 import { ErrorCodes } from '../../src/errors'
 import { type CompilerOptions, generate } from '../../src'
 import { FRAGMENT, RENDER_LIST, RENDER_SLOT } from '../../src/runtimeHelpers'
-import { PatchFlagNames, PatchFlags } from '@vue/shared'
-import { createObjectMatcher, genFlagText } from '../testUtils'
+import { PatchFlags } from '@vue/shared'
+import { createObjectMatcher } from '../testUtils'
 
 export function parseWithForTransform(
   template: string,
@@ -696,10 +696,10 @@ describe('compiler: v-for', () => {
         tag: FRAGMENT,
         disableTracking,
         patchFlag: !disableTracking
-          ? genFlagText(PatchFlags.STABLE_FRAGMENT)
+          ? PatchFlags.STABLE_FRAGMENT
           : keyed
-            ? genFlagText(PatchFlags.KEYED_FRAGMENT)
-            : genFlagText(PatchFlags.UNKEYED_FRAGMENT),
+            ? PatchFlags.KEYED_FRAGMENT
+            : PatchFlags.UNKEYED_FRAGMENT,
         children: {
           type: NodeTypes.JS_CALL_EXPRESSION,
           callee: RENDER_LIST,
@@ -822,7 +822,7 @@ describe('compiler: v-for', () => {
               constType: ConstantTypes.NOT_CONSTANT,
             },
           },
-          patchFlag: genFlagText(PatchFlags.TEXT),
+          patchFlag: PatchFlags.TEXT,
         },
       })
       expect(generate(root).code).toMatchSnapshot()
@@ -846,7 +846,7 @@ describe('compiler: v-for', () => {
             { type: NodeTypes.TEXT, content: `hello` },
             { type: NodeTypes.ELEMENT, tag: `span` },
           ],
-          patchFlag: genFlagText(PatchFlags.STABLE_FRAGMENT),
+          patchFlag: PatchFlags.STABLE_FRAGMENT,
         },
       })
       expect(generate(root).code).toMatchSnapshot()
@@ -950,7 +950,7 @@ describe('compiler: v-for', () => {
             { type: NodeTypes.TEXT, content: `hello` },
             { type: NodeTypes.ELEMENT, tag: `span` },
           ],
-          patchFlag: genFlagText(PatchFlags.STABLE_FRAGMENT),
+          patchFlag: PatchFlags.STABLE_FRAGMENT,
         },
       })
       expect(generate(root).code).toMatchSnapshot()
@@ -971,7 +971,7 @@ describe('compiler: v-for', () => {
           }),
           isBlock: true,
           disableTracking: true,
-          patchFlag: genFlagText(PatchFlags.UNKEYED_FRAGMENT),
+          patchFlag: PatchFlags.UNKEYED_FRAGMENT,
           children: {
             type: NodeTypes.JS_CALL_EXPRESSION,
             callee: RENDER_LIST,
@@ -1009,7 +1009,7 @@ describe('compiler: v-for', () => {
           }),
           isBlock: true,
           disableTracking: true,
-          patchFlag: genFlagText(PatchFlags.UNKEYED_FRAGMENT),
+          patchFlag: PatchFlags.UNKEYED_FRAGMENT,
           children: {
             type: NodeTypes.JS_CALL_EXPRESSION,
             callee: RENDER_LIST,
@@ -1048,9 +1048,7 @@ describe('compiler: v-for', () => {
       const {
         node: { codegenNode },
       } = parseWithForTransform('<div v-for="key in keys" :key>test</div>')
-      expect(codegenNode.patchFlag).toBe(
-        `${PatchFlags.KEYED_FRAGMENT} /* ${PatchFlagNames[PatchFlags.KEYED_FRAGMENT]} */`,
-      )
+      expect(codegenNode.patchFlag).toBe(PatchFlags.KEYED_FRAGMENT)
     })
 
     test('template v-for key w/ :key shorthand on template injected to the child', () => {
index 3afcf0fc0536674bf8e469ec6dfecb37d90ee055..4766c2ca9d863c3177701e9c45f2104958a51ebb 100644 (file)
@@ -24,7 +24,7 @@ import {
   trackVForSlotScopes,
 } from '../../src/transforms/vSlot'
 import { CREATE_SLOTS, RENDER_LIST } from '../../src/runtimeHelpers'
-import { createObjectMatcher, genFlagText } from '../testUtils'
+import { createObjectMatcher } from '../testUtils'
 import { PatchFlags } from '@vue/shared'
 import { transformFor } from '../../src/transforms/vFor'
 import { transformIf } from '../../src/transforms/vIf'
@@ -432,7 +432,7 @@ describe('compiler: transform component slots', () => {
                 ),
                 // nested slot should be forced dynamic, since scope variables
                 // are not tracked as dependencies of the slot.
-                patchFlag: genFlagText(PatchFlags.DYNAMIC_SLOTS),
+                patchFlag: PatchFlags.DYNAMIC_SLOTS,
               },
             },
             // test scope
@@ -474,9 +474,7 @@ describe('compiler: transform component slots', () => {
     const div = ((root.children[0] as ForNode).children[0] as ElementNode)
       .codegenNode as any
     const comp = div.children[0]
-    expect(comp.codegenNode.patchFlag).toBe(
-      genFlagText(PatchFlags.DYNAMIC_SLOTS),
-    )
+    expect(comp.codegenNode.patchFlag).toBe(PatchFlags.DYNAMIC_SLOTS)
   })
 
   test('should only force dynamic slots when actually using scope vars w/ prefixIdentifiers: true', () => {
@@ -494,7 +492,7 @@ describe('compiler: transform component slots', () => {
         flag = (innerComp.codegenNode as VNodeCall).patchFlag
       }
       if (shouldForce) {
-        expect(flag).toBe(genFlagText(PatchFlags.DYNAMIC_SLOTS))
+        expect(flag).toBe(PatchFlags.DYNAMIC_SLOTS)
       } else {
         expect(flag).toBeUndefined()
       }
@@ -581,8 +579,8 @@ describe('compiler: transform component slots', () => {
         },
       ],
     })
-    expect((root as any).children[0].codegenNode.patchFlag).toMatch(
-      PatchFlags.DYNAMIC_SLOTS + '',
+    expect((root as any).children[0].codegenNode.patchFlag).toBe(
+      PatchFlags.DYNAMIC_SLOTS,
     )
     expect(generate(root).code).toMatchSnapshot()
   })
@@ -630,8 +628,8 @@ describe('compiler: transform component slots', () => {
         },
       ],
     })
-    expect((root as any).children[0].codegenNode.patchFlag).toMatch(
-      PatchFlags.DYNAMIC_SLOTS + '',
+    expect((root as any).children[0].codegenNode.patchFlag).toBe(
+      PatchFlags.DYNAMIC_SLOTS,
     )
     expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
   })
@@ -693,8 +691,8 @@ describe('compiler: transform component slots', () => {
         },
       ],
     })
-    expect((root as any).children[0].codegenNode.patchFlag).toMatch(
-      PatchFlags.DYNAMIC_SLOTS + '',
+    expect((root as any).children[0].codegenNode.patchFlag).toBe(
+      PatchFlags.DYNAMIC_SLOTS,
     )
     expect((root as any).children[0].children.length).toBe(3)
     expect(generate(root).code).toMatchSnapshot()
@@ -744,8 +742,8 @@ describe('compiler: transform component slots', () => {
         },
       ],
     })
-    expect((root as any).children[0].codegenNode.patchFlag).toMatch(
-      PatchFlags.DYNAMIC_SLOTS + '',
+    expect((root as any).children[0].codegenNode.patchFlag).toBe(
+      PatchFlags.DYNAMIC_SLOTS,
     )
     expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
   })
index 91354b1b40bf1e3a3eb9039773f7c046d530586e..562e24e72e3746a32badedd4e833d4217fdc384a 100644 (file)
@@ -1,4 +1,4 @@
-import { isString } from '@vue/shared'
+import { type PatchFlags, isString } from '@vue/shared'
 import {
   CREATE_BLOCK,
   CREATE_ELEMENT_BLOCK,
@@ -331,7 +331,7 @@ export interface VNodeCall extends Node {
     | ForRenderListExpression // v-for fragment call
     | SimpleExpressionNode // hoisted
     | undefined
-  patchFlag: string | undefined
+  patchFlag: PatchFlags | undefined
   dynamicProps: string | SimpleExpressionNode | undefined
   directives: DirectiveArguments | undefined
   isBlock: boolean
@@ -561,7 +561,7 @@ export interface ForCodegenNode extends VNodeCall {
   tag: typeof FRAGMENT
   props: undefined
   children: ForRenderListExpression
-  patchFlag: string
+  patchFlag: PatchFlags
   disableTracking: boolean
 }
 
index 39170bac5a0e2dac8f1422984521dc3db72b1e75..4dd51133ce7129e821d9d9d0ff563d69501790cf 100644 (file)
@@ -35,7 +35,13 @@ import {
   isSimpleIdentifier,
   toValidAssetId,
 } from './utils'
-import { isArray, isString, isSymbol } from '@vue/shared'
+import {
+  PatchFlagNames,
+  type PatchFlags,
+  isArray,
+  isString,
+  isSymbol,
+} from '@vue/shared'
 import {
   CREATE_COMMENT,
   CREATE_ELEMENT_VNODE,
@@ -843,6 +849,28 @@ function genVNodeCall(node: VNodeCall, context: CodegenContext) {
     disableTracking,
     isComponent,
   } = node
+
+  // add dev annotations to patch flags
+  let patchFlagString
+  if (patchFlag) {
+    if (__DEV__) {
+      if (patchFlag < 0) {
+        // special flags (negative and mutually exclusive)
+        patchFlagString = patchFlag + ` /* ${PatchFlagNames[patchFlag]} */`
+      } else {
+        // bitwise flags
+        const flagNames = Object.keys(PatchFlagNames)
+          .map(Number)
+          .filter(n => n > 0 && patchFlag & n)
+          .map(n => PatchFlagNames[n as PatchFlags])
+          .join(`, `)
+        patchFlagString = patchFlag + ` /* ${flagNames} */`
+      }
+    } else {
+      patchFlagString = String(patchFlag)
+    }
+  }
+
   if (directives) {
     push(helper(WITH_DIRECTIVES) + `(`)
   }
@@ -857,7 +885,7 @@ function genVNodeCall(node: VNodeCall, context: CodegenContext) {
     : getVNodeHelper(context.inSSR, isComponent)
   push(helper(callHelper) + `(`, NewlineType.None, node)
   genNodeList(
-    genNullableArgs([tag, props, children, patchFlag, dynamicProps]),
+    genNullableArgs([tag, props, children, patchFlagString, dynamicProps]),
     context,
   )
   push(`)`)
index 69821f7f879f30263cc6e216b26cf50aa27c290b..83ed8a92064b93df582939ee55c7449b2b027a96 100644 (file)
@@ -382,7 +382,7 @@ function createRootCodegen(root: RootNode, context: TransformContext) {
       helper(FRAGMENT),
       undefined,
       root.children,
-      patchFlag + (__DEV__ ? ` /* ${patchFlagText} */` : ``),
+      patchFlag,
       undefined,
       undefined,
       true,
index 67bdaa887bf5f1d7c06af7a411f5b633b2b04d2f..5942b73097b07c53b4ee7799a5b0d7a8d78b53fb 100644 (file)
@@ -70,8 +70,7 @@ function walk(
         : getConstantType(child, context)
       if (constantType > ConstantTypes.NOT_CONSTANT) {
         if (constantType >= ConstantTypes.CAN_HOIST) {
-          ;(child.codegenNode as VNodeCall).patchFlag =
-            PatchFlags.HOISTED + (__DEV__ ? ` /* HOISTED */` : ``)
+          ;(child.codegenNode as VNodeCall).patchFlag = PatchFlags.HOISTED
           child.codegenNode = context.hoist(child.codegenNode!)
           hoistedCount++
           continue
@@ -81,9 +80,9 @@ function walk(
         // hoisting.
         const codegenNode = child.codegenNode!
         if (codegenNode.type === NodeTypes.VNODE_CALL) {
-          const flag = getPatchFlag(codegenNode)
+          const flag = codegenNode.patchFlag
           if (
-            (!flag ||
+            (flag === undefined ||
               flag === PatchFlags.NEED_PATCH ||
               flag === PatchFlags.TEXT) &&
             getGeneratedPropsConstantType(child, context) >=
@@ -179,8 +178,7 @@ export function getConstantType(
       ) {
         return ConstantTypes.NOT_CONSTANT
       }
-      const flag = getPatchFlag(codegenNode)
-      if (!flag) {
+      if (codegenNode.patchFlag === undefined) {
         let returnType = ConstantTypes.CAN_STRINGIFY
 
         // Element itself has no patch flag. However we still need to check:
@@ -365,8 +363,3 @@ function getNodeProps(node: PlainElementNode) {
     return codegenNode.props
   }
 }
-
-function getPatchFlag(node: VNodeCall): number | undefined {
-  const flag = node.patchFlag
-  return flag ? parseInt(flag, 10) : undefined
-}
index b1be06db7030227f6deba53c7e696b2a10e9872e..ebaf08375b9642c8e5bce9bc339726810fc0cf5a 100644 (file)
@@ -23,7 +23,6 @@ import {
   createVNodeCall,
 } from '../ast'
 import {
-  PatchFlagNames,
   PatchFlags,
   camelize,
   capitalize,
@@ -101,8 +100,7 @@ export const transformElement: NodeTransform = (node, context) => {
 
     let vnodeProps: VNodeCall['props']
     let vnodeChildren: VNodeCall['children']
-    let vnodePatchFlag: VNodeCall['patchFlag']
-    let patchFlag: number = 0
+    let patchFlag: VNodeCall['patchFlag'] | 0 = 0
     let vnodeDynamicProps: VNodeCall['dynamicProps']
     let dynamicPropNames: string[] | undefined
     let vnodeDirectives: VNodeCall['directives']
@@ -206,27 +204,8 @@ export const transformElement: NodeTransform = (node, context) => {
     }
 
     // patchFlag & dynamicPropNames
-    if (patchFlag !== 0) {
-      if (__DEV__) {
-        if (patchFlag < 0) {
-          // special flags (negative and mutually exclusive)
-          vnodePatchFlag =
-            patchFlag + ` /* ${PatchFlagNames[patchFlag as PatchFlags]} */`
-        } else {
-          // bitwise flags
-          const flagNames = Object.keys(PatchFlagNames)
-            .map(Number)
-            .filter(n => n > 0 && patchFlag & n)
-            .map(n => PatchFlagNames[n as PatchFlags])
-            .join(`, `)
-          vnodePatchFlag = patchFlag + ` /* ${flagNames} */`
-        }
-      } else {
-        vnodePatchFlag = String(patchFlag)
-      }
-      if (dynamicPropNames && dynamicPropNames.length) {
-        vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames)
-      }
+    if (dynamicPropNames && dynamicPropNames.length) {
+      vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames)
     }
 
     node.codegenNode = createVNodeCall(
@@ -234,7 +213,7 @@ export const transformElement: NodeTransform = (node, context) => {
       vnodeTag,
       vnodeProps,
       vnodeChildren,
-      vnodePatchFlag,
+      patchFlag === 0 ? undefined : patchFlag,
       vnodeDynamicProps,
       vnodeDirectives,
       !!shouldUseBlock,
index 16c48ede06745a622259d2eec044c591e4a03979..0db961528e63eb1c9821e21b2f153ff3e5e6dfd4 100644 (file)
@@ -46,7 +46,7 @@ import {
 } from '../runtimeHelpers'
 import { processExpression } from './transformExpression'
 import { validateBrowserExpression } from '../validateExpression'
-import { PatchFlagNames, PatchFlags } from '@vue/shared'
+import { PatchFlags } from '@vue/shared'
 import { transformBindShorthand } from './vBind'
 
 export const transformFor = createStructuralDirectiveTransform(
@@ -109,8 +109,7 @@ export const transformFor = createStructuralDirectiveTransform(
         helper(FRAGMENT),
         undefined,
         renderExp,
-        fragmentFlag +
-          (__DEV__ ? ` /* ${PatchFlagNames[fragmentFlag]} */` : ``),
+        fragmentFlag,
         undefined,
         undefined,
         true /* isBlock */,
@@ -169,10 +168,7 @@ export const transformFor = createStructuralDirectiveTransform(
             helper(FRAGMENT),
             keyProperty ? createObjectExpression([keyProperty]) : undefined,
             node.children,
-            PatchFlags.STABLE_FRAGMENT +
-              (__DEV__
-                ? ` /* ${PatchFlagNames[PatchFlags.STABLE_FRAGMENT]} */`
-                : ``),
+            PatchFlags.STABLE_FRAGMENT,
             undefined,
             undefined,
             true,
index a6437f89c639bf32b7d973721512e6ab6f534b5a..06255b25fdc754b6d9bbdd36ea7a18925a992e9e 100644 (file)
@@ -280,7 +280,7 @@ function createChildrenCodegenNode(
         helper(FRAGMENT),
         createObjectExpression([keyProperty]),
         children,
-        patchFlag + (__DEV__ ? ` /* ${patchFlagText} */` : ``),
+        patchFlag,
         undefined,
         undefined,
         true,
index a59a7a40aaf32ac3a180a1aed99ecad4935e2544..bca2fdf955815278be12167cb96ed4f29e22bd34 100644 (file)
@@ -6,10 +6,7 @@ import {
 } from '@vue/compiler-core'
 import { transformVHtml } from '../../src/transforms/vHtml'
 import { transformElement } from '../../../compiler-core/src/transforms/transformElement'
-import {
-  createObjectMatcher,
-  genFlagText,
-} from '../../../compiler-core/__tests__/testUtils'
+import { createObjectMatcher } from '../../../compiler-core/__tests__/testUtils'
 import { PatchFlags } from '@vue/shared'
 import { DOMErrorCodes } from '../../src/errors'
 
@@ -34,7 +31,7 @@ describe('compiler: v-html transform', () => {
         innerHTML: `[test]`,
       }),
       children: undefined,
-      patchFlag: genFlagText(PatchFlags.PROPS),
+      patchFlag: PatchFlags.PROPS,
       dynamicProps: `["innerHTML"]`,
     })
   })
@@ -53,7 +50,7 @@ describe('compiler: v-html transform', () => {
         innerHTML: `[test]`,
       }),
       children: undefined, // <-- children should have been removed
-      patchFlag: genFlagText(PatchFlags.PROPS),
+      patchFlag: PatchFlags.PROPS,
       dynamicProps: `["innerHTML"]`,
     })
   })
index 2e80729119d16c4985d7edfd9fc5ca451259d4ee..f53fbb69b0700eec5f5c86510cf1a55250248124 100644 (file)
@@ -14,7 +14,6 @@ import { transformOn } from '../../src/transforms/vOn'
 import { V_ON_WITH_KEYS, V_ON_WITH_MODIFIERS } from '../../src/runtimeHelpers'
 import { transformElement } from '../../../compiler-core/src/transforms/transformElement'
 import { transformExpression } from '../../../compiler-core/src/transforms/transformExpression'
-import { genFlagText } from '../../../compiler-core/__tests__/testUtils'
 import { PatchFlags } from '@vue/shared'
 
 function parseWithVOn(template: string, options: CompilerOptions = {}) {
@@ -272,7 +271,7 @@ describe('compiler-dom: transform v-on', () => {
     // should not treat cached handler as dynamicProp, so it should have no
     // dynamicProps flags and only the hydration flag
     expect((root as any).children[0].codegenNode.patchFlag).toBe(
-      genFlagText(PatchFlags.NEED_HYDRATION),
+      PatchFlags.NEED_HYDRATION,
     )
     expect(prop).toMatchObject({
       key: {
@@ -300,6 +299,6 @@ describe('compiler-dom: transform v-on', () => {
       },
     })
     // should only have hydration flag
-    expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_HYDRATION))
+    expect(node.patchFlag).toBe(PatchFlags.NEED_HYDRATION)
   })
 })
index 1b717e8339846509b92d05e696c4c0537b7fea41..e96ab297298ca40359263dba64937786488418b3 100644 (file)
@@ -6,10 +6,7 @@ import {
 } from '@vue/compiler-core'
 import { transformVText } from '../../src/transforms/vText'
 import { transformElement } from '../../../compiler-core/src/transforms/transformElement'
-import {
-  createObjectMatcher,
-  genFlagText,
-} from '../../../compiler-core/__tests__/testUtils'
+import { createObjectMatcher } from '../../../compiler-core/__tests__/testUtils'
 import { PatchFlags } from '@vue/shared'
 import { DOMErrorCodes } from '../../src/errors'
 
@@ -36,7 +33,7 @@ describe('compiler: v-text transform', () => {
         },
       }),
       children: undefined,
-      patchFlag: genFlagText(PatchFlags.PROPS),
+      patchFlag: PatchFlags.PROPS,
       dynamicProps: `["textContent"]`,
     })
   })
@@ -57,7 +54,7 @@ describe('compiler: v-text transform', () => {
         },
       }),
       children: undefined, // <-- children should have been removed
-      patchFlag: genFlagText(PatchFlags.PROPS),
+      patchFlag: PatchFlags.PROPS,
       dynamicProps: `["textContent"]`,
     })
   })
index 53974bc93843f65e4442d3e98bf619fec0485f71..60941d0369c95f0da4a9fbbdd05a965d4c8f0947 100644 (file)
@@ -1317,76 +1317,83 @@ describe('SSR hydration', () => {
   // #10607
   test('update component stable slot (prod + optimized mode)', async () => {
     __DEV__ = false
-    const container = document.createElement('div')
-    container.innerHTML = `<template><div show="false"><!--[--><div><div><!----></div></div><div>0</div><!--]--></div></template>`
-    const Comp = {
-      render(this: any) {
-        return (
-          openBlock(),
-          createElementBlock('div', null, [renderSlot(this.$slots, 'default')])
-        )
-      },
-    }
-    const show = ref(false)
-    const clicked = ref(false)
-
-    const Wrapper = {
-      setup() {
-        const items = ref<number[]>([])
-        onMounted(() => {
-          items.value = [1]
-        })
-        return () => {
+    try {
+      const container = document.createElement('div')
+      container.innerHTML = `<template><div show="false"><!--[--><div><div><!----></div></div><div>0</div><!--]--></div></template>`
+      const Comp = {
+        render(this: any) {
           return (
             openBlock(),
-            createBlock(Comp, null, {
-              default: withCtx(() => [
-                createElementVNode('div', null, [
+            createElementBlock('div', null, [
+              renderSlot(this.$slots, 'default'),
+            ])
+          )
+        },
+      }
+      const show = ref(false)
+      const clicked = ref(false)
+
+      const Wrapper = {
+        setup() {
+          const items = ref<number[]>([])
+          onMounted(() => {
+            items.value = [1]
+          })
+          return () => {
+            return (
+              openBlock(),
+              createBlock(Comp, null, {
+                default: withCtx(() => [
                   createElementVNode('div', null, [
-                    clicked.value
-                      ? (openBlock(),
-                        createElementBlock('div', { key: 0 }, 'foo'))
-                      : createCommentVNode('v-if', true),
+                    createElementVNode('div', null, [
+                      clicked.value
+                        ? (openBlock(),
+                          createElementBlock('div', { key: 0 }, 'foo'))
+                        : createCommentVNode('v-if', true),
+                    ]),
                   ]),
+                  createElementVNode(
+                    'div',
+                    null,
+                    items.value.length,
+                    1 /* TEXT */,
+                  ),
                 ]),
-                createElementVNode(
-                  'div',
-                  null,
-                  items.value.length,
-                  1 /* TEXT */,
-                ),
-              ]),
-              _: 1 /* STABLE */,
-            })
-          )
-        }
-      },
-    }
-    createSSRApp({
-      components: { Wrapper },
-      data() {
-        return { show }
-      },
-      template: `<Wrapper :show="show"/>`,
-    }).mount(container)
+                _: 1 /* STABLE */,
+              })
+            )
+          }
+        },
+      }
+      createSSRApp({
+        components: { Wrapper },
+        data() {
+          return { show }
+        },
+        template: `<Wrapper :show="show"/>`,
+      }).mount(container)
 
-    await nextTick()
-    expect(container.innerHTML).toBe(
-      `<div show="false"><!--[--><div><div><!----></div></div><div>1</div><!--]--></div>`,
-    )
+      await nextTick()
+      expect(container.innerHTML).toBe(
+        `<div show="false"><!--[--><div><div><!----></div></div><div>1</div><!--]--></div>`,
+      )
 
-    show.value = true
-    await nextTick()
-    expect(async () => {
-      clicked.value = true
+      show.value = true
       await nextTick()
-    }).not.toThrow("Cannot read properties of null (reading 'insertBefore')")
+      expect(async () => {
+        clicked.value = true
+        await nextTick()
+      }).not.toThrow("Cannot read properties of null (reading 'insertBefore')")
 
-    await nextTick()
-    expect(container.innerHTML).toBe(
-      `<div show="true"><!--[--><div><div><div>foo</div></div></div><div>1</div><!--]--></div>`,
-    )
-    __DEV__ = true
+      await nextTick()
+      expect(container.innerHTML).toBe(
+        `<div show="true"><!--[--><div><div><div>foo</div></div></div><div>1</div><!--]--></div>`,
+      )
+    } catch (e) {
+      throw e
+    } finally {
+      __DEV__ = true
+    }
   })
 
   describe('mismatch handling', () => {