parent
524688bc99
commit
ae942cdcd9
@ -96,6 +96,233 @@ export default /*#__PURE__*/ Object.assign(__default__, {
|
|||||||
})"
|
})"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`SFC compile <script setup> async/await detection expression statement 1`] = `
|
||||||
|
"import { withAsyncContext as _withAsyncContext } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
async setup(__props, { expose }) {
|
||||||
|
expose()
|
||||||
|
|
||||||
|
let __temp, __restore
|
||||||
|
;(
|
||||||
|
([__temp,__restore] = _withAsyncContext(() => {
|
||||||
|
return foo
|
||||||
|
})),
|
||||||
|
__temp = await __temp,
|
||||||
|
__restore()
|
||||||
|
)
|
||||||
|
return { }
|
||||||
|
}
|
||||||
|
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`SFC compile <script setup> async/await detection nested await 1`] = `
|
||||||
|
"import { withAsyncContext as _withAsyncContext } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
async setup(__props, { expose }) {
|
||||||
|
expose()
|
||||||
|
|
||||||
|
let __temp, __restore
|
||||||
|
;(
|
||||||
|
([__temp,__restore] = _withAsyncContext(async () => {
|
||||||
|
return ((
|
||||||
|
([__temp,__restore] = _withAsyncContext(() => {
|
||||||
|
return foo
|
||||||
|
})),
|
||||||
|
__temp = await __temp,
|
||||||
|
__restore(),
|
||||||
|
__temp
|
||||||
|
))
|
||||||
|
})),
|
||||||
|
__temp = await __temp,
|
||||||
|
__restore()
|
||||||
|
)
|
||||||
|
return { }
|
||||||
|
}
|
||||||
|
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`SFC compile <script setup> async/await detection nested await 2`] = `
|
||||||
|
"import { withAsyncContext as _withAsyncContext } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
async setup(__props, { expose }) {
|
||||||
|
expose()
|
||||||
|
|
||||||
|
let __temp, __restore
|
||||||
|
;(
|
||||||
|
([__temp,__restore] = _withAsyncContext(async () => {
|
||||||
|
return (((
|
||||||
|
([__temp,__restore] = _withAsyncContext(() => {
|
||||||
|
return foo
|
||||||
|
})),
|
||||||
|
__temp = await __temp,
|
||||||
|
__restore(),
|
||||||
|
__temp
|
||||||
|
)))
|
||||||
|
})),
|
||||||
|
__temp = await __temp,
|
||||||
|
__restore()
|
||||||
|
)
|
||||||
|
return { }
|
||||||
|
}
|
||||||
|
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`SFC compile <script setup> async/await detection nested await 3`] = `
|
||||||
|
"import { withAsyncContext as _withAsyncContext } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
async setup(__props, { expose }) {
|
||||||
|
expose()
|
||||||
|
|
||||||
|
let __temp, __restore
|
||||||
|
;(
|
||||||
|
([__temp,__restore] = _withAsyncContext(async () => {
|
||||||
|
return ((
|
||||||
|
([__temp,__restore] = _withAsyncContext(async () => {
|
||||||
|
return ((
|
||||||
|
([__temp,__restore] = _withAsyncContext(() => {
|
||||||
|
return foo
|
||||||
|
})),
|
||||||
|
__temp = await __temp,
|
||||||
|
__restore(),
|
||||||
|
__temp
|
||||||
|
))
|
||||||
|
})),
|
||||||
|
__temp = await __temp,
|
||||||
|
__restore(),
|
||||||
|
__temp
|
||||||
|
))
|
||||||
|
})),
|
||||||
|
__temp = await __temp,
|
||||||
|
__restore()
|
||||||
|
)
|
||||||
|
return { }
|
||||||
|
}
|
||||||
|
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`SFC compile <script setup> async/await detection nested statements 1`] = `
|
||||||
|
"import { withAsyncContext as _withAsyncContext } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
async setup(__props, { expose }) {
|
||||||
|
expose()
|
||||||
|
|
||||||
|
let __temp, __restore
|
||||||
|
if (ok) { ;(
|
||||||
|
([__temp,__restore] = _withAsyncContext(() => {
|
||||||
|
return foo
|
||||||
|
})),
|
||||||
|
__temp = await __temp,
|
||||||
|
__restore()
|
||||||
|
) } else { ;(
|
||||||
|
([__temp,__restore] = _withAsyncContext(() => {
|
||||||
|
return bar
|
||||||
|
})),
|
||||||
|
__temp = await __temp,
|
||||||
|
__restore()
|
||||||
|
) }
|
||||||
|
return { }
|
||||||
|
}
|
||||||
|
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`SFC compile <script setup> async/await detection ref 1`] = `
|
||||||
|
"import { withAsyncContext as _withAsyncContext, ref as _ref } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
async setup(__props, { expose }) {
|
||||||
|
expose()
|
||||||
|
|
||||||
|
let __temp, __restore
|
||||||
|
let a = _ref(1 + ((
|
||||||
|
([__temp,__restore] = _withAsyncContext(() => {
|
||||||
|
return foo
|
||||||
|
})),
|
||||||
|
__temp = await __temp,
|
||||||
|
__restore(),
|
||||||
|
__temp
|
||||||
|
)))
|
||||||
|
return { a }
|
||||||
|
}
|
||||||
|
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`SFC compile <script setup> async/await detection should ignore await inside functions 1`] = `
|
||||||
|
"export default {
|
||||||
|
setup(__props, { expose }) {
|
||||||
|
expose()
|
||||||
|
async function foo() { await bar }
|
||||||
|
return { foo }
|
||||||
|
}
|
||||||
|
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`SFC compile <script setup> async/await detection should ignore await inside functions 2`] = `
|
||||||
|
"export default {
|
||||||
|
setup(__props, { expose }) {
|
||||||
|
expose()
|
||||||
|
const foo = async () => { await bar }
|
||||||
|
return { foo }
|
||||||
|
}
|
||||||
|
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`SFC compile <script setup> async/await detection should ignore await inside functions 3`] = `
|
||||||
|
"export default {
|
||||||
|
setup(__props, { expose }) {
|
||||||
|
expose()
|
||||||
|
const obj = { async method() { await bar }}
|
||||||
|
return { obj }
|
||||||
|
}
|
||||||
|
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`SFC compile <script setup> async/await detection should ignore await inside functions 4`] = `
|
||||||
|
"export default {
|
||||||
|
setup(__props, { expose }) {
|
||||||
|
expose()
|
||||||
|
const cls = class Foo { async method() { await bar }}
|
||||||
|
return { cls }
|
||||||
|
}
|
||||||
|
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`SFC compile <script setup> async/await detection variable 1`] = `
|
||||||
|
"import { withAsyncContext as _withAsyncContext } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
async setup(__props, { expose }) {
|
||||||
|
expose()
|
||||||
|
|
||||||
|
let __temp, __restore
|
||||||
|
const a = 1 + ((
|
||||||
|
([__temp,__restore] = _withAsyncContext(() => {
|
||||||
|
return foo
|
||||||
|
})),
|
||||||
|
__temp = await __temp,
|
||||||
|
__restore(),
|
||||||
|
__temp
|
||||||
|
))
|
||||||
|
return { a }
|
||||||
|
}
|
||||||
|
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`SFC compile <script setup> binding analysis for destructur 1`] = `
|
exports[`SFC compile <script setup> binding analysis for destructur 1`] = `
|
||||||
"export default {
|
"export default {
|
||||||
setup(__props, { expose }) {
|
setup(__props, { expose }) {
|
||||||
|
@ -1057,11 +1057,7 @@ const emit = defineEmits(['a', 'b'])
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('async/await detection', () => {
|
describe('async/await detection', () => {
|
||||||
function assertAwaitDetection(
|
function assertAwaitDetection(code: string, shouldAsync = true) {
|
||||||
code: string,
|
|
||||||
expected: string | ((content: string) => boolean),
|
|
||||||
shouldAsync = true
|
|
||||||
) {
|
|
||||||
const { content } = compile(`<script setup>${code}</script>`, {
|
const { content } = compile(`<script setup>${code}</script>`, {
|
||||||
refSugar: true
|
refSugar: true
|
||||||
})
|
})
|
||||||
@ -1069,70 +1065,41 @@ const emit = defineEmits(['a', 'b'])
|
|||||||
expect(content).toMatch(`let __temp, __restore`)
|
expect(content).toMatch(`let __temp, __restore`)
|
||||||
}
|
}
|
||||||
expect(content).toMatch(`${shouldAsync ? `async ` : ``}setup(`)
|
expect(content).toMatch(`${shouldAsync ? `async ` : ``}setup(`)
|
||||||
if (typeof expected === 'string') {
|
assertCode(content)
|
||||||
expect(content).toMatch(expected)
|
|
||||||
} else {
|
|
||||||
expect(expected(content)).toBe(true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test('expression statement', () => {
|
test('expression statement', () => {
|
||||||
assertAwaitDetection(
|
assertAwaitDetection(`await foo`)
|
||||||
`await foo`,
|
|
||||||
`;(([__temp,__restore]=_withAsyncContext(()=>(foo))),__temp=await __temp,__restore())`
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('variable', () => {
|
test('variable', () => {
|
||||||
assertAwaitDetection(
|
assertAwaitDetection(`const a = 1 + (await foo)`)
|
||||||
`const a = 1 + (await foo)`,
|
|
||||||
`1 + ((([__temp,__restore]=_withAsyncContext(()=>(foo))),__temp=await __temp,__restore(),__temp))`
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('ref', () => {
|
test('ref', () => {
|
||||||
assertAwaitDetection(
|
assertAwaitDetection(`let a = $ref(1 + (await foo))`)
|
||||||
`let a = $ref(1 + (await foo))`,
|
})
|
||||||
`1 + ((([__temp,__restore]=_withAsyncContext(()=>(foo))),__temp=await __temp,__restore(),__temp))`
|
|
||||||
)
|
test('nested await', () => {
|
||||||
|
assertAwaitDetection(`await (await foo)`)
|
||||||
|
assertAwaitDetection(`await ((await foo))`)
|
||||||
|
assertAwaitDetection(`await (await (await foo))`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('nested statements', () => {
|
test('nested statements', () => {
|
||||||
assertAwaitDetection(`if (ok) { await foo } else { await bar }`, code => {
|
assertAwaitDetection(`if (ok) { await foo } else { await bar }`)
|
||||||
return (
|
|
||||||
code.includes(
|
|
||||||
`;(([__temp,__restore]=_withAsyncContext(()=>(foo))),__temp=await __temp,__restore())`
|
|
||||||
) &&
|
|
||||||
code.includes(
|
|
||||||
`;(([__temp,__restore]=_withAsyncContext(()=>(bar))),__temp=await __temp,__restore())`
|
|
||||||
)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should ignore await inside functions', () => {
|
test('should ignore await inside functions', () => {
|
||||||
// function declaration
|
// function declaration
|
||||||
assertAwaitDetection(
|
assertAwaitDetection(`async function foo() { await bar }`, false)
|
||||||
`async function foo() { await bar }`,
|
|
||||||
`await bar`,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
// function expression
|
// function expression
|
||||||
assertAwaitDetection(
|
assertAwaitDetection(`const foo = async () => { await bar }`, false)
|
||||||
`const foo = async () => { await bar }`,
|
|
||||||
`await bar`,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
// object method
|
// object method
|
||||||
assertAwaitDetection(
|
assertAwaitDetection(`const obj = { async method() { await bar }}`, false)
|
||||||
`const obj = { async method() { await bar }}`,
|
|
||||||
`await bar`,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
// class method
|
// class method
|
||||||
assertAwaitDetection(
|
assertAwaitDetection(
|
||||||
`const cls = class Foo { async method() { await bar }}`,
|
`const cls = class Foo { async method() { await bar }}`,
|
||||||
`await bar`,
|
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -509,19 +509,33 @@ export function compileScript(
|
|||||||
/**
|
/**
|
||||||
* await foo()
|
* await foo()
|
||||||
* -->
|
* -->
|
||||||
* (([__temp, __restore] = withAsyncContext(() => foo())),__temp=await __temp,__restore(),__temp)
|
* (([__temp, __restore] = withAsyncContext(async () => foo())),__temp=await __temp,__restore(),__temp)
|
||||||
*/
|
*/
|
||||||
function processAwait(node: AwaitExpression, isStatement: boolean) {
|
function processAwait(node: AwaitExpression, isStatement: boolean) {
|
||||||
|
const argumentStart =
|
||||||
|
node.argument.extra && node.argument.extra.parenthesized
|
||||||
|
? (node.argument.extra.parenStart as number)
|
||||||
|
: node.argument.start!
|
||||||
|
|
||||||
|
const argumentStr = source.slice(
|
||||||
|
argumentStart + startOffset,
|
||||||
|
node.argument.end! + startOffset
|
||||||
|
)
|
||||||
|
|
||||||
|
const containsNestedAwait = /\bawait\b/.test(argumentStr)
|
||||||
|
|
||||||
s.overwrite(
|
s.overwrite(
|
||||||
node.start! + startOffset,
|
node.start! + startOffset,
|
||||||
node.argument.start! + startOffset,
|
argumentStart + startOffset,
|
||||||
`${isStatement ? `;` : ``}(([__temp,__restore]=${helper(
|
`${isStatement ? `;` : ``}(\n ([__temp,__restore] = ${helper(
|
||||||
`withAsyncContext`
|
`withAsyncContext`
|
||||||
)}(()=>(`
|
)}(${containsNestedAwait ? `async ` : ``}() => {\n return `
|
||||||
)
|
)
|
||||||
s.appendLeft(
|
s.appendLeft(
|
||||||
node.end! + startOffset,
|
node.end! + startOffset,
|
||||||
`))),__temp=await __temp,__restore()${isStatement ? `` : `,__temp`})`
|
`\n })),\n __temp = await __temp,\n __restore()${
|
||||||
|
isStatement ? `` : `,\n __temp`
|
||||||
|
}\n)`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user