test: test updates for d40c642

This commit is contained in:
Evan You 2020-02-11 18:40:21 -05:00
parent e3988b40d8
commit e861c6da90
37 changed files with 1261 additions and 1324 deletions

View File

@ -19,7 +19,7 @@ module.exports = {
'!packages/template-explorer/**', '!packages/template-explorer/**',
'!packages/size-check/**' '!packages/size-check/**'
], ],
watchPathIgnorePatterns: ['/node_modules/'], watchPathIgnorePatterns: ['/node_modules/', '/dist/', '/.git/'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'], moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
moduleNameMapper: { moduleNameMapper: {
'^@vue/(.*?)$': '<rootDir>/packages/$1/src', '^@vue/(.*?)$': '<rootDir>/packages/$1/src',

View File

@ -59,15 +59,6 @@ return function render(_ctx, _cache) {
}" }"
`; `;
exports[`compiler: codegen SequenceExpression 1`] = `
"
return function render(_ctx, _cache) {
with (this) {
return (foo, bar(baz))
}
}"
`;
exports[`compiler: codegen assets + temps 1`] = ` exports[`compiler: codegen assets + temps 1`] = `
" "
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
@ -106,7 +97,7 @@ exports[`compiler: codegen forNode 1`] = `
" "
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
return (foo, bar) return (_openBlock(true), _createBlock(_Fragment, null, _renderList(), 1))
} }
}" }"
`; `;
@ -147,7 +138,9 @@ exports[`compiler: codegen ifNode 1`] = `
" "
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
return (foo, bar) return foo
? bar
: baz
} }
}" }"
`; `;

View File

