mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-14 16:56:06 -05:00
Use isReachableFlowNode to check for implicit return
This commit is contained in:
@@ -569,7 +569,7 @@ namespace ts {
|
||||
}
|
||||
// We create a return control flow graph for IIFEs and constructors. For constructors
|
||||
// we use the return control flow graph in strict property initialization checks.
|
||||
currentReturnTarget = isIIFE || node.kind === SyntaxKind.Constructor ? createBranchLabel() : undefined;
|
||||
currentReturnTarget = containerFlags & ContainerFlags.IsFunctionLike && nodeIsPresent((<FunctionLikeDeclaration>node).body) ? createBranchLabel() : undefined;
|
||||
currentBreakTarget = undefined;
|
||||
currentContinueTarget = undefined;
|
||||
activeLabels = undefined;
|
||||
@@ -589,9 +589,7 @@ namespace ts {
|
||||
if (currentReturnTarget) {
|
||||
addAntecedent(currentReturnTarget, currentFlow);
|
||||
currentFlow = finishFlowLabel(currentReturnTarget);
|
||||
if (node.kind === SyntaxKind.Constructor) {
|
||||
(<ConstructorDeclaration>node).returnFlowNode = currentFlow;
|
||||
}
|
||||
(<FunctionLikeDeclaration>node).returnFlowNode = currentFlow;
|
||||
}
|
||||
if (!isIIFE) {
|
||||
currentFlow = saveCurrentFlow;
|
||||
|
||||
@@ -23803,15 +23803,10 @@ namespace ts {
|
||||
return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes);
|
||||
}
|
||||
|
||||
function isNeverFunctionCall(expr: Expression) {
|
||||
const signature = expr.kind === SyntaxKind.CallExpression && getEffectsSignature(<CallExpression>expr);
|
||||
return !!(signature && getReturnTypeOfSignature(signature).flags & TypeFlags.Never);
|
||||
}
|
||||
|
||||
function functionHasImplicitReturn(func: FunctionLikeDeclaration) {
|
||||
return !!(func.flags & NodeFlags.HasImplicitReturn) && !some((<Block>func.body).statements, statement =>
|
||||
statement.kind === SyntaxKind.SwitchStatement && isExhaustiveSwitchStatement(<SwitchStatement>statement) ||
|
||||
statement.kind === SyntaxKind.ExpressionStatement && isNeverFunctionCall((<ExpressionStatement>statement).expression));
|
||||
return !!(func.flags & NodeFlags.HasImplicitReturn &&
|
||||
!some((<Block>func.body).statements, s => s.kind === SyntaxKind.SwitchStatement && isExhaustiveSwitchStatement(<SwitchStatement>s)) &&
|
||||
!(func.returnFlowNode && !isReachableFlowNode(func.returnFlowNode)));
|
||||
}
|
||||
|
||||
/** NOTE: Return value of `[]` means a different thing than `undefined`. `[]` means func returns `void`, `undefined` means it returns `never`. */
|
||||
|
||||
@@ -1040,6 +1040,7 @@ namespace ts {
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
body?: Block | Expression;
|
||||
/* @internal */ returnFlowNode?: FlowNode;
|
||||
}
|
||||
|
||||
export type FunctionLikeDeclaration =
|
||||
@@ -1085,7 +1086,6 @@ namespace ts {
|
||||
kind: SyntaxKind.Constructor;
|
||||
parent: ClassLikeDeclaration;
|
||||
body?: FunctionBody;
|
||||
/* @internal */ returnFlowNode?: FlowNode;
|
||||
}
|
||||
|
||||
/** For when we encounter a semicolon in a class declaration. ES6 allows these as class elements. */
|
||||
|
||||
Reference in New Issue
Block a user