OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 | 4 |
5 library dart2js.world.class_set; | 5 library dart2js.world.class_set; |
6 | 6 |
7 import 'dart:collection' show IterableBase; | 7 import 'dart:collection' show IterableBase; |
8 | 8 |
9 import '../elements/elements.dart' show ClassElement; | 9 import '../elements/elements.dart' show ClassElement; |
10 import '../elements/entities.dart' show ClassEntity; | 10 import '../elements/entities.dart' show ClassEntity; |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 /// This means that [other] is a subclass of [cls]. | 221 /// This means that [other] is a subclass of [cls]. |
222 bool contains(ClassHierarchyNode other) { | 222 bool contains(ClassHierarchyNode other) { |
223 while (other != null) { | 223 while (other != null) { |
224 if (cls == other.cls) return true; | 224 if (cls == other.cls) return true; |
225 if (hierarchyDepth >= other.hierarchyDepth) return false; | 225 if (hierarchyDepth >= other.hierarchyDepth) return false; |
226 other = other.parentNode; | 226 other = other.parentNode; |
227 } | 227 } |
228 return false; | 228 return false; |
229 } | 229 } |
230 | 230 |
| 231 /// Returns `true` if `other.cls` is a subclass of [cls]. |
| 232 bool hasSubclass(ClassHierarchyNode other) { |
| 233 return contains(other); |
| 234 } |
| 235 |
231 /// `true` if [cls] has been directly, indirectly, or abstractly instantiated. | 236 /// `true` if [cls] has been directly, indirectly, or abstractly instantiated. |
232 bool get isInstantiated => | 237 bool get isInstantiated => |
233 isExplicitlyInstantiated || isIndirectlyInstantiated; | 238 isExplicitlyInstantiated || isIndirectlyInstantiated; |
234 | 239 |
235 /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls]. | 240 /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls]. |
236 /// | 241 /// |
237 /// Subclasses are included if their instantiation properties intersect with | 242 /// Subclasses are included if their instantiation properties intersect with |
238 /// their corresponding [Instantiation] values in [mask]. If [strict] is | 243 /// their corresponding [Instantiation] values in [mask]. If [strict] is |
239 /// `true`, [cls] itself is _not_ returned. | 244 /// `true`, [cls] itself is _not_ returned. |
240 Iterable<ClassEntity> subclassesByMask(EnumSet<Instantiation> mask, | 245 Iterable<ClassEntity> subclassesByMask(EnumSet<Instantiation> mask, |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 /// because it implements `A` through `B` and `D` because it implements `A` | 478 /// because it implements `A` through `B` and `D` because it implements `A` |
474 /// directly. `E` also implements `A` through its extension of `D` and it is | 479 /// directly. `E` also implements `A` through its extension of `D` and it is |
475 /// therefore included through the class hierarchy node for `D`. | 480 /// therefore included through the class hierarchy node for `D`. |
476 /// | 481 /// |
477 List<ClassHierarchyNode> _subtypes; | 482 List<ClassHierarchyNode> _subtypes; |
478 | 483 |
479 ClassSet(this.node); | 484 ClassSet(this.node); |
480 | 485 |
481 ClassEntity get cls => node.cls; | 486 ClassEntity get cls => node.cls; |
482 | 487 |
| 488 /// Returns `true` if `other.cls` is a subclass of [cls]. |
| 489 bool hasSubclass(ClassHierarchyNode other) => node.hasSubclass(other); |
| 490 |
| 491 /// Returns `true` if `other.cls` is a subtype of [cls]. |
| 492 bool hasSubtype(ClassHierarchyNode other) { |
| 493 if (hasSubclass(other)) return true; |
| 494 if (_subtypes != null) { |
| 495 for (ClassHierarchyNode subtypeNode in _subtypes) { |
| 496 if (subtypeNode.hasSubclass(other)) return true; |
| 497 } |
| 498 } |
| 499 return false; |
| 500 } |
| 501 |
483 /// Returns the number of directly instantiated subtypes of [cls]. | 502 /// Returns the number of directly instantiated subtypes of [cls]. |
484 int get instantiatedSubtypeCount { | 503 int get instantiatedSubtypeCount { |
485 int count = node.instantiatedSubclassCount; | 504 int count = node.instantiatedSubclassCount; |
486 if (_subtypes != null) { | 505 if (_subtypes != null) { |
487 for (ClassHierarchyNode subtypeNode in _subtypes) { | 506 for (ClassHierarchyNode subtypeNode in _subtypes) { |
488 if (subtypeNode.isExplicitlyInstantiated) { | 507 if (subtypeNode.isExplicitlyInstantiated) { |
489 count++; | 508 count++; |
490 } | 509 } |
491 count += subtypeNode.instantiatedSubclassCount; | 510 count += subtypeNode.instantiatedSubclassCount; |
492 } | 511 } |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
899 STOP, | 918 STOP, |
900 | 919 |
901 /// Iteration skips the subclasses of the current class. | 920 /// Iteration skips the subclasses of the current class. |
902 SKIP_SUBCLASSES, | 921 SKIP_SUBCLASSES, |
903 } | 922 } |
904 | 923 |
905 /// Visiting function used for the `forEachX` functions of [ClassHierarchyNode] | 924 /// Visiting function used for the `forEachX` functions of [ClassHierarchyNode] |
906 /// and [ClassSet]. The return value controls the continued iteration. If `null` | 925 /// and [ClassSet]. The return value controls the continued iteration. If `null` |
907 /// is returned, iteration continues to the end. | 926 /// is returned, iteration continues to the end. |
908 typedef IterationStep ForEachFunction(ClassEntity cls); | 927 typedef IterationStep ForEachFunction(ClassEntity cls); |
OLD | NEW |