import { VNode , ReactiveFlags , ShapeFlags , VNodeNormalizedChildren } from '../shared/svu' ; import { isString , isObject , isFunction , isArray } from '../shared' ; export const Fragment = Symbol ( 'Fragment' ) ; export const Text = Symbol ( 'Text' ) ; export const Comment = Symbol ( 'Comment' ) ; export const Static = Symbol ( 'Static' ) ; /**
 * (openBlock(1),
      createBlock('div', null, [
        ((openBlock(2),
        createBlock("Frag", null, [
          222,
          333
        ])))
    ]))
    编译器会做--：
    一种树的遍历，先按照层级顺序执行openBlock，然后再是树的完成过程（叶子节点开始）
    openBlock1 --> openBlock2 --> Frag --> div
 */ export const blockStack = [ ] ; let currentBlock = null ; export function openBlock ( ) { blockStack . push ( ( currentBlock = [ ] ) ) ; } export function closeBlock ( ) { blockStack . pop ( ) ; currentBlock = blockStack [ blockStack . length - 1 ] || null ; } export function createBlock ( type , props ? , children ? , patchFlag ? , dynamicProps ? ) { const vnode = createVnode ( type , props , children , patchFlag , dynamicProps ) ; vnode . dynamicChildren = currentBlock || [ ] ; closeBlock ( ) ; if ( currentBlock ) { currentBlock . push ( vnode ) ; } return vnode ; } /**
 * 创建 vnode
 */ export const createVnode = ( type , props ? , children = null , patchFlag = 0 , dynamicProps = null ) : VNode => { const shapeFlag = isString ( type ) ? ShapeFlags . ELEMENT : isObject ( type ) ? ShapeFlags . STATEFUL_COMPONENT : isFunction ( type ) ? ShapeFlags . FUNCTIONAL_COMPONENT : 0 ; const vnode = { [ ReactiveFlags . SKIP ] : true , type , props , key : props && props . key , children : null , component : null , el : null , target : null , shapeFlag , patchFlag , dynamicProps , dynamicChildren : null , } ; normalizeChildren ( vnode , children ) ; if ( currentBlock && patchFlag > 0 ) { currentBlock . push ( vnode ) ; } return vnode ; } ; function normalizeChildren ( vnode , children ) { let type = 0 ; if ( isArray ( children ) ) { type = ShapeFlags . ARRAY_CHILDREN ; } else if ( isFunction ( children ) ) { children = { default : children } ; type = ShapeFlags . SLOTS_CHILDREN ; } else { children = String ( children ) ; type = ShapeFlags . TEXT_CHILDREN ; } vnode . children = children as VNodeNormalizedChildren ; vnode . shapeFlag |= type ; }