wip(compiler): adjust statement positions

This commit is contained in:
Evan You 2019-09-25 15:09:58 -04:00
parent b43f3b61b7
commit ff2313e43a
5 changed files with 43 additions and 20 deletions

View File

@ -71,10 +71,10 @@ return function render() {
`; `;
exports[`compiler: codegen function mode preamble 1`] = ` exports[`compiler: codegen function mode preamble 1`] = `
"const { helperOne, helperTwo } = Vue "const _Vue = Vue
return function render() { return function render() {
with (this) { with (this) {
const { helperOne, helperTwo } = _Vue
return null return null
} }
}" }"
@ -147,10 +147,10 @@ return function render() {
exports[`compiler: codegen statements 1`] = ` exports[`compiler: codegen statements 1`] = `
" "
return function render() { return function render() {
const a = 1
const b = 2
with (this) { with (this) {
const a = 1
const b = 2
return null return null
} }
}" }"

View File

@ -55,7 +55,8 @@ describe('compiler: codegen', () => {
imports: [`helperOne`, `helperTwo`] imports: [`helperOne`, `helperTwo`]
}) })
const { code } = generate(root, { mode: 'function' }) const { code } = generate(root, { mode: 'function' })
expect(code).toMatch(`const { helperOne, helperTwo } = Vue`) expect(code).toMatch(`const _Vue = Vue`)
expect(code).toMatch(`const { helperOne, helperTwo } = _Vue`)
expect(code).toMatchSnapshot() expect(code).toMatchSnapshot()
}) })

View File

@ -9,10 +9,10 @@ test('basic source map support', async () => {
filename: `foo.vue` filename: `foo.vue`
}) })
expect(code).toMatch( expect(code).toMatch(
`const { toString } = Vue `const _Vue = Vue
return function render() { return function render() {
with (this) { with (this) {
const { toString } = _Vue
return [ return [
"hello ", "hello ",
toString(world) toString(world)

View File

@ -145,10 +145,20 @@ export function generate(
const context = createCodegenContext(ast, options) const context = createCodegenContext(ast, options)
const { mode, push, prefixIdentifiers, indent, deindent, newline } = context const { mode, push, prefixIdentifiers, indent, deindent, newline } = context
const imports = ast.imports.join(', ') const imports = ast.imports.join(', ')
// preambles
if (mode === 'function') { if (mode === 'function') {
// generate const declarations for helpers // Generate const declaration for helpers
// In prefix mode, we place the const declaration at top so it's done
// only once; But if we not prefixing, we place the decalration inside the
// with block so it doesn't incur the `in` check cost for every helper access.
if (imports) { if (imports) {
push(`const { ${imports} } = Vue\n`) if (prefixIdentifiers) {
push(`const { ${imports} } = Vue\n`)
} else {
// save Vue in a separate variable to avoid collision
push(`const _Vue = Vue`)
}
} }
genHoists(ast.hoists, context) genHoists(ast.hoists, context)
push(`return `) push(`return `)
@ -160,8 +170,24 @@ export function generate(
genHoists(ast.hoists, context) genHoists(ast.hoists, context)
push(`export default `) push(`export default `)
} }
// enter render function
push(`function render() {`) push(`function render() {`)
indent() indent()
if (!prefixIdentifiers) {
push(`with (this) {`)
indent()
// function mode const declarations should be inside with block
if (mode === 'function' && imports) {
push(`const { ${imports} } = _Vue`)
newline()
}
} else {
push(`const _ctx = this`)
newline()
}
// generate asset resolution statements // generate asset resolution statements
if (ast.statements.length) { if (ast.statements.length) {
ast.statements.forEach(s => { ast.statements.forEach(s => {
@ -170,13 +196,8 @@ export function generate(
}) })
newline() newline()
} }
if (!prefixIdentifiers) {
push(`with (this) {`) // generate the VNode tree expression
indent()
} else {
push(`const _ctx = this`)
newline()
}
push(`return `) push(`return `)
genChildren(ast.children, context, true /* asRoot */) genChildren(ast.children, context, true /* asRoot */)
if (!prefixIdentifiers) { if (!prefixIdentifiers) {

View File

@ -82,9 +82,10 @@ export const PublicInstanceProxyHandlers = {
const { renderContext, data, props } = target const { renderContext, data, props } = target
// TODO handle $xxx properties // TODO handle $xxx properties
return ( return (
(data !== EMPTY_OBJ && hasOwn(data, key)) || key[0] !== '_' &&
hasOwn(renderContext, key) || ((data !== EMPTY_OBJ && hasOwn(data, key)) ||
hasOwn(props, key) hasOwn(renderContext, key) ||
hasOwn(props, key))
) )
}, },
set(target: ComponentInternalInstance, key: string, value: any): boolean { set(target: ComponentInternalInstance, key: string, value: any): boolean {