]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-sfc): fix TLA codegen semicolon insertion
authorEvan You <yyx990803@gmail.com>
Thu, 16 Sep 2021 20:49:59 +0000 (16:49 -0400)
committerEvan You <yyx990803@gmail.com>
Thu, 16 Sep 2021 20:49:59 +0000 (16:49 -0400)
fix #4596

packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap
packages/compiler-sfc/__tests__/compileScript.spec.ts
packages/compiler-sfc/src/compileScript.ts

index 855ddd4a610c8b25b22acf3e9bbc84e51ab0f9d8..fe8d095f4c5a5666268bd789c90c678174a3e6df 100644 (file)
@@ -96,6 +96,36 @@ 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`] = `
 "import { withAsyncContext as _withAsyncContext } from 'vue'
 
@@ -109,7 +139,8 @@ let __temp, __restore
     return foo
   })),
   __temp = await __temp,
-  __restore()
+  __restore(),
+  __temp
 )
 return {  }
 }
@@ -137,7 +168,8 @@ let __temp, __restore
 ))
   })),
   __temp = await __temp,
-  __restore()
+  __restore(),
+  __temp
 )
 return {  }
 }
@@ -165,7 +197,8 @@ let __temp, __restore
 )))
   })),
   __temp = await __temp,
-  __restore()
+  __restore(),
+  __temp
 )
 return {  }
 }
@@ -200,7 +233,8 @@ let __temp, __restore
 ))
   })),
   __temp = await __temp,
-  __restore()
+  __restore(),
+  __temp
 )
 return {  }
 }
@@ -216,18 +250,20 @@ export default {
   expose()
 
 let __temp, __restore
-if (ok) { ;(
+if (ok) { (
   ([__temp,__restore] = _withAsyncContext(() => {
     return foo
   })),
   __temp = await __temp,
-  __restore()
-) } else { ;(
+  __restore(),
+  __temp
+) } else { (
   ([__temp,__restore] = _withAsyncContext(() => {
     return bar
   })),
   __temp = await __temp,
-  __restore()
+  __restore(),
+  __temp
 ) }
 return {  }
 }
@@ -301,6 +337,28 @@ return { cls }
 }"
 `;
 
+exports[`SFC compile <script setup> async/await detection single line conditions 1`] = `
+"import { withAsyncContext as _withAsyncContext } from 'vue'
+
+export default {
+  async setup(__props, { expose }) {
+  expose()
+
+let __temp, __restore
+if (false) (
+  ([__temp,__restore] = _withAsyncContext(() => {
+    return foo()
+  })),
+  __temp = await __temp,
+  __restore(),
+  __temp
+)
+return {  }
+}
+
+}"
+`;
+
 exports[`SFC compile <script setup> async/await detection variable 1`] = `
 "import { withAsyncContext as _withAsyncContext } from 'vue'
 
index 64b4fcfcf1b2edc6baf39141ed7a8bab90367f92..9aec5707e0121cae1db2e368dcddb42336c35a0e 100644 (file)
@@ -1066,6 +1066,7 @@ const emit = defineEmits(['a', 'b'])
       }
       expect(content).toMatch(`${shouldAsync ? `async ` : ``}setup(`)
       assertCode(content)
+      return content
     }
 
     test('expression statement', () => {
@@ -1080,12 +1081,25 @@ const emit = defineEmits(['a', 'b'])
       assertAwaitDetection(`let a = $ref(1 + (await foo))`)
     })
 
+    // #4448
     test('nested await', () => {
       assertAwaitDetection(`await (await foo)`)
       assertAwaitDetection(`await ((await foo))`)
       assertAwaitDetection(`await (await (await foo))`)
     })
 
+    // should prepend semicolon
+    test('await in expression statement', () => {
+      const code = assertAwaitDetection(`foo()\nawait 1 + await 2`)
+      expect(code).toMatch(`foo()\n;(`)
+    })
+
+    // #4596 should NOT prepend semicolon
+    test('single line conditions', () => {
+      const code = assertAwaitDetection(`if (false) await foo()`)
+      expect(code).not.toMatch(`if (false) ;(`)
+    })
+
     test('nested statements', () => {
       assertAwaitDetection(`if (ok) { await foo } else { await bar }`)
     })
index 848bb322251e228cf39cf2388ccf59b43c53d196..fc0dd171b9fdd91830bb57e9d4ee455c2e737575 100644 (file)
@@ -507,11 +507,13 @@ export function compileScript(
   }
 
   /**
-   * await foo()
-   * -->
-   * (([__temp, __restore] = withAsyncContext(async () => foo())),__temp=await __temp,__restore(),__temp)
+   * await foo() -->
+   *
+   * (([__temp, __restore] = withAsyncContext(async () => {
+   *   return foo()
+   * })),__temp=await __temp,__restore(),__temp)
    */
-  function processAwait(node: AwaitExpression, isStatement: boolean) {
+  function processAwait(node: AwaitExpression, needSemi: boolean) {
     const argumentStart =
       node.argument.extra && node.argument.extra.parenthesized
         ? (node.argument.extra.parenStart as number)
@@ -527,15 +529,13 @@ export function compileScript(
     s.overwrite(
       node.start! + startOffset,
       argumentStart + startOffset,
-      `${isStatement ? `;` : ``}(\n  ([__temp,__restore] = ${helper(
+      `${needSemi ? `;` : ``}(\n  ([__temp,__restore] = ${helper(
         `withAsyncContext`
       )}(${containsNestedAwait ? `async ` : ``}() => {\n    return `
     )
     s.appendLeft(
       node.end! + startOffset,
-      `\n  })),\n  __temp = await __temp,\n  __restore()${
-        isStatement ? `` : `,\n  __temp`
-      }\n)`
+      `\n  })),\n  __temp = await __temp,\n  __restore(),\n  __temp\n)`
     )
   }
 
@@ -934,7 +934,10 @@ export function compileScript(
           }
           if (child.type === 'AwaitExpression') {
             hasAwait = true
-            processAwait(child, parent.type === 'ExpressionStatement')
+            const needsSemi = scriptSetupAst.body.some(n => {
+              return n.type === 'ExpressionStatement' && n.start === child.start
+            })
+            processAwait(child, needsSemi)
           }
         }
       })