Browse Source

fix(compiler-core): fix for loop temp variable prefixing edge case caused by reused AST

daiwei 1 year ago
parent
commit
39d34416cf

+ 13 - 5
packages/compiler-core/src/babelUtils.ts

@@ -81,13 +81,21 @@ export function walkIdentifiers(
           )
         }
       } else if (node.type === 'CatchClause' && node.param) {
-        for (const id of extractIdentifiers(node.param)) {
-          markScopeIdentifier(node, id, knownIds)
+        if (node.scopeIds) {
+          node.scopeIds.forEach(id => markKnownIds(id, knownIds))
+        } else {
+          for (const id of extractIdentifiers(node.param)) {
+            markScopeIdentifier(node, id, knownIds)
+          }
         }
       } else if (isForStatement(node)) {
-        walkForStatement(node, false, id =>
-          markScopeIdentifier(node, id, knownIds),
-        )
+        if (node.scopeIds) {
+          node.scopeIds.forEach(id => markKnownIds(id, knownIds))
+        } else {
+          walkForStatement(node, false, id =>
+            markScopeIdentifier(node, id, knownIds),
+          )
+        }
       }
     },
     leave(node: Node & { scopeIds?: Set<string> }, parent: Node | null) {

+ 25 - 0
packages/compiler-sfc/__tests__/compileTemplate.spec.ts

@@ -428,6 +428,31 @@ test('prefixing edge case for reused AST', () => {
   expect(code).not.toMatch(`_ctx.t`)
 })
 
+test('for loop prefixing edge case for reused AST', () => {
+  const src = `
+  <script setup lang="ts">
+    import { Foo } from './foo'
+  </script>
+  <template>
+    <div @click="(event) => {
+        for (const item of event) {
+          console.log(item)
+        }
+      }"></div>
+  </template>
+  `
+  const { descriptor } = parse(src)
+  // compileScript triggers importUsageCheck
+  compileScript(descriptor, { id: 'xxx' })
+  const { code } = compileTemplate({
+    id: 'xxx',
+    filename: 'test.vue',
+    ast: descriptor.template!.ast,
+    source: descriptor.template!.content,
+  })
+  expect(code).not.toMatch(`_ctx.item`)
+})
+
 test('prefixing edge case for reused AST ssr mode', () => {
   const src = `
   <script setup lang="ts">