|
|
@@ -1344,6 +1344,23 @@ function genRuntimeEmits(emits: Set<string>) {
|
|
|
: ``
|
|
|
}
|
|
|
|
|
|
+function markScopeIdentifier(
|
|
|
+ node: Node & { scopeIds?: Set<string> },
|
|
|
+ child: Identifier,
|
|
|
+ knownIds: Record<string, number>
|
|
|
+) {
|
|
|
+ const { name } = child
|
|
|
+ if (node.scopeIds && node.scopeIds.has(name)) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (name in knownIds) {
|
|
|
+ knownIds[name]++
|
|
|
+ } else {
|
|
|
+ knownIds[name] = 1
|
|
|
+ }
|
|
|
+ ;(node.scopeIds || (node.scopeIds = new Set())).add(name)
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Walk an AST and find identifiers that are variable references.
|
|
|
* This is largely the same logic with `transformExpressions` in compiler-core
|
|
|
@@ -1367,6 +1384,21 @@ function walkIdentifiers(
|
|
|
onIdentifier(node, parent!, parentStack)
|
|
|
}
|
|
|
} else if (isFunction(node)) {
|
|
|
+ // #3445
|
|
|
+ // should not rewrite local variables sharing a name with a top-level ref
|
|
|
+ if (node.body.type === 'BlockStatement') {
|
|
|
+ node.body.body.forEach(p => {
|
|
|
+ if (p.type === 'VariableDeclaration') {
|
|
|
+ ;(walk as any)(p, {
|
|
|
+ enter(child: Node) {
|
|
|
+ if (child.type === 'Identifier') {
|
|
|
+ markScopeIdentifier(node, child, knownIds)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
// walk function expressions and add its arguments to known identifiers
|
|
|
// so that we don't prefix them
|
|
|
node.params.forEach(p =>
|
|
|
@@ -1384,16 +1416,7 @@ function walkIdentifiers(
|
|
|
parent.right === child
|
|
|
)
|
|
|
) {
|
|
|
- const { name } = child
|
|
|
- if (node.scopeIds && node.scopeIds.has(name)) {
|
|
|
- return
|
|
|
- }
|
|
|
- if (name in knownIds) {
|
|
|
- knownIds[name]++
|
|
|
- } else {
|
|
|
- knownIds[name] = 1
|
|
|
- }
|
|
|
- ;(node.scopeIds || (node.scopeIds = new Set())).add(name)
|
|
|
+ markScopeIdentifier(node, child, knownIds)
|
|
|
}
|
|
|
}
|
|
|
})
|