@@ -160,6 +160,8 @@ namespace ts {
160160 let getGlobalPromiseConstructorLikeType: () => ObjectType;
161161 let getGlobalThenableType: () => ObjectType;
162162
163+ let jsxElementClassType: Type;
164+
163165 let tupleTypes: Map<TupleType> = {};
164166 let unionTypes: Map<UnionType> = {};
165167 let intersectionTypes: Map<IntersectionType> = {};
@@ -7874,7 +7876,6 @@ namespace ts {
78747876 return prop || unknownSymbol;
78757877 }
78767878
7877- let jsxElementClassType: Type = undefined;
78787879 function getJsxGlobalElementClassType(): Type {
78797880 if (!jsxElementClassType) {
78807881 jsxElementClassType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.ElementClass);
@@ -9620,21 +9621,11 @@ namespace ts {
96209621 return aggregatedTypes;
96219622 }
96229623
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-
96339624 // TypeScript Specification 1.0 (6.3) - July 2014
96349625 // An explicitly typed function whose return type isn't the Void or the Any type
96359626 // must have at least one return statement somewhere in its body.
96369627 // 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 {
96389629 if (!produceDiagnostics) {
96399630 return;
96409631 }
@@ -9645,26 +9636,20 @@ namespace ts {
96459636 }
96469637
96479638 // 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)) {
96499641 return;
96509642 }
96519643
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+ }
96579648 }
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);
96649652 }
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);
96689653 }
96699654
96709655 function checkFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | MethodDeclaration, contextualMapper?: TypeMapper): Type {
@@ -9744,7 +9729,7 @@ namespace ts {
97449729 }
97459730
97469731 if (returnType && !node.asteriskToken) {
9747- checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment (node, isAsync ? promisedType : returnType);
9732+ checkAllCodePathsInNonVoidFunctionReturnOrThrow (node, isAsync ? promisedType : returnType);
97489733 }
97499734
97509735 if (node.body) {
@@ -10945,8 +10930,15 @@ namespace ts {
1094510930 checkGrammarFunctionLikeDeclaration(node) || checkGrammarAccessor(node) || checkGrammarComputedPropertyName(node.name);
1094610931
1094710932 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+ }
1095010942 }
1095110943 }
1095210944
@@ -11877,7 +11869,7 @@ namespace ts {
1187711869 promisedType = checkAsyncFunctionReturnType(node);
1187811870 }
1187911871
11880- checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment (node, isAsync ? promisedType : returnType);
11872+ checkAllCodePathsInNonVoidFunctionReturnOrThrow (node, isAsync ? promisedType : returnType);
1188111873 }
1188211874
1188311875 if (produceDiagnostics && !node.type) {
@@ -14915,7 +14907,7 @@ namespace ts {
1491514907 function initializeTypeChecker() {
1491614908 // Bind all source files and propagate errors
1491714909 forEach(host.getSourceFiles(), file => {
14918- bindSourceFile(file);
14910+ bindSourceFile(file, compilerOptions );
1491914911 });
1492014912
1492114913 // Initialize global symbol table
0 commit comments