diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart index 67407748cfee..15f8d7ec0104 100644 --- a/pkg/kernel/lib/class_hierarchy.dart +++ b/pkg/kernel/lib/class_hierarchy.dart @@ -417,18 +417,20 @@ class ClosedWorldClassHierarchy implements ClassHierarchy { _reportOverrides(info.declaredSetters, superSetters, callback, isSetter: true, onlyAbstract: true); } - // If a class declares an abstract method M whose - // implementation M' is inherited from the superclass, then the inherited - // method M' overrides the declared method M. - // This flies in the face of conventional override logic, but is necessary - // because an instance of the class will contain the method M' which can - // be invoked through the interface of M. - // Note that [_reportOverrides] does not report self-overrides, so in - // most cases these calls will just scan both lists and report nothing. - _reportOverrides(info.implementedGettersAndCalls, - info.declaredGettersAndCalls, callback); - _reportOverrides(info.implementedSetters, info.declaredSetters, callback, - isSetter: true); + if (!class_.isAbstract) { + // If a non-abstract class declares an abstract method M whose + // implementation M' is inherited from the superclass, then the inherited + // method M' overrides the declared method M. + // This flies in the face of conventional override logic, but is necessary + // because an instance of the class will contain the method M' which can + // be invoked through the interface of M. + // Note that [_reportOverrides] does not report self-overrides, so in + // most cases these calls will just scan both lists and report nothing. + _reportOverrides(info.implementedGettersAndCalls, + info.declaredGettersAndCalls, callback); + _reportOverrides(info.implementedSetters, info.declaredSetters, callback, + isSetter: true); + } } @override diff --git a/pkg/kernel/lib/src/incremental_class_hierarchy.dart b/pkg/kernel/lib/src/incremental_class_hierarchy.dart index dc202c7b7d83..b99956ee2a47 100644 --- a/pkg/kernel/lib/src/incremental_class_hierarchy.dart +++ b/pkg/kernel/lib/src/incremental_class_hierarchy.dart @@ -104,18 +104,20 @@ class IncrementalClassHierarchy implements ClassHierarchy { _reportOverrides(info.declaredSetters, superSetters, callback, isSetter: true, onlyAbstract: true); } - // If a class declares an abstract method M whose - // implementation M' is inherited from the superclass, then the inherited - // method M' overrides the declared method M. - // This flies in the face of conventional override logic, but is necessary - // because an instance of the class will contain the method M' which can - // be invoked through the interface of M. - // Note that [_reportOverrides] does not report self-overrides, so in - // most cases these calls will just scan both lists and report nothing. - _reportOverrides(info.implementedGettersAndCalls, - info.declaredGettersAndCalls, callback); - _reportOverrides(info.implementedSetters, info.declaredSetters, callback, - isSetter: true); + if (!node.isAbstract) { + // If a non-abstract class declares an abstract method M whose + // implementation M' is inherited from the superclass, then the inherited + // method M' overrides the declared method M. + // This flies in the face of conventional override logic, but is necessary + // because an instance of the class will contain the method M' which can + // be invoked through the interface of M. + // Note that [_reportOverrides] does not report self-overrides, so in + // most cases these calls will just scan both lists and report nothing. + _reportOverrides(info.implementedGettersAndCalls, + info.declaredGettersAndCalls, callback); + _reportOverrides(info.implementedSetters, info.declaredSetters, callback, + isSetter: true); + } } @override diff --git a/pkg/kernel/test/class_hierarchy_test.dart b/pkg/kernel/test/class_hierarchy_test.dart index f57cf02c3ccc..1039035a7a7a 100644 --- a/pkg/kernel/test/class_hierarchy_test.dart +++ b/pkg/kernel/test/class_hierarchy_test.dart @@ -304,6 +304,8 @@ class E = self::D with self::A implements self::B {} supertype: a.asThisSupertype, procedures: [newEmptyMethod('foo', isAbstract: true)], isAbstract: true)); + var d = addClass(new Class(name: 'D', supertype: b.asThisSupertype)); + var e = addClass(new Class(name: 'E', supertype: c.asThisSupertype)); _assertTestLibraryText(''' class A { @@ -315,16 +317,17 @@ class B extends self::A { abstract class C extends self::A { abstract method foo() → void; } +class D extends self::B {} +class E extends self::C {} '''); _assertOverridePairs(b, [ 'test::A::foo overrides test::B::foo', 'test::B::foo overrides test::A::foo' ]); - _assertOverridePairs(c, [ - 'test::A::foo overrides test::C::foo', - 'test::C::foo overrides test::A::foo' - ]); + _assertOverridePairs(c, ['test::C::foo overrides test::A::foo']); + _assertOverridePairs(d, ['test::A::foo overrides test::B::foo']); + _assertOverridePairs(e, ['test::A::foo overrides test::C::foo']); } /// 3. A non-abstract member is inherited from a superclass, and it overrides