| 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 |