Chromium Code Reviews| 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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 /// By default getters and setters are overridden separately. The [isSetter] | 116 /// By default getters and setters are overridden separately. The [isSetter] |
| 117 /// callback parameter determines which type of access is being overridden. | 117 /// callback parameter determines which type of access is being overridden. |
| 118 void forEachOverridePair(Class class_, | |
| 119 callback(Member declaredMember, Member interfaceMember, bool isSetter)); | |
| 120 | |
| 121 /// Invokes [callback] for every function, field, or getter declared in | |
| 122 /// [class_] that has a corresponding setter in a supertype of [class_], and | |
| 123 /// for every setter or non-final field declared in [class_] that has a | |
| 124 /// corresponding function, field, or getter in a supertype of [class_]. | |
| 118 /// | 125 /// |
| 119 /// However if [crossGettersSetters] is set to `true`, getters might be | 126 /// We use the term "inheritable" for members that are candidates for |
| 120 /// reported as overriding setters, and vice versa - setter overriding | 127 /// inheritance but may have been overridden. The "declared" members of a |
| 121 /// getters. The callback should check the [Procedure.kind] property. | 128 /// mixin application are those declared in the mixed-in type. The callback is |
| 122 void forEachOverridePair(Class class_, | 129 /// invoked in the following case: |
| 123 callback(Member declaredMember, Member interfaceMember, bool isSetter), | 130 /// |
| 124 {bool crossGettersSetters: false}); | 131 /// A member declared in the class overrides a member inheritable through |
| 132 /// one of the supertypes of the class. | |
| 133 /// | |
| 134 /// This method will not report that a member overrides itself. A given pair | |
| 135 /// may be reported multiple times when there are multiple inheritance paths | |
| 136 /// to the overridden member. | |
| 137 /// | |
| 138 /// By default getters and setters are overridden separately. The [isSetter] | |
|
scheglov
2017/06/26 20:29:12
"By default getters and setters are overridden sep
Paul Berry
2017/06/27 20:53:30
Thanks! https://codereview.chromium.org/296003300
| |
| 139 /// callback parameter corresponds to whether [declaredMember] is a setter. | |
| 140 void forEachCrossOverridePair(Class class_, | |
| 141 callback(Member declaredMember, Member interfaceMember, bool isSetter)); | |
| 125 | 142 |
| 126 /// This method is invoked by the client after it changed the [classes], and | 143 /// This method is invoked by the client after it changed the [classes], and |
| 127 /// some of the information that this hierarchy might have cached, is not | 144 /// some of the information that this hierarchy might have cached, is not |
| 128 /// valid anymore. The hierarchy may perform required updates and return the | 145 /// valid anymore. The hierarchy may perform required updates and return the |
| 129 /// same instance, or return a new instance. | 146 /// same instance, or return a new instance. |
| 130 ClassHierarchy applyChanges(Iterable<Class> classes); | 147 ClassHierarchy applyChanges(Iterable<Class> classes); |
| 131 } | 148 } |
| 132 | 149 |
| 133 /// Implementation of [ClassHierarchy] for closed world. | 150 /// Implementation of [ClassHierarchy] for closed world. |
| 134 class ClosedWorldClassHierarchy implements ClassHierarchy { | 151 class ClosedWorldClassHierarchy implements ClassHierarchy { |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 389 var superclass = supertype.classNode; | 406 var superclass = supertype.classNode; |
| 390 var superGetters = getInterfaceMembers(superclass); | 407 var superGetters = getInterfaceMembers(superclass); |
| 391 var superSetters = getInterfaceMembers(superclass, setters: true); | 408 var superSetters = getInterfaceMembers(superclass, setters: true); |
| 392 _reportOverrides(info.implementedGettersAndCalls, superGetters, callback); | 409 _reportOverrides(info.implementedGettersAndCalls, superGetters, callback); |
| 393 _reportOverrides(info.declaredGettersAndCalls, superGetters, callback, | 410 _reportOverrides(info.declaredGettersAndCalls, superGetters, callback, |
| 394 onlyAbstract: true); | 411 onlyAbstract: true); |
| 395 _reportOverrides(info.implementedSetters, superSetters, callback, | 412 _reportOverrides(info.implementedSetters, superSetters, callback, |
| 396 isSetter: true); | 413 isSetter: true); |
| 397 _reportOverrides(info.declaredSetters, superSetters, callback, | 414 _reportOverrides(info.declaredSetters, superSetters, callback, |
| 398 isSetter: true, onlyAbstract: true); | 415 isSetter: true, onlyAbstract: true); |
| 399 if (crossGettersSetters) { | |
| 400 _reportOverrides(info.declaredGettersAndCalls, superSetters, callback); | |
| 401 _reportOverrides(info.declaredSetters, superGetters, callback); | |
| 402 } | |
| 403 } | 416 } |
| 404 if (!class_.isAbstract) { | 417 if (!class_.isAbstract) { |
| 405 // If a non-abstract class declares an abstract method M whose | 418 // If a non-abstract class declares an abstract method M whose |
| 406 // implementation M' is inherited from the superclass, then the inherited | 419 // implementation M' is inherited from the superclass, then the inherited |
| 407 // method M' overrides the declared method M. | 420 // method M' overrides the declared method M. |
| 408 // This flies in the face of conventional override logic, but is necessary | 421 // This flies in the face of conventional override logic, but is necessary |
| 409 // because an instance of the class will contain the method M' which can | 422 // because an instance of the class will contain the method M' which can |
| 410 // be invoked through the interface of M. | 423 // be invoked through the interface of M. |
| 411 // Note that [_reportOverrides] does not report self-overrides, so in | 424 // Note that [_reportOverrides] does not report self-overrides, so in |
| 412 // most cases these calls will just scan both lists and report nothing. | 425 // most cases these calls will just scan both lists and report nothing. |
| 413 _reportOverrides(info.implementedGettersAndCalls, | 426 _reportOverrides(info.implementedGettersAndCalls, |
| 414 info.declaredGettersAndCalls, callback); | 427 info.declaredGettersAndCalls, callback); |
| 415 _reportOverrides(info.implementedSetters, info.declaredSetters, callback, | 428 _reportOverrides(info.implementedSetters, info.declaredSetters, callback, |
| 416 isSetter: true); | 429 isSetter: true); |
| 417 } | 430 } |
| 418 } | 431 } |
| 419 | 432 |
| 433 @override | |
| 434 void forEachCrossOverridePair(Class class_, | |
| 435 callback(Member declaredMember, Member interfaceMember, bool isSetter), | |
| 436 {bool crossGettersSetters: false}) { | |
| 437 _ClassInfo info = _infoFor[class_]; | |
| 438 for (var supertype in class_.supers) { | |
| 439 var superclass = supertype.classNode; | |
| 440 var superGetters = getInterfaceMembers(superclass); | |
| 441 var superSetters = getInterfaceMembers(superclass, setters: true); | |
| 442 _reportOverrides(info.declaredGettersAndCalls, superSetters, callback); | |
| 443 _reportOverrides(info.declaredSetters, superGetters, callback, | |
| 444 isSetter: true); | |
| 445 } | |
| 446 } | |
| 447 | |
| 420 static void _reportOverrides( | 448 static void _reportOverrides( |
| 421 List<Member> declaredList, | 449 List<Member> declaredList, |
| 422 List<Member> inheritedList, | 450 List<Member> inheritedList, |
| 423 callback(Member declaredMember, Member interfaceMember, bool isSetter), | 451 callback(Member declaredMember, Member interfaceMember, bool isSetter), |
| 424 {bool isSetter: false, | 452 {bool isSetter: false, |
| 425 bool onlyAbstract: false}) { | 453 bool onlyAbstract: false}) { |
| 426 int i = 0, j = 0; | 454 int i = 0, j = 0; |
| 427 while (i < declaredList.length && j < inheritedList.length) { | 455 while (i < declaredList.length && j < inheritedList.length) { |
| 428 Member declared = declaredList[i]; | 456 Member declared = declaredList[i]; |
| 429 if (onlyAbstract && !declared.isAbstract) { | 457 if (onlyAbstract && !declared.isAbstract) { |
| (...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1140 class _LubHeap extends Heap<_ClassInfo> { | 1168 class _LubHeap extends Heap<_ClassInfo> { |
| 1141 @override | 1169 @override |
| 1142 bool sortsBefore(_ClassInfo a, _ClassInfo b) => sortsBeforeStatic(a, b); | 1170 bool sortsBefore(_ClassInfo a, _ClassInfo b) => sortsBeforeStatic(a, b); |
| 1143 | 1171 |
| 1144 static bool sortsBeforeStatic(_ClassInfo a, _ClassInfo b) { | 1172 static bool sortsBeforeStatic(_ClassInfo a, _ClassInfo b) { |
| 1145 if (a.depth > b.depth) return true; | 1173 if (a.depth > b.depth) return true; |
| 1146 if (a.depth < b.depth) return false; | 1174 if (a.depth < b.depth) return false; |
| 1147 return a.topologicalIndex < b.topologicalIndex; | 1175 return a.topologicalIndex < b.topologicalIndex; |
| 1148 } | 1176 } |
| 1149 } | 1177 } |
| OLD | NEW |