function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
    context.helper(WITH_CTX);
    const { children, loc } = node;
    const slotsProperties = [];
    const dynamicSlots = [];
    const buildDefaultSlotProperty = (props, children) => createObjectProperty(`default`, buildSlotFn(props, children, loc));
    // If the slot is inside a v-for or another v-slot, force it to be dynamic
    // since it likely uses a scope variable.
    let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
    // 1. Check for slot with slotProps on component itself.
    //    <Comp v-slot="{ prop }"/>
    const onComponentSlot = findDir(node, 'slot', true);
    if (onComponentSlot) {
        const { arg, exp } = onComponentSlot;
        if (arg && !isStaticExp(arg)) {
            hasDynamicSlots = true;
        }
        slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
    }
    // 2. Iterate through children and check for template slots
    //    <template v-slot:foo="{ prop }">
    let hasTemplateSlots = false;
    let hasNamedDefaultSlot = false;
    const implicitDefaultChildren = [];
    const seenSlotNames = new Set();
    for (let i = 0; i < children.length; i++) {
        const slotElement = children[i];
        let slotDir;
        if (!isTemplateNode(slotElement) ||
            !(slotDir = findDir(slotElement, 'slot', true))) {
            // not a <template v-slot>, skip.
            if (slotElement.type !== 3 /* COMMENT */) {
                implicitDefaultChildren.push(slotElement);
            }
            continue;
        }
        if (onComponentSlot) {
            // already has on-component slot - this is incorrect usage.
            context.onError(createCompilerError(36 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));
            break;
        }
        hasTemplateSlots = true;
        const { children: slotChildren, loc: slotLoc } = slotElement;
        const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
        // check if name is dynamic.
        let staticSlotName;
        if (isStaticExp(slotName)) {
            staticSlotName = slotName ? slotName.content : `default`;
        }
        else {
            hasDynamicSlots = true;
        }
        const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
        // check if this slot is conditional (v-if/v-for)
        let vIf;
        let vElse;
        let vFor;
        if ((vIf = findDir(slotElement, 'if'))) {
            hasDynamicSlots = true;
            dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));
        }
        else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {
            // find adjacent v-if
            let j = i;
            let prev;
            while (j--) {
                prev = children[j];
                if (prev.type !== 3 /* COMMENT */) {
                    break;
                }
            }
            if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
                // remove node
                children.splice(i, 1);
                i--;
                // attach this slot to previous conditional
                let conditional = dynamicSlots[dynamicSlots.length - 1];
                while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
                    conditional = conditional.alternate;
                }
                conditional.alternate = vElse.exp
                    ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)
                    : buildDynamicSlot(slotName, slotFunction);
            }
            else {
                context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));
            }
        }
        else if ((vFor = findDir(slotElement, 'for'))) {
            hasDynamicSlots = true;
            const parseResult = vFor.parseResult ||
                parseForExpression(vFor.exp, context);
            if (parseResult) {
                // Render the dynamic slots as an array and add it to the createSlot()
                // args. The runtime knows how to handle it appropriately.
                dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
                    parseResult.source,
                    createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)
                ]));
            }
            else {
                context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));
            }
        }
        else {
            // check duplicate static names
            if (staticSlotName) {
                if (seenSlotNames.has(staticSlotName)) {
                    context.onError(createCompilerError(37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));
                    continue;
                }
                seenSlotNames.add(staticSlotName);
                if (staticSlotName === 'default') {
                    hasNamedDefaultSlot = true;
                }
            }
            slotsProperties.push(createObjectProperty(slotName, slotFunction));
        }
    }
    if (!onComponentSlot) {
        if (!hasTemplateSlots) {
            // implicit default slot (on component)
            slotsProperties.push(buildDefaultSlotProperty(undefined, children));
        }
        else if (implicitDefaultChildren.length) {
            // implicit default slot (mixed with named slots)
            if (hasNamedDefaultSlot) {
                context.onError(createCompilerError(38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));
            }
            else {
                slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
            }
        }
    }
    const slotFlag = hasDynamicSlots
        ? 2 /* DYNAMIC */
        : hasForwardedSlots(node.children)
            ? 3 /* FORWARDED */
            : 1 /* STABLE */;
    let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 
    // 2 = compiled but dynamic = can skip normalization, but must run diff
    // 1 = compiled and static = can skip normalization AND diff as optimized
    createSimpleExpression(slotFlag + ( ` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);
    if (dynamicSlots.length) {
        slots = createCallExpression(context.helper(CREATE_SLOTS), [
            slots,
            createArrayExpression(dynamicSlots)
        ]);
    }
    return {
        slots,
        hasDynamicSlots
    };
}
// transformElement to build the slots object for a component.
transformElement to build the slots object for a component.
transformElement to build the slots object for a component .
function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
    context.helper(WITH_CTX);
    const { children, loc } = node;
    const slotsProperties = [];
    const dynamicSlots = [];
    const buildDefaultSlotProperty = (props, children) => createObjectProperty(`default`, buildSlotFn(props, children, loc));
    let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
    const onComponentSlot = findDir(node, 'slot', true);
    if (onComponentSlot) {
        const { arg, exp } = onComponentSlot;
        if (arg && !isStaticExp(arg)) {
            hasDynamicSlots = true;
        }
        slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
    }
    let hasTemplateSlots = false;
    let hasNamedDefaultSlot = false;
    const implicitDefaultChildren = [];
    const seenSlotNames = new Set();
    for (let i = 0; i < children.length; i++) {
        const slotElement = children[i];
        let slotDir;
        if (!isTemplateNode(slotElement) ||
            !(slotDir = findDir(slotElement, 'slot', true))) {
            if (slotElement.type !== 3 ) {
                implicitDefaultChildren.push(slotElement);
            }
            continue;
        }
        if (onComponentSlot) {
            context.onError(createCompilerError(36 , slotDir.loc));
            break;
        }
        hasTemplateSlots = true;
        const { children: slotChildren, loc: slotLoc } = slotElement;
        const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
        let staticSlotName;
        if (isStaticExp(slotName)) {
            staticSlotName = slotName ? slotName.content : `default`;
        }
        else {
            hasDynamicSlots = true;
        }
        const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
        let vIf;
        let vElse;
        let vFor;
        if ((vIf = findDir(slotElement, 'if'))) {
            hasDynamicSlots = true;
            dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));
        }
        else if ((vElse = findDir(slotElement, /^else(-if)?$/, true ))) {
            let j = i;
            let prev;
            while (j--) {
                prev = children[j];
                if (prev.type !== 3 ) {
                    break;
                }
            }
            if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
                children.splice(i, 1);
                i--;
                let conditional = dynamicSlots[dynamicSlots.length - 1];
                while (conditional.alternate.type === 19 ) {
                    conditional = conditional.alternate;
                }
                conditional.alternate = vElse.exp
                    ? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)
                    : buildDynamicSlot(slotName, slotFunction);
            }
            else {
                context.onError(createCompilerError(29 , vElse.loc));
            }
        }
        else if ((vFor = findDir(slotElement, 'for'))) {
            hasDynamicSlots = true;
            const parseResult = vFor.parseResult ||
                parseForExpression(vFor.exp, context);
            if (parseResult) {
                dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
                    parseResult.source,
                    createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true )
                ]));
            }
            else {
                context.onError(createCompilerError(31 , vFor.loc));
            }
        }
        else {
            if (staticSlotName) {
                if (seenSlotNames.has(staticSlotName)) {
                    context.onError(createCompilerError(37 , dirLoc));
                    continue;
                }
                seenSlotNames.add(staticSlotName);
                if (staticSlotName === 'default') {
                    hasNamedDefaultSlot = true;
                }
            }
            slotsProperties.push(createObjectProperty(slotName, slotFunction));
        }
    }
    if (!onComponentSlot) {
        if (!hasTemplateSlots) {
            slotsProperties.push(buildDefaultSlotProperty(undefined, children));
        }
        else if (implicitDefaultChildren.length) {
            if (hasNamedDefaultSlot) {
                context.onError(createCompilerError(38 , implicitDefaultChildren[0].loc));
            }
            else {
                slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
            }
        }
    }
    const slotFlag = hasDynamicSlots
        ? 2 
        : hasForwardedSlots(node.children)
            ? 3 
            : 1 ;
    let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`, 
    createSimpleExpression(slotFlag + ( ` /* ${slotFlagsText[slotFlag]} */` ), false))), loc);
    if (dynamicSlots.length) {
        slots = createCallExpression(context.helper(CREATE_SLOTS), [
            slots,
            createArrayExpression(dynamicSlots)
        ]);
    }
    return {
        slots,
        hasDynamicSlots
    };
}
function buildSlots ( node , context , buildSlotFn = buildClientSlotFn ) { context . helper ( WITH_CTX ) ; const { children , loc } = node ; const slotsProperties = [ ] ; const dynamicSlots = [ ] ; const buildDefaultSlotProperty = ( props , children ) => createObjectProperty ( ` ` , buildSlotFn ( props , children , loc ) ) ; let hasDynamicSlots = context . scopes . vSlot > 0 || context . scopes . vFor > 0 ; const onComponentSlot = findDir ( node , 'slot' , true ) ; if ( onComponentSlot ) { const { arg , exp } = onComponentSlot ; if ( arg && ! isStaticExp ( arg ) ) { hasDynamicSlots = true ; } slotsProperties . push ( createObjectProperty ( arg || createSimpleExpression ( 'default' , true ) , buildSlotFn ( exp , children , loc ) ) ) ; } let hasTemplateSlots = false ; let hasNamedDefaultSlot = false ; const implicitDefaultChildren = [ ] ; const seenSlotNames = new Set ( ) ; for ( let i = 0 ; i < children . length ; i ++ ) { const slotElement = children [ i ] ; let slotDir ; if ( ! isTemplateNode ( slotElement ) || ! ( slotDir = findDir ( slotElement , 'slot' , true ) ) ) { if ( slotElement . type !== 3 ) { implicitDefaultChildren . push ( slotElement ) ; } continue ; } if ( onComponentSlot ) { context . onError ( createCompilerError ( 36 , slotDir . loc ) ) ; break ; } hasTemplateSlots = true ; const { children : slotChildren , loc : slotLoc } = slotElement ; const { arg : slotName = createSimpleExpression ( ` ` , true ) , exp : slotProps , loc : dirLoc } = slotDir ; let staticSlotName ; if ( isStaticExp ( slotName ) ) { staticSlotName = slotName ? slotName . content : ` ` ; } else { hasDynamicSlots = true ; } const slotFunction = buildSlotFn ( slotProps , slotChildren , slotLoc ) ; let vIf ; let vElse ; let vFor ; if ( ( vIf = findDir ( slotElement , 'if' ) ) ) { hasDynamicSlots = true ; dynamicSlots . push ( createConditionalExpression ( vIf . exp , buildDynamicSlot ( slotName , slotFunction ) , defaultFallback ) ) ; } else if ( ( vElse = findDir ( slotElement , / ^else(-if)?$ / , true ) ) ) { let j = i ; let prev ; while ( j -- ) { prev = children [ j ] ; if ( prev . type !== 3 ) { break ; } } if ( prev && isTemplateNode ( prev ) && findDir ( prev , 'if' ) ) { children . splice ( i , 1 ) ; i -- ; let conditional = dynamicSlots [ dynamicSlots . length - 1 ] ; while ( conditional . alternate . type === 19 ) { conditional = conditional . alternate ; } conditional . alternate = vElse . exp ? createConditionalExpression ( vElse . exp , buildDynamicSlot ( slotName , slotFunction ) , defaultFallback ) : buildDynamicSlot ( slotName , slotFunction ) ; } else { context . onError ( createCompilerError ( 29 , vElse . loc ) ) ; } } else if ( ( vFor = findDir ( slotElement , 'for' ) ) ) { hasDynamicSlots = true ; const parseResult = vFor . parseResult || parseForExpression ( vFor . exp , context ) ; if ( parseResult ) { dynamicSlots . push ( createCallExpression ( context . helper ( RENDER_LIST ) , [ parseResult . source , createFunctionExpression ( createForLoopParams ( parseResult ) , buildDynamicSlot ( slotName , slotFunction ) , true ) ] ) ) ; } else { context . onError ( createCompilerError ( 31 , vFor . loc ) ) ; } } else { if ( staticSlotName ) { if ( seenSlotNames . has ( staticSlotName ) ) { context . onError ( createCompilerError ( 37 , dirLoc ) ) ; continue ; } seenSlotNames . add ( staticSlotName ) ; if ( staticSlotName === 'default' ) { hasNamedDefaultSlot = true ; } } slotsProperties . push ( createObjectProperty ( slotName , slotFunction ) ) ; } } if ( ! onComponentSlot ) { if ( ! hasTemplateSlots ) { slotsProperties . push ( buildDefaultSlotProperty ( undefined , children ) ) ; } else if ( implicitDefaultChildren . length ) { if ( hasNamedDefaultSlot ) { context . onError ( createCompilerError ( 38 , implicitDefaultChildren [ 0 ] . loc ) ) ; } else { slotsProperties . push ( buildDefaultSlotProperty ( undefined , implicitDefaultChildren ) ) ; } } } const slotFlag = hasDynamicSlots ? 2 : hasForwardedSlots ( node . children ) ? 3 : 1 ; let slots = createObjectExpression ( slotsProperties . concat ( createObjectProperty ( ` ` , createSimpleExpression ( slotFlag + ( ` ${ slotFlagsText [ slotFlag ] } ` ) , false ) ) ) , loc ) ; if ( dynamicSlots . length ) { slots = createCallExpression ( context . helper ( CREATE_SLOTS ) , [ slots , createArrayExpression ( dynamicSlots ) ] ) ; } return { slots , hasDynamicSlots } ; }
transformElement to build the slots object for a component.
transformElement to build the slots object for a component .
// If the slot is inside a v-for or another v-slot, force it to be dynamic // since it likely uses a scope variable. // 1. Check for slot with slotProps on component itself. //    <Comp v-slot="{ prop }"/> // 2. Iterate through children and check for template slots //    <template v-slot:foo="{ prop }"> // not a <template v-slot>, skip. /* COMMENT */ // already has on-component slot - this is incorrect usage. /* X_V_SLOT_MIXED_SLOT_USAGE */ // check if name is dynamic. // check if this slot is conditional (v-if/v-for) /* allowEmpty */ // find adjacent v-if /* COMMENT */ // remove node // attach this slot to previous conditional /* JS_CONDITIONAL_EXPRESSION */ /* X_V_ELSE_NO_ADJACENT_IF */ // Render the dynamic slots as an array and add it to the createSlot() // args. The runtime knows how to handle it appropriately. /* force newline */ /* X_V_FOR_MALFORMED_EXPRESSION */ // check duplicate static names /* X_V_SLOT_DUPLICATE_SLOT_NAMES */ // implicit default slot (on component) // implicit default slot (mixed with named slots) /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */ /* DYNAMIC */ /* FORWARDED */ /* STABLE */ // 2 = compiled but dynamic = can skip normalization, but must run diff // 1 = compiled and static = can skip normalization AND diff as optimized