"
return function render() {
with (this) {
- return (foo, ok
+ return ok
? foo()
: orNot
? bar()
- : baz())
+ : baz()
}
}"
`;
-exports[`compiler: codegen SequenceExpression 1`] = `
-"
-return function render() {
- with (this) {
- return (foo, bar(baz))
- }
-}"
-`;
-
-exports[`compiler: codegen callExpression + objectExpression + arrayExpression 1`] = `
+exports[`compiler: codegen Element (callExpression + objectExpression + arrayExpression) 1`] = `
"
return function render() {
with (this) {
}"
`;
+exports[`compiler: codegen SequenceExpression 1`] = `
+"
+return function render() {
+ with (this) {
+ return (foo, bar(baz))
+ }
+}"
+`;
+
exports[`compiler: codegen comment 1`] = `
"
return function render() {
}"
`;
+exports[`compiler: codegen forNode 1`] = `
+"
+return function render() {
+ with (this) {
+ return (foo, bar)
+ }
+}"
+`;
+
exports[`compiler: codegen function mode preamble 1`] = `
"const _Vue = Vue
}
}"
`;
-
-exports[`compiler: codegen text + comment + interpolation 1`] = `
-"
-return function render() {
- with (this) {
- return [
- \\"foo\\",
- _toString(hello),
- _createVNode(_Comment, 0, \\"foo\\")
- ]
- }
-}"
-`;
-
-exports[`compiler: codegen text + comment + interpolation w/ prefixIdentifiers: true 1`] = `
-"
-return function render() {
- const _ctx = this
- return [
- \\"foo\\",
- toString(hello),
- createVNode(Comment, 0, \\"foo\\")
- ]
-}"
-`;
with (this) {
const { toString: _toString, openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, Empty: _Empty, Fragment: _Fragment, renderList: _renderList } = _Vue
- return _createVNode(\\"div\\", {
+ return (_openBlock(), _createBlock(\\"div\\", {
id: \\"foo\\",
class: bar.baz
}, [
_createVNode(\\"span\\", null, _toString(value + index), 1 /* TEXT */)
]))
}), 128 /* UNKEYED_FRAGMENT */))
- ], 2 /* CLASS */)
+ ], 2 /* CLASS */))
}
}"
`;
return function render() {
const _ctx = this
- return createVNode(\\"div\\", {
+ return (openBlock(), createBlock(\\"div\\", {
id: \\"foo\\",
class: _ctx.bar.baz
}, [
createVNode(\\"span\\", null, toString(value + index), 1 /* TEXT */)
]))
}), 128 /* UNKEYED_FRAGMENT */))
- ], 2 /* CLASS */)
+ ], 2 /* CLASS */))
}"
`;
export default function render() {
const _ctx = this
- return createVNode(\\"div\\", {
+ return (openBlock(), createBlock(\\"div\\", {
id: \\"foo\\",
class: _ctx.bar.baz
}, [
createVNode(\\"span\\", null, _toString(value + index), 1 /* TEXT */)
]))
}), 128 /* UNKEYED_FRAGMENT */))
- ], 2 /* CLASS */)
+ ], 2 /* CLASS */))
}"
`;
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 3,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 2,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 2,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 5,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
"type": 1,
},
],
+ "codegenNode": undefined,
"hoists": Array [],
"imports": Array [],
"loc": Object {
imports: [],
statements: [],
hoists: [],
+ codegenNode: undefined,
loc: locStub,
...options
}
test('static text', () => {
const { code } = generate(
createRoot({
- children: [
- {
- type: NodeTypes.TEXT,
- content: 'hello',
- isEmpty: false,
- loc: locStub
- }
- ]
+ codegenNode: {
+ type: NodeTypes.TEXT,
+ content: 'hello',
+ isEmpty: false,
+ loc: locStub
+ }
})
)
expect(code).toMatch(`return "hello"`)
test('interpolation', () => {
const { code } = generate(
createRoot({
- children: [createInterpolation(`hello`, locStub)]
+ codegenNode: createInterpolation(`hello`, locStub)
})
)
expect(code).toMatch(`return _${TO_STRING}(hello)`)
test('comment', () => {
const { code } = generate(
createRoot({
- children: [
- {
- type: NodeTypes.COMMENT,
- content: 'foo',
- loc: locStub
- }
- ]
+ codegenNode: {
+ type: NodeTypes.COMMENT,
+ content: 'foo',
+ loc: locStub
+ }
})
)
expect(code).toMatch(`return _${CREATE_VNODE}(_${COMMENT}, 0, "foo")`)
expect(code).toMatchSnapshot()
})
- test('text + comment + interpolation', () => {
+ test('compound expression', () => {
const { code } = generate(
createRoot({
- children: [
- {
- type: NodeTypes.TEXT,
- content: 'foo',
- isEmpty: false,
- loc: locStub
- },
- createInterpolation(`hello`, locStub),
+ codegenNode: createCompoundExpression([
+ `_ctx.`,
+ createSimpleExpression(`foo`, false, locStub),
+ ` + `,
{
- type: NodeTypes.COMMENT,
- content: 'foo',
- loc: locStub
+ type: NodeTypes.INTERPOLATION,
+ loc: locStub,
+ content: createSimpleExpression(`bar`, false, locStub)
}
- ]
+ ])
})
)
- expect(code).toMatch(`
- return [
- "foo",
- _${TO_STRING}(hello),
- _${CREATE_VNODE}(_${COMMENT}, 0, "foo")
- ]`)
- expect(code).toMatchSnapshot()
- })
-
- test('text + comment + interpolation w/ prefixIdentifiers: true', () => {
- const { code } = generate(
- createRoot({
- children: [
- {
- type: NodeTypes.TEXT,
- content: 'foo',
- isEmpty: false,
- loc: locStub
- },
- createInterpolation(`hello`, locStub),
- {
- type: NodeTypes.COMMENT,
- content: 'foo',
- loc: locStub
- }
- ]
- }),
- {
- prefixIdentifiers: true
- }
- )
- expect(code).toMatch(`
- return [
- "foo",
- ${TO_STRING}(hello),
- ${CREATE_VNODE}(${COMMENT}, 0, "foo")
- ]`)
+ expect(code).toMatch(`return _ctx.foo + _${TO_STRING}(bar)`)
expect(code).toMatchSnapshot()
})
- test('compound expression', () => {
+ test('ifNode', () => {
const { code } = generate(
createRoot({
- children: [
- createCompoundExpression([
- `_ctx.`,
- createSimpleExpression(`foo`, false, locStub),
- ` + `,
- {
- type: NodeTypes.INTERPOLATION,
- loc: locStub,
- content: createSimpleExpression(`bar`, false, locStub)
- }
+ codegenNode: {
+ type: NodeTypes.IF,
+ loc: locStub,
+ branches: [],
+ codegenNode: createSequenceExpression([
+ createSimpleExpression('foo', false),
+ createSimpleExpression('bar', false)
])
- ]
+ }
})
)
- expect(code).toMatch(`return _ctx.foo + _${TO_STRING}(bar)`)
+ expect(code).toMatch(`return (foo, bar)`)
expect(code).toMatchSnapshot()
})
- test('ifNode', () => {
+ test('forNode', () => {
const { code } = generate(
createRoot({
- children: [
- {
- type: NodeTypes.IF,
- loc: locStub,
- branches: [],
- codegenNode: createSequenceExpression([
- createSimpleExpression('foo', false),
- createSimpleExpression('bar', false)
- ])
- }
- ]
+ codegenNode: {
+ type: NodeTypes.FOR,
+ loc: locStub,
+ source: createSimpleExpression('foo', false),
+ valueAlias: undefined,
+ keyAlias: undefined,
+ objectIndexAlias: undefined,
+ children: [],
+ codegenNode: createSequenceExpression([
+ createSimpleExpression('foo', false),
+ createSimpleExpression('bar', false)
+ ])
+ }
})
)
expect(code).toMatch(`return (foo, bar)`)
expect(code).toMatchSnapshot()
})
- // test('forNode', () => {
- // const { code } = generate(
- // createRoot({
- // children: [
- // {
- // type: NodeTypes.FOR,
- // loc: locStub,
- // source: createSimpleExpression(`list`, false, locStub),
- // valueAlias: createSimpleExpression(`v`, false, locStub),
- // keyAlias: createSimpleExpression(`k`, false, locStub),
- // objectIndexAlias: createSimpleExpression(`i`, false, locStub),
- // children: [createInterpolation(`v`, locStub)]
- // }
- // ]
- // })
- // )
- // expect(code).toMatch(
- // `return _${RENDER_LIST}(list, (v, k, i) => {
- // return _${TO_STRING}(v)
- // })`
- // )
- // expect(code).toMatchSnapshot()
- // })
-
- // test('forNode w/ prefixIdentifiers: true', () => {
- // const { code } = generate(
- // createRoot({
- // children: [
- // {
- // type: NodeTypes.FOR,
- // loc: locStub,
- // source: createSimpleExpression(`list`, false, locStub),
- // valueAlias: createSimpleExpression(`v`, false, locStub),
- // keyAlias: createSimpleExpression(`k`, false, locStub),
- // objectIndexAlias: createSimpleExpression(`i`, false, locStub),
- // children: [createInterpolation(`v`, locStub)]
- // }
- // ]
- // }),
- // {
- // prefixIdentifiers: true
- // }
- // )
- // expect(code).toMatch(
- // `return ${RENDER_LIST}(list, (v, k, i) => {
- // return ${TO_STRING}(v)
- // })`
- // )
- // expect(code).toMatchSnapshot()
- // })
-
- // test('forNode w/ skipped value alias', () => {
- // const { code } = generate(
- // createRoot({
- // children: [
- // {
- // type: NodeTypes.FOR,
- // loc: locStub,
- // source: createSimpleExpression(`list`, false, locStub),
- // valueAlias: undefined,
- // keyAlias: createSimpleExpression(`k`, false, locStub),
- // objectIndexAlias: createSimpleExpression(`i`, false, locStub),
- // children: [createInterpolation(`v`, locStub)]
- // }
- // ]
- // })
- // )
- // expect(code).toMatch(
- // `return _${RENDER_LIST}(list, (__value, k, i) => {
- // return _${TO_STRING}(v)
- // })`
- // )
- // expect(code).toMatchSnapshot()
- // })
-
- // test('forNode w/ skipped key alias', () => {
- // const { code } = generate(
- // createRoot({
- // children: [
- // {
- // type: NodeTypes.FOR,
- // loc: locStub,
- // source: createSimpleExpression(`list`, false, locStub),
- // valueAlias: createSimpleExpression(`v`, false, locStub),
- // keyAlias: undefined,
- // objectIndexAlias: createSimpleExpression(`i`, false, locStub),
- // children: [createInterpolation(`v`, locStub)]
- // }
- // ]
- // })
- // )
- // expect(code).toMatch(
- // `return _${RENDER_LIST}(list, (v, __key, i) => {
- // return _${TO_STRING}(v)
- // })`
- // )
- // expect(code).toMatchSnapshot()
- // })
-
- // test('forNode w/ skipped value and key aliases', () => {
- // const { code } = generate(
- // createRoot({
- // children: [
- // {
- // type: NodeTypes.FOR,
- // loc: locStub,
- // source: createSimpleExpression(`list`, false, locStub),
- // valueAlias: undefined,
- // keyAlias: undefined,
- // objectIndexAlias: createSimpleExpression(`i`, false, locStub),
- // children: [createInterpolation(`v`, locStub)]
- // }
- // ]
- // })
- // )
- // expect(code).toMatch(
- // `return _${RENDER_LIST}(list, (__value, __key, i) => {
- // return _${TO_STRING}(v)
- // })`
- // )
- // expect(code).toMatchSnapshot()
- // })
-
- // test('SlotFunctionExpression', () => {
- // const { code } = generate(
- // createRoot({
- // children: [
- // {
- // type: NodeTypes.ELEMENT,
- // tagType: ElementTypes.COMPONENT,
- // ns: Namespaces.HTML,
- // isSelfClosing: false,
- // tag: `Comp`,
- // loc: locStub,
- // props: [],
- // children: [],
- // codegenNode: {
- // type: NodeTypes.JS_CALL_EXPRESSION,
- // loc: locStub,
- // callee: `_${CREATE_VNODE}`,
- // arguments: [
- // `Comp`,
- // `0`,
- // {
- // type: NodeTypes.JS_OBJECT_EXPRESSION,
- // loc: locStub,
- // properties: [
- // {
- // type: NodeTypes.JS_PROPERTY,
- // loc: locStub,
- // key: {
- // type: NodeTypes.SIMPLE_EXPRESSION,
- // isStatic: true,
- // content: `default`,
- // loc: locStub
- // },
- // value: {
- // type: NodeTypes.JS_FUNCTION_EXPRESSION,
- // loc: locStub,
- // params: {
- // type: NodeTypes.SIMPLE_EXPRESSION,
- // isStatic: false,
- // content: `{ foo }`,
- // loc: locStub
- // },
- // returns: [
- // {
- // type: NodeTypes.INTERPOLATION,
- // loc: locStub,
- // content: {
- // type: NodeTypes.SIMPLE_EXPRESSION,
- // isStatic: false,
- // content: `foo`,
- // loc: locStub
- // }
- // }
- // ]
- // }
- // }
- // ]
- // }
- // ]
- // }
- // }
- // ]
- // })
- // )
- // expect(code).toMatch(
- // `return _createVNode(Comp, 0, {
- // default: ({ foo }) => [
- // _toString(foo)
- // ]
- // })`
- // )
- // expect(code).toMatchSnapshot()
- // })
-
- test('callExpression + objectExpression + arrayExpression', () => {
+ test('Element (callExpression + objectExpression + arrayExpression)', () => {
const { code } = generate(
createRoot({
- children: [
- createElementWithCodegen([
- // string
- `"div"`,
- // ObjectExpression
- createObjectExpression(
- [
- createObjectProperty(
- createSimpleExpression(`id`, true, locStub),
- createSimpleExpression(`foo`, true, locStub)
- ),
- createObjectProperty(
- createSimpleExpression(`prop`, false, locStub),
- createSimpleExpression(`bar`, false, locStub)
- ),
- // compound expression as computed key
- createObjectProperty(
- {
- type: NodeTypes.COMPOUND_EXPRESSION,
- loc: locStub,
- children: [
- `foo + `,
- createSimpleExpression(`bar`, false, locStub)
- ]
- },
- createSimpleExpression(`bar`, false, locStub)
- )
- ],
- locStub
- ),
- // ChildNode[]
+ codegenNode: createElementWithCodegen([
+ // string
+ `"div"`,
+ // ObjectExpression
+ createObjectExpression(
[
- createElementWithCodegen([
- `"p"`,
- createObjectExpression(
- [
- createObjectProperty(
- // should quote the key!
- createSimpleExpression(`some-key`, true, locStub),
- createSimpleExpression(`foo`, true, locStub)
- )
- ],
- locStub
- )
- ])
- ],
- // ArrayExpression
- createArrayExpression(
- [
- 'foo',
+ createObjectProperty(
+ createSimpleExpression(`id`, true, locStub),
+ createSimpleExpression(`foo`, true, locStub)
+ ),
+ createObjectProperty(
+ createSimpleExpression(`prop`, false, locStub),
+ createSimpleExpression(`bar`, false, locStub)
+ ),
+ // compound expression as computed key
+ createObjectProperty(
{
- type: NodeTypes.JS_CALL_EXPRESSION,
+ type: NodeTypes.COMPOUND_EXPRESSION,
loc: locStub,
- callee: CREATE_VNODE,
- arguments: [`"p"`]
- }
- ],
- locStub
- )
- ])
- ]
+ children: [
+ `foo + `,
+ createSimpleExpression(`bar`, false, locStub)
+ ]
+ },
+ createSimpleExpression(`bar`, false, locStub)
+ )
+ ],
+ locStub
+ ),
+ // ChildNode[]
+ [
+ createElementWithCodegen([
+ `"p"`,
+ createObjectExpression(
+ [
+ createObjectProperty(
+ // should quote the key!
+ createSimpleExpression(`some-key`, true, locStub),
+ createSimpleExpression(`foo`, true, locStub)
+ )
+ ],
+ locStub
+ )
+ ])
+ ],
+ // ArrayExpression
+ createArrayExpression(
+ [
+ 'foo',
+ {
+ type: NodeTypes.JS_CALL_EXPRESSION,
+ loc: locStub,
+ callee: CREATE_VNODE,
+ arguments: [`"p"`]
+ }
+ ],
+ locStub
+ )
+ ])
})
)
expect(code).toMatch(`
test('SequenceExpression', () => {
const { code } = generate(
createRoot({
- children: [
- {
- type: NodeTypes.IF,
- loc: locStub,
- branches: [],
- codegenNode: createSequenceExpression([
- createSimpleExpression(`foo`, false),
- createCallExpression(`bar`, [`baz`])
- ])
- }
- ]
+ codegenNode: createSequenceExpression([
+ createSimpleExpression(`foo`, false),
+ createCallExpression(`bar`, [`baz`])
+ ])
})
)
expect(code).toMatch(`return (foo, bar(baz))`)
test('ConditionalExpression', () => {
const { code } = generate(
createRoot({
- children: [
- {
- type: NodeTypes.IF,
- loc: locStub,
- branches: [],
- codegenNode: createSequenceExpression([
- createSimpleExpression(`foo`, false),
- createConditionalExpression(
- createSimpleExpression(`ok`, false),
- createCallExpression(`foo`),
- createConditionalExpression(
- createSimpleExpression(`orNot`, false),
- createCallExpression(`bar`),
- createCallExpression(`baz`)
- )
- )
- ])
- }
- ]
+ codegenNode: createConditionalExpression(
+ createSimpleExpression(`ok`, false),
+ createCallExpression(`foo`),
+ createConditionalExpression(
+ createSimpleExpression(`orNot`, false),
+ createCallExpression(`bar`),
+ createCallExpression(`baz`)
+ )
+ )
})
)
expect(code).toMatch(
- `return (foo, ok
+ `return ok
? foo()
: orNot
? bar()
- : baz())`
+ : baz()`
)
expect(code).toMatchSnapshot()
})
return function render() {
with (this) {
- const { createVNode: _createVNode, toString: _toString } = _Vue
+ const { createVNode: _createVNode, toString: _toString, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
- return [
+ return (_openBlock(), _createBlock(_Fragment, null, [
_createVNode(\\"div\\"),
_toString(foo) + \\" bar \\" + _toString(baz),
_createVNode(\\"div\\")
- ]
+ ]))
}
}"
`;
return function render() {
with (this) {
- const { createVNode: _createVNode, toString: _toString } = _Vue
+ const { createVNode: _createVNode, toString: _toString, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
- return [
+ return (_openBlock(), _createBlock(_Fragment, null, [
_createVNode(\\"div\\"),
_toString(foo) + \\" bar \\" + _toString(baz),
_createVNode(\\"div\\"),
_toString(foo) + \\" bar \\" + _toString(baz),
_createVNode(\\"div\\")
- ]
+ ]))
}
}"
`;
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`compiler: transform component slots dynamically named slots 1`] = `
-"const { toString, resolveComponent, createVNode } = Vue
+"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue
return function render() {
const _ctx = this
const _component_Comp = resolveComponent(\\"Comp\\")
- return createVNode(_component_Comp, null, {
+ return (openBlock(), createBlock(_component_Comp, null, {
[_ctx.one]: ({ foo }) => [
toString(foo),
toString(_ctx.bar)
toString(_ctx.foo),
toString(bar)
]
- }, 256 /* DYNAMIC_SLOTS */)
+ }, 256 /* DYNAMIC_SLOTS */))
}"
`;
exports[`compiler: transform component slots explicit default slot 1`] = `
-"const { toString, resolveComponent, createVNode } = Vue
+"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue
return function render() {
const _ctx = this
const _component_Comp = resolveComponent(\\"Comp\\")
- return createVNode(_component_Comp, null, {
+ return (openBlock(), createBlock(_component_Comp, null, {
default: ({ foo }) => [
toString(foo),
toString(_ctx.bar)
]
- })
+ }))
}"
`;
exports[`compiler: transform component slots implicit default slot 1`] = `
-"const { createVNode, resolveComponent } = Vue
+"const { createVNode, resolveComponent, openBlock, createBlock } = Vue
return function render() {
const _ctx = this
const _component_Comp = resolveComponent(\\"Comp\\")
- return createVNode(_component_Comp, null, {
+ return (openBlock(), createBlock(_component_Comp, null, {
default: () => [
createVNode(\\"div\\")
]
- })
+ }))
}"
`;
exports[`compiler: transform component slots named slots 1`] = `
-"const { toString, resolveComponent, createVNode } = Vue
+"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue
return function render() {
const _ctx = this
const _component_Comp = resolveComponent(\\"Comp\\")
- return createVNode(_component_Comp, null, {
+ return (openBlock(), createBlock(_component_Comp, null, {
one: ({ foo }) => [
toString(foo),
toString(_ctx.bar)
toString(_ctx.foo),
toString(bar)
]
- })
+ }))
}"
`;
exports[`compiler: transform component slots nested slots scoping 1`] = `
-"const { toString, resolveComponent, createVNode } = Vue
+"const { toString, resolveComponent, createVNode, openBlock, createBlock } = Vue
return function render() {
const _ctx = this
const _component_Inner = resolveComponent(\\"Inner\\")
const _component_Comp = resolveComponent(\\"Comp\\")
- return createVNode(_component_Comp, null, {
+ return (openBlock(), createBlock(_component_Comp, null, {
default: ({ foo }) => [
createVNode(_component_Inner, null, {
default: ({ bar }) => [
toString(_ctx.bar),
toString(_ctx.baz)
]
- })
+ }))
}"
`;
})
})
+ test('should handle plain <template> as normal element', () => {
+ const { node } = parseWithElementTransform(`<template id="foo" />`)
+ expect(node.callee).toBe(`_${CREATE_VNODE}`)
+ expect(node.arguments).toMatchObject([
+ `"template"`,
+ createObjectMatcher({
+ id: 'foo'
+ })
+ ])
+ })
+
test('error on v-bind with no argument', () => {
const onError = jest.fn()
parseWithElementTransform(`<div v-bind/>`, { onError })
imports: string[]
statements: string[]
hoists: JSChildNode[]
+ codegenNode: TemplateChildNode | JSChildNode | undefined
}
export interface ElementNode extends Node {
// generate the VNode tree expression
push(`return `)
-
- genRoot(ast, context)
+ if (ast.codegenNode) {
+ genNode(ast.codegenNode, context)
+ } else {
+ push(`null`)
+ }
if (useWithBlock) {
deindent()
context.newline()
}
-function genRoot(root: RootNode, context: CodegenContext) {
- // TODO handle blocks
- const { children } = root
- if (children.length === 0) {
- context.push(`null`)
- } else if (children.length === 1) {
- genNode(children[0], context)
- } else {
- genNodeListAsArray(children, context)
- }
-}
-
function genNodeListAsArray(
nodes: (string | CodegenNode | TemplateChildNode[])[],
context: CodegenContext
imports: [],
statements: [],
hoists: [],
+ codegenNode: undefined,
loc: getSelection(context, start)
}
}
ExpressionNode,
createSimpleExpression,
JSChildNode,
- SimpleExpressionNode
+ SimpleExpressionNode,
+ ElementTypes
} from './ast'
import { isString, isArray } from '@vue/shared'
import { CompilerError, defaultOnError } from './errors'
-import { TO_STRING, COMMENT, CREATE_VNODE } from './runtimeConstants'
+import { TO_STRING, COMMENT, CREATE_VNODE, FRAGMENT } from './runtimeConstants'
+import { createBlockExpression } from './utils'
// There are two types of transforms:
//
export function transform(root: RootNode, options: TransformOptions) {
const context = createTransformContext(root, options)
traverseNode(root, context)
+ finalizeRoot(root, context)
+}
+
+function finalizeRoot(root: RootNode, context: TransformContext) {
+ const { helper } = context
+ const { children } = root
+ if (children.length === 1) {
+ const child = children[0]
+ if (child.type === NodeTypes.ELEMENT && child.codegenNode) {
+ // only child is a <slot/> - it needs to be in a fragment block.
+ if (child.tagType === ElementTypes.SLOT) {
+ root.codegenNode = createBlockExpression(
+ [helper(FRAGMENT), `null`, child.codegenNode],
+ context
+ )
+ } else {
+ // turn root element into a block
+ root.codegenNode = createBlockExpression(
+ child.codegenNode.arguments,
+ context
+ )
+ }
+ } else {
+ // IfNode, ForNode, TextNodes or transform calls without transformElement.
+ // Just generate the node as-is
+ root.codegenNode = child
+ }
+ } else if (children.length > 1) {
+ // root has multiple nodes - return a fragment block.
+ root.codegenNode = createBlockExpression(
+ [helper(FRAGMENT), `null`, root.children],
+ context
+ )
+ }
+
+ // finalize meta information
root.imports = [...context.imports]
root.statements = [...context.statements]
root.hoists = context.hoists
const { nodeTransforms } = context
const exitFns = []
for (let i = 0; i < nodeTransforms.length; i++) {
- const plugin = nodeTransforms[i]
- const onExit = plugin(node, context)
+ const onExit = nodeTransforms[i](node, context)
if (onExit) {
if (isArray(onExit)) {
exitFns.push(...onExit)
switch (node.type) {
case NodeTypes.COMMENT:
- context.helper(CREATE_VNODE)
// inject import for the Comment symbol, which is needed for creating
// comment nodes with `createVNode`
+ context.helper(CREATE_VNODE)
context.helper(COMMENT)
break
case NodeTypes.INTERPOLATION:
TO_HANDLERS
} from '../runtimeConstants'
import { getInnerRange } from '../utils'
-import { buildSlots } from './vSlot'
+import { buildSlots, isVSlot } from './vSlot'
const toValidId = (str: string): string => str.replace(/[^\w]/g, '')
if (node.type === NodeTypes.ELEMENT) {
if (
node.tagType === ElementTypes.ELEMENT ||
- node.tagType === ElementTypes.COMPONENT
+ node.tagType === ElementTypes.COMPONENT ||
+ // <template> with v-if or v-for are ignored during traversal.
+ // <template> without v-slot should be treated as a normal element.
+ (node.tagType === ElementTypes.TEMPLATE && !node.props.some(isVSlot))
) {
// perform the work on exit, after all child expressions have been
// processed and merged.
CallExpression
} from '../ast'
import { createCompilerError, ErrorCodes } from '../errors'
-import { getInnerRange, findProp } from '../utils'
+import { getInnerRange, findProp, createBlockExpression } from '../utils'
import {
RENDER_LIST,
OPEN_BLOCK,
valueAlias: value,
keyAlias: key,
objectIndexAlias: index,
- children: [node],
+ children:
+ node.tagType === ElementTypes.TEMPLATE ? node.children : [node],
codegenNode
})
}
let childBlockChildren: TemplateChildNode[] | CallExpression =
node.children
+ // if the only child is a <slot/>, use it directly as fragment
+ // children since it already returns an array.
if (childBlockChildren.length === 1) {
const child = childBlockChildren[0]
if (
childBlockChildren = child.codegenNode!
}
}
- childBlock = createSequenceExpression([
- createCallExpression(helper(OPEN_BLOCK)),
- createCallExpression(helper(CREATE_BLOCK), [
- helper(FRAGMENT),
- childBlockProps,
- childBlockChildren
- ])
- ])
+ childBlock = createBlockExpression(
+ [helper(FRAGMENT), childBlockProps, childBlockChildren],
+ context
+ )
} else {
- // Normal element v-for. Directly use the child's codegenNode,
+ // Normal element v-for. Directly use the child's codegenNode arguments,
// but replace createVNode() with createBlock()
- node.codegenNode!.callee = helper(CREATE_BLOCK)
- childBlock = createSequenceExpression([
- createCallExpression(helper(OPEN_BLOCK)),
- node.codegenNode!
- ])
+ childBlock = createBlockExpression(
+ node.codegenNode!.arguments,
+ context
+ )
}
renderExp.arguments.push(
import { createCompilerError, ErrorCodes } from '../errors'
import { isString } from '@vue/shared'
-const isVSlot = (p: ElementNode['props'][0]): p is DirectiveNode =>
+export const isVSlot = (p: ElementNode['props'][0]): p is DirectiveNode =>
p.type === NodeTypes.DIRECTIVE && p.name === 'slot'
// A NodeTransform that tracks scope identifiers for scoped slots so that they
-import { SourceLocation, Position, ElementNode, NodeTypes } from './ast'
+import {
+ SourceLocation,
+ Position,
+ ElementNode,
+ NodeTypes,
+ CallExpression,
+ SequenceExpression,
+ createSequenceExpression,
+ createCallExpression
+} from './ast'
import { parse } from 'acorn'
import { walk } from 'estree-walker'
+import { TransformContext } from './transform'
+import { OPEN_BLOCK, CREATE_BLOCK } from './runtimeConstants'
// cache node requires
// lazy require dependencies so that they don't end up in rollup's dep graph
}
}
}
+
+export function createBlockExpression(
+ args: CallExpression['arguments'],
+ context: TransformContext
+): SequenceExpression {
+ return createSequenceExpression([
+ createCallExpression(context.helper(OPEN_BLOCK)),
+ createCallExpression(context.helper(CREATE_BLOCK), args)
+ ])
+}