From 0c17476d09655c7232134ed311edadfb93924e63 Mon Sep 17 00:00:00 2001 From: Alexander T Date: Mon, 25 Nov 2019 06:18:04 +0200 Subject: [PATCH] assign error to method definition node if a return type is empty (#35309) --- src/compiler/checker.ts | 2 +- .../getterControlFlowStrictNull.errors.txt | 17 ++++++++++- .../reference/getterControlFlowStrictNull.js | 29 +++++++++++++++++++ .../getterControlFlowStrictNull.symbols | 22 ++++++++++++++ .../getterControlFlowStrictNull.types | 26 +++++++++++++++++ .../compiler/getterControlFlowStrictNull.ts | 12 ++++++++ 6 files changed, 106 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6b64f6dfe7d1b..bb65f5f3782b2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26102,7 +26102,7 @@ namespace ts { error(getEffectiveReturnTypeNode(func), Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value); } else if (type && strictNullChecks && !isTypeAssignableTo(undefinedType, type)) { - error(getEffectiveReturnTypeNode(func), Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined); + error(getEffectiveReturnTypeNode(func) || func, Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined); } else if (compilerOptions.noImplicitReturns) { if (!type) { diff --git a/tests/baselines/reference/getterControlFlowStrictNull.errors.txt b/tests/baselines/reference/getterControlFlowStrictNull.errors.txt index 1c4f02d6a756f..e853ee7d38b62 100644 --- a/tests/baselines/reference/getterControlFlowStrictNull.errors.txt +++ b/tests/baselines/reference/getterControlFlowStrictNull.errors.txt @@ -1,8 +1,9 @@ tests/cases/compiler/getterControlFlowStrictNull.ts(2,9): error TS2366: Function lacks ending return statement and return type does not include 'undefined'. tests/cases/compiler/getterControlFlowStrictNull.ts(11,14): error TS2366: Function lacks ending return statement and return type does not include 'undefined'. +tests/cases/compiler/getterControlFlowStrictNull.ts(20,9): error TS2366: Function lacks ending return statement and return type does not include 'undefined'. -==== tests/cases/compiler/getterControlFlowStrictNull.ts (2 errors) ==== +==== tests/cases/compiler/getterControlFlowStrictNull.ts (3 errors) ==== class A { a(): string | null { ~~~~~~~~~~~~~ @@ -24,4 +25,18 @@ tests/cases/compiler/getterControlFlowStrictNull.ts(11,14): error TS2366: Functi // it should error here because it returns undefined } + } + class C { + get a() { + ~ +!!! error TS2366: Function lacks ending return statement and return type does not include 'undefined'. + if (Math.random() > 0.5) { + return 0; + } + + // it should error here because it returns undefined + } + + set a(value: number) { + } } \ No newline at end of file diff --git a/tests/baselines/reference/getterControlFlowStrictNull.js b/tests/baselines/reference/getterControlFlowStrictNull.js index b55aea4bd6138..00f50144586b6 100644 --- a/tests/baselines/reference/getterControlFlowStrictNull.js +++ b/tests/baselines/reference/getterControlFlowStrictNull.js @@ -16,6 +16,18 @@ class B { // it should error here because it returns undefined } +} +class C { + get a() { + if (Math.random() > 0.5) { + return 0; + } + + // it should error here because it returns undefined + } + + set a(value: number) { + } } //// [getterControlFlowStrictNull.js] @@ -45,3 +57,20 @@ var B = /** @class */ (function () { }); return B; }()); +var C = /** @class */ (function () { + function C() { + } + Object.defineProperty(C.prototype, "a", { + get: function () { + if (Math.random() > 0.5) { + return 0; + } + // it should error here because it returns undefined + }, + set: function (value) { + }, + enumerable: true, + configurable: true + }); + return C; +}()); diff --git a/tests/baselines/reference/getterControlFlowStrictNull.symbols b/tests/baselines/reference/getterControlFlowStrictNull.symbols index 4f10644a5cd3c..fb923bdb75e1a 100644 --- a/tests/baselines/reference/getterControlFlowStrictNull.symbols +++ b/tests/baselines/reference/getterControlFlowStrictNull.symbols @@ -33,3 +33,25 @@ class B { // it should error here because it returns undefined } } +class C { +>C : Symbol(C, Decl(getterControlFlowStrictNull.ts, 17, 1)) + + get a() { +>a : Symbol(C.a, Decl(getterControlFlowStrictNull.ts, 18, 9), Decl(getterControlFlowStrictNull.ts, 25, 5)) + + if (Math.random() > 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return 0; + } + + // it should error here because it returns undefined + } + + set a(value: number) { +>a : Symbol(C.a, Decl(getterControlFlowStrictNull.ts, 18, 9), Decl(getterControlFlowStrictNull.ts, 25, 5)) +>value : Symbol(value, Decl(getterControlFlowStrictNull.ts, 27, 10)) + } +} diff --git a/tests/baselines/reference/getterControlFlowStrictNull.types b/tests/baselines/reference/getterControlFlowStrictNull.types index 2415e24909908..41be9d6fb919c 100644 --- a/tests/baselines/reference/getterControlFlowStrictNull.types +++ b/tests/baselines/reference/getterControlFlowStrictNull.types @@ -43,3 +43,29 @@ class B { // it should error here because it returns undefined } } +class C { +>C : C + + get a() { +>a : number + + if (Math.random() > 0.5) { +>Math.random() > 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + + return 0; +>0 : 0 + } + + // it should error here because it returns undefined + } + + set a(value: number) { +>a : number +>value : number + } +} diff --git a/tests/cases/compiler/getterControlFlowStrictNull.ts b/tests/cases/compiler/getterControlFlowStrictNull.ts index 44fbe35978942..43a0857365c2f 100644 --- a/tests/cases/compiler/getterControlFlowStrictNull.ts +++ b/tests/cases/compiler/getterControlFlowStrictNull.ts @@ -17,4 +17,16 @@ class B { // it should error here because it returns undefined } +} +class C { + get a() { + if (Math.random() > 0.5) { + return 0; + } + + // it should error here because it returns undefined + } + + set a(value: number) { + } } \ No newline at end of file