// mark property in destructure pattern
;(node as any).inPattern = true
} else if (isFunctionType(node)) {
- // walk function expressions and add its arguments to known identifiers
- // so that we don't prefix them
- walkFunctionParams(node, id => markScopeIdentifier(node, id, knownIds))
+ if (node.scopeIds) {
+ node.scopeIds.forEach(id => markKnownIds(id, knownIds))
+ } else {
+ // walk function expressions and add its arguments to known identifiers
+ // so that we don't prefix them
+ walkFunctionParams(node, id =>
+ markScopeIdentifier(node, id, knownIds)
+ )
+ }
} else if (node.type === 'BlockStatement') {
- // #3445 record block-level local variables
- walkBlockDeclarations(node, id =>
- markScopeIdentifier(node, id, knownIds)
- )
+ if (node.scopeIds) {
+ node.scopeIds.forEach(id => markKnownIds(id, knownIds))
+ } else {
+ // #3445 record block-level local variables
+ walkBlockDeclarations(node, id =>
+ markScopeIdentifier(node, id, knownIds)
+ )
+ }
}
},
leave(node: Node & { scopeIds?: Set<string> }, parent: Node | undefined) {
return nodes
}
+function markKnownIds(name: string, knownIds: Record<string, number>) {
+ if (name in knownIds) {
+ knownIds[name]++
+ } else {
+ knownIds[name] = 1
+ }
+}
+
function markScopeIdentifier(
node: Node & { scopeIds?: Set<string> },
child: Identifier,
if (node.scopeIds && node.scopeIds.has(name)) {
return
}
- if (name in knownIds) {
- knownIds[name]++
- } else {
- knownIds[name] = 1
- }
+ markKnownIds(name, knownIds)
;(node.scopeIds || (node.scopeIds = new Set())).add(name)
}
SFCTemplateCompileOptions
} from '../src/compileTemplate'
import { parse, SFCTemplateBlock } from '../src/parse'
+import { compileScript } from '../src'
function compile(opts: Omit<SFCTemplateCompileOptions, 'id'>) {
return compileTemplate({
expect(result.code).toMatchSnapshot()
})
+// #9853 regression found in Nuxt tests
+// walkIdentifiers can get called multiple times on the same node
+// due to #9729 calling it during SFC template usage check.
+// conditions needed:
+// 1. `<script setup lang="ts">`
+// 2. Has import
+// 3. inlineTemplate: false
+// 4. AST being reused
+test('prefixing edge case for reused AST', () => {
+ const src = `
+ <script setup lang="ts">
+ import { Foo } from './foo'
+ </script>
+ <template>
+ {{ list.map((t, index) => ({ t: t })) }}
+ </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.t`)
+})
+
interface Pos {
line: number
column: number