refactor(ref-transform): improve algorithm into one pass

This commit is contained in:
Evan You
2021-08-23 18:22:21 -04:00
parent 06051c4bf2
commit f1fa30adc3
4 changed files with 437 additions and 409 deletions

View File

@@ -18,9 +18,7 @@ export function walkIdentifiers(
isReference: boolean,
isLocal: boolean
) => void,
onNode?: (node: Node, parent: Node, parentStack: Node[]) => void | boolean,
includeAll = false,
analyzeScope = true,
parentStack: Node[] = [],
knownIds: Record<string, number> = Object.create(null)
) {
@@ -41,11 +39,8 @@ export function walkIdentifiers(
) {
return this.skip()
}
if (onNode && onNode(node, parent!, parentStack) === false) {
return this.skip()
}
if (node.type === 'Identifier') {
const isLocal = analyzeScope && !!knownIds[node.name]
const isLocal = !!knownIds[node.name]
const isRefed = isReferencedIdentifier(node, parent!, parentStack)
if (includeAll || (isRefed && !isLocal)) {
onIdentifier(node, parent!, parentStack, isRefed, isLocal)
@@ -56,24 +51,20 @@ export function walkIdentifiers(
) {
// mark property in destructure pattern
;(node as any).inPattern = true
} else if (analyzeScope) {
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)
)
} else if (node.type === 'BlockStatement') {
// #3445 record block-level local variables
walkBlockDeclarations(node, id =>
markScopeIdentifier(node, id, knownIds)
)
}
} 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))
} else if (node.type === 'BlockStatement') {
// #3445 record block-level local variables
walkBlockDeclarations(node, id =>
markScopeIdentifier(node, id, knownIds)
)
}
},
leave(node: Node & { scopeIds?: Set<string> }, parent: Node | undefined) {
parent && parentStack.pop()
if (analyzeScope && node !== rootExp && node.scopeIds) {
if (node !== rootExp && node.scopeIds) {
for (const id of node.scopeIds) {
knownIds[id]--
if (knownIds[id] === 0) {
@@ -189,13 +180,13 @@ export function extractIdentifiers(
break
case 'ObjectPattern':
param.properties.forEach(prop => {
for (const prop of param.properties) {
if (prop.type === 'RestElement') {
extractIdentifiers(prop.argument, nodes)
} else {
extractIdentifiers(prop.value, nodes)
}
})
}
break
case 'ArrayPattern':

View File

@@ -282,9 +282,7 @@ export function processExpression(
ids.push(node as QualifiedId)
}
},
undefined,
true, // invoke on ALL identifiers
true, // isLocal scope analysis
parentStack,
knownIds
)