]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(reactivity-transform): fix $$ escape edge cases
authorEvan You <yyx990803@gmail.com>
Mon, 14 Nov 2022 03:36:24 +0000 (11:36 +0800)
committerEvan You <yyx990803@gmail.com>
Mon, 14 Nov 2022 03:36:24 +0000 (11:36 +0800)
fix #6312
close #6944

packages/reactivity-transform/__tests__/__snapshots__/reactivityTransform.spec.ts.snap
packages/reactivity-transform/__tests__/reactivityTransform.spec.ts
packages/reactivity-transform/src/reactivityTransform.ts

index ea6641578b850f808b713fe40a3f774873399ec2..26490ac9d9d9a5d92c86c7b553286b67e0541b46 100644 (file)
@@ -24,6 +24,35 @@ exports[`$$ 1`] = `
     "
 `;
 
+exports[`$$ with some edge cases 1`] = `
+"import { ref as _ref } from 'vue'
+
+    ;(  /* 2 */ count /* 2 */   )
+    ;(   count /* 2 */, /**/ a   )
+    ;(   (count /* 2 */, /**/ a) /**/   )
+    {
+      a:(count,a)
+    }
+    ;((count) + 1)
+    ;([count])
+    ; (count )
+    console.log(((a)))
+    ;(a,b)
+    ;(((a++,b)))
+    count = ( a++ ,b)
+    count = ()=>(a++,b)
+    let r1 = _ref(a, (a++,b))
+    let r2 = { a:(a++,b),b: (a) }
+    switch((c)){
+      case d:
+        ;(a)
+        ;((h,f))
+        break
+    }
+    ((count++,(count),(count,a)))
+    "
+`;
+
 exports[`$computed declaration 1`] = `
 "import { computed as _computed } from 'vue'
 
index f1c5d4eb0cb6611bf22c99454d477236479c740e..d1e0368f6865ac128dd212e41698195ef0fad2dc 100644 (file)
@@ -305,6 +305,50 @@ test('$$', () => {
   assertCode(code)
 })
 
+test('$$ with some edge cases', () => {
+  const { code } = transform(`
+    $$(  /* 2 */ count /* 2 */   )
+    $$(   count /* 2 */, /**/ a   )
+    $$(   (count /* 2 */, /**/ a) /**/   )
+    {
+      a:$$(count,a)
+    }
+    $$((count) + 1)
+    $$([count])
+    $$ (count )
+    console.log($$($$(a)))
+    $$(a,b)
+    $$($$((a++,b)))
+    count = $$( a++ ,b)
+    count = ()=>$$(a++,b)
+    let r1 = $ref(a, $$(a++,b))
+    let r2 = { a:$$(a++,b),b:$$ (a) }
+    switch($$(c)){
+      case d:
+        $$(a)
+        $$($$(h,f))
+        break
+    }
+    ($$(count++,$$(count),$$(count,a)))
+    `)
+  expect(code).toMatch(`/* 2 */ count /* 2 */`)
+  expect(code).toMatch(`;(   count /* 2 */, /**/ a   )`)
+  expect(code).toMatch(`;(   (count /* 2 */, /**/ a) /**/   )`)
+  expect(code).toMatch(`a:(count,a)`)
+  expect(code).toMatch(`;((count) + 1)`)
+  expect(code).toMatch(`;([count])`)
+  expect(code).toMatch(`;(a,b)`)
+  expect(code).toMatch(`log(((a)))`)
+  expect(code).toMatch(`count = ( a++ ,b)`)
+  expect(code).toMatch(`()=>(a++,b)`)
+  expect(code).toMatch(`_ref(a, (a++,b))`)
+  expect(code).toMatch(`{ a:(a++,b),b: (a) }`)
+  expect(code).toMatch(`switch((c))`)
+  expect(code).toMatch(`;((h,f))`)
+  expect(code).toMatch(`((count++,(count),(count,a)))`)
+  assertCode(code)
+})
+
 test('nested scopes', () => {
   const { code, rootRefs } = transform(`
     let a = $ref(0)
index f35be8b2e1de17ebc91a61c1a69b5b6edba5aa53..4f6d47a6d844b0f55caa89f0b8e39f0d95668900 100644 (file)
@@ -671,8 +671,29 @@ export function transformAST(
           currentScope[escapeSymbol] === undefined &&
           callee === escapeSymbol
         ) {
-          s.remove(node.callee.start! + offset, node.callee.end! + offset)
           escapeScope = node
+          s.remove(node.callee.start! + offset, node.callee.end! + offset)
+
+          if (parent?.type === 'ExpressionStatement') {
+            // edge case where the call expression is an expression statement
+            // if its own - prepend semicolon to avoid it being parsed as
+            // function invocation of previous line
+            let i =
+              (node.leadingComments
+                ? node.leadingComments[0].start
+                : node.start)! + offset
+            while (i--) {
+              const char = s.original.charAt(i)
+              if (char === '\n') {
+                // only insert semi if it's actually the fisrt thign after
+                // newline
+                s.prependRight(node.start! + offset, ';')
+                break
+              } else if (!/\s/.test(char)) {
+                break
+              }
+            }
+          }
         }
 
         // TODO remove when out of experimental