feat(compiler): block optimization codegen for RootNode

This commit is contained in:
Evan You
2019-10-02 13:11:07 -04:00
parent c0bf341748
commit 24bd6c27e0
15 changed files with 376 additions and 491 deletions

View File

@@ -23,6 +23,7 @@ function createRoot(options: Partial<RootNode> = {}): RootNode {
imports: [],
statements: [],
hoists: [],
codegenNode: undefined,
loc: locStub,
...options
}
@@ -103,14 +104,12 @@ describe('compiler: codegen', () => {
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"`)
@@ -120,7 +119,7 @@ describe('compiler: codegen', () => {
test('interpolation', () => {
const { code } = generate(
createRoot({
children: [createInterpolation(`hello`, locStub)]
codegenNode: createInterpolation(`hello`, locStub)
})
)
expect(code).toMatch(`return _${TO_STRING}(hello)`)
@@ -130,93 +129,30 @@ describe('compiler: codegen', () => {
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', () => {
const { code } = generate(
createRoot({
children: [
{
type: NodeTypes.TEXT,
content: 'foo',
isEmpty: false,
loc: locStub
},
createInterpolation(`hello`, locStub),
{
type: NodeTypes.COMMENT,
content: 'foo',
loc: 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).toMatchSnapshot()
})
test('compound expression', () => {
const { code } = generate(
createRoot({
children: [
createCompoundExpression([
`_ctx.`,
createSimpleExpression(`foo`, false, locStub),
` + `,
{
type: NodeTypes.INTERPOLATION,
loc: locStub,
content: createSimpleExpression(`bar`, false, locStub)
}
])
]
codegenNode: createCompoundExpression([
`_ctx.`,
createSimpleExpression(`foo`, false, locStub),
` + `,
{
type: NodeTypes.INTERPOLATION,
loc: locStub,
content: createSimpleExpression(`bar`, false, locStub)
}
])
})
)
expect(code).toMatch(`return _ctx.foo + _${TO_STRING}(bar)`)
@@ -226,284 +162,105 @@ describe('compiler: codegen', () => {
test('ifNode', () => {
const { code } = generate(
createRoot({
children: [
{
type: NodeTypes.IF,
loc: locStub,
branches: [],
codegenNode: createSequenceExpression([
createSimpleExpression('foo', false),
createSimpleExpression('bar', false)
])
}
]
codegenNode: {
type: NodeTypes.IF,
loc: locStub,
branches: [],
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('forNode', () => {
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[]
[
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
)
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('Element (callExpression + objectExpression + arrayExpression)', () => {
const { code } = generate(
createRoot({
codegenNode: 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[]
[
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(`
@@ -523,17 +280,10 @@ describe('compiler: codegen', () => {
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))`)
@@ -543,33 +293,23 @@ describe('compiler: codegen', () => {
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()
})