From d33127ad34d7b87ca43b6b5dc6ca39898fd92331 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 18 Jul 2014 15:19:23 -0700 Subject: [PATCH 1/5] Complain when a non-void/any function lacks a return expresson. In effect this fixes #62. Also - Changes the error message for get accessors lacking return expressions. - Actually checks for return expressions instead of return statements for get-accessors. - Removes fancy quotes. - Corrects errors in the compiler caught by the new check. - Simplified `checkAndAggregateReturnTypes` by extracting it out to `visitReturnStatements`. --- src/compiler/checker.ts | 122 ++++++++++++----- .../diagnosticInformationMap.generated.ts | 3 +- src/compiler/diagnosticMessages.json | 6 +- src/compiler/parser.ts | 2 +- .../reference/ParameterList5.errors.txt | 4 +- .../reference/ambientGetters.errors.txt | 4 +- .../conflictingTypeAnnotatedVar.errors.txt | 8 +- ...orOnContextuallyTypedReturnType.errors.txt | 4 +- .../functionImplementationErrors.errors.txt | 4 +- .../functionImplementations.errors.txt | 127 ++++++++++++++++++ .../reference/functionReturn.errors.txt | 17 +++ .../functionWithThrowButNoReturn1.errors.txt | 8 ++ ...rsiveImplicitConstructorErrors3.errors.txt | 4 +- .../getterMissingReturnError.errors.txt | 2 +- .../gettersAndSettersErrors.errors.txt | 4 +- tests/baselines/reference/giant.errors.txt | 36 ++--- .../invalidReturnStatements.errors.txt | 10 +- .../missingReturnStatement.errors.txt | 10 ++ .../missingReturnStatement1.errors.txt | 9 ++ .../reference/multiLineErrors.errors.txt | 7 +- .../reference/parserAccessors1.errors.txt | 2 +- .../reference/parserAccessors3.errors.txt | 2 +- .../reference/parserAccessors7.errors.txt | 2 +- .../reference/parserES3Accessors1.errors.txt | 2 +- .../reference/parserES3Accessors3.errors.txt | 2 +- .../parserErrorRecovery_Block3.errors.txt | 6 +- .../parserGenericsInTypeContexts1.errors.txt | 4 +- .../parserGenericsInTypeContexts2.errors.txt | 4 +- ...rGetAccessorWithTypeParameters1.errors.txt | 2 +- .../parserMemberAccessor1.errors.txt | 2 +- ...arserMemberAccessorDeclaration1.errors.txt | 2 +- ...rserMemberAccessorDeclaration10.errors.txt | 2 +- ...rserMemberAccessorDeclaration12.errors.txt | 2 +- ...arserMemberAccessorDeclaration2.errors.txt | 2 +- ...arserMemberAccessorDeclaration3.errors.txt | 2 +- ...arserMemberAccessorDeclaration7.errors.txt | 2 +- ...arserMemberAccessorDeclaration8.errors.txt | 2 +- ...arserMemberAccessorDeclaration9.errors.txt | 2 +- .../reference/parserParameterList5.errors.txt | 4 +- .../parserReturnStatement4.errors.txt | 6 +- ...rSetAccessorWithTypeAnnotation1.errors.txt | 4 +- .../recursiveFunctionTypes.errors.txt | 6 +- .../reference/returnTypeParameter.errors.txt | 4 +- ...rUsedAsTypeParameterConstraint4.errors.txt | 10 +- .../reference/unknownSymbols1.errors.txt | 4 +- 45 files changed, 379 insertions(+), 94 deletions(-) create mode 100644 tests/baselines/reference/functionImplementations.errors.txt create mode 100644 tests/baselines/reference/functionReturn.errors.txt create mode 100644 tests/baselines/reference/functionWithThrowButNoReturn1.errors.txt create mode 100644 tests/baselines/reference/missingReturnStatement.errors.txt create mode 100644 tests/baselines/reference/missingReturnStatement1.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7faabfae6abe2..aea4695e8b422 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3932,12 +3932,10 @@ module ts { } // Aggregate the types of expressions within all the return statements. - var types: Type[] = []; - checkAndAggregateReturnExpressionTypes(func.body); + var types = checkAndAggregateReturnExpressionTypes(func.body, contextualType, contextualMapper); // Try to return the best common type if we have any return expressions. - if (types.length) { - + if (types.length > 0) { var commonType = getBestCommonType(types, /*contextualType:*/ undefined, /*candidatesOnly:*/ true); if (!commonType) { error(func, Diagnostics.No_best_common_type_exists_among_return_expressions); @@ -3963,16 +3961,18 @@ module ts { } return voidType; + } + + // WARNING: This has the same semantics as forEach, in that traversal terminates + // in the event that 'visitor' supplies a truthy value! + function visitReturnStatements(body: Block, visitor: (stmt: ReturnStatement) => T): T { + + return visitHelper(body); - function checkAndAggregateReturnExpressionTypes(node: Node) { + function visitHelper(node: Node): T { switch (node.kind) { case SyntaxKind.ReturnStatement: - var expr = (node).expression; - if (expr) { - var type = checkAndMarkExpression(expr, contextualType, contextualMapper); - if (!contains(types, type)) types.push(type); - } - break; + return visitor(node); case SyntaxKind.Block: case SyntaxKind.FunctionBlock: case SyntaxKind.IfStatement: @@ -3989,15 +3989,77 @@ module ts { case SyntaxKind.TryBlock: case SyntaxKind.CatchBlock: case SyntaxKind.FinallyBlock: - forEachChild(node, checkAndAggregateReturnExpressionTypes); - break; + return forEachChild(node, visitHelper); + } + } + } + + /// Returns a set of types relating to every return expression relating to a function block. + function checkAndAggregateReturnExpressionTypes(body: Block, contextualType?: Type, contextualMapper?: TypeMapper): Type[] { + var aggregatedTypes: Type[] = []; + + visitReturnStatements(body, (returnStatement) => { + var expr = returnStatement.expression; + if (expr) { + var type = checkAndMarkExpression(expr, contextualType, contextualMapper); + if (!contains(aggregatedTypes, type)) { + aggregatedTypes.push(type); + } } + }); + + return aggregatedTypes; + } + + function bodyContainsReturnExpressions(funcBody: Block) { + return visitReturnStatements(funcBody, (returnStatement) => { + return returnStatement.expression !== undefined; + }); + } + + function bodyContainsSingleThrowStatement(body: Block) { + return (body.statements.length === 1) && (body.statements[0].kind === SyntaxKind.ThrowStatement) + } + + // TypeScript Specification 1.0 (6.3) - July 2014 + // An explicitly typed function whose return type isn't the Void or the Any type + // must have at least one return statement somewhere in its body. + // An exception to this rule is if the function implementation consists of a single 'throw' statement. + function checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(decl: FunctionDeclaration, returnType: Type): void { + // Functions that return 'void' or 'any' don't need any return expressions. + if (returnType === voidType || returnType === anyType) { + return; + } + + // If all we have is a function signature, or an arrow function with an expression body, then there is nothing to check. + if (!decl.body || decl.body.kind !== SyntaxKind.FunctionBlock) { + return; } + + var bodyBlock = decl.body; + + // Ensure the body has at least one return expression. + if (bodyContainsReturnExpressions(bodyBlock)) { + return; + } + + // If there are no return expressions, then we need to check if + // the function body consists solely of a throw statement; + // this is to make an exception for unimplemented functions. + if (bodyContainsSingleThrowStatement(bodyBlock)) { + return; + } + + // This function does not conform to the specification. + error(decl.type, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_have_a_return_expression_or_consist_of_a_single_throw_statement); } function checkFunctionExpression(node: FunctionExpression, contextualType?: Type, contextualMapper?: TypeMapper): Type { // The identityMapper object is used to indicate that function expressions are wildcards - if (contextualMapper === identityMapper) return anyFunctionType; + if (contextualMapper === identityMapper) { + return anyFunctionType; + } + var type = getTypeOfSymbol(node.symbol); var links = getNodeLinks(node); @@ -4015,6 +4077,9 @@ module ts { signature.resolvedReturnType = returnType; } } + else { + checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type)); + } } checkSignatureDeclaration(node); if (node.body.kind === SyntaxKind.FunctionBlock) { @@ -4587,28 +4652,9 @@ module ts { } function checkAccessorDeclaration(node: AccessorDeclaration) { - function checkGetterContainsSingleThrowStatement(node: AccessorDeclaration): boolean { - var block = node.body; - return block.statements.length === 1 && block.statements[0].kind === SyntaxKind.ThrowStatement; - } - - function checkGetterReturnsValue(n: Node): boolean { - switch (n.kind) { - case SyntaxKind.ReturnStatement: - return true; - // do not dive into function-like things - return statements there don't count - case SyntaxKind.FunctionExpression: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ArrowFunction: - case SyntaxKind.ObjectLiteral: - return false; - default: - return forEachChild(n, checkGetterReturnsValue); - } - } if (node.kind === SyntaxKind.GetAccessor) { - if (!isInAmbientContext(node) && node.body && !(checkGetterContainsSingleThrowStatement(node) || checkGetterReturnsValue(node))) { - error(node.name, Diagnostics.Getters_must_return_a_value); + if (!isInAmbientContext(node) && node.body && !(bodyContainsReturnExpressions(node.body) || bodyContainsSingleThrowStatement(node.body))) { + error(node.name, Diagnostics.A_get_accessor_must_return_a_value_or_consist_of_a_single_throw_statement); } } @@ -4838,7 +4884,7 @@ module ts { } } - // TODO: Check at least one return statement in non-void/any function (except single throw) + // TODO (drosen): Check at least one return statement in non-void/any function (except single throw) } function checkFunctionDeclaration(node: FunctionDeclaration) { @@ -4850,7 +4896,11 @@ module ts { if (node === firstDeclaration) { checkFunctionOrConstructorSymbol(symbol); } + checkSourceElement(node.body); + if (node.type) { + checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type)); + } // If there is no body and no explicit return type, then report an error. if (program.getCompilerOptions().noImplicitAny && !node.body && !node.type) { diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 2c967b40b6511..75f49efc36c87 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -113,8 +113,9 @@ module ts { The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2117, category: DiagnosticCategory.Error, key: "The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter." }, The_left_hand_side_of_an_in_expression_must_be_of_types_any_string_or_number: { code: 2118, category: DiagnosticCategory.Error, key: "The left-hand side of an 'in' expression must be of types 'any', 'string' or 'number'." }, The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2119, category: DiagnosticCategory.Error, key: "The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter" }, - Getters_must_return_a_value: { code: 2126, category: DiagnosticCategory.Error, key: "Getters must return a value." }, + A_get_accessor_must_return_a_value_or_consist_of_a_single_throw_statement: { code: 2126, category: DiagnosticCategory.Error, key: "A 'get' accessor must return a value or consist of a single 'throw' statement." }, Getter_and_setter_accessors_do_not_agree_in_visibility: { code: 2127, category: DiagnosticCategory.Error, key: "Getter and setter accessors do not agree in visibility." }, + A_function_whose_declared_type_is_neither_void_nor_any_must_have_a_return_expression_or_consist_of_a_single_throw_statement: { code: 2131, category: DiagnosticCategory.Error, key: "A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement." }, Untyped_function_calls_may_not_accept_type_arguments: { code: 2158, category: DiagnosticCategory.Error, key: "Untyped function calls may not accept type arguments." }, The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2120, category: DiagnosticCategory.Error, key: "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter." }, The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type: { code: 2121, category: DiagnosticCategory.Error, key: "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 55d0ffa226824..40da04b39881d 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -446,7 +446,7 @@ "category": "Error", "code": 2119 }, - "Getters must return a value.": { + "A 'get' accessor must return a value or consist of a single 'throw' statement.": { "category": "Error", "code": 2126 }, @@ -454,6 +454,10 @@ "category": "Error", "code": 2127 }, + "A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement.": { + "category": "Error", + "code": 2131 + }, "Untyped function calls may not accept type arguments.": { "category": "Error", "code": 2158 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index fcfb2120b7cbe..c2bffaed57b16 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1070,7 +1070,7 @@ module ts { return finishNode(node); } - function checkIndexSignature(node: SignatureDeclaration, indexerStart: number, indexerLength: number): boolean { + function checkIndexSignature(node: SignatureDeclaration, indexerStart: number, indexerLength: number): void { var parameter = node.parameters[0]; if (node.parameters.length !== 1) { var arityDiagnostic = Diagnostics.An_index_signature_must_have_exactly_one_parameter diff --git a/tests/baselines/reference/ParameterList5.errors.txt b/tests/baselines/reference/ParameterList5.errors.txt index 37487b5c3199d..113afa1008a90 100644 --- a/tests/baselines/reference/ParameterList5.errors.txt +++ b/tests/baselines/reference/ParameterList5.errors.txt @@ -1,5 +1,7 @@ -==== tests/cases/compiler/ParameterList5.ts (2 errors) ==== +==== tests/cases/compiler/ParameterList5.ts (3 errors) ==== function A(): (public B) => C { + ~~~~~~~~~~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. ~~~~~~~~ !!! A parameter property is only allowed in a constructor implementation. ~ diff --git a/tests/baselines/reference/ambientGetters.errors.txt b/tests/baselines/reference/ambientGetters.errors.txt index 05c405810740b..9c2cbe0dbad63 100644 --- a/tests/baselines/reference/ambientGetters.errors.txt +++ b/tests/baselines/reference/ambientGetters.errors.txt @@ -1,9 +1,11 @@ -==== tests/cases/compiler/ambientGetters.ts (2 errors) ==== +==== tests/cases/compiler/ambientGetters.ts (3 errors) ==== declare class A { get length() : number; ~ !!! '{' expected. + ~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. } declare class B { diff --git a/tests/baselines/reference/conflictingTypeAnnotatedVar.errors.txt b/tests/baselines/reference/conflictingTypeAnnotatedVar.errors.txt index 85867f5e573e3..7e864771685ef 100644 --- a/tests/baselines/reference/conflictingTypeAnnotatedVar.errors.txt +++ b/tests/baselines/reference/conflictingTypeAnnotatedVar.errors.txt @@ -1,8 +1,12 @@ -==== tests/cases/compiler/conflictingTypeAnnotatedVar.ts (2 errors) ==== +==== tests/cases/compiler/conflictingTypeAnnotatedVar.ts (4 errors) ==== var foo: string; function foo(): number { } ~~~ !!! Duplicate identifier 'foo'. + ~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. function foo(): number { } ~~~ -!!! Duplicate identifier 'foo'. \ No newline at end of file +!!! Duplicate identifier 'foo'. + ~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. \ No newline at end of file diff --git a/tests/baselines/reference/errorOnContextuallyTypedReturnType.errors.txt b/tests/baselines/reference/errorOnContextuallyTypedReturnType.errors.txt index cb501a10e0640..e472cb831853b 100644 --- a/tests/baselines/reference/errorOnContextuallyTypedReturnType.errors.txt +++ b/tests/baselines/reference/errorOnContextuallyTypedReturnType.errors.txt @@ -1,7 +1,9 @@ -==== tests/cases/compiler/errorOnContextuallyTypedReturnType.ts (1 errors) ==== +==== tests/cases/compiler/errorOnContextuallyTypedReturnType.ts (2 errors) ==== var n1: () => boolean = function () { }; // expect an error here ~~ !!! Type '() => void' is not assignable to type '() => boolean': !!! Type 'void' is not assignable to type 'boolean'. var n2: () => boolean = function ():boolean { }; // expect an error here + ~~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. \ No newline at end of file diff --git a/tests/baselines/reference/functionImplementationErrors.errors.txt b/tests/baselines/reference/functionImplementationErrors.errors.txt index d9d35c555ad9b..e9876914bac82 100644 --- a/tests/baselines/reference/functionImplementationErrors.errors.txt +++ b/tests/baselines/reference/functionImplementationErrors.errors.txt @@ -1,4 +1,4 @@ -==== tests/cases/conformance/functions/functionImplementationErrors.ts (6 errors) ==== +==== tests/cases/conformance/functions/functionImplementationErrors.ts (7 errors) ==== // FunctionExpression with no return type annotation with multiple return statements with unrelated types var f1 = function () { ~~~~~~~~~~~~~ @@ -47,6 +47,8 @@ // Function implemetnation with non -void return type annotation with no return function f5(): number { + ~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. } var m; diff --git a/tests/baselines/reference/functionImplementations.errors.txt b/tests/baselines/reference/functionImplementations.errors.txt new file mode 100644 index 0000000000000..0a30e453480d6 --- /dev/null +++ b/tests/baselines/reference/functionImplementations.errors.txt @@ -0,0 +1,127 @@ +==== tests/cases/conformance/functions/functionImplementations.ts (1 errors) ==== + // FunctionExpression with no return type annotation and no return statement returns void + var v: void = function () { } (); + + // FunctionExpression f with no return type annotation and directly references f in its body returns any + var a: any = function f() { + return f; + }; + var a: any = function f() { + return f(); + }; + + // FunctionExpression f with no return type annotation and indirectly references f in its body returns any + var a: any = function f() { + var x = f; + return x; + }; + + // Two mutually recursive function implementations with no return type annotations + function rec1() { + return rec2(); + } + function rec2() { + return rec1(); + } + var a = rec1(); + var a = rec2(); + + // Two mutually recursive function implementations with return type annotation in one + function rec3(): number { + return rec4(); + } + function rec4() { + return rec3(); + } + var n: number; + var n = rec3(); + var n = rec4(); + + // FunctionExpression with no return type annotation and returns a number + var n = function () { + return 3; + } (); + + // FunctionExpression with no return type annotation and returns null + var nu = null; + var nu = function () { + return null; + } (); + + // FunctionExpression with no return type annotation and returns undefined + var un = undefined; + var un = function () { + return undefined; + } (); + + // FunctionExpression with no return type annotation and returns a type parameter type + var n = function (x: T) { + return x; + } (4); + + // FunctionExpression with no return type annotation and returns a constrained type parameter type + var n = function (x: T) { + return x; + } (4); + + // FunctionExpression with no return type annotation with multiple return statements with identical types + var n = function () { + return 3; + return 5; + }(); + + // FunctionExpression with no return type annotation with multiple return statements with subtype relation between returns + class Base { private m; } + class Derived extends Base { private q; } + var b: Base; + var b = function () { + return new Base(); return new Derived(); + } (); + + // FunctionExpression with no return type annotation with multiple return statements with one a recursive call + var a = function f() { + return new Base(); return new Derived(); return f(); // ? + } (); + + // FunctionExpression with non -void return type annotation with a single throw statement + undefined === function (): number { + throw undefined; + }; + + // Type of 'this' in function implementation is 'any' + function thisFunc() { + var x = this; + var x: any; + } + + // Function signature with optional parameter, no type annotation and initializer has initializer's type + function opt1(n = 4) { + var m = n; + var m: number; + } + + // Function signature with optional parameter, no type annotation and initializer has initializer's widened type + function opt2(n = { x: null, y: undefined }) { + var m = n; + var m: { x: any; y: any }; + } + + // Function signature with initializer referencing other parameter to the left + function opt3(n: number, m = n) { + var y = m; + var y: number; + } + + // Function signature with optional parameter has correct codegen + // (tested above) + + // FunctionExpression with non -void return type annotation return with no expression + function f6(): number { + ~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. + return; + } + + + + \ No newline at end of file diff --git a/tests/baselines/reference/functionReturn.errors.txt b/tests/baselines/reference/functionReturn.errors.txt new file mode 100644 index 0000000000000..020df9703cce3 --- /dev/null +++ b/tests/baselines/reference/functionReturn.errors.txt @@ -0,0 +1,17 @@ +==== tests/cases/compiler/functionReturn.ts (1 errors) ==== + function f0(): void { } + function f1() { + var n: any = f0(); + } + function f2(): any { } + function f3(): string { return; } + ~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. + function f4(): string { + return ''; + return; + } + function f5(): string { + return ''; + return undefined; + } \ No newline at end of file diff --git a/tests/baselines/reference/functionWithThrowButNoReturn1.errors.txt b/tests/baselines/reference/functionWithThrowButNoReturn1.errors.txt new file mode 100644 index 0000000000000..817cf95d6be9e --- /dev/null +++ b/tests/baselines/reference/functionWithThrowButNoReturn1.errors.txt @@ -0,0 +1,8 @@ +==== tests/cases/compiler/functionWithThrowButNoReturn1.ts (1 errors) ==== + function fn(): number { + ~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. + throw new Error('NYI'); + var t; + } + \ No newline at end of file diff --git a/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.errors.txt b/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.errors.txt index 71545ae7503c7..d43866c3874a8 100644 --- a/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.errors.txt +++ b/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.errors.txt @@ -1,8 +1,10 @@ -==== tests/cases/compiler/genericRecursiveImplicitConstructorErrors3.ts (7 errors) ==== +==== tests/cases/compiler/genericRecursiveImplicitConstructorErrors3.ts (8 errors) ==== module TypeScript { export class MemberName { static create(arg1: any, arg2?: any, arg3?: any): MemberName { ~~~~~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. + ~~~~~~~~~~ !!! Generic type 'MemberName' requires 3 type argument(s). } } diff --git a/tests/baselines/reference/getterMissingReturnError.errors.txt b/tests/baselines/reference/getterMissingReturnError.errors.txt index cf4f9b6b1a7a7..ae560c5de8794 100644 --- a/tests/baselines/reference/getterMissingReturnError.errors.txt +++ b/tests/baselines/reference/getterMissingReturnError.errors.txt @@ -4,7 +4,7 @@ ~~ !!! Accessors are only available when targeting ECMAScript 5 and higher. ~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } } diff --git a/tests/baselines/reference/gettersAndSettersErrors.errors.txt b/tests/baselines/reference/gettersAndSettersErrors.errors.txt index 1cfefea5202ed..32531ccf4efe9 100644 --- a/tests/baselines/reference/gettersAndSettersErrors.errors.txt +++ b/tests/baselines/reference/gettersAndSettersErrors.errors.txt @@ -1,4 +1,4 @@ -==== tests/cases/compiler/gettersAndSettersErrors.ts (9 errors) ==== +==== tests/cases/compiler/gettersAndSettersErrors.ts (10 errors) ==== class C { public get Foo() { return "foo";} // ok ~~~ @@ -16,6 +16,8 @@ public set Goo(v:string):string {} // error - setters must not specify a return type ~~~ !!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. } class E { diff --git a/tests/baselines/reference/giant.errors.txt b/tests/baselines/reference/giant.errors.txt index 35dddbb324e6d..f6b6dd5c7962c 100644 --- a/tests/baselines/reference/giant.errors.txt +++ b/tests/baselines/reference/giant.errors.txt @@ -26,7 +26,7 @@ ~~~ !!! Duplicate identifier 'pgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. public psF(param:any) { } ~~~~~~ !!! '{' expected. @@ -40,7 +40,7 @@ ~~~ !!! Duplicate identifier 'rgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. private rsF(param:any) { } ~~~~~~~ !!! '{' expected. @@ -62,7 +62,7 @@ ~~~ !!! Duplicate identifier 'tgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } ~ !!! '{' expected. @@ -128,7 +128,7 @@ ~~~ !!! Duplicate identifier 'pgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. public psF(param:any) { } ~~~~~~ !!! '{' expected. @@ -142,7 +142,7 @@ ~~~ !!! Duplicate identifier 'rgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. private rsF(param:any) { } ~~~~~~~ !!! '{' expected. @@ -164,7 +164,7 @@ ~~~ !!! Duplicate identifier 'tgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } ~ !!! '{' expected. @@ -247,7 +247,7 @@ ~~~ !!! Duplicate identifier 'pgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. public psF(param:any) { } ~~~~~~ !!! '{' expected. @@ -261,7 +261,7 @@ ~~~ !!! Duplicate identifier 'rgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. private rsF(param:any) { } ~~~~~~~ !!! '{' expected. @@ -283,7 +283,7 @@ ~~~ !!! Duplicate identifier 'tgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } ~ !!! '{' expected. @@ -456,7 +456,7 @@ ~~~ !!! Duplicate identifier 'pgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. public psF(param:any) { } ~~~~~~ !!! '{' expected. @@ -470,7 +470,7 @@ ~~~ !!! Duplicate identifier 'rgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. private rsF(param:any) { } ~~~~~~~ !!! '{' expected. @@ -492,7 +492,7 @@ ~~~ !!! Duplicate identifier 'tgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } ~ !!! '{' expected. @@ -558,7 +558,7 @@ ~~~ !!! Duplicate identifier 'pgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. public psF(param:any) { } ~~~~~~ !!! '{' expected. @@ -572,7 +572,7 @@ ~~~ !!! Duplicate identifier 'rgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. private rsF(param:any) { } ~~~~~~~ !!! '{' expected. @@ -594,7 +594,7 @@ ~~~ !!! Duplicate identifier 'tgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } ~ !!! '{' expected. @@ -677,7 +677,7 @@ ~~~ !!! Duplicate identifier 'pgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. public psF(param:any) { } ~~~~~~ !!! '{' expected. @@ -691,7 +691,7 @@ ~~~ !!! Duplicate identifier 'rgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. private rsF(param:any) { } ~~~~~~~ !!! '{' expected. @@ -713,7 +713,7 @@ ~~~ !!! Duplicate identifier 'tgF'. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } ~ !!! '{' expected. diff --git a/tests/baselines/reference/invalidReturnStatements.errors.txt b/tests/baselines/reference/invalidReturnStatements.errors.txt index d870be638b998..b37a2935370d2 100644 --- a/tests/baselines/reference/invalidReturnStatements.errors.txt +++ b/tests/baselines/reference/invalidReturnStatements.errors.txt @@ -1,9 +1,17 @@ -==== tests/cases/conformance/statements/returnStatements/invalidReturnStatements.ts (2 errors) ==== +==== tests/cases/conformance/statements/returnStatements/invalidReturnStatements.ts (6 errors) ==== // all the following should be error function fn1(): number { } + ~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. function fn2(): string { } + ~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. function fn3(): boolean { } + ~~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. function fn4(): Date { } + ~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. function fn7(): any { } // should be valid: any includes void interface I { id: number } diff --git a/tests/baselines/reference/missingReturnStatement.errors.txt b/tests/baselines/reference/missingReturnStatement.errors.txt new file mode 100644 index 0000000000000..5a920744119eb --- /dev/null +++ b/tests/baselines/reference/missingReturnStatement.errors.txt @@ -0,0 +1,10 @@ +==== tests/cases/compiler/missingReturnStatement.ts (1 errors) ==== + module Test { + export class Bug { + public foo():string { + ~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. + } + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/missingReturnStatement1.errors.txt b/tests/baselines/reference/missingReturnStatement1.errors.txt new file mode 100644 index 0000000000000..b0f2f5ef884ec --- /dev/null +++ b/tests/baselines/reference/missingReturnStatement1.errors.txt @@ -0,0 +1,9 @@ +==== tests/cases/compiler/missingReturnStatement1.ts (1 errors) ==== + class Foo { + foo(): number { + ~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. + //return 4; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/multiLineErrors.errors.txt b/tests/baselines/reference/multiLineErrors.errors.txt index b01adc3bfb057..f0ee4fa48353f 100644 --- a/tests/baselines/reference/multiLineErrors.errors.txt +++ b/tests/baselines/reference/multiLineErrors.errors.txt @@ -1,10 +1,15 @@ -==== tests/cases/compiler/multiLineErrors.ts (1 errors) ==== +==== tests/cases/compiler/multiLineErrors.ts (2 errors) ==== var t = 32; function noReturn(): { + ~ n: string; + ~~~~~~~~~~~~~~ y: number; + ~~~~~~~~~~~~~~ } + ~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. { var x = 4; var y = 10; diff --git a/tests/baselines/reference/parserAccessors1.errors.txt b/tests/baselines/reference/parserAccessors1.errors.txt index 4621637b211cc..76747e3710476 100644 --- a/tests/baselines/reference/parserAccessors1.errors.txt +++ b/tests/baselines/reference/parserAccessors1.errors.txt @@ -2,5 +2,5 @@ class C { get Foo() { } ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } \ No newline at end of file diff --git a/tests/baselines/reference/parserAccessors3.errors.txt b/tests/baselines/reference/parserAccessors3.errors.txt index 4d722dd1310f4..dd1f2075ae68a 100644 --- a/tests/baselines/reference/parserAccessors3.errors.txt +++ b/tests/baselines/reference/parserAccessors3.errors.txt @@ -1,4 +1,4 @@ ==== tests/cases/conformance/parser/ecmascript5/Accessors/parserAccessors3.ts (1 errors) ==== var v = { get Foo() { } }; ~~~ -!!! Getters must return a value. \ No newline at end of file +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. \ No newline at end of file diff --git a/tests/baselines/reference/parserAccessors7.errors.txt b/tests/baselines/reference/parserAccessors7.errors.txt index 13597d19f7104..cac6f016814b4 100644 --- a/tests/baselines/reference/parserAccessors7.errors.txt +++ b/tests/baselines/reference/parserAccessors7.errors.txt @@ -3,4 +3,4 @@ ~~~ !!! A 'get' accessor cannot have parameters. ~~~ -!!! Getters must return a value. \ No newline at end of file +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. \ No newline at end of file diff --git a/tests/baselines/reference/parserES3Accessors1.errors.txt b/tests/baselines/reference/parserES3Accessors1.errors.txt index 3ab21b3001e66..53bfc5e868e16 100644 --- a/tests/baselines/reference/parserES3Accessors1.errors.txt +++ b/tests/baselines/reference/parserES3Accessors1.errors.txt @@ -4,5 +4,5 @@ ~~~ !!! Accessors are only available when targeting ECMAScript 5 and higher. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } \ No newline at end of file diff --git a/tests/baselines/reference/parserES3Accessors3.errors.txt b/tests/baselines/reference/parserES3Accessors3.errors.txt index 3678eb94dc11a..74a79ccf6d89f 100644 --- a/tests/baselines/reference/parserES3Accessors3.errors.txt +++ b/tests/baselines/reference/parserES3Accessors3.errors.txt @@ -3,4 +3,4 @@ ~~~ !!! Accessors are only available when targeting ECMAScript 5 and higher. ~~~ -!!! Getters must return a value. \ No newline at end of file +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. \ No newline at end of file diff --git a/tests/baselines/reference/parserErrorRecovery_Block3.errors.txt b/tests/baselines/reference/parserErrorRecovery_Block3.errors.txt index 15bc9ad3385ae..900c0acab9288 100644 --- a/tests/baselines/reference/parserErrorRecovery_Block3.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_Block3.errors.txt @@ -1,9 +1,13 @@ -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/Blocks/parserErrorRecovery_Block3.ts (1 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/Blocks/parserErrorRecovery_Block3.ts (3 errors) ==== class C { private a(): boolean { + ~~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. private b(): boolean { ~~~~~~~ !!! Statement expected. + ~~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. } } \ No newline at end of file diff --git a/tests/baselines/reference/parserGenericsInTypeContexts1.errors.txt b/tests/baselines/reference/parserGenericsInTypeContexts1.errors.txt index 2239f1ff99313..8567f11b77d5d 100644 --- a/tests/baselines/reference/parserGenericsInTypeContexts1.errors.txt +++ b/tests/baselines/reference/parserGenericsInTypeContexts1.errors.txt @@ -1,4 +1,4 @@ -==== tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts1.ts (9 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts1.ts (10 errors) ==== class C extends A implements B { ~~~~ !!! Cannot find name 'A'. @@ -30,6 +30,8 @@ function f2(): F { ~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. + ~~~~ !!! Cannot find name 'F'. } diff --git a/tests/baselines/reference/parserGenericsInTypeContexts2.errors.txt b/tests/baselines/reference/parserGenericsInTypeContexts2.errors.txt index b99d682616956..26631669d8f31 100644 --- a/tests/baselines/reference/parserGenericsInTypeContexts2.errors.txt +++ b/tests/baselines/reference/parserGenericsInTypeContexts2.errors.txt @@ -1,4 +1,4 @@ -==== tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts2.ts (9 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Generics/parserGenericsInTypeContexts2.ts (10 errors) ==== class C extends A, Y>> implements B, Y>> { ~~~~~~~~~~~~~~~~ !!! Cannot find name 'A'. @@ -30,6 +30,8 @@ function f2(): F, Y>> { ~~~~~~~~~~~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. + ~~~~~~~~~~~~~~~~ !!! Cannot find name 'F'. } diff --git a/tests/baselines/reference/parserGetAccessorWithTypeParameters1.errors.txt b/tests/baselines/reference/parserGetAccessorWithTypeParameters1.errors.txt index 33705621fb82f..0f290dbd8abd7 100644 --- a/tests/baselines/reference/parserGetAccessorWithTypeParameters1.errors.txt +++ b/tests/baselines/reference/parserGetAccessorWithTypeParameters1.errors.txt @@ -4,5 +4,5 @@ ~~~ !!! An accessor cannot have type parameters. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessor1.errors.txt b/tests/baselines/reference/parserMemberAccessor1.errors.txt index cc64233237bc9..c768b0ce2fe8e 100644 --- a/tests/baselines/reference/parserMemberAccessor1.errors.txt +++ b/tests/baselines/reference/parserMemberAccessor1.errors.txt @@ -2,6 +2,6 @@ class C { get foo() { } ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. set foo(a) { } } \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessorDeclaration1.errors.txt b/tests/baselines/reference/parserMemberAccessorDeclaration1.errors.txt index a052f03808ec8..403a30a67aed8 100644 --- a/tests/baselines/reference/parserMemberAccessorDeclaration1.errors.txt +++ b/tests/baselines/reference/parserMemberAccessorDeclaration1.errors.txt @@ -2,5 +2,5 @@ class C { get a() { } ~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessorDeclaration10.errors.txt b/tests/baselines/reference/parserMemberAccessorDeclaration10.errors.txt index 8ea973bbb2984..a1b29085f5d61 100644 --- a/tests/baselines/reference/parserMemberAccessorDeclaration10.errors.txt +++ b/tests/baselines/reference/parserMemberAccessorDeclaration10.errors.txt @@ -4,5 +4,5 @@ ~~~~~~ !!! 'export' modifier cannot appear on a class element. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessorDeclaration12.errors.txt b/tests/baselines/reference/parserMemberAccessorDeclaration12.errors.txt index d3ca95a6bc2ab..7cbf2606274ab 100644 --- a/tests/baselines/reference/parserMemberAccessorDeclaration12.errors.txt +++ b/tests/baselines/reference/parserMemberAccessorDeclaration12.errors.txt @@ -4,5 +4,5 @@ ~~~ !!! A 'get' accessor cannot have parameters. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessorDeclaration2.errors.txt b/tests/baselines/reference/parserMemberAccessorDeclaration2.errors.txt index 3cdd230ad6568..1a32d342f1b30 100644 --- a/tests/baselines/reference/parserMemberAccessorDeclaration2.errors.txt +++ b/tests/baselines/reference/parserMemberAccessorDeclaration2.errors.txt @@ -2,5 +2,5 @@ class C { get "b"() { } ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessorDeclaration3.errors.txt b/tests/baselines/reference/parserMemberAccessorDeclaration3.errors.txt index 53a0dd84fac83..dbf94b6420f0f 100644 --- a/tests/baselines/reference/parserMemberAccessorDeclaration3.errors.txt +++ b/tests/baselines/reference/parserMemberAccessorDeclaration3.errors.txt @@ -2,5 +2,5 @@ class C { get 0() { } ~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessorDeclaration7.errors.txt b/tests/baselines/reference/parserMemberAccessorDeclaration7.errors.txt index 614c1251aa483..20ebd2f358380 100644 --- a/tests/baselines/reference/parserMemberAccessorDeclaration7.errors.txt +++ b/tests/baselines/reference/parserMemberAccessorDeclaration7.errors.txt @@ -4,5 +4,5 @@ ~~~~~~ !!! Accessibility modifier already seen. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessorDeclaration8.errors.txt b/tests/baselines/reference/parserMemberAccessorDeclaration8.errors.txt index f28ee32f00ef7..f6d151bfb7fb4 100644 --- a/tests/baselines/reference/parserMemberAccessorDeclaration8.errors.txt +++ b/tests/baselines/reference/parserMemberAccessorDeclaration8.errors.txt @@ -4,5 +4,5 @@ ~~~~~~ !!! 'static' modifier already seen. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessorDeclaration9.errors.txt b/tests/baselines/reference/parserMemberAccessorDeclaration9.errors.txt index d2a52098aa755..e4c88dfd57d5f 100644 --- a/tests/baselines/reference/parserMemberAccessorDeclaration9.errors.txt +++ b/tests/baselines/reference/parserMemberAccessorDeclaration9.errors.txt @@ -4,5 +4,5 @@ ~~~~~~ !!! 'public' modifier must precede 'static' modifier. ~~~ -!!! Getters must return a value. +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. } \ No newline at end of file diff --git a/tests/baselines/reference/parserParameterList5.errors.txt b/tests/baselines/reference/parserParameterList5.errors.txt index c8a9aa31b7836..3b677a57e4848 100644 --- a/tests/baselines/reference/parserParameterList5.errors.txt +++ b/tests/baselines/reference/parserParameterList5.errors.txt @@ -1,5 +1,7 @@ -==== tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList5.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList5.ts (3 errors) ==== function A(): (public B) => C { + ~~~~~~~~~~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. ~~~~~~~~ !!! A parameter property is only allowed in a constructor implementation. ~ diff --git a/tests/baselines/reference/parserReturnStatement4.errors.txt b/tests/baselines/reference/parserReturnStatement4.errors.txt index 6a418c8208038..7ffaae0f482bd 100644 --- a/tests/baselines/reference/parserReturnStatement4.errors.txt +++ b/tests/baselines/reference/parserReturnStatement4.errors.txt @@ -1,4 +1,6 @@ -==== tests/cases/conformance/parser/ecmascript5/Statements/ReturnStatements/parserReturnStatement4.ts (1 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Statements/ReturnStatements/parserReturnStatement4.ts (2 errors) ==== var v = { get foo() { return } }; ~~~ -!!! Accessors are only available when targeting ECMAScript 5 and higher. \ No newline at end of file +!!! Accessors are only available when targeting ECMAScript 5 and higher. + ~~~ +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. \ No newline at end of file diff --git a/tests/baselines/reference/parserSetAccessorWithTypeAnnotation1.errors.txt b/tests/baselines/reference/parserSetAccessorWithTypeAnnotation1.errors.txt index 135f06cf304b4..00084e4607aa7 100644 --- a/tests/baselines/reference/parserSetAccessorWithTypeAnnotation1.errors.txt +++ b/tests/baselines/reference/parserSetAccessorWithTypeAnnotation1.errors.txt @@ -1,7 +1,9 @@ -==== tests/cases/conformance/parser/ecmascript5/Accessors/parserSetAccessorWithTypeAnnotation1.ts (1 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Accessors/parserSetAccessorWithTypeAnnotation1.ts (2 errors) ==== class C { set foo(v): number { ~~~ !!! A 'set' accessor cannot have a return type annotation. + ~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. } } \ No newline at end of file diff --git a/tests/baselines/reference/recursiveFunctionTypes.errors.txt b/tests/baselines/reference/recursiveFunctionTypes.errors.txt index e14d3a38a5c35..ab20996c93312 100644 --- a/tests/baselines/reference/recursiveFunctionTypes.errors.txt +++ b/tests/baselines/reference/recursiveFunctionTypes.errors.txt @@ -1,4 +1,4 @@ -==== tests/cases/compiler/recursiveFunctionTypes.ts (10 errors) ==== +==== tests/cases/compiler/recursiveFunctionTypes.ts (12 errors) ==== function fn(): typeof fn { return 1; } ~ !!! Type 'number' is not assignable to type '() => typeof fn'. @@ -17,7 +17,11 @@ function f1(d: typeof f1) { } function f2(): typeof g2 { } + ~~~~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. function g2(): typeof f2 { } + ~~~~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. interface I { } function f3(): I { return f3; } diff --git a/tests/baselines/reference/returnTypeParameter.errors.txt b/tests/baselines/reference/returnTypeParameter.errors.txt index 1490825c77a6c..1f97ca1cfb49b 100644 --- a/tests/baselines/reference/returnTypeParameter.errors.txt +++ b/tests/baselines/reference/returnTypeParameter.errors.txt @@ -1,5 +1,7 @@ -==== tests/cases/compiler/returnTypeParameter.ts (1 errors) ==== +==== tests/cases/compiler/returnTypeParameter.ts (2 errors) ==== function f(a: T): T { } // error, no return statement + ~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. function f2(a: T): T { return T; } // bug was that this satisfied the return statement requirement ~ !!! Cannot find name 'T'. \ No newline at end of file diff --git a/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt b/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt index 9903408f70bf5..e8891b1072f43 100644 --- a/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt +++ b/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt @@ -1,4 +1,4 @@ -==== tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts (25 errors) ==== +==== tests/cases/conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts (29 errors) ==== // Type parameters are in scope in their own and other type parameter lists // Some negative cases @@ -35,9 +35,13 @@ ~~~~~~~~~~~ !!! Constraint of a type parameter cannot reference any type parameter from the same type parameter list. ~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. + ~ !!! Cannot find name 'V'. function bar(): X { // error ~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. + ~ !!! Cannot find name 'X'. function baz(a: X, b: Y): T { x = y; @@ -54,9 +58,13 @@ ~~~~~~~~~~~ !!! Constraint of a type parameter cannot reference any type parameter from the same type parameter list. ~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. + ~ !!! Cannot find name 'W'. function bar(): Y { // error ~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. + ~ !!! Cannot find name 'Y'. function baz(a: X, b: Y): T { x = y; diff --git a/tests/baselines/reference/unknownSymbols1.errors.txt b/tests/baselines/reference/unknownSymbols1.errors.txt index 220d7ba0ddb80..2d16630a69ebe 100644 --- a/tests/baselines/reference/unknownSymbols1.errors.txt +++ b/tests/baselines/reference/unknownSymbols1.errors.txt @@ -1,4 +1,4 @@ -==== tests/cases/compiler/unknownSymbols1.ts (13 errors) ==== +==== tests/cases/compiler/unknownSymbols1.ts (14 errors) ==== var x = asdf; ~~~~ !!! Cannot find name 'asdf'. @@ -10,6 +10,8 @@ ~~~~ !!! Cannot find name 'asdf'. ~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. + ~~~~ !!! Cannot find name 'asdf'. function foo2() { return asdf; From b7343c214dc1e64899bc889d2a4cd422588f36bd Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 18 Jul 2014 16:01:24 -0700 Subject: [PATCH 2/5] Removed TODO relating to the task I just fixed. --- src/compiler/checker.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index aea4695e8b422..3eb4b9206cafe 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4883,8 +4883,6 @@ module ts { } } } - - // TODO (drosen): Check at least one return statement in non-void/any function (except single throw) } function checkFunctionDeclaration(node: FunctionDeclaration) { From 69018e635a2d7f237f815594c43d7a471c6684dd Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 18 Jul 2014 17:26:45 -0700 Subject: [PATCH 3/5] Minor renaming. --- src/compiler/checker.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3eb4b9206cafe..8fd5e821b1824 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4025,18 +4025,18 @@ module ts { // An explicitly typed function whose return type isn't the Void or the Any type // must have at least one return statement somewhere in its body. // An exception to this rule is if the function implementation consists of a single 'throw' statement. - function checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(decl: FunctionDeclaration, returnType: Type): void { + function checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(func: FunctionDeclaration, returnType: Type): void { // Functions that return 'void' or 'any' don't need any return expressions. if (returnType === voidType || returnType === anyType) { return; } // If all we have is a function signature, or an arrow function with an expression body, then there is nothing to check. - if (!decl.body || decl.body.kind !== SyntaxKind.FunctionBlock) { + if (!func.body || func.body.kind !== SyntaxKind.FunctionBlock) { return; } - var bodyBlock = decl.body; + var bodyBlock = func.body; // Ensure the body has at least one return expression. if (bodyContainsReturnExpressions(bodyBlock)) { @@ -4051,7 +4051,7 @@ module ts { } // This function does not conform to the specification. - error(decl.type, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_have_a_return_expression_or_consist_of_a_single_throw_statement); + error(func.type, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_have_a_return_expression_or_consist_of_a_single_throw_statement); } function checkFunctionExpression(node: FunctionExpression, contextualType?: Type, contextualMapper?: TypeMapper): Type { From 1728f7c65466c3f4998b45709eab756aeea5d767 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 21 Jul 2014 11:30:35 -0700 Subject: [PATCH 4/5] Changed check on annotated functions/getters to only look for return statements. --- src/compiler/checker.ts | 24 ++-- .../functionImplementations.errors.txt | 127 ----------------- .../reference/functionReturn.errors.txt | 17 --- ...gReturnStatementsAndExpressions.errors.txt | 129 ++++++++++++++++++ .../parserReturnStatement4.errors.txt | 6 +- ...nsMissingReturnStatementsAndExpressions.ts | 119 ++++++++++++++++ 6 files changed, 262 insertions(+), 160 deletions(-) delete mode 100644 tests/baselines/reference/functionImplementations.errors.txt delete mode 100644 tests/baselines/reference/functionReturn.errors.txt create mode 100644 tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.errors.txt create mode 100644 tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8fd5e821b1824..d972209969964 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3963,13 +3963,13 @@ module ts { return voidType; } - // WARNING: This has the same semantics as forEach, in that traversal terminates - // in the event that 'visitor' supplies a truthy value! - function visitReturnStatements(body: Block, visitor: (stmt: ReturnStatement) => T): T { + // WARNING: This has the same semantics as the forEach family of functions, + // in that traversal terminates in the event that 'visitor' supplies a truthy value. + function forEachReturnStatement(body: Block, visitor: (stmt: ReturnStatement) => T): T { - return visitHelper(body); + return traverse(body); - function visitHelper(node: Node): T { + function traverse(node: Node): T { switch (node.kind) { case SyntaxKind.ReturnStatement: return visitor(node); @@ -3989,7 +3989,7 @@ module ts { case SyntaxKind.TryBlock: case SyntaxKind.CatchBlock: case SyntaxKind.FinallyBlock: - return forEachChild(node, visitHelper); + return forEachChild(node, traverse); } } } @@ -3998,7 +3998,7 @@ module ts { function checkAndAggregateReturnExpressionTypes(body: Block, contextualType?: Type, contextualMapper?: TypeMapper): Type[] { var aggregatedTypes: Type[] = []; - visitReturnStatements(body, (returnStatement) => { + forEachReturnStatement(body, (returnStatement) => { var expr = returnStatement.expression; if (expr) { var type = checkAndMarkExpression(expr, contextualType, contextualMapper); @@ -4011,9 +4011,9 @@ module ts { return aggregatedTypes; } - function bodyContainsReturnExpressions(funcBody: Block) { - return visitReturnStatements(funcBody, (returnStatement) => { - return returnStatement.expression !== undefined; + function bodyContainsAReturnStatement(funcBody: Block) { + return forEachReturnStatement(funcBody, (returnStatement) => { + return true; }); } @@ -4039,7 +4039,7 @@ module ts { var bodyBlock = func.body; // Ensure the body has at least one return expression. - if (bodyContainsReturnExpressions(bodyBlock)) { + if (bodyContainsAReturnStatement(bodyBlock)) { return; } @@ -4653,7 +4653,7 @@ module ts { function checkAccessorDeclaration(node: AccessorDeclaration) { if (node.kind === SyntaxKind.GetAccessor) { - if (!isInAmbientContext(node) && node.body && !(bodyContainsReturnExpressions(node.body) || bodyContainsSingleThrowStatement(node.body))) { + if (!isInAmbientContext(node) && node.body && !(bodyContainsAReturnStatement(node.body) || bodyContainsSingleThrowStatement(node.body))) { error(node.name, Diagnostics.A_get_accessor_must_return_a_value_or_consist_of_a_single_throw_statement); } } diff --git a/tests/baselines/reference/functionImplementations.errors.txt b/tests/baselines/reference/functionImplementations.errors.txt deleted file mode 100644 index 0a30e453480d6..0000000000000 --- a/tests/baselines/reference/functionImplementations.errors.txt +++ /dev/null @@ -1,127 +0,0 @@ -==== tests/cases/conformance/functions/functionImplementations.ts (1 errors) ==== - // FunctionExpression with no return type annotation and no return statement returns void - var v: void = function () { } (); - - // FunctionExpression f with no return type annotation and directly references f in its body returns any - var a: any = function f() { - return f; - }; - var a: any = function f() { - return f(); - }; - - // FunctionExpression f with no return type annotation and indirectly references f in its body returns any - var a: any = function f() { - var x = f; - return x; - }; - - // Two mutually recursive function implementations with no return type annotations - function rec1() { - return rec2(); - } - function rec2() { - return rec1(); - } - var a = rec1(); - var a = rec2(); - - // Two mutually recursive function implementations with return type annotation in one - function rec3(): number { - return rec4(); - } - function rec4() { - return rec3(); - } - var n: number; - var n = rec3(); - var n = rec4(); - - // FunctionExpression with no return type annotation and returns a number - var n = function () { - return 3; - } (); - - // FunctionExpression with no return type annotation and returns null - var nu = null; - var nu = function () { - return null; - } (); - - // FunctionExpression with no return type annotation and returns undefined - var un = undefined; - var un = function () { - return undefined; - } (); - - // FunctionExpression with no return type annotation and returns a type parameter type - var n = function (x: T) { - return x; - } (4); - - // FunctionExpression with no return type annotation and returns a constrained type parameter type - var n = function (x: T) { - return x; - } (4); - - // FunctionExpression with no return type annotation with multiple return statements with identical types - var n = function () { - return 3; - return 5; - }(); - - // FunctionExpression with no return type annotation with multiple return statements with subtype relation between returns - class Base { private m; } - class Derived extends Base { private q; } - var b: Base; - var b = function () { - return new Base(); return new Derived(); - } (); - - // FunctionExpression with no return type annotation with multiple return statements with one a recursive call - var a = function f() { - return new Base(); return new Derived(); return f(); // ? - } (); - - // FunctionExpression with non -void return type annotation with a single throw statement - undefined === function (): number { - throw undefined; - }; - - // Type of 'this' in function implementation is 'any' - function thisFunc() { - var x = this; - var x: any; - } - - // Function signature with optional parameter, no type annotation and initializer has initializer's type - function opt1(n = 4) { - var m = n; - var m: number; - } - - // Function signature with optional parameter, no type annotation and initializer has initializer's widened type - function opt2(n = { x: null, y: undefined }) { - var m = n; - var m: { x: any; y: any }; - } - - // Function signature with initializer referencing other parameter to the left - function opt3(n: number, m = n) { - var y = m; - var y: number; - } - - // Function signature with optional parameter has correct codegen - // (tested above) - - // FunctionExpression with non -void return type annotation return with no expression - function f6(): number { - ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. - return; - } - - - - \ No newline at end of file diff --git a/tests/baselines/reference/functionReturn.errors.txt b/tests/baselines/reference/functionReturn.errors.txt deleted file mode 100644 index 020df9703cce3..0000000000000 --- a/tests/baselines/reference/functionReturn.errors.txt +++ /dev/null @@ -1,17 +0,0 @@ -==== tests/cases/compiler/functionReturn.ts (1 errors) ==== - function f0(): void { } - function f1() { - var n: any = f0(); - } - function f2(): any { } - function f3(): string { return; } - ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. - function f4(): string { - return ''; - return; - } - function f5(): string { - return ''; - return undefined; - } \ No newline at end of file diff --git a/tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.errors.txt b/tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.errors.txt new file mode 100644 index 0000000000000..97170cf4df1e4 --- /dev/null +++ b/tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.errors.txt @@ -0,0 +1,129 @@ +==== tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts (5 errors) ==== + + function f1(): string { + ~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. + // errors because there are no return statements + } + + function f2(): string { + // Permissible; returns undefined. + return; + } + + function f3(): string { + return "Okay, because this is a return expression."; + } + + function f4(): void { + // Fine since we are typed void. + } + + function f5(): void { + // Fine since we are typed void. + return; + } + + function f6(): void { + // Fine since we are typed void and return undefined + return undefined; + } + + function f7(): void { + // Fine since we are typed void and return null + return null; + } + + function f8(): void { + // Fine since are typed any. + return; + } + + function f9(): void { + // Fine since we are typed any and return undefined + return undefined; + } + + function f10(): void { + // Fine since we are typed any and return null + return null; + } + + function f11(): string { + // Fine since we consist of a single throw statement. + throw undefined; + } + + function f12(): void { + // Fine since we consist of a single throw statement. + throw undefined; + } + + function f13(): any { + // Fine since we consist of a single throw statement. + throw undefined; + } + + function f14(): number { + ~~~~~~ +!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. + // Not fine, since we can *only* consist of a single throw statement + // if no return statements are present but we are annotated. + throw undefined; + throw null; + } + + function f15(): number { + // Fine, since we have a return statement somewhere. + throw undefined; + throw null; + return; + } + + + function f16() { + // Okay; not type annotated. + } + + function f17() { + // Okay; not type annotated. + return; + } + + function f18() { + return "Okay, not type annotated."; + } + + + class C { + public get m1() { + ~~ +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. + // Errors; get accessors must return a value. + } + + public get m2() { + // Permissible; returns undefined. + return; + } + + public get m3() { + return "Okay, because this is a return expression."; + } + + public get m4() { + // Fine since this consists of a single throw statement. + throw null; + } + + public get m5() { + ~~ +!!! A 'get' accessor must return a value or consist of a single 'throw' statement. + // Not fine, since we can *only* consist of a single throw statement + // if no return statements are present but we are a get accessor. + throw null; + throw undefined. + } + ~ +!!! Identifier expected. + } \ No newline at end of file diff --git a/tests/baselines/reference/parserReturnStatement4.errors.txt b/tests/baselines/reference/parserReturnStatement4.errors.txt index 7ffaae0f482bd..6a418c8208038 100644 --- a/tests/baselines/reference/parserReturnStatement4.errors.txt +++ b/tests/baselines/reference/parserReturnStatement4.errors.txt @@ -1,6 +1,4 @@ -==== tests/cases/conformance/parser/ecmascript5/Statements/ReturnStatements/parserReturnStatement4.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Statements/ReturnStatements/parserReturnStatement4.ts (1 errors) ==== var v = { get foo() { return } }; ~~~ -!!! Accessors are only available when targeting ECMAScript 5 and higher. - ~~~ -!!! A 'get' accessor must return a value or consist of a single 'throw' statement. \ No newline at end of file +!!! Accessors are only available when targeting ECMAScript 5 and higher. \ No newline at end of file diff --git a/tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts b/tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts new file mode 100644 index 0000000000000..81259fd7c0c7f --- /dev/null +++ b/tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts @@ -0,0 +1,119 @@ +// @target: es5 + +function f1(): string { + // errors because there are no return statements +} + +function f2(): string { + // Permissible; returns undefined. + return; +} + +function f3(): string { + return "Okay, because this is a return expression."; +} + +function f4(): void { + // Fine since we are typed void. +} + +function f5(): void { + // Fine since we are typed void. + return; +} + +function f6(): void { + // Fine since we are typed void and return undefined + return undefined; +} + +function f7(): void { + // Fine since we are typed void and return null + return null; +} + +function f8(): void { + // Fine since are typed any. + return; +} + +function f9(): void { + // Fine since we are typed any and return undefined + return undefined; +} + +function f10(): void { + // Fine since we are typed any and return null + return null; +} + +function f11(): string { + // Fine since we consist of a single throw statement. + throw undefined; +} + +function f12(): void { + // Fine since we consist of a single throw statement. + throw undefined; +} + +function f13(): any { + // Fine since we consist of a single throw statement. + throw undefined; +} + +function f14(): number { + // Not fine, since we can *only* consist of a single throw statement + // if no return statements are present but we are annotated. + throw undefined; + throw null; +} + +function f15(): number { + // Fine, since we have a return statement somewhere. + throw undefined; + throw null; + return; +} + + +function f16() { + // Okay; not type annotated. +} + +function f17() { + // Okay; not type annotated. + return; +} + +function f18() { + return "Okay, not type annotated."; +} + + +class C { + public get m1() { + // Errors; get accessors must return a value. + } + + public get m2() { + // Permissible; returns undefined. + return; + } + + public get m3() { + return "Okay, because this is a return expression."; + } + + public get m4() { + // Fine since this consists of a single throw statement. + throw null; + } + + public get m5() { + // Not fine, since we can *only* consist of a single throw statement + // if no return statements are present but we are a get accessor. + throw null; + throw undefined. + } +} \ No newline at end of file From 0f4e887155777a65dfd039c814b3de4f8db01e78 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 21 Jul 2014 11:36:29 -0700 Subject: [PATCH 5/5] Changed error message for annotated functions lacking return statements. --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticInformationMap.generated.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- tests/baselines/reference/ParameterList5.errors.txt | 2 +- tests/baselines/reference/ambientGetters.errors.txt | 2 +- .../reference/conflictingTypeAnnotatedVar.errors.txt | 4 ++-- .../errorOnContextuallyTypedReturnType.errors.txt | 2 +- .../reference/functionImplementationErrors.errors.txt | 2 +- .../reference/functionWithThrowButNoReturn1.errors.txt | 2 +- ...ctionsMissingReturnStatementsAndExpressions.errors.txt | 4 ++-- .../genericRecursiveImplicitConstructorErrors3.errors.txt | 2 +- .../reference/gettersAndSettersErrors.errors.txt | 2 +- .../reference/invalidReturnStatements.errors.txt | 8 ++++---- .../baselines/reference/missingReturnStatement.errors.txt | 2 +- .../reference/missingReturnStatement1.errors.txt | 2 +- tests/baselines/reference/multiLineErrors.errors.txt | 2 +- .../reference/parserErrorRecovery_Block3.errors.txt | 4 ++-- .../reference/parserGenericsInTypeContexts1.errors.txt | 2 +- .../reference/parserGenericsInTypeContexts2.errors.txt | 2 +- tests/baselines/reference/parserParameterList5.errors.txt | 2 +- .../parserSetAccessorWithTypeAnnotation1.errors.txt | 2 +- .../baselines/reference/recursiveFunctionTypes.errors.txt | 4 ++-- tests/baselines/reference/returnTypeParameter.errors.txt | 2 +- ...typeParameterUsedAsTypeParameterConstraint4.errors.txt | 8 ++++---- tests/baselines/reference/unknownSymbols1.errors.txt | 2 +- 25 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d972209969964..2a0ffc49b0df1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4051,7 +4051,7 @@ module ts { } // This function does not conform to the specification. - error(func.type, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_have_a_return_expression_or_consist_of_a_single_throw_statement); + 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); } function checkFunctionExpression(node: FunctionExpression, contextualType?: Type, contextualMapper?: TypeMapper): Type { diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 75f49efc36c87..4f831b185bca8 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -115,7 +115,7 @@ module ts { The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2119, category: DiagnosticCategory.Error, key: "The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter" }, A_get_accessor_must_return_a_value_or_consist_of_a_single_throw_statement: { code: 2126, category: DiagnosticCategory.Error, key: "A 'get' accessor must return a value or consist of a single 'throw' statement." }, Getter_and_setter_accessors_do_not_agree_in_visibility: { code: 2127, category: DiagnosticCategory.Error, key: "Getter and setter accessors do not agree in visibility." }, - A_function_whose_declared_type_is_neither_void_nor_any_must_have_a_return_expression_or_consist_of_a_single_throw_statement: { code: 2131, category: DiagnosticCategory.Error, key: "A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement." }, + A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value_or_consist_of_a_single_throw_statement: { code: 2131, category: DiagnosticCategory.Error, key: "A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement." }, Untyped_function_calls_may_not_accept_type_arguments: { code: 2158, category: DiagnosticCategory.Error, key: "Untyped function calls may not accept type arguments." }, The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: { code: 2120, category: DiagnosticCategory.Error, key: "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter." }, The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type: { code: 2121, category: DiagnosticCategory.Error, key: "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 40da04b39881d..0f92044f87783 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -454,7 +454,7 @@ "category": "Error", "code": 2127 }, - "A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement.": { + "A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement.": { "category": "Error", "code": 2131 }, diff --git a/tests/baselines/reference/ParameterList5.errors.txt b/tests/baselines/reference/ParameterList5.errors.txt index 113afa1008a90..412fb71eb1480 100644 --- a/tests/baselines/reference/ParameterList5.errors.txt +++ b/tests/baselines/reference/ParameterList5.errors.txt @@ -1,7 +1,7 @@ ==== tests/cases/compiler/ParameterList5.ts (3 errors) ==== function A(): (public B) => C { ~~~~~~~~~~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. ~~~~~~~~ !!! A parameter property is only allowed in a constructor implementation. ~ diff --git a/tests/baselines/reference/ambientGetters.errors.txt b/tests/baselines/reference/ambientGetters.errors.txt index 9c2cbe0dbad63..a8c913b66c7a6 100644 --- a/tests/baselines/reference/ambientGetters.errors.txt +++ b/tests/baselines/reference/ambientGetters.errors.txt @@ -5,7 +5,7 @@ ~ !!! '{' expected. ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. } declare class B { diff --git a/tests/baselines/reference/conflictingTypeAnnotatedVar.errors.txt b/tests/baselines/reference/conflictingTypeAnnotatedVar.errors.txt index 7e864771685ef..6bb45b67ee743 100644 --- a/tests/baselines/reference/conflictingTypeAnnotatedVar.errors.txt +++ b/tests/baselines/reference/conflictingTypeAnnotatedVar.errors.txt @@ -4,9 +4,9 @@ ~~~ !!! Duplicate identifier 'foo'. ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. function foo(): number { } ~~~ !!! Duplicate identifier 'foo'. ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. \ No newline at end of file +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. \ No newline at end of file diff --git a/tests/baselines/reference/errorOnContextuallyTypedReturnType.errors.txt b/tests/baselines/reference/errorOnContextuallyTypedReturnType.errors.txt index e472cb831853b..414fa7dc4c2b1 100644 --- a/tests/baselines/reference/errorOnContextuallyTypedReturnType.errors.txt +++ b/tests/baselines/reference/errorOnContextuallyTypedReturnType.errors.txt @@ -5,5 +5,5 @@ !!! Type 'void' is not assignable to type 'boolean'. var n2: () => boolean = function ():boolean { }; // expect an error here ~~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. \ No newline at end of file diff --git a/tests/baselines/reference/functionImplementationErrors.errors.txt b/tests/baselines/reference/functionImplementationErrors.errors.txt index e9876914bac82..3da56bd681801 100644 --- a/tests/baselines/reference/functionImplementationErrors.errors.txt +++ b/tests/baselines/reference/functionImplementationErrors.errors.txt @@ -48,7 +48,7 @@ // Function implemetnation with non -void return type annotation with no return function f5(): number { ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. } var m; diff --git a/tests/baselines/reference/functionWithThrowButNoReturn1.errors.txt b/tests/baselines/reference/functionWithThrowButNoReturn1.errors.txt index 817cf95d6be9e..b354a9f8852fe 100644 --- a/tests/baselines/reference/functionWithThrowButNoReturn1.errors.txt +++ b/tests/baselines/reference/functionWithThrowButNoReturn1.errors.txt @@ -1,7 +1,7 @@ ==== tests/cases/compiler/functionWithThrowButNoReturn1.ts (1 errors) ==== function fn(): number { ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. throw new Error('NYI'); var t; } diff --git a/tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.errors.txt b/tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.errors.txt index 97170cf4df1e4..6ddbc91db5701 100644 --- a/tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.errors.txt +++ b/tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.errors.txt @@ -2,7 +2,7 @@ function f1(): string { ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. // errors because there are no return statements } @@ -66,7 +66,7 @@ function f14(): number { ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. // Not fine, since we can *only* consist of a single throw statement // if no return statements are present but we are annotated. throw undefined; diff --git a/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.errors.txt b/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.errors.txt index d43866c3874a8..1320a21f46bfe 100644 --- a/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.errors.txt +++ b/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.errors.txt @@ -3,7 +3,7 @@ export class MemberName { static create(arg1: any, arg2?: any, arg3?: any): MemberName { ~~~~~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. ~~~~~~~~~~ !!! Generic type 'MemberName' requires 3 type argument(s). } diff --git a/tests/baselines/reference/gettersAndSettersErrors.errors.txt b/tests/baselines/reference/gettersAndSettersErrors.errors.txt index 32531ccf4efe9..dbd06a744f0c4 100644 --- a/tests/baselines/reference/gettersAndSettersErrors.errors.txt +++ b/tests/baselines/reference/gettersAndSettersErrors.errors.txt @@ -17,7 +17,7 @@ ~~~ !!! Accessors are only available when targeting ECMAScript 5 and higher. ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. } class E { diff --git a/tests/baselines/reference/invalidReturnStatements.errors.txt b/tests/baselines/reference/invalidReturnStatements.errors.txt index b37a2935370d2..ee371f5f000de 100644 --- a/tests/baselines/reference/invalidReturnStatements.errors.txt +++ b/tests/baselines/reference/invalidReturnStatements.errors.txt @@ -2,16 +2,16 @@ // all the following should be error function fn1(): number { } ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. function fn2(): string { } ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. function fn3(): boolean { } ~~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. function fn4(): Date { } ~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. function fn7(): any { } // should be valid: any includes void interface I { id: number } diff --git a/tests/baselines/reference/missingReturnStatement.errors.txt b/tests/baselines/reference/missingReturnStatement.errors.txt index 5a920744119eb..9a92adf4c03f0 100644 --- a/tests/baselines/reference/missingReturnStatement.errors.txt +++ b/tests/baselines/reference/missingReturnStatement.errors.txt @@ -3,7 +3,7 @@ export class Bug { public foo():string { ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. } } } diff --git a/tests/baselines/reference/missingReturnStatement1.errors.txt b/tests/baselines/reference/missingReturnStatement1.errors.txt index b0f2f5ef884ec..d1d47368bb1f9 100644 --- a/tests/baselines/reference/missingReturnStatement1.errors.txt +++ b/tests/baselines/reference/missingReturnStatement1.errors.txt @@ -2,7 +2,7 @@ class Foo { foo(): number { ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. //return 4; } } diff --git a/tests/baselines/reference/multiLineErrors.errors.txt b/tests/baselines/reference/multiLineErrors.errors.txt index f0ee4fa48353f..911c07731e328 100644 --- a/tests/baselines/reference/multiLineErrors.errors.txt +++ b/tests/baselines/reference/multiLineErrors.errors.txt @@ -9,7 +9,7 @@ ~~~~~~~~~~~~~~ } ~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. { var x = 4; var y = 10; diff --git a/tests/baselines/reference/parserErrorRecovery_Block3.errors.txt b/tests/baselines/reference/parserErrorRecovery_Block3.errors.txt index 900c0acab9288..354cfff1fdd1c 100644 --- a/tests/baselines/reference/parserErrorRecovery_Block3.errors.txt +++ b/tests/baselines/reference/parserErrorRecovery_Block3.errors.txt @@ -2,12 +2,12 @@ class C { private a(): boolean { ~~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. private b(): boolean { ~~~~~~~ !!! Statement expected. ~~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. } } \ No newline at end of file diff --git a/tests/baselines/reference/parserGenericsInTypeContexts1.errors.txt b/tests/baselines/reference/parserGenericsInTypeContexts1.errors.txt index 8567f11b77d5d..574c03823dfe4 100644 --- a/tests/baselines/reference/parserGenericsInTypeContexts1.errors.txt +++ b/tests/baselines/reference/parserGenericsInTypeContexts1.errors.txt @@ -30,7 +30,7 @@ function f2(): F { ~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. ~~~~ !!! Cannot find name 'F'. } diff --git a/tests/baselines/reference/parserGenericsInTypeContexts2.errors.txt b/tests/baselines/reference/parserGenericsInTypeContexts2.errors.txt index 26631669d8f31..f3b47f0436898 100644 --- a/tests/baselines/reference/parserGenericsInTypeContexts2.errors.txt +++ b/tests/baselines/reference/parserGenericsInTypeContexts2.errors.txt @@ -30,7 +30,7 @@ function f2(): F, Y>> { ~~~~~~~~~~~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. ~~~~~~~~~~~~~~~~ !!! Cannot find name 'F'. } diff --git a/tests/baselines/reference/parserParameterList5.errors.txt b/tests/baselines/reference/parserParameterList5.errors.txt index 3b677a57e4848..ccc5d8c0dbf83 100644 --- a/tests/baselines/reference/parserParameterList5.errors.txt +++ b/tests/baselines/reference/parserParameterList5.errors.txt @@ -1,7 +1,7 @@ ==== tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList5.ts (3 errors) ==== function A(): (public B) => C { ~~~~~~~~~~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. ~~~~~~~~ !!! A parameter property is only allowed in a constructor implementation. ~ diff --git a/tests/baselines/reference/parserSetAccessorWithTypeAnnotation1.errors.txt b/tests/baselines/reference/parserSetAccessorWithTypeAnnotation1.errors.txt index 00084e4607aa7..f4898163e0ff0 100644 --- a/tests/baselines/reference/parserSetAccessorWithTypeAnnotation1.errors.txt +++ b/tests/baselines/reference/parserSetAccessorWithTypeAnnotation1.errors.txt @@ -4,6 +4,6 @@ ~~~ !!! A 'set' accessor cannot have a return type annotation. ~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. } } \ No newline at end of file diff --git a/tests/baselines/reference/recursiveFunctionTypes.errors.txt b/tests/baselines/reference/recursiveFunctionTypes.errors.txt index ab20996c93312..833fcf386c07e 100644 --- a/tests/baselines/reference/recursiveFunctionTypes.errors.txt +++ b/tests/baselines/reference/recursiveFunctionTypes.errors.txt @@ -18,10 +18,10 @@ function f2(): typeof g2 { } ~~~~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. function g2(): typeof f2 { } ~~~~~~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. interface I { } function f3(): I { return f3; } diff --git a/tests/baselines/reference/returnTypeParameter.errors.txt b/tests/baselines/reference/returnTypeParameter.errors.txt index 1f97ca1cfb49b..f8927fef42727 100644 --- a/tests/baselines/reference/returnTypeParameter.errors.txt +++ b/tests/baselines/reference/returnTypeParameter.errors.txt @@ -1,7 +1,7 @@ ==== tests/cases/compiler/returnTypeParameter.ts (2 errors) ==== function f(a: T): T { } // error, no return statement ~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. function f2(a: T): T { return T; } // bug was that this satisfied the return statement requirement ~ !!! Cannot find name 'T'. \ No newline at end of file diff --git a/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt b/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt index e8891b1072f43..da073522ae83e 100644 --- a/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt +++ b/tests/baselines/reference/typeParameterUsedAsTypeParameterConstraint4.errors.txt @@ -35,12 +35,12 @@ ~~~~~~~~~~~ !!! Constraint of a type parameter cannot reference any type parameter from the same type parameter list. ~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. ~ !!! Cannot find name 'V'. function bar(): X { // error ~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. ~ !!! Cannot find name 'X'. function baz(a: X, b: Y): T { @@ -58,12 +58,12 @@ ~~~~~~~~~~~ !!! Constraint of a type parameter cannot reference any type parameter from the same type parameter list. ~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. ~ !!! Cannot find name 'W'. function bar(): Y { // error ~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. ~ !!! Cannot find name 'Y'. function baz(a: X, b: Y): T { diff --git a/tests/baselines/reference/unknownSymbols1.errors.txt b/tests/baselines/reference/unknownSymbols1.errors.txt index 2d16630a69ebe..beb39743441af 100644 --- a/tests/baselines/reference/unknownSymbols1.errors.txt +++ b/tests/baselines/reference/unknownSymbols1.errors.txt @@ -10,7 +10,7 @@ ~~~~ !!! Cannot find name 'asdf'. ~~~~ -!!! A function whose declared type is neither 'void' nor 'any' must have a 'return' expression or consist of a single 'throw' statement. +!!! A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. ~~~~ !!! Cannot find name 'asdf'. function foo2() {