mirror of https://github.com/vuejs/core.git
70 lines
1.7 KiB
TypeScript
70 lines
1.7 KiB
TypeScript
import { AwaitExpression } from '@babel/types'
|
|
import { ScriptCompileContext } from './context'
|
|
|
|
/**
|
|
* Support context-persistence between top-level await expressions:
|
|
*
|
|
* ```js
|
|
* const instance = getCurrentInstance()
|
|
* await foo()
|
|
* expect(getCurrentInstance()).toBe(instance)
|
|
* ```
|
|
*
|
|
* In the future we can potentially get rid of this when Async Context
|
|
* becomes generally available: https://github.com/tc39/proposal-async-context
|
|
*
|
|
* ```js
|
|
* // input
|
|
* await foo()
|
|
* // output
|
|
* ;(
|
|
* ([__temp,__restore] = withAsyncContext(() => foo())),
|
|
* await __temp,
|
|
* __restore()
|
|
* )
|
|
*
|
|
* // input
|
|
* const a = await foo()
|
|
* // output
|
|
* const a = (
|
|
* ([__temp, __restore] = withAsyncContext(() => foo())),
|
|
* __temp = await __temp,
|
|
* __restore(),
|
|
* __temp
|
|
* )
|
|
* ```
|
|
*/
|
|
export function processAwait(
|
|
ctx: ScriptCompileContext,
|
|
node: AwaitExpression,
|
|
needSemi: boolean,
|
|
isStatement: boolean
|
|
) {
|
|
const argumentStart =
|
|
node.argument.extra && node.argument.extra.parenthesized
|
|
? (node.argument.extra.parenStart as number)
|
|
: node.argument.start!
|
|
|
|
const startOffset = ctx.startOffset!
|
|
const argumentStr = ctx.descriptor.source.slice(
|
|
argumentStart + startOffset,
|
|
node.argument.end! + startOffset
|
|
)
|
|
|
|
const containsNestedAwait = /\bawait\b/.test(argumentStr)
|
|
|
|
ctx.s.overwrite(
|
|
node.start! + startOffset,
|
|
argumentStart + startOffset,
|
|
`${needSemi ? `;` : ``}(\n ([__temp,__restore] = ${ctx.helper(
|
|
`withAsyncContext`
|
|
)}(${containsNestedAwait ? `async ` : ``}() => `
|
|
)
|
|
ctx.s.appendLeft(
|
|
node.end! + startOffset,
|
|
`)),\n ${isStatement ? `` : `__temp = `}await __temp,\n __restore()${
|
|
isStatement ? `` : `,\n __temp`
|
|
}\n)`
|
|
)
|
|
}
|