Merge pull request #37800 from jtbandes/diagnose-accidental-accessor-call

Better error message for accidental calls to get-accessors
This commit is contained in:
Nathan Shively-Sanders
2020-05-20 17:17:12 -07:00
committed by GitHub
9 changed files with 120 additions and 19 deletions
+15 -7
View File
@@ -26383,7 +26383,7 @@ namespace ts {
return true;
}
function invocationErrorDetails(apparentType: Type, kind: SignatureKind): { messageChain: DiagnosticMessageChain, relatedMessage: DiagnosticMessage | undefined } {
function invocationErrorDetails(errorTarget: Node, apparentType: Type, kind: SignatureKind): { messageChain: DiagnosticMessageChain, relatedMessage: DiagnosticMessage | undefined } {
let errorInfo: DiagnosticMessageChain | undefined;
const isCall = kind === SignatureKind.Call;
const awaitedType = getAwaitedType(apparentType);
@@ -26452,16 +26452,24 @@ namespace ts {
typeToString(apparentType)
);
}
let headMessage = isCall ? Diagnostics.This_expression_is_not_callable : Diagnostics.This_expression_is_not_constructable;
// Diagnose get accessors incorrectly called as functions
if (isCallExpression(errorTarget.parent) && errorTarget.parent.arguments.length === 0) {
const { resolvedSymbol } = getNodeLinks(errorTarget);
if (resolvedSymbol && resolvedSymbol.flags & SymbolFlags.GetAccessor) {
headMessage = Diagnostics.This_expression_is_not_callable_because_it_is_a_get_accessor_Did_you_mean_to_use_it_without;
}
}
return {
messageChain: chainDiagnosticMessages(
errorInfo,
isCall ? Diagnostics.This_expression_is_not_callable : Diagnostics.This_expression_is_not_constructable
),
messageChain: chainDiagnosticMessages(errorInfo, headMessage),
relatedMessage: maybeMissingAwait ? Diagnostics.Did_you_forget_to_use_await : undefined,
};
}
function invocationError(errorTarget: Node, apparentType: Type, kind: SignatureKind, relatedInformation?: DiagnosticRelatedInformation) {
const { messageChain, relatedMessage: relatedInfo } = invocationErrorDetails(apparentType, kind);
const { messageChain, relatedMessage: relatedInfo } = invocationErrorDetails(errorTarget, apparentType, kind);
const diagnostic = createDiagnosticForNodeFromMessageChain(errorTarget, messageChain);
if (relatedInfo) {
addRelatedInfo(diagnostic, createDiagnosticForNode(errorTarget, relatedInfo));
@@ -26565,7 +26573,7 @@ namespace ts {
const headMessage = getDiagnosticHeadMessageForDecoratorResolution(node);
if (!callSignatures.length) {
const errorDetails = invocationErrorDetails(apparentType, SignatureKind.Call);
const errorDetails = invocationErrorDetails(node.expression, apparentType, SignatureKind.Call);
const messageChain = chainDiagnosticMessages(errorDetails.messageChain, headMessage);
const diag = createDiagnosticForNodeFromMessageChain(node.expression, messageChain);
if (errorDetails.relatedMessage) {
+4
View File
@@ -4416,6 +4416,10 @@
"category": "Error",
"code": 6233
},
"This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?": {
"category": "Error",
"code": 6234
},
"Projects to reference": {
"category": "Message",
@@ -0,0 +1,16 @@
tests/cases/compiler/accessorAccidentalCallDiagnostic.ts(6,14): error TS6234: This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?
Type 'Number' has no call signatures.
==== tests/cases/compiler/accessorAccidentalCallDiagnostic.ts (1 errors) ====
// https://github.com/microsoft/TypeScript/issues/24554
class Test24554 {
get property(): number { return 1; }
}
function test24554(x: Test24554) {
return x.property();
~~~~~~~~
!!! error TS6234: This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?
!!! error TS6234: Type 'Number' has no call signatures.
}
@@ -0,0 +1,25 @@
//// [accessorAccidentalCallDiagnostic.ts]
// https://github.com/microsoft/TypeScript/issues/24554
class Test24554 {
get property(): number { return 1; }
}
function test24554(x: Test24554) {
return x.property();
}
//// [accessorAccidentalCallDiagnostic.js]
// https://github.com/microsoft/TypeScript/issues/24554
var Test24554 = /** @class */ (function () {
function Test24554() {
}
Object.defineProperty(Test24554.prototype, "property", {
get: function () { return 1; },
enumerable: false,
configurable: true
});
return Test24554;
}());
function test24554(x) {
return x.property();
}
@@ -0,0 +1,19 @@
=== tests/cases/compiler/accessorAccidentalCallDiagnostic.ts ===
// https://github.com/microsoft/TypeScript/issues/24554
class Test24554 {
>Test24554 : Symbol(Test24554, Decl(accessorAccidentalCallDiagnostic.ts, 0, 0))
get property(): number { return 1; }
>property : Symbol(Test24554.property, Decl(accessorAccidentalCallDiagnostic.ts, 1, 17))
}
function test24554(x: Test24554) {
>test24554 : Symbol(test24554, Decl(accessorAccidentalCallDiagnostic.ts, 3, 1))
>x : Symbol(x, Decl(accessorAccidentalCallDiagnostic.ts, 4, 19))
>Test24554 : Symbol(Test24554, Decl(accessorAccidentalCallDiagnostic.ts, 0, 0))
return x.property();
>x.property : Symbol(Test24554.property, Decl(accessorAccidentalCallDiagnostic.ts, 1, 17))
>x : Symbol(x, Decl(accessorAccidentalCallDiagnostic.ts, 4, 19))
>property : Symbol(Test24554.property, Decl(accessorAccidentalCallDiagnostic.ts, 1, 17))
}
@@ -0,0 +1,20 @@
=== tests/cases/compiler/accessorAccidentalCallDiagnostic.ts ===
// https://github.com/microsoft/TypeScript/issues/24554
class Test24554 {
>Test24554 : Test24554
get property(): number { return 1; }
>property : number
>1 : 1
}
function test24554(x: Test24554) {
>test24554 : (x: Test24554) => any
>x : Test24554
return x.property();
>x.property() : any
>x.property : number
>x : Test24554
>property : number
}
@@ -1,10 +1,10 @@
tests/cases/conformance/classes/members/classTypes/instancePropertiesInheritedIntoClassType.ts(4,13): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
tests/cases/conformance/classes/members/classTypes/instancePropertiesInheritedIntoClassType.ts(7,13): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
tests/cases/conformance/classes/members/classTypes/instancePropertiesInheritedIntoClassType.ts(19,16): error TS2349: This expression is not callable.
tests/cases/conformance/classes/members/classTypes/instancePropertiesInheritedIntoClassType.ts(19,16): error TS6234: This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?
Type 'Number' has no call signatures.
tests/cases/conformance/classes/members/classTypes/instancePropertiesInheritedIntoClassType.ts(26,13): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
tests/cases/conformance/classes/members/classTypes/instancePropertiesInheritedIntoClassType.ts(29,13): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
tests/cases/conformance/classes/members/classTypes/instancePropertiesInheritedIntoClassType.ts(41,16): error TS2349: This expression is not callable.
tests/cases/conformance/classes/members/classTypes/instancePropertiesInheritedIntoClassType.ts(41,16): error TS6234: This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?
Type 'String' has no call signatures.
@@ -33,8 +33,8 @@ tests/cases/conformance/classes/members/classTypes/instancePropertiesInheritedIn
r.y = 4;
var r6 = d.y(); // error
~
!!! error TS2349: This expression is not callable.
!!! error TS2349: Type 'Number' has no call signatures.
!!! error TS6234: This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?
!!! error TS6234: Type 'Number' has no call signatures.
}
@@ -62,6 +62,6 @@ tests/cases/conformance/classes/members/classTypes/instancePropertiesInheritedIn
r.y = '';
var r6 = d.y(); // error
~
!!! error TS2349: This expression is not callable.
!!! error TS2349: Type 'String' has no call signatures.
!!! error TS6234: This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?
!!! error TS6234: Type 'String' has no call signatures.
}
@@ -1,10 +1,10 @@
tests/cases/conformance/classes/members/classTypes/instancePropertyInClassType.ts(4,13): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
tests/cases/conformance/classes/members/classTypes/instancePropertyInClassType.ts(7,13): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
tests/cases/conformance/classes/members/classTypes/instancePropertyInClassType.ts(17,16): error TS2349: This expression is not callable.
tests/cases/conformance/classes/members/classTypes/instancePropertyInClassType.ts(17,16): error TS6234: This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?
Type 'Number' has no call signatures.
tests/cases/conformance/classes/members/classTypes/instancePropertyInClassType.ts(24,13): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
tests/cases/conformance/classes/members/classTypes/instancePropertyInClassType.ts(27,13): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
tests/cases/conformance/classes/members/classTypes/instancePropertyInClassType.ts(37,16): error TS2349: This expression is not callable.
tests/cases/conformance/classes/members/classTypes/instancePropertyInClassType.ts(37,16): error TS6234: This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?
Type 'String' has no call signatures.
@@ -31,8 +31,8 @@ tests/cases/conformance/classes/members/classTypes/instancePropertyInClassType.t
r.y = 4;
var r6 = c.y(); // error
~
!!! error TS2349: This expression is not callable.
!!! error TS2349: Type 'Number' has no call signatures.
!!! error TS6234: This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?
!!! error TS6234: Type 'Number' has no call signatures.
}
@@ -58,6 +58,6 @@ tests/cases/conformance/classes/members/classTypes/instancePropertyInClassType.t
r.y = '';
var r6 = c.y(); // error
~
!!! error TS2349: This expression is not callable.
!!! error TS2349: Type 'String' has no call signatures.
!!! error TS6234: This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?
!!! error TS6234: Type 'String' has no call signatures.
}
@@ -0,0 +1,9 @@
// @target: es5
// https://github.com/microsoft/TypeScript/issues/24554
class Test24554 {
get property(): number { return 1; }
}
function test24554(x: Test24554) {
return x.property();
}