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