Skip to content

Commit c671c3a

Browse files
committed
Only track flow analysis stack depth
1 parent ecea287 commit c671c3a

File tree

1 file changed

+12
-15
lines changed

1 file changed

+12
-15
lines changed

src/compiler/checker.ts

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ namespace ts {
335335
let flowLoopStart = 0;
336336
let flowLoopCount = 0;
337337
let sharedFlowCount = 0;
338-
let flowNodeCount = 0;
338+
let flowAnalysisDisabled = false;
339339

340340
const emptyStringType = getLiteralType("");
341341
const zeroType = getLiteralType(0);
@@ -11470,7 +11470,7 @@ namespace ts {
1147011470
function getFlowTypeOfReference(reference: Node, declaredType: Type, initialType = declaredType, flowContainer?: Node, couldBeUninitialized?: boolean) {
1147111471
let key: string;
1147211472
let flowDepth = 0;
11473-
if (flowNodeCount < 0) {
11473+
if (flowAnalysisDisabled) {
1147411474
return unknownType;
1147511475
}
1147611476
if (!reference.flowNode || !couldBeUninitialized && !(declaredType.flags & TypeFlags.Narrowable)) {
@@ -11490,17 +11490,15 @@ namespace ts {
1149011490
return resultType;
1149111491

1149211492
function getTypeAtFlowNode(flow: FlowNode): FlowType {
11493+
if (flowDepth === 2500) {
11494+
// We have made 2500 recursive invocations. To avoid overflowing the call stack we report an error
11495+
// and disable further control flow analysis in the containing function or module body.
11496+
flowAnalysisDisabled = true;
11497+
reportFlowControlError(reference);
11498+
return unknownType;
11499+
}
1149311500
flowDepth++;
1149411501
while (true) {
11495-
flowNodeCount++;
11496-
if (flowDepth >= 2500 || flowNodeCount >= 100000000) {
11497-
// We have made over 2500 recursive invocations or visited over 100M flow nodes. Rather than
11498-
// overflowing the call stack or spending an excessive amount of time, we report an error
11499-
// and disable further control flow analysis in the containing function or module body.
11500-
flowNodeCount = -1;
11501-
reportFlowControlError(reference);
11502-
return unknownType;
11503-
}
1150411502
const flags = flow.flags;
1150511503
if (flags & FlowFlags.Shared) {
1150611504
// We cache results of flow type resolution for shared nodes that were previously visited in
@@ -19963,10 +19961,9 @@ namespace ts {
1996319961
checkGrammarStatementInAmbientContext(node);
1996419962
}
1996519963
if (isFunctionOrModuleBlock(node)) {
19966-
const saveFlowNodeCount = flowNodeCount;
19967-
flowNodeCount = 0;
19964+
const saveFlowAnalysisDisabled = flowAnalysisDisabled;
1996819965
forEach(node.statements, checkSourceElement);
19969-
flowNodeCount = saveFlowNodeCount;
19966+
flowAnalysisDisabled = saveFlowAnalysisDisabled;
1997019967
}
1997119968
else {
1997219969
forEach(node.statements, checkSourceElement);
@@ -22560,7 +22557,7 @@ namespace ts {
2256022557

2256122558
deferredNodes = [];
2256222559
deferredUnusedIdentifierNodes = produceDiagnostics && noUnusedIdentifiers ? [] : undefined;
22563-
flowNodeCount = 0;
22560+
flowAnalysisDisabled = false;
2256422561

2256522562
forEach(node.statements, checkSourceElement);
2256622563

0 commit comments

Comments
 (0)