Skip to content

Commit 39cebf5

Browse files
committed
fix(compiler-sfc): fix TLA codegen semicolon insertion
fix #4596
1 parent ae942cd commit 39cebf5

File tree

3 files changed

+92
-17
lines changed

3 files changed

+92
-17
lines changed

Diff for: packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap

+66-8
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,36 @@ export default /*#__PURE__*/ Object.assign(__default__, {
9696
})"
9797
`;
9898
99+
exports[`SFC compile <script setup> async/await detection await in expression statement 1`] = `
100+
"import { withAsyncContext as _withAsyncContext } from 'vue'
101+
102+
export default {
103+
async setup(__props, { expose }) {
104+
expose()
105+
106+
let __temp, __restore
107+
foo()
108+
;(
109+
([__temp,__restore] = _withAsyncContext(() => {
110+
return 1
111+
})),
112+
__temp = await __temp,
113+
__restore(),
114+
__temp
115+
) + (
116+
([__temp,__restore] = _withAsyncContext(() => {
117+
return 2
118+
})),
119+
__temp = await __temp,
120+
__restore(),
121+
__temp
122+
)
123+
return { }
124+
}
125+
126+
}"
127+
`;
128+
99129
exports[`SFC compile <script setup> async/await detection expression statement 1`] = `
100130
"import { withAsyncContext as _withAsyncContext } from 'vue'
101131
@@ -109,7 +139,8 @@ let __temp, __restore
109139
return foo
110140
})),
111141
__temp = await __temp,
112-
__restore()
142+
__restore(),
143+
__temp
113144
)
114145
return { }
115146
}
@@ -137,7 +168,8 @@ let __temp, __restore
137168
))
138169
})),
139170
__temp = await __temp,
140-
__restore()
171+
__restore(),
172+
__temp
141173
)
142174
return { }
143175
}
@@ -165,7 +197,8 @@ let __temp, __restore
165197
)))
166198
})),
167199
__temp = await __temp,
168-
__restore()
200+
__restore(),
201+
__temp
169202
)
170203
return { }
171204
}
@@ -200,7 +233,8 @@ let __temp, __restore
200233
))
201234
})),
202235
__temp = await __temp,
203-
__restore()
236+
__restore(),
237+
__temp
204238
)
205239
return { }
206240
}
@@ -216,18 +250,20 @@ export default {
216250
expose()
217251
218252
let __temp, __restore
219-
if (ok) { ;(
253+
if (ok) { (
220254
([__temp,__restore] = _withAsyncContext(() => {
221255
return foo
222256
})),
223257
__temp = await __temp,
224-
__restore()
225-
) } else { ;(
258+
__restore(),
259+
__temp
260+
) } else { (
226261
([__temp,__restore] = _withAsyncContext(() => {
227262
return bar
228263
})),
229264
__temp = await __temp,
230-
__restore()
265+
__restore(),
266+
__temp
231267
) }
232268
return { }
233269
}
@@ -301,6 +337,28 @@ return { cls }
301337
}"
302338
`;
303339
340+
exports[`SFC compile <script setup> async/await detection single line conditions 1`] = `
341+
"import { withAsyncContext as _withAsyncContext } from 'vue'
342+
343+
export default {
344+
async setup(__props, { expose }) {
345+
expose()
346+
347+
let __temp, __restore
348+
if (false) (
349+
([__temp,__restore] = _withAsyncContext(() => {
350+
return foo()
351+
})),
352+
__temp = await __temp,
353+
__restore(),
354+
__temp
355+
)
356+
return { }
357+
}
358+
359+
}"
360+
`;
361+
304362
exports[`SFC compile <script setup> async/await detection variable 1`] = `
305363
"import { withAsyncContext as _withAsyncContext } from 'vue'
306364

Diff for: packages/compiler-sfc/__tests__/compileScript.spec.ts

+14
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,7 @@ const emit = defineEmits(['a', 'b'])
10661066
}
10671067
expect(content).toMatch(`${shouldAsync ? `async ` : ``}setup(`)
10681068
assertCode(content)
1069+
return content
10691070
}
10701071

10711072
test('expression statement', () => {
@@ -1080,12 +1081,25 @@ const emit = defineEmits(['a', 'b'])
10801081
assertAwaitDetection(`let a = $ref(1 + (await foo))`)
10811082
})
10821083

1084+
// #4448
10831085
test('nested await', () => {
10841086
assertAwaitDetection(`await (await foo)`)
10851087
assertAwaitDetection(`await ((await foo))`)
10861088
assertAwaitDetection(`await (await (await foo))`)
10871089
})
10881090

1091+
// should prepend semicolon
1092+
test('await in expression statement', () => {
1093+
const code = assertAwaitDetection(`foo()\nawait 1 + await 2`)
1094+
expect(code).toMatch(`foo()\n;(`)
1095+
})
1096+
1097+
// #4596 should NOT prepend semicolon
1098+
test('single line conditions', () => {
1099+
const code = assertAwaitDetection(`if (false) await foo()`)
1100+
expect(code).not.toMatch(`if (false) ;(`)
1101+
})
1102+
10891103
test('nested statements', () => {
10901104
assertAwaitDetection(`if (ok) { await foo } else { await bar }`)
10911105
})

Diff for: packages/compiler-sfc/src/compileScript.ts

+12-9
Original file line numberDiff line numberDiff line change
@@ -507,11 +507,13 @@ export function compileScript(
507507
}
508508

509509
/**
510-
* await foo()
511-
* -->
512-
* (([__temp, __restore] = withAsyncContext(async () => foo())),__temp=await __temp,__restore(),__temp)
510+
* await foo() -->
511+
*
512+
* (([__temp, __restore] = withAsyncContext(async () => {
513+
* return foo()
514+
* })),__temp=await __temp,__restore(),__temp)
513515
*/
514-
function processAwait(node: AwaitExpression, isStatement: boolean) {
516+
function processAwait(node: AwaitExpression, needSemi: boolean) {
515517
const argumentStart =
516518
node.argument.extra && node.argument.extra.parenthesized
517519
? (node.argument.extra.parenStart as number)
@@ -527,15 +529,13 @@ export function compileScript(
527529
s.overwrite(
528530
node.start! + startOffset,
529531
argumentStart + startOffset,
530-
`${isStatement ? `;` : ``}(\n ([__temp,__restore] = ${helper(
532+
`${needSemi ? `;` : ``}(\n ([__temp,__restore] = ${helper(
531533
`withAsyncContext`
532534
)}(${containsNestedAwait ? `async ` : ``}() => {\n return `
533535
)
534536
s.appendLeft(
535537
node.end! + startOffset,
536-
`\n })),\n __temp = await __temp,\n __restore()${
537-
isStatement ? `` : `,\n __temp`
538-
}\n)`
538+
`\n })),\n __temp = await __temp,\n __restore(),\n __temp\n)`
539539
)
540540
}
541541

@@ -934,7 +934,10 @@ export function compileScript(
934934
}
935935
if (child.type === 'AwaitExpression') {
936936
hasAwait = true
937-
processAwait(child, parent.type === 'ExpressionStatement')
937+
const needsSemi = scriptSetupAst.body.some(n => {
938+
return n.type === 'ExpressionStatement' && n.start === child.start
939+
})
940+
processAwait(child, needsSemi)
938941
}
939942
}
940943
})

0 commit comments

Comments
 (0)