refactor(compiler-sfc): improve TLA codegen

This commit is contained in:
Evan You 2021-09-16 17:07:29 -04:00
parent 39cebf5f7a
commit cab9541ffd
3 changed files with 84 additions and 100 deletions

View File

@ -96,36 +96,6 @@ export default /*#__PURE__*/ Object.assign(__default__, {
})" })"
`; `;
exports[`SFC compile <script setup> async/await detection await in expression statement 1`] = `
"import { withAsyncContext as _withAsyncContext } from 'vue'
export default {
async setup(__props, { expose }) {
expose()
let __temp, __restore
foo()
;(
([__temp,__restore] = _withAsyncContext(() => {
return 1
})),
__temp = await __temp,
__restore(),
__temp
) + (
([__temp,__restore] = _withAsyncContext(() => {
return 2
})),
__temp = await __temp,
__restore(),
__temp
)
return { }
}
}"
`;
exports[`SFC compile <script setup> async/await detection expression statement 1`] = ` exports[`SFC compile <script setup> async/await detection expression statement 1`] = `
"import { withAsyncContext as _withAsyncContext } from 'vue' "import { withAsyncContext as _withAsyncContext } from 'vue'
@ -135,12 +105,9 @@ export default {
let __temp, __restore let __temp, __restore
;( ;(
([__temp,__restore] = _withAsyncContext(() => { ([__temp,__restore] = _withAsyncContext(() => foo)),
return foo await __temp,
})), __restore()
__temp = await __temp,
__restore(),
__temp
) )
return { } return { }
} }
@ -157,19 +124,14 @@ export default {
let __temp, __restore let __temp, __restore
;( ;(
([__temp,__restore] = _withAsyncContext(async () => { ([__temp,__restore] = _withAsyncContext(async () => ((
return (( ([__temp,__restore] = _withAsyncContext(() => foo)),
([__temp,__restore] = _withAsyncContext(() => {
return foo
})),
__temp = await __temp,
__restore(),
__temp
))
})),
__temp = await __temp, __temp = await __temp,
__restore(), __restore(),
__temp __temp
)))),
await __temp,
__restore()
) )
return { } return { }
} }
@ -186,19 +148,14 @@ export default {
let __temp, __restore let __temp, __restore
;( ;(
([__temp,__restore] = _withAsyncContext(async () => { ([__temp,__restore] = _withAsyncContext(async () => (((
return ((( ([__temp,__restore] = _withAsyncContext(() => foo)),
([__temp,__restore] = _withAsyncContext(() => {
return foo
})),
__temp = await __temp,
__restore(),
__temp
)))
})),
__temp = await __temp, __temp = await __temp,
__restore(), __restore(),
__temp __temp
))))),
await __temp,
__restore()
) )
return { } return { }
} }
@ -215,23 +172,42 @@ export default {
let __temp, __restore let __temp, __restore
;( ;(
([__temp,__restore] = _withAsyncContext(async () => { ([__temp,__restore] = _withAsyncContext(async () => ((
return (( ([__temp,__restore] = _withAsyncContext(async () => ((
([__temp,__restore] = _withAsyncContext(async () => { ([__temp,__restore] = _withAsyncContext(() => foo)),
return ((
([__temp,__restore] = _withAsyncContext(() => {
return foo
})),
__temp = await __temp, __temp = await __temp,
__restore(), __restore(),
__temp __temp
)) )))),
})),
__temp = await __temp, __temp = await __temp,
__restore(), __restore(),
__temp __temp
)) )))),
})), await __temp,
__restore()
)
return { }
}
}"
`;
exports[`SFC compile <script setup> async/await detection nested leading await in expression statement 1`] = `
"import { withAsyncContext as _withAsyncContext } from 'vue'
export default {
async setup(__props, { expose }) {
expose()
let __temp, __restore
foo()
;(
([__temp,__restore] = _withAsyncContext(() => 1)),
__temp = await __temp,
__restore(),
__temp
) + (
([__temp,__restore] = _withAsyncContext(() => 2)),
__temp = await __temp, __temp = await __temp,
__restore(), __restore(),
__temp __temp
@ -251,19 +227,13 @@ export default {
let __temp, __restore let __temp, __restore
if (ok) { ( if (ok) { (
([__temp,__restore] = _withAsyncContext(() => { ([__temp,__restore] = _withAsyncContext(() => foo)),
return foo await __temp,
})), __restore()
__temp = await __temp,
__restore(),
__temp
) } else { ( ) } else { (
([__temp,__restore] = _withAsyncContext(() => { ([__temp,__restore] = _withAsyncContext(() => bar)),
return bar await __temp,
})), __restore()
__temp = await __temp,
__restore(),
__temp
) } ) }
return { } return { }
} }
@ -280,9 +250,7 @@ export default {
let __temp, __restore let __temp, __restore
let a = _ref(1 + (( let a = _ref(1 + ((
([__temp,__restore] = _withAsyncContext(() => { ([__temp,__restore] = _withAsyncContext(() => foo)),
return foo
})),
__temp = await __temp, __temp = await __temp,
__restore(), __restore(),
__temp __temp
@ -346,12 +314,9 @@ export default {
let __temp, __restore let __temp, __restore
if (false) ( if (false) (
([__temp,__restore] = _withAsyncContext(() => { ([__temp,__restore] = _withAsyncContext(() => foo())),
return foo() await __temp,
})), __restore()
__temp = await __temp,
__restore(),
__temp
) )
return { } return { }
} }
@ -368,9 +333,7 @@ export default {
let __temp, __restore let __temp, __restore
const a = 1 + (( const a = 1 + ((
([__temp,__restore] = _withAsyncContext(() => { ([__temp,__restore] = _withAsyncContext(() => foo)),
return foo
})),
__temp = await __temp, __temp = await __temp,
__restore(), __restore(),
__temp __temp

View File

@ -1089,7 +1089,7 @@ const emit = defineEmits(['a', 'b'])
}) })
// should prepend semicolon // should prepend semicolon
test('await in expression statement', () => { test('nested leading await in expression statement', () => {
const code = assertAwaitDetection(`foo()\nawait 1 + await 2`) const code = assertAwaitDetection(`foo()\nawait 1 + await 2`)
expect(code).toMatch(`foo()\n;(`) expect(code).toMatch(`foo()\n;(`)
}) })

View File

@ -507,13 +507,28 @@ export function compileScript(
} }
/** /**
* await foo() --> * await foo()
* -->
* ;(
* ([__temp,__restore] = withAsyncContext(() => foo())),
* await __temp,
* __restore()
* )
* *
* (([__temp, __restore] = withAsyncContext(async () => { * const a = await foo()
* return foo() * -->
* })),__temp=await __temp,__restore(),__temp) * const a = (
* ([__temp, __restore] = withAsyncContext(() => foo())),
* __temp = await __temp,
* __restore(),
* __temp
* )
*/ */
function processAwait(node: AwaitExpression, needSemi: boolean) { function processAwait(
node: AwaitExpression,
needSemi: boolean,
isStatement: boolean
) {
const argumentStart = const argumentStart =
node.argument.extra && node.argument.extra.parenthesized node.argument.extra && node.argument.extra.parenthesized
? (node.argument.extra.parenStart as number) ? (node.argument.extra.parenStart as number)
@ -531,11 +546,13 @@ export function compileScript(
argumentStart + startOffset, argumentStart + startOffset,
`${needSemi ? `;` : ``}(\n ([__temp,__restore] = ${helper( `${needSemi ? `;` : ``}(\n ([__temp,__restore] = ${helper(
`withAsyncContext` `withAsyncContext`
)}(${containsNestedAwait ? `async ` : ``}() => {\n return ` )}(${containsNestedAwait ? `async ` : ``}() => `
) )
s.appendLeft( s.appendLeft(
node.end! + startOffset, node.end! + startOffset,
`\n })),\n __temp = await __temp,\n __restore(),\n __temp\n)` `)),\n ${isStatement ? `` : `__temp = `}await __temp,\n __restore()${
isStatement ? `` : `,\n __temp`
}\n)`
) )
} }
@ -937,7 +954,11 @@ export function compileScript(
const needsSemi = scriptSetupAst.body.some(n => { const needsSemi = scriptSetupAst.body.some(n => {
return n.type === 'ExpressionStatement' && n.start === child.start return n.type === 'ExpressionStatement' && n.start === child.start
}) })
processAwait(child, needsSemi) processAwait(
child,
needsSemi,
parent.type === 'ExpressionStatement'
)
} }
} }
}) })