]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-sfc): fix defineProps/defineEmits usage in multi-variable declarations
authorEvan You <yyx990803@gmail.com>
Mon, 28 Jun 2021 20:27:30 +0000 (16:27 -0400)
committerEvan You <yyx990803@gmail.com>
Mon, 28 Jun 2021 20:31:55 +0000 (16:31 -0400)
fix #3739

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

index 4164124a2b36af6929f23ba4ba1e2ed00a552bf5..36604db2576930ef929ec228ee210b21cf458e3c 100644 (file)
@@ -108,6 +108,38 @@ return { props, bar }
 }"
 `;
 
+exports[`SFC compile <script setup> defineProps/defineEmits in multi-variable decalration (full removal) 1`] = `
+"export default {
+  props: ['item'],
+  emits: ['a'],
+  setup(__props, { expose, emit }) {
+  expose()
+
+const props = __props
+    
+    
+return { props, emit }
+}
+
+}"
+`;
+
+exports[`SFC compile <script setup> defineProps/defineEmits in multi-variable decalration 1`] = `
+"export default {
+  props: ['item'],
+  emits: ['a'],
+  setup(__props, { expose, emit }) {
+  expose()
+
+const props = __props
+    const a = 1;
+    
+return { props, a, emit }
+}
+
+}"
+`;
+
 exports[`SFC compile <script setup> errors should allow defineProps/Emit() referencing imported binding 1`] = `
 "import { bar } from './bar'
         
index f59ee13fda34581cce4872c3882b6196fc782aa9..caf56fab59e39f8c311c8cb8013020c9e01d0508 100644 (file)
@@ -97,6 +97,32 @@ const myEmit = defineEmits(['foo', 'bar'])
   emits: ['foo', 'bar'],`)
   })
 
+  test('defineProps/defineEmits in multi-variable decalration', () => {
+    const { content } = compile(`
+    <script setup>
+    const props = defineProps(['item']),
+      a = 1,
+      emit = defineEmits(['a']);
+    </script>
+  `)
+    assertCode(content)
+    expect(content).toMatch(`const a = 1;`) // test correct removal
+    expect(content).toMatch(`props: ['item'],`)
+    expect(content).toMatch(`emits: ['a'],`)
+  })
+
+  test('defineProps/defineEmits in multi-variable decalration (full removal)', () => {
+    const { content } = compile(`
+    <script setup>
+    const props = defineProps(['item']),
+          emit = defineEmits(['a']);
+    </script>
+  `)
+    assertCode(content)
+    expect(content).toMatch(`props: ['item'],`)
+    expect(content).toMatch(`emits: ['a'],`)
+  })
+
   test('defineExpose()', () => {
     const { content } = compile(`
 <script setup>
index 08f0c2d4db1b3a7b76e314637613f9246952c61d..de688acdb303f3ca82dbaa629cd3c2e2cf8c74e2 100644 (file)
@@ -820,7 +820,10 @@ export function compileScript(
     }
 
     if (node.type === 'VariableDeclaration' && !node.declare) {
-      for (const decl of node.declarations) {
+      const total = node.declarations.length
+      let left = total
+      for (let i = 0; i < total; i++) {
+        const decl = node.declarations[i]
         if (decl.init) {
           const isDefineProps =
             processDefineProps(decl.init) || processWithDefaults(decl.init)
@@ -838,10 +841,20 @@ export function compileScript(
             )
           }
           if (isDefineProps || isDefineEmits)
-            if (node.declarations.length === 1) {
+            if (left === 1) {
               s.remove(node.start! + startOffset, node.end! + startOffset)
             } else {
-              s.remove(decl.start! + startOffset, decl.end! + startOffset)
+              let start = decl.start! + startOffset
+              let end = decl.end! + startOffset
+              if (i < total - 1) {
+                // not the last one, locate the start of the next
+                end = node.declarations[i + 1].start! + startOffset
+              } else {
+                // last one, locate the end of the prev
+                start = node.declarations[i - 1].end! + startOffset
+              }
+              s.remove(start, end)
+              left--
             }
         }
       }