@@ -29329,7 +29329,7 @@ namespace ts {
29329
29329
29330
29330
// NOTE: assignability is checked in checkClassDeclaration
29331
29331
const baseProperties = getPropertiesOfType(baseType);
29332
- for (const baseProperty of baseProperties) {
29332
+ basePropertyCheck: for (const baseProperty of baseProperties) {
29333
29333
const base = getTargetSymbol(baseProperty);
29334
29334
29335
29335
if (base.flags & SymbolFlags.Prototype) {
@@ -29341,60 +29341,70 @@ namespace ts {
29341
29341
29342
29342
Debug.assert(!!derived, "derived should point to something, even if it is the base class' declaration.");
29343
29343
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;
29364
29365
}
29365
29366
}
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
- }
29374
29367
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)) ;
29378
29371
}
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));
29388
29375
}
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;
29391
29395
}
29392
29396
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 ;
29394
29398
}
29395
-
29396
- error(getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type));
29397
29399
}
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));
29398
29408
}
29399
29409
}
29400
29410
}
0 commit comments