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 |