mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-24 02:21:30 -05:00
feat(57240): Unimplemented abstract methods result in verbose, repetitive message (#57291)
This commit is contained in:
@@ -45069,9 +45069,15 @@ 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) {
|
||||
|
||||
interface MemberInfo {
|
||||
missedProperties: string[];
|
||||
baseTypeName: string;
|
||||
typeName: string;
|
||||
}
|
||||
const notImplementedInfo = new Map<ClassLikeDeclaration, MemberInfo>();
|
||||
|
||||
basePropertyCheck: for (const baseProperty of baseProperties) {
|
||||
const base = getTargetSymbol(baseProperty);
|
||||
|
||||
if (base.flags & SymbolFlags.Prototype) {
|
||||
@@ -45108,38 +45114,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
continue basePropertyCheck;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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 {
|
||||
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),
|
||||
),
|
||||
);
|
||||
}
|
||||
const baseTypeName = typeToString(baseType);
|
||||
const typeName = typeToString(type);
|
||||
const basePropertyName = symbolToString(baseProperty);
|
||||
const missedProperties = append(notImplementedInfo.get(derivedClassDecl)?.missedProperties, basePropertyName);
|
||||
notImplementedInfo.set(derivedClassDecl, { baseTypeName, typeName, missedProperties });
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -45223,6 +45202,36 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
error(getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type));
|
||||
}
|
||||
}
|
||||
|
||||
for (const [errorNode, memberInfo] of notImplementedInfo) {
|
||||
if (length(memberInfo.missedProperties) === 1) {
|
||||
if (isClassExpression(errorNode)) {
|
||||
error(errorNode, Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, first(memberInfo.missedProperties), memberInfo.baseTypeName);
|
||||
}
|
||||
else {
|
||||
error(errorNode, Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2, memberInfo.typeName, first(memberInfo.missedProperties), memberInfo.baseTypeName);
|
||||
}
|
||||
}
|
||||
else if (length(memberInfo.missedProperties) > 5) {
|
||||
const missedProperties = map(memberInfo.missedProperties.slice(0, 4), prop => `'${prop}'`).join(", ");
|
||||
const remainingMissedProperties = length(memberInfo.missedProperties) - 4;
|
||||
if (isClassExpression(errorNode)) {
|
||||
error(errorNode, Diagnostics.Non_abstract_class_expression_is_missing_implementations_for_the_following_members_of_0_Colon_1_and_2_more, memberInfo.baseTypeName, missedProperties, remainingMissedProperties);
|
||||
}
|
||||
else {
|
||||
error(errorNode, Diagnostics.Non_abstract_class_0_is_missing_implementations_for_the_following_members_of_1_Colon_2_and_3_more, memberInfo.typeName, memberInfo.baseTypeName, missedProperties, remainingMissedProperties);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const missedProperties = map(memberInfo.missedProperties, prop => `'${prop}'`).join(", ");
|
||||
if (isClassExpression(errorNode)) {
|
||||
error(errorNode, Diagnostics.Non_abstract_class_expression_is_missing_implementations_for_the_following_members_of_0_Colon_1, memberInfo.baseTypeName, missedProperties);
|
||||
}
|
||||
else {
|
||||
error(errorNode, Diagnostics.Non_abstract_class_0_is_missing_implementations_for_the_following_members_of_1_Colon_2, memberInfo.typeName, memberInfo.baseTypeName, missedProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isPropertyAbstractOrInterface(declaration: Declaration, baseDeclarationFlags: ModifierFlags) {
|
||||
|
||||
@@ -2484,7 +2484,7 @@
|
||||
"category": "Error",
|
||||
"code": 2514
|
||||
},
|
||||
"Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'.": {
|
||||
"Non-abstract class '{0}' does not implement inherited abstract member {1} from class '{2}'.": {
|
||||
"category": "Error",
|
||||
"code": 2515
|
||||
},
|
||||
@@ -2926,6 +2926,10 @@
|
||||
"category": "Error",
|
||||
"code": 2649
|
||||
},
|
||||
"Non-abstract class expression is missing implementations for the following members of '{0}': {1} and {2} more.": {
|
||||
"category": "Error",
|
||||
"code": 2650
|
||||
},
|
||||
"A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums.": {
|
||||
"category": "Error",
|
||||
"code": 2651
|
||||
@@ -2938,6 +2942,18 @@
|
||||
"category": "Error",
|
||||
"code": 2653
|
||||
},
|
||||
"Non-abstract class '{0}' is missing implementations for the following members of '{1}': {2}.": {
|
||||
"category": "Error",
|
||||
"code": 2654
|
||||
},
|
||||
"Non-abstract class '{0}' is missing implementations for the following members of '{1}': {2} and {3} more.": {
|
||||
"category": "Error",
|
||||
"code": 2655
|
||||
},
|
||||
"Non-abstract class expression is missing implementations for the following members of '{0}': {1}.": {
|
||||
"category": "Error",
|
||||
"code": 2656
|
||||
},
|
||||
"JSX expressions must have one parent element.": {
|
||||
"category": "Error",
|
||||
"code": 2657
|
||||
@@ -7937,10 +7953,6 @@
|
||||
"category": "Error",
|
||||
"code": 18051
|
||||
},
|
||||
"Non-abstract class '{0}' does not implement all abstract members of '{1}'": {
|
||||
"category": "Error",
|
||||
"code": 18052
|
||||
},
|
||||
"Its type '{0}' is not a valid JSX element type.": {
|
||||
"category": "Error",
|
||||
"code": 18053
|
||||
|
||||
@@ -26,8 +26,14 @@ import {
|
||||
} from "../_namespaces/ts.codefix";
|
||||
|
||||
const errorCodes = [
|
||||
Diagnostics.Non_abstract_class_0_does_not_implement_all_abstract_members_of_1.code,
|
||||
Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2.code,
|
||||
Diagnostics.Non_abstract_class_0_is_missing_implementations_for_the_following_members_of_1_Colon_2.code,
|
||||
Diagnostics.Non_abstract_class_0_is_missing_implementations_for_the_following_members_of_1_Colon_2_and_3_more.code,
|
||||
Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1.code,
|
||||
Diagnostics.Non_abstract_class_expression_is_missing_implementations_for_the_following_members_of_0_Colon_1.code,
|
||||
Diagnostics.Non_abstract_class_expression_is_missing_implementations_for_the_following_members_of_0_Colon_1_and_2_more.code,
|
||||
];
|
||||
|
||||
const fixId = "fixClassDoesntImplementInheritedAbstractMember";
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
abstractPropertyNegative.ts(13,7): error TS18052: Non-abstract class 'C' does not implement all abstract members of 'B'
|
||||
abstractPropertyNegative.ts(13,7): error TS2654: Non-abstract class 'C' is missing implementations for the following members of 'B': 'prop', 'readonlyProp', 'm', 'mismatch'.
|
||||
abstractPropertyNegative.ts(15,5): error TS1253: Abstract properties can only appear within an abstract class.
|
||||
abstractPropertyNegative.ts(16,37): error TS1005: '{' expected.
|
||||
abstractPropertyNegative.ts(19,3): error TS2540: Cannot assign to 'ro' because it is a read-only property.
|
||||
@@ -29,11 +29,7 @@ abstractPropertyNegative.ts(41,18): error TS2676: Accessors must both be abstrac
|
||||
}
|
||||
class C extends B {
|
||||
~
|
||||
!!! error TS18052: Non-abstract class 'C' does not implement all abstract members of 'B'
|
||||
!!! related TS2515 abstractPropertyNegative.ts:6:14: Non-abstract class 'C' does not implement inherited abstract member 'prop' from class 'B'.
|
||||
!!! related TS2515 abstractPropertyNegative.ts:8:18: Non-abstract class 'C' does not implement inherited abstract member 'readonlyProp' from class 'B'.
|
||||
!!! related TS2515 abstractPropertyNegative.ts:9:14: Non-abstract class 'C' does not implement inherited abstract member 'm' from class 'B'.
|
||||
!!! related TS2515 abstractPropertyNegative.ts:10:18: Non-abstract class 'C' does not implement inherited abstract member 'mismatch' from class 'B'.
|
||||
!!! error TS2654: Non-abstract class 'C' is missing implementations for the following members of 'B': 'prop', 'readonlyProp', 'm', 'mismatch'.
|
||||
readonly ro = "readonly please";
|
||||
abstract notAllowed: string;
|
||||
~~~~~~~~
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
classAbstractDeclarations.d.ts(2,5): error TS1242: 'abstract' modifier can only appear on a class, method, or property declaration.
|
||||
classAbstractDeclarations.d.ts(2,28): error TS1183: An implementation cannot be declared in ambient contexts.
|
||||
classAbstractDeclarations.d.ts(11,15): error TS18052: Non-abstract class 'CC' does not implement all abstract members of 'AA'
|
||||
classAbstractDeclarations.d.ts(13,15): error TS18052: Non-abstract class 'DD' does not implement all abstract members of 'BB'
|
||||
classAbstractDeclarations.d.ts(17,15): error TS18052: Non-abstract class 'FF' does not implement all abstract members of 'CC'
|
||||
classAbstractDeclarations.d.ts(11,15): error TS2515: Non-abstract class 'CC' does not implement inherited abstract member foo from class 'AA'.
|
||||
classAbstractDeclarations.d.ts(13,15): error TS2515: Non-abstract class 'DD' does not implement inherited abstract member foo from class 'BB'.
|
||||
classAbstractDeclarations.d.ts(17,15): error TS2515: Non-abstract class 'FF' does not implement inherited abstract member foo from class 'CC'.
|
||||
|
||||
|
||||
==== classAbstractDeclarations.d.ts (5 errors) ====
|
||||
@@ -22,20 +22,17 @@ classAbstractDeclarations.d.ts(17,15): error TS18052: Non-abstract class 'FF' do
|
||||
|
||||
declare class CC extends AA {}
|
||||
~~
|
||||
!!! error TS18052: Non-abstract class 'CC' does not implement all abstract members of 'AA'
|
||||
!!! related TS2515 classAbstractDeclarations.d.ts:6:14: Non-abstract class 'CC' does not implement inherited abstract member 'foo' from class 'AA'.
|
||||
!!! error TS2515: Non-abstract class 'CC' does not implement inherited abstract member foo from class 'AA'.
|
||||
|
||||
declare class DD extends BB {}
|
||||
~~
|
||||
!!! error TS18052: Non-abstract class 'DD' does not implement all abstract members of 'BB'
|
||||
!!! related TS2515 classAbstractDeclarations.d.ts:6:14: Non-abstract class 'DD' does not implement inherited abstract member 'foo' from class 'BB'.
|
||||
!!! error TS2515: 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 TS18052: Non-abstract class 'FF' does not implement all abstract members of 'CC'
|
||||
!!! related TS2515 classAbstractDeclarations.d.ts:6:14: Non-abstract class 'FF' does not implement inherited abstract member 'foo' from class 'CC'.
|
||||
!!! error TS2515: Non-abstract class 'FF' does not implement inherited abstract member foo from class 'CC'.
|
||||
|
||||
declare abstract class GG extends CC {}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
classAbstractExtends.ts(9,7): error TS18052: Non-abstract class 'C' does not implement all abstract members of 'B'
|
||||
classAbstractExtends.ts(9,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member bar from class 'B'.
|
||||
|
||||
|
||||
==== classAbstractExtends.ts (1 errors) ====
|
||||
@@ -12,8 +12,7 @@ classAbstractExtends.ts(9,7): error TS18052: Non-abstract class 'C' does not imp
|
||||
|
||||
class C extends B { }
|
||||
~
|
||||
!!! error TS18052: Non-abstract class 'C' does not implement all abstract members of 'B'
|
||||
!!! related TS2515 classAbstractExtends.ts:6:14: Non-abstract class 'C' does not implement inherited abstract member 'bar' from class 'B'.
|
||||
!!! error TS2515: Non-abstract class 'C' does not implement inherited abstract member bar from class 'B'.
|
||||
|
||||
abstract class D extends B {}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
classAbstractGeneric.ts(10,7): error TS18052: Non-abstract class 'C<T>' does not implement all abstract members of 'A<T>'
|
||||
classAbstractGeneric.ts(12,7): error TS18052: Non-abstract class 'D' does not implement all abstract members of 'A<number>'
|
||||
classAbstractGeneric.ts(14,7): error TS18052: Non-abstract class 'E<T>' does not implement all abstract members of 'A<T>'
|
||||
classAbstractGeneric.ts(18,7): error TS18052: Non-abstract class 'F<T>' does not implement all abstract members of 'A<T>'
|
||||
classAbstractGeneric.ts(10,7): error TS2654: Non-abstract class 'C<T>' is missing implementations for the following members of 'A<T>': 'foo', 'bar'.
|
||||
classAbstractGeneric.ts(12,7): error TS2654: Non-abstract class 'D' is missing implementations for the following members of 'A<number>': 'foo', 'bar'.
|
||||
classAbstractGeneric.ts(14,7): error TS2515: Non-abstract class 'E<T>' does not implement inherited abstract member bar from class 'A<T>'.
|
||||
classAbstractGeneric.ts(18,7): error TS2515: Non-abstract class 'F<T>' does not implement inherited abstract member foo from class 'A<T>'.
|
||||
|
||||
|
||||
==== classAbstractGeneric.ts (4 errors) ====
|
||||
@@ -16,27 +16,21 @@ classAbstractGeneric.ts(18,7): error TS18052: Non-abstract class 'F<T>' does not
|
||||
|
||||
class C<T> extends A<T> {} // error -- inherits abstract methods
|
||||
~
|
||||
!!! error TS18052: Non-abstract class 'C<T>' does not implement all abstract members of 'A<T>'
|
||||
!!! related TS2515 classAbstractGeneric.ts:4:14: Non-abstract class 'C<T>' does not implement inherited abstract member 'foo' from class 'A<T>'.
|
||||
!!! related TS2515 classAbstractGeneric.ts:5:14: Non-abstract class 'C<T>' does not implement inherited abstract member 'bar' from class 'A<T>'.
|
||||
!!! error TS2654: Non-abstract class 'C<T>' is missing implementations for the following members of 'A<T>': 'foo', 'bar'.
|
||||
|
||||
class D extends A<number> {} // error -- inherits abstract methods
|
||||
~
|
||||
!!! error TS18052: Non-abstract class 'D' does not implement all abstract members of 'A<number>'
|
||||
!!! related TS2515 classAbstractGeneric.ts:4:14: Non-abstract class 'D' does not implement inherited abstract member 'foo' from class 'A<number>'.
|
||||
!!! related TS2515 classAbstractGeneric.ts:5:14: Non-abstract class 'D' does not implement inherited abstract member 'bar' from class 'A<number>'.
|
||||
!!! error TS2654: Non-abstract class 'D' is missing implementations for the following members of 'A<number>': 'foo', 'bar'.
|
||||
|
||||
class E<T> extends A<T> { // error -- doesn't implement bar
|
||||
~
|
||||
!!! error TS18052: Non-abstract class 'E<T>' does not implement all abstract members of 'A<T>'
|
||||
!!! related TS2515 classAbstractGeneric.ts:5:14: Non-abstract class 'E<T>' does not implement inherited abstract member 'bar' from class 'A<T>'.
|
||||
!!! error TS2515: 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 TS18052: Non-abstract class 'F<T>' does not implement all abstract members of 'A<T>'
|
||||
!!! related TS2515 classAbstractGeneric.ts:4:14: Non-abstract class 'F<T>' does not implement inherited abstract member 'foo' from class 'A<T>'.
|
||||
!!! error TS2515: Non-abstract class 'F<T>' does not implement inherited abstract member foo from class 'A<T>'.
|
||||
bar(t : T) {}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
classAbstractInheritance.ts(13,7): error TS18052: Non-abstract class 'CC' does not implement all abstract members of 'AA'
|
||||
classAbstractInheritance.ts(15,7): error TS18052: Non-abstract class 'DD' does not implement all abstract members of 'BB'
|
||||
classAbstractInheritance.ts(19,7): error TS18052: Non-abstract class 'FF' does not implement all abstract members of 'CC'
|
||||
|
||||
|
||||
==== classAbstractInheritance.ts (3 errors) ====
|
||||
abstract class A {}
|
||||
|
||||
abstract class B extends A {}
|
||||
|
||||
class C extends A {}
|
||||
|
||||
abstract class AA {
|
||||
abstract foo();
|
||||
}
|
||||
|
||||
abstract class BB extends AA {}
|
||||
|
||||
class CC extends AA {}
|
||||
~~
|
||||
!!! error TS18052: Non-abstract class 'CC' does not implement all abstract members of 'AA'
|
||||
!!! related TS2515 classAbstractInheritance.ts:8:14: Non-abstract class 'CC' does not implement inherited abstract member 'foo' from class 'AA'.
|
||||
|
||||
class DD extends BB {}
|
||||
~~
|
||||
!!! error TS18052: Non-abstract class 'DD' does not implement all abstract members of 'BB'
|
||||
!!! related TS2515 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 TS18052: Non-abstract class 'FF' does not implement all abstract members of 'CC'
|
||||
!!! related TS2515 classAbstractInheritance.ts:8:14: Non-abstract class 'FF' does not implement inherited abstract member 'foo' from class 'CC'.
|
||||
|
||||
abstract class GG extends CC {}
|
||||
@@ -1,45 +0,0 @@
|
||||
//// [tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts] ////
|
||||
|
||||
=== classAbstractInheritance.ts ===
|
||||
abstract class A {}
|
||||
>A : Symbol(A, Decl(classAbstractInheritance.ts, 0, 0))
|
||||
|
||||
abstract class B extends A {}
|
||||
>B : Symbol(B, Decl(classAbstractInheritance.ts, 0, 19))
|
||||
>A : Symbol(A, Decl(classAbstractInheritance.ts, 0, 0))
|
||||
|
||||
class C extends A {}
|
||||
>C : Symbol(C, Decl(classAbstractInheritance.ts, 2, 29))
|
||||
>A : Symbol(A, Decl(classAbstractInheritance.ts, 0, 0))
|
||||
|
||||
abstract class AA {
|
||||
>AA : Symbol(AA, Decl(classAbstractInheritance.ts, 4, 20))
|
||||
|
||||
abstract foo();
|
||||
>foo : Symbol(AA.foo, Decl(classAbstractInheritance.ts, 6, 19))
|
||||
}
|
||||
|
||||
abstract class BB extends AA {}
|
||||
>BB : Symbol(BB, Decl(classAbstractInheritance.ts, 8, 1))
|
||||
>AA : Symbol(AA, Decl(classAbstractInheritance.ts, 4, 20))
|
||||
|
||||
class CC extends AA {}
|
||||
>CC : Symbol(CC, Decl(classAbstractInheritance.ts, 10, 31))
|
||||
>AA : Symbol(AA, Decl(classAbstractInheritance.ts, 4, 20))
|
||||
|
||||
class DD extends BB {}
|
||||
>DD : Symbol(DD, Decl(classAbstractInheritance.ts, 12, 22))
|
||||
>BB : Symbol(BB, Decl(classAbstractInheritance.ts, 8, 1))
|
||||
|
||||
abstract class EE extends BB {}
|
||||
>EE : Symbol(EE, Decl(classAbstractInheritance.ts, 14, 22))
|
||||
>BB : Symbol(BB, Decl(classAbstractInheritance.ts, 8, 1))
|
||||
|
||||
class FF extends CC {}
|
||||
>FF : Symbol(FF, Decl(classAbstractInheritance.ts, 16, 31))
|
||||
>CC : Symbol(CC, Decl(classAbstractInheritance.ts, 10, 31))
|
||||
|
||||
abstract class GG extends CC {}
|
||||
>GG : Symbol(GG, Decl(classAbstractInheritance.ts, 18, 22))
|
||||
>CC : Symbol(CC, Decl(classAbstractInheritance.ts, 10, 31))
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
classAbstractInheritance1.ts(13,7): error TS2515: Non-abstract class 'CC' does not implement inherited abstract member foo from class 'AA'.
|
||||
classAbstractInheritance1.ts(15,7): error TS2515: Non-abstract class 'DD' does not implement inherited abstract member foo from class 'BB'.
|
||||
classAbstractInheritance1.ts(19,7): error TS2515: Non-abstract class 'FF' does not implement inherited abstract member foo from class 'CC'.
|
||||
|
||||
|
||||
==== classAbstractInheritance1.ts (3 errors) ====
|
||||
abstract class A {}
|
||||
|
||||
abstract class B extends A {}
|
||||
|
||||
class C extends A {}
|
||||
|
||||
abstract class AA {
|
||||
abstract foo();
|
||||
}
|
||||
|
||||
abstract class BB extends AA {}
|
||||
|
||||
class CC extends AA {}
|
||||
~~
|
||||
!!! error TS2515: 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'.
|
||||
|
||||
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'.
|
||||
|
||||
abstract class GG extends CC {}
|
||||
@@ -1,6 +1,6 @@
|
||||
//// [tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts] ////
|
||||
//// [tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance1.ts] ////
|
||||
|
||||
//// [classAbstractInheritance.ts]
|
||||
//// [classAbstractInheritance1.ts]
|
||||
abstract class A {}
|
||||
|
||||
abstract class B extends A {}
|
||||
@@ -23,7 +23,7 @@ class FF extends CC {}
|
||||
|
||||
abstract class GG extends CC {}
|
||||
|
||||
//// [classAbstractInheritance.js]
|
||||
//// [classAbstractInheritance1.js]
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
45
tests/baselines/reference/classAbstractInheritance1.symbols
Normal file
45
tests/baselines/reference/classAbstractInheritance1.symbols
Normal file
@@ -0,0 +1,45 @@
|
||||
//// [tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance1.ts] ////
|
||||
|
||||
=== classAbstractInheritance1.ts ===
|
||||
abstract class A {}
|
||||
>A : Symbol(A, Decl(classAbstractInheritance1.ts, 0, 0))
|
||||
|
||||
abstract class B extends A {}
|
||||
>B : Symbol(B, Decl(classAbstractInheritance1.ts, 0, 19))
|
||||
>A : Symbol(A, Decl(classAbstractInheritance1.ts, 0, 0))
|
||||
|
||||
class C extends A {}
|
||||
>C : Symbol(C, Decl(classAbstractInheritance1.ts, 2, 29))
|
||||
>A : Symbol(A, Decl(classAbstractInheritance1.ts, 0, 0))
|
||||
|
||||
abstract class AA {
|
||||
>AA : Symbol(AA, Decl(classAbstractInheritance1.ts, 4, 20))
|
||||
|
||||
abstract foo();
|
||||
>foo : Symbol(AA.foo, Decl(classAbstractInheritance1.ts, 6, 19))
|
||||
}
|
||||
|
||||
abstract class BB extends AA {}
|
||||
>BB : Symbol(BB, Decl(classAbstractInheritance1.ts, 8, 1))
|
||||
>AA : Symbol(AA, Decl(classAbstractInheritance1.ts, 4, 20))
|
||||
|
||||
class CC extends AA {}
|
||||
>CC : Symbol(CC, Decl(classAbstractInheritance1.ts, 10, 31))
|
||||
>AA : Symbol(AA, Decl(classAbstractInheritance1.ts, 4, 20))
|
||||
|
||||
class DD extends BB {}
|
||||
>DD : Symbol(DD, Decl(classAbstractInheritance1.ts, 12, 22))
|
||||
>BB : Symbol(BB, Decl(classAbstractInheritance1.ts, 8, 1))
|
||||
|
||||
abstract class EE extends BB {}
|
||||
>EE : Symbol(EE, Decl(classAbstractInheritance1.ts, 14, 22))
|
||||
>BB : Symbol(BB, Decl(classAbstractInheritance1.ts, 8, 1))
|
||||
|
||||
class FF extends CC {}
|
||||
>FF : Symbol(FF, Decl(classAbstractInheritance1.ts, 16, 31))
|
||||
>CC : Symbol(CC, Decl(classAbstractInheritance1.ts, 10, 31))
|
||||
|
||||
abstract class GG extends CC {}
|
||||
>GG : Symbol(GG, Decl(classAbstractInheritance1.ts, 18, 22))
|
||||
>CC : Symbol(CC, Decl(classAbstractInheritance1.ts, 10, 31))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//// [tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts] ////
|
||||
//// [tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance1.ts] ////
|
||||
|
||||
=== classAbstractInheritance.ts ===
|
||||
=== classAbstractInheritance1.ts ===
|
||||
abstract class A {}
|
||||
>A : A
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
classAbstractInheritance2.ts(10,7): error TS2655: Non-abstract class 'B' is missing implementations for the following members of 'A': 'm1', 'm2', 'm3', 'm4' and 2 more.
|
||||
classAbstractInheritance2.ts(11,11): error TS2650: Non-abstract class expression is missing implementations for the following members of 'A': 'm1', 'm2', 'm3', 'm4' and 2 more.
|
||||
|
||||
|
||||
==== classAbstractInheritance2.ts (2 errors) ====
|
||||
abstract class A {
|
||||
abstract m1(): number;
|
||||
abstract m2(): number;
|
||||
abstract m3(): number;
|
||||
abstract m4(): number;
|
||||
abstract m5(): number;
|
||||
abstract m6(): number;
|
||||
}
|
||||
|
||||
class B extends A { }
|
||||
~
|
||||
!!! error TS2655: Non-abstract class 'B' is missing implementations for the following members of 'A': 'm1', 'm2', 'm3', 'm4' and 2 more.
|
||||
const C = class extends A {}
|
||||
~~~~~
|
||||
!!! error TS2650: Non-abstract class expression is missing implementations for the following members of 'A': 'm1', 'm2', 'm3', 'm4' and 2 more.
|
||||
|
||||
51
tests/baselines/reference/classAbstractInheritance2.js
Normal file
51
tests/baselines/reference/classAbstractInheritance2.js
Normal file
@@ -0,0 +1,51 @@
|
||||
//// [tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance2.ts] ////
|
||||
|
||||
//// [classAbstractInheritance2.ts]
|
||||
abstract class A {
|
||||
abstract m1(): number;
|
||||
abstract m2(): number;
|
||||
abstract m3(): number;
|
||||
abstract m4(): number;
|
||||
abstract m5(): number;
|
||||
abstract m6(): number;
|
||||
}
|
||||
|
||||
class B extends A { }
|
||||
const C = class extends A {}
|
||||
|
||||
|
||||
//// [classAbstractInheritance2.js]
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var A = /** @class */ (function () {
|
||||
function A() {
|
||||
}
|
||||
return A;
|
||||
}());
|
||||
var B = /** @class */ (function (_super) {
|
||||
__extends(B, _super);
|
||||
function B() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return B;
|
||||
}(A));
|
||||
var C = /** @class */ (function (_super) {
|
||||
__extends(C, _super);
|
||||
function C() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return C;
|
||||
}(A));
|
||||
33
tests/baselines/reference/classAbstractInheritance2.symbols
Normal file
33
tests/baselines/reference/classAbstractInheritance2.symbols
Normal file
@@ -0,0 +1,33 @@
|
||||
//// [tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance2.ts] ////
|
||||
|
||||
=== classAbstractInheritance2.ts ===
|
||||
abstract class A {
|
||||
>A : Symbol(A, Decl(classAbstractInheritance2.ts, 0, 0))
|
||||
|
||||
abstract m1(): number;
|
||||
>m1 : Symbol(A.m1, Decl(classAbstractInheritance2.ts, 0, 18))
|
||||
|
||||
abstract m2(): number;
|
||||
>m2 : Symbol(A.m2, Decl(classAbstractInheritance2.ts, 1, 26))
|
||||
|
||||
abstract m3(): number;
|
||||
>m3 : Symbol(A.m3, Decl(classAbstractInheritance2.ts, 2, 26))
|
||||
|
||||
abstract m4(): number;
|
||||
>m4 : Symbol(A.m4, Decl(classAbstractInheritance2.ts, 3, 26))
|
||||
|
||||
abstract m5(): number;
|
||||
>m5 : Symbol(A.m5, Decl(classAbstractInheritance2.ts, 4, 26))
|
||||
|
||||
abstract m6(): number;
|
||||
>m6 : Symbol(A.m6, Decl(classAbstractInheritance2.ts, 5, 26))
|
||||
}
|
||||
|
||||
class B extends A { }
|
||||
>B : Symbol(B, Decl(classAbstractInheritance2.ts, 7, 1))
|
||||
>A : Symbol(A, Decl(classAbstractInheritance2.ts, 0, 0))
|
||||
|
||||
const C = class extends A {}
|
||||
>C : Symbol(C, Decl(classAbstractInheritance2.ts, 10, 5))
|
||||
>A : Symbol(A, Decl(classAbstractInheritance2.ts, 0, 0))
|
||||
|
||||
34
tests/baselines/reference/classAbstractInheritance2.types
Normal file
34
tests/baselines/reference/classAbstractInheritance2.types
Normal file
@@ -0,0 +1,34 @@
|
||||
//// [tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance2.ts] ////
|
||||
|
||||
=== classAbstractInheritance2.ts ===
|
||||
abstract class A {
|
||||
>A : A
|
||||
|
||||
abstract m1(): number;
|
||||
>m1 : () => number
|
||||
|
||||
abstract m2(): number;
|
||||
>m2 : () => number
|
||||
|
||||
abstract m3(): number;
|
||||
>m3 : () => number
|
||||
|
||||
abstract m4(): number;
|
||||
>m4 : () => number
|
||||
|
||||
abstract m5(): number;
|
||||
>m5 : () => number
|
||||
|
||||
abstract m6(): number;
|
||||
>m6 : () => number
|
||||
}
|
||||
|
||||
class B extends A { }
|
||||
>B : B
|
||||
>A : A
|
||||
|
||||
const C = class extends A {}
|
||||
>C : typeof C
|
||||
>class extends A {} : typeof C
|
||||
>A : A
|
||||
|
||||
@@ -4,7 +4,7 @@ classAbstractInstantiations2.ts(13,5): error TS2322: Type 'typeof B' is not assi
|
||||
classAbstractInstantiations2.ts(17,5): error TS2511: Cannot create an instance of an abstract class.
|
||||
classAbstractInstantiations2.ts(21,1): error TS2511: Cannot create an instance of an abstract class.
|
||||
classAbstractInstantiations2.ts(23,15): error TS2449: Class 'C' used before its declaration.
|
||||
classAbstractInstantiations2.ts(26,7): error TS18052: Non-abstract class 'C' does not implement all abstract members of 'B'
|
||||
classAbstractInstantiations2.ts(26,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member bar from class 'B'.
|
||||
classAbstractInstantiations2.ts(46,5): error TS2391: Function implementation is missing or not immediately following the declaration.
|
||||
classAbstractInstantiations2.ts(46,5): error TS2512: Overload signatures must all be abstract or non-abstract.
|
||||
classAbstractInstantiations2.ts(50,5): error TS1244: Abstract methods can only appear within an abstract class.
|
||||
@@ -50,8 +50,7 @@ classAbstractInstantiations2.ts(50,5): error TS1244: Abstract methods can only a
|
||||
|
||||
class C extends B { } // error -- not declared abstract
|
||||
~
|
||||
!!! error TS18052: Non-abstract class 'C' does not implement all abstract members of 'B'
|
||||
!!! related TS2515 classAbstractInstantiations2.ts:7:14: Non-abstract class 'C' does not implement inherited abstract member 'bar' from class 'B'.
|
||||
!!! error TS2515: Non-abstract class 'C' does not implement inherited abstract member bar from class 'B'.
|
||||
|
||||
abstract class D extends B { } // okay
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
classAbstractOverrideWithAbstract.ts(19,7): error TS18052: Non-abstract class 'CC' does not implement all abstract members of 'BB'
|
||||
classAbstractOverrideWithAbstract.ts(19,7): error TS2515: Non-abstract class 'CC' does not implement inherited abstract member foo from class 'BB'.
|
||||
|
||||
|
||||
==== classAbstractOverrideWithAbstract.ts (1 errors) ====
|
||||
@@ -22,8 +22,7 @@ classAbstractOverrideWithAbstract.ts(19,7): error TS18052: Non-abstract class 'C
|
||||
|
||||
class CC extends BB {} // error
|
||||
~~
|
||||
!!! error TS18052: Non-abstract class 'CC' does not implement all abstract members of 'BB'
|
||||
!!! related TS2515 classAbstractOverrideWithAbstract.ts:15:14: Non-abstract class 'CC' does not implement inherited abstract member 'foo' from class 'BB'.
|
||||
!!! error TS2515: Non-abstract class 'CC' does not implement inherited abstract member foo from class 'BB'.
|
||||
|
||||
class DD extends BB {
|
||||
foo() {}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
classAbstractUsingAbstractMethods2.ts(2,5): error TS1244: Abstract methods can only appear within an abstract class.
|
||||
classAbstractUsingAbstractMethods2.ts(5,7): error TS18052: Non-abstract class 'B' does not implement all abstract members of 'A'
|
||||
classAbstractUsingAbstractMethods2.ts(21,7): error TS18052: Non-abstract class 'BB' does not implement all abstract members of 'AA'
|
||||
classAbstractUsingAbstractMethods2.ts(5,7): error TS2515: Non-abstract class 'B' does not implement inherited abstract member foo from class 'A'.
|
||||
classAbstractUsingAbstractMethods2.ts(21,7): error TS2515: Non-abstract class 'BB' does not implement inherited abstract member foo from class 'AA'.
|
||||
|
||||
|
||||
==== classAbstractUsingAbstractMethods2.ts (3 errors) ====
|
||||
@@ -12,8 +12,7 @@ classAbstractUsingAbstractMethods2.ts(21,7): error TS18052: Non-abstract class '
|
||||
|
||||
class B extends A {}
|
||||
~
|
||||
!!! error TS18052: Non-abstract class 'B' does not implement all abstract members of 'A'
|
||||
!!! related TS2515 classAbstractUsingAbstractMethods2.ts:2:14: Non-abstract class 'B' does not implement inherited abstract member 'foo' from class 'A'.
|
||||
!!! error TS2515: Non-abstract class 'B' does not implement inherited abstract member foo from class 'A'.
|
||||
|
||||
abstract class C extends A {}
|
||||
|
||||
@@ -31,8 +30,7 @@ classAbstractUsingAbstractMethods2.ts(21,7): error TS18052: Non-abstract class '
|
||||
|
||||
class BB extends AA {}
|
||||
~~
|
||||
!!! error TS18052: Non-abstract class 'BB' does not implement all abstract members of 'AA'
|
||||
!!! related TS2515 classAbstractUsingAbstractMethods2.ts:18:14: Non-abstract class 'BB' does not implement inherited abstract member 'foo' from class 'AA'.
|
||||
!!! error TS2515: Non-abstract class 'BB' does not implement inherited abstract member foo from class 'AA'.
|
||||
|
||||
abstract class CC extends AA {}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
classExpressionExtendingAbstractClass.ts(5,9): error TS18052: Non-abstract class 'C' does not implement all abstract members of 'A'
|
||||
classExpressionExtendingAbstractClass.ts(5,9): error TS2653: Non-abstract class expression does not implement inherited abstract member 'foo' from class 'A'.
|
||||
|
||||
|
||||
==== classExpressionExtendingAbstractClass.ts (1 errors) ====
|
||||
@@ -8,8 +8,7 @@ classExpressionExtendingAbstractClass.ts(5,9): error TS18052: Non-abstract class
|
||||
|
||||
var C = class extends A { // no error reported!
|
||||
~~~~~
|
||||
!!! error TS18052: Non-abstract class 'C' does not implement all abstract members of 'A'
|
||||
!!! related TS2653 classExpressionExtendingAbstractClass.ts:2:14: Non-abstract class expression does not implement inherited abstract member 'foo' from class 'A'.
|
||||
!!! error TS2653: Non-abstract class expression does not implement inherited abstract member 'foo' from class 'A'.
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
mixinAbstractClasses.2.ts(7,11): error TS2797: A mixin class that extends from a type variable containing an abstract construct signature must also be declared 'abstract'.
|
||||
mixinAbstractClasses.2.ts(21,7): error TS18052: Non-abstract class 'DerivedFromAbstract' does not implement all abstract members of 'AbstractBase & Mixin'
|
||||
mixinAbstractClasses.2.ts(21,7): error TS2515: Non-abstract class 'DerivedFromAbstract' does not implement inherited abstract member abstractBaseMethod from class 'AbstractBase & Mixin'.
|
||||
mixinAbstractClasses.2.ts(25,1): error TS2511: Cannot create an instance of an abstract class.
|
||||
|
||||
|
||||
@@ -28,8 +28,7 @@ mixinAbstractClasses.2.ts(25,1): error TS2511: Cannot create an instance of an a
|
||||
// error expected: Non-abstract class 'DerivedFromAbstract' does not implement inherited abstract member 'abstractBaseMethod' from class 'AbstractBase & Mixin'.
|
||||
class DerivedFromAbstract extends MixedBase {
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS18052: Non-abstract class 'DerivedFromAbstract' does not implement all abstract members of 'AbstractBase & Mixin'
|
||||
!!! related TS2515 mixinAbstractClasses.2.ts:15:14: Non-abstract class 'DerivedFromAbstract' does not implement inherited abstract member 'abstractBaseMethod' from class 'AbstractBase & Mixin'.
|
||||
!!! error TS2515: Non-abstract class 'DerivedFromAbstract' does not implement inherited abstract member abstractBaseMethod from class 'AbstractBase & Mixin'.
|
||||
}
|
||||
|
||||
// error expected: Cannot create an instance of an abstract class.
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
abstract class A {
|
||||
abstract m1(): number;
|
||||
abstract m2(): number;
|
||||
abstract m3(): number;
|
||||
abstract m4(): number;
|
||||
abstract m5(): number;
|
||||
abstract m6(): number;
|
||||
}
|
||||
|
||||
class B extends A { }
|
||||
const C = class extends A {}
|
||||
Reference in New Issue
Block a user