mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-04-17 01:49:41 -05:00
Record flow analysis errors in NodeLinks
This commit is contained in:
@@ -541,7 +541,7 @@ namespace ts {
|
||||
let flowLoopCount = 0;
|
||||
let sharedFlowCount = 0;
|
||||
let flowNodeCount = -1;
|
||||
let flowAnalysisDisabled = false;
|
||||
let flowAnalysisErrors = false;
|
||||
|
||||
const emptyStringType = getLiteralType("");
|
||||
const zeroType = getLiteralType(0);
|
||||
@@ -15950,17 +15950,14 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function reportFlowControlError(node: Node) {
|
||||
const block = <Block | ModuleBlock | SourceFile>findAncestor(node, isFunctionOrModuleBlock);
|
||||
const sourceFile = getSourceFileOfNode(node);
|
||||
const span = getSpanOfTokenAtPosition(sourceFile, block.statements.pos);
|
||||
diagnostics.add(createFileDiagnostic(sourceFile, span.start, span.length, Diagnostics.The_containing_function_or_module_body_is_too_complex_for_control_flow_analysis));
|
||||
function getContainingBlock(node: Node) {
|
||||
return <Block | ModuleBlock | SourceFile>findAncestor(node, isFunctionOrModuleBlock);
|
||||
}
|
||||
|
||||
function getFlowTypeOfReference(reference: Node, declaredType: Type, initialType = declaredType, flowContainer?: Node, couldBeUninitialized?: boolean) {
|
||||
let key: string | undefined;
|
||||
let flowDepth = 0;
|
||||
if (flowAnalysisDisabled) {
|
||||
if (flowAnalysisErrors && getNodeLinks(getContainingBlock(reference)).flags & NodeCheckFlags.FlowAnalysisError) {
|
||||
return errorType;
|
||||
}
|
||||
if (!reference.flowNode || !couldBeUninitialized && !(declaredType.flags & TypeFlags.Narrowable)) {
|
||||
@@ -15984,9 +15981,14 @@ namespace ts {
|
||||
// We have made 2000 recursive invocations or visited 500000 control flow nodes while analyzing
|
||||
// the containing function or module body, the limit at which we consider the function or module
|
||||
// body is too complex and disable further control flow analysis.
|
||||
if (!flowAnalysisDisabled) {
|
||||
flowAnalysisDisabled = true;
|
||||
reportFlowControlError(reference);
|
||||
const block = getContainingBlock(reference);
|
||||
const nodeLinks = getNodeLinks(block);
|
||||
if (!(nodeLinks.flags & NodeCheckFlags.FlowAnalysisError)) {
|
||||
nodeLinks.flags |= NodeCheckFlags.FlowAnalysisError;
|
||||
const sourceFile = getSourceFileOfNode(block);
|
||||
const span = getSpanOfTokenAtPosition(sourceFile, block.statements.pos);
|
||||
diagnostics.add(createFileDiagnostic(sourceFile, span.start, span.length, Diagnostics.The_containing_function_or_module_body_is_too_complex_for_control_flow_analysis));
|
||||
flowAnalysisErrors = true;
|
||||
}
|
||||
return errorType;
|
||||
}
|
||||
@@ -26032,11 +26034,9 @@ namespace ts {
|
||||
}
|
||||
if (isFunctionOrModuleBlock(node)) {
|
||||
const saveFlowNodeCount = flowNodeCount;
|
||||
const saveFlowAnalysisDisabled = flowAnalysisDisabled;
|
||||
flowNodeCount = 0;
|
||||
forEach(node.statements, checkSourceElement);
|
||||
flowNodeCount = saveFlowNodeCount;
|
||||
flowAnalysisDisabled = saveFlowAnalysisDisabled;
|
||||
}
|
||||
else {
|
||||
forEach(node.statements, checkSourceElement);
|
||||
|
||||
@@ -3855,6 +3855,7 @@ namespace ts {
|
||||
AssignmentsMarked = 0x00800000, // Parameter assignments have been marked
|
||||
ClassWithConstructorReference = 0x01000000, // Class that contains a binding to its constructor inside of the class body.
|
||||
ConstructorReferenceInClass = 0x02000000, // Binding to a class constructor inside of the class's body.
|
||||
FlowAnalysisError = 0x04000000, // Control flow analysis error in this block
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
Reference in New Issue
Block a user