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

@@ -34,7 +34,7 @@ function createRoot(options: Partial<RootNode> = {}): RootNode {
components: [],
directives: [],
hoists: [],
codegenNode: undefined,
codegenNode: createSimpleExpression(`null`, false),
loc: locStub,
...options
}

View File

@@ -4,7 +4,7 @@ import {
locStub,
Namespaces,
ElementTypes,
ElementCodegenNode
PlainElementCodegenNode
} from '../src'
import { CREATE_VNODE } from '../src/runtimeHelpers'
import { isString, PatchFlags, PatchFlagNames, isArray } from '@vue/shared'
@@ -39,7 +39,7 @@ export function createObjectMatcher(obj: any) {
}
export function createElementWithCodegen(
args: ElementCodegenNode['arguments']
args: PlainElementCodegenNode['arguments']
): ElementNode {
return {
type: NodeTypes.ELEMENT,

View File

@@ -14,7 +14,8 @@ import {
OPEN_BLOCK,
CREATE_BLOCK,
FRAGMENT,
RENDER_SLOT
RENDER_SLOT,
APPLY_DIRECTIVES
} from '../src/runtimeHelpers'
import { transformIf } from '../src/transforms/vIf'
import { transformFor } from '../src/transforms/vFor'
@@ -301,6 +302,28 @@ describe('compiler: transform', () => {
})
})
test('root element with custom directive', () => {
const ast = transformWithCodegen(`<div v-foo/>`)
expect(ast.codegenNode).toMatchObject({
type: NodeTypes.JS_SEQUENCE_EXPRESSION,
expressions: [
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: OPEN_BLOCK
},
{
type: NodeTypes.JS_CALL_EXPRESSION,
// should wrap applyDirectives() around createBlock()
callee: APPLY_DIRECTIVES,
arguments: [
{ callee: CREATE_BLOCK },
{ type: NodeTypes.JS_ARRAY_EXPRESSION }
]
}
]
})
})
test('single text', () => {
const ast = transformWithCodegen(`hello`)
expect(ast.codegenNode).toMatchObject({

View File

@@ -11,7 +11,7 @@ const _hoisted_1 = _createVNode(\\"p\\", null, [
return function render() {
with (this) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
_hoisted_1
@@ -29,7 +29,7 @@ const _hoisted_2 = _createVNode(\\"div\\")
return function render() {
with (this) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
_hoisted_1,
@@ -47,7 +47,7 @@ const _hoisted_1 = _createVNode(\\"span\\", { class: \\"inline\\" }, \\"hello\\"
return function render() {
with (this) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
_hoisted_1
@@ -64,7 +64,7 @@ const _hoisted_1 = { id: \\"foo\\" }
return function render() {
with (this) {
const { createVNode: _createVNode, applyDirectives: _applyDirectives, resolveDirective: _resolveDirective, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createVNode: _createVNode, applyDirectives: _applyDirectives, resolveDirective: _resolveDirective, createBlock: _createBlock, openBlock: _openBlock } = _Vue
const _directive_foo = _resolveDirective(\\"foo\\")
@@ -85,7 +85,7 @@ const _hoisted_1 = { id: \\"foo\\" }
return function render() {
with (this) {
const { toString: _toString, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { toString: _toString, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"div\\", _hoisted_1, _toString(hello), 1 /* TEXT */)
@@ -102,7 +102,7 @@ const _hoisted_1 = { id: \\"foo\\" }
return function render() {
with (this) {
const { resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { resolveComponent: _resolveComponent, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\")
@@ -120,7 +120,7 @@ exports[`compiler: hositStatic transform should NOT hoist components 1`] = `
return function render() {
with (this) {
const { resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { resolveComponent: _resolveComponent, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\")
@@ -136,7 +136,7 @@ exports[`compiler: hositStatic transform should NOT hoist element with dynamic p
return function render() {
with (this) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, [\\"id\\"])
@@ -150,7 +150,7 @@ exports[`compiler: hositStatic transform should NOT hoist root node 1`] = `
return function render() {
with (this) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\"))
}

View File

@@ -17,7 +17,7 @@ exports[`compiler: optimize interpolation consecutive text between elements 1`]
return function render() {
with (this) {
const { createVNode: _createVNode, toString: _toString, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createVNode: _createVNode, toString: _toString, createBlock: _createBlock, Fragment: _Fragment, openBlock: _openBlock } = _Vue
return (_openBlock(), _createBlock(_Fragment, null, [
_createVNode(\\"div\\"),
@@ -33,7 +33,7 @@ exports[`compiler: optimize interpolation consecutive text mixed with elements 1
return function render() {
with (this) {
const { createVNode: _createVNode, toString: _toString, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { createVNode: _createVNode, toString: _toString, createBlock: _createBlock, Fragment: _Fragment, openBlock: _openBlock } = _Vue
return (_openBlock(), _createBlock(_Fragment, null, [
_createVNode(\\"div\\"),

View File

@@ -132,6 +132,24 @@ return function render() {
}"
`;
exports[`compiler: v-for codegen v-for on element with custom directive 1`] = `
"const _Vue = Vue
return function render() {
with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode, applyDirectives: _applyDirectives, resolveDirective: _resolveDirective } = _Vue
const _directive_foo = _resolveDirective(\\"foo\\")
return (_openBlock(), _createBlock(_Fragment, null, _renderList(list, (i) => {
return (_openBlock(), _applyDirectives(_createBlock(\\"div\\", null, null, 32 /* NEED_PATCH */), [
[_directive_foo]
]))
}), 128 /* UNKEYED_FRAGMENT */))
}
}"
`;
exports[`compiler: v-for codegen v-if + v-for 1`] = `
"const _Vue = Vue

View File

@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`compiler: transform component slots dynamically named slots 1`] = `
"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue
"const { toString, resolveComponent, createVNode, createBlock, openBlock } = Vue
return function render() {
const _ctx = this
@@ -16,7 +16,7 @@ return function render() {
`;
exports[`compiler: transform component slots explicit default slot 1`] = `
"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue
"const { toString, resolveComponent, createVNode, createBlock, openBlock } = Vue
return function render() {
const _ctx = this
@@ -30,7 +30,7 @@ return function render() {
`;
exports[`compiler: transform component slots implicit default slot 1`] = `
"const { createVNode, resolveComponent, openBlock, createBlock } = Vue
"const { createVNode, resolveComponent, createBlock, openBlock } = Vue
return function render() {
const _ctx = this
@@ -46,7 +46,7 @@ return function render() {
`;
exports[`compiler: transform component slots named slot with v-for w/ prefixIdentifiers: true 1`] = `
"const { toString, resolveComponent, renderList, createSlots, createVNode, openBlock, createBlock } = Vue
"const { toString, resolveComponent, renderList, createSlots, createVNode, createBlock, openBlock } = Vue
return function render() {
const _ctx = this
@@ -64,7 +64,7 @@ return function render() {
`;
exports[`compiler: transform component slots named slot with v-if + prefixIdentifiers: true 1`] = `
"const { toString, resolveComponent, createSlots, createVNode, openBlock, createBlock } = Vue
"const { toString, resolveComponent, createSlots, createVNode, createBlock, openBlock } = Vue
return function render() {
const _ctx = this
@@ -86,7 +86,7 @@ exports[`compiler: transform component slots named slot with v-if + v-else-if +
return function render() {
with (this) {
const { resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\")
@@ -115,7 +115,7 @@ exports[`compiler: transform component slots named slot with v-if 1`] = `
return function render() {
with (this) {
const { resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\")
@@ -132,7 +132,7 @@ return function render() {
`;
exports[`compiler: transform component slots named slots 1`] = `
"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue
"const { toString, resolveComponent, createVNode, createBlock, openBlock } = Vue
return function render() {
const _ctx = this
@@ -147,7 +147,7 @@ return function render() {
`;
exports[`compiler: transform component slots nested slots scoping 1`] = `
"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue
"const { toString, resolveComponent, createVNode, createBlock, openBlock } = Vue
return function render() {
const _ctx = this

View File

@@ -1,10 +1,4 @@
import {
ElementNode,
CompilerOptions,
parse,
transform,
ErrorCodes
} from '../../src'
import { CompilerOptions, parse, transform, ErrorCodes } from '../../src'
import {
RESOLVE_COMPONENT,
CREATE_VNODE,
@@ -35,12 +29,14 @@ function parseWithElementTransform(
root: RootNode
node: CallExpression
} {
const ast = parse(template, options)
// wrap raw template in an extra div so that it doesn't get turned into a
// block as root node
const ast = parse(`<div>${template}</div>`, options)
transform(ast, {
nodeTransforms: [optimizeText, transformElement],
...options
})
const codegenNode = (ast.children[0] as ElementNode)
const codegenNode = (ast as any).children[0].children[0]
.codegenNode as CallExpression
expect(codegenNode.type).toBe(NodeTypes.JS_CALL_EXPRESSION)
return {

View File

@@ -22,7 +22,8 @@ import {
CREATE_BLOCK,
FRAGMENT,
RENDER_LIST,
RENDER_SLOT
RENDER_SLOT,
APPLY_DIRECTIVES
} from '../../src/runtimeHelpers'
import { PatchFlags } from '@vue/runtime-dom'
import { createObjectMatcher, genFlagText } from '../testUtils'
@@ -845,5 +846,28 @@ describe('compiler: v-for', () => {
})
expect(generate(root).code).toMatchSnapshot()
})
test('v-for on element with custom directive', () => {
const {
root,
node: { codegenNode }
} = parseWithForTransform('<div v-for="i in list" v-foo/>')
const { returns } = assertSharedCodegen(codegenNode, false, true)
expect(returns).toMatchObject({
type: NodeTypes.JS_SEQUENCE_EXPRESSION,
expressions: [
{ callee: OPEN_BLOCK },
// should wrap applyDirectives() around createBlock()
{
callee: APPLY_DIRECTIVES,
arguments: [
{ callee: CREATE_BLOCK },
{ type: NodeTypes.JS_ARRAY_EXPRESSION }
]
}
]
})
expect(generate(root).code).toMatchSnapshot()
})
})
})