Skip to content

Use related spans for "implement abstract class" errors #48030

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43138,6 +43138,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {

// NOTE: assignability is checked in checkClassDeclaration
const baseProperties = getPropertiesOfType(baseType);
let inheritedAbstractMemberNotImplementedError: Diagnostic | undefined;
basePropertyCheck: for (const baseProperty of baseProperties) {
const base = getTargetSymbol(baseProperty);

Expand Down Expand Up @@ -43176,13 +43177,28 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}

if (!inheritedAbstractMemberNotImplementedError) {
inheritedAbstractMemberNotImplementedError = error(
derivedClassDecl,
Diagnostics.Non_abstract_class_0_does_not_implement_all_abstract_members_of_1,
typeToString(type), typeToString(baseType));

}
if (derivedClassDecl.kind === SyntaxKind.ClassExpression) {
error(derivedClassDecl, Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1,
symbolToString(baseProperty), typeToString(baseType));
addRelatedInfo(
inheritedAbstractMemberNotImplementedError,
createDiagnosticForNode(
baseProperty.valueDeclaration ?? (baseProperty.declarations && first(baseProperty.declarations)) ?? derivedClassDecl,
Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1,
symbolToString(baseProperty), typeToString(baseType)));
}
else {
error(derivedClassDecl, Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2,
typeToString(type), symbolToString(baseProperty), typeToString(baseType));
addRelatedInfo(
inheritedAbstractMemberNotImplementedError,
createDiagnosticForNode(
baseProperty.valueDeclaration ?? (baseProperty.declarations && first(baseProperty.declarations)) ?? derivedClassDecl,
Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2,
typeToString(type), symbolToString(baseProperty), typeToString(baseType)));
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -7760,5 +7760,9 @@
"Compiler option '{0}' cannot be given an empty string.": {
"category": "Error",
"code": 18051
},
"Non-abstract class '{0}' does not implement all abstract members of '{1}'": {
"category": "Error",
"code": 18052
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ import {
} from "../_namespaces/ts.codefix";

const errorCodes = [
Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2.code,
Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1.code,
Diagnostics.Non_abstract_class_0_does_not_implement_all_abstract_members_of_1.code,
];
const fixId = "fixClassDoesntImplementInheritedAbstractMember";
registerCodeFix({
Expand Down
19 changes: 7 additions & 12 deletions tests/baselines/reference/abstractPropertyNegative.errors.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
tests/cases/compiler/abstractPropertyNegative.ts(10,18): error TS2380: The return type of a 'get' accessor must be assignable to its 'set' accessor type
tests/cases/compiler/abstractPropertyNegative.ts(13,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'm' from class 'B'.
tests/cases/compiler/abstractPropertyNegative.ts(13,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'mismatch' from class 'B'.
tests/cases/compiler/abstractPropertyNegative.ts(13,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'prop' from class 'B'.
tests/cases/compiler/abstractPropertyNegative.ts(13,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'readonlyProp' from class 'B'.
tests/cases/compiler/abstractPropertyNegative.ts(13,7): error TS18052: Non-abstract class 'C' does not implement all abstract members of 'B'
tests/cases/compiler/abstractPropertyNegative.ts(15,5): error TS1253: Abstract properties can only appear within an abstract class.
tests/cases/compiler/abstractPropertyNegative.ts(16,37): error TS1005: '{' expected.
tests/cases/compiler/abstractPropertyNegative.ts(19,3): error TS2540: Cannot assign to 'ro' because it is a read-only property.
Expand All @@ -18,7 +15,7 @@ tests/cases/compiler/abstractPropertyNegative.ts(40,9): error TS2676: Accessors
tests/cases/compiler/abstractPropertyNegative.ts(41,18): error TS2676: Accessors must both be abstract or non-abstract.


==== tests/cases/compiler/abstractPropertyNegative.ts (15 errors) ====
==== tests/cases/compiler/abstractPropertyNegative.ts (12 errors) ====
interface A {
prop: string;
m(): string;
Expand All @@ -35,13 +32,11 @@ tests/cases/compiler/abstractPropertyNegative.ts(41,18): error TS2676: Accessors
}
class C extends B {
~
!!! error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'm' from class 'B'.
~
!!! error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'mismatch' from class 'B'.
~
!!! error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'prop' from class 'B'.
~
!!! error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'readonlyProp' from class 'B'.
!!! error TS18052: Non-abstract class 'C' does not implement all abstract members of 'B'
!!! related TS2515 tests/cases/compiler/abstractPropertyNegative.ts:6:14: Non-abstract class 'C' does not implement inherited abstract member 'prop' from class 'B'.
!!! related TS2515 tests/cases/compiler/abstractPropertyNegative.ts:8:18: Non-abstract class 'C' does not implement inherited abstract member 'readonlyProp' from class 'B'.
!!! related TS2515 tests/cases/compiler/abstractPropertyNegative.ts:9:14: Non-abstract class 'C' does not implement inherited abstract member 'm' from class 'B'.
!!! related TS2515 tests/cases/compiler/abstractPropertyNegative.ts:10:18: Non-abstract class 'C' does not implement inherited abstract member 'mismatch' from class 'B'.
readonly ro = "readonly please";
abstract notAllowed: string;
~~~~~~~~
Expand Down
15 changes: 9 additions & 6 deletions tests/baselines/reference/classAbstractDeclarations.d.errors.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(2,5): error TS1242: 'abstract' modifier can only appear on a class, method, or property declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(2,28): error TS1183: An implementation cannot be declared in ambient contexts.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(11,15): error TS2515: Non-abstract class 'CC' does not implement inherited abstract member 'foo' from class 'AA'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(13,15): error TS2515: Non-abstract class 'DD' does not implement inherited abstract member 'foo' from class 'BB'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(17,15): error TS2515: Non-abstract class 'FF' does not implement inherited abstract member 'foo' from class 'CC'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(11,15): error TS18052: Non-abstract class 'CC' does not implement all abstract members of 'AA'
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(13,15): error TS18052: Non-abstract class 'DD' does not implement all abstract members of 'BB'
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(17,15): error TS18052: Non-abstract class 'FF' does not implement all abstract members of 'CC'


==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts (5 errors) ====
Expand All @@ -22,17 +22,20 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst

declare class CC extends AA {}
~~
!!! error TS2515: Non-abstract class 'CC' does not implement inherited abstract member 'foo' from class 'AA'.
!!! error TS18052: Non-abstract class 'CC' does not implement all abstract members of 'AA'
!!! related TS2515 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts:6:14: Non-abstract class 'CC' does not implement inherited abstract member 'foo' from class 'AA'.

declare class DD extends BB {}
~~
!!! error TS2515: Non-abstract class 'DD' does not implement inherited abstract member 'foo' from class 'BB'.
!!! error TS18052: Non-abstract class 'DD' does not implement all abstract members of 'BB'
!!! related TS2515 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts:6:14: Non-abstract class 'DD' does not implement inherited abstract member 'foo' from class 'BB'.

declare abstract class EE extends BB {}

declare class FF extends CC {}
~~
!!! error TS2515: Non-abstract class 'FF' does not implement inherited abstract member 'foo' from class 'CC'.
!!! error TS18052: Non-abstract class 'FF' does not implement all abstract members of 'CC'
!!! related TS2515 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts:6:14: Non-abstract class 'FF' does not implement inherited abstract member 'foo' from class 'CC'.

declare abstract class GG extends CC {}

Expand Down
5 changes: 3 additions & 2 deletions tests/baselines/reference/classAbstractExtends.errors.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractExtends.ts(9,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'bar' from class 'B'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractExtends.ts(9,7): error TS18052: Non-abstract class 'C' does not implement all abstract members of 'B'


==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractExtends.ts (1 errors) ====
Expand All @@ -12,7 +12,8 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst

class C extends B { }
~
!!! error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'bar' from class 'B'.
!!! error TS18052: Non-abstract class 'C' does not implement all abstract members of 'B'
!!! related TS2515 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractExtends.ts:6:14: Non-abstract class 'C' does not implement inherited abstract member 'bar' from class 'B'.

abstract class D extends B {}

Expand Down
30 changes: 15 additions & 15 deletions tests/baselines/reference/classAbstractGeneric.errors.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts(10,7): error TS2515: Non-abstract class 'C<T>' does not implement inherited abstract member 'bar' from class 'A<T>'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts(10,7): error TS2515: Non-abstract class 'C<T>' does not implement inherited abstract member 'foo' from class 'A<T>'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts(12,7): error TS2515: Non-abstract class 'D' does not implement inherited abstract member 'bar' from class 'A<number>'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts(12,7): error TS2515: Non-abstract class 'D' does not implement inherited abstract member 'foo' from class 'A<number>'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts(14,7): error TS2515: Non-abstract class 'E<T>' does not implement inherited abstract member 'bar' from class 'A<T>'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts(18,7): error TS2515: Non-abstract class 'F<T>' does not implement inherited abstract member 'foo' from class 'A<T>'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts(10,7): error TS18052: Non-abstract class 'C<T>' does not implement all abstract members of 'A<T>'
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts(12,7): error TS18052: Non-abstract class 'D' does not implement all abstract members of 'A<number>'
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts(14,7): error TS18052: Non-abstract class 'E<T>' does not implement all abstract members of 'A<T>'
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts(18,7): error TS18052: Non-abstract class 'F<T>' does not implement all abstract members of 'A<T>'


==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts (6 errors) ====
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts (4 errors) ====
abstract class A<T> {
t: T;

Expand All @@ -18,25 +16,27 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst

class C<T> extends A<T> {} // error -- inherits abstract methods
~
!!! error TS2515: Non-abstract class 'C<T>' does not implement inherited abstract member 'bar' from class 'A<T>'.
~
!!! error TS2515: Non-abstract class 'C<T>' does not implement inherited abstract member 'foo' from class 'A<T>'.
!!! error TS18052: Non-abstract class 'C<T>' does not implement all abstract members of 'A<T>'
!!! related TS2515 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts:4:14: Non-abstract class 'C<T>' does not implement inherited abstract member 'foo' from class 'A<T>'.
!!! related TS2515 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts:5:14: Non-abstract class 'C<T>' does not implement inherited abstract member 'bar' from class 'A<T>'.

class D extends A<number> {} // error -- inherits abstract methods
~
!!! error TS2515: Non-abstract class 'D' does not implement inherited abstract member 'bar' from class 'A<number>'.
~
!!! error TS2515: Non-abstract class 'D' does not implement inherited abstract member 'foo' from class 'A<number>'.
!!! error TS18052: Non-abstract class 'D' does not implement all abstract members of 'A<number>'
!!! related TS2515 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts:4:14: Non-abstract class 'D' does not implement inherited abstract member 'foo' from class 'A<number>'.
!!! related TS2515 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts:5:14: Non-abstract class 'D' does not implement inherited abstract member 'bar' from class 'A<number>'.

class E<T> extends A<T> { // error -- doesn't implement bar
~
!!! error TS2515: Non-abstract class 'E<T>' does not implement inherited abstract member 'bar' from class 'A<T>'.
!!! error TS18052: Non-abstract class 'E<T>' does not implement all abstract members of 'A<T>'
!!! related TS2515 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts:5:14: Non-abstract class 'E<T>' does not implement inherited abstract member 'bar' from class 'A<T>'.
foo() { return this.t; }
}

class F<T> extends A<T> { // error -- doesn't implement foo
~
!!! error TS2515: Non-abstract class 'F<T>' does not implement inherited abstract member 'foo' from class 'A<T>'.
!!! error TS18052: Non-abstract class 'F<T>' does not implement all abstract members of 'A<T>'
!!! related TS2515 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractGeneric.ts:4:14: Non-abstract class 'F<T>' does not implement inherited abstract member 'foo' from class 'A<T>'.
bar(t : T) {}
}

Expand Down
15 changes: 9 additions & 6 deletions tests/baselines/reference/classAbstractInheritance.errors.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts(13,7): error TS2515: Non-abstract class 'CC' does not implement inherited abstract member 'foo' from class 'AA'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts(15,7): error TS2515: Non-abstract class 'DD' does not implement inherited abstract member 'foo' from class 'BB'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts(19,7): error TS2515: Non-abstract class 'FF' does not implement inherited abstract member 'foo' from class 'CC'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts(13,7): error TS18052: Non-abstract class 'CC' does not implement all abstract members of 'AA'
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts(15,7): error TS18052: Non-abstract class 'DD' does not implement all abstract members of 'BB'
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts(19,7): error TS18052: Non-abstract class 'FF' does not implement all abstract members of 'CC'


==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts (3 errors) ====
Expand All @@ -18,16 +18,19 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst

class CC extends AA {}
~~
!!! error TS2515: Non-abstract class 'CC' does not implement inherited abstract member 'foo' from class 'AA'.
!!! error TS18052: Non-abstract class 'CC' does not implement all abstract members of 'AA'
!!! related TS2515 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts:8:14: Non-abstract class 'CC' does not implement inherited abstract member 'foo' from class 'AA'.

class DD extends BB {}
~~
!!! error TS2515: Non-abstract class 'DD' does not implement inherited abstract member 'foo' from class 'BB'.
!!! error TS18052: Non-abstract class 'DD' does not implement all abstract members of 'BB'
!!! related TS2515 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts:8:14: Non-abstract class 'DD' does not implement inherited abstract member 'foo' from class 'BB'.

abstract class EE extends BB {}

class FF extends CC {}
~~
!!! error TS2515: Non-abstract class 'FF' does not implement inherited abstract member 'foo' from class 'CC'.
!!! error TS18052: Non-abstract class 'FF' does not implement all abstract members of 'CC'
!!! related TS2515 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts:8:14: Non-abstract class 'FF' does not implement inherited abstract member 'foo' from class 'CC'.

abstract class GG extends CC {}
Loading