diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5491daee439..4b2378ecba3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -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(); + + 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) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 0bedb964ffd..412718aa1de 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -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 diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts index 44c14f724c1..d22e9b08678 100644 --- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts +++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts @@ -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, diff --git a/tests/baselines/reference/abstractPropertyNegative.errors.txt b/tests/baselines/reference/abstractPropertyNegative.errors.txt index 62fea47881b..34f7fd8e453 100644 --- a/tests/baselines/reference/abstractPropertyNegative.errors.txt +++ b/tests/baselines/reference/abstractPropertyNegative.errors.txt @@ -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; ~~~~~~~~ diff --git a/tests/baselines/reference/classAbstractDeclarations.d.errors.txt b/tests/baselines/reference/classAbstractDeclarations.d.errors.txt index 50812079f59..581958eb02b 100644 --- a/tests/baselines/reference/classAbstractDeclarations.d.errors.txt +++ b/tests/baselines/reference/classAbstractDeclarations.d.errors.txt @@ -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 {} diff --git a/tests/baselines/reference/classAbstractExtends.errors.txt b/tests/baselines/reference/classAbstractExtends.errors.txt index 5cabffb18d2..c740843f17a 100644 --- a/tests/baselines/reference/classAbstractExtends.errors.txt +++ b/tests/baselines/reference/classAbstractExtends.errors.txt @@ -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 {} diff --git a/tests/baselines/reference/classAbstractGeneric.errors.txt b/tests/baselines/reference/classAbstractGeneric.errors.txt index c836577069c..0824c9d4c53 100644 --- a/tests/baselines/reference/classAbstractGeneric.errors.txt +++ b/tests/baselines/reference/classAbstractGeneric.errors.txt @@ -1,7 +1,7 @@ -classAbstractGeneric.ts(10,7): error TS18052: Non-abstract class 'C' does not implement all abstract members of 'A' -classAbstractGeneric.ts(12,7): error TS18052: Non-abstract class 'D' does not implement all abstract members of 'A' -classAbstractGeneric.ts(14,7): error TS18052: Non-abstract class 'E' does not implement all abstract members of 'A' -classAbstractGeneric.ts(18,7): error TS18052: Non-abstract class 'F' does not implement all abstract members of 'A' +classAbstractGeneric.ts(10,7): error TS2654: Non-abstract class 'C' is missing implementations for the following members of 'A': 'foo', 'bar'. +classAbstractGeneric.ts(12,7): error TS2654: Non-abstract class 'D' is missing implementations for the following members of 'A': 'foo', 'bar'. +classAbstractGeneric.ts(14,7): error TS2515: Non-abstract class 'E' does not implement inherited abstract member bar from class 'A'. +classAbstractGeneric.ts(18,7): error TS2515: Non-abstract class 'F' does not implement inherited abstract member foo from class 'A'. ==== classAbstractGeneric.ts (4 errors) ==== @@ -16,27 +16,21 @@ classAbstractGeneric.ts(18,7): error TS18052: Non-abstract class 'F' does not class C extends A {} // error -- inherits abstract methods ~ -!!! error TS18052: Non-abstract class 'C' does not implement all abstract members of 'A' -!!! related TS2515 classAbstractGeneric.ts:4:14: Non-abstract class 'C' does not implement inherited abstract member 'foo' from class 'A'. -!!! related TS2515 classAbstractGeneric.ts:5:14: Non-abstract class 'C' does not implement inherited abstract member 'bar' from class 'A'. +!!! error TS2654: Non-abstract class 'C' is missing implementations for the following members of 'A': 'foo', 'bar'. class D extends A {} // error -- inherits abstract methods ~ -!!! error TS18052: Non-abstract class 'D' does not implement all abstract members of 'A' -!!! related TS2515 classAbstractGeneric.ts:4:14: Non-abstract class 'D' does not implement inherited abstract member 'foo' from class 'A'. -!!! related TS2515 classAbstractGeneric.ts:5:14: Non-abstract class 'D' does not implement inherited abstract member 'bar' from class 'A'. +!!! error TS2654: Non-abstract class 'D' is missing implementations for the following members of 'A': 'foo', 'bar'. class E extends A { // error -- doesn't implement bar ~ -!!! error TS18052: Non-abstract class 'E' does not implement all abstract members of 'A' -!!! related TS2515 classAbstractGeneric.ts:5:14: Non-abstract class 'E' does not implement inherited abstract member 'bar' from class 'A'. +!!! error TS2515: Non-abstract class 'E' does not implement inherited abstract member bar from class 'A'. foo() { return this.t; } } class F extends A { // error -- doesn't implement foo ~ -!!! error TS18052: Non-abstract class 'F' does not implement all abstract members of 'A' -!!! related TS2515 classAbstractGeneric.ts:4:14: Non-abstract class 'F' does not implement inherited abstract member 'foo' from class 'A'. +!!! error TS2515: Non-abstract class 'F' does not implement inherited abstract member foo from class 'A'. bar(t : T) {} } diff --git a/tests/baselines/reference/classAbstractInheritance.errors.txt b/tests/baselines/reference/classAbstractInheritance.errors.txt deleted file mode 100644 index a1e3574f718..00000000000 --- a/tests/baselines/reference/classAbstractInheritance.errors.txt +++ /dev/null @@ -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 {} \ No newline at end of file diff --git a/tests/baselines/reference/classAbstractInheritance.symbols b/tests/baselines/reference/classAbstractInheritance.symbols deleted file mode 100644 index d597f1b6d9c..00000000000 --- a/tests/baselines/reference/classAbstractInheritance.symbols +++ /dev/null @@ -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)) - diff --git a/tests/baselines/reference/classAbstractInheritance1.errors.txt b/tests/baselines/reference/classAbstractInheritance1.errors.txt new file mode 100644 index 00000000000..14055613fec --- /dev/null +++ b/tests/baselines/reference/classAbstractInheritance1.errors.txt @@ -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 {} \ No newline at end of file diff --git a/tests/baselines/reference/classAbstractInheritance.js b/tests/baselines/reference/classAbstractInheritance1.js similarity index 93% rename from tests/baselines/reference/classAbstractInheritance.js rename to tests/baselines/reference/classAbstractInheritance1.js index a8e69c00314..7e7211374d6 100644 --- a/tests/baselines/reference/classAbstractInheritance.js +++ b/tests/baselines/reference/classAbstractInheritance1.js @@ -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 || diff --git a/tests/baselines/reference/classAbstractInheritance1.symbols b/tests/baselines/reference/classAbstractInheritance1.symbols new file mode 100644 index 00000000000..a0c4307888a --- /dev/null +++ b/tests/baselines/reference/classAbstractInheritance1.symbols @@ -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)) + diff --git a/tests/baselines/reference/classAbstractInheritance.types b/tests/baselines/reference/classAbstractInheritance1.types similarity index 80% rename from tests/baselines/reference/classAbstractInheritance.types rename to tests/baselines/reference/classAbstractInheritance1.types index 885d78f138e..ab062e32bcd 100644 --- a/tests/baselines/reference/classAbstractInheritance.types +++ b/tests/baselines/reference/classAbstractInheritance1.types @@ -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 diff --git a/tests/baselines/reference/classAbstractInheritance2.errors.txt b/tests/baselines/reference/classAbstractInheritance2.errors.txt new file mode 100644 index 00000000000..7725c00de66 --- /dev/null +++ b/tests/baselines/reference/classAbstractInheritance2.errors.txt @@ -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. + \ No newline at end of file diff --git a/tests/baselines/reference/classAbstractInheritance2.js b/tests/baselines/reference/classAbstractInheritance2.js new file mode 100644 index 00000000000..3beb03e2dac --- /dev/null +++ b/tests/baselines/reference/classAbstractInheritance2.js @@ -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)); diff --git a/tests/baselines/reference/classAbstractInheritance2.symbols b/tests/baselines/reference/classAbstractInheritance2.symbols new file mode 100644 index 00000000000..b547130fe06 --- /dev/null +++ b/tests/baselines/reference/classAbstractInheritance2.symbols @@ -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)) + diff --git a/tests/baselines/reference/classAbstractInheritance2.types b/tests/baselines/reference/classAbstractInheritance2.types new file mode 100644 index 00000000000..29e00fe37f3 --- /dev/null +++ b/tests/baselines/reference/classAbstractInheritance2.types @@ -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 + diff --git a/tests/baselines/reference/classAbstractInstantiations2.errors.txt b/tests/baselines/reference/classAbstractInstantiations2.errors.txt index 616a0d38f30..e07d75144f2 100644 --- a/tests/baselines/reference/classAbstractInstantiations2.errors.txt +++ b/tests/baselines/reference/classAbstractInstantiations2.errors.txt @@ -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 diff --git a/tests/baselines/reference/classAbstractOverrideWithAbstract.errors.txt b/tests/baselines/reference/classAbstractOverrideWithAbstract.errors.txt index 6884209666d..3293a5fbd1f 100644 --- a/tests/baselines/reference/classAbstractOverrideWithAbstract.errors.txt +++ b/tests/baselines/reference/classAbstractOverrideWithAbstract.errors.txt @@ -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() {} diff --git a/tests/baselines/reference/classAbstractUsingAbstractMethods2.errors.txt b/tests/baselines/reference/classAbstractUsingAbstractMethods2.errors.txt index ffe9be2ced9..34d37e13864 100644 --- a/tests/baselines/reference/classAbstractUsingAbstractMethods2.errors.txt +++ b/tests/baselines/reference/classAbstractUsingAbstractMethods2.errors.txt @@ -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 {} diff --git a/tests/baselines/reference/classExpressionExtendingAbstractClass.errors.txt b/tests/baselines/reference/classExpressionExtendingAbstractClass.errors.txt index da9f5191ddc..94e62b6f8ac 100644 --- a/tests/baselines/reference/classExpressionExtendingAbstractClass.errors.txt +++ b/tests/baselines/reference/classExpressionExtendingAbstractClass.errors.txt @@ -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'. }; \ No newline at end of file diff --git a/tests/baselines/reference/mixinAbstractClasses.2.errors.txt b/tests/baselines/reference/mixinAbstractClasses.2.errors.txt index 2be06ed0b5b..0d7b085edec 100644 --- a/tests/baselines/reference/mixinAbstractClasses.2.errors.txt +++ b/tests/baselines/reference/mixinAbstractClasses.2.errors.txt @@ -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. diff --git a/tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts b/tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance1.ts similarity index 100% rename from tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance.ts rename to tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance1.ts diff --git a/tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance2.ts b/tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance2.ts new file mode 100644 index 00000000000..4df474beb35 --- /dev/null +++ b/tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInheritance2.ts @@ -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 {}