@@ -44241,9 +44241,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4424144241 const nodeId = getNodeId(container);
4424244242 if (!queryTypeParameterReferencesCache.has(nodeId)) {
4424344243 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);
4424744245 queryTypeParameterReferencesCache.set(nodeId, references);
4424844246 }
4424944247 return queryTypeParameterReferencesCache.get(nodeId)!;
@@ -44431,18 +44429,26 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4443144429 return !!(flow.flags & (FlowFlags.Assignment | FlowFlags.Condition | FlowFlags.SwitchClause | FlowFlags.ArrayMutation | FlowFlags.Call | FlowFlags.ReduceLabel));
4443244430 }
4443344431
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+ }
4444644452 }
4444744453 }
4444844454
0 commit comments