@@ -44241,9 +44241,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
44241
44241
const nodeId = getNodeId(container);
44242
44242
if (!queryTypeParameterReferencesCache.has(nodeId)) {
44243
44243
const flowNodes = collectFlowNodes(container); // >> TODO: collectFlowNodes may have duplicates
44244
- // >> TODO: this will cause us to possibly visit the same flow nodes more than once.
44245
- // >> Dedupe work.
44246
- flowNodes.forEach(flowNode => visitFlowNode(flowNode, collectNode));
44244
+ visitFlowNodes(flowNodes, collectNode);
44247
44245
queryTypeParameterReferencesCache.set(nodeId, references);
44248
44246
}
44249
44247
return queryTypeParameterReferencesCache.get(nodeId)!;
@@ -44431,18 +44429,26 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
44431
44429
return !!(flow.flags & (FlowFlags.Assignment | FlowFlags.Condition | FlowFlags.SwitchClause | FlowFlags.ArrayMutation | FlowFlags.Call | FlowFlags.ReduceLabel));
44432
44430
}
44433
44431
44434
- function visitFlowNode(flow: FlowNode, visit: (n: FlowNode) => void): void {
44435
- visit(flow);
44436
- const flags = flow.flags;
44437
- if (flags & FlowFlags.Label) {
44438
- return (flow as FlowLabel).antecedents?.forEach(f => visitFlowNode(f, visit));
44439
- }
44440
- if (flags & FlowFlags.ReduceLabel) {
44441
- (flow as FlowReduceLabel).antecedents.forEach(f => visitFlowNode(f, visit));
44442
- // >> TODO: also visit flow.target?
44443
- }
44444
- if (hasFlowAntecedent(flow)) {
44445
- return visitFlowNode((flow as HasFlowAntecedent).antecedent, visit);
44432
+ function visitFlowNodes(flowNodes: FlowNode[], visit: (n: FlowNode) => void): void {
44433
+ const visited = new Set<number>();
44434
+ flowNodes.forEach(visitFlowNode);
44435
+ function visitFlowNode(flow: FlowNode): void {
44436
+ const id = getFlowNodeId(flow);
44437
+ if (visited.has(id)) return;
44438
+ visited.add(id);
44439
+
44440
+ visit(flow);
44441
+ const flags = flow.flags;
44442
+ if (flags & FlowFlags.Label) {
44443
+ return (flow as FlowLabel).antecedents?.forEach(visitFlowNode);
44444
+ }
44445
+ if (flags & FlowFlags.ReduceLabel) {
44446
+ (flow as FlowReduceLabel).antecedents.forEach(visitFlowNode);
44447
+ // >> TODO: also visit flow.target?
44448
+ }
44449
+ if (hasFlowAntecedent(flow)) {
44450
+ return visitFlowNode((flow as HasFlowAntecedent).antecedent);
44451
+ }
44446
44452
}
44447
44453
}
44448
44454
0 commit comments