@@ -1426,7 +1426,7 @@ const enum IntrinsicTypeKind {
14261426 NoInfer,
14271427}
14281428
1429- const enum FlowNodeReachableCacheFlags {
1429+ const enum SharedFlowNodeCacheFlags {
14301430 None = 0,
14311431 Read = 1 << 0,
14321432 Write = 1 << 1,
@@ -28111,7 +28111,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2811128111 }
2811228112
2811328113 function isReachableFlowNode(flow: FlowNode) {
28114- const result = isReachableFlowNodeWorker(flow, FlowNodeReachableCacheFlags .ReadWrite);
28114+ const result = isReachableFlowNodeWorker(flow, SharedFlowNodeCacheFlags .ReadWrite);
2811528115 lastFlowNode = flow;
2811628116 lastFlowNodeReachable = result;
2811728117 return result;
@@ -28125,26 +28125,26 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2812528125 );
2812628126 }
2812728127
28128- function isReachableFlowNodeWorker(flow: FlowNode, cacheFlags: FlowNodeReachableCacheFlags ): boolean {
28128+ function isReachableFlowNodeWorker(flow: FlowNode, cacheFlags: SharedFlowNodeCacheFlags ): boolean {
2812928129 while (true) {
2813028130 if (flow === lastFlowNode) {
2813128131 return lastFlowNodeReachable;
2813228132 }
2813328133 const flags = flow.flags;
2813428134 if (flags & FlowFlags.Shared) {
28135- if (cacheFlags & FlowNodeReachableCacheFlags .Read) {
28135+ if (cacheFlags & SharedFlowNodeCacheFlags .Read) {
2813628136 const id = getFlowNodeId(flow);
2813728137 let reachable = flowNodeReachable[id];
2813828138 if (reachable !== undefined) {
2813928139 return reachable;
2814028140 }
28141- reachable = isReachableFlowNodeWorker(flow, cacheFlags & ~FlowNodeReachableCacheFlags .Read);
28142- if (cacheFlags & FlowNodeReachableCacheFlags .Write) {
28141+ reachable = isReachableFlowNodeWorker(flow, cacheFlags & ~SharedFlowNodeCacheFlags .Read);
28142+ if (cacheFlags & SharedFlowNodeCacheFlags .Write) {
2814328143 flowNodeReachable[id] = reachable;
2814428144 }
2814528145 return reachable;
2814628146 }
28147- cacheFlags |= FlowNodeReachableCacheFlags .Read;
28147+ cacheFlags |= SharedFlowNodeCacheFlags .Read;
2814828148 }
2814928149 if (flags & (FlowFlags.Assignment | FlowFlags.Condition | FlowFlags.ArrayMutation)) {
2815028150 flow = (flow as FlowAssignment | FlowCondition | FlowArrayMutation).antecedent;
@@ -28204,16 +28204,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2820428204
2820528205 // Return true if the given flow node is preceded by a 'super(...)' call in every possible code path
2820628206 // leading to the node.
28207- function isPostSuperFlowNode(flow: FlowNode, noCacheCheck: boolean ): boolean {
28207+ function isPostSuperFlowNode(flow: FlowNode, cacheFlags: SharedFlowNodeCacheFlags ): boolean {
2820828208 while (true) {
2820928209 const flags = flow.flags;
2821028210 if (flags & FlowFlags.Shared) {
28211- if (!noCacheCheck ) {
28211+ if (cacheFlags & SharedFlowNodeCacheFlags.Read ) {
2821228212 const id = getFlowNodeId(flow);
28213- const postSuper = flowNodePostSuper[id];
28214- return postSuper !== undefined ? postSuper : (flowNodePostSuper[id] = isPostSuperFlowNode(flow, /*noCacheCheck*/ true));
28213+ let postSuper = flowNodePostSuper[id];
28214+ if (postSuper !== undefined) {
28215+ return postSuper;
28216+ }
28217+ postSuper = isPostSuperFlowNode(flow, cacheFlags & ~SharedFlowNodeCacheFlags.Read);
28218+ if (cacheFlags & SharedFlowNodeCacheFlags.Write) {
28219+ flowNodePostSuper[id] = postSuper;
28220+ }
28221+ return postSuper;
2821528222 }
28216- noCacheCheck = false ;
28223+ cacheFlags |= SharedFlowNodeCacheFlags.Read ;
2821728224 }
2821828225 if (flags & (FlowFlags.Assignment | FlowFlags.Condition | FlowFlags.ArrayMutation | FlowFlags.SwitchClause)) {
2821928226 flow = (flow as FlowAssignment | FlowCondition | FlowArrayMutation | FlowSwitchClause).antecedent;
@@ -28226,7 +28233,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2822628233 }
2822728234 else if (flags & FlowFlags.BranchLabel) {
2822828235 // A branching point is post-super if every branch is post-super.
28229- return every((flow as FlowLabel).antecedent, f => isPostSuperFlowNode(f, /*noCacheCheck*/ false ));
28236+ return every((flow as FlowLabel).antecedent, f => isPostSuperFlowNode(f, cacheFlags ));
2823028237 }
2823128238 else if (flags & FlowFlags.LoopLabel) {
2823228239 // A loop is post-super if the control flow path that leads to the top is post-super.
@@ -28236,7 +28243,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2823628243 const target = (flow as FlowReduceLabel).node.target;
2823728244 const saveAntecedents = target.antecedent;
2823828245 target.antecedent = (flow as FlowReduceLabel).node.antecedents;
28239- const result = isPostSuperFlowNode((flow as FlowReduceLabel).antecedent, /*noCacheCheck*/ false );
28246+ const result = isPostSuperFlowNode((flow as FlowReduceLabel).antecedent, SharedFlowNodeCacheFlags.None );
2824028247 target.antecedent = saveAntecedents;
2824128248 return result;
2824228249 }
0 commit comments