@ -12,9 +12,9 @@ return function render(_ctx, _cache) {
class: bar.baz class: bar.baz
}, [ }, [
_createTextVNode(_toDisplayString(world.burn()) + \\" \\", 1 /* TEXT */), _createTextVNode(_toDisplayString(world.burn()) + \\" \\", 1 /* TEXT */),
(_openBlock(), ok ok
? _createBlock(\\"div\\", { key: 0 }, \\"yes\\") ? (_openBlock(), _createBlock(\\"div\\", { key: 0 }, \\"yes\\"))
: _createBlock(_Fragment, { key: 1 }, [\\"no\\"])), : (_openBlock(), _createBlock(_Fragment, { key: 1 }, [\\"no\\"])),
(_openBlock(true), _createBlock(_Fragment, null, _renderList(list, (value, index) => { (_openBlock(true), _createBlock(_Fragment, null, _renderList(list, (value, index) => {
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"span\\", null, _toDisplayString(value + index), 1 /* TEXT */) _createVNode(\\"span\\", null, _toDisplayString(value + index), 1 /* TEXT */)
@ -34,9 +34,9 @@ return function render(_ctx, _cache) {
class: _ctx.bar.baz class: _ctx.bar.baz
}, [ }, [
_createTextVNode(_toDisplayString(_ctx.world.burn()) + \\" \\", 1 /* TEXT */), _createTextVNode(_toDisplayString(_ctx.world.burn()) + \\" \\", 1 /* TEXT */),
(_openBlock(), (_ctx.ok) (_ctx.ok)
? _createBlock(\\"div\\", { key: 0 }, \\"yes\\") ? (_openBlock(), _createBlock(\\"div\\", { key: 0 }, \\"yes\\"))
: _createBlock(_Fragment, { key: 1 }, [\\"no\\"])), : (_openBlock(), _createBlock(_Fragment, { key: 1 }, [\\"no\\"])),
(_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.list, (value, index) => { (_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.list, (value, index) => {
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"span\\", null, _toDisplayString(value + index), 1 /* TEXT */) _createVNode(\\"span\\", null, _toDisplayString(value + index), 1 /* TEXT */)
@ -55,9 +55,9 @@ export function render(_ctx, _cache) {
class: _ctx.bar.baz class: _ctx.bar.baz
}, [ }, [
_createTextVNode(_toDisplayString(_ctx.world.burn()) + \\" \\", 1 /* TEXT */), _createTextVNode(_toDisplayString(_ctx.world.burn()) + \\" \\", 1 /* TEXT */),
(_openBlock(), (_ctx.ok) (_ctx.ok)
? _createBlock(\\"div\\", { key: 0 }, \\"yes\\") ? (_openBlock(), _createBlock(\\"div\\", { key: 0 }, \\"yes\\"))
: _createBlock(_Fragment, { key: 1 }, [\\"no\\"])), : (_openBlock(), _createBlock(_Fragment, { key: 1 }, [\\"no\\"])),
(_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.list, (value, index) => { (_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.list, (value, index) => {
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"span\\", null, _toDisplayString(value + index), 1 /* TEXT */) _createVNode(\\"span\\", null, _toDisplayString(value + index), 1 /* TEXT */)

View File

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`scopeId compiler support should push scopeId for hoisted nodes 1`] = ` exports[`scopeId compiler support should push scopeId for hoisted nodes 1`] = `
"import { createVNode as _createVNode, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, createBlock as _createBlock, openBlock as _openBlock, withScopeId as _withScopeId, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \\"vue\\" "import { createVNode as _createVNode, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \\"vue\\"
const _withId = _withScopeId(\\"test\\") const _withId = _withScopeId(\\"test\\")
_pushScopeId(\\"test\\") _pushScopeId(\\"test\\")
@ -19,7 +19,7 @@ export const render = _withId(function render(_ctx, _cache) {
`; `;
exports[`scopeId compiler support should wrap default slot 1`] = ` exports[`scopeId compiler support should wrap default slot 1`] = `
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, createBlock as _createBlock, openBlock as _openBlock, withScopeId as _withScopeId } from \\"vue\\" "import { createVNode as _createVNode, resolveComponent as _resolveComponent, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
const _withId = _withScopeId(\\"test\\") const _withId = _withScopeId(\\"test\\")
export const render = _withId(function render(_ctx, _cache) { export const render = _withId(function render(_ctx, _cache) {
@ -35,7 +35,7 @@ export const render = _withId(function render(_ctx, _cache) {
`; `;
exports[`scopeId compiler support should wrap dynamic slots 1`] = ` exports[`scopeId compiler support should wrap dynamic slots 1`] = `
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, renderList as _renderList, createSlots as _createSlots, createBlock as _createBlock, openBlock as _openBlock, withScopeId as _withScopeId } from \\"vue\\" "import { createVNode as _createVNode, resolveComponent as _resolveComponent, renderList as _renderList, createSlots as _createSlots, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
const _withId = _withScopeId(\\"test\\") const _withId = _withScopeId(\\"test\\")
export const render = _withId(function render(_ctx, _cache) { export const render = _withId(function render(_ctx, _cache) {
@ -63,7 +63,7 @@ export const render = _withId(function render(_ctx, _cache) {
`; `;
exports[`scopeId compiler support should wrap named slots 1`] = ` exports[`scopeId compiler support should wrap named slots 1`] = `
"import { toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, createVNode as _createVNode, resolveComponent as _resolveComponent, createBlock as _createBlock, openBlock as _openBlock, withScopeId as _withScopeId } from \\"vue\\" "import { toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, createVNode as _createVNode, resolveComponent as _resolveComponent, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
const _withId = _withScopeId(\\"test\\") const _withId = _withScopeId(\\"test\\")
export const render = _withId(function render(_ctx, _cache) { export const render = _withId(function render(_ctx, _cache) {
@ -82,7 +82,7 @@ export const render = _withId(function render(_ctx, _cache) {
`; `;
exports[`scopeId compiler support should wrap render function 1`] = ` exports[`scopeId compiler support should wrap render function 1`] = `
"import { createVNode as _createVNode, createBlock as _createBlock, openBlock as _openBlock, withScopeId as _withScopeId } from \\"vue\\" "import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
const _withId = _withScopeId(\\"test\\") const _withId = _withScopeId(\\"test\\")
export const render = _withId(function render(_ctx, _cache) { export const render = _withId(function render(_ctx, _cache) {

View File

@ -9,16 +9,18 @@ import {
createArrayExpression, createArrayExpression,
createCompoundExpression, createCompoundExpression,
createInterpolation, createInterpolation,
createSequenceExpression,
createCallExpression, createCallExpression,
createConditionalExpression, createConditionalExpression,
IfCodegenNode,
ForCodegenNode, ForCodegenNode,
createCacheExpression, createCacheExpression,
createTemplateLiteral, createTemplateLiteral,
createBlockStatement, createBlockStatement,
createIfStatement, createIfStatement,
createAssignmentExpression createAssignmentExpression,
IfConditionalExpression,
createVNodeCall,
VNodeCall,
DirectiveArguments
} from '../src' } from '../src'
import { import {
CREATE_VNODE, CREATE_VNODE,
@ -26,7 +28,9 @@ import {
RESOLVE_DIRECTIVE, RESOLVE_DIRECTIVE,
helperNameMap, helperNameMap,
RESOLVE_COMPONENT, RESOLVE_COMPONENT,
CREATE_COMMENT CREATE_COMMENT,
FRAGMENT,
RENDER_LIST
} from '../src/runtimeHelpers' } from '../src/runtimeHelpers'
import { createElementWithCodegen } from './testUtils' import { createElementWithCodegen } from './testUtils'
import { PatchFlags } from '@vue/shared' import { PatchFlags } from '@vue/shared'
@ -251,14 +255,15 @@ describe('compiler: codegen', () => {
type: NodeTypes.IF, type: NodeTypes.IF,
loc: locStub, loc: locStub,
branches: [], branches: [],
codegenNode: createSequenceExpression([ codegenNode: createConditionalExpression(
createSimpleExpression('foo', false), createSimpleExpression('foo', false),
createSimpleExpression('bar', false) createSimpleExpression('bar', false),
]) as IfCodegenNode createSimpleExpression('baz', false)
) as IfConditionalExpression
} }
}) })
) )
expect(code).toMatch(`return (foo, bar)`) expect(code).toMatch(/return foo\s+\? bar\s+: baz/)
expect(code).toMatchSnapshot() expect(code).toMatchSnapshot()
}) })
@ -274,21 +279,29 @@ describe('compiler: codegen', () => {
objectIndexAlias: undefined, objectIndexAlias: undefined,
children: [], children: [],
parseResult: {} as any, parseResult: {} as any,
codegenNode: createSequenceExpression([ codegenNode: {
createSimpleExpression('foo', false), type: NodeTypes.VNODE_CALL,
createSimpleExpression('bar', false) tag: FRAGMENT,
]) as ForCodegenNode isBlock: true,
isForBlock: true,
props: undefined,
children: createCallExpression(RENDER_LIST),
patchFlag: '1',
dynamicProps: undefined,
directives: undefined,
loc: locStub
} as ForCodegenNode
} }
}) })
) )
expect(code).toMatch(`return (foo, bar)`) expect(code).toMatch(`openBlock(true)`)
expect(code).toMatchSnapshot() expect(code).toMatchSnapshot()
}) })
test('Element (callExpression + objectExpression + TemplateChildNode[])', () => { test('Element (callExpression + objectExpression + TemplateChildNode[])', () => {
const { code } = generate( const { code } = generate(
createRoot({ createRoot({
codegenNode: createElementWithCodegen([ codegenNode: createElementWithCodegen(
// string // string
`"div"`, `"div"`,
// ObjectExpression // ObjectExpression
@ -319,7 +332,7 @@ describe('compiler: codegen', () => {
), ),
// ChildNode[] // ChildNode[]
[ [
createElementWithCodegen([ createElementWithCodegen(
`"p"`, `"p"`,
createObjectExpression( createObjectExpression(
[ [
@ -331,11 +344,11 @@ describe('compiler: codegen', () => {
], ],
locStub locStub
) )
]) )
], ],
// flag // flag
PatchFlags.FULL_PROPS + '' PatchFlags.FULL_PROPS + ''
]) )
}) })
) )
expect(code).toMatch(` expect(code).toMatch(`
@ -365,19 +378,6 @@ describe('compiler: codegen', () => {
expect(code).toMatchSnapshot() expect(code).toMatchSnapshot()
}) })
test('SequenceExpression', () => {
const { code } = generate(
createRoot({
codegenNode: createSequenceExpression([
createSimpleExpression(`foo`, false),
createCallExpression(`bar`, [`baz`])
])
})
)
expect(code).toMatch(`return (foo, bar(baz))`)
expect(code).toMatchSnapshot()
})
test('ConditionalExpression', () => { test('ConditionalExpression', () => {
const { code } = generate( const { code } = generate(
createRoot({ createRoot({
@ -595,4 +595,149 @@ describe('compiler: codegen', () => {
}" }"
`) `)
}) })
describe('VNodeCall', () => {
function genCode(node: VNodeCall) {
return generate(
createRoot({
codegenNode: node
})
).code.match(/with \(this\) \{\s+([^]+)\s+\}\s+\}$/)![1]
}
const mockProps = createObjectExpression([
createObjectProperty(`foo`, createSimpleExpression(`bar`, true))
])
const mockChildren = createCompoundExpression(['children'])
const mockDirs = createArrayExpression([
createArrayExpression([`foo`, createSimpleExpression(`bar`, false)])
]) as DirectiveArguments
test('tag only', () => {
expect(genCode(createVNodeCall(null, `"div"`))).toMatchInlineSnapshot(`
"return _createVNode(\\"div\\")
"
`)
expect(genCode(createVNodeCall(null, FRAGMENT))).toMatchInlineSnapshot(`
"return _createVNode(_Fragment)
"
`)
})
test('with props', () => {
expect(genCode(createVNodeCall(null, `"div"`, mockProps)))
.toMatchInlineSnapshot(`
"return _createVNode(\\"div\\", { foo: \\"bar\\" })
"
`)
})
test('with children, no props', () => {
expect(genCode(createVNodeCall(null, `"div"`, undefined, mockChildren)))
.toMatchInlineSnapshot(`
"return _createVNode(\\"div\\", null, children)
"
`)
})
test('with children + props', () => {
expect(genCode(createVNodeCall(null, `"div"`, mockProps, mockChildren)))
.toMatchInlineSnapshot(`
"return _createVNode(\\"div\\", { foo: \\"bar\\" }, children)
"
`)
})
test('with patchFlag and no children/props', () => {
expect(genCode(createVNodeCall(null, `"div"`, undefined, undefined, '1')))
.toMatchInlineSnapshot(`
"return _createVNode(\\"div\\", null, null, 1)
"
`)
})
test('as block', () => {
expect(
genCode(
createVNodeCall(
null,
`"div"`,
mockProps,
mockChildren,
undefined,
undefined,
undefined,
true
)
)
).toMatchInlineSnapshot(`
"return (_openBlock(), _createBlock(\\"div\\", { foo: \\"bar\\" }, children))
"
`)
})
test('as for block', () => {
expect(
genCode(
createVNodeCall(
null,
`"div"`,
mockProps,
mockChildren,
undefined,
undefined,
undefined,
true,
true
)
)
).toMatchInlineSnapshot(`
"return (_openBlock(true), _createBlock(\\"div\\", { foo: \\"bar\\" }, children))
"
`)
})
test('with directives', () => {
expect(
genCode(
createVNodeCall(
null,
`"div"`,
mockProps,
mockChildren,
undefined,
undefined,
mockDirs
)
)
).toMatchInlineSnapshot(`
"return _withDirectives(_createVNode(\\"div\\", { foo: \\"bar\\" }, children), [
[foo, bar]
])
"
`)
})
test('block + directives', () => {
expect(
genCode(
createVNodeCall(
null,
`"div"`,
mockProps,
mockChildren,
undefined,
undefined,
mockDirs,
true
)
)
).toMatchInlineSnapshot(`
"return _withDirectives((_openBlock(), _createBlock(\\"div\\", { foo: \\"bar\\" }, children)), [
[foo, bar]
])
"
`)
})
})
}) })

View File

@ -4,9 +4,8 @@ import {
locStub, locStub,
Namespaces, Namespaces,
ElementTypes, ElementTypes,
PlainElementCodegenNode VNodeCall
} from '../src' } from '../src'
import { CREATE_VNODE } from '../src/runtimeHelpers'
import { isString, PatchFlags, PatchFlagNames, isArray } from '@vue/shared' import { isString, PatchFlags, PatchFlagNames, isArray } from '@vue/shared'
const leadingBracketRE = /^\[/ const leadingBracketRE = /^\[/
@ -39,7 +38,11 @@ export function createObjectMatcher(obj: Record<string, any>) {
} }
export function createElementWithCodegen( export function createElementWithCodegen(
args: PlainElementCodegenNode['arguments'] tag: VNodeCall['tag'],
props?: VNodeCall['props'],
children?: VNodeCall['children'],
patchFlag?: VNodeCall['patchFlag'],
dynamicProps?: VNodeCall['dynamicProps']
): ElementNode { ): ElementNode {
return { return {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
@ -51,10 +54,16 @@ export function createElementWithCodegen(
props: [], props: [],
children: [], children: [],
codegenNode: { codegenNode: {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
loc: locStub, tag,
callee: CREATE_VNODE, props,
arguments: args children,
patchFlag,
dynamicProps,
directives: undefined,
isBlock: false,
isForBlock: false,
loc: locStub
} }
} }
} }

View File

@ -4,16 +4,14 @@ import {
ElementNode, ElementNode,
NodeTypes, NodeTypes,
DirectiveNode, DirectiveNode,
ExpressionNode ExpressionNode,
VNodeCall
} from '../src/ast' } from '../src/ast'
import { ErrorCodes, createCompilerError } from '../src/errors' import { ErrorCodes, createCompilerError } from '../src/errors'
import { import {
TO_DISPLAY_STRING, TO_DISPLAY_STRING,
OPEN_BLOCK,
CREATE_BLOCK,
FRAGMENT, FRAGMENT,
RENDER_SLOT, RENDER_SLOT,
WITH_DIRECTIVES,
CREATE_COMMENT CREATE_COMMENT
} from '../src/runtimeHelpers' } from '../src/runtimeHelpers'
import { transformIf } from '../src/transforms/vIf' import { transformIf } from '../src/transforms/vIf'
@ -251,20 +249,19 @@ describe('compiler: transform', () => {
return ast return ast
} }
function createBlockMatcher(args: any[]) { function createBlockMatcher(
tag: VNodeCall['tag'],
props?: VNodeCall['props'],
children?: VNodeCall['children'],
patchFlag?: VNodeCall['patchFlag']
) {
return { return {
type: NodeTypes.JS_SEQUENCE_EXPRESSION, type: NodeTypes.VNODE_CALL,
expressions: [ isBlock: true,
{ tag,
type: NodeTypes.JS_CALL_EXPRESSION, props,
callee: OPEN_BLOCK children,
}, patchFlag
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: CREATE_BLOCK,
arguments: args
}
]
} }
} }
@ -285,7 +282,7 @@ describe('compiler: transform', () => {
test('single element', () => { test('single element', () => {
const ast = transformWithCodegen(`<div/>`) const ast = transformWithCodegen(`<div/>`)
expect(ast.codegenNode).toMatchObject(createBlockMatcher([`"div"`])) expect(ast.codegenNode).toMatchObject(createBlockMatcher(`"div"`))
}) })
test('root v-if', () => { test('root v-if', () => {
@ -305,22 +302,8 @@ describe('compiler: transform', () => {
test('root element with custom directive', () => { test('root element with custom directive', () => {
const ast = transformWithCodegen(`<div v-foo/>`) const ast = transformWithCodegen(`<div v-foo/>`)
expect(ast.codegenNode).toMatchObject({ expect(ast.codegenNode).toMatchObject({
type: NodeTypes.JS_SEQUENCE_EXPRESSION, type: NodeTypes.VNODE_CALL,
expressions: [ directives: { type: NodeTypes.JS_ARRAY_EXPRESSION }
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: OPEN_BLOCK
},
{
type: NodeTypes.JS_CALL_EXPRESSION,
// should wrap withDirectives() around createBlock()
callee: WITH_DIRECTIVES,
arguments: [
{ callee: CREATE_BLOCK },
{ type: NodeTypes.JS_ARRAY_EXPRESSION }
]
}
]
}) })
}) })
@ -348,15 +331,15 @@ describe('compiler: transform', () => {
test('multiple children', () => { test('multiple children', () => {
const ast = transformWithCodegen(`<div/><div/>`) const ast = transformWithCodegen(`<div/><div/>`)
expect(ast.codegenNode).toMatchObject( expect(ast.codegenNode).toMatchObject(
createBlockMatcher([ createBlockMatcher(
FRAGMENT, FRAGMENT,
`null`, undefined,
[ [
{ type: NodeTypes.ELEMENT, tag: `div` }, { type: NodeTypes.ELEMENT, tag: `div` },
{ type: NodeTypes.ELEMENT, tag: `div` } { type: NodeTypes.ELEMENT, tag: `div` }
], ] as any,
genFlagText(PatchFlags.STABLE_FRAGMENT) genFlagText(PatchFlags.STABLE_FRAGMENT)
]) )
) )
}) })
}) })

View File

@ -8,7 +8,7 @@ const _hoisted_1 = _createVNode(\\"div\\", { key: \\"foo\\" })
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_hoisted_1 _hoisted_1
@ -28,7 +28,7 @@ const _hoisted_1 = _createVNode(\\"p\\", null, [
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_hoisted_1 _hoisted_1
@ -47,7 +47,7 @@ const _hoisted_1 = _createVNode(\\"div\\", null, [
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createCommentVNode: _createCommentVNode, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { createCommentVNode: _createCommentVNode, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_hoisted_1 _hoisted_1
@ -65,7 +65,7 @@ const _hoisted_2 = _createVNode(\\"div\\")
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_hoisted_1, _hoisted_1,
@ -83,7 +83,7 @@ const _hoisted_1 = _createVNode(\\"span\\", { class: \\"inline\\" }, \\"hello\\"
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_hoisted_1 _hoisted_1
@ -100,7 +100,7 @@ const _hoisted_1 = { id: \\"foo\\" }
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, withDirectives: _withDirectives, resolveDirective: _resolveDirective, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { resolveDirective: _resolveDirective, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _directive_foo = _resolveDirective(\\"foo\\") const _directive_foo = _resolveDirective(\\"foo\\")
@ -121,7 +121,7 @@ const _hoisted_1 = { id: \\"foo\\" }
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { toDisplayString: _toDisplayString, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { toDisplayString: _toDisplayString, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"div\\", _hoisted_1, _toDisplayString(hello), 1 /* TEXT */) _createVNode(\\"div\\", _hoisted_1, _toDisplayString(hello), 1 /* TEXT */)
@ -138,7 +138,7 @@ const _hoisted_1 = { id: \\"foo\\" }
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { resolveComponent: _resolveComponent, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\") const _component_Comp = _resolveComponent(\\"Comp\\")
@ -159,7 +159,7 @@ const _hoisted_1 = { class: { foo: true } }
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { toDisplayString: _toDisplayString, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { toDisplayString: _toDisplayString, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"span\\", _hoisted_1, _toDisplayString(_ctx.bar), 1 /* TEXT */) _createVNode(\\"span\\", _hoisted_1, _toDisplayString(_ctx.bar), 1 /* TEXT */)
@ -176,7 +176,7 @@ const _hoisted_1 = _createVNode(\\"span\\", null, \\"foo \\" + _toDisplayString(
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { toDisplayString: _toDisplayString, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { toDisplayString: _toDisplayString, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_hoisted_1 _hoisted_1
@ -193,7 +193,7 @@ const _hoisted_1 = _createVNode(\\"span\\", { foo: 0 }, _toDisplayString(1))
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { toDisplayString: _toDisplayString, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { toDisplayString: _toDisplayString, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_hoisted_1 _hoisted_1
@ -203,7 +203,7 @@ return function render(_ctx, _cache) {
`; `;
exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist elements with cached handlers 1`] = ` exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist elements with cached handlers 1`] = `
"import { createVNode as _createVNode, createBlock as _createBlock, openBlock as _openBlock } from \\"vue\\" "import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
export function render(_ctx, _cache) { export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
@ -221,7 +221,7 @@ exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist expr
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, toDisplayString: _toDisplayString, createVNode: _createVNode } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, toDisplayString: _toDisplayString, createVNode: _createVNode } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
(_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.list, (o) => { (_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.list, (o) => {
@ -239,7 +239,7 @@ exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist expr
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, resolveComponent: _resolveComponent, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\") const _component_Comp = _resolveComponent(\\"Comp\\")
@ -258,7 +258,7 @@ exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist expr
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, toDisplayString: _toDisplayString, createVNode: _createVNode } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, toDisplayString: _toDisplayString, createVNode: _createVNode } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
(_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.list, (o) => { (_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.list, (o) => {
@ -276,7 +276,7 @@ exports[`compiler: hoistStatic transform should NOT hoist components 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { resolveComponent: _resolveComponent, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\") const _component_Comp = _resolveComponent(\\"Comp\\")
@ -292,7 +292,7 @@ exports[`compiler: hoistStatic transform should NOT hoist element with dynamic k
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"div\\", { key: foo }) _createVNode(\\"div\\", { key: foo })
@ -306,7 +306,7 @@ exports[`compiler: hoistStatic transform should NOT hoist element with dynamic p
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, [\\"id\\"]) _createVNode(\\"div\\", { id: foo }, null, 8 /* PROPS */, [\\"id\\"])
@ -320,7 +320,7 @@ exports[`compiler: hoistStatic transform should NOT hoist element with dynamic r
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_createVNode(\\"div\\", { ref: foo }, null, 32 /* NEED_PATCH */) _createVNode(\\"div\\", { ref: foo }, null, 32 /* NEED_PATCH */)
@ -334,7 +334,7 @@ exports[`compiler: hoistStatic transform should NOT hoist root node 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\")) return (_openBlock(), _createBlock(\\"div\\"))
} }
@ -350,7 +350,7 @@ const _hoisted_2 = _createVNode(\\"span\\")
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
(_openBlock(true), _createBlock(_Fragment, null, _renderList(list, (i) => { (_openBlock(true), _createBlock(_Fragment, null, _renderList(list, (i) => {
@ -378,11 +378,11 @@ return function render(_ctx, _cache) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
(_openBlock(), ok ok
? _createBlock(\\"div\\", _hoisted_1, [ ? (_openBlock(), _createBlock(\\"div\\", _hoisted_1, [
_hoisted_2 _hoisted_2
]) ]))
: _createCommentVNode(\\"v-if\\", true)) : _createCommentVNode(\\"v-if\\", true)
])) ]))
} }
}" }"

View File

@ -5,7 +5,7 @@ exports[`compiler: transform text <template v-for> 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, createTextVNode: _createTextVNode } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createTextVNode: _createTextVNode } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(list, (i) => { return (_openBlock(true), _createBlock(_Fragment, null, _renderList(list, (i) => {
return (_openBlock(), _createBlock(_Fragment, null, [ return (_openBlock(), _createBlock(_Fragment, null, [
@ -33,7 +33,7 @@ exports[`compiler: transform text consecutive text between elements 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, createBlock: _createBlock, Fragment: _Fragment, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(_Fragment, null, [ return (_openBlock(), _createBlock(_Fragment, null, [
_createVNode(\\"div\\"), _createVNode(\\"div\\"),
@ -49,7 +49,7 @@ exports[`compiler: transform text consecutive text mixed with elements 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, createBlock: _createBlock, Fragment: _Fragment, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(_Fragment, null, [ return (_openBlock(), _createBlock(_Fragment, null, [
_createVNode(\\"div\\"), _createVNode(\\"div\\"),
@ -79,7 +79,7 @@ exports[`compiler: transform text text between elements (static) 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, createTextVNode: _createTextVNode, createBlock: _createBlock, Fragment: _Fragment, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, createTextVNode: _createTextVNode, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(_Fragment, null, [ return (_openBlock(), _createBlock(_Fragment, null, [
_createVNode(\\"div\\"), _createVNode(\\"div\\"),

View File

@ -5,7 +5,7 @@ exports[`compiler: v-for codegen basic v-for 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => { return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createBlock(\\"span\\")) return (_openBlock(), _createBlock(\\"span\\"))
@ -19,7 +19,7 @@ exports[`compiler: v-for codegen keyed template v-for 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => { return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createBlock(_Fragment, { key: item }, [ return (_openBlock(), _createBlock(_Fragment, { key: item }, [
@ -36,7 +36,7 @@ exports[`compiler: v-for codegen keyed v-for 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => { return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createBlock(\\"span\\", { key: item })) return (_openBlock(), _createBlock(\\"span\\", { key: item }))
@ -50,7 +50,7 @@ exports[`compiler: v-for codegen skipped key 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item, __, index) => { return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item, __, index) => {
return (_openBlock(), _createBlock(\\"span\\")) return (_openBlock(), _createBlock(\\"span\\"))
@ -64,7 +64,7 @@ exports[`compiler: v-for codegen skipped value & key 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (_, __, index) => { return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (_, __, index) => {
return (_openBlock(), _createBlock(\\"span\\")) return (_openBlock(), _createBlock(\\"span\\"))
@ -78,7 +78,7 @@ exports[`compiler: v-for codegen skipped value 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (_, key, index) => { return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (_, key, index) => {
return (_openBlock(), _createBlock(\\"span\\")) return (_openBlock(), _createBlock(\\"span\\"))
@ -92,7 +92,7 @@ exports[`compiler: v-for codegen template v-for 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => { return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createBlock(_Fragment, null, [ return (_openBlock(), _createBlock(_Fragment, null, [
@ -109,7 +109,7 @@ exports[`compiler: v-for codegen template v-for w/ <slot/> 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, renderSlot: _renderSlot } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, renderSlot: _renderSlot } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => { return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return _renderSlot($slots, \\"default\\") return _renderSlot($slots, \\"default\\")
@ -123,7 +123,7 @@ exports[`compiler: v-for codegen v-for on <slot/> 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, renderSlot: _renderSlot } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, renderSlot: _renderSlot } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => { return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return _renderSlot($slots, \\"default\\") return _renderSlot($slots, \\"default\\")
@ -137,14 +137,14 @@ exports[`compiler: v-for codegen v-for on element with custom directive 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode, withDirectives: _withDirectives, resolveDirective: _resolveDirective } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, resolveDirective: _resolveDirective, createVNode: _createVNode, withDirectives: _withDirectives } = _Vue
const _directive_foo = _resolveDirective(\\"foo\\") const _directive_foo = _resolveDirective(\\"foo\\")
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(list, (i) => { return (_openBlock(true), _createBlock(_Fragment, null, _renderList(list, (i) => {
return (_openBlock(), _withDirectives(_createBlock(\\"div\\", null, null, 32 /* NEED_PATCH */), [ return _withDirectives((_openBlock(), _createBlock(\\"div\\", null, null, 32 /* NEED_PATCH */)), [
[_directive_foo] [_directive_foo]
])) ])
}), 256 /* UNKEYED_FRAGMENT */)) }), 256 /* UNKEYED_FRAGMENT */))
} }
}" }"
@ -155,13 +155,13 @@ exports[`compiler: v-for codegen v-if + v-for 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode, createCommentVNode: _createCommentVNode } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode, createCommentVNode: _createCommentVNode } = _Vue
return (_openBlock(), ok return ok
? _createBlock(_Fragment, { key: 0 }, _renderList(list, (i) => { ? (_openBlock(true), _createBlock(_Fragment, { key: 0 }, _renderList(list, (i) => {
return (_openBlock(), _createBlock(\\"div\\")) return (_openBlock(), _createBlock(\\"div\\"))
}), 256 /* UNKEYED_FRAGMENT */) }), 256 /* UNKEYED_FRAGMENT */))
: _createCommentVNode(\\"v-if\\", true)) : _createCommentVNode(\\"v-if\\", true)
} }
}" }"
`; `;
@ -171,7 +171,7 @@ exports[`compiler: v-for codegen value + key + index 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode } = _Vue const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item, key, index) => { return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item, key, index) => {
return (_openBlock(), _createBlock(\\"span\\")) return (_openBlock(), _createBlock(\\"span\\"))

View File

@ -7,9 +7,9 @@ return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
return (_openBlock(), ok return ok
? _createBlock(\\"div\\", { key: 0 }) ? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))
: _createCommentVNode(\\"v-if\\", true)) : _createCommentVNode(\\"v-if\\", true)
} }
}" }"
`; `;
@ -19,15 +19,15 @@ exports[`compiler: v-if codegen template v-if 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, openBlock: _openBlock, Fragment: _Fragment, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue const { createVNode: _createVNode, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
return (_openBlock(), ok return ok
? _createBlock(_Fragment, { key: 0 }, [ ? (_openBlock(), _createBlock(_Fragment, { key: 0 }, [
_createVNode(\\"div\\"), _createVNode(\\"div\\"),
\\"hello\\", \\"hello\\",
_createVNode(\\"p\\") _createVNode(\\"p\\")
]) ]))
: _createCommentVNode(\\"v-if\\", true)) : _createCommentVNode(\\"v-if\\", true)
} }
}" }"
`; `;
@ -37,11 +37,11 @@ exports[`compiler: v-if codegen template v-if w/ single <slot/> child 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderSlot: _renderSlot, openBlock: _openBlock, createCommentVNode: _createCommentVNode } = _Vue const { renderSlot: _renderSlot, createCommentVNode: _createCommentVNode } = _Vue
return (_openBlock(), ok return ok
? _renderSlot($slots, \\"default\\", { key: 0 }) ? _renderSlot($slots, \\"default\\", { key: 0 })
: _createCommentVNode(\\"v-if\\", true)) : _createCommentVNode(\\"v-if\\", true)
} }
}" }"
`; `;
@ -53,9 +53,9 @@ return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
return (_openBlock(), ok return ok
? _createBlock(\\"div\\", { key: 0 }) ? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))
: _createBlock(\\"p\\", { key: 1 })) : (_openBlock(), _createBlock(\\"p\\", { key: 1 }))
} }
}" }"
`; `;
@ -67,11 +67,11 @@ return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue
return (_openBlock(), ok return ok
? _createBlock(\\"div\\", { key: 0 }) ? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))
: orNot : orNot
? _createBlock(\\"p\\", { key: 1 }) ? (_openBlock(), _createBlock(\\"p\\", { key: 1 }))
: _createBlock(_Fragment, { key: 2 }, [\\"fine\\"])) : (_openBlock(), _createBlock(_Fragment, { key: 2 }, [\\"fine\\"]))
} }
}" }"
`; `;
@ -83,11 +83,11 @@ return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
return (_openBlock(), ok return ok
? _createBlock(\\"div\\", { key: 0 }) ? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))
: orNot : orNot
? _createBlock(\\"p\\", { key: 1 }) ? (_openBlock(), _createBlock(\\"p\\", { key: 1 }))
: _createCommentVNode(\\"v-if\\", true)) : _createCommentVNode(\\"v-if\\", true)
} }
}" }"
`; `;
@ -97,11 +97,11 @@ exports[`compiler: v-if codegen v-if on <slot/> 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { renderSlot: _renderSlot, openBlock: _openBlock, createCommentVNode: _createCommentVNode } = _Vue const { renderSlot: _renderSlot, createCommentVNode: _createCommentVNode } = _Vue
return (_openBlock(), ok return ok
? _renderSlot($slots, \\"default\\", { key: 0 }) ? _renderSlot($slots, \\"default\\", { key: 0 })
: _createCommentVNode(\\"v-if\\", true)) : _createCommentVNode(\\"v-if\\", true)
} }
}" }"
`; `;
@ -113,9 +113,9 @@ return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
return (_openBlock(), ok return ok
? _createBlock(\\"div\\", { key: \\"some-key\\" }) ? (_openBlock(), _createBlock(\\"div\\", { key: \\"some-key\\" }))
: _createCommentVNode(\\"v-if\\", true)) : _createCommentVNode(\\"v-if\\", true)
} }
}" }"
`; `;

View File

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`compiler: transform v-model compound expression (with prefixIdentifiers) 1`] = ` exports[`compiler: transform v-model compound expression (with prefixIdentifiers) 1`] = `
"import { createVNode as _createVNode, createBlock as _createBlock, openBlock as _openBlock } from \\"vue\\" "import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
export function render(_ctx, _cache) { export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"input\\", { return (_openBlock(), _createBlock(\\"input\\", {
@ -16,7 +16,7 @@ exports[`compiler: transform v-model compound expression 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"input\\", { return (_openBlock(), _createBlock(\\"input\\", {
modelValue: model[index], modelValue: model[index],
@ -27,7 +27,7 @@ return function render(_ctx, _cache) {
`; `;
exports[`compiler: transform v-model simple exprssion (with prefixIdentifiers) 1`] = ` exports[`compiler: transform v-model simple exprssion (with prefixIdentifiers) 1`] = `
"import { createVNode as _createVNode, createBlock as _createBlock, openBlock as _openBlock } from \\"vue\\" "import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
export function render(_ctx, _cache) { export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"input\\", { return (_openBlock(), _createBlock(\\"input\\", {
@ -42,7 +42,7 @@ exports[`compiler: transform v-model simple exprssion 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"input\\", { return (_openBlock(), _createBlock(\\"input\\", {
modelValue: model, modelValue: model,
@ -57,7 +57,7 @@ exports[`compiler: transform v-model with argument 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"input\\", { return (_openBlock(), _createBlock(\\"input\\", {
value: model, value: model,
@ -68,7 +68,7 @@ return function render(_ctx, _cache) {
`; `;
exports[`compiler: transform v-model with dynamic argument (with prefixIdentifiers) 1`] = ` exports[`compiler: transform v-model with dynamic argument (with prefixIdentifiers) 1`] = `
"import { createVNode as _createVNode, createBlock as _createBlock, openBlock as _openBlock } from \\"vue\\" "import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
export function render(_ctx, _cache) { export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"input\\", { return (_openBlock(), _createBlock(\\"input\\", {
@ -83,7 +83,7 @@ exports[`compiler: transform v-model with dynamic argument 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"input\\", { return (_openBlock(), _createBlock(\\"input\\", {
[value]: model, [value]: model,

View File

@ -22,7 +22,7 @@ exports[`compiler: v-once transform on component 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { setBlockTracking: _setBlockTracking, resolveComponent: _resolveComponent, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { setBlockTracking: _setBlockTracking, resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\") const _component_Comp = _resolveComponent(\\"Comp\\")
@ -43,7 +43,7 @@ exports[`compiler: v-once transform on nested plain element 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { setBlockTracking: _setBlockTracking, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { setBlockTracking: _setBlockTracking, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_cache[1] || ( _cache[1] || (
@ -62,7 +62,7 @@ exports[`compiler: v-once transform on slot outlet 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { setBlockTracking: _setBlockTracking, renderSlot: _renderSlot, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { setBlockTracking: _setBlockTracking, renderSlot: _renderSlot, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_cache[1] || ( _cache[1] || (
@ -81,7 +81,7 @@ exports[`compiler: v-once transform with hoistStatic: true 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { setBlockTracking: _setBlockTracking, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { setBlockTracking: _setBlockTracking, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [ return (_openBlock(), _createBlock(\\"div\\", null, [
_cache[1] || ( _cache[1] || (

View File

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`compiler: transform component slots dynamically named slots 1`] = ` exports[`compiler: transform component slots dynamically named slots 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = Vue "const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
const _component_Comp = _resolveComponent(\\"Comp\\") const _component_Comp = _resolveComponent(\\"Comp\\")
@ -15,7 +15,7 @@ return function render(_ctx, _cache) {
`; `;
exports[`compiler: transform component slots implicit default slot 1`] = ` exports[`compiler: transform component slots implicit default slot 1`] = `
"const { createVNode: _createVNode, resolveComponent: _resolveComponent, createBlock: _createBlock, openBlock: _openBlock } = Vue "const { createVNode: _createVNode, resolveComponent: _resolveComponent, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
const _component_Comp = _resolveComponent(\\"Comp\\") const _component_Comp = _resolveComponent(\\"Comp\\")
@ -30,7 +30,7 @@ return function render(_ctx, _cache) {
`; `;
exports[`compiler: transform component slots named slot with v-for w/ prefixIdentifiers: true 1`] = ` exports[`compiler: transform component slots named slot with v-for w/ prefixIdentifiers: true 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, renderList: _renderList, createSlots: _createSlots, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = Vue "const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, renderList: _renderList, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
const _component_Comp = _resolveComponent(\\"Comp\\") const _component_Comp = _resolveComponent(\\"Comp\\")
@ -47,7 +47,7 @@ return function render(_ctx, _cache) {
`; `;
exports[`compiler: transform component slots named slot with v-if + prefixIdentifiers: true 1`] = ` exports[`compiler: transform component slots named slot with v-if + prefixIdentifiers: true 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = Vue "const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
const _component_Comp = _resolveComponent(\\"Comp\\") const _component_Comp = _resolveComponent(\\"Comp\\")
@ -68,7 +68,7 @@ exports[`compiler: transform component slots named slot with v-if + v-else-if +
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\") const _component_Comp = _resolveComponent(\\"Comp\\")
@ -97,7 +97,7 @@ exports[`compiler: transform component slots named slot with v-if 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { resolveComponent: _resolveComponent, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\") const _component_Comp = _resolveComponent(\\"Comp\\")
@ -114,7 +114,7 @@ return function render(_ctx, _cache) {
`; `;
exports[`compiler: transform component slots named slots 1`] = ` exports[`compiler: transform component slots named slots 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = Vue "const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
const _component_Comp = _resolveComponent(\\"Comp\\") const _component_Comp = _resolveComponent(\\"Comp\\")
@ -132,7 +132,7 @@ exports[`compiler: transform component slots named slots w/ implicit default slo
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, resolveComponent: _resolveComponent, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, resolveComponent: _resolveComponent, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\") const _component_Comp = _resolveComponent(\\"Comp\\")
@ -149,7 +149,7 @@ return function render(_ctx, _cache) {
`; `;
exports[`compiler: transform component slots nested slots scoping 1`] = ` exports[`compiler: transform component slots nested slots scoping 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = Vue "const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
const _component_Inner = _resolveComponent(\\"Inner\\") const _component_Inner = _resolveComponent(\\"Inner\\")
@ -172,7 +172,7 @@ return function render(_ctx, _cache) {
`; `;
exports[`compiler: transform component slots on-component default slot 1`] = ` exports[`compiler: transform component slots on-component default slot 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = Vue "const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
const _component_Comp = _resolveComponent(\\"Comp\\") const _component_Comp = _resolveComponent(\\"Comp\\")

View File

@ -3,17 +3,13 @@ import {
transform, transform,
NodeTypes, NodeTypes,
generate, generate,
CompilerOptions CompilerOptions,
VNodeCall,
IfNode,
ElementNode,
ForNode
} from '../../src' } from '../../src'
import { import { FRAGMENT, RENDER_LIST, CREATE_TEXT } from '../../src/runtimeHelpers'
OPEN_BLOCK,
CREATE_BLOCK,
CREATE_VNODE,
WITH_DIRECTIVES,
FRAGMENT,
RENDER_LIST,
CREATE_TEXT
} from '../../src/runtimeHelpers'
import { transformElement } from '../../src/transforms/transformElement' import { transformElement } from '../../src/transforms/transformElement'
import { transformExpression } from '../../src/transforms/transformExpression' import { transformExpression } from '../../src/transforms/transformExpression'
import { transformIf } from '../../src/transforms/vIf' import { transformIf } from '../../src/transforms/vIf'
@ -21,8 +17,8 @@ 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, genFlagText } from '../testUtils'
import { PatchFlags } from '@vue/shared'
import { transformText } from '../../src/transforms/transformText' import { transformText } from '../../src/transforms/transformText'
import { PatchFlags } from '@vue/shared'
function transformWithHoist(template: string, options: CompilerOptions = {}) { function transformWithHoist(template: string, options: CompilerOptions = {}) {
const ast = parse(template) const ast = parse(template)
@ -42,56 +38,43 @@ function transformWithHoist(template: string, options: CompilerOptions = {}) {
...options ...options
}) })
expect(ast.codegenNode).toMatchObject({ expect(ast.codegenNode).toMatchObject({
type: NodeTypes.JS_SEQUENCE_EXPRESSION, type: NodeTypes.VNODE_CALL,
expressions: [ isBlock: true
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: OPEN_BLOCK
},
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: CREATE_BLOCK
}
]
}) })
return { return ast
root: ast,
args: (ast.codegenNode as any).expressions[1].arguments
}
} }
describe('compiler: hoistStatic transform', () => { describe('compiler: hoistStatic transform', () => {
test('should NOT hoist root node', () => { test('should NOT hoist root node', () => {
// if the whole tree is static, the root still needs to be a block // if the whole tree is static, the root still needs to be a block
// so that it's patched in optimized mode to skip children // so that it's patched in optimized mode to skip children
const { root, args } = transformWithHoist(`<div/>`) const root = transformWithHoist(`<div/>`)
expect(root.hoists.length).toBe(0) expect(root.hoists.length).toBe(0)
expect(args).toEqual([`"div"`]) expect(root.codegenNode).toMatchObject({
tag: `"div"`
})
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
test('hoist simple element', () => { test('hoist simple element', () => {
const { root, args } = transformWithHoist( const root = transformWithHoist(
`<div><span class="inline">hello</span></div>` `<div><span class="inline">hello</span></div>`
) )
expect(root.hoists).toMatchObject([ expect(root.hoists).toMatchObject([
{ {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
callee: CREATE_VNODE, tag: `"span"`,
arguments: [ props: createObjectMatcher({ class: 'inline' }),
`"span"`, children: {
createObjectMatcher({ class: 'inline' }),
{
type: NodeTypes.TEXT, type: NodeTypes.TEXT,
content: `hello` content: `hello`
} }
]
} }
]) ])
expect(args).toMatchObject([ expect(root.codegenNode).toMatchObject({
`"div"`, tag: `"div"`,
`null`, props: undefined,
[ children: [
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
@ -100,29 +83,24 @@ describe('compiler: hoistStatic transform', () => {
} }
} }
] ]
]) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
test('hoist nested static tree', () => { test('hoist nested static tree', () => {
const { root, args } = transformWithHoist( const root = transformWithHoist(`<div><p><span/><span/></p></div>`)
`<div><p><span/><span/></p></div>`
)
expect(root.hoists).toMatchObject([ expect(root.hoists).toMatchObject([
{ {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
callee: CREATE_VNODE, tag: `"p"`,
arguments: [ props: undefined,
`"p"`, children: [
`null`,
[
{ type: NodeTypes.ELEMENT, tag: `span` }, { type: NodeTypes.ELEMENT, tag: `span` },
{ type: NodeTypes.ELEMENT, tag: `span` } { type: NodeTypes.ELEMENT, tag: `span` }
] ]
]
} }
]) ])
expect(args[2]).toMatchObject([ expect((root.codegenNode as VNodeCall).children).toMatchObject([
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
@ -135,21 +113,16 @@ describe('compiler: hoistStatic transform', () => {
}) })
test('hoist nested static tree with comments', () => { test('hoist nested static tree with comments', () => {
const { root, args } = transformWithHoist( const root = transformWithHoist(`<div><div><!--comment--></div></div>`)
`<div><div><!--comment--></div></div>`
)
expect(root.hoists).toMatchObject([ expect(root.hoists).toMatchObject([
{ {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
callee: CREATE_VNODE, tag: `"div"`,
arguments: [ props: undefined,
`"div"`, children: [{ type: NodeTypes.COMMENT, content: `comment` }]
`null`,
[{ type: NodeTypes.COMMENT, content: `comment` }]
]
} }
]) ])
expect(args[2]).toMatchObject([ expect((root.codegenNode as VNodeCall).children).toMatchObject([
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
@ -162,20 +135,18 @@ describe('compiler: hoistStatic transform', () => {
}) })
test('hoist siblings with common non-hoistable parent', () => { test('hoist siblings with common non-hoistable parent', () => {
const { root, args } = transformWithHoist(`<div><span/><div/></div>`) const root = transformWithHoist(`<div><span/><div/></div>`)
expect(root.hoists).toMatchObject([ expect(root.hoists).toMatchObject([
{ {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
callee: CREATE_VNODE, tag: `"span"`
arguments: [`"span"`]
}, },
{ {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
callee: CREATE_VNODE, tag: `"div"`
arguments: [`"div"`]
} }
]) ])
expect(args[2]).toMatchObject([ expect((root.codegenNode as VNodeCall).children).toMatchObject([
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
@ -195,14 +166,14 @@ describe('compiler: hoistStatic transform', () => {
}) })
test('should NOT hoist components', () => { test('should NOT hoist components', () => {
const { root, args } = transformWithHoist(`<div><Comp/></div>`) const root = transformWithHoist(`<div><Comp/></div>`)
expect(root.hoists.length).toBe(0) expect(root.hoists.length).toBe(0)
expect(args[2]).toMatchObject([ expect((root.codegenNode as VNodeCall).children).toMatchObject([
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
callee: CREATE_VNODE, type: NodeTypes.VNODE_CALL,
arguments: [`_component_Comp`] tag: `_component_Comp`
} }
} }
]) ])
@ -210,22 +181,20 @@ describe('compiler: hoistStatic transform', () => {
}) })
test('should NOT hoist element with dynamic props', () => { test('should NOT hoist element with dynamic props', () => {
const { root, args } = transformWithHoist(`<div><div :id="foo"/></div>`) const root = transformWithHoist(`<div><div :id="foo"/></div>`)
expect(root.hoists.length).toBe(0) expect(root.hoists.length).toBe(0)
expect(args[2]).toMatchObject([ expect((root.codegenNode as VNodeCall).children).toMatchObject([
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
callee: CREATE_VNODE, type: NodeTypes.VNODE_CALL,
arguments: [ tag: `"div"`,
`"div"`, props: createObjectMatcher({
createObjectMatcher({
id: `[foo]` id: `[foo]`
}), }),
`null`, children: undefined,
genFlagText(PatchFlags.PROPS), patchFlag: genFlagText(PatchFlags.PROPS),
`["id"]` dynamicProps: `["id"]`
]
} }
} }
]) ])
@ -233,19 +202,19 @@ describe('compiler: hoistStatic transform', () => {
}) })
test('hoist element with static key', () => { test('hoist element with static key', () => {
const { root, args } = transformWithHoist(`<div><div key="foo"/></div>`) const root = transformWithHoist(`<div><div key="foo"/></div>`)
expect(root.hoists.length).toBe(1) expect(root.hoists.length).toBe(1)
expect(root.hoists).toMatchObject([ expect(root.hoists).toMatchObject([
{ {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
callee: CREATE_VNODE, tag: `"div"`,
arguments: [`"div"`, createObjectMatcher({ key: 'foo' })] props: createObjectMatcher({ key: 'foo' })
} }
]) ])
expect(args).toMatchObject([ expect(root.codegenNode).toMatchObject({
`"div"`, tag: `"div"`,
`null`, props: undefined,
[ children: [
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
@ -254,24 +223,22 @@ describe('compiler: hoistStatic transform', () => {
} }
} }
] ]
]) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
test('should NOT hoist element with dynamic key', () => { test('should NOT hoist element with dynamic key', () => {
const { root, args } = transformWithHoist(`<div><div :key="foo"/></div>`) const root = transformWithHoist(`<div><div :key="foo"/></div>`)
expect(root.hoists.length).toBe(0) expect(root.hoists.length).toBe(0)
expect(args[2]).toMatchObject([ expect((root.codegenNode as VNodeCall).children).toMatchObject([
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
callee: CREATE_VNODE, type: NodeTypes.VNODE_CALL,
arguments: [ tag: `"div"`,
`"div"`, props: createObjectMatcher({
createObjectMatcher({
key: `[foo]` key: `[foo]`
}) })
]
} }
} }
]) ])
@ -279,21 +246,19 @@ describe('compiler: hoistStatic transform', () => {
}) })
test('should NOT hoist element with dynamic ref', () => { test('should NOT hoist element with dynamic ref', () => {
const { root, args } = transformWithHoist(`<div><div :ref="foo"/></div>`) const root = transformWithHoist(`<div><div :ref="foo"/></div>`)
expect(root.hoists.length).toBe(0) expect(root.hoists.length).toBe(0)
expect(args[2]).toMatchObject([ expect((root.codegenNode as VNodeCall).children).toMatchObject([
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
callee: CREATE_VNODE, type: NodeTypes.VNODE_CALL,
arguments: [ tag: `"div"`,
`"div"`, props: createObjectMatcher({
createObjectMatcher({
ref: `[foo]` ref: `[foo]`
}), }),
`null`, children: undefined,
genFlagText(PatchFlags.NEED_PATCH) patchFlag: genFlagText(PatchFlags.NEED_PATCH)
]
} }
} }
]) ])
@ -301,32 +266,23 @@ describe('compiler: hoistStatic transform', () => {
}) })
test('hoist static props for elements with directives', () => { test('hoist static props for elements with directives', () => {
const { root, args } = transformWithHoist( const root = transformWithHoist(`<div><div id="foo" v-foo/></div>`)
`<div><div id="foo" v-foo/></div>`
)
expect(root.hoists).toMatchObject([createObjectMatcher({ id: 'foo' })]) expect(root.hoists).toMatchObject([createObjectMatcher({ id: 'foo' })])
expect(args[2]).toMatchObject([ expect((root.codegenNode as VNodeCall).children).toMatchObject([
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
callee: WITH_DIRECTIVES, type: NodeTypes.VNODE_CALL,
arguments: [ tag: `"div"`,
{ props: {
callee: CREATE_VNODE,
arguments: [
`"div"`,
{
type: NodeTypes.SIMPLE_EXPRESSION, type: NodeTypes.SIMPLE_EXPRESSION,
content: `_hoisted_1` content: `_hoisted_1`
}, },
`null`, children: undefined,
genFlagText(PatchFlags.NEED_PATCH) patchFlag: genFlagText(PatchFlags.NEED_PATCH),
] directives: {
},
{
type: NodeTypes.JS_ARRAY_EXPRESSION type: NodeTypes.JS_ARRAY_EXPRESSION
} }
]
} }
} }
]) ])
@ -334,21 +290,19 @@ describe('compiler: hoistStatic transform', () => {
}) })
test('hoist static props for elements with dynamic text children', () => { test('hoist static props for elements with dynamic text children', () => {
const { root, args } = transformWithHoist( const root = transformWithHoist(
`<div><div id="foo">{{ hello }}</div></div>` `<div><div id="foo">{{ hello }}</div></div>`
) )
expect(root.hoists).toMatchObject([createObjectMatcher({ id: 'foo' })]) expect(root.hoists).toMatchObject([createObjectMatcher({ id: 'foo' })])
expect(args[2]).toMatchObject([ expect((root.codegenNode as VNodeCall).children).toMatchObject([
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
callee: CREATE_VNODE, type: NodeTypes.VNODE_CALL,
arguments: [ tag: `"div"`,
`"div"`, props: { content: `_hoisted_1` },
{ content: `_hoisted_1` }, children: { type: NodeTypes.INTERPOLATION },
{ type: NodeTypes.INTERPOLATION }, patchFlag: genFlagText(PatchFlags.TEXT)
genFlagText(PatchFlags.TEXT)
]
} }
} }
]) ])
@ -356,20 +310,16 @@ describe('compiler: hoistStatic transform', () => {
}) })
test('hoist static props for elements with unhoistable children', () => { test('hoist static props for elements with unhoistable children', () => {
const { root, args } = transformWithHoist( const root = transformWithHoist(`<div><div id="foo"><Comp/></div></div>`)
`<div><div id="foo"><Comp/></div></div>`
)
expect(root.hoists).toMatchObject([createObjectMatcher({ id: 'foo' })]) expect(root.hoists).toMatchObject([createObjectMatcher({ id: 'foo' })])
expect(args[2]).toMatchObject([ expect((root.codegenNode as VNodeCall).children).toMatchObject([
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
callee: CREATE_VNODE, type: NodeTypes.VNODE_CALL,
arguments: [ tag: `"div"`,
`"div"`, props: { content: `_hoisted_1` },
{ content: `_hoisted_1` }, children: [{ type: NodeTypes.ELEMENT, tag: `Comp` }]
[{ type: NodeTypes.ELEMENT, tag: `Comp` }]
]
} }
} }
]) ])
@ -377,7 +327,7 @@ describe('compiler: hoistStatic transform', () => {
}) })
test('should hoist v-if props/children if static', () => { test('should hoist v-if props/children if static', () => {
const { root, args } = transformWithHoist( const root = transformWithHoist(
`<div><div v-if="ok" id="foo"><span/></div></div>` `<div><div v-if="ok" id="foo"><span/></div></div>`
) )
expect(root.hoists).toMatchObject([ expect(root.hoists).toMatchObject([
@ -386,37 +336,31 @@ describe('compiler: hoistStatic transform', () => {
id: 'foo' id: 'foo'
}), }),
{ {
callee: CREATE_VNODE, type: NodeTypes.VNODE_CALL,
arguments: [`"span"`] tag: `"span"`
} }
]) ])
expect(args[2][0].codegenNode).toMatchObject({ expect(
type: NodeTypes.JS_SEQUENCE_EXPRESSION, ((root.children[0] as ElementNode).children[0] as IfNode).codegenNode
expressions: [ ).toMatchObject({
{ callee: OPEN_BLOCK },
{
type: NodeTypes.JS_CONDITIONAL_EXPRESSION, type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
consequent: { consequent: {
// blocks should NOT be hoisted // blocks should NOT be hoisted
callee: CREATE_BLOCK, type: NodeTypes.VNODE_CALL,
arguments: [ tag: `"div"`,
`"div"`, props: { content: `_hoisted_1` },
{ content: `_hoisted_1` }, children: [
[
{ {
codegenNode: { content: `_hoisted_2` } codegenNode: { content: `_hoisted_2` }
} }
] ]
]
} }
}
]
}) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
test('should hoist v-for children if static', () => { test('should hoist v-for children if static', () => {
const { root, args } = transformWithHoist( const root = transformWithHoist(
`<div><div v-for="i in list" id="foo"><span/></div></div>` `<div><div v-for="i in list" id="foo"><span/></div></div>`
) )
expect(root.hoists).toMatchObject([ expect(root.hoists).toMatchObject([
@ -424,54 +368,38 @@ describe('compiler: hoistStatic transform', () => {
id: 'foo' id: 'foo'
}), }),
{ {
callee: CREATE_VNODE, type: NodeTypes.VNODE_CALL,
arguments: [`"span"`] tag: `"span"`
} }
]) ])
const forBlockCodegen = args[2][0].codegenNode const forBlockCodegen = ((root.children[0] as ElementNode)
.children[0] as ForNode).codegenNode
expect(forBlockCodegen).toMatchObject({ expect(forBlockCodegen).toMatchObject({
type: NodeTypes.JS_SEQUENCE_EXPRESSION, type: NodeTypes.VNODE_CALL,
expressions: [ tag: FRAGMENT,
{ callee: OPEN_BLOCK }, props: undefined,
{ children: {
callee: CREATE_BLOCK,
arguments: [
FRAGMENT,
`null`,
{
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_LIST callee: RENDER_LIST
}, },
genFlagText(PatchFlags.UNKEYED_FRAGMENT) patchFlag: genFlagText(PatchFlags.UNKEYED_FRAGMENT)
]
}
]
}) })
const innerBlockCodegen = const innerBlockCodegen = forBlockCodegen!.children.arguments[1]
forBlockCodegen.expressions[1].arguments[2].arguments[1].returns expect(innerBlockCodegen.returns).toMatchObject({
expect(innerBlockCodegen).toMatchObject({ type: NodeTypes.VNODE_CALL,
type: NodeTypes.JS_SEQUENCE_EXPRESSION, tag: `"div"`,
expressions: [ props: { content: `_hoisted_1` },
{ callee: OPEN_BLOCK }, children: [
{
callee: CREATE_BLOCK,
arguments: [
`"div"`,
{ content: `_hoisted_1` },
[
{ {
codegenNode: { content: `_hoisted_2` } codegenNode: { content: `_hoisted_2` }
} }
] ]
]
}
]
}) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
test('hoist static text node between elements', () => { test('hoist static text node between elements', () => {
const { root } = transformWithHoist(`<div>static<div>static</div></div>`) const root = transformWithHoist(`<div>static<div>static</div></div>`)
expect(root.hoists).toMatchObject([ expect(root.hoists).toMatchObject([
{ {
callee: CREATE_TEXT, callee: CREATE_TEXT,
@ -483,14 +411,15 @@ describe('compiler: hoistStatic transform', () => {
] ]
}, },
{ {
callee: CREATE_VNODE type: NodeTypes.VNODE_CALL,
tag: `"div"`
} }
]) ])
}) })
describe('prefixIdentifiers', () => { describe('prefixIdentifiers', () => {
test('hoist nested static tree with static interpolation', () => { test('hoist nested static tree with static interpolation', () => {
const { root, args } = transformWithHoist( const root = transformWithHoist(
`<div><span>foo {{ 1 }} {{ true }}</span></div>`, `<div><span>foo {{ 1 }} {{ true }}</span></div>`,
{ {
prefixIdentifiers: true prefixIdentifiers: true
@ -498,21 +427,18 @@ describe('compiler: hoistStatic transform', () => {
) )
expect(root.hoists).toMatchObject([ expect(root.hoists).toMatchObject([
{ {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
callee: CREATE_VNODE, tag: `"span"`,
arguments: [ props: undefined,
`"span"`, children: {
`null`,
{
type: NodeTypes.COMPOUND_EXPRESSION type: NodeTypes.COMPOUND_EXPRESSION
} }
]
} }
]) ])
expect(args).toMatchObject([ expect(root.codegenNode).toMatchObject({
`"div"`, tag: `"div"`,
`null`, props: undefined,
[ children: [
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
@ -521,12 +447,12 @@ describe('compiler: hoistStatic transform', () => {
} }
} }
] ]
]) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
test('hoist nested static tree with static prop value', () => { test('hoist nested static tree with static prop value', () => {
const { root, args } = transformWithHoist( const root = transformWithHoist(
`<div><span :foo="0">{{ 1 }}</span></div>`, `<div><span :foo="0">{{ 1 }}</span></div>`,
{ {
prefixIdentifiers: true prefixIdentifiers: true
@ -535,12 +461,10 @@ describe('compiler: hoistStatic transform', () => {
expect(root.hoists).toMatchObject([ expect(root.hoists).toMatchObject([
{ {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
callee: CREATE_VNODE, tag: `"span"`,
arguments: [ props: createObjectMatcher({ foo: `[0]` }),
`"span"`, children: {
createObjectMatcher({ foo: `[0]` }),
{
type: NodeTypes.INTERPOLATION, type: NodeTypes.INTERPOLATION,
content: { content: {
content: `1`, content: `1`,
@ -548,13 +472,12 @@ describe('compiler: hoistStatic transform', () => {
isConstant: true isConstant: true
} }
} }
]
} }
]) ])
expect(args).toMatchObject([ expect(root.codegenNode).toMatchObject({
`"div"`, tag: `"div"`,
`null`, props: undefined,
[ children: [
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
@ -563,12 +486,12 @@ describe('compiler: hoistStatic transform', () => {
} }
} }
] ]
]) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
test('hoist class with static object value', () => { test('hoist class with static object value', () => {
const { root, args } = transformWithHoist( const root = transformWithHoist(
`<div><span :class="{ foo: true }">{{ bar }}</span></div>`, `<div><span :class="{ foo: true }">{{ bar }}</span></div>`,
{ {
prefixIdentifiers: true prefixIdentifiers: true
@ -594,21 +517,20 @@ describe('compiler: hoistStatic transform', () => {
] ]
} }
]) ])
expect(args).toMatchObject([ expect(root.codegenNode).toMatchObject({
`"div"`, tag: `"div"`,
`null`, props: undefined,
[ children: [
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
callee: CREATE_VNODE, type: NodeTypes.VNODE_CALL,
arguments: [ tag: `"span"`,
`"span"`, props: {
{
type: NodeTypes.SIMPLE_EXPRESSION, type: NodeTypes.SIMPLE_EXPRESSION,
content: `_hoisted_1` content: `_hoisted_1`
}, },
{ children: {
type: NodeTypes.INTERPOLATION, type: NodeTypes.INTERPOLATION,
content: { content: {
content: `_ctx.bar`, content: `_ctx.bar`,
@ -616,17 +538,16 @@ describe('compiler: hoistStatic transform', () => {
isStatic: false isStatic: false
} }
}, },
`1 /* TEXT */` patchFlag: `1 /* TEXT */`
]
} }
} }
] ]
]) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
test('should NOT hoist expressions that refer scope variables', () => { test('should NOT hoist expressions that refer scope variables', () => {
const { root } = transformWithHoist( const root = transformWithHoist(
`<div><p v-for="o in list"><span>{{ o }}</span></p></div>`, `<div><p v-for="o in list"><span>{{ o }}</span></p></div>`,
{ {
prefixIdentifiers: true prefixIdentifiers: true
@ -638,7 +559,7 @@ describe('compiler: hoistStatic transform', () => {
}) })
test('should NOT hoist expressions that refer scope variables (2)', () => { test('should NOT hoist expressions that refer scope variables (2)', () => {
const { root } = transformWithHoist( const root = transformWithHoist(
`<div><p v-for="o in list"><span>{{ o + 'foo' }}</span></p></div>`, `<div><p v-for="o in list"><span>{{ o + 'foo' }}</span></p></div>`,
{ {
prefixIdentifiers: true prefixIdentifiers: true
@ -650,7 +571,7 @@ describe('compiler: hoistStatic transform', () => {
}) })
test('should NOT hoist expressions that refer scope variables (v-slot)', () => { test('should NOT hoist expressions that refer scope variables (v-slot)', () => {
const { root } = transformWithHoist( const root = transformWithHoist(
`<Comp v-slot="{ foo }">{{ foo }}</Comp>`, `<Comp v-slot="{ foo }">{{ foo }}</Comp>`,
{ {
prefixIdentifiers: true prefixIdentifiers: true
@ -662,7 +583,7 @@ describe('compiler: hoistStatic transform', () => {
}) })
test('should NOT hoist elements with cached handlers', () => { test('should NOT hoist elements with cached handlers', () => {
const { root } = transformWithHoist( const root = transformWithHoist(
`<div><div><div @click="foo"/></div></div>`, `<div><div><div @click="foo"/></div></div>`,
{ {
prefixIdentifiers: true, prefixIdentifiers: true,

View File

@ -2,8 +2,8 @@ import {
baseParse as parse, baseParse as parse,
transform, transform,
ElementNode, ElementNode,
CallExpression, noopDirectiveTransform,
noopDirectiveTransform VNodeCall
} from '../../src' } from '../../src'
import { transformElement } from '../../src/transforms/transformElement' import { transformElement } from '../../src/transforms/transformElement'
@ -17,10 +17,8 @@ describe('compiler: noop directive transform', () => {
} }
}) })
const node = ast.children[0] as ElementNode const node = ast.children[0] as ElementNode
const codegenArgs = (node.codegenNode as CallExpression).arguments
// As v-noop adds no properties the codegen should be identical to // As v-noop adds no properties the codegen should be identical to
// rendering a div with no props or reactive data (so just the tag as the arg) // rendering a div with no props or reactive data (so just the tag as the arg)
expect(codegenArgs.length).toBe(1) expect((node.codegenNode as VNodeCall).props).toBeUndefined()
}) })
}) })

View File

@ -9,23 +9,20 @@ import {
CREATE_VNODE, CREATE_VNODE,
MERGE_PROPS, MERGE_PROPS,
RESOLVE_DIRECTIVE, RESOLVE_DIRECTIVE,
WITH_DIRECTIVES,
TO_HANDLERS, TO_HANDLERS,
helperNameMap, helperNameMap,
PORTAL, PORTAL,
RESOLVE_DYNAMIC_COMPONENT, RESOLVE_DYNAMIC_COMPONENT,
SUSPENSE, SUSPENSE,
KEEP_ALIVE, KEEP_ALIVE,
BASE_TRANSITION, BASE_TRANSITION
OPEN_BLOCK,
CREATE_BLOCK
} from '../../src/runtimeHelpers' } from '../../src/runtimeHelpers'
import { import {
CallExpression,
NodeTypes, NodeTypes,
createObjectProperty, createObjectProperty,
DirectiveNode, DirectiveNode,
RootNode RootNode,
VNodeCall
} from '../../src/ast' } from '../../src/ast'
import { transformElement } from '../../src/transforms/transformElement' import { transformElement } from '../../src/transforms/transformElement'
import { transformStyle } from '../../../compiler-dom/src/transforms/transformStyle' import { transformStyle } from '../../../compiler-dom/src/transforms/transformStyle'
@ -40,7 +37,7 @@ function parseWithElementTransform(
options: CompilerOptions = {} options: CompilerOptions = {}
): { ): {
root: RootNode root: RootNode
node: CallExpression node: VNodeCall
} { } {
// wrap raw template in an extra div so that it doesn't get turned into a // wrap raw template in an extra div so that it doesn't get turned into a
// block as root node // block as root node
@ -50,8 +47,8 @@ function parseWithElementTransform(
...options ...options
}) })
const codegenNode = (ast as any).children[0].children[0] const codegenNode = (ast as any).children[0].children[0]
.codegenNode as CallExpression .codegenNode as VNodeCall
expect(codegenNode.type).toBe(NodeTypes.JS_CALL_EXPRESSION) expect(codegenNode.type).toBe(NodeTypes.VNODE_CALL)
return { return {
root: ast, root: ast,
node: codegenNode node: codegenNode
@ -75,63 +72,63 @@ describe('compiler: element transform', () => {
test('static props', () => { test('static props', () => {
const { node } = parseWithElementTransform(`<div id="foo" class="bar" />`) const { node } = parseWithElementTransform(`<div id="foo" class="bar" />`)
expect(node.callee).toBe(CREATE_VNODE) expect(node).toMatchObject({
expect(node.arguments).toMatchObject([ tag: `"div"`,
`"div"`, props: createObjectMatcher({
createObjectMatcher({
id: 'foo', id: 'foo',
class: 'bar' class: 'bar'
}),
children: undefined
}) })
])
}) })
test('props + children', () => { test('props + children', () => {
const { node } = parseWithElementTransform(`<div id="foo"><span/></div>`) const { node } = parseWithElementTransform(`<div id="foo"><span/></div>`)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments).toMatchObject([ expect(node).toMatchObject({
`"div"`, tag: `"div"`,
createObjectMatcher({ props: createObjectMatcher({
id: 'foo' id: 'foo'
}), }),
[ children: [
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
tag: 'span', tag: 'span',
codegenNode: { codegenNode: {
callee: CREATE_VNODE, type: NodeTypes.VNODE_CALL,
arguments: [`"span"`] tag: `"span"`
} }
} }
] ]
]) })
}) })
test('0 placeholder for children with no props', () => { test('0 placeholder for children with no props', () => {
const { node } = parseWithElementTransform(`<div><span/></div>`) const { node } = parseWithElementTransform(`<div><span/></div>`)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments).toMatchObject([ expect(node).toMatchObject({
`"div"`, tag: `"div"`,
`null`, props: undefined,
[ children: [
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
tag: 'span', tag: 'span',
codegenNode: { codegenNode: {
callee: CREATE_VNODE, type: NodeTypes.VNODE_CALL,
arguments: [`"span"`] tag: `"span"`
} }
} }
] ]
]) })
}) })
test('v-bind="obj"', () => { test('v-bind="obj"', () => {
const { root, node } = parseWithElementTransform(`<div v-bind="obj" />`) const { root, node } = parseWithElementTransform(`<div v-bind="obj" />`)
// single v-bind doesn't need mergeProps // single v-bind doesn't need mergeProps
expect(root.helpers).not.toContain(MERGE_PROPS) expect(root.helpers).not.toContain(MERGE_PROPS)
expect(node.callee).toBe(CREATE_VNODE)
// should directly use `obj` in props position // should directly use `obj` in props position
expect(node.arguments[1]).toMatchObject({ expect(node.props).toMatchObject({
type: NodeTypes.SIMPLE_EXPRESSION, type: NodeTypes.SIMPLE_EXPRESSION,
content: `obj` content: `obj`
}) })
@ -142,8 +139,8 @@ describe('compiler: element transform', () => {
`<div id="foo" v-bind="obj" />` `<div id="foo" v-bind="obj" />`
) )
expect(root.helpers).toContain(MERGE_PROPS) expect(root.helpers).toContain(MERGE_PROPS)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments[1]).toMatchObject({ expect(node.props).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: MERGE_PROPS, callee: MERGE_PROPS,
arguments: [ arguments: [
@ -163,8 +160,8 @@ describe('compiler: element transform', () => {
`<div v-bind="obj" id="foo" />` `<div v-bind="obj" id="foo" />`
) )
expect(root.helpers).toContain(MERGE_PROPS) expect(root.helpers).toContain(MERGE_PROPS)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments[1]).toMatchObject({ expect(node.props).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: MERGE_PROPS, callee: MERGE_PROPS,
arguments: [ arguments: [
@ -184,8 +181,8 @@ describe('compiler: element transform', () => {
`<div id="foo" v-bind="obj" class="bar" />` `<div id="foo" v-bind="obj" class="bar" />`
) )
expect(root.helpers).toContain(MERGE_PROPS) expect(root.helpers).toContain(MERGE_PROPS)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments[1]).toMatchObject({ expect(node.props).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: MERGE_PROPS, callee: MERGE_PROPS,
arguments: [ arguments: [
@ -208,8 +205,8 @@ describe('compiler: element transform', () => {
`<div id="foo" v-on="obj" class="bar" />` `<div id="foo" v-on="obj" class="bar" />`
) )
expect(root.helpers).toContain(MERGE_PROPS) expect(root.helpers).toContain(MERGE_PROPS)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments[1]).toMatchObject({ expect(node.props).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: MERGE_PROPS, callee: MERGE_PROPS,
arguments: [ arguments: [
@ -238,8 +235,8 @@ describe('compiler: element transform', () => {
`<div id="foo" v-on="handlers" v-bind="obj" />` `<div id="foo" v-on="handlers" v-bind="obj" />`
) )
expect(root.helpers).toContain(MERGE_PROPS) expect(root.helpers).toContain(MERGE_PROPS)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments[1]).toMatchObject({ expect(node.props).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: MERGE_PROPS, callee: MERGE_PROPS,
arguments: [ arguments: [
@ -266,13 +263,13 @@ describe('compiler: element transform', () => {
test('should handle plain <template> as normal element', () => { test('should handle plain <template> as normal element', () => {
const { node } = parseWithElementTransform(`<template id="foo" />`) const { node } = parseWithElementTransform(`<template id="foo" />`)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments).toMatchObject([ expect(node).toMatchObject({
`"template"`, tag: `"template"`,
createObjectMatcher({ props: createObjectMatcher({
id: 'foo' id: 'foo'
}) })
]) })
}) })
test('should handle <Portal> with normal children', () => { test('should handle <Portal> with normal children', () => {
@ -282,23 +279,23 @@ describe('compiler: element transform', () => {
) )
expect(root.components.length).toBe(0) expect(root.components.length).toBe(0)
expect(root.helpers).toContain(PORTAL) expect(root.helpers).toContain(PORTAL)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments).toMatchObject([ expect(node).toMatchObject({
PORTAL, tag: PORTAL,
createObjectMatcher({ props: createObjectMatcher({
target: '#foo' target: '#foo'
}), }),
[ children: [
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
tag: 'span', tag: 'span',
codegenNode: { codegenNode: {
callee: CREATE_VNODE, type: NodeTypes.VNODE_CALL,
arguments: [`"span"`] tag: `"span"`
} }
} }
] ]
]) })
} }
assert(`portal`) assert(`portal`)
@ -312,11 +309,11 @@ describe('compiler: element transform', () => {
) )
expect(root.components.length).toBe(0) expect(root.components.length).toBe(0)
expect(root.helpers).toContain(SUSPENSE) expect(root.helpers).toContain(SUSPENSE)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments).toMatchObject([ expect(node).toMatchObject({
SUSPENSE, tag: SUSPENSE,
`null`, props: undefined,
hasFallback children: hasFallback
? createObjectMatcher({ ? createObjectMatcher({
default: { default: {
type: NodeTypes.JS_FUNCTION_EXPRESSION type: NodeTypes.JS_FUNCTION_EXPRESSION
@ -332,7 +329,7 @@ describe('compiler: element transform', () => {
}, },
_compiled: `[true]` _compiled: `[true]`
}) })
]) })
} }
assert(`suspense`, `foo`) assert(`suspense`, `foo`)
@ -353,18 +350,15 @@ describe('compiler: element transform', () => {
expect(root.components.length).toBe(0) expect(root.components.length).toBe(0)
expect(root.helpers).toContain(KEEP_ALIVE) expect(root.helpers).toContain(KEEP_ALIVE)
const node = (root.children[0] as any).children[0].codegenNode const node = (root.children[0] as any).children[0].codegenNode
expect(node.type).toBe(NodeTypes.JS_SEQUENCE_EXPRESSION) expect(node).toMatchObject({
expect(node.expressions[1]).toMatchObject({ type: NodeTypes.VNODE_CALL,
type: NodeTypes.JS_CALL_EXPRESSION, tag: KEEP_ALIVE,
callee: CREATE_BLOCK, // should be forced into a block isBlock: true, // should be forced into a block
arguments: [ props: undefined,
KEEP_ALIVE,
`null`,
// keep-alive should not compile content to slots // keep-alive should not compile content to slots
[{ 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
genFlagText(PatchFlags.DYNAMIC_SLOTS) patchFlag: genFlagText(PatchFlags.DYNAMIC_SLOTS)
]
}) })
} }
@ -379,17 +373,17 @@ describe('compiler: element transform', () => {
) )
expect(root.components.length).toBe(0) expect(root.components.length).toBe(0)
expect(root.helpers).toContain(BASE_TRANSITION) expect(root.helpers).toContain(BASE_TRANSITION)
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments).toMatchObject([ expect(node).toMatchObject({
BASE_TRANSITION, tag: BASE_TRANSITION,
`null`, props: undefined,
createObjectMatcher({ children: createObjectMatcher({
default: { default: {
type: NodeTypes.JS_FUNCTION_EXPRESSION type: NodeTypes.JS_FUNCTION_EXPRESSION
}, },
_compiled: `[true]` _compiled: `[true]`
}) })
]) })
} }
assert(`base-transition`) assert(`base-transition`)
@ -418,8 +412,8 @@ describe('compiler: element transform', () => {
} }
} }
}) })
expect(node.callee).toBe(CREATE_VNODE)
expect(node.arguments[1]).toMatchObject({ expect(node.props).toMatchObject({
type: NodeTypes.JS_OBJECT_EXPRESSION, type: NodeTypes.JS_OBJECT_EXPRESSION,
properties: [ properties: [
{ {
@ -431,8 +425,8 @@ 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.arguments[3]).toMatch(PatchFlags.PROPS + '') expect(node.patchFlag).toMatch(PatchFlags.PROPS + '')
expect(node.arguments[4]).toMatch(`"bar"`) expect(node.dynamicProps).toMatch(`"bar"`)
}) })
test('directiveTransform with needRuntime: true', () => { test('directiveTransform with needRuntime: true', () => {
@ -451,20 +445,12 @@ describe('compiler: element transform', () => {
) )
expect(root.helpers).toContain(RESOLVE_DIRECTIVE) expect(root.helpers).toContain(RESOLVE_DIRECTIVE)
expect(root.directives).toContain(`foo`) expect(root.directives).toContain(`foo`)
expect(node).toMatchObject({
expect(node.callee).toBe(WITH_DIRECTIVES) tag: `"div"`,
expect(node.arguments).toMatchObject([ props: undefined,
{ children: undefined,
type: NodeTypes.JS_CALL_EXPRESSION, patchFlag: genFlagText(PatchFlags.NEED_PATCH), // should generate appropriate flag
callee: CREATE_VNODE, directives: {
arguments: [
`"div"`,
`null`,
`null`,
genFlagText(PatchFlags.NEED_PATCH) // should generate appropriate flag
]
},
{
type: NodeTypes.JS_ARRAY_EXPRESSION, type: NodeTypes.JS_ARRAY_EXPRESSION,
elements: [ elements: [
{ {
@ -487,7 +473,7 @@ describe('compiler: element transform', () => {
} }
] ]
} }
]) })
}) })
test('directiveTransform with needRuntime: Symbol', () => { test('directiveTransform with needRuntime: Symbol', () => {
@ -508,7 +494,7 @@ describe('compiler: element transform', () => {
expect(root.helpers).toContain(CREATE_VNODE) expect(root.helpers).toContain(CREATE_VNODE)
expect(root.helpers).not.toContain(RESOLVE_DIRECTIVE) expect(root.helpers).not.toContain(RESOLVE_DIRECTIVE)
expect(root.directives.length).toBe(0) expect(root.directives.length).toBe(0)
expect((node as any).arguments[1].elements[0].elements[0]).toBe( expect(node.directives!.elements[0].elements[0]).toBe(
`_${helperNameMap[CREATE_VNODE]}` `_${helperNameMap[CREATE_VNODE]}`
) )
}) })
@ -522,12 +508,8 @@ describe('compiler: element transform', () => {
expect(root.directives).toContain(`bar`) expect(root.directives).toContain(`bar`)
expect(root.directives).toContain(`baz`) expect(root.directives).toContain(`baz`)
expect(node.callee).toBe(WITH_DIRECTIVES) expect(node).toMatchObject({
expect(node.arguments).toMatchObject([ directives: {
{
type: NodeTypes.JS_CALL_EXPRESSION
},
{
type: NodeTypes.JS_ARRAY_EXPRESSION, type: NodeTypes.JS_ARRAY_EXPRESSION,
elements: [ elements: [
{ {
@ -597,7 +579,7 @@ describe('compiler: element transform', () => {
} }
] ]
} }
]) })
}) })
test(`props merging: event handlers`, () => { test(`props merging: event handlers`, () => {
@ -609,7 +591,7 @@ describe('compiler: element transform', () => {
} }
} }
) )
expect(node.arguments[1]).toMatchObject({ expect(node.props).toMatchObject({
type: NodeTypes.JS_OBJECT_EXPRESSION, type: NodeTypes.JS_OBJECT_EXPRESSION,
properties: [ properties: [
{ {
@ -649,7 +631,7 @@ describe('compiler: element transform', () => {
} }
} }
) )
expect(node.arguments[1]).toMatchObject({ expect(node.props).toMatchObject({
type: NodeTypes.JS_OBJECT_EXPRESSION, type: NodeTypes.JS_OBJECT_EXPRESSION,
properties: [ properties: [
{ {
@ -688,7 +670,7 @@ describe('compiler: element transform', () => {
} }
} }
) )
expect(node.arguments[1]).toMatchObject({ expect(node.props).toMatchObject({
type: NodeTypes.JS_OBJECT_EXPRESSION, type: NodeTypes.JS_OBJECT_EXPRESSION,
properties: [ properties: [
{ {
@ -721,85 +703,72 @@ describe('compiler: element transform', () => {
describe('patchFlag analysis', () => { describe('patchFlag analysis', () => {
test('TEXT', () => { test('TEXT', () => {
const { node } = parseWithBind(`<div>foo</div>`) const { node } = parseWithBind(`<div>foo</div>`)
expect(node.arguments.length).toBe(3) expect(node.patchFlag).toBeUndefined()
const { node: node2 } = parseWithBind(`<div>{{ foo }}</div>`) const { node: node2 } = parseWithBind(`<div>{{ foo }}</div>`)
expect(node2.arguments.length).toBe(4) expect(node2.patchFlag).toBe(genFlagText(PatchFlags.TEXT))
expect(node2.arguments[3]).toBe(genFlagText(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.arguments.length).toBe(4) expect(node3.patchFlag).toBe(genFlagText(PatchFlags.TEXT))
expect(node3.arguments[3]).toBe(genFlagText(PatchFlags.TEXT))
}) })
test('CLASS', () => { test('CLASS', () => {
const { node } = parseWithBind(`<div :class="foo" />`) const { node } = parseWithBind(`<div :class="foo" />`)
expect(node.arguments.length).toBe(4) expect(node.patchFlag).toBe(genFlagText(PatchFlags.CLASS))
expect(node.arguments[3]).toBe(genFlagText(PatchFlags.CLASS))
}) })
test('STYLE', () => { test('STYLE', () => {
const { node } = parseWithBind(`<div :style="foo" />`) const { node } = parseWithBind(`<div :style="foo" />`)
expect(node.arguments.length).toBe(4) expect(node.patchFlag).toBe(genFlagText(PatchFlags.STYLE))
expect(node.arguments[3]).toBe(genFlagText(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.arguments.length).toBe(5) expect(node.patchFlag).toBe(genFlagText(PatchFlags.PROPS))
expect(node.arguments[3]).toBe(genFlagText(PatchFlags.PROPS)) expect(node.dynamicProps).toBe(`["foo", "baz"]`)
expect(node.arguments[4]).toBe(`["foo", "baz"]`)
}) })
test('CLASS + STYLE + PROPS', () => { test('CLASS + STYLE + PROPS', () => {
const { node } = parseWithBind( const { node } = parseWithBind(
`<div id="foo" :class="cls" :style="styl" :foo="bar" :baz="qux"/>` `<div id="foo" :class="cls" :style="styl" :foo="bar" :baz="qux"/>`
) )
expect(node.arguments.length).toBe(5) expect(node.patchFlag).toBe(
expect(node.arguments[3]).toBe(
genFlagText([PatchFlags.CLASS, PatchFlags.STYLE, PatchFlags.PROPS]) genFlagText([PatchFlags.CLASS, PatchFlags.STYLE, PatchFlags.PROPS])
) )
expect(node.arguments[4]).toBe(`["foo", "baz"]`) expect(node.dynamicProps).toBe(`["foo", "baz"]`)
}) })
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.arguments.length).toBe(4) expect(node.patchFlag).toBe(genFlagText(PatchFlags.FULL_PROPS))
expect(node.arguments[3]).toBe(genFlagText(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.arguments.length).toBe(4) expect(node.patchFlag).toBe(genFlagText(PatchFlags.FULL_PROPS))
expect(node.arguments[3]).toBe(genFlagText(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.arguments.length).toBe(4) expect(node.patchFlag).toBe(genFlagText(PatchFlags.FULL_PROPS))
expect(node.arguments[3]).toBe(genFlagText(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.arguments.length).toBe(4) expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
expect(node.arguments[3]).toBe(genFlagText(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.arguments.length).toBe(4) expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
expect(node.arguments[3]).toBe(genFlagText(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 />`)
const vnodeCall = node.arguments[0] as CallExpression expect(node.patchFlag).toBe(genFlagText(PatchFlags.NEED_PATCH))
expect(vnodeCall.arguments.length).toBe(4)
expect(vnodeCall.arguments[3]).toBe(genFlagText(PatchFlags.NEED_PATCH))
}) })
}) })
@ -808,16 +777,15 @@ describe('compiler: element transform', () => {
const { node, root } = parseWithBind(`<component is="foo" />`) const { node, root } = parseWithBind(`<component is="foo" />`)
expect(root.helpers).not.toContain(RESOLVE_DYNAMIC_COMPONENT) expect(root.helpers).not.toContain(RESOLVE_DYNAMIC_COMPONENT)
expect(node).toMatchObject({ expect(node).toMatchObject({
callee: CREATE_VNODE, tag: '_component_foo'
arguments: ['_component_foo']
}) })
}) })
test('dynamic binding', () => { test('dynamic binding', () => {
const { node, root } = parseWithBind(`<component :is="foo" />`) const { node, root } = parseWithBind(`<component :is="foo" />`)
expect(root.helpers).toContain(RESOLVE_DYNAMIC_COMPONENT) expect(root.helpers).toContain(RESOLVE_DYNAMIC_COMPONENT)
expect(node.arguments).toMatchObject([ expect(node).toMatchObject({
{ tag: {
callee: RESOLVE_DYNAMIC_COMPONENT, callee: RESOLVE_DYNAMIC_COMPONENT,
arguments: [ arguments: [
{ {
@ -827,7 +795,7 @@ describe('compiler: element transform', () => {
'$' '$'
] ]
} }
]) })
}) })
}) })
@ -837,18 +805,9 @@ describe('compiler: element transform', () => {
nodeTransforms: [transformElement] nodeTransforms: [transformElement]
}) })
expect((ast as any).children[0].children[0].codegenNode).toMatchObject({ expect((ast as any).children[0].children[0].codegenNode).toMatchObject({
type: NodeTypes.JS_SEQUENCE_EXPRESSION, type: NodeTypes.VNODE_CALL,
expressions: [ tag: `"svg"`,
{ isBlock: true
type: NodeTypes.JS_CALL_EXPRESSION,
callee: OPEN_BLOCK
},
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: CREATE_BLOCK,
arguments: [`"svg"`]
}
]
}) })
}) })
}) })

View File

@ -5,7 +5,7 @@ import {
ObjectExpression, ObjectExpression,
CompilerOptions, CompilerOptions,
ErrorCodes, ErrorCodes,
CallExpression VNodeCall
} from '../../src' } from '../../src'
import { transformBind } from '../../src/transforms/vBind' import { transformBind } from '../../src/transforms/vBind'
import { transformElement } from '../../src/transforms/transformElement' import { transformElement } from '../../src/transforms/transformElement'
@ -33,8 +33,7 @@ function parseWithVBind(
describe('compiler: transform v-bind', () => { describe('compiler: transform v-bind', () => {
test('basic', () => { test('basic', () => {
const node = parseWithVBind(`<div v-bind:id="id"/>`) const node = parseWithVBind(`<div v-bind:id="id"/>`)
const props = (node.codegenNode as CallExpression) const props = (node.codegenNode as VNodeCall).props as ObjectExpression
.arguments[1] as ObjectExpression
expect(props.properties[0]).toMatchObject({ expect(props.properties[0]).toMatchObject({
key: { key: {
content: `id`, content: `id`,
@ -69,8 +68,7 @@ describe('compiler: transform v-bind', () => {
test('dynamic arg', () => { test('dynamic arg', () => {
const node = parseWithVBind(`<div v-bind:[id]="id"/>`) const node = parseWithVBind(`<div v-bind:[id]="id"/>`)
const props = (node.codegenNode as CallExpression) const props = (node.codegenNode as VNodeCall).props as ObjectExpression
.arguments[1] as ObjectExpression
expect(props.properties[0]).toMatchObject({ expect(props.properties[0]).toMatchObject({
key: { key: {
content: `id`, content: `id`,
@ -103,8 +101,7 @@ describe('compiler: transform v-bind', () => {
test('.camel modifier', () => { test('.camel modifier', () => {
const node = parseWithVBind(`<div v-bind:foo-bar.camel="id"/>`) const node = parseWithVBind(`<div v-bind:foo-bar.camel="id"/>`)
const props = (node.codegenNode as CallExpression) const props = (node.codegenNode as VNodeCall).props as ObjectExpression
.arguments[1] as ObjectExpression
expect(props.properties[0]).toMatchObject({ expect(props.properties[0]).toMatchObject({
key: { key: {
content: `fooBar`, content: `fooBar`,
@ -119,8 +116,7 @@ describe('compiler: transform v-bind', () => {
test('.camel modifier w/ dynamic arg', () => { test('.camel modifier w/ dynamic arg', () => {
const node = parseWithVBind(`<div v-bind:[foo].camel="id"/>`) const node = parseWithVBind(`<div v-bind:[foo].camel="id"/>`)
const props = (node.codegenNode as CallExpression) const props = (node.codegenNode as VNodeCall).props as ObjectExpression
.arguments[1] as ObjectExpression
expect(props.properties[0]).toMatchObject({ expect(props.properties[0]).toMatchObject({
key: { key: {
content: `_${helperNameMap[CAMELIZE]}(foo)`, content: `_${helperNameMap[CAMELIZE]}(foo)`,
@ -137,8 +133,7 @@ describe('compiler: transform v-bind', () => {
const node = parseWithVBind(`<div v-bind:[foo(bar)].camel="id"/>`, { const node = parseWithVBind(`<div v-bind:[foo(bar)].camel="id"/>`, {
prefixIdentifiers: true prefixIdentifiers: true
}) })
const props = (node.codegenNode as CallExpression) const props = (node.codegenNode as VNodeCall).props as ObjectExpression
.arguments[1] as ObjectExpression
expect(props.properties[0]).toMatchObject({ expect(props.properties[0]).toMatchObject({
key: { key: {
children: [ children: [

View File

@ -12,20 +12,11 @@ import {
SimpleExpressionNode, SimpleExpressionNode,
ElementNode, ElementNode,
InterpolationNode, InterpolationNode,
CallExpression,
SequenceExpression,
ForCodegenNode ForCodegenNode
} from '../../src/ast' } from '../../src/ast'
import { ErrorCodes } from '../../src/errors' import { ErrorCodes } from '../../src/errors'
import { CompilerOptions, generate } from '../../src' import { CompilerOptions, generate } from '../../src'
import { import { FRAGMENT, RENDER_LIST, RENDER_SLOT } from '../../src/runtimeHelpers'
OPEN_BLOCK,
CREATE_BLOCK,
FRAGMENT,
RENDER_LIST,
RENDER_SLOT,
WITH_DIRECTIVES
} from '../../src/runtimeHelpers'
import { PatchFlags } from '@vue/shared' import { PatchFlags } from '@vue/shared'
import { createObjectMatcher, genFlagText } from '../testUtils' import { createObjectMatcher, genFlagText } from '../testUtils'
@ -567,24 +558,18 @@ describe('compiler: v-for', () => {
describe('codegen', () => { describe('codegen', () => {
function assertSharedCodegen( function assertSharedCodegen(
node: SequenceExpression, node: ForCodegenNode,
keyed: boolean = false, keyed: boolean = false,
customReturn: boolean = false customReturn: boolean = false
) { ) {
expect(node).toMatchObject({ expect(node).toMatchObject({
type: NodeTypes.JS_SEQUENCE_EXPRESSION, type: NodeTypes.VNODE_CALL,
expressions: [ tag: FRAGMENT,
{ isForBlock: true,
type: NodeTypes.JS_CALL_EXPRESSION, patchFlag: keyed
callee: OPEN_BLOCK ? genFlagText(PatchFlags.KEYED_FRAGMENT)
}, : genFlagText(PatchFlags.UNKEYED_FRAGMENT),
{ children: {
type: NodeTypes.JS_CALL_EXPRESSION,
callee: CREATE_BLOCK,
arguments: [
FRAGMENT,
`null`,
{
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_LIST, callee: RENDER_LIST,
arguments: [ arguments: [
@ -594,37 +579,19 @@ describe('compiler: v-for', () => {
returns: customReturn returns: customReturn
? {} ? {}
: { : {
type: NodeTypes.JS_SEQUENCE_EXPRESSION, type: NodeTypes.VNODE_CALL,
expressions: [ isBlock: true
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: OPEN_BLOCK
},
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: CREATE_BLOCK
}
]
} }
} }
] ]
},
keyed
? genFlagText(PatchFlags.KEYED_FRAGMENT)
: genFlagText(PatchFlags.UNKEYED_FRAGMENT)
]
} }
]
}) })
const renderListArgs = ((node.expressions[1] as CallExpression) const renderListArgs = node.children.arguments
.arguments[2] as CallExpression).arguments
return { return {
source: renderListArgs[0] as SimpleExpressionNode, source: renderListArgs[0] as SimpleExpressionNode,
params: (renderListArgs[1] as any).params, params: (renderListArgs[1] as any).params,
returns: (renderListArgs[1] as any).returns, returns: (renderListArgs[1] as any).returns,
blockArgs: customReturn innerVNodeCall: customReturn ? null : (renderListArgs[1] as any).returns
? null
: (renderListArgs[1] as any).returns.expressions[1].arguments
} }
} }
@ -636,7 +603,9 @@ describe('compiler: v-for', () => {
expect(assertSharedCodegen(codegenNode)).toMatchObject({ expect(assertSharedCodegen(codegenNode)).toMatchObject({
source: { content: `items` }, source: { content: `items` },
params: [{ content: `item` }], params: [{ content: `item` }],
blockArgs: [`"span"`] innerVNodeCall: {
tag: `"span"`
}
}) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
@ -699,15 +668,16 @@ describe('compiler: v-for', () => {
expect(assertSharedCodegen(codegenNode)).toMatchObject({ expect(assertSharedCodegen(codegenNode)).toMatchObject({
source: { content: `items` }, source: { content: `items` },
params: [{ content: `item` }], params: [{ content: `item` }],
blockArgs: [ innerVNodeCall: {
FRAGMENT, tag: FRAGMENT,
`null`, props: undefined,
[ isBlock: true,
children: [
{ type: NodeTypes.TEXT, content: `hello` }, { type: NodeTypes.TEXT, content: `hello` },
{ type: NodeTypes.ELEMENT, tag: `span` } { type: NodeTypes.ELEMENT, tag: `span` }
], ],
genFlagText(PatchFlags.STABLE_FRAGMENT) patchFlag: genFlagText(PatchFlags.STABLE_FRAGMENT)
] }
}) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
@ -758,12 +728,12 @@ describe('compiler: v-for', () => {
expect(assertSharedCodegen(codegenNode, true)).toMatchObject({ expect(assertSharedCodegen(codegenNode, true)).toMatchObject({
source: { content: `items` }, source: { content: `items` },
params: [{ content: `item` }], params: [{ content: `item` }],
blockArgs: [ innerVNodeCall: {
`"span"`, tag: `"span"`,
createObjectMatcher({ props: createObjectMatcher({
key: `[item]` key: `[item]`
}) })
] }
}) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
@ -778,17 +748,17 @@ describe('compiler: v-for', () => {
expect(assertSharedCodegen(codegenNode, true)).toMatchObject({ expect(assertSharedCodegen(codegenNode, true)).toMatchObject({
source: { content: `items` }, source: { content: `items` },
params: [{ content: `item` }], params: [{ content: `item` }],
blockArgs: [ innerVNodeCall: {
FRAGMENT, tag: FRAGMENT,
createObjectMatcher({ props: createObjectMatcher({
key: `[item]` key: `[item]`
}), }),
[ children: [
{ type: NodeTypes.TEXT, content: `hello` }, { type: NodeTypes.TEXT, content: `hello` },
{ type: NodeTypes.ELEMENT, tag: `span` } { type: NodeTypes.ELEMENT, tag: `span` }
], ],
genFlagText(PatchFlags.STABLE_FRAGMENT) patchFlag: genFlagText(PatchFlags.STABLE_FRAGMENT)
] }
}) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
@ -799,24 +769,17 @@ describe('compiler: v-for', () => {
node: { codegenNode } node: { codegenNode }
} = parseWithForTransform(`<div v-if="ok" v-for="i in list"/>`) } = parseWithForTransform(`<div v-if="ok" v-for="i in list"/>`)
expect(codegenNode).toMatchObject({ expect(codegenNode).toMatchObject({
type: NodeTypes.JS_SEQUENCE_EXPRESSION,
expressions: [
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: OPEN_BLOCK,
arguments: []
},
{
type: NodeTypes.JS_CONDITIONAL_EXPRESSION, type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
test: { content: `ok` }, test: { content: `ok` },
consequent: { consequent: {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
callee: CREATE_BLOCK, props: createObjectMatcher({
// should optimize v-if + v-for into a single Fragment block key: `[0]`
arguments: [ }),
FRAGMENT, isBlock: true,
createObjectMatcher({ key: `[0]` }), isForBlock: true,
{ patchFlag: genFlagText(PatchFlags.UNKEYED_FRAGMENT),
children: {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_LIST, callee: RENDER_LIST,
arguments: [ arguments: [
@ -825,27 +788,14 @@ describe('compiler: v-for', () => {
type: NodeTypes.JS_FUNCTION_EXPRESSION, type: NodeTypes.JS_FUNCTION_EXPRESSION,
params: [{ content: `i` }], params: [{ content: `i` }],
returns: { returns: {
type: NodeTypes.JS_SEQUENCE_EXPRESSION, type: NodeTypes.VNODE_CALL,
expressions: [ tag: `"div"`,
{ isBlock: true
type: NodeTypes.JS_CALL_EXPRESSION,
callee: OPEN_BLOCK
},
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: CREATE_BLOCK,
arguments: [`"div"`]
}
]
} }
} }
] ]
},
genFlagText(PatchFlags.UNKEYED_FRAGMENT)
]
} }
} }
]
}) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
@ -857,18 +807,8 @@ describe('compiler: v-for', () => {
} = parseWithForTransform('<div v-for="i in list" v-foo/>') } = parseWithForTransform('<div v-for="i in list" v-foo/>')
const { returns } = assertSharedCodegen(codegenNode, false, true) const { returns } = assertSharedCodegen(codegenNode, false, true)
expect(returns).toMatchObject({ expect(returns).toMatchObject({
type: NodeTypes.JS_SEQUENCE_EXPRESSION, type: NodeTypes.VNODE_CALL,
expressions: [ directives: { type: NodeTypes.JS_ARRAY_EXPRESSION }
{ callee: OPEN_BLOCK },
// should wrap withDirectives() around createBlock()
{
callee: WITH_DIRECTIVES,
arguments: [
{ callee: CREATE_BLOCK },
{ type: NodeTypes.JS_ARRAY_EXPRESSION }
]
}
]
}) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })

View File

@ -10,19 +10,15 @@ import {
TextNode, TextNode,
CommentNode, CommentNode,
SimpleExpressionNode, SimpleExpressionNode,
SequenceExpression,
ConditionalExpression, ConditionalExpression,
CallExpression, IfConditionalExpression,
IfCodegenNode VNodeCall
} from '../../src/ast' } from '../../src/ast'
import { ErrorCodes } from '../../src/errors' import { ErrorCodes } from '../../src/errors'
import { CompilerOptions, generate } from '../../src' import { CompilerOptions, generate } from '../../src'
import { import {
OPEN_BLOCK,
CREATE_BLOCK,
FRAGMENT, FRAGMENT,
MERGE_PROPS, MERGE_PROPS,
WITH_DIRECTIVES,
RENDER_SLOT, RENDER_SLOT,
CREATE_COMMENT CREATE_COMMENT
} from '../../src/runtimeHelpers' } from '../../src/runtimeHelpers'
@ -44,7 +40,9 @@ function parseWithIfTransform(
} }
return { return {
root: ast, root: ast,
node: ast.children[returnIndex] as IfNode & { codegenNode: IfCodegenNode } node: ast.children[returnIndex] as IfNode & {
codegenNode: IfConditionalExpression
}
} }
} }
@ -267,32 +265,29 @@ describe('compiler: v-if', () => {
describe('codegen', () => { describe('codegen', () => {
function assertSharedCodegen( function assertSharedCodegen(
node: SequenceExpression, node: IfConditionalExpression,
depth: number = 0, depth: number = 0,
hasElse: boolean = false hasElse: boolean = false
) { ) {
expect(node).toMatchObject({ expect(node).toMatchObject({
type: NodeTypes.JS_SEQUENCE_EXPRESSION,
expressions: [
{
type: NodeTypes.JS_CALL_EXPRESSION,
callee: OPEN_BLOCK,
arguments: []
},
{
type: NodeTypes.JS_CONDITIONAL_EXPRESSION, type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
test: { test: {
content: `ok` content: `ok`
}, },
consequent: { consequent: {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
callee: CREATE_BLOCK isBlock: true
}, },
alternate: alternate:
depth < 1 depth < 1
? hasElse
? { ? {
type: NodeTypes.VNODE_CALL,
isBlock: true
}
: {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: hasElse ? CREATE_BLOCK : CREATE_COMMENT callee: CREATE_COMMENT
} }
: { : {
type: NodeTypes.JS_CONDITIONAL_EXPRESSION, type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
@ -300,16 +295,19 @@ describe('compiler: v-if', () => {
content: `orNot` content: `orNot`
}, },
consequent: { consequent: {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
callee: CREATE_BLOCK isBlock: true
}, },
alternate: { alternate: hasElse
? {
type: NodeTypes.VNODE_CALL,
isBlock: true
}
: {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: hasElse ? CREATE_BLOCK : CREATE_COMMENT callee: CREATE_COMMENT
} }
} }
}
]
}) })
} }
@ -319,15 +317,11 @@ describe('compiler: v-if', () => {
node: { codegenNode } node: { codegenNode }
} = parseWithIfTransform(`<div v-if="ok"/>`) } = parseWithIfTransform(`<div v-if="ok"/>`)
assertSharedCodegen(codegenNode) assertSharedCodegen(codegenNode)
const branch1 = (codegenNode.expressions[1] as ConditionalExpression) expect(codegenNode.consequent).toMatchObject({
.consequent as CallExpression tag: `"div"`,
expect(branch1.arguments).toMatchObject([ props: createObjectMatcher({ key: `[0]` })
`"div"`, })
createObjectMatcher({ key: `[0]` }) expect(codegenNode.alternate).toMatchObject({
])
const branch2 = (codegenNode.expressions[1] as ConditionalExpression)
.alternate as CallExpression
expect(branch2).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: CREATE_COMMENT callee: CREATE_COMMENT
}) })
@ -340,20 +334,16 @@ describe('compiler: v-if', () => {
node: { codegenNode } node: { codegenNode }
} = parseWithIfTransform(`<template v-if="ok"><div/>hello<p/></template>`) } = parseWithIfTransform(`<template v-if="ok"><div/>hello<p/></template>`)
assertSharedCodegen(codegenNode) assertSharedCodegen(codegenNode)
const branch1 = (codegenNode.expressions[1] as ConditionalExpression) expect(codegenNode.consequent).toMatchObject({
.consequent as CallExpression tag: FRAGMENT,
expect(branch1.arguments).toMatchObject([ props: createObjectMatcher({ key: `[0]` }),
FRAGMENT, children: [
createObjectMatcher({ key: `[0]` }),
[
{ type: NodeTypes.ELEMENT, tag: 'div' }, { type: NodeTypes.ELEMENT, tag: 'div' },
{ type: NodeTypes.TEXT, content: `hello` }, { type: NodeTypes.TEXT, content: `hello` },
{ type: NodeTypes.ELEMENT, tag: 'p' } { type: NodeTypes.ELEMENT, tag: 'p' }
] ]
]) })
const branch2 = (codegenNode.expressions[1] as ConditionalExpression) expect(codegenNode.alternate).toMatchObject({
.alternate as CallExpression
expect(branch2).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: CREATE_COMMENT callee: CREATE_COMMENT
}) })
@ -365,10 +355,7 @@ describe('compiler: v-if', () => {
root, root,
node: { codegenNode } node: { codegenNode }
} = parseWithIfTransform(`<template v-if="ok"><slot/></template>`) } = parseWithIfTransform(`<template v-if="ok"><slot/></template>`)
// assertSharedCodegen(codegenNode) expect(codegenNode.consequent).toMatchObject({
const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
.consequent as CallExpression
expect(branch1).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_SLOT, callee: RENDER_SLOT,
arguments: ['$slots', '"default"', createObjectMatcher({ key: `[0]` })] arguments: ['$slots', '"default"', createObjectMatcher({ key: `[0]` })]
@ -381,10 +368,7 @@ describe('compiler: v-if', () => {
root, root,
node: { codegenNode } node: { codegenNode }
} = parseWithIfTransform(`<slot v-if="ok"></slot>`) } = parseWithIfTransform(`<slot v-if="ok"></slot>`)
// assertSharedCodegen(codegenNode) expect(codegenNode.consequent).toMatchObject({
const branch1 = (codegenNode.expressions[1] as ConditionalExpression)
.consequent as CallExpression
expect(branch1).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_SLOT, callee: RENDER_SLOT,
arguments: ['$slots', '"default"', createObjectMatcher({ key: `[0]` })] arguments: ['$slots', '"default"', createObjectMatcher({ key: `[0]` })]
@ -398,18 +382,14 @@ describe('compiler: v-if', () => {
node: { codegenNode } node: { codegenNode }
} = parseWithIfTransform(`<div v-if="ok"/><p v-else/>`) } = parseWithIfTransform(`<div v-if="ok"/><p v-else/>`)
assertSharedCodegen(codegenNode, 0, true) assertSharedCodegen(codegenNode, 0, true)
const branch1 = (codegenNode.expressions[1] as ConditionalExpression) expect(codegenNode.consequent).toMatchObject({
.consequent as CallExpression tag: `"div"`,
expect(branch1.arguments).toMatchObject([ props: createObjectMatcher({ key: `[0]` })
`"div"`, })
createObjectMatcher({ key: `[0]` }) expect(codegenNode.alternate).toMatchObject({
]) tag: `"p"`,
const branch2 = (codegenNode.expressions[1] as ConditionalExpression) props: createObjectMatcher({ key: `[1]` })
.alternate as CallExpression })
expect(branch2.arguments).toMatchObject([
`"p"`,
createObjectMatcher({ key: `[1]` })
])
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
@ -419,18 +399,15 @@ describe('compiler: v-if', () => {
node: { codegenNode } node: { codegenNode }
} = parseWithIfTransform(`<div v-if="ok"/><p v-else-if="orNot" />`) } = parseWithIfTransform(`<div v-if="ok"/><p v-else-if="orNot" />`)
assertSharedCodegen(codegenNode, 1) assertSharedCodegen(codegenNode, 1)
const branch1 = (codegenNode.expressions[1] as ConditionalExpression) expect(codegenNode.consequent).toMatchObject({
.consequent as CallExpression tag: `"div"`,
expect(branch1.arguments).toMatchObject([ props: createObjectMatcher({ key: `[0]` })
`"div"`, })
createObjectMatcher({ key: `[0]` }) const branch2 = codegenNode.alternate as ConditionalExpression
]) expect(branch2.consequent).toMatchObject({
const branch2 = (codegenNode.expressions[1] as ConditionalExpression) tag: `"p"`,
.alternate as ConditionalExpression props: createObjectMatcher({ key: `[1]` })
expect((branch2.consequent as CallExpression).arguments).toMatchObject([ })
`"p"`,
createObjectMatcher({ key: `[1]` })
])
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
@ -442,28 +419,25 @@ describe('compiler: v-if', () => {
`<div v-if="ok"/><p v-else-if="orNot"/><template v-else>fine</template>` `<div v-if="ok"/><p v-else-if="orNot"/><template v-else>fine</template>`
) )
assertSharedCodegen(codegenNode, 1, true) assertSharedCodegen(codegenNode, 1, true)
const branch1 = (codegenNode.expressions[1] as ConditionalExpression) expect(codegenNode.consequent).toMatchObject({
.consequent as CallExpression tag: `"div"`,
expect(branch1.arguments).toMatchObject([ props: createObjectMatcher({ key: `[0]` })
`"div"`, })
createObjectMatcher({ key: `[0]` }) const branch2 = codegenNode.alternate as ConditionalExpression
]) expect(branch2.consequent).toMatchObject({
const branch2 = (codegenNode.expressions[1] as ConditionalExpression) tag: `"p"`,
.alternate as ConditionalExpression props: createObjectMatcher({ key: `[1]` })
expect((branch2.consequent as CallExpression).arguments).toMatchObject([ })
`"p"`, expect(branch2.alternate).toMatchObject({
createObjectMatcher({ key: `[1]` }) tag: FRAGMENT,
]) props: createObjectMatcher({ key: `[2]` }),
expect((branch2.alternate as CallExpression).arguments).toMatchObject([ children: [
FRAGMENT,
createObjectMatcher({ key: `[2]` }),
[
{ {
type: NodeTypes.TEXT, type: NodeTypes.TEXT,
content: `fine` content: `fine`
} }
] ]
]) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })
@ -471,9 +445,8 @@ describe('compiler: v-if', () => {
const { const {
node: { codegenNode } node: { codegenNode }
} = parseWithIfTransform(`<div v-if="ok" v-bind="obj"/>`) } = parseWithIfTransform(`<div v-if="ok" v-bind="obj"/>`)
const branch1 = (codegenNode.expressions[1] as ConditionalExpression) const branch1 = codegenNode.consequent as VNodeCall
.consequent as CallExpression expect(branch1.props).toMatchObject({
expect(branch1.arguments[1]).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: MERGE_PROPS, callee: MERGE_PROPS,
arguments: [createObjectMatcher({ key: `[0]` }), { content: `obj` }] arguments: [createObjectMatcher({ key: `[0]` }), { content: `obj` }]
@ -484,9 +457,8 @@ describe('compiler: v-if', () => {
const { const {
node: { codegenNode } node: { codegenNode }
} = parseWithIfTransform(`<div v-if="ok" id="foo" v-bind="obj"/>`) } = parseWithIfTransform(`<div v-if="ok" id="foo" v-bind="obj"/>`)
const branch1 = (codegenNode.expressions[1] as ConditionalExpression) const branch1 = codegenNode.consequent as VNodeCall
.consequent as CallExpression expect(branch1.props).toMatchObject({
expect(branch1.arguments[1]).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: MERGE_PROPS, callee: MERGE_PROPS,
arguments: [ arguments: [
@ -503,9 +475,8 @@ describe('compiler: v-if', () => {
const { const {
node: { codegenNode } node: { codegenNode }
} = parseWithIfTransform(`<div v-if="ok" v-bind="obj" id="foo"/>`) } = parseWithIfTransform(`<div v-if="ok" v-bind="obj" id="foo"/>`)
const branch1 = (codegenNode.expressions[1] as ConditionalExpression) const branch1 = codegenNode.consequent as VNodeCall
.consequent as CallExpression expect(branch1.props).toMatchObject({
expect(branch1.arguments[1]).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
callee: MERGE_PROPS, callee: MERGE_PROPS,
arguments: [ arguments: [
@ -522,13 +493,9 @@ describe('compiler: v-if', () => {
const { const {
node: { codegenNode } node: { codegenNode }
} = parseWithIfTransform(`<div v-if="ok" v-foo />`) } = parseWithIfTransform(`<div v-if="ok" v-foo />`)
const branch1 = (codegenNode.expressions[1] as ConditionalExpression) const branch1 = codegenNode.consequent as VNodeCall
.consequent as CallExpression expect(branch1.directives).not.toBeUndefined()
expect(branch1.callee).toBe(WITH_DIRECTIVES) expect(branch1.props).toMatchObject(createObjectMatcher({ key: `[0]` }))
const realBranch = branch1.arguments[0] as CallExpression
expect(realBranch.arguments[1]).toMatchObject(
createObjectMatcher({ key: `[0]` })
)
}) })
test('v-if with key', () => { test('v-if with key', () => {
@ -536,12 +503,10 @@ describe('compiler: v-if', () => {
root, root,
node: { codegenNode } node: { codegenNode }
} = parseWithIfTransform(`<div v-if="ok" key="some-key"/>`) } = parseWithIfTransform(`<div v-if="ok" key="some-key"/>`)
const branch1 = (codegenNode.expressions[1] as ConditionalExpression) expect(codegenNode.consequent).toMatchObject({
.consequent as CallExpression tag: `"div"`,
expect(branch1.arguments).toMatchObject([ props: createObjectMatcher({ key: 'some-key' })
`"div"`, })
createObjectMatcher({ key: 'some-key' })
])
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
}) })

View File

@ -5,12 +5,11 @@ import {
ElementNode, ElementNode,
ObjectExpression, ObjectExpression,
CompilerOptions, CompilerOptions,
CallExpression,
ForNode, ForNode,
PlainElementNode, PlainElementNode,
PlainElementCodegenNode,
ComponentNode, ComponentNode,
NodeTypes NodeTypes,
VNodeCall
} from '../../src' } from '../../src'
import { ErrorCodes } from '../../src/errors' import { ErrorCodes } from '../../src/errors'
import { transformModel } from '../../src/transforms/vModel' import { transformModel } from '../../src/transforms/vModel'
@ -43,8 +42,8 @@ describe('compiler: transform v-model', () => {
test('simple exprssion', () => { test('simple exprssion', () => {
const root = parseWithVModel('<input v-model="model" />') const root = parseWithVModel('<input v-model="model" />')
const node = root.children[0] as ElementNode const node = root.children[0] as ElementNode
const props = ((node.codegenNode as CallExpression) const props = ((node.codegenNode as VNodeCall).props as ObjectExpression)
.arguments[1] as ObjectExpression).properties .properties
expect(props[0]).toMatchObject({ expect(props[0]).toMatchObject({
key: { key: {
@ -82,8 +81,8 @@ describe('compiler: transform v-model', () => {
prefixIdentifiers: true prefixIdentifiers: true
}) })
const node = root.children[0] as ElementNode const node = root.children[0] as ElementNode
const props = ((node.codegenNode as CallExpression) const props = ((node.codegenNode as VNodeCall).props as ObjectExpression)
.arguments[1] as ObjectExpression).properties .properties
expect(props[0]).toMatchObject({ expect(props[0]).toMatchObject({
key: { key: {
@ -119,8 +118,8 @@ describe('compiler: transform v-model', () => {
test('compound expression', () => { test('compound expression', () => {
const root = parseWithVModel('<input v-model="model[index]" />') const root = parseWithVModel('<input v-model="model[index]" />')
const node = root.children[0] as ElementNode const node = root.children[0] as ElementNode
const props = ((node.codegenNode as CallExpression) const props = ((node.codegenNode as VNodeCall).props as ObjectExpression)
.arguments[1] as ObjectExpression).properties .properties
expect(props[0]).toMatchObject({ expect(props[0]).toMatchObject({
key: { key: {
@ -158,8 +157,8 @@ describe('compiler: transform v-model', () => {
prefixIdentifiers: true prefixIdentifiers: true
}) })
const node = root.children[0] as ElementNode const node = root.children[0] as ElementNode
const props = ((node.codegenNode as CallExpression) const props = ((node.codegenNode as VNodeCall).props as ObjectExpression)
.arguments[1] as ObjectExpression).properties .properties
expect(props[0]).toMatchObject({ expect(props[0]).toMatchObject({
key: { key: {
@ -215,9 +214,8 @@ describe('compiler: transform v-model', () => {
test('with argument', () => { test('with argument', () => {
const root = parseWithVModel('<input v-model:value="model" />') const root = parseWithVModel('<input v-model:value="model" />')
const node = root.children[0] as ElementNode const node = root.children[0] as ElementNode
const props = ((node.codegenNode as CallExpression) const props = ((node.codegenNode as VNodeCall).props as ObjectExpression)
.arguments[1] as ObjectExpression).properties .properties
expect(props[0]).toMatchObject({ expect(props[0]).toMatchObject({
key: { key: {
content: 'value', content: 'value',
@ -252,8 +250,8 @@ describe('compiler: transform v-model', () => {
test('with dynamic argument', () => { test('with dynamic argument', () => {
const root = parseWithVModel('<input v-model:[value]="model" />') const root = parseWithVModel('<input v-model:[value]="model" />')
const node = root.children[0] as ElementNode const node = root.children[0] as ElementNode
const props = ((node.codegenNode as CallExpression) const props = ((node.codegenNode as VNodeCall).props as ObjectExpression)
.arguments[1] as ObjectExpression).properties .properties
expect(props[0]).toMatchObject({ expect(props[0]).toMatchObject({
key: { key: {
@ -296,8 +294,8 @@ describe('compiler: transform v-model', () => {
prefixIdentifiers: true prefixIdentifiers: true
}) })
const node = root.children[0] as ElementNode const node = root.children[0] as ElementNode
const props = ((node.codegenNode as CallExpression) const props = ((node.codegenNode as VNodeCall).props as ObjectExpression)
.arguments[1] as ObjectExpression).properties .properties
expect(props[0]).toMatchObject({ expect(props[0]).toMatchObject({
key: { key: {
@ -342,12 +340,12 @@ describe('compiler: transform v-model', () => {
}) })
expect(root.cached).toBe(1) expect(root.cached).toBe(1)
const codegen = (root.children[0] as PlainElementNode) const codegen = (root.children[0] as PlainElementNode)
.codegenNode as PlainElementCodegenNode .codegenNode as VNodeCall
// should not list cached prop in dynamicProps // should not list cached prop in dynamicProps
expect(codegen.arguments[4]).toBe(`["modelValue"]`) expect(codegen.dynamicProps).toBe(`["modelValue"]`)
expect( expect((codegen.props as ObjectExpression).properties[1].value.type).toBe(
(codegen.arguments[1] as ObjectExpression).properties[1].value.type NodeTypes.JS_CACHE_EXPRESSION
).toBe(NodeTypes.JS_CACHE_EXPRESSION) )
}) })
test('should not cache update handler if it refers v-for scope variables', () => { test('should not cache update handler if it refers v-for scope variables', () => {
@ -360,10 +358,10 @@ describe('compiler: transform v-model', () => {
) )
expect(root.cached).toBe(0) expect(root.cached).toBe(0)
const codegen = ((root.children[0] as ForNode) const codegen = ((root.children[0] as ForNode)
.children[0] as PlainElementNode).codegenNode as PlainElementCodegenNode .children[0] as PlainElementNode).codegenNode as VNodeCall
expect(codegen.arguments[4]).toBe(`["modelValue", "onUpdate:modelValue"]`) expect(codegen.dynamicProps).toBe(`["modelValue", "onUpdate:modelValue"]`)
expect( expect(
(codegen.arguments[1] as ObjectExpression).properties[1].value.type (codegen.props as ObjectExpression).properties[1].value.type
).not.toBe(NodeTypes.JS_CACHE_EXPRESSION) ).not.toBe(NodeTypes.JS_CACHE_EXPRESSION)
}) })
@ -375,18 +373,18 @@ describe('compiler: transform v-model', () => {
} }
) )
const codegen = ((root.children[0] as ComponentNode) const codegen = ((root.children[0] as ComponentNode)
.children[0] as PlainElementNode).codegenNode as PlainElementCodegenNode .children[0] as PlainElementNode).codegenNode as VNodeCall
expect(codegen.arguments[4]).toBe(`["modelValue", "onUpdate:modelValue"]`) expect(codegen.dynamicProps).toBe(`["modelValue", "onUpdate:modelValue"]`)
}) })
test('should generate modelModifers for component v-model', () => { test('should generate modelModifers for component v-model', () => {
const root = parseWithVModel('<Comp v-model.trim.bar-baz="foo" />', { const root = parseWithVModel('<Comp v-model.trim.bar-baz="foo" />', {
prefixIdentifiers: true prefixIdentifiers: true
}) })
const args = ((root.children[0] as ComponentNode) const vnodeCall = (root.children[0] as ComponentNode)
.codegenNode as CallExpression).arguments .codegenNode as VNodeCall
// props // props
expect(args[1]).toMatchObject({ expect(vnodeCall.props).toMatchObject({
properties: [ properties: [
{ key: { content: `modelValue` } }, { key: { content: `modelValue` } },
{ key: { content: `onUpdate:modelValue` } }, { key: { content: `onUpdate:modelValue` } },
@ -398,7 +396,7 @@ describe('compiler: transform v-model', () => {
}) })
// should NOT include modelModifiers in dynamicPropNames because it's never // should NOT include modelModifiers in dynamicPropNames because it's never
// gonna change // gonna change
expect(args[4]).toBe(`["modelValue", "onUpdate:modelValue"]`) expect(vnodeCall.dynamicProps).toBe(`["modelValue", "onUpdate:modelValue"]`)
}) })
test('should generate modelModifers for component v-model with arguments', () => { test('should generate modelModifers for component v-model with arguments', () => {
@ -408,10 +406,10 @@ describe('compiler: transform v-model', () => {
prefixIdentifiers: true prefixIdentifiers: true
} }
) )
const args = ((root.children[0] as ComponentNode) const vnodeCall = (root.children[0] as ComponentNode)
.codegenNode as CallExpression).arguments .codegenNode as VNodeCall
// props // props
expect(args[1]).toMatchObject({ expect(vnodeCall.props).toMatchObject({
properties: [ properties: [
{ key: { content: `foo` } }, { key: { content: `foo` } },
{ key: { content: `onUpdate:foo` } }, { key: { content: `onUpdate:foo` } },
@ -429,7 +427,9 @@ describe('compiler: transform v-model', () => {
}) })
// should NOT include modelModifiers in dynamicPropNames because it's never // should NOT include modelModifiers in dynamicPropNames because it's never
// gonna change // gonna change
expect(args[4]).toBe(`["foo", "onUpdate:foo", "bar", "onUpdate:bar"]`) expect(vnodeCall.dynamicProps).toBe(
`["foo", "onUpdate:foo", "bar", "onUpdate:bar"]`
)
}) })
describe('errors', () => { describe('errors', () => {

View File

@ -6,8 +6,7 @@ import {
CompilerOptions, CompilerOptions,
ErrorCodes, ErrorCodes,
NodeTypes, NodeTypes,
CallExpression, VNodeCall
PlainElementCodegenNode
} from '../../src' } from '../../src'
import { transformOn } from '../../src/transforms/vOn' import { transformOn } from '../../src/transforms/vOn'
import { transformElement } from '../../src/transforms/transformElement' import { transformElement } from '../../src/transforms/transformElement'
@ -31,9 +30,9 @@ function parseWithVOn(template: string, options: CompilerOptions = {}) {
describe('compiler: transform v-on', () => { describe('compiler: transform v-on', () => {
test('basic', () => { test('basic', () => {
const { node } = parseWithVOn(`<div v-on:click="onClick"/>`) const { node } = parseWithVOn(`<div v-on:click="onClick"/>`)
const props = (node.codegenNode as CallExpression) expect((node.codegenNode as VNodeCall).props).toMatchObject({
.arguments[1] as ObjectExpression properties: [
expect(props.properties[0]).toMatchObject({ {
key: { key: {
content: `onClick`, content: `onClick`,
isStatic: true, isStatic: true,
@ -62,14 +61,16 @@ describe('compiler: transform v-on', () => {
} }
} }
} }
}
]
}) })
}) })
test('dynamic arg', () => { test('dynamic arg', () => {
const { node } = parseWithVOn(`<div v-on:[event]="handler"/>`) const { node } = parseWithVOn(`<div v-on:[event]="handler"/>`)
const props = (node.codegenNode as CallExpression) expect((node.codegenNode as VNodeCall).props).toMatchObject({
.arguments[1] as ObjectExpression properties: [
expect(props.properties[0]).toMatchObject({ {
key: { key: {
type: NodeTypes.COMPOUND_EXPRESSION, type: NodeTypes.COMPOUND_EXPRESSION,
children: [`"on" + (`, { content: `event` }, `)`] children: [`"on" + (`, { content: `event` }, `)`]
@ -79,6 +80,8 @@ describe('compiler: transform v-on', () => {
content: `handler`, content: `handler`,
isStatic: false isStatic: false
} }
}
]
}) })
}) })
@ -86,9 +89,9 @@ describe('compiler: transform v-on', () => {
const { node } = parseWithVOn(`<div v-on:[event]="handler"/>`, { const { node } = parseWithVOn(`<div v-on:[event]="handler"/>`, {
prefixIdentifiers: true prefixIdentifiers: true
}) })
const props = (node.codegenNode as CallExpression) expect((node.codegenNode as VNodeCall).props).toMatchObject({
.arguments[1] as ObjectExpression properties: [
expect(props.properties[0]).toMatchObject({ {
key: { key: {
type: NodeTypes.COMPOUND_EXPRESSION, type: NodeTypes.COMPOUND_EXPRESSION,
children: [`"on" + (`, { content: `_ctx.event` }, `)`] children: [`"on" + (`, { content: `_ctx.event` }, `)`]
@ -98,6 +101,8 @@ describe('compiler: transform v-on', () => {
content: `_ctx.handler`, content: `_ctx.handler`,
isStatic: false isStatic: false
} }
}
]
}) })
}) })
@ -105,9 +110,9 @@ describe('compiler: transform v-on', () => {
const { node } = parseWithVOn(`<div v-on:[event(foo)]="handler"/>`, { const { node } = parseWithVOn(`<div v-on:[event(foo)]="handler"/>`, {
prefixIdentifiers: true prefixIdentifiers: true
}) })
const props = (node.codegenNode as CallExpression) expect((node.codegenNode as VNodeCall).props).toMatchObject({
.arguments[1] as ObjectExpression properties: [
expect(props.properties[0]).toMatchObject({ {
key: { key: {
type: NodeTypes.COMPOUND_EXPRESSION, type: NodeTypes.COMPOUND_EXPRESSION,
children: [ children: [
@ -124,27 +129,31 @@ describe('compiler: transform v-on', () => {
content: `_ctx.handler`, content: `_ctx.handler`,
isStatic: false isStatic: false
} }
}
]
}) })
}) })
test('should wrap as function if expression is inline statement', () => { test('should wrap as function if expression is inline statement', () => {
const { node } = parseWithVOn(`<div @click="i++"/>`) const { node } = parseWithVOn(`<div @click="i++"/>`)
const props = (node.codegenNode as CallExpression) expect((node.codegenNode as VNodeCall).props).toMatchObject({
.arguments[1] as ObjectExpression properties: [
expect(props.properties[0]).toMatchObject({ {
key: { content: `onClick` }, key: { content: `onClick` },
value: { value: {
type: NodeTypes.COMPOUND_EXPRESSION, type: NodeTypes.COMPOUND_EXPRESSION,
children: [`$event => (`, { content: `i++` }, `)`] children: [`$event => (`, { content: `i++` }, `)`]
} }
}
]
}) })
}) })
test('should handle multiple inline statement', () => { test('should handle multiple inline statement', () => {
const { node } = parseWithVOn(`<div @click="foo();bar()"/>`) const { node } = parseWithVOn(`<div @click="foo();bar()"/>`)
const props = (node.codegenNode as CallExpression) expect((node.codegenNode as VNodeCall).props).toMatchObject({
.arguments[1] as ObjectExpression properties: [
expect(props.properties[0]).toMatchObject({ {
key: { content: `onClick` }, key: { content: `onClick` },
value: { value: {
type: NodeTypes.COMPOUND_EXPRESSION, type: NodeTypes.COMPOUND_EXPRESSION,
@ -153,6 +162,8 @@ describe('compiler: transform v-on', () => {
// consistent with 2.x // consistent with 2.x
children: [`$event => {`, { content: `foo();bar()` }, `}`] children: [`$event => {`, { content: `foo();bar()` }, `}`]
} }
}
]
}) })
}) })
@ -160,9 +171,9 @@ describe('compiler: transform v-on', () => {
const { node } = parseWithVOn(`<div @click="foo($event)"/>`, { const { node } = parseWithVOn(`<div @click="foo($event)"/>`, {
prefixIdentifiers: true prefixIdentifiers: true
}) })
const props = (node.codegenNode as CallExpression) expect((node.codegenNode as VNodeCall).props).toMatchObject({
.arguments[1] as ObjectExpression properties: [
expect(props.properties[0]).toMatchObject({ {
key: { content: `onClick` }, key: { content: `onClick` },
value: { value: {
type: NodeTypes.COMPOUND_EXPRESSION, type: NodeTypes.COMPOUND_EXPRESSION,
@ -181,6 +192,8 @@ describe('compiler: transform v-on', () => {
`)` `)`
] ]
} }
}
]
}) })
}) })
@ -188,9 +201,9 @@ describe('compiler: transform v-on', () => {
const { node } = parseWithVOn(`<div @click="foo($event);bar()"/>`, { const { node } = parseWithVOn(`<div @click="foo($event);bar()"/>`, {
prefixIdentifiers: true prefixIdentifiers: true
}) })
const props = (node.codegenNode as CallExpression) expect((node.codegenNode as VNodeCall).props).toMatchObject({
.arguments[1] as ObjectExpression properties: [
expect(props.properties[0]).toMatchObject({ {
key: { content: `onClick` }, key: { content: `onClick` },
value: { value: {
type: NodeTypes.COMPOUND_EXPRESSION, type: NodeTypes.COMPOUND_EXPRESSION,
@ -210,32 +223,38 @@ describe('compiler: transform v-on', () => {
`}` `}`
] ]
} }
}
]
}) })
}) })
test('should NOT wrap as function if expression is already function expression', () => { test('should NOT wrap as function if expression is already function expression', () => {
const { node } = parseWithVOn(`<div @click="$event => foo($event)"/>`) const { node } = parseWithVOn(`<div @click="$event => foo($event)"/>`)
const props = (node.codegenNode as CallExpression) expect((node.codegenNode as VNodeCall).props).toMatchObject({
.arguments[1] as ObjectExpression properties: [
expect(props.properties[0]).toMatchObject({ {
key: { content: `onClick` }, key: { content: `onClick` },
value: { value: {
type: NodeTypes.SIMPLE_EXPRESSION, type: NodeTypes.SIMPLE_EXPRESSION,
content: `$event => foo($event)` content: `$event => foo($event)`
} }
}
]
}) })
}) })
test('should NOT wrap as function if expression is complex member expression', () => { test('should NOT wrap as function if expression is complex member expression', () => {
const { node } = parseWithVOn(`<div @click="a['b' + c]"/>`) const { node } = parseWithVOn(`<div @click="a['b' + c]"/>`)
const props = (node.codegenNode as CallExpression) expect((node.codegenNode as VNodeCall).props).toMatchObject({
.arguments[1] as ObjectExpression properties: [
expect(props.properties[0]).toMatchObject({ {
key: { content: `onClick` }, key: { content: `onClick` },
value: { value: {
type: NodeTypes.SIMPLE_EXPRESSION, type: NodeTypes.SIMPLE_EXPRESSION,
content: `a['b' + c]` content: `a['b' + c]`
} }
}
]
}) })
}) })
@ -243,14 +262,21 @@ describe('compiler: transform v-on', () => {
const { node } = parseWithVOn(`<div @click="a['b' + c]"/>`, { const { node } = parseWithVOn(`<div @click="a['b' + c]"/>`, {
prefixIdentifiers: true prefixIdentifiers: true
}) })
const props = (node.codegenNode as CallExpression) expect((node.codegenNode as VNodeCall).props).toMatchObject({
.arguments[1] as ObjectExpression properties: [
expect(props.properties[0]).toMatchObject({ {
key: { content: `onClick` }, key: { content: `onClick` },
value: { value: {
type: NodeTypes.COMPOUND_EXPRESSION, type: NodeTypes.COMPOUND_EXPRESSION,
children: [{ content: `_ctx.a` }, `['b' + `, { content: `_ctx.c` }, `]`] children: [
{ content: `_ctx.a` },
`['b' + `,
{ content: `_ctx.c` },
`]`
]
} }
}
]
}) })
}) })
@ -258,9 +284,9 @@ describe('compiler: transform v-on', () => {
const { node } = parseWithVOn(`<div @click="e => foo(e)"/>`, { const { node } = parseWithVOn(`<div @click="e => foo(e)"/>`, {
prefixIdentifiers: true prefixIdentifiers: true
}) })
const props = (node.codegenNode as CallExpression) expect((node.codegenNode as VNodeCall).props).toMatchObject({
.arguments[1] as ObjectExpression properties: [
expect(props.properties[0]).toMatchObject({ {
key: { content: `onClick` }, key: { content: `onClick` },
value: { value: {
type: NodeTypes.COMPOUND_EXPRESSION, type: NodeTypes.COMPOUND_EXPRESSION,
@ -273,6 +299,8 @@ describe('compiler: transform v-on', () => {
`)` `)`
] ]
} }
}
]
}) })
}) })
@ -302,15 +330,17 @@ describe('compiler: transform v-on', () => {
test('case conversion for vnode hooks', () => { test('case conversion for vnode hooks', () => {
const { node } = parseWithVOn(`<div v-on:vnode-mounted="onMount"/>`) const { node } = parseWithVOn(`<div v-on:vnode-mounted="onMount"/>`)
const props = (node.codegenNode as CallExpression) expect((node.codegenNode as VNodeCall).props).toMatchObject({
.arguments[1] as ObjectExpression properties: [
expect(props.properties[0]).toMatchObject({ {
key: { key: {
content: `onVnodeMounted` content: `onVnodeMounted`
}, },
value: { value: {
content: `onMount` content: `onMount`
} }
}
]
}) })
}) })
@ -321,10 +351,12 @@ describe('compiler: transform v-on', () => {
cacheHandlers: true cacheHandlers: true
}) })
expect(root.cached).toBe(1) expect(root.cached).toBe(1)
const args = (node.codegenNode as PlainElementCodegenNode).arguments const vnodeCall = node.codegenNode as VNodeCall
// should not treat cached handler as dynamicProp, so no flags // should not treat cached handler as dynamicProp, so no flags
expect(args.length).toBe(2) expect(vnodeCall.patchFlag).toBeUndefined()
expect((args[1] as ObjectExpression).properties[0].value).toMatchObject({ expect(
(vnodeCall.props as ObjectExpression).properties[0].value
).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION, type: NodeTypes.JS_CACHE_EXPRESSION,
index: 1, index: 1,
value: { value: {
@ -340,10 +372,12 @@ describe('compiler: transform v-on', () => {
cacheHandlers: true cacheHandlers: true
}) })
expect(root.cached).toBe(1) expect(root.cached).toBe(1)
const args = (node.codegenNode as PlainElementCodegenNode).arguments const vnodeCall = node.codegenNode as VNodeCall
// should not treat cached handler as dynamicProp, so no flags // should not treat cached handler as dynamicProp, so no flags
expect(args.length).toBe(2) expect(vnodeCall.patchFlag).toBeUndefined()
expect((args[1] as ObjectExpression).properties[0].value).toMatchObject({ expect(
(vnodeCall.props as ObjectExpression).properties[0].value
).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION, type: NodeTypes.JS_CACHE_EXPRESSION,
index: 1, index: 1,
value: { value: {
@ -359,10 +393,12 @@ describe('compiler: transform v-on', () => {
cacheHandlers: true cacheHandlers: true
}) })
expect(root.cached).toBe(1) expect(root.cached).toBe(1)
const args = (node.codegenNode as PlainElementCodegenNode).arguments const vnodeCall = node.codegenNode as VNodeCall
// should not treat cached handler as dynamicProp, so no flags // should not treat cached handler as dynamicProp, so no flags
expect(args.length).toBe(2) expect(vnodeCall.patchFlag).toBeUndefined()
expect((args[1] as ObjectExpression).properties[0].value).toMatchObject({ expect(
(vnodeCall.props as ObjectExpression).properties[0].value
).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION, type: NodeTypes.JS_CACHE_EXPRESSION,
index: 1, index: 1,
value: { value: {
@ -378,10 +414,13 @@ describe('compiler: transform v-on', () => {
cacheHandlers: true cacheHandlers: true
}) })
expect(root.cached).toBe(1) expect(root.cached).toBe(1)
const args = (node.codegenNode as PlainElementCodegenNode).arguments expect(root.cached).toBe(1)
const vnodeCall = node.codegenNode as VNodeCall
// should not treat cached handler as dynamicProp, so no flags // should not treat cached handler as dynamicProp, so no flags
expect(args.length).toBe(2) expect(vnodeCall.patchFlag).toBeUndefined()
expect((args[1] as ObjectExpression).properties[0].value).toMatchObject({ expect(
(vnodeCall.props as ObjectExpression).properties[0].value
).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION, type: NodeTypes.JS_CACHE_EXPRESSION,
index: 1, index: 1,
value: { value: {

View File

@ -7,11 +7,7 @@ import {
} from '../../src' } from '../../src'
import { transformOnce } from '../../src/transforms/vOnce' import { transformOnce } from '../../src/transforms/vOnce'
import { transformElement } from '../../src/transforms/transformElement' import { transformElement } from '../../src/transforms/transformElement'
import { import { RENDER_SLOT, SET_BLOCK_TRACKING } from '../../src/runtimeHelpers'
CREATE_VNODE,
RENDER_SLOT,
SET_BLOCK_TRACKING
} from '../../src/runtimeHelpers'
import { transformBind } from '../../src/transforms/vBind' import { transformBind } from '../../src/transforms/vBind'
import { transformSlotOutlet } from '../../src/transforms/transformSlotOutlet' import { transformSlotOutlet } from '../../src/transforms/transformSlotOutlet'
@ -36,8 +32,8 @@ describe('compiler: v-once transform', () => {
type: NodeTypes.JS_CACHE_EXPRESSION, type: NodeTypes.JS_CACHE_EXPRESSION,
index: 1, index: 1,
value: { value: {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
callee: CREATE_VNODE tag: `"div"`
} }
}) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
@ -51,8 +47,8 @@ describe('compiler: v-once transform', () => {
type: NodeTypes.JS_CACHE_EXPRESSION, type: NodeTypes.JS_CACHE_EXPRESSION,
index: 1, index: 1,
value: { value: {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
callee: CREATE_VNODE tag: `"div"`
} }
}) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
@ -66,8 +62,8 @@ describe('compiler: v-once transform', () => {
type: NodeTypes.JS_CACHE_EXPRESSION, type: NodeTypes.JS_CACHE_EXPRESSION,
index: 1, index: 1,
value: { value: {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
callee: CREATE_VNODE tag: `_component_Comp`
} }
}) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
@ -100,8 +96,8 @@ describe('compiler: v-once transform', () => {
type: NodeTypes.JS_CACHE_EXPRESSION, type: NodeTypes.JS_CACHE_EXPRESSION,
index: 1, index: 1,
value: { value: {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
callee: CREATE_VNODE tag: `"div"`
} }
}) })
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()

View File

@ -7,8 +7,9 @@ import {
NodeTypes, NodeTypes,
ErrorCodes, ErrorCodes,
ForNode, ForNode,
CallExpression, ComponentNode,
ComponentNode VNodeCall,
SlotsExpression
} from '../../src' } from '../../src'
import { transformElement } from '../../src/transforms/transformElement' import { transformElement } from '../../src/transforms/transformElement'
import { transformOn } from '../../src/transforms/vOn' import { transformOn } from '../../src/transforms/vOn'
@ -46,7 +47,8 @@ function parseWithSlots(template: string, options: CompilerOptions = {}) {
root: ast, root: ast,
slots: slots:
ast.children[0].type === NodeTypes.ELEMENT ast.children[0].type === NodeTypes.ELEMENT
? (ast.children[0].codegenNode as CallExpression).arguments[2] ? ((ast.children[0].codegenNode as VNodeCall)
.children as SlotsExpression)
: null : null
} }
} }
@ -311,11 +313,10 @@ describe('compiler: transform component slots', () => {
{ {
type: NodeTypes.ELEMENT, type: NodeTypes.ELEMENT,
codegenNode: { codegenNode: {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.VNODE_CALL,
arguments: [ tag: `_component_Inner`,
`_component_Inner`, props: undefined,
`null`, children: createSlotMatcher({
createSlotMatcher({
default: { default: {
type: NodeTypes.JS_FUNCTION_EXPRESSION, type: NodeTypes.JS_FUNCTION_EXPRESSION,
params: { params: {
@ -346,8 +347,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.
genFlagText(PatchFlags.DYNAMIC_SLOTS) patchFlag: genFlagText(PatchFlags.DYNAMIC_SLOTS)
]
} }
}, },
// test scope // test scope
@ -388,8 +388,8 @@ 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.arguments[2][0] const comp = div.children[0]
expect(comp.codegenNode.arguments[3]).toBe( expect(comp.codegenNode.patchFlag).toBe(
genFlagText(PatchFlags.DYNAMIC_SLOTS) genFlagText(PatchFlags.DYNAMIC_SLOTS)
) )
}) })
@ -401,12 +401,12 @@ describe('compiler: transform component slots', () => {
if (root.children[0].type === NodeTypes.FOR) { if (root.children[0].type === NodeTypes.FOR) {
const div = (root.children[0].children[0] as ElementNode) const div = (root.children[0].children[0] as ElementNode)
.codegenNode as any .codegenNode as any
const comp = div.arguments[2][0] const comp = div.children[0]
flag = comp.codegenNode.arguments[3] flag = comp.codegenNode.patchFlag
} else { } else {
const innerComp = (root.children[0] as ComponentNode) const innerComp = (root.children[0] as ComponentNode)
.children[0] as ComponentNode .children[0] as ComponentNode
flag = (innerComp.codegenNode as CallExpression).arguments[3] flag = (innerComp.codegenNode as VNodeCall).patchFlag
} }
if (shouldForce) { if (shouldForce) {
expect(flag).toBe(genFlagText(PatchFlags.DYNAMIC_SLOTS)) expect(flag).toBe(genFlagText(PatchFlags.DYNAMIC_SLOTS))
@ -480,7 +480,7 @@ describe('compiler: transform component slots', () => {
} }
] ]
}) })
expect((root as any).children[0].codegenNode.arguments[3]).toMatch( expect((root as any).children[0].codegenNode.patchFlag).toMatch(
PatchFlags.DYNAMIC_SLOTS + '' PatchFlags.DYNAMIC_SLOTS + ''
) )
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
@ -528,7 +528,7 @@ describe('compiler: transform component slots', () => {
} }
] ]
}) })
expect((root as any).children[0].codegenNode.arguments[3]).toMatch( expect((root as any).children[0].codegenNode.patchFlag).toMatch(
PatchFlags.DYNAMIC_SLOTS + '' PatchFlags.DYNAMIC_SLOTS + ''
) )
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot() expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()
@ -588,7 +588,7 @@ describe('compiler: transform component slots', () => {
} }
] ]
}) })
expect((root as any).children[0].codegenNode.arguments[3]).toMatch( expect((root as any).children[0].codegenNode.patchFlag).toMatch(
PatchFlags.DYNAMIC_SLOTS + '' PatchFlags.DYNAMIC_SLOTS + ''
) )
expect(generate(root).code).toMatchSnapshot() expect(generate(root).code).toMatchSnapshot()
@ -638,7 +638,7 @@ describe('compiler: transform component slots', () => {
} }
] ]
}) })
expect((root as any).children[0].codegenNode.arguments[3]).toMatch( expect((root as any).children[0].codegenNode.patchFlag).toMatch(
PatchFlags.DYNAMIC_SLOTS + '' PatchFlags.DYNAMIC_SLOTS + ''
) )
expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot() expect(generate(root, { prefixIdentifiers: true }).code).toMatchSnapshot()

View File

@ -506,7 +506,7 @@ export function createRoot(
} }
export function createVNodeCall( export function createVNodeCall(
context: TransformContext, context: TransformContext | null,
tag: VNodeCall['tag'], tag: VNodeCall['tag'],
props?: VNodeCall['props'], props?: VNodeCall['props'],
children?: VNodeCall['children'], children?: VNodeCall['children'],
@ -517,6 +517,7 @@ export function createVNodeCall(
isForBlock: VNodeCall['isForBlock'] = false, isForBlock: VNodeCall['isForBlock'] = false,
loc = locStub loc = locStub
): VNodeCall { ): VNodeCall {
if (context) {
if (isBlock) { if (isBlock) {
context.helper(OPEN_BLOCK) context.helper(OPEN_BLOCK)
context.helper(CREATE_BLOCK) context.helper(CREATE_BLOCK)
@ -526,6 +527,7 @@ export function createVNodeCall(
if (directives) { if (directives) {
context.helper(WITH_DIRECTIVES) context.helper(WITH_DIRECTIVES)
} }
}
return { return {
type: NodeTypes.VNODE_CALL, type: NodeTypes.VNODE_CALL,

View File

@ -8,7 +8,7 @@ const _hoisted_1 = {}
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { createVNode: _createVNode, createBlock: _createBlock, Fragment: _Fragment, openBlock: _openBlock } = _Vue const { createVNode: _createVNode, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(_Fragment, null, [ return (_openBlock(), _createBlock(_Fragment, null, [
_createVNode(\\"div\\", { textContent: text }, null, 8 /* PROPS */, [\\"textContent\\"]), _createVNode(\\"div\\", { textContent: text }, null, 8 /* PROPS */, [\\"textContent\\"]),

View File

@ -5,14 +5,14 @@ exports[`compiler: transform v-model input w/ dynamic v-bind 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { vModelDynamic: _vModelDynamic, mergeProps: _mergeProps, createVNode: _createVNode, withDirectives: _withDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { vModelDynamic: _vModelDynamic, mergeProps: _mergeProps, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _withDirectives(_createBlock(\\"input\\", _mergeProps(obj, { return _withDirectives((_openBlock(), _createBlock(\\"input\\", _mergeProps(obj, {
modelValue: model, modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event) \\"onUpdate:modelValue\\": $event => (model = $event)
}), null, 16 /* FULL_PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [ }), null, 16 /* FULL_PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"])), [
[_vModelDynamic, model] [_vModelDynamic, model]
])) ])
} }
}" }"
`; `;
@ -22,17 +22,17 @@ exports[`compiler: transform v-model input w/ dynamic v-bind 2`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { vModelDynamic: _vModelDynamic, createVNode: _createVNode, withDirectives: _withDirectives, resolveDirective: _resolveDirective, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { vModelDynamic: _vModelDynamic, resolveDirective: _resolveDirective, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _directive_bind = _resolveDirective(\\"bind\\") const _directive_bind = _resolveDirective(\\"bind\\")
return (_openBlock(), _withDirectives(_createBlock(\\"input\\", { return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
modelValue: model, modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event) \\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [ }, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"])), [
[_directive_bind, val, key], [_directive_bind, val, key],
[_vModelDynamic, model] [_vModelDynamic, model]
])) ])
} }
}" }"
`; `;
@ -42,19 +42,19 @@ exports[`compiler: transform v-model modifiers .lazy 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _withDirectives(_createBlock(\\"input\\", { return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
modelValue: model, modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event) \\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [ }, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"])), [
[ [
_vModelText, _vModelText,
model, model,
void 0, void 0,
{ lazy: true } { lazy: true }
] ]
])) ])
} }
}" }"
`; `;
@ -64,19 +64,19 @@ exports[`compiler: transform v-model modifiers .number 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _withDirectives(_createBlock(\\"input\\", { return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
modelValue: model, modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event) \\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [ }, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"])), [
[ [
_vModelText, _vModelText,
model, model,
void 0, void 0,
{ number: true } { number: true }
] ]
])) ])
} }
}" }"
`; `;
@ -86,19 +86,19 @@ exports[`compiler: transform v-model modifiers .trim 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _withDirectives(_createBlock(\\"input\\", { return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
modelValue: model, modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event) \\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [ }, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"])), [
[ [
_vModelText, _vModelText,
model, model,
void 0, void 0,
{ trim: true } { trim: true }
] ]
])) ])
} }
}" }"
`; `;
@ -108,14 +108,14 @@ exports[`compiler: transform v-model simple expression 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _withDirectives(_createBlock(\\"input\\", { return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
modelValue: model, modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event) \\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [ }, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"])), [
[_vModelText, model] [_vModelText, model]
])) ])
} }
}" }"
`; `;
@ -125,15 +125,15 @@ exports[`compiler: transform v-model simple expression for input (checkbox) 1`]
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { vModelCheckbox: _vModelCheckbox, createVNode: _createVNode, withDirectives: _withDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { vModelCheckbox: _vModelCheckbox, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _withDirectives(_createBlock(\\"input\\", { return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
type: \\"checkbox\\", type: \\"checkbox\\",
modelValue: model, modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event) \\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [ }, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"])), [
[_vModelCheckbox, model] [_vModelCheckbox, model]
])) ])
} }
}" }"
`; `;
@ -143,17 +143,17 @@ exports[`compiler: transform v-model simple expression for input (dynamic type)
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { vModelDynamic: _vModelDynamic, createVNode: _createVNode, withDirectives: _withDirectives, resolveDirective: _resolveDirective, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { vModelDynamic: _vModelDynamic, resolveDirective: _resolveDirective, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _directive_bind = _resolveDirective(\\"bind\\") const _directive_bind = _resolveDirective(\\"bind\\")
return (_openBlock(), _withDirectives(_createBlock(\\"input\\", { return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
modelValue: model, modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event) \\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [ }, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"])), [
[_directive_bind, foo, \\"type\\"], [_directive_bind, foo, \\"type\\"],
[_vModelDynamic, model] [_vModelDynamic, model]
])) ])
} }
}" }"
`; `;
@ -163,15 +163,15 @@ exports[`compiler: transform v-model simple expression for input (radio) 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { vModelRadio: _vModelRadio, createVNode: _createVNode, withDirectives: _withDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { vModelRadio: _vModelRadio, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _withDirectives(_createBlock(\\"input\\", { return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
type: \\"radio\\", type: \\"radio\\",
modelValue: model, modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event) \\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [ }, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"])), [
[_vModelRadio, model] [_vModelRadio, model]
])) ])
} }
}" }"
`; `;
@ -181,15 +181,15 @@ exports[`compiler: transform v-model simple expression for input (text) 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _withDirectives(_createBlock(\\"input\\", { return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
type: \\"text\\", type: \\"text\\",
modelValue: model, modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event) \\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [ }, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"])), [
[_vModelText, model] [_vModelText, model]
])) ])
} }
}" }"
`; `;
@ -199,14 +199,14 @@ exports[`compiler: transform v-model simple expression for select 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { vModelSelect: _vModelSelect, createVNode: _createVNode, withDirectives: _withDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { vModelSelect: _vModelSelect, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _withDirectives(_createBlock(\\"select\\", { return _withDirectives((_openBlock(), _createBlock(\\"select\\", {
modelValue: model, modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event) \\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [ }, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"])), [
[_vModelSelect, model] [_vModelSelect, model]
])) ])
} }
}" }"
`; `;
@ -216,14 +216,14 @@ exports[`compiler: transform v-model simple expression for textarea 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _withDirectives(_createBlock(\\"textarea\\", { return _withDirectives((_openBlock(), _createBlock(\\"textarea\\", {
modelValue: model, modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event) \\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [ }, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"])), [
[_vModelText, model] [_vModelText, model]
])) ])
} }
}" }"
`; `;

View File

@ -5,11 +5,11 @@ exports[`compiler: v-show transform simple expression 1`] = `
return function render(_ctx, _cache) { return function render(_ctx, _cache) {
with (this) { with (this) {
const { vShow: _vShow, createVNode: _createVNode, withDirectives: _withDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue const { vShow: _vShow, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _withDirectives(_createBlock(\\"div\\", null, null, 32 /* NEED_PATCH */), [ return _withDirectives((_openBlock(), _createBlock(\\"div\\", null, null, 32 /* NEED_PATCH */)), [
[_vShow, a] [_vShow, a]
])) ])
} }
}" }"
`; `;

View File

@ -4,7 +4,7 @@ import {
CompilerOptions, CompilerOptions,
ElementNode, ElementNode,
NodeTypes, NodeTypes,
CallExpression VNodeCall
} from '@vue/compiler-core' } from '@vue/compiler-core'
import { transformBind } from '../../../compiler-core/src/transforms/vBind' import { transformBind } from '../../../compiler-core/src/transforms/vBind'
import { transformElement } from '../../../compiler-core/src/transforms/transformElement' import { transformElement } from '../../../compiler-core/src/transforms/transformElement'
@ -60,7 +60,7 @@ describe('compiler: style transform', () => {
bind: transformBind bind: transformBind
} }
}) })
expect((node.codegenNode as CallExpression).arguments[1]).toMatchObject({ expect((node.codegenNode as VNodeCall).props).toMatchObject({
type: NodeTypes.JS_OBJECT_EXPRESSION, type: NodeTypes.JS_OBJECT_EXPRESSION,
properties: [ properties: [
{ {
@ -78,6 +78,6 @@ describe('compiler: style transform', () => {
] ]
}) })
// should not cause the STYLE patchFlag to be attached // should not cause the STYLE patchFlag to be attached
expect((node.codegenNode as CallExpression).arguments.length).toBe(2) expect((node.codegenNode as VNodeCall).patchFlag).toBeUndefined()
}) })
}) })

View File

@ -29,15 +29,13 @@ describe('compiler: v-html transform', () => {
it('should convert v-html to innerHTML', () => { it('should convert v-html to innerHTML', () => {
const ast = transformWithVHtml(`<div v-html="test"/>`) const ast = transformWithVHtml(`<div v-html="test"/>`)
expect((ast.children[0] as PlainElementNode).codegenNode).toMatchObject({ expect((ast.children[0] as PlainElementNode).codegenNode).toMatchObject({
arguments: [ tag: `"div"`,
`"div"`, props: createObjectMatcher({
createObjectMatcher({
innerHTML: `[test]` innerHTML: `[test]`
}), }),
`null`, children: undefined,
genFlagText(PatchFlags.PROPS), patchFlag: genFlagText(PatchFlags.PROPS),
`["innerHTML"]` dynamicProps: `["innerHTML"]`
]
}) })
}) })
@ -50,15 +48,13 @@ describe('compiler: v-html transform', () => {
[{ code: DOMErrorCodes.X_V_HTML_WITH_CHILDREN }] [{ code: DOMErrorCodes.X_V_HTML_WITH_CHILDREN }]
]) ])
expect((ast.children[0] as PlainElementNode).codegenNode).toMatchObject({ expect((ast.children[0] as PlainElementNode).codegenNode).toMatchObject({
arguments: [ tag: `"div"`,
`"div"`, props: createObjectMatcher({
createObjectMatcher({
innerHTML: `[test]` innerHTML: `[test]`
}), }),
`null`, // <-- children should have been removed children: undefined, // <-- children should have been removed
genFlagText(PatchFlags.PROPS), patchFlag: genFlagText(PatchFlags.PROPS),
`["innerHTML"]` dynamicProps: `["innerHTML"]`
]
}) })
}) })

View File

@ -4,8 +4,8 @@ import {
CompilerOptions, CompilerOptions,
ElementNode, ElementNode,
ObjectExpression, ObjectExpression,
CallExpression, NodeTypes,
NodeTypes VNodeCall
} from '@vue/compiler-core' } from '@vue/compiler-core'
import { transformOn } from '../../src/transforms/vOn' import { transformOn } from '../../src/transforms/vOn'
import { V_ON_WITH_MODIFIERS, V_ON_WITH_KEYS } from '../../src/runtimeHelpers' import { V_ON_WITH_MODIFIERS, V_ON_WITH_KEYS } from '../../src/runtimeHelpers'
@ -24,8 +24,8 @@ function parseWithVOn(template: string, options: CompilerOptions = {}) {
}) })
return { return {
root: ast, root: ast,
props: (((ast.children[0] as ElementNode).codegenNode as CallExpression) props: (((ast.children[0] as ElementNode).codegenNode as VNodeCall)
.arguments[1] as ObjectExpression).properties .props as ObjectExpression).properties
} }
} }
@ -158,7 +158,7 @@ describe('compiler-dom: transform v-on', () => {
}) })
expect(root.cached).toBe(1) expect(root.cached).toBe(1)
// should not treat cached handler as dynamicProp, so no flags // should not treat cached handler as dynamicProp, so no flags
expect((root as any).children[0].codegenNode.arguments.length).toBe(2) expect((root as any).children[0].codegenNode.patchFlag).toBeUndefined()
expect(prop.value).toMatchObject({ expect(prop.value).toMatchObject({
type: NodeTypes.JS_CACHE_EXPRESSION, type: NodeTypes.JS_CACHE_EXPRESSION,
index: 1, index: 1,

View File

@ -29,15 +29,13 @@ describe('compiler: v-text transform', () => {
it('should convert v-text to textContent', () => { it('should convert v-text to textContent', () => {
const ast = transformWithVText(`<div v-text="test"/>`) const ast = transformWithVText(`<div v-text="test"/>`)
expect((ast.children[0] as PlainElementNode).codegenNode).toMatchObject({ expect((ast.children[0] as PlainElementNode).codegenNode).toMatchObject({
arguments: [ tag: `"div"`,
`"div"`, props: createObjectMatcher({
createObjectMatcher({
textContent: `[test]` textContent: `[test]`
}), }),
`null`, children: undefined,
genFlagText(PatchFlags.PROPS), patchFlag: genFlagText(PatchFlags.PROPS),
`["textContent"]` dynamicProps: `["textContent"]`
]
}) })
}) })
@ -50,15 +48,13 @@ describe('compiler: v-text transform', () => {
[{ code: DOMErrorCodes.X_V_TEXT_WITH_CHILDREN }] [{ code: DOMErrorCodes.X_V_TEXT_WITH_CHILDREN }]
]) ])
expect((ast.children[0] as PlainElementNode).codegenNode).toMatchObject({ expect((ast.children[0] as PlainElementNode).codegenNode).toMatchObject({
arguments: [ tag: `"div"`,
`"div"`, props: createObjectMatcher({
createObjectMatcher({
textContent: `[test]` textContent: `[test]`
}), }),
`null`, // <-- children should have been removed children: undefined, // <-- children should have been removed
genFlagText(PatchFlags.PROPS), patchFlag: genFlagText(PatchFlags.PROPS),
`["textContent"]` dynamicProps: `["textContent"]`
]
}) })
}) })

View File

@ -2,7 +2,7 @@
exports[`source map 1`] = ` exports[`source map 1`] = `
Object { Object {
"mappings": ";;;UAAA,cACE,aAA8B;IAAzB,aAAmB,4BAAbA,WAAM", "mappings": ";;;wBACE,aAA8B;IAAzB,aAAmB,4BAAbA,WAAM",
"names": Array [ "names": Array [
"render", "render",
], ],

View File

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`compiler sfc: transform asset url support uri fragment 1`] = ` exports[`compiler sfc: transform asset url support uri fragment 1`] = `
"import { createVNode as _createVNode, createBlock as _createBlock, openBlock as _openBlock } from \\"vue\\" "import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
import _imports_0 from '@svg/file.svg' import _imports_0 from '@svg/file.svg'
@ -13,7 +13,7 @@ export function render(_ctx, _cache) {
`; `;
exports[`compiler sfc: transform asset url support uri is empty 1`] = ` exports[`compiler sfc: transform asset url support uri is empty 1`] = `
"import { createVNode as _createVNode, createBlock as _createBlock, openBlock as _openBlock } from \\"vue\\" "import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
export function render(_ctx, _cache) { export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"use\\", { href: '' })) return (_openBlock(), _createBlock(\\"use\\", { href: '' }))
@ -21,7 +21,7 @@ export function render(_ctx, _cache) {
`; `;
exports[`compiler sfc: transform asset url transform assetUrls 1`] = ` exports[`compiler sfc: transform asset url transform assetUrls 1`] = `
"import { createVNode as _createVNode, createBlock as _createBlock, Fragment as _Fragment, openBlock as _openBlock } from \\"vue\\" "import { createVNode as _createVNode, Fragment as _Fragment, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
import _imports_0 from './logo.png' import _imports_0 from './logo.png'
import _imports_1 from 'fixtures/logo.png' import _imports_1 from 'fixtures/logo.png'

View File

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`compiler sfc: transform srcset transform srcset 1`] = ` exports[`compiler sfc: transform srcset transform srcset 1`] = `
"import { createVNode as _createVNode, createBlock as _createBlock, Fragment as _Fragment, openBlock as _openBlock } from \\"vue\\" "import { createVNode as _createVNode, Fragment as _Fragment, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
import _imports_0 from './logo.png' import _imports_0 from './logo.png'

View File

@ -209,7 +209,7 @@ describe('ssr: components', () => {
</template> </template>
</foo>`).code </foo>`).code
).toMatchInlineSnapshot(` ).toMatchInlineSnapshot(`
"const { resolveComponent: _resolveComponent, renderList: _renderList, openBlock: _openBlock, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode, createCommentVNode: _createCommentVNode } = require(\\"vue\\") "const { resolveComponent: _resolveComponent, renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode, createCommentVNode: _createCommentVNode } = require(\\"vue\\")
const { ssrRenderComponent: _ssrRenderComponent, ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\") const { ssrRenderComponent: _ssrRenderComponent, ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\")
return function ssrRender(_ctx, _push, _parent) { return function ssrRender(_ctx, _push, _parent) {
@ -229,13 +229,13 @@ describe('ssr: components', () => {
} }
} else { } else {
return [ return [
(_openBlock(), (_ctx.ok) (_ctx.ok)
? _createBlock(\\"div\\", { key: 0 }, [ ? (_openBlock(), _createBlock(\\"div\\", { key: 0 }, [
(_openBlock(true), _createBlock(_Fragment, null, _renderList(list, (i) => { (_openBlock(true), _createBlock(_Fragment, null, _renderList(list, (i) => {
return (_openBlock(), _createBlock(\\"span\\")) return (_openBlock(), _createBlock(\\"span\\"))
}), 256 /* UNKEYED_FRAGMENT */)) }), 256 /* UNKEYED_FRAGMENT */))
]) ]))
: _createCommentVNode(\\"v-if\\", true)) : _createCommentVNode(\\"v-if\\", true)
] ]
} }
}, },
@ -252,13 +252,13 @@ describe('ssr: components', () => {
} }
} else { } else {
return [ return [
(_openBlock(), ok ok
? _createBlock(\\"div\\", { key: 0 }, [ ? (_openBlock(), _createBlock(\\"div\\", { key: 0 }, [
(_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.list, (i) => { (_openBlock(true), _createBlock(_Fragment, null, _renderList(_ctx.list, (i) => {
return (_openBlock(), _createBlock(\\"span\\")) return (_openBlock(), _createBlock(\\"span\\"))
}), 256 /* UNKEYED_FRAGMENT */)) }), 256 /* UNKEYED_FRAGMENT */))
]) ]))
: _createCommentVNode(\\"v-if\\", true)) : _createCommentVNode(\\"v-if\\", true)
] ]
} }
}, },