Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(689)

Side by Side Diff: pkg/compiler/lib/src/universe/class_set.dart

Issue 1568213003: Add EnumSet. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
8 import '../elements/elements.dart' show ClassElement; 8 IterableBase;
9 import '../util/util.dart' show Link; 9 import '../elements/elements.dart' show
10 ClassElement;
11 import '../util/enumset.dart' show
12 EnumSet;
13 import '../util/util.dart' show
14 Link;
15
16 /// Enum for the different kinds of instantiation of a class.
17 enum Instantiation {
18 UNINSTANTIATED,
19 DIRECTLY_INSTANTIATED,
20 INDIRECTLY_INSTANTIATED,
21 }
10 22
11 /// Node for [cls] in a tree forming the subclass relation of [ClassElement]s. 23 /// Node for [cls] in a tree forming the subclass relation of [ClassElement]s.
12 /// 24 ///
13 /// This is used by the [ClassWorld] to perform queries on subclass and subtype 25 /// This is used by the [ClassWorld] to perform queries on subclass and subtype
14 /// relations. 26 /// relations.
15 /// 27 ///
16 /// For this class hierarchy: 28 /// For this class hierarchy:
17 /// 29 ///
18 /// class A {} 30 /// class A {}
19 /// class B extends A {} 31 /// class B extends A {}
20 /// class C extends A {} 32 /// class C extends A {}
21 /// class D extends B {} 33 /// class D extends B {}
22 /// class E extends D {} 34 /// class E extends D {}
23 /// 35 ///
24 /// the [ClassHierarchyNode]s form this subclass tree: 36 /// the [ClassHierarchyNode]s form this subclass tree:
25 /// 37 ///
26 /// Object 38 /// Object
27 /// | 39 /// |
28 /// A 40 /// A
29 /// / \ 41 /// / \
30 /// B C 42 /// B C
31 /// | 43 /// |
32 /// D 44 /// D
33 /// | 45 /// |
34 /// E 46 /// E
35 /// 47 ///
36 class ClassHierarchyNode { 48 class ClassHierarchyNode {
49 /// Enum set for selecting instantiated classes in
50 /// [ClassHierarchyNode.subclassesByMask],
51 /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
52 static final EnumSet<Instantiation> INSTANTIATED =
53 new EnumSet<Instantiation>.fromValues(
54 const <Instantiation>[
55 Instantiation.DIRECTLY_INSTANTIATED,
56 Instantiation.INDIRECTLY_INSTANTIATED],
57 fixed: true);
58
59 /// Enum set for selecting directly instantiated classes in
60 /// [ClassHierarchyNode.subclassesByMask],
61 /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
62 static final EnumSet<Instantiation> DIRECTLY_INSTANTIATED =
63 new EnumSet<Instantiation>.fromValues(
64 const <Instantiation>[Instantiation.DIRECTLY_INSTANTIATED],
65 fixed: true);
66
67 /// Enum set for selecting all classes in
68 /// [ClassHierarchyNode.subclassesByMask],
69 /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
70 static final EnumSet<Instantiation> ALL =
71 new EnumSet<Instantiation>.fromValues(
72 Instantiation.values,
73 fixed: true);
74
75 /// Creates an enum set for selecting the returned classes in
76 /// [ClassHierarchyNode.subclassesByMask],
77 /// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
78 static EnumSet<Instantiation> createMask(
79 {bool includeDirectlyInstantiated: true,
80 bool includeIndirectlyInstantiated: true,
81 bool includeUninstantiated: true}) {
82 EnumSet<Instantiation> mask = new EnumSet<Instantiation>();
83 if (includeDirectlyInstantiated) {
84 mask.add(Instantiation.DIRECTLY_INSTANTIATED);
85 }
86 if (includeIndirectlyInstantiated) {
87 mask.add(Instantiation.INDIRECTLY_INSTANTIATED);
88 }
89 if (includeUninstantiated) {
90 mask.add(Instantiation.UNINSTANTIATED);
91 }
92 return mask;
93 }
94
37 final ClassElement cls; 95 final ClassElement cls;
96 final EnumSet<Instantiation> _mask =
97 new EnumSet<Instantiation>.fromValues(
98 const <Instantiation>[Instantiation.UNINSTANTIATED]);
99
38 ClassElement _leastUpperInstantiatedSubclass; 100 ClassElement _leastUpperInstantiatedSubclass;
39 101
40 /// `true` if [cls] has been directly instantiated. 102 /// `true` if [cls] has been directly instantiated.
41 /// 103 ///
42 /// For instance `C` but _not_ `B` in: 104 /// For instance `C` but _not_ `B` in:
43 /// class B {} 105 /// class B {}
44 /// class C extends B {} 106 /// class C extends B {}
45 /// main() => new C(); 107 /// main() => new C();
46 /// 108 ///
47 bool isDirectlyInstantiated = false; 109 bool get isDirectlyInstantiated =>
110 _mask.contains(Instantiation.DIRECTLY_INSTANTIATED);
111
112 void set isDirectlyInstantiated(bool value) {
113 if (value != isDirectlyInstantiated) {
114 if (value) {
115 _mask.remove(Instantiation.UNINSTANTIATED);
116 _mask.add(Instantiation.DIRECTLY_INSTANTIATED);
117 } else {
118 _mask.remove(Instantiation.DIRECTLY_INSTANTIATED);
119 if (_mask.isEmpty) {
120 _mask.add(Instantiation.UNINSTANTIATED);
121 }
122 }
123 }
124 }
48 125
49 /// `true` if [cls] has been instantiated through subclasses. 126 /// `true` if [cls] has been instantiated through subclasses.
50 /// 127 ///
51 /// For instance `A` and `B` but _not_ `C` in: 128 /// For instance `A` and `B` but _not_ `C` in:
52 /// class A {} 129 /// class A {}
53 /// class B extends A {} 130 /// class B extends A {}
54 /// class C extends B {} 131 /// class C extends B {}
55 /// main() => [new B(), new C()]; 132 /// main() => [new B(), new C()];
56 /// 133 ///
57 bool isIndirectlyInstantiated = false; 134 bool get isIndirectlyInstantiated =>
135 _mask.contains(Instantiation.INDIRECTLY_INSTANTIATED);
136
137 void set isIndirectlyInstantiated(bool value) {
138 if (value != isIndirectlyInstantiated) {
139 if (value) {
140 _mask.remove(Instantiation.UNINSTANTIATED);
141 _mask.add(Instantiation.INDIRECTLY_INSTANTIATED);
142 } else {
143 _mask.remove(Instantiation.INDIRECTLY_INSTANTIATED);
144 if (_mask.isEmpty) {
145 _mask.add(Instantiation.UNINSTANTIATED);
146 }
147 }
148 }
149 }
58 150
59 /// The nodes for the direct subclasses of [cls]. 151 /// The nodes for the direct subclasses of [cls].
60 Link<ClassHierarchyNode> _directSubclasses = const Link<ClassHierarchyNode>(); 152 Link<ClassHierarchyNode> _directSubclasses = const Link<ClassHierarchyNode>();
61 153
62 ClassHierarchyNode(this.cls); 154 ClassHierarchyNode(this.cls);
63 155
64 /// Adds [subclass] as a direct subclass of [cls]. 156 /// Adds [subclass] as a direct subclass of [cls].
65 void addDirectSubclass(ClassHierarchyNode subclass) { 157 void addDirectSubclass(ClassHierarchyNode subclass) {
66 assert(subclass.cls.superclass == cls); 158 assert(subclass.cls.superclass == cls);
67 assert(!_directSubclasses.contains(subclass)); 159 assert(!_directSubclasses.contains(subclass));
(...skipping 19 matching lines...) Expand all
87 /// 179 ///
88 /// The directly instantiated, indirectly instantiated and uninstantiated 180 /// The directly instantiated, indirectly instantiated and uninstantiated
89 /// subclasses of [cls] are returned if [includeDirectlyInstantiated], 181 /// subclasses of [cls] are returned if [includeDirectlyInstantiated],
90 /// [includeIndirectlyInstantiated], and [includeUninstantiated] are `true`, 182 /// [includeIndirectlyInstantiated], and [includeUninstantiated] are `true`,
91 /// respectively. If [strict] is `true`, [cls] itself is _not_ returned. 183 /// respectively. If [strict] is `true`, [cls] itself is _not_ returned.
92 Iterable<ClassElement> subclasses( 184 Iterable<ClassElement> subclasses(
93 {bool includeDirectlyInstantiated: true, 185 {bool includeDirectlyInstantiated: true,
94 bool includeIndirectlyInstantiated: true, 186 bool includeIndirectlyInstantiated: true,
95 bool includeUninstantiated: true, 187 bool includeUninstantiated: true,
96 bool strict: false}) { 188 bool strict: false}) {
189 EnumSet<Instantiation> mask = createMask(
190 includeDirectlyInstantiated: includeDirectlyInstantiated,
191 includeIndirectlyInstantiated:includeIndirectlyInstantiated,
192 includeUninstantiated: includeUninstantiated);
193 return subclassesByMask(mask, strict: strict);
194 }
195
196 /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
197 ///
198 /// The [mask] defines the included subset of the subclasses based on their
199 /// instantiation properties. If [strict] is `true`, [cls] itself is _not_
200 /// returned.
201 Iterable<ClassElement> subclassesByMask(
202 EnumSet<Instantiation> mask,
203 {bool strict: false}) {
97 return new ClassHierarchyNodeIterable( 204 return new ClassHierarchyNodeIterable(
98 this, 205 this, mask, includeRoot: !strict);
99 includeRoot: !strict,
100 includeDirectlyInstantiated: includeDirectlyInstantiated,
101 includeIndirectlyInstantiated: includeIndirectlyInstantiated,
102 includeUninstantiated: includeUninstantiated);
103 } 206 }
104 207
105 /// Returns the most specific subclass of [cls] (including [cls]) that is 208 /// Returns the most specific subclass of [cls] (including [cls]) that is
106 /// directly instantiated or a superclass of all directly instantiated 209 /// directly instantiated or a superclass of all directly instantiated
107 /// subclasses. If [cls] is not instantiated, `null` is returned. 210 /// subclasses. If [cls] is not instantiated, `null` is returned.
108 ClassElement getLubOfInstantiatedSubclasses() { 211 ClassElement getLubOfInstantiatedSubclasses() {
109 if (!isInstantiated) return null; 212 if (!isInstantiated) return null;
110 if (_leastUpperInstantiatedSubclass == null) { 213 if (_leastUpperInstantiatedSubclass == null) {
111 _leastUpperInstantiatedSubclass = 214 _leastUpperInstantiatedSubclass =
112 _computeLeastUpperInstantiatedSubclass(); 215 _computeLeastUpperInstantiatedSubclass();
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 /// 371 ///
269 /// The directly instantiated, indirectly instantiated and uninstantiated 372 /// The directly instantiated, indirectly instantiated and uninstantiated
270 /// subclasses of [cls] are returned if [includeDirectlyInstantiated], 373 /// subclasses of [cls] are returned if [includeDirectlyInstantiated],
271 /// [includeIndirectlyInstantiated], and [includeUninstantiated] are `true`, 374 /// [includeIndirectlyInstantiated], and [includeUninstantiated] are `true`,
272 /// respectively. If [strict] is `true`, [cls] itself is _not_ returned. 375 /// respectively. If [strict] is `true`, [cls] itself is _not_ returned.
273 Iterable<ClassElement> subclasses( 376 Iterable<ClassElement> subclasses(
274 {bool includeDirectlyInstantiated: true, 377 {bool includeDirectlyInstantiated: true,
275 bool includeIndirectlyInstantiated: true, 378 bool includeIndirectlyInstantiated: true,
276 bool includeUninstantiated: true, 379 bool includeUninstantiated: true,
277 bool strict: false}) { 380 bool strict: false}) {
278 return node.subclasses( 381 EnumSet<Instantiation> mask = ClassHierarchyNode.createMask(
279 strict: strict,
280 includeDirectlyInstantiated: includeDirectlyInstantiated, 382 includeDirectlyInstantiated: includeDirectlyInstantiated,
281 includeIndirectlyInstantiated: includeIndirectlyInstantiated, 383 includeIndirectlyInstantiated:includeIndirectlyInstantiated,
282 includeUninstantiated: includeUninstantiated); 384 includeUninstantiated: includeUninstantiated);
385 return subclassesByMask(mask, strict: strict);
386 }
387
388 /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
389 ///
390 /// The [mask] defines the included subset of the subclasses based on their
391 /// instantiation properties. If [strict] is `true`, [cls] itself is _not_
392 /// returned.
393 Iterable<ClassElement> subclassesByMask(
394 EnumSet<Instantiation> mask,
395 {bool strict: false}) {
396 return node.subclassesByMask(mask, strict: strict);
283 } 397 }
284 398
285 /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls]. 399 /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls].
286 /// 400 ///
287 /// The directly instantiated, indirectly instantiated and uninstantiated 401 /// The directly instantiated, indirectly instantiated and uninstantiated
288 /// subtypes of [cls] are returned if [includeDirectlyInstantiated], 402 /// subtypes of [cls] are returned if [includeDirectlyInstantiated],
289 /// [includeIndirectlyInstantiated], and [includeUninstantiated] are `true`, 403 /// [includeIndirectlyInstantiated], and [includeUninstantiated] are `true`,
290 /// respectively. If [strict] is `true`, [cls] itself is _not_ returned. 404 /// respectively. If [strict] is `true`, [cls] itself is _not_ returned.
291 Iterable<ClassElement> subtypes( 405 Iterable<ClassElement> subtypes(
292 {bool includeDirectlyInstantiated: true, 406 {bool includeDirectlyInstantiated: true,
293 bool includeIndirectlyInstantiated: true, 407 bool includeIndirectlyInstantiated: true,
294 bool includeUninstantiated: true, 408 bool includeUninstantiated: true,
295 bool strict: false}) { 409 bool strict: false}) {
410 EnumSet<Instantiation> mask = ClassHierarchyNode.createMask(
411 includeDirectlyInstantiated: includeDirectlyInstantiated,
412 includeIndirectlyInstantiated:includeIndirectlyInstantiated,
413 includeUninstantiated: includeUninstantiated);
414 return subtypesByMask(mask, strict: strict);
415 }
416
417
418 /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls].
419 ///
420 /// The [mask] defines the included subset of the subtypes based on their
sigurdm 2016/01/11 08:48:55 It is not clear from the description of `mask` tha
Johnni Winther 2016/01/22 11:54:13 Updated the comments.
421 /// instantiation properties. If [strict] is `true`, [cls] itself is _not_
422 /// returned.
423 Iterable<ClassElement> subtypesByMask(
424 EnumSet<Instantiation> mask,
425 {bool strict: false}) {
296 if (_directSubtypes == null) { 426 if (_directSubtypes == null) {
297 return node.subclasses( 427 return node.subclassesByMask(
298 strict: strict, 428 mask,
299 includeDirectlyInstantiated: includeDirectlyInstantiated, 429 strict: strict);
300 includeIndirectlyInstantiated: includeIndirectlyInstantiated,
301 includeUninstantiated: includeUninstantiated);
302 } 430 }
431
303 return new SubtypesIterable.SubtypesIterator(this, 432 return new SubtypesIterable.SubtypesIterator(this,
304 includeRoot: !strict, 433 mask,
305 includeDirectlyInstantiated: includeDirectlyInstantiated, 434 includeRoot: !strict);
306 includeIndirectlyInstantiated: includeIndirectlyInstantiated,
307 includeUninstantiated: includeUninstantiated);
308 } 435 }
309 436
310 /// Adds [subtype] as a subtype of [cls]. 437 /// Adds [subtype] as a subtype of [cls].
311 void addSubtype(ClassHierarchyNode subtype) { 438 void addSubtype(ClassHierarchyNode subtype) {
312 if (node.contains(subtype.cls)) { 439 if (node.contains(subtype.cls)) {
313 return; 440 return;
314 } 441 }
315 if (_directSubtypes == null) { 442 if (_directSubtypes == null) {
316 _directSubtypes = <ClassHierarchyNode>[subtype]; 443 _directSubtypes = <ClassHierarchyNode>[subtype];
317 } else { 444 } else {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 } 532 }
406 } 533 }
407 sb.write(']'); 534 sb.write(']');
408 return sb.toString(); 535 return sb.toString();
409 } 536 }
410 } 537 }
411 538
412 /// Iterable for subclasses of a [ClassHierarchyNode]. 539 /// Iterable for subclasses of a [ClassHierarchyNode].
413 class ClassHierarchyNodeIterable extends IterableBase<ClassElement> { 540 class ClassHierarchyNodeIterable extends IterableBase<ClassElement> {
414 final ClassHierarchyNode root; 541 final ClassHierarchyNode root;
542 final EnumSet<Instantiation> mask;
415 final bool includeRoot; 543 final bool includeRoot;
416 final bool includeDirectlyInstantiated;
417 final bool includeIndirectlyInstantiated;
418 final bool includeUninstantiated;
419 544
420 ClassHierarchyNodeIterable( 545 ClassHierarchyNodeIterable(
421 this.root, 546 this.root,
422 {this.includeRoot: true, 547 this.mask,
423 this.includeDirectlyInstantiated: true, 548 {this.includeRoot: true}) {
424 this.includeIndirectlyInstantiated: true,
425 this.includeUninstantiated: true}) {
426 if (root == null) throw new StateError("No root for iterable."); 549 if (root == null) throw new StateError("No root for iterable.");
427 } 550 }
428 551
429 @override 552 @override
430 Iterator<ClassElement> get iterator { 553 Iterator<ClassElement> get iterator {
431 return new ClassHierarchyNodeIterator(this); 554 return new ClassHierarchyNodeIterator(this);
432 } 555 }
433 } 556 }
434 557
435 /// Iterator for subclasses of a [ClassHierarchyNode]. 558 /// Iterator for subclasses of a [ClassHierarchyNode].
(...skipping 12 matching lines...) Expand all
448 /// 571 ///
449 /// This is `null` before the first call to [moveNext]. 572 /// This is `null` before the first call to [moveNext].
450 Link<ClassHierarchyNode> stack; 573 Link<ClassHierarchyNode> stack;
451 574
452 ClassHierarchyNodeIterator(this.iterable); 575 ClassHierarchyNodeIterator(this.iterable);
453 576
454 ClassHierarchyNode get root => iterable.root; 577 ClassHierarchyNode get root => iterable.root;
455 578
456 bool get includeRoot => iterable.includeRoot; 579 bool get includeRoot => iterable.includeRoot;
457 580
458 bool get includeDirectlyInstantiated => iterable.includeDirectlyInstantiated; 581 EnumSet<Instantiation> get mask => iterable.mask;
459 582
460 bool get includeIndirectlyInstantiated { 583 bool get includeUninstantiated {
461 return iterable.includeIndirectlyInstantiated; 584 return mask.contains(Instantiation.UNINSTANTIATED);
462 } 585 }
463 586
464 bool get includeUninstantiated => iterable.includeUninstantiated;
465
466 @override 587 @override
467 ClassElement get current { 588 ClassElement get current {
468 return currentNode != null ? currentNode.cls : null; 589 return currentNode != null ? currentNode.cls : null;
469 } 590 }
470 591
471 @override 592 @override
472 bool moveNext() { 593 bool moveNext() {
473 if (stack == null) { 594 if (stack == null) {
474 // First call to moveNext 595 // First call to moveNext
475 stack = const Link<ClassHierarchyNode>().prepend(root); 596 stack = const Link<ClassHierarchyNode>().prepend(root);
(...skipping 28 matching lines...) Expand all
504 } 625 }
505 if (_isValid(currentNode)) { 626 if (_isValid(currentNode)) {
506 return true; 627 return true;
507 } 628 }
508 } 629 }
509 } 630 }
510 631
511 /// Returns `true` if the class of [node] is a valid result for this iterator. 632 /// Returns `true` if the class of [node] is a valid result for this iterator.
512 bool _isValid(ClassHierarchyNode node) { 633 bool _isValid(ClassHierarchyNode node) {
513 if (!includeRoot && node == root) return false; 634 if (!includeRoot && node == root) return false;
514 if (includeDirectlyInstantiated && node.isDirectlyInstantiated) { 635 return mask.intersects(node._mask);
515 return true;
516 }
517 if (includeIndirectlyInstantiated && node.isIndirectlyInstantiated) {
518 return true;
519 }
520 if (includeUninstantiated && !node.isInstantiated) {
521 return true;
522 }
523 return false;
524 } 636 }
525 } 637 }
526 638
527 /// Iterable for the subtypes in a [ClassSet]. 639 /// Iterable for the subtypes in a [ClassSet].
528 class SubtypesIterable extends IterableBase<ClassElement> { 640 class SubtypesIterable extends IterableBase<ClassElement> {
529 final ClassSet subtypeSet; 641 final ClassSet subtypeSet;
642 final EnumSet<Instantiation> mask;
530 final bool includeRoot; 643 final bool includeRoot;
531 final bool includeDirectlyInstantiated;
532 final bool includeIndirectlyInstantiated;
533 final bool includeUninstantiated;
534 644
535 SubtypesIterable.SubtypesIterator( 645 SubtypesIterable.SubtypesIterator(
536 this.subtypeSet, 646 this.subtypeSet,
537 {this.includeRoot: true, 647 this.mask,
538 this.includeDirectlyInstantiated: true, 648 {this.includeRoot: true});
539 this.includeIndirectlyInstantiated: true,
540 this.includeUninstantiated: true});
541 649
542 @override 650 @override
543 Iterator<ClassElement> get iterator => new SubtypesIterator(this); 651 Iterator<ClassElement> get iterator => new SubtypesIterator(this);
544 } 652 }
545 653
546 /// Iterator for the subtypes in a [ClassSet]. 654 /// Iterator for the subtypes in a [ClassSet].
547 class SubtypesIterator extends Iterator<ClassElement> { 655 class SubtypesIterator extends Iterator<ClassElement> {
548 final SubtypesIterable iterable; 656 final SubtypesIterable iterable;
549 Iterator<ClassElement> elements; 657 Iterator<ClassElement> elements;
550 Iterator<ClassHierarchyNode> hierarchyNodes; 658 Iterator<ClassHierarchyNode> hierarchyNodes;
551 659
552 SubtypesIterator(this.iterable); 660 SubtypesIterator(this.iterable);
553 661
554 bool get includeRoot => iterable.includeRoot; 662 bool get includeRoot => iterable.includeRoot;
555 663
556 bool get includeDirectlyInstantiated => iterable.includeDirectlyInstantiated; 664 EnumSet<Instantiation> get mask => iterable.mask;
557
558 bool get includeIndirectlyInstantiated {
559 return iterable.includeIndirectlyInstantiated;
560 }
561
562 bool get includeUninstantiated => iterable.includeUninstantiated;
563 665
564 @override 666 @override
565 ClassElement get current { 667 ClassElement get current {
566 if (elements != null) { 668 if (elements != null) {
567 return elements.current; 669 return elements.current;
568 } 670 }
569 return null; 671 return null;
570 } 672 }
571 673
572 @override 674 @override
573 bool moveNext() { 675 bool moveNext() {
574 if (elements == null && hierarchyNodes == null) { 676 if (elements == null && hierarchyNodes == null) {
575 // Initial state. Iterate through subclasses. 677 // Initial state. Iterate through subclasses.
576 elements = iterable.subtypeSet.node.subclasses( 678 elements = iterable.subtypeSet.node.subclassesByMask(
577 strict: !includeRoot, 679 mask,
578 includeDirectlyInstantiated: includeDirectlyInstantiated, 680 strict: !includeRoot).iterator;
579 includeIndirectlyInstantiated: includeIndirectlyInstantiated,
580 includeUninstantiated: includeUninstantiated).iterator;
581 } 681 }
582 if (elements != null && elements.moveNext()) { 682 if (elements != null && elements.moveNext()) {
583 return true; 683 return true;
584 } 684 }
585 if (hierarchyNodes == null) { 685 if (hierarchyNodes == null) {
586 // Start iterating through subtypes. 686 // Start iterating through subtypes.
587 hierarchyNodes = iterable.subtypeSet._directSubtypes.iterator; 687 hierarchyNodes = iterable.subtypeSet._directSubtypes.iterator;
588 } 688 }
589 while (hierarchyNodes.moveNext()) { 689 while (hierarchyNodes.moveNext()) {
590 elements = hierarchyNodes.current.subclasses( 690 elements = hierarchyNodes.current.subclassesByMask(mask).iterator;
591 includeDirectlyInstantiated: includeDirectlyInstantiated,
592 includeIndirectlyInstantiated: includeIndirectlyInstantiated,
593 includeUninstantiated: includeUninstantiated).iterator;
594 if (elements.moveNext()) { 691 if (elements.moveNext()) {
595 return true; 692 return true;
596 } 693 }
597 } 694 }
598 return false; 695 return false;
599 } 696 }
600 } 697 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698