@@ -160,6 +160,8 @@ namespace ts {
160
160
let getGlobalPromiseConstructorLikeType: () => ObjectType;
161
161
let getGlobalThenableType: () => ObjectType;
162
162
163
+ let jsxElementClassType: Type;
164
+
163
165
let tupleTypes: Map<TupleType> = {};
164
166
let unionTypes: Map<UnionType> = {};
165
167
let intersectionTypes: Map<IntersectionType> = {};
@@ -7874,7 +7876,6 @@ namespace ts {
7874
7876
return prop || unknownSymbol;
7875
7877
}
7876
7878
7877
- let jsxElementClassType: Type = undefined;
7878
7879
function getJsxGlobalElementClassType(): Type {
7879
7880
if (!jsxElementClassType) {
7880
7881
jsxElementClassType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.ElementClass);
@@ -9620,21 +9621,11 @@ namespace ts {
9620
9621
return aggregatedTypes;
9621
9622
}
9622
9623
9623
- function bodyContainsAReturnStatement(funcBody: Block) {
9624
- return forEachReturnStatement(funcBody, returnStatement => {
9625
- return true;
9626
- });
9627
- }
9628
-
9629
- function bodyContainsSingleThrowStatement(body: Block) {
9630
- return (body.statements.length === 1) && (body.statements[0].kind === SyntaxKind.ThrowStatement);
9631
- }
9632
-
9633
9624
// TypeScript Specification 1.0 (6.3) - July 2014
9634
9625
// An explicitly typed function whose return type isn't the Void or the Any type
9635
9626
// must have at least one return statement somewhere in its body.
9636
9627
// An exception to this rule is if the function implementation consists of a single 'throw' statement.
9637
- function checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment (func: FunctionLikeDeclaration, returnType: Type): void {
9628
+ function checkAllCodePathsInNonVoidFunctionReturnOrThrow (func: FunctionLikeDeclaration, returnType: Type): void {
9638
9629
if (!produceDiagnostics) {
9639
9630
return;
9640
9631
}
@@ -9645,26 +9636,20 @@ namespace ts {
9645
9636
}
9646
9637
9647
9638
// If all we have is a function signature, or an arrow function with an expression body, then there is nothing to check.
9648
- if (nodeIsMissing(func.body) || func.body.kind !== SyntaxKind.Block) {
9639
+ // also if HasImplicitReturnValue flags is not set this means that all codepaths in function body end with return of throw
9640
+ if (nodeIsMissing(func.body) || func.body.kind !== SyntaxKind.Block || !(func.flags & NodeFlags.HasImplicitReturn)) {
9649
9641
return;
9650
9642
}
9651
9643
9652
- let bodyBlock = <Block>func.body;
9653
-
9654
- // Ensure the body has at least one return expression.
9655
- if (bodyContainsAReturnStatement(bodyBlock)) {
9656
- return;
9644
+ if (func.flags & NodeFlags.HasExplicitReturn) {
9645
+ if (compilerOptions.noImplicitReturns) {
9646
+ error(func.type, Diagnostics.Not_all_code_paths_return_a_value);
9647
+ }
9657
9648
}
9658
-
9659
- // If there are no return expressions, then we need to check if
9660
- // the function body consists solely of a throw statement;
9661
- // this is to make an exception for unimplemented functions.
9662
- if (bodyContainsSingleThrowStatement(bodyBlock)) {
9663
- return;
9649
+ else {
9650
+ // This function does not conform to the specification.
9651
+ error(func.type, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
9664
9652
}
9665
-
9666
- // This function does not conform to the specification.
9667
- error(func.type, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value_or_consist_of_a_single_throw_statement);
9668
9653
}
9669
9654
9670
9655
function checkFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | MethodDeclaration, contextualMapper?: TypeMapper): Type {
@@ -9744,7 +9729,7 @@ namespace ts {
9744
9729
}
9745
9730
9746
9731
if (returnType && !node.asteriskToken) {
9747
- checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment (node, isAsync ? promisedType : returnType);
9732
+ checkAllCodePathsInNonVoidFunctionReturnOrThrow (node, isAsync ? promisedType : returnType);
9748
9733
}
9749
9734
9750
9735
if (node.body) {
@@ -10945,8 +10930,15 @@ namespace ts {
10945
10930
checkGrammarFunctionLikeDeclaration(node) || checkGrammarAccessor(node) || checkGrammarComputedPropertyName(node.name);
10946
10931
10947
10932
if (node.kind === SyntaxKind.GetAccessor) {
10948
- if (!isInAmbientContext(node) && nodeIsPresent(node.body) && !(bodyContainsAReturnStatement(<Block>node.body) || bodyContainsSingleThrowStatement(<Block>node.body))) {
10949
- error(node.name, Diagnostics.A_get_accessor_must_return_a_value_or_consist_of_a_single_throw_statement);
10933
+ if (!isInAmbientContext(node) && nodeIsPresent(node.body) && (node.flags & NodeFlags.HasImplicitReturn)) {
10934
+ if (node.flags & NodeFlags.HasExplicitReturn) {
10935
+ if (compilerOptions.noImplicitReturns) {
10936
+ error(node.name, Diagnostics.Not_all_code_paths_return_a_value);
10937
+ }
10938
+ }
10939
+ else {
10940
+ error(node.name, Diagnostics.A_get_accessor_must_return_a_value);
10941
+ }
10950
10942
}
10951
10943
}
10952
10944
@@ -11877,7 +11869,7 @@ namespace ts {
11877
11869
promisedType = checkAsyncFunctionReturnType(node);
11878
11870
}
11879
11871
11880
- checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment (node, isAsync ? promisedType : returnType);
11872
+ checkAllCodePathsInNonVoidFunctionReturnOrThrow (node, isAsync ? promisedType : returnType);
11881
11873
}
11882
11874
11883
11875
if (produceDiagnostics && !node.type) {
@@ -14915,7 +14907,7 @@ namespace ts {
14915
14907
function initializeTypeChecker() {
14916
14908
// Bind all source files and propagate errors
14917
14909
forEach(host.getSourceFiles(), file => {
14918
- bindSourceFile(file);
14910
+ bindSourceFile(file, compilerOptions );
14919
14911
});
14920
14912
14921
14913
// Initialize global symbol table
0 commit comments