Skip to content

Commit 11d9a60

Browse files
committed
Add test case, cache similarly to loop cache, reuse loop cache key (now corrected)
1 parent 1074ddd commit 11d9a60

File tree

6 files changed

+28166
-4
lines changed

6 files changed

+28166
-4
lines changed

src/compiler/checker.ts

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,7 @@ namespace ts {
561561
const symbolLinks: SymbolLinks[] = [];
562562
const nodeLinks: NodeLinks[] = [];
563563
const flowLoopCaches: Map<Type>[] = [];
564+
const flowAssignmentCaches: Map<Type>[] = [];
564565
const flowLoopNodes: FlowNode[] = [];
565566
const flowLoopKeys: string[] = [];
566567
const flowLoopTypes: Type[][] = [];
@@ -16093,6 +16094,7 @@ namespace ts {
1609316094

1609416095
function getFlowTypeOfReference(reference: Node, declaredType: Type, initialType = declaredType, flowContainer?: Node, couldBeUninitialized?: boolean) {
1609516096
let key: string | undefined;
16097+
let keySet = false;
1609616098
let flowDepth = 0;
1609716099
if (flowAnalysisDisabled) {
1609816100
return errorType;
@@ -16113,6 +16115,14 @@ namespace ts {
1611316115
}
1611416116
return resultType;
1611516117

16118+
function getOrSetCacheKey() {
16119+
if (keySet) {
16120+
return key;
16121+
}
16122+
keySet = true;
16123+
return key = getFlowCacheKey(reference, declaredType, initialType, flowContainer);
16124+
}
16125+
1611616126
function getTypeAtFlowNode(flow: FlowNode): FlowType {
1611716127
if (flowDepth === 2000) {
1611816128
// We have made 2000 recursive invocations. To avoid overflowing the call stack we report an error
@@ -16124,6 +16134,17 @@ namespace ts {
1612416134
flowDepth++;
1612516135
while (true) {
1612616136
const flags = flow.flags;
16137+
if (flags & FlowFlags.Cached) {
16138+
const key = getOrSetCacheKey();
16139+
if (key) {
16140+
const id = getFlowNodeId(flow);
16141+
const cache = flowAssignmentCaches[id] || (flowAssignmentCaches[id] = createMap<Type>());
16142+
const cached = cache.get(key);
16143+
if (cached) {
16144+
return cached;
16145+
}
16146+
}
16147+
}
1612716148
if (flags & FlowFlags.Shared) {
1612816149
// We cache results of flow type resolution for shared nodes that were previously visited in
1612916150
// the same getFlowTypeOfReference invocation. A node is considered shared when it is the
@@ -16154,6 +16175,15 @@ namespace ts {
1615416175
flow = (<FlowAssignment>flow).antecedent;
1615516176
continue;
1615616177
}
16178+
else if (flowLoopCount === flowLoopStart) { // Only cache assignments when not within loop analysis
16179+
const key = getOrSetCacheKey();
16180+
if (key && !isIncomplete(type)) {
16181+
flow.flags |= FlowFlags.Cached;
16182+
const id = getFlowNodeId(flow);
16183+
const cache = flowAssignmentCaches[id] || (flowAssignmentCaches[id] = createMap<Type>());
16184+
cache.set(key, type as Type);
16185+
}
16186+
}
1615716187
}
1615816188
else if (flags & FlowFlags.Condition) {
1615916189
type = getTypeAtFlowCondition(<FlowCondition>flow);
@@ -16366,12 +16396,10 @@ namespace ts {
1636616396
// this flow loop junction, return the cached type.
1636716397
const id = getFlowNodeId(flow);
1636816398
const cache = flowLoopCaches[id] || (flowLoopCaches[id] = createMap<Type>());
16399+
const key = getOrSetCacheKey();
1636916400
if (!key) {
16370-
key = getFlowCacheKey(reference, declaredType, initialType, flowContainer);
1637116401
// No cache key is generated when binding patterns are in unnarrowable situations
16372-
if (!key) {
16373-
return declaredType;
16374-
}
16402+
return declaredType;
1637516403
}
1637616404
const cached = cache.get(key);
1637716405
if (cached) {

src/compiler/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2546,6 +2546,8 @@ namespace ts {
25462546
Shared = 1 << 10, // Referenced as antecedent more than once
25472547
PreFinally = 1 << 11, // Injected edge that links pre-finally label and pre-try flow
25482548
AfterFinally = 1 << 12, // Injected edge that links post-finally flow with the rest of the graph
2549+
/** @internal */
2550+
Cached = 1 << 13, // Indicates that at least one cross-call cache entry exists for this node, even if not a loop participant
25492551
Label = BranchLabel | LoopLabel,
25502552
Condition = TrueCondition | FalseCondition
25512553
}

0 commit comments

Comments
 (0)