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

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

Issue 2813853002: Use entity WorldImpl where possible (Closed)
Patch Set: Created 3 years, 8 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/world.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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;
11 import '../util/enumset.dart' show EnumSet; 11 import '../util/enumset.dart' show EnumSet;
12 import '../util/util.dart' show Link; 12 import '../util/util.dart' show Link;
13 13
14 /// Enum for the different kinds of instantiation of a class. 14 /// Enum for the different kinds of instantiation of a class.
15 enum Instantiation { 15 enum Instantiation {
16 UNINSTANTIATED, 16 UNINSTANTIATED,
17 DIRECTLY_INSTANTIATED, 17 DIRECTLY_INSTANTIATED,
18 INDIRECTLY_INSTANTIATED, 18 INDIRECTLY_INSTANTIATED,
19 ABSTRACTLY_INSTANTIATED, 19 ABSTRACTLY_INSTANTIATED,
20 } 20 }
21 21
22 /// Node for [cls] in a tree forming the subclass relation of [ClassElement]s. 22 /// Node for [cls] in a tree forming the subclass relation of [ClassEntity]s.
23 /// 23 ///
24 /// This is used by the [ClosedWorld] to perform queries on subclass and subtype 24 /// This is used by the [ClosedWorld] to perform queries on subclass and subtype
25 /// relations. 25 /// relations.
26 /// 26 ///
27 /// For this class hierarchy: 27 /// For this class hierarchy:
28 /// 28 ///
29 /// class A {} 29 /// class A {}
30 /// class B extends A {} 30 /// class B extends A {}
31 /// class C extends A {} 31 /// class C extends A {}
32 /// class D extends B {} 32 /// class D extends B {}
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 return mask; 94 return mask;
95 } 95 }
96 96
97 final ClassHierarchyNode parentNode; 97 final ClassHierarchyNode parentNode;
98 final ClassEntity cls; 98 final ClassEntity cls;
99 final EnumSet<Instantiation> _mask = new EnumSet<Instantiation>.fromValues( 99 final EnumSet<Instantiation> _mask = new EnumSet<Instantiation>.fromValues(
100 const <Instantiation>[Instantiation.UNINSTANTIATED]); 100 const <Instantiation>[Instantiation.UNINSTANTIATED]);
101 101
102 final int hierarchyDepth; 102 final int hierarchyDepth;
103 103
104 ClassElement _leastUpperInstantiatedSubclass; 104 ClassEntity _leastUpperInstantiatedSubclass;
105 int _instantiatedSubclassCount = 0; 105 int _instantiatedSubclassCount = 0;
106 106
107 /// `true` if [cls] has been directly instantiated. 107 /// `true` if [cls] has been directly instantiated.
108 /// 108 ///
109 /// For instance `C` but _not_ `B` in: 109 /// For instance `C` but _not_ `B` in:
110 /// class B {} 110 /// class B {}
111 /// class C extends B {} 111 /// class C extends B {}
112 /// main() => new C(); 112 /// main() => new C();
113 /// 113 ///
114 bool get isDirectlyInstantiated => 114 bool get isDirectlyInstantiated =>
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 230
231 /// `true` if [cls] has been directly, indirectly, or abstractly instantiated. 231 /// `true` if [cls] has been directly, indirectly, or abstractly instantiated.
232 bool get isInstantiated => 232 bool get isInstantiated =>
233 isExplicitlyInstantiated || isIndirectlyInstantiated; 233 isExplicitlyInstantiated || isIndirectlyInstantiated;
234 234
235 /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls]. 235 /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
236 /// 236 ///
237 /// Subclasses are included if their instantiation properties intersect with 237 /// Subclasses are included if their instantiation properties intersect with
238 /// their corresponding [Instantiation] values in [mask]. If [strict] is 238 /// their corresponding [Instantiation] values in [mask]. If [strict] is
239 /// `true`, [cls] itself is _not_ returned. 239 /// `true`, [cls] itself is _not_ returned.
240 Iterable<ClassElement> subclassesByMask(EnumSet<Instantiation> mask, 240 Iterable<ClassEntity> subclassesByMask(EnumSet<Instantiation> mask,
241 {bool strict: false}) { 241 {bool strict: false}) {
242 return new ClassHierarchyNodeIterable(this, mask, includeRoot: !strict); 242 return new ClassHierarchyNodeIterable(this, mask, includeRoot: !strict);
243 } 243 }
244 244
245 /// Applies [predicate] to each subclass of [cls] matching the criteria 245 /// Applies [predicate] to each subclass of [cls] matching the criteria
246 /// specified by [mask] and [strict]. If [predicate] returns `true` on a 246 /// specified by [mask] and [strict]. If [predicate] returns `true` on a
247 /// class, visitation is stopped immediately and the function returns `true`. 247 /// class, visitation is stopped immediately and the function returns `true`.
248 /// 248 ///
249 /// [predicate] is applied to subclasses if their instantiation properties 249 /// [predicate] is applied to subclasses if their instantiation properties
250 /// intersect with their corresponding [Instantiation] values in [mask]. If 250 /// intersect with their corresponding [Instantiation] values in [mask]. If
251 /// [strict] is `true`, [predicate] is _not_ called on [cls] itself. 251 /// [strict] is `true`, [predicate] is _not_ called on [cls] itself.
252 bool anySubclass( 252 bool anySubclass(bool predicate(ClassEntity cls), EnumSet<Instantiation> mask,
253 bool predicate(ClassElement cls), EnumSet<Instantiation> mask,
254 {bool strict: false}) { 253 {bool strict: false}) {
255 IterationStep wrapper(ClassElement cls) { 254 IterationStep wrapper(ClassEntity cls) {
256 return predicate(cls) ? IterationStep.STOP : IterationStep.CONTINUE; 255 return predicate(cls) ? IterationStep.STOP : IterationStep.CONTINUE;
257 } 256 }
258 257
259 return forEachSubclass(wrapper, mask, strict: strict) == IterationStep.STOP; 258 return forEachSubclass(wrapper, mask, strict: strict) == IterationStep.STOP;
260 } 259 }
261 260
262 /// Applies [f] to each subclass of [cls] matching the criteria specified by 261 /// Applies [f] to each subclass of [cls] matching the criteria specified by
263 /// [mask] and [strict]. 262 /// [mask] and [strict].
264 /// 263 ///
265 /// [f] is a applied to subclasses if their instantiation properties intersect 264 /// [f] is a applied to subclasses if their instantiation properties intersect
(...skipping 28 matching lines...) Expand all
294 } 293 }
295 if (nextStep == IterationStep.STOP) { 294 if (nextStep == IterationStep.STOP) {
296 return nextStep; 295 return nextStep;
297 } 296 }
298 return IterationStep.CONTINUE; 297 return IterationStep.CONTINUE;
299 } 298 }
300 299
301 /// Returns the most specific subclass of [cls] (including [cls]) that is 300 /// Returns the most specific subclass of [cls] (including [cls]) that is
302 /// directly instantiated or a superclass of all directly instantiated 301 /// directly instantiated or a superclass of all directly instantiated
303 /// subclasses. If [cls] is not instantiated, `null` is returned. 302 /// subclasses. If [cls] is not instantiated, `null` is returned.
304 ClassElement getLubOfInstantiatedSubclasses() { 303 ClassEntity getLubOfInstantiatedSubclasses() {
305 if (!isInstantiated) return null; 304 if (!isInstantiated) return null;
306 if (_leastUpperInstantiatedSubclass == null) { 305 if (_leastUpperInstantiatedSubclass == null) {
307 _leastUpperInstantiatedSubclass = 306 _leastUpperInstantiatedSubclass =
308 _computeLeastUpperInstantiatedSubclass(); 307 _computeLeastUpperInstantiatedSubclass();
309 } 308 }
310 return _leastUpperInstantiatedSubclass; 309 return _leastUpperInstantiatedSubclass;
311 } 310 }
312 311
313 ClassElement _computeLeastUpperInstantiatedSubclass() { 312 ClassEntity _computeLeastUpperInstantiatedSubclass() {
314 if (isExplicitlyInstantiated) { 313 if (isExplicitlyInstantiated) {
315 return cls; 314 return cls;
316 } 315 }
317 if (!isInstantiated) { 316 if (!isInstantiated) {
318 return null; 317 return null;
319 } 318 }
320 ClassHierarchyNode subclass; 319 ClassHierarchyNode subclass;
321 for (Link<ClassHierarchyNode> link = _directSubclasses; 320 for (Link<ClassHierarchyNode> link = _directSubclasses;
322 !link.isEmpty; 321 !link.isEmpty;
323 link = link.tail) { 322 link = link.tail) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 StringBuffer sb = new StringBuffer(); 404 StringBuffer sb = new StringBuffer();
406 printOn(sb, indentation, 405 printOn(sb, indentation,
407 instantiatedOnly: instantiatedOnly, withRespectTo: withRespectTo); 406 instantiatedOnly: instantiatedOnly, withRespectTo: withRespectTo);
408 return sb.toString(); 407 return sb.toString();
409 } 408 }
410 409
411 String toString() => cls.toString(); 410 String toString() => cls.toString();
412 } 411 }
413 412
414 /// Object holding the subclass and subtype relation for a single 413 /// Object holding the subclass and subtype relation for a single
415 /// [ClassElement]. 414 /// [ClassEntity].
416 /// 415 ///
417 /// The subclass relation for a class `C` is modelled through a reference to 416 /// The subclass relation for a class `C` is modelled through a reference to
418 /// the [ClassHierarchyNode] for `C` in the global [ClassHierarchyNode] tree 417 /// the [ClassHierarchyNode] for `C` in the global [ClassHierarchyNode] tree
419 /// computed in [World]. 418 /// computed in [World].
420 /// 419 ///
421 /// The subtype relation for a class `C` is modelled through a collection of 420 /// The subtype relation for a class `C` is modelled through a collection of
422 /// disjoint [ClassHierarchyNode] subtrees. The subclasses of `C`, modelled 421 /// disjoint [ClassHierarchyNode] subtrees. The subclasses of `C`, modelled
423 /// through the aforementioned [ClassHierarchyNode] pointer, are extended with 422 /// through the aforementioned [ClassHierarchyNode] pointer, are extended with
424 /// the subtypes that do not extend `C` through a list of additional 423 /// the subtypes that do not extend `C` through a list of additional
425 /// [ClassHierarchyNode] nodes. This list is normalized to contain only the 424 /// [ClassHierarchyNode] nodes. This list is normalized to contain only the
(...skipping 24 matching lines...) Expand all
450 /// The subtypes `B` and `E` are not directly modeled because they are implied 449 /// The subtypes `B` and `E` are not directly modeled because they are implied
451 /// by their subclass relation to `A` and `D`, repectively. This can be seen 450 /// by their subclass relation to `A` and `D`, repectively. This can be seen
452 /// if we expand the subclass subtrees: 451 /// if we expand the subclass subtrees:
453 /// 452 ///
454 /// A -> [C, D, F] 453 /// A -> [C, D, F]
455 /// | | 454 /// | |
456 /// B E 455 /// B E
457 /// 456 ///
458 class ClassSet { 457 class ClassSet {
459 final ClassHierarchyNode node; 458 final ClassHierarchyNode node;
460 ClassElement _leastUpperInstantiatedSubtype; 459 ClassEntity _leastUpperInstantiatedSubtype;
461 460
462 /// A list of the class hierarchy nodes for the subtypes that declare a 461 /// A list of the class hierarchy nodes for the subtypes that declare a
463 /// subtype relationship to [cls] either directly or indirectly. 462 /// subtype relationship to [cls] either directly or indirectly.
464 /// 463 ///
465 /// For instance 464 /// For instance
466 /// 465 ///
467 /// class A {} 466 /// class A {}
468 /// class B extends A {} 467 /// class B extends A {}
469 /// class C implements B {} 468 /// class C implements B {}
470 /// class D implements A {} 469 /// class D implements A {}
471 /// class E extends D {} 470 /// class E extends D {}
472 /// 471 ///
473 /// The class hierarchy nodes for classes `C` and `D` are in [_subtypes]. `C` 472 /// The class hierarchy nodes for classes `C` and `D` are in [_subtypes]. `C`
474 /// because it implements `A` through `B` and `D` because it implements `A` 473 /// because it implements `A` through `B` and `D` because it implements `A`
475 /// directly. `E` also implements `A` through its extension of `D` and it is 474 /// directly. `E` also implements `A` through its extension of `D` and it is
476 /// therefore included through the class hierarchy node for `D`. 475 /// therefore included through the class hierarchy node for `D`.
477 /// 476 ///
478 List<ClassHierarchyNode> _subtypes; 477 List<ClassHierarchyNode> _subtypes;
479 478
480 ClassSet(this.node); 479 ClassSet(this.node);
481 480
482 ClassElement get cls => node.cls; 481 ClassEntity get cls => node.cls;
483 482
484 /// Returns the number of directly instantiated subtypes of [cls]. 483 /// Returns the number of directly instantiated subtypes of [cls].
485 int get instantiatedSubtypeCount { 484 int get instantiatedSubtypeCount {
486 int count = node.instantiatedSubclassCount; 485 int count = node.instantiatedSubclassCount;
487 if (_subtypes != null) { 486 if (_subtypes != null) {
488 for (ClassHierarchyNode subtypeNode in _subtypes) { 487 for (ClassHierarchyNode subtypeNode in _subtypes) {
489 if (subtypeNode.isExplicitlyInstantiated) { 488 if (subtypeNode.isExplicitlyInstantiated) {
490 count++; 489 count++;
491 } 490 }
492 count += subtypeNode.instantiatedSubclassCount; 491 count += subtypeNode.instantiatedSubclassCount;
(...skipping 17 matching lines...) Expand all
510 509
511 Iterable<ClassHierarchyNode> get subtypeNodes { 510 Iterable<ClassHierarchyNode> get subtypeNodes {
512 return _subtypes ?? const <ClassHierarchyNode>[]; 511 return _subtypes ?? const <ClassHierarchyNode>[];
513 } 512 }
514 513
515 /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls]. 514 /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
516 /// 515 ///
517 /// Subclasses are included if their instantiation properties intersect with 516 /// Subclasses are included if their instantiation properties intersect with
518 /// their corresponding [Instantiation] values in [mask]. If [strict] is 517 /// their corresponding [Instantiation] values in [mask]. If [strict] is
519 /// `true`, [cls] itself is _not_ returned. 518 /// `true`, [cls] itself is _not_ returned.
520 Iterable<ClassElement> subclassesByMask(EnumSet<Instantiation> mask, 519 Iterable<ClassEntity> subclassesByMask(EnumSet<Instantiation> mask,
521 {bool strict: false}) { 520 {bool strict: false}) {
522 return node.subclassesByMask(mask, strict: strict); 521 return node.subclassesByMask(mask, strict: strict);
523 } 522 }
524 523
525 /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls]. 524 /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls].
526 /// 525 ///
527 /// The directly instantiated, indirectly instantiated and uninstantiated 526 /// The directly instantiated, indirectly instantiated and uninstantiated
528 /// subtypes of [cls] are returned if [includeDirectlyInstantiated], 527 /// subtypes of [cls] are returned if [includeDirectlyInstantiated],
529 /// [includeIndirectlyInstantiated], and [includeUninstantiated] are `true`, 528 /// [includeIndirectlyInstantiated], and [includeUninstantiated] are `true`,
530 /// respectively. If [strict] is `true`, [cls] itself is _not_ returned. 529 /// respectively. If [strict] is `true`, [cls] itself is _not_ returned.
531 Iterable<ClassElement> subtypes( 530 Iterable<ClassEntity> subtypes(
532 {bool includeDirectlyInstantiated: true, 531 {bool includeDirectlyInstantiated: true,
533 bool includeIndirectlyInstantiated: true, 532 bool includeIndirectlyInstantiated: true,
534 bool includeUninstantiated: true, 533 bool includeUninstantiated: true,
535 bool strict: false}) { 534 bool strict: false}) {
536 EnumSet<Instantiation> mask = ClassHierarchyNode.createMask( 535 EnumSet<Instantiation> mask = ClassHierarchyNode.createMask(
537 includeDirectlyInstantiated: includeDirectlyInstantiated, 536 includeDirectlyInstantiated: includeDirectlyInstantiated,
538 includeIndirectlyInstantiated: includeIndirectlyInstantiated, 537 includeIndirectlyInstantiated: includeIndirectlyInstantiated,
539 includeUninstantiated: includeUninstantiated); 538 includeUninstantiated: includeUninstantiated);
540 return subtypesByMask(mask, strict: strict); 539 return subtypesByMask(mask, strict: strict);
541 } 540 }
542 541
543 /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls]. 542 /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls].
544 /// 543 ///
545 /// Subtypes are included if their instantiation properties intersect with 544 /// Subtypes are included if their instantiation properties intersect with
546 /// their corresponding [Instantiation] values in [mask]. If [strict] is 545 /// their corresponding [Instantiation] values in [mask]. If [strict] is
547 /// `true`, [cls] itself is _not_ returned. 546 /// `true`, [cls] itself is _not_ returned.
548 Iterable<ClassElement> subtypesByMask(EnumSet<Instantiation> mask, 547 Iterable<ClassEntity> subtypesByMask(EnumSet<Instantiation> mask,
549 {bool strict: false}) { 548 {bool strict: false}) {
550 if (_subtypes == null) { 549 if (_subtypes == null) {
551 return node.subclassesByMask(mask, strict: strict); 550 return node.subclassesByMask(mask, strict: strict);
552 } 551 }
553 552
554 return new SubtypesIterable.SubtypesIterator(this, mask, 553 return new SubtypesIterable.SubtypesIterator(this, mask,
555 includeRoot: !strict); 554 includeRoot: !strict);
556 } 555 }
557 556
558 /// Applies [predicate] to each subclass of [cls] matching the criteria 557 /// Applies [predicate] to each subclass of [cls] matching the criteria
559 /// specified by [mask] and [strict]. If [predicate] returns `true` on a 558 /// specified by [mask] and [strict]. If [predicate] returns `true` on a
560 /// class, visitation is stopped immediately and the function returns `true`. 559 /// class, visitation is stopped immediately and the function returns `true`.
561 /// 560 ///
562 /// [predicate] is applied to subclasses if their instantiation properties 561 /// [predicate] is applied to subclasses if their instantiation properties
563 /// intersect with their corresponding [Instantiation] values in [mask]. If 562 /// intersect with their corresponding [Instantiation] values in [mask]. If
564 /// [strict] is `true`, [predicate] is _not_ called on [cls] itself. 563 /// [strict] is `true`, [predicate] is _not_ called on [cls] itself.
565 bool anySubclass( 564 bool anySubclass(bool predicate(ClassEntity cls), EnumSet<Instantiation> mask,
566 bool predicate(ClassElement cls), EnumSet<Instantiation> mask,
567 {bool strict: false}) { 565 {bool strict: false}) {
568 return node.anySubclass(predicate, mask, strict: strict); 566 return node.anySubclass(predicate, mask, strict: strict);
569 } 567 }
570 568
571 /// Applies [f] to each subclass of [cls] matching the criteria specified by 569 /// Applies [f] to each subclass of [cls] matching the criteria specified by
572 /// [mask] and [strict]. 570 /// [mask] and [strict].
573 /// 571 ///
574 /// [f] is a applied to subclasses if their instantiation properties intersect 572 /// [f] is a applied to subclasses if their instantiation properties intersect
575 /// with their corresponding [Instantiation] values in [mask]. If [strict] is 573 /// with their corresponding [Instantiation] values in [mask]. If [strict] is
576 /// `true`, [f] is _not_ called on [cls] itself. 574 /// `true`, [f] is _not_ called on [cls] itself.
(...skipping 10 matching lines...) Expand all
587 return node.forEachSubclass(f, mask, strict: strict); 585 return node.forEachSubclass(f, mask, strict: strict);
588 } 586 }
589 587
590 /// Applies [predicate] to each subtype of [cls] matching the criteria 588 /// Applies [predicate] to each subtype of [cls] matching the criteria
591 /// specified by [mask] and [strict]. If [predicate] returns `true` on a 589 /// specified by [mask] and [strict]. If [predicate] returns `true` on a
592 /// class, visitation is stopped immediately and the function returns `true`. 590 /// class, visitation is stopped immediately and the function returns `true`.
593 /// 591 ///
594 /// [predicate] is applied to subtypes if their instantiation properties 592 /// [predicate] is applied to subtypes if their instantiation properties
595 /// intersect with their corresponding [Instantiation] values in [mask]. If 593 /// intersect with their corresponding [Instantiation] values in [mask]. If
596 /// [strict] is `true`, [predicate] is _not_ called on [cls] itself. 594 /// [strict] is `true`, [predicate] is _not_ called on [cls] itself.
597 bool anySubtype(bool predicate(ClassElement cls), EnumSet<Instantiation> mask, 595 bool anySubtype(bool predicate(ClassEntity cls), EnumSet<Instantiation> mask,
598 {bool strict: false}) { 596 {bool strict: false}) {
599 IterationStep wrapper(ClassElement cls) { 597 IterationStep wrapper(ClassEntity cls) {
600 return predicate(cls) ? IterationStep.STOP : IterationStep.CONTINUE; 598 return predicate(cls) ? IterationStep.STOP : IterationStep.CONTINUE;
601 } 599 }
602 600
603 return forEachSubtype(wrapper, mask, strict: strict) == IterationStep.STOP; 601 return forEachSubtype(wrapper, mask, strict: strict) == IterationStep.STOP;
604 } 602 }
605 603
606 /// Applies [f] to each subtype of [cls] matching the criteria specified by 604 /// Applies [f] to each subtype of [cls] matching the criteria specified by
607 /// [mask] and [strict]. 605 /// [mask] and [strict].
608 /// 606 ///
609 /// [f] is a applied to subtypes if their instantiation properties intersect 607 /// [f] is a applied to subtypes if their instantiation properties intersect
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 if (!added) { 677 if (!added) {
680 newSubtypes.add(subtype); 678 newSubtypes.add(subtype);
681 } 679 }
682 _subtypes = newSubtypes; 680 _subtypes = newSubtypes;
683 } 681 }
684 } 682 }
685 683
686 /// Returns the most specific subtype of [cls] (including [cls]) that is 684 /// Returns the most specific subtype of [cls] (including [cls]) that is
687 /// directly instantiated or a superclass of all directly instantiated 685 /// directly instantiated or a superclass of all directly instantiated
688 /// subtypes. If no subtypes of [cls] are instantiated, `null` is returned. 686 /// subtypes. If no subtypes of [cls] are instantiated, `null` is returned.
689 ClassElement getLubOfInstantiatedSubtypes() { 687 ClassEntity getLubOfInstantiatedSubtypes() {
690 if (_leastUpperInstantiatedSubtype == null) { 688 if (_leastUpperInstantiatedSubtype == null) {
691 _leastUpperInstantiatedSubtype = _computeLeastUpperInstantiatedSubtype(); 689 _leastUpperInstantiatedSubtype = _computeLeastUpperInstantiatedSubtype();
692 } 690 }
693 return _leastUpperInstantiatedSubtype; 691 return _leastUpperInstantiatedSubtype;
694 } 692 }
695 693
696 ClassElement _computeLeastUpperInstantiatedSubtype() { 694 ClassEntity _computeLeastUpperInstantiatedSubtype() {
697 if (node.isExplicitlyInstantiated) { 695 if (node.isExplicitlyInstantiated) {
698 return cls; 696 return cls;
699 } 697 }
700 if (_subtypes == null) { 698 if (_subtypes == null) {
701 return node.getLubOfInstantiatedSubclasses(); 699 return node.getLubOfInstantiatedSubclasses();
702 } 700 }
703 ClassHierarchyNode subtype; 701 ClassHierarchyNode subtype;
704 if (node.isInstantiated) { 702 if (node.isInstantiated) {
705 subtype = node; 703 subtype = node;
706 } 704 }
(...skipping 22 matching lines...) Expand all
729 node.printOn(sb, ' '); 727 node.printOn(sb, ' ');
730 sb.write('\n'); 728 sb.write('\n');
731 } 729 }
732 } 730 }
733 sb.write(']'); 731 sb.write(']');
734 return sb.toString(); 732 return sb.toString();
735 } 733 }
736 } 734 }
737 735
738 /// Iterable for subclasses of a [ClassHierarchyNode]. 736 /// Iterable for subclasses of a [ClassHierarchyNode].
739 class ClassHierarchyNodeIterable extends IterableBase<ClassElement> { 737 class ClassHierarchyNodeIterable extends IterableBase<ClassEntity> {
740 final ClassHierarchyNode root; 738 final ClassHierarchyNode root;
741 final EnumSet<Instantiation> mask; 739 final EnumSet<Instantiation> mask;
742 final bool includeRoot; 740 final bool includeRoot;
743 741
744 ClassHierarchyNodeIterable(this.root, this.mask, {this.includeRoot: true}) { 742 ClassHierarchyNodeIterable(this.root, this.mask, {this.includeRoot: true}) {
745 if (root == null) throw new StateError("No root for iterable."); 743 if (root == null) throw new StateError("No root for iterable.");
746 } 744 }
747 745
748 @override 746 @override
749 Iterator<ClassElement> get iterator { 747 Iterator<ClassEntity> get iterator {
750 return new ClassHierarchyNodeIterator(this); 748 return new ClassHierarchyNodeIterator(this);
751 } 749 }
752 } 750 }
753 751
754 /// Iterator for subclasses of a [ClassHierarchyNode]. 752 /// Iterator for subclasses of a [ClassHierarchyNode].
755 /// 753 ///
756 /// Classes are returned in pre-order DFS fashion. 754 /// Classes are returned in pre-order DFS fashion.
757 class ClassHierarchyNodeIterator implements Iterator<ClassElement> { 755 class ClassHierarchyNodeIterator implements Iterator<ClassEntity> {
758 final ClassHierarchyNodeIterable iterable; 756 final ClassHierarchyNodeIterable iterable;
759 757
760 /// The class node holding the [current] class. 758 /// The class node holding the [current] class.
761 /// 759 ///
762 /// This is `null` before the first call to [moveNext] and at the end of 760 /// This is `null` before the first call to [moveNext] and at the end of
763 /// iteration, i.e. after [moveNext] has returned `false`. 761 /// iteration, i.e. after [moveNext] has returned `false`.
764 ClassHierarchyNode currentNode; 762 ClassHierarchyNode currentNode;
765 763
766 /// Stack of pending class nodes. 764 /// Stack of pending class nodes.
767 /// 765 ///
768 /// This is `null` before the first call to [moveNext]. 766 /// This is `null` before the first call to [moveNext].
769 Link<ClassHierarchyNode> stack; 767 Link<ClassHierarchyNode> stack;
770 768
771 ClassHierarchyNodeIterator(this.iterable); 769 ClassHierarchyNodeIterator(this.iterable);
772 770
773 ClassHierarchyNode get root => iterable.root; 771 ClassHierarchyNode get root => iterable.root;
774 772
775 bool get includeRoot => iterable.includeRoot; 773 bool get includeRoot => iterable.includeRoot;
776 774
777 EnumSet<Instantiation> get mask => iterable.mask; 775 EnumSet<Instantiation> get mask => iterable.mask;
778 776
779 bool get includeUninstantiated { 777 bool get includeUninstantiated {
780 return mask.contains(Instantiation.UNINSTANTIATED); 778 return mask.contains(Instantiation.UNINSTANTIATED);
781 } 779 }
782 780
783 @override 781 @override
784 ClassElement get current { 782 ClassEntity get current {
785 return currentNode != null ? currentNode.cls : null; 783 return currentNode != null ? currentNode.cls : null;
786 } 784 }
787 785
788 @override 786 @override
789 bool moveNext() { 787 bool moveNext() {
790 if (stack == null) { 788 if (stack == null) {
791 // First call to moveNext 789 // First call to moveNext
792 stack = const Link<ClassHierarchyNode>().prepend(root); 790 stack = const Link<ClassHierarchyNode>().prepend(root);
793 return _findNext(); 791 return _findNext();
794 } else { 792 } else {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 } 824 }
827 825
828 /// Returns `true` if the class of [node] is a valid result for this iterator. 826 /// Returns `true` if the class of [node] is a valid result for this iterator.
829 bool _isValid(ClassHierarchyNode node) { 827 bool _isValid(ClassHierarchyNode node) {
830 if (!includeRoot && node == root) return false; 828 if (!includeRoot && node == root) return false;
831 return mask.intersects(node._mask); 829 return mask.intersects(node._mask);
832 } 830 }
833 } 831 }
834 832
835 /// Iterable for the subtypes in a [ClassSet]. 833 /// Iterable for the subtypes in a [ClassSet].
836 class SubtypesIterable extends IterableBase<ClassElement> { 834 class SubtypesIterable extends IterableBase<ClassEntity> {
837 final ClassSet subtypeSet; 835 final ClassSet subtypeSet;
838 final EnumSet<Instantiation> mask; 836 final EnumSet<Instantiation> mask;
839 final bool includeRoot; 837 final bool includeRoot;
840 838
841 SubtypesIterable.SubtypesIterator(this.subtypeSet, this.mask, 839 SubtypesIterable.SubtypesIterator(this.subtypeSet, this.mask,
842 {this.includeRoot: true}); 840 {this.includeRoot: true});
843 841
844 @override 842 @override
845 Iterator<ClassElement> get iterator => new SubtypesIterator(this); 843 Iterator<ClassEntity> get iterator => new SubtypesIterator(this);
846 } 844 }
847 845
848 /// Iterator for the subtypes in a [ClassSet]. 846 /// Iterator for the subtypes in a [ClassSet].
849 class SubtypesIterator extends Iterator<ClassElement> { 847 class SubtypesIterator extends Iterator<ClassEntity> {
850 final SubtypesIterable iterable; 848 final SubtypesIterable iterable;
851 Iterator<ClassElement> elements; 849 Iterator<ClassEntity> elements;
852 Iterator<ClassHierarchyNode> hierarchyNodes; 850 Iterator<ClassHierarchyNode> hierarchyNodes;
853 851
854 SubtypesIterator(this.iterable); 852 SubtypesIterator(this.iterable);
855 853
856 bool get includeRoot => iterable.includeRoot; 854 bool get includeRoot => iterable.includeRoot;
857 855
858 EnumSet<Instantiation> get mask => iterable.mask; 856 EnumSet<Instantiation> get mask => iterable.mask;
859 857
860 @override 858 @override
861 ClassElement get current { 859 ClassEntity get current {
862 if (elements != null) { 860 if (elements != null) {
863 return elements.current; 861 return elements.current;
864 } 862 }
865 return null; 863 return null;
866 } 864 }
867 865
868 @override 866 @override
869 bool moveNext() { 867 bool moveNext() {
870 if (elements == null && hierarchyNodes == null) { 868 if (elements == null && hierarchyNodes == null) {
871 // Initial state. Iterate through subclasses. 869 // Initial state. Iterate through subclasses.
(...skipping 28 matching lines...) Expand all
900 /// Iteration stops immediately. 898 /// Iteration stops immediately.
901 STOP, 899 STOP,
902 900
903 /// Iteration skips the subclasses of the current class. 901 /// Iteration skips the subclasses of the current class.
904 SKIP_SUBCLASSES, 902 SKIP_SUBCLASSES,
905 } 903 }
906 904
907 /// Visiting function used for the `forEachX` functions of [ClassHierarchyNode] 905 /// Visiting function used for the `forEachX` functions of [ClassHierarchyNode]
908 /// and [ClassSet]. The return value controls the continued iteration. If `null` 906 /// and [ClassSet]. The return value controls the continued iteration. If `null`
909 /// is returned, iteration continues to the end. 907 /// is returned, iteration continues to the end.
910 typedef IterationStep ForEachFunction(ClassElement cls); 908 typedef IterationStep ForEachFunction(ClassEntity cls);
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/world.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698