fix(compiler): handle block nodes with custom directives + improve ast types

This commit is contained in:
Evan You
2019-10-08 10:50:00 -04:00
parent 1393ee52ca
commit 16da9ae89f
15 changed files with 200 additions and 157 deletions

View File

@@ -16,14 +16,17 @@ import {
JSChildNode,
createObjectExpression,
SlotOutletNode,
TemplateNode
TemplateNode,
BlockCodegenNode,
ElementCodegenNode,
SlotOutletCodegenNode,
ComponentCodegenNode
} from './ast'
import { parse } from 'acorn'
import { walk } from 'estree-walker'
import { TransformContext } from './transform'
import { OPEN_BLOCK, CREATE_BLOCK, MERGE_PROPS } from './runtimeHelpers'
import { OPEN_BLOCK, MERGE_PROPS, RENDER_SLOT } from './runtimeHelpers'
import { isString, isFunction } from '@vue/shared'
import { PropsExpression } from './transforms/transformElement'
// cache node requires
// lazy require dependencies so that they don't end up in rollup's dep graph
@@ -168,12 +171,12 @@ export function findProp(
}
export function createBlockExpression(
args: CallExpression['arguments'],
blockExp: BlockCodegenNode,
context: TransformContext
): SequenceExpression {
return createSequenceExpression([
createCallExpression(context.helper(OPEN_BLOCK)),
createCallExpression(context.helper(CREATE_BLOCK), args)
blockExp
])
}
@@ -191,12 +194,15 @@ export const isSlotOutlet = (
node.type === NodeTypes.ELEMENT && node.tagType === ElementTypes.SLOT
export function injectProp(
props: PropsExpression | undefined | 'null',
node: ElementCodegenNode | ComponentCodegenNode | SlotOutletCodegenNode,
prop: Property,
context: TransformContext
): ObjectExpression | CallExpression {
if (props == null || props === `null`) {
return createObjectExpression([prop])
) {
let propsWithInjection: ObjectExpression | CallExpression
const props =
node.callee === RENDER_SLOT ? node.arguments[2] : node.arguments[1]
if (props == null || isString(props)) {
propsWithInjection = createObjectExpression([prop])
} else if (props.type === NodeTypes.JS_CALL_EXPRESSION) {
// merged props... add ours
// only inject key to object literal if it's the first argument so that
@@ -207,17 +213,22 @@ export function injectProp(
} else {
props.arguments.unshift(createObjectExpression([prop]))
}
return props
propsWithInjection = props
} else if (props.type === NodeTypes.JS_OBJECT_EXPRESSION) {
props.properties.unshift(prop)
return props
propsWithInjection = props
} else {
// single v-bind with expression, return a merged replacement
return createCallExpression(context.helper(MERGE_PROPS), [
propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
createObjectExpression([prop]),
props
])
}
if (node.callee === RENDER_SLOT) {
node.arguments[2] = propsWithInjection
} else {
node.arguments[1] = propsWithInjection
}
}
export function toValidAssetId(