| Index: pkg/kernel/lib/src/incremental_class_hierarchy.dart
|
| diff --git a/pkg/kernel/lib/src/incremental_class_hierarchy.dart b/pkg/kernel/lib/src/incremental_class_hierarchy.dart
|
| index 54a5d0cbb4f55ccbc6d3646484b3adbeb532cc2a..af79293b68243ec755b4202a8e661058ace27f8b 100644
|
| --- a/pkg/kernel/lib/src/incremental_class_hierarchy.dart
|
| +++ b/pkg/kernel/lib/src/incremental_class_hierarchy.dart
|
| @@ -84,10 +84,38 @@ class IncrementalClassHierarchy implements ClassHierarchy {
|
| }
|
|
|
| @override
|
| - void forEachOverridePair(Class class_,
|
| + void forEachOverridePair(Class node,
|
| callback(Member declaredMember, Member interfaceMember, bool isSetter)) {
|
| - // TODO(scheglov): implement forEachOverridePair
|
| - throw new UnimplementedError();
|
| + _ClassInfo info = _getInfo(node);
|
| + for (var supertype in node.supers) {
|
| + var superNode = supertype.classNode;
|
| + var superInfo = _getInfo(superNode);
|
| +
|
| + var superGetters = superInfo.interfaceGettersAndCalls;
|
| + _reportOverrides(info.implementedGettersAndCalls, superGetters, callback);
|
| + _reportOverrides(info.declaredGettersAndCalls, superGetters, callback,
|
| + onlyAbstract: true);
|
| +
|
| + var superSetters = superInfo.interfaceSetters;
|
| + _reportOverrides(info.implementedSetters, superSetters, callback,
|
| + isSetter: true);
|
| + _reportOverrides(info.declaredSetters, superSetters, callback,
|
| + isSetter: true, onlyAbstract: 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
|
| @@ -555,6 +583,36 @@ class IncrementalClassHierarchy implements ClassHierarchy {
|
| result.length = storeIndex;
|
| return result;
|
| }
|
| +
|
| + static void _reportOverrides(
|
| + List<Member> declaredList,
|
| + List<Member> inheritedList,
|
| + callback(Member declaredMember, Member interfaceMember, bool isSetter),
|
| + {bool isSetter: false,
|
| + bool onlyAbstract: false}) {
|
| + int i = 0, j = 0;
|
| + while (i < declaredList.length && j < inheritedList.length) {
|
| + Member declared = declaredList[i];
|
| + if (onlyAbstract && !declared.isAbstract) {
|
| + ++i;
|
| + continue;
|
| + }
|
| + Member inherited = inheritedList[j];
|
| + int comparison = _compareMembers(declared, inherited);
|
| + if (comparison < 0) {
|
| + ++i;
|
| + } else if (comparison > 0) {
|
| + ++j;
|
| + } else {
|
| + if (!identical(declared, inherited)) {
|
| + callback(declared, inherited, isSetter);
|
| + }
|
| + // A given declared member may override multiple interface members,
|
| + // so only move past the interface member.
|
| + ++j;
|
| + }
|
| + }
|
| + }
|
| }
|
|
|
| /// Information about a [Class].
|
|
|