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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 /// Getters and setters are overridden separately. The [isSetter] callback |
117 /// parameter determines which type of access is being overridden. | 117 /// parameter determines which type of access is being overridden. |
118 void forEachOverridePair(Class class_, | 118 void forEachOverridePair(Class class_, |
119 callback(Member declaredMember, Member interfaceMember, bool isSetter)); | 119 callback(Member declaredMember, Member interfaceMember, bool isSetter), |
| 120 {bool crossGettersSetters: false}); |
120 | 121 |
121 /// This method is invoked by the client after it changed the [classes], and | 122 /// 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 | 123 /// some of the information that this hierarchy might have cached, is not |
123 /// valid anymore. The hierarchy may perform required updates and return the | 124 /// valid anymore. The hierarchy may perform required updates and return the |
124 /// same instance, or return a new instance. | 125 /// same instance, or return a new instance. |
125 ClassHierarchy applyChanges(Iterable<Class> classes); | 126 ClassHierarchy applyChanges(Iterable<Class> classes); |
126 } | 127 } |
127 | 128 |
128 /// Implementation of [ClassHierarchy] for closed world. | 129 /// Implementation of [ClassHierarchy] for closed world. |
129 class ClosedWorldClassHierarchy implements ClassHierarchy { | 130 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 | 371 /// when members are inherited through different supertypes and not overridden |
371 /// in the class. | 372 /// in the class. |
372 /// | 373 /// |
373 /// Also see [getInterfaceMember]. | 374 /// Also see [getInterfaceMember]. |
374 List<Member> getInterfaceMembers(Class class_, {bool setters: false}) { | 375 List<Member> getInterfaceMembers(Class class_, {bool setters: false}) { |
375 return _buildInterfaceMembers(class_, _infoFor[class_], setters: setters); | 376 return _buildInterfaceMembers(class_, _infoFor[class_], setters: setters); |
376 } | 377 } |
377 | 378 |
378 @override | 379 @override |
379 void forEachOverridePair(Class class_, | 380 void forEachOverridePair(Class class_, |
380 callback(Member declaredMember, Member interfaceMember, bool isSetter)) { | 381 callback(Member declaredMember, Member interfaceMember, bool isSetter), |
| 382 {bool crossGettersSetters: false}) { |
381 _ClassInfo info = _infoFor[class_]; | 383 _ClassInfo info = _infoFor[class_]; |
382 for (var supertype in class_.supers) { | 384 for (var supertype in class_.supers) { |
383 var superclass = supertype.classNode; | 385 var superclass = supertype.classNode; |
384 var superGetters = getInterfaceMembers(superclass); | 386 var superGetters = getInterfaceMembers(superclass); |
385 var superSetters = getInterfaceMembers(superclass, setters: true); | 387 var superSetters = getInterfaceMembers(superclass, setters: true); |
386 _reportOverrides(info.implementedGettersAndCalls, superGetters, callback); | 388 _reportOverrides(info.implementedGettersAndCalls, superGetters, callback); |
387 _reportOverrides(info.declaredGettersAndCalls, superGetters, callback, | 389 _reportOverrides(info.declaredGettersAndCalls, superGetters, callback, |
388 onlyAbstract: true); | 390 onlyAbstract: true); |
389 _reportOverrides(info.implementedSetters, superSetters, callback, | 391 _reportOverrides(info.implementedSetters, superSetters, callback, |
390 isSetter: true); | 392 isSetter: true); |
391 _reportOverrides(info.declaredSetters, superSetters, callback, | 393 _reportOverrides(info.declaredSetters, superSetters, callback, |
392 isSetter: true, onlyAbstract: true); | 394 isSetter: true, onlyAbstract: true); |
| 395 if (crossGettersSetters) { |
| 396 _reportOverrides(info.declaredGettersAndCalls, superSetters, callback); |
| 397 _reportOverrides(info.declaredSetters, superGetters, callback); |
| 398 } |
393 } | 399 } |
394 if (!class_.isAbstract) { | 400 if (!class_.isAbstract) { |
395 // If a non-abstract class declares an abstract method M whose | 401 // If a non-abstract class declares an abstract method M whose |
396 // implementation M' is inherited from the superclass, then the inherited | 402 // implementation M' is inherited from the superclass, then the inherited |
397 // method M' overrides the declared method M. | 403 // method M' overrides the declared method M. |
398 // This flies in the face of conventional override logic, but is necessary | 404 // 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 | 405 // because an instance of the class will contain the method M' which can |
400 // be invoked through the interface of M. | 406 // be invoked through the interface of M. |
401 // Note that [_reportOverrides] does not report self-overrides, so in | 407 // Note that [_reportOverrides] does not report self-overrides, so in |
402 // most cases these calls will just scan both lists and report nothing. | 408 // 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> { | 1136 class _LubHeap extends Heap<_ClassInfo> { |
1131 @override | 1137 @override |
1132 bool sortsBefore(_ClassInfo a, _ClassInfo b) => sortsBeforeStatic(a, b); | 1138 bool sortsBefore(_ClassInfo a, _ClassInfo b) => sortsBeforeStatic(a, b); |
1133 | 1139 |
1134 static bool sortsBeforeStatic(_ClassInfo a, _ClassInfo b) { | 1140 static bool sortsBeforeStatic(_ClassInfo a, _ClassInfo b) { |
1135 if (a.depth > b.depth) return true; | 1141 if (a.depth > b.depth) return true; |
1136 if (a.depth < b.depth) return false; | 1142 if (a.depth < b.depth) return false; |
1137 return a.topologicalIndex < b.topologicalIndex; | 1143 return a.topologicalIndex < b.topologicalIndex; |
1138 } | 1144 } |
1139 } | 1145 } |
OLD | NEW |