OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 library kernel.class_hierarchy; | 4 library kernel.class_hierarchy; |
5 | 5 |
6 import 'ast.dart'; | 6 import 'ast.dart'; |
7 import 'dart:math'; | 7 import 'dart:math'; |
8 import 'dart:typed_data'; | 8 import 'dart:typed_data'; |
9 import 'src/heap.dart'; | 9 import 'src/heap.dart'; |
10 import 'type_algebra.dart'; | 10 import 'type_algebra.dart'; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 /// | 106 /// |
107 /// 3. A non-abstract member is inherited from a superclass, and it overrides | 107 /// 3. A non-abstract member is inherited from a superclass, and it overrides |
108 /// an abstract member declared in this class. | 108 /// an abstract member declared in this class. |
109 /// | 109 /// |
110 /// This method will not report that a member overrides itself. A given pair | 110 /// This method will not report that a member overrides itself. A given pair |
111 /// may be reported multiple times when there are multiple inheritance paths | 111 /// may be reported multiple times when there are multiple inheritance paths |
112 /// to the overridden member. | 112 /// to the overridden member. |
113 /// | 113 /// |
114 /// It is possible for two methods to override one another in both directions. | 114 /// It is possible for two methods to override one another in both directions. |
115 /// | 115 /// |
116 /// Getters and setters are overridden separately. The [isSetter] callback | 116 /// By default getters and setters are overridden separately. The [isSetter] |
117 /// parameter determines which type of access is being overridden. | 117 /// callback parameter determines which type of access is being overridden. |
| 118 /// |
| 119 /// However if [crossGettersSetters] is set to `true`, getters might be |
| 120 /// reported as overriding setters, and vice versa - setter overriding |
| 121 /// getters. The callback should check the [Procedure.kind] property. |
118 void forEachOverridePair(Class class_, | 122 void forEachOverridePair(Class class_, |
119 callback(Member declaredMember, Member interfaceMember, bool isSetter)); | 123 callback(Member declaredMember, Member interfaceMember, bool isSetter), |
| 124 {bool crossGettersSetters: false}); |
120 | 125 |
121 /// This method is invoked by the client after it changed the [classes], and | 126 /// This method is invoked by the client after it changed the [classes], and |
122 /// some of the information that this hierarchy might have cached, is not | 127 /// some of the information that this hierarchy might have cached, is not |
123 /// valid anymore. The hierarchy may perform required updates and return the | 128 /// valid anymore. The hierarchy may perform required updates and return the |
124 /// same instance, or return a new instance. | 129 /// same instance, or return a new instance. |
125 ClassHierarchy applyChanges(Iterable<Class> classes); | 130 ClassHierarchy applyChanges(Iterable<Class> classes); |
126 } | 131 } |
127 | 132 |
128 /// Implementation of [ClassHierarchy] for closed world. | 133 /// Implementation of [ClassHierarchy] for closed world. |
129 class ClosedWorldClassHierarchy implements ClassHierarchy { | 134 class ClosedWorldClassHierarchy implements ClassHierarchy { |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 /// when members are inherited through different supertypes and not overridden | 375 /// when members are inherited through different supertypes and not overridden |
371 /// in the class. | 376 /// in the class. |
372 /// | 377 /// |
373 /// Also see [getInterfaceMember]. | 378 /// Also see [getInterfaceMember]. |
374 List<Member> getInterfaceMembers(Class class_, {bool setters: false}) { | 379 List<Member> getInterfaceMembers(Class class_, {bool setters: false}) { |
375 return _buildInterfaceMembers(class_, _infoFor[class_], setters: setters); | 380 return _buildInterfaceMembers(class_, _infoFor[class_], setters: setters); |
376 } | 381 } |
377 | 382 |
378 @override | 383 @override |
379 void forEachOverridePair(Class class_, | 384 void forEachOverridePair(Class class_, |
380 callback(Member declaredMember, Member interfaceMember, bool isSetter)) { | 385 callback(Member declaredMember, Member interfaceMember, bool isSetter), |
| 386 {bool crossGettersSetters: false}) { |
381 _ClassInfo info = _infoFor[class_]; | 387 _ClassInfo info = _infoFor[class_]; |
382 for (var supertype in class_.supers) { | 388 for (var supertype in class_.supers) { |
383 var superclass = supertype.classNode; | 389 var superclass = supertype.classNode; |
384 var superGetters = getInterfaceMembers(superclass); | 390 var superGetters = getInterfaceMembers(superclass); |
385 var superSetters = getInterfaceMembers(superclass, setters: true); | 391 var superSetters = getInterfaceMembers(superclass, setters: true); |
386 _reportOverrides(info.implementedGettersAndCalls, superGetters, callback); | 392 _reportOverrides(info.implementedGettersAndCalls, superGetters, callback); |
387 _reportOverrides(info.declaredGettersAndCalls, superGetters, callback, | 393 _reportOverrides(info.declaredGettersAndCalls, superGetters, callback, |
388 onlyAbstract: true); | 394 onlyAbstract: true); |
389 _reportOverrides(info.implementedSetters, superSetters, callback, | 395 _reportOverrides(info.implementedSetters, superSetters, callback, |
390 isSetter: true); | 396 isSetter: true); |
391 _reportOverrides(info.declaredSetters, superSetters, callback, | 397 _reportOverrides(info.declaredSetters, superSetters, callback, |
392 isSetter: true, onlyAbstract: true); | 398 isSetter: true, onlyAbstract: true); |
| 399 if (crossGettersSetters) { |
| 400 _reportOverrides(info.declaredGettersAndCalls, superSetters, callback); |
| 401 _reportOverrides(info.declaredSetters, superGetters, callback); |
| 402 } |
393 } | 403 } |
394 if (!class_.isAbstract) { | 404 if (!class_.isAbstract) { |
395 // If a non-abstract class declares an abstract method M whose | 405 // If a non-abstract class declares an abstract method M whose |
396 // implementation M' is inherited from the superclass, then the inherited | 406 // implementation M' is inherited from the superclass, then the inherited |
397 // method M' overrides the declared method M. | 407 // method M' overrides the declared method M. |
398 // This flies in the face of conventional override logic, but is necessary | 408 // This flies in the face of conventional override logic, but is necessary |
399 // because an instance of the class will contain the method M' which can | 409 // because an instance of the class will contain the method M' which can |
400 // be invoked through the interface of M. | 410 // be invoked through the interface of M. |
401 // Note that [_reportOverrides] does not report self-overrides, so in | 411 // Note that [_reportOverrides] does not report self-overrides, so in |
402 // most cases these calls will just scan both lists and report nothing. | 412 // most cases these calls will just scan both lists and report nothing. |
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1130 class _LubHeap extends Heap<_ClassInfo> { | 1140 class _LubHeap extends Heap<_ClassInfo> { |
1131 @override | 1141 @override |
1132 bool sortsBefore(_ClassInfo a, _ClassInfo b) => sortsBeforeStatic(a, b); | 1142 bool sortsBefore(_ClassInfo a, _ClassInfo b) => sortsBeforeStatic(a, b); |
1133 | 1143 |
1134 static bool sortsBeforeStatic(_ClassInfo a, _ClassInfo b) { | 1144 static bool sortsBeforeStatic(_ClassInfo a, _ClassInfo b) { |
1135 if (a.depth > b.depth) return true; | 1145 if (a.depth > b.depth) return true; |
1136 if (a.depth < b.depth) return false; | 1146 if (a.depth < b.depth) return false; |
1137 return a.topologicalIndex < b.topologicalIndex; | 1147 return a.topologicalIndex < b.topologicalIndex; |
1138 } | 1148 } |
1139 } | 1149 } |
OLD | NEW |