@@ -29329,7 +29329,7 @@ namespace ts {
2932929329
2933029330 // NOTE: assignability is checked in checkClassDeclaration
2933129331 const baseProperties = getPropertiesOfType(baseType);
29332- for (const baseProperty of baseProperties) {
29332+ basePropertyCheck: for (const baseProperty of baseProperties) {
2933329333 const base = getTargetSymbol(baseProperty);
2933429334
2933529335 if (base.flags & SymbolFlags.Prototype) {
@@ -29341,60 +29341,70 @@ namespace ts {
2934129341
2934229342 Debug.assert(!!derived, "derived should point to something, even if it is the base class' declaration.");
2934329343
29344- if (derived) {
29345- // In order to resolve whether the inherited method was overridden in the base class or not,
29346- // we compare the Symbols obtained. Since getTargetSymbol returns the symbol on the *uninstantiated*
29347- // type declaration, derived and base resolve to the same symbol even in the case of generic classes.
29348- if (derived === base) {
29349- // derived class inherits base without override/redeclaration
29350-
29351- const derivedClassDecl = getClassLikeDeclarationOfSymbol(type.symbol)!;
29352-
29353- // It is an error to inherit an abstract member without implementing it or being declared abstract.
29354- // If there is no declaration for the derived class (as in the case of class expressions),
29355- // then the class cannot be declared abstract.
29356- if (baseDeclarationFlags & ModifierFlags.Abstract && (!derivedClassDecl || !hasModifier(derivedClassDecl, ModifierFlags.Abstract))) {
29357- if (derivedClassDecl.kind === SyntaxKind.ClassExpression) {
29358- error(derivedClassDecl, Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1,
29359- symbolToString(baseProperty), typeToString(baseType));
29360- }
29361- else {
29362- error(derivedClassDecl, Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2,
29363- typeToString(type), symbolToString(baseProperty), typeToString(baseType));
29344+ // In order to resolve whether the inherited method was overridden in the base class or not,
29345+ // we compare the Symbols obtained. Since getTargetSymbol returns the symbol on the *uninstantiated*
29346+ // type declaration, derived and base resolve to the same symbol even in the case of generic classes.
29347+ if (derived === base) {
29348+ // derived class inherits base without override/redeclaration
29349+
29350+ const derivedClassDecl = getClassLikeDeclarationOfSymbol(type.symbol)!;
29351+
29352+ // It is an error to inherit an abstract member without implementing it or being declared abstract.
29353+ // If there is no declaration for the derived class (as in the case of class expressions),
29354+ // then the class cannot be declared abstract.
29355+ if (baseDeclarationFlags & ModifierFlags.Abstract && (!derivedClassDecl || !hasModifier(derivedClassDecl, ModifierFlags.Abstract))) {
29356+ // Searches other base types for a declaration that would satisfy the inherited abstract member.
29357+ // (The class may have more than one base type via declaration merging with an interface with the
29358+ // same name.)
29359+ for (const otherBaseType of getBaseTypes(type)) {
29360+ if (otherBaseType === baseType) continue;
29361+ const baseSymbol = getPropertyOfObjectType(otherBaseType, base.escapedName);
29362+ const derivedElsewhere = baseSymbol && getTargetSymbol(baseSymbol);
29363+ if (derivedElsewhere && derivedElsewhere !== base) {
29364+ continue basePropertyCheck;
2936429365 }
2936529366 }
29366- }
29367- else {
29368- // derived overrides base.
29369- const derivedDeclarationFlags = getDeclarationModifierFlagsFromSymbol(derived);
29370- if (baseDeclarationFlags & ModifierFlags.Private || derivedDeclarationFlags & ModifierFlags.Private) {
29371- // either base or derived property is private - not override, skip it
29372- continue;
29373- }
2937429367
29375- if (isPrototypeProperty(base) || base.flags & SymbolFlags.PropertyOrAccessor && derived.flags & SymbolFlags.PropertyOrAccessor ) {
29376- // method is overridden with method or property/accessor is overridden with property/accessor - correct case
29377- continue ;
29368+ if (derivedClassDecl.kind === SyntaxKind.ClassExpression ) {
29369+ error(derivedClassDecl, Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1,
29370+ symbolToString(baseProperty), typeToString(baseType)) ;
2937829371 }
29379-
29380- let errorMessage: DiagnosticMessage;
29381- if (isPrototypeProperty(base)) {
29382- if (derived.flags & SymbolFlags.Accessor) {
29383- errorMessage = Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor;
29384- }
29385- else {
29386- errorMessage = Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property;
29387- }
29372+ else {
29373+ error(derivedClassDecl, Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2,
29374+ typeToString(type), symbolToString(baseProperty), typeToString(baseType));
2938829375 }
29389- else if (base.flags & SymbolFlags.Accessor) {
29390- errorMessage = Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function;
29376+ }
29377+ }
29378+ else {
29379+ // derived overrides base.
29380+ const derivedDeclarationFlags = getDeclarationModifierFlagsFromSymbol(derived);
29381+ if (baseDeclarationFlags & ModifierFlags.Private || derivedDeclarationFlags & ModifierFlags.Private) {
29382+ // either base or derived property is private - not override, skip it
29383+ continue;
29384+ }
29385+
29386+ if (isPrototypeProperty(base) || base.flags & SymbolFlags.PropertyOrAccessor && derived.flags & SymbolFlags.PropertyOrAccessor) {
29387+ // method is overridden with method or property/accessor is overridden with property/accessor - correct case
29388+ continue;
29389+ }
29390+
29391+ let errorMessage: DiagnosticMessage;
29392+ if (isPrototypeProperty(base)) {
29393+ if (derived.flags & SymbolFlags.Accessor) {
29394+ errorMessage = Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor;
2939129395 }
2939229396 else {
29393- errorMessage = Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function ;
29397+ errorMessage = Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property ;
2939429398 }
29395-
29396- error(getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type));
2939729399 }
29400+ else if (base.flags & SymbolFlags.Accessor) {
29401+ errorMessage = Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function;
29402+ }
29403+ else {
29404+ errorMessage = Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function;
29405+ }
29406+
29407+ error(getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type));
2939829408 }
2939929409 }
2940029410 }
0 commit comments