OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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; | 5 library dart2js.world; |
6 | 6 |
7 import 'closure.dart' show ClosureClassElement, SynthesizedCallMethodElementX; | 7 import 'closure.dart' show ClosureClassElement, SynthesizedCallMethodElementX; |
8 import 'common.dart'; | 8 import 'common.dart'; |
9 import 'constants/constant_system.dart'; | 9 import 'constants/constant_system.dart'; |
10 import 'common_elements.dart' show CommonElements; | 10 import 'common_elements.dart' show CommonElements; |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
467 CommonMasks get commonMasks { | 467 CommonMasks get commonMasks { |
468 return _commonMasks; | 468 return _commonMasks; |
469 } | 469 } |
470 | 470 |
471 TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) { | 471 TypeMask getCachedMask(ClassEntity base, int flags, TypeMask createMask()) { |
472 Map<ClassEntity, TypeMask> cachedMasks = | 472 Map<ClassEntity, TypeMask> cachedMasks = |
473 _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{}; | 473 _canonicalizedTypeMasks[flags] ??= <ClassEntity, TypeMask>{}; |
474 return cachedMasks.putIfAbsent(base, createMask); | 474 return cachedMasks.putIfAbsent(base, createMask); |
475 } | 475 } |
476 | 476 |
477 bool _checkEntity(Entity element); | 477 bool checkEntity(Entity element); |
478 | 478 |
479 bool _checkClass(ClassEntity cls); | 479 bool checkClass(ClassEntity cls); |
480 | 480 |
481 bool _checkInvariants(ClassEntity cls, {bool mustBeInstantiated: true}); | 481 bool checkInvariants(ClassEntity cls, {bool mustBeInstantiated: true}); |
482 | 482 |
483 OrderedTypeSet _getOrderedTypeSet(ClassEntity cls); | 483 OrderedTypeSet getOrderedTypeSet(ClassEntity cls); |
484 | 484 |
485 int _getHierarchyDepth(ClassEntity cls); | 485 int getHierarchyDepth(ClassEntity cls); |
486 | 486 |
487 ClassEntity _getSuperClass(ClassEntity cls); | 487 ClassEntity getSuperClass(ClassEntity cls); |
488 | 488 |
489 Iterable<ClassEntity> _getInterfaces(ClassEntity cls); | 489 Iterable<ClassEntity> getInterfaces(ClassEntity cls); |
490 | 490 |
491 ClassEntity _getAppliedMixin(ClassEntity cls); | 491 ClassEntity getAppliedMixin(ClassEntity cls); |
492 | 492 |
493 bool _isNamedMixinApplication(ClassEntity cls); | 493 bool isNamedMixinApplication(ClassEntity cls); |
494 | 494 |
495 @override | 495 @override |
496 bool isInstantiated(ClassEntity cls) { | 496 bool isInstantiated(ClassEntity cls) { |
497 assert(_checkClass(cls)); | 497 assert(checkClass(cls)); |
498 ClassHierarchyNode node = _classHierarchyNodes[cls]; | 498 ClassHierarchyNode node = _classHierarchyNodes[cls]; |
499 return node != null && node.isInstantiated; | 499 return node != null && node.isInstantiated; |
500 } | 500 } |
501 | 501 |
502 @override | 502 @override |
503 bool isDirectlyInstantiated(ClassEntity cls) { | 503 bool isDirectlyInstantiated(ClassEntity cls) { |
504 assert(_checkClass(cls)); | 504 assert(checkClass(cls)); |
505 ClassHierarchyNode node = _classHierarchyNodes[cls]; | 505 ClassHierarchyNode node = _classHierarchyNodes[cls]; |
506 return node != null && node.isDirectlyInstantiated; | 506 return node != null && node.isDirectlyInstantiated; |
507 } | 507 } |
508 | 508 |
509 @override | 509 @override |
510 bool isAbstractlyInstantiated(ClassEntity cls) { | 510 bool isAbstractlyInstantiated(ClassEntity cls) { |
511 assert(_checkClass(cls)); | 511 assert(checkClass(cls)); |
512 ClassHierarchyNode node = _classHierarchyNodes[cls]; | 512 ClassHierarchyNode node = _classHierarchyNodes[cls]; |
513 return node != null && node.isAbstractlyInstantiated; | 513 return node != null && node.isAbstractlyInstantiated; |
514 } | 514 } |
515 | 515 |
516 @override | 516 @override |
517 bool isExplicitlyInstantiated(ClassEntity cls) { | 517 bool isExplicitlyInstantiated(ClassEntity cls) { |
518 assert(_checkClass(cls)); | 518 assert(checkClass(cls)); |
519 ClassHierarchyNode node = _classHierarchyNodes[cls]; | 519 ClassHierarchyNode node = _classHierarchyNodes[cls]; |
520 return node != null && node.isExplicitlyInstantiated; | 520 return node != null && node.isExplicitlyInstantiated; |
521 } | 521 } |
522 | 522 |
523 @override | 523 @override |
524 bool isIndirectlyInstantiated(ClassEntity cls) { | 524 bool isIndirectlyInstantiated(ClassEntity cls) { |
525 assert(_checkClass(cls)); | 525 assert(checkClass(cls)); |
526 ClassHierarchyNode node = _classHierarchyNodes[cls]; | 526 ClassHierarchyNode node = _classHierarchyNodes[cls]; |
527 return node != null && node.isIndirectlyInstantiated; | 527 return node != null && node.isIndirectlyInstantiated; |
528 } | 528 } |
529 | 529 |
530 @override | 530 @override |
531 bool isAbstract(ClassEntity cls) => cls.isAbstract; | 531 bool isAbstract(ClassEntity cls) => cls.isAbstract; |
532 | 532 |
533 /// Returns `true` if [cls] is implemented by an instantiated class. | 533 /// Returns `true` if [cls] is implemented by an instantiated class. |
534 bool isImplemented(ClassEntity cls) { | 534 bool isImplemented(ClassEntity cls) { |
535 return _resolverWorld.isImplemented(cls); | 535 return _resolverWorld.isImplemented(cls); |
536 } | 536 } |
537 | 537 |
538 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an | 538 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an |
539 /// instance of [y]. | 539 /// instance of [y]. |
540 bool isSubtypeOf(ClassEntity x, ClassEntity y) { | 540 bool isSubtypeOf(ClassEntity x, ClassEntity y) { |
541 assert(_checkInvariants(x)); | 541 assert(checkInvariants(x)); |
542 assert(_checkInvariants(y, mustBeInstantiated: false)); | 542 assert(checkInvariants(y, mustBeInstantiated: false)); |
543 return _classSets[y].hasSubtype(_classHierarchyNodes[x]); | 543 ClassSet classSet = _classSets[y]; |
544 assert( | |
545 classSet != null, | |
546 failedAt(y, | |
547 "No ClassSet for $y (${y.runtimeType}): ${dump(y)} : ${_classSets}") ); | |
Siggi Cherem (dart-lang)
2017/06/08 18:10:22
nit: long line
Johnni Winther
2017/06/09 10:27:10
Done.
| |
548 ClassHierarchyNode classHierarchyNode = _classHierarchyNodes[x]; | |
549 assert(classHierarchyNode != null, | |
550 failedAt(x, "No ClassHierarchyNode for $x: ${dump(x)}")); | |
551 return classSet.hasSubtype(classHierarchyNode); | |
544 } | 552 } |
545 | 553 |
546 /// Return `true` if [x] is a (non-strict) subclass of [y]. | 554 /// Return `true` if [x] is a (non-strict) subclass of [y]. |
547 bool isSubclassOf(ClassEntity x, ClassEntity y) { | 555 bool isSubclassOf(ClassEntity x, ClassEntity y) { |
548 assert(_checkInvariants(x)); | 556 assert(checkInvariants(x)); |
549 assert(_checkInvariants(y)); | 557 assert(checkInvariants(y)); |
550 return _classHierarchyNodes[y].hasSubclass(_classHierarchyNodes[x]); | 558 return _classHierarchyNodes[y].hasSubclass(_classHierarchyNodes[x]); |
551 } | 559 } |
552 | 560 |
553 /// Returns an iterable over the directly instantiated classes that extend | 561 /// Returns an iterable over the directly instantiated classes that extend |
554 /// [cls] possibly including [cls] itself, if it is live. | 562 /// [cls] possibly including [cls] itself, if it is live. |
555 Iterable<ClassEntity> subclassesOf(ClassEntity cls) { | 563 Iterable<ClassEntity> subclassesOf(ClassEntity cls) { |
556 assert(_checkClass(cls)); | 564 assert(checkClass(cls)); |
557 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls]; | 565 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls]; |
558 if (hierarchy == null) return const <ClassEntity>[]; | 566 if (hierarchy == null) return const <ClassEntity>[]; |
559 return hierarchy | 567 return hierarchy |
560 .subclassesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED); | 568 .subclassesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED); |
561 } | 569 } |
562 | 570 |
563 /// Returns an iterable over the directly instantiated classes that extend | 571 /// Returns an iterable over the directly instantiated classes that extend |
564 /// [cls] _not_ including [cls] itself. | 572 /// [cls] _not_ including [cls] itself. |
565 Iterable<ClassEntity> strictSubclassesOf(ClassEntity cls) { | 573 Iterable<ClassEntity> strictSubclassesOf(ClassEntity cls) { |
566 assert(_checkClass(cls)); | 574 assert(checkClass(cls)); |
567 ClassHierarchyNode subclasses = _classHierarchyNodes[cls]; | 575 ClassHierarchyNode subclasses = _classHierarchyNodes[cls]; |
568 if (subclasses == null) return const <ClassEntity>[]; | 576 if (subclasses == null) return const <ClassEntity>[]; |
569 return subclasses.subclassesByMask( | 577 return subclasses.subclassesByMask( |
570 ClassHierarchyNode.EXPLICITLY_INSTANTIATED, | 578 ClassHierarchyNode.EXPLICITLY_INSTANTIATED, |
571 strict: true); | 579 strict: true); |
572 } | 580 } |
573 | 581 |
574 /// Returns the number of live classes that extend [cls] _not_ | 582 /// Returns the number of live classes that extend [cls] _not_ |
575 /// including [cls] itself. | 583 /// including [cls] itself. |
576 int strictSubclassCount(ClassEntity cls) { | 584 int strictSubclassCount(ClassEntity cls) { |
577 assert(_checkClass(cls)); | 585 assert(checkClass(cls)); |
578 ClassHierarchyNode subclasses = _classHierarchyNodes[cls]; | 586 ClassHierarchyNode subclasses = _classHierarchyNodes[cls]; |
579 if (subclasses == null) return 0; | 587 if (subclasses == null) return 0; |
580 return subclasses.instantiatedSubclassCount; | 588 return subclasses.instantiatedSubclassCount; |
581 } | 589 } |
582 | 590 |
583 /// Applies [f] to each live class that extend [cls] _not_ including [cls] | 591 /// Applies [f] to each live class that extend [cls] _not_ including [cls] |
584 /// itself. | 592 /// itself. |
585 void forEachStrictSubclassOf( | 593 void forEachStrictSubclassOf( |
586 ClassEntity cls, IterationStep f(ClassEntity cls)) { | 594 ClassEntity cls, IterationStep f(ClassEntity cls)) { |
587 assert(_checkClass(cls)); | 595 assert(checkClass(cls)); |
588 ClassHierarchyNode subclasses = _classHierarchyNodes[cls]; | 596 ClassHierarchyNode subclasses = _classHierarchyNodes[cls]; |
589 if (subclasses == null) return; | 597 if (subclasses == null) return; |
590 subclasses.forEachSubclass(f, ClassHierarchyNode.EXPLICITLY_INSTANTIATED, | 598 subclasses.forEachSubclass(f, ClassHierarchyNode.EXPLICITLY_INSTANTIATED, |
591 strict: true); | 599 strict: true); |
592 } | 600 } |
593 | 601 |
594 /// Returns `true` if [predicate] applies to any live class that extend [cls] | 602 /// Returns `true` if [predicate] applies to any live class that extend [cls] |
595 /// _not_ including [cls] itself. | 603 /// _not_ including [cls] itself. |
596 bool anyStrictSubclassOf(ClassEntity cls, bool predicate(ClassEntity cls)) { | 604 bool anyStrictSubclassOf(ClassEntity cls, bool predicate(ClassEntity cls)) { |
597 assert(_checkClass(cls)); | 605 assert(checkClass(cls)); |
598 ClassHierarchyNode subclasses = _classHierarchyNodes[cls]; | 606 ClassHierarchyNode subclasses = _classHierarchyNodes[cls]; |
599 if (subclasses == null) return false; | 607 if (subclasses == null) return false; |
600 return subclasses.anySubclass( | 608 return subclasses.anySubclass( |
601 predicate, ClassHierarchyNode.EXPLICITLY_INSTANTIATED, | 609 predicate, ClassHierarchyNode.EXPLICITLY_INSTANTIATED, |
602 strict: true); | 610 strict: true); |
603 } | 611 } |
604 | 612 |
605 /// Returns an iterable over the directly instantiated that implement [cls] | 613 /// Returns an iterable over the directly instantiated that implement [cls] |
606 /// possibly including [cls] itself, if it is live. | 614 /// possibly including [cls] itself, if it is live. |
607 Iterable<ClassEntity> subtypesOf(ClassEntity cls) { | 615 Iterable<ClassEntity> subtypesOf(ClassEntity cls) { |
608 assert(_checkClass(cls)); | 616 assert(checkClass(cls)); |
609 ClassSet classSet = _classSets[cls]; | 617 ClassSet classSet = _classSets[cls]; |
610 if (classSet == null) { | 618 if (classSet == null) { |
611 return const <ClassEntity>[]; | 619 return const <ClassEntity>[]; |
612 } else { | 620 } else { |
613 return classSet | 621 return classSet |
614 .subtypesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED); | 622 .subtypesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED); |
615 } | 623 } |
616 } | 624 } |
617 | 625 |
618 /// Returns an iterable over the directly instantiated that implement [cls] | 626 /// Returns an iterable over the directly instantiated that implement [cls] |
619 /// _not_ including [cls]. | 627 /// _not_ including [cls]. |
620 Iterable<ClassEntity> strictSubtypesOf(ClassEntity cls) { | 628 Iterable<ClassEntity> strictSubtypesOf(ClassEntity cls) { |
621 assert(_checkClass(cls)); | 629 assert(checkClass(cls)); |
622 ClassSet classSet = _classSets[cls]; | 630 ClassSet classSet = _classSets[cls]; |
623 if (classSet == null) { | 631 if (classSet == null) { |
624 return const <ClassEntity>[]; | 632 return const <ClassEntity>[]; |
625 } else { | 633 } else { |
626 return classSet.subtypesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED, | 634 return classSet.subtypesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED, |
627 strict: true); | 635 strict: true); |
628 } | 636 } |
629 } | 637 } |
630 | 638 |
631 /// Returns the number of live classes that implement [cls] _not_ | 639 /// Returns the number of live classes that implement [cls] _not_ |
632 /// including [cls] itself. | 640 /// including [cls] itself. |
633 int strictSubtypeCount(ClassEntity cls) { | 641 int strictSubtypeCount(ClassEntity cls) { |
634 assert(_checkClass(cls)); | 642 assert(checkClass(cls)); |
635 ClassSet classSet = _classSets[cls]; | 643 ClassSet classSet = _classSets[cls]; |
636 if (classSet == null) return 0; | 644 if (classSet == null) return 0; |
637 return classSet.instantiatedSubtypeCount; | 645 return classSet.instantiatedSubtypeCount; |
638 } | 646 } |
639 | 647 |
640 /// Applies [f] to each live class that implements [cls] _not_ including [cls] | 648 /// Applies [f] to each live class that implements [cls] _not_ including [cls] |
641 /// itself. | 649 /// itself. |
642 void forEachStrictSubtypeOf( | 650 void forEachStrictSubtypeOf( |
643 ClassEntity cls, IterationStep f(ClassEntity cls)) { | 651 ClassEntity cls, IterationStep f(ClassEntity cls)) { |
644 assert(_checkClass(cls)); | 652 assert(checkClass(cls)); |
645 ClassSet classSet = _classSets[cls]; | 653 ClassSet classSet = _classSets[cls]; |
646 if (classSet == null) return; | 654 if (classSet == null) return; |
647 classSet.forEachSubtype(f, ClassHierarchyNode.EXPLICITLY_INSTANTIATED, | 655 classSet.forEachSubtype(f, ClassHierarchyNode.EXPLICITLY_INSTANTIATED, |
648 strict: true); | 656 strict: true); |
649 } | 657 } |
650 | 658 |
651 /// Returns `true` if [predicate] applies to any live class that extend [cls] | 659 /// Returns `true` if [predicate] applies to any live class that extend [cls] |
652 /// _not_ including [cls] itself. | 660 /// _not_ including [cls] itself. |
653 bool anyStrictSubtypeOf(ClassEntity cls, bool predicate(ClassEntity cls)) { | 661 bool anyStrictSubtypeOf(ClassEntity cls, bool predicate(ClassEntity cls)) { |
654 assert(_checkClass(cls)); | 662 assert(checkClass(cls)); |
655 ClassSet classSet = _classSets[cls]; | 663 ClassSet classSet = _classSets[cls]; |
656 if (classSet == null) return false; | 664 if (classSet == null) return false; |
657 return classSet.anySubtype( | 665 return classSet.anySubtype( |
658 predicate, ClassHierarchyNode.EXPLICITLY_INSTANTIATED, | 666 predicate, ClassHierarchyNode.EXPLICITLY_INSTANTIATED, |
659 strict: true); | 667 strict: true); |
660 } | 668 } |
661 | 669 |
662 /// Returns `true` if [a] and [b] have any known common subtypes. | 670 /// Returns `true` if [a] and [b] have any known common subtypes. |
663 bool haveAnyCommonSubtypes(ClassEntity a, ClassEntity b) { | 671 bool haveAnyCommonSubtypes(ClassEntity a, ClassEntity b) { |
664 assert(_checkClass(a)); | 672 assert(checkClass(a)); |
665 assert(_checkClass(b)); | 673 assert(checkClass(b)); |
666 ClassSet classSetA = _classSets[a]; | 674 ClassSet classSetA = _classSets[a]; |
667 ClassSet classSetB = _classSets[b]; | 675 ClassSet classSetB = _classSets[b]; |
668 if (classSetA == null || classSetB == null) return false; | 676 if (classSetA == null || classSetB == null) return false; |
669 // TODO(johnniwinther): Implement an optimized query on [ClassSet]. | 677 // TODO(johnniwinther): Implement an optimized query on [ClassSet]. |
670 Set<ClassEntity> subtypesOfB = classSetB.subtypes().toSet(); | 678 Set<ClassEntity> subtypesOfB = classSetB.subtypes().toSet(); |
671 for (ClassEntity subtypeOfA in classSetA.subtypes()) { | 679 for (ClassEntity subtypeOfA in classSetA.subtypes()) { |
672 if (subtypesOfB.contains(subtypeOfA)) { | 680 if (subtypesOfB.contains(subtypeOfA)) { |
673 return true; | 681 return true; |
674 } | 682 } |
675 } | 683 } |
676 return false; | 684 return false; |
677 } | 685 } |
678 | 686 |
679 /// Returns `true` if any directly instantiated class other than [cls] extends | 687 /// Returns `true` if any directly instantiated class other than [cls] extends |
680 /// [cls]. | 688 /// [cls]. |
681 bool hasAnyStrictSubclass(ClassEntity cls) { | 689 bool hasAnyStrictSubclass(ClassEntity cls) { |
682 assert(_checkClass(cls)); | 690 assert(checkClass(cls)); |
683 ClassHierarchyNode subclasses = _classHierarchyNodes[cls]; | 691 ClassHierarchyNode subclasses = _classHierarchyNodes[cls]; |
684 if (subclasses == null) return false; | 692 if (subclasses == null) return false; |
685 return subclasses.isIndirectlyInstantiated; | 693 return subclasses.isIndirectlyInstantiated; |
686 } | 694 } |
687 | 695 |
688 /// Returns `true` if any directly instantiated class other than [cls] | 696 /// Returns `true` if any directly instantiated class other than [cls] |
689 /// implements [cls]. | 697 /// implements [cls]. |
690 bool hasAnyStrictSubtype(ClassEntity cls) { | 698 bool hasAnyStrictSubtype(ClassEntity cls) { |
691 return strictSubtypeCount(cls) > 0; | 699 return strictSubtypeCount(cls) > 0; |
692 } | 700 } |
693 | 701 |
694 /// Returns `true` if all directly instantiated classes that implement [cls] | 702 /// Returns `true` if all directly instantiated classes that implement [cls] |
695 /// extend it. | 703 /// extend it. |
696 bool hasOnlySubclasses(ClassEntity cls) { | 704 bool hasOnlySubclasses(ClassEntity cls) { |
697 assert(_checkClass(cls)); | 705 assert(checkClass(cls)); |
698 // TODO(johnniwinther): move this to ClassSet? | 706 // TODO(johnniwinther): move this to ClassSet? |
699 if (cls == commonElements.objectClass) return true; | 707 if (cls == commonElements.objectClass) return true; |
700 ClassSet classSet = _classSets[cls]; | 708 ClassSet classSet = _classSets[cls]; |
701 if (classSet == null) { | 709 if (classSet == null) { |
702 // Vacuously true. | 710 // Vacuously true. |
703 return true; | 711 return true; |
704 } | 712 } |
705 return classSet.hasOnlyInstantiatedSubclasses; | 713 return classSet.hasOnlyInstantiatedSubclasses; |
706 } | 714 } |
707 | 715 |
708 @override | 716 @override |
709 ClassEntity getLubOfInstantiatedSubclasses(ClassEntity cls) { | 717 ClassEntity getLubOfInstantiatedSubclasses(ClassEntity cls) { |
710 assert(_checkClass(cls)); | 718 assert(checkClass(cls)); |
711 if (nativeData.isJsInteropClass(cls)) { | 719 if (nativeData.isJsInteropClass(cls)) { |
712 return commonElements.jsJavaScriptObjectClass; | 720 return commonElements.jsJavaScriptObjectClass; |
713 } | 721 } |
714 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls]; | 722 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls]; |
715 return hierarchy != null | 723 return hierarchy != null |
716 ? hierarchy.getLubOfInstantiatedSubclasses() | 724 ? hierarchy.getLubOfInstantiatedSubclasses() |
717 : null; | 725 : null; |
718 } | 726 } |
719 | 727 |
720 @override | 728 @override |
721 ClassEntity getLubOfInstantiatedSubtypes(ClassEntity cls) { | 729 ClassEntity getLubOfInstantiatedSubtypes(ClassEntity cls) { |
722 assert(_checkClass(cls)); | 730 assert(checkClass(cls)); |
723 if (nativeData.isJsInteropClass(cls)) { | 731 if (nativeData.isJsInteropClass(cls)) { |
724 return commonElements.jsJavaScriptObjectClass; | 732 return commonElements.jsJavaScriptObjectClass; |
725 } | 733 } |
726 ClassSet classSet = _classSets[cls]; | 734 ClassSet classSet = _classSets[cls]; |
727 return classSet != null ? classSet.getLubOfInstantiatedSubtypes() : null; | 735 return classSet != null ? classSet.getLubOfInstantiatedSubtypes() : null; |
728 } | 736 } |
729 | 737 |
730 Set<ClassEntity> _commonContainedClasses(ClassEntity cls1, ClassQuery query1, | 738 Set<ClassEntity> _commonContainedClasses(ClassEntity cls1, ClassQuery query1, |
731 ClassEntity cls2, ClassQuery query2) { | 739 ClassEntity cls2, ClassQuery query2) { |
732 Iterable<ClassEntity> xSubset = _containedSubset(cls1, query1); | 740 Iterable<ClassEntity> xSubset = _containedSubset(cls1, query1); |
(...skipping 23 matching lines...) Expand all Loading... | |
756 /// Returns `true` if any live class that mixes in [cls] implements [type]. | 764 /// Returns `true` if any live class that mixes in [cls] implements [type]. |
757 bool hasAnySubclassOfMixinUseThatImplements( | 765 bool hasAnySubclassOfMixinUseThatImplements( |
758 ClassEntity cls, ClassEntity type) { | 766 ClassEntity cls, ClassEntity type) { |
759 return mixinUsesOf(cls) | 767 return mixinUsesOf(cls) |
760 .any((use) => hasAnySubclassThatImplements(use, type)); | 768 .any((use) => hasAnySubclassThatImplements(use, type)); |
761 } | 769 } |
762 | 770 |
763 /// Returns `true` if every subtype of [x] is a subclass of [y] or a subclass | 771 /// Returns `true` if every subtype of [x] is a subclass of [y] or a subclass |
764 /// of a mixin application of [y]. | 772 /// of a mixin application of [y]. |
765 bool everySubtypeIsSubclassOfOrMixinUseOf(ClassEntity x, ClassEntity y) { | 773 bool everySubtypeIsSubclassOfOrMixinUseOf(ClassEntity x, ClassEntity y) { |
766 assert(_checkClass(x)); | 774 assert(checkClass(x)); |
767 assert(_checkClass(y)); | 775 assert(checkClass(y)); |
768 Map<ClassEntity, bool> secondMap = | 776 Map<ClassEntity, bool> secondMap = |
769 _subtypeCoveredByCache[x] ??= <ClassEntity, bool>{}; | 777 _subtypeCoveredByCache[x] ??= <ClassEntity, bool>{}; |
770 return secondMap[y] ??= subtypesOf(x).every((ClassEntity cls) => | 778 return secondMap[y] ??= subtypesOf(x).every((ClassEntity cls) => |
771 isSubclassOf(cls, y) || isSubclassOfMixinUseOf(cls, y)); | 779 isSubclassOf(cls, y) || isSubclassOfMixinUseOf(cls, y)); |
772 } | 780 } |
773 | 781 |
774 /// Returns `true` if any subclass of [superclass] implements [type]. | 782 /// Returns `true` if any subclass of [superclass] implements [type]. |
775 bool hasAnySubclassThatImplements(ClassEntity superclass, ClassEntity type) { | 783 bool hasAnySubclassThatImplements(ClassEntity superclass, ClassEntity type) { |
776 assert(_checkClass(superclass)); | 784 assert(checkClass(superclass)); |
777 Set<ClassEntity> subclasses = _typesImplementedBySubclasses[superclass]; | 785 Set<ClassEntity> subclasses = _typesImplementedBySubclasses[superclass]; |
778 if (subclasses == null) return false; | 786 if (subclasses == null) return false; |
779 return subclasses.contains(type); | 787 return subclasses.contains(type); |
780 } | 788 } |
781 | 789 |
782 /// Returns whether a [selector] call on an instance of [cls] | 790 /// Returns whether a [selector] call on an instance of [cls] |
783 /// will hit a method at runtime, and not go through [noSuchMethod]. | 791 /// will hit a method at runtime, and not go through [noSuchMethod]. |
784 bool hasConcreteMatch(ClassEntity cls, Selector selector, | 792 bool hasConcreteMatch(ClassEntity cls, Selector selector, |
785 {ClassEntity stopAtSuperclass}); | 793 {ClassEntity stopAtSuperclass}); |
786 | 794 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
831 return false; | 839 return false; |
832 } | 840 } |
833 } | 841 } |
834 | 842 |
835 /// Returns an iterable over the common supertypes of the [classes]. | 843 /// Returns an iterable over the common supertypes of the [classes]. |
836 Iterable<ClassEntity> commonSupertypesOf(Iterable<ClassEntity> classes) { | 844 Iterable<ClassEntity> commonSupertypesOf(Iterable<ClassEntity> classes) { |
837 Iterator<ClassEntity> iterator = classes.iterator; | 845 Iterator<ClassEntity> iterator = classes.iterator; |
838 if (!iterator.moveNext()) return const <ClassEntity>[]; | 846 if (!iterator.moveNext()) return const <ClassEntity>[]; |
839 | 847 |
840 ClassEntity cls = iterator.current; | 848 ClassEntity cls = iterator.current; |
841 assert(_checkInvariants(cls)); | 849 assert(checkInvariants(cls)); |
842 OrderedTypeSet typeSet = _getOrderedTypeSet(cls); | 850 OrderedTypeSet typeSet = getOrderedTypeSet(cls); |
843 if (!iterator.moveNext()) return typeSet.types.map((type) => type.element); | 851 if (!iterator.moveNext()) return typeSet.types.map((type) => type.element); |
844 | 852 |
845 int depth = typeSet.maxDepth; | 853 int depth = typeSet.maxDepth; |
846 Link<OrderedTypeSet> otherTypeSets = const Link<OrderedTypeSet>(); | 854 Link<OrderedTypeSet> otherTypeSets = const Link<OrderedTypeSet>(); |
847 do { | 855 do { |
848 ClassEntity otherClass = iterator.current; | 856 ClassEntity otherClass = iterator.current; |
849 assert(_checkInvariants(otherClass)); | 857 assert(checkInvariants(otherClass)); |
850 OrderedTypeSet otherTypeSet = _getOrderedTypeSet(otherClass); | 858 OrderedTypeSet otherTypeSet = getOrderedTypeSet(otherClass); |
851 otherTypeSets = otherTypeSets.prepend(otherTypeSet); | 859 otherTypeSets = otherTypeSets.prepend(otherTypeSet); |
852 if (otherTypeSet.maxDepth < depth) { | 860 if (otherTypeSet.maxDepth < depth) { |
853 depth = otherTypeSet.maxDepth; | 861 depth = otherTypeSet.maxDepth; |
854 } | 862 } |
855 } while (iterator.moveNext()); | 863 } while (iterator.moveNext()); |
856 | 864 |
857 List<ClassEntity> commonSupertypes = <ClassEntity>[]; | 865 List<ClassEntity> commonSupertypes = <ClassEntity>[]; |
858 OUTER: | 866 OUTER: |
859 for (Link<InterfaceType> link = typeSet[depth]; | 867 for (Link<InterfaceType> link = typeSet[depth]; |
860 link.head.element != commonElements.objectClass; | 868 link.head.element != commonElements.objectClass; |
861 link = link.tail) { | 869 link = link.tail) { |
862 ClassEntity cls = link.head.element; | 870 ClassEntity cls = link.head.element; |
863 for (Link<OrderedTypeSet> link = otherTypeSets; | 871 for (Link<OrderedTypeSet> link = otherTypeSets; |
864 !link.isEmpty; | 872 !link.isEmpty; |
865 link = link.tail) { | 873 link = link.tail) { |
866 if (link.head.asInstanceOf(cls, _getHierarchyDepth(cls)) == null) { | 874 if (link.head.asInstanceOf(cls, getHierarchyDepth(cls)) == null) { |
867 continue OUTER; | 875 continue OUTER; |
868 } | 876 } |
869 } | 877 } |
870 commonSupertypes.add(cls); | 878 commonSupertypes.add(cls); |
871 } | 879 } |
872 commonSupertypes.add(commonElements.objectClass); | 880 commonSupertypes.add(commonElements.objectClass); |
873 return commonSupertypes; | 881 return commonSupertypes; |
874 } | 882 } |
875 | 883 |
876 Iterable<ClassEntity> commonSubclasses(ClassEntity cls1, ClassQuery query1, | 884 Iterable<ClassEntity> commonSubclasses(ClassEntity cls1, ClassQuery query1, |
877 ClassEntity cls2, ClassQuery query2) { | 885 ClassEntity cls2, ClassQuery query2) { |
878 // TODO(johnniwinther): Use [ClassSet] to compute this. | 886 // TODO(johnniwinther): Use [ClassSet] to compute this. |
879 // Compute the set of classes that are contained in both class subsets. | 887 // Compute the set of classes that are contained in both class subsets. |
880 Set<ClassEntity> common = | 888 Set<ClassEntity> common = |
881 _commonContainedClasses(cls1, query1, cls2, query2); | 889 _commonContainedClasses(cls1, query1, cls2, query2); |
882 if (common == null || common.isEmpty) return const <ClassEntity>[]; | 890 if (common == null || common.isEmpty) return const <ClassEntity>[]; |
883 // Narrow down the candidates by only looking at common classes | 891 // Narrow down the candidates by only looking at common classes |
884 // that do not have a superclass or supertype that will be a | 892 // that do not have a superclass or supertype that will be a |
885 // better candidate. | 893 // better candidate. |
886 return common.where((ClassEntity each) { | 894 return common.where((ClassEntity each) { |
887 bool containsSuperclass = common.contains(_getSuperClass(each)); | 895 bool containsSuperclass = common.contains(getSuperClass(each)); |
888 // If the superclass is also a candidate, then we don't want to | 896 // If the superclass is also a candidate, then we don't want to |
889 // deal with this class. If we're only looking for a subclass we | 897 // deal with this class. If we're only looking for a subclass we |
890 // know we don't have to look at the list of interfaces because | 898 // know we don't have to look at the list of interfaces because |
891 // they can never be in the common set. | 899 // they can never be in the common set. |
892 if (containsSuperclass || | 900 if (containsSuperclass || |
893 query1 == ClassQuery.SUBCLASS || | 901 query1 == ClassQuery.SUBCLASS || |
894 query2 == ClassQuery.SUBCLASS) { | 902 query2 == ClassQuery.SUBCLASS) { |
895 return !containsSuperclass; | 903 return !containsSuperclass; |
896 } | 904 } |
897 // Run through the direct supertypes of the class. If the common | 905 // Run through the direct supertypes of the class. If the common |
898 // set contains the direct supertype of the class, we ignore the | 906 // set contains the direct supertype of the class, we ignore the |
899 // the class because the supertype is a better candidate. | 907 // the class because the supertype is a better candidate. |
900 | 908 |
901 for (ClassEntity interface in _getInterfaces(each)) { | 909 for (ClassEntity interface in getInterfaces(each)) { |
902 if (common.contains(interface)) return false; | 910 if (common.contains(interface)) return false; |
903 } | 911 } |
904 return true; | 912 return true; |
905 }); | 913 }); |
906 } | 914 } |
907 | 915 |
908 /// Returns an iterable over the live mixin applications that mixin [cls]. | 916 /// Returns an iterable over the live mixin applications that mixin [cls]. |
909 Iterable<ClassEntity> mixinUsesOf(ClassEntity cls) { | 917 Iterable<ClassEntity> mixinUsesOf(ClassEntity cls) { |
910 if (_liveMixinUses == null) { | 918 if (_liveMixinUses == null) { |
911 _liveMixinUses = new Map<ClassEntity, List<ClassEntity>>(); | 919 _liveMixinUses = new Map<ClassEntity, List<ClassEntity>>(); |
912 for (ClassEntity mixin in _mixinUses.keys) { | 920 for (ClassEntity mixin in _mixinUses.keys) { |
913 List<ClassEntity> uses = <ClassEntity>[]; | 921 List<ClassEntity> uses = <ClassEntity>[]; |
914 | 922 |
915 void addLiveUse(ClassEntity mixinApplication) { | 923 void addLiveUse(ClassEntity mixinApplication) { |
916 if (isInstantiated(mixinApplication)) { | 924 if (isInstantiated(mixinApplication)) { |
917 uses.add(mixinApplication); | 925 uses.add(mixinApplication); |
918 } else if (_isNamedMixinApplication(mixinApplication)) { | 926 } else if (isNamedMixinApplication(mixinApplication)) { |
919 Set<ClassEntity> next = _mixinUses[mixinApplication]; | 927 Set<ClassEntity> next = _mixinUses[mixinApplication]; |
920 if (next != null) { | 928 if (next != null) { |
921 next.forEach(addLiveUse); | 929 next.forEach(addLiveUse); |
922 } | 930 } |
923 } | 931 } |
924 } | 932 } |
925 | 933 |
926 _mixinUses[mixin].forEach(addLiveUse); | 934 _mixinUses[mixin].forEach(addLiveUse); |
927 if (uses.isNotEmpty) { | 935 if (uses.isNotEmpty) { |
928 _liveMixinUses[mixin] = uses; | 936 _liveMixinUses[mixin] = uses; |
929 } | 937 } |
930 } | 938 } |
931 } | 939 } |
932 Iterable<ClassEntity> uses = _liveMixinUses[cls]; | 940 Iterable<ClassEntity> uses = _liveMixinUses[cls]; |
933 return uses != null ? uses : const <ClassEntity>[]; | 941 return uses != null ? uses : const <ClassEntity>[]; |
934 } | 942 } |
935 | 943 |
936 /// Returns `true` if any live class that mixes in [mixin] is also a subclass | 944 /// Returns `true` if any live class that mixes in [mixin] is also a subclass |
937 /// of [superclass]. | 945 /// of [superclass]. |
938 bool hasAnySubclassThatMixes(ClassEntity superclass, ClassEntity mixin) { | 946 bool hasAnySubclassThatMixes(ClassEntity superclass, ClassEntity mixin) { |
939 return mixinUsesOf(mixin).any((ClassEntity each) { | 947 return mixinUsesOf(mixin).any((ClassEntity each) { |
940 return isSubclassOf(each, superclass); | 948 return isSubclassOf(each, superclass); |
941 }); | 949 }); |
942 } | 950 } |
943 | 951 |
944 /// Returns `true` if [cls] or any superclass mixes in [mixin]. | 952 /// Returns `true` if [cls] or any superclass mixes in [mixin]. |
945 bool isSubclassOfMixinUseOf(ClassEntity cls, ClassEntity mixin) { | 953 bool isSubclassOfMixinUseOf(ClassEntity cls, ClassEntity mixin) { |
946 assert(_checkClass(cls)); | 954 assert(checkClass(cls)); |
947 assert(_checkClass(mixin)); | 955 assert(checkClass(mixin)); |
948 if (isUsedAsMixin(mixin)) { | 956 if (isUsedAsMixin(mixin)) { |
949 ClassEntity current = cls; | 957 ClassEntity current = cls; |
950 while (current != null) { | 958 while (current != null) { |
951 ClassEntity currentMixin = _getAppliedMixin(current); | 959 ClassEntity currentMixin = getAppliedMixin(current); |
952 if (currentMixin == mixin) return true; | 960 if (currentMixin == mixin) return true; |
953 current = _getSuperClass(current); | 961 current = getSuperClass(current); |
954 } | 962 } |
955 } | 963 } |
956 return false; | 964 return false; |
957 } | 965 } |
958 | 966 |
959 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies | 967 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies |
960 /// of known classes. | 968 /// of known classes. |
961 /// | 969 /// |
962 /// This method is only provided for testing. For queries on classes, use the | 970 /// This method is only provided for testing. For queries on classes, use the |
963 /// methods defined in [ClosedWorld]. | 971 /// methods defined in [ClosedWorld]. |
964 ClassHierarchyNode getClassHierarchyNode(ClassEntity cls) { | 972 ClassHierarchyNode getClassHierarchyNode(ClassEntity cls) { |
965 assert(_checkClass(cls)); | 973 assert(checkClass(cls)); |
966 return _classHierarchyNodes[cls]; | 974 return _classHierarchyNodes[cls]; |
967 } | 975 } |
968 | 976 |
969 /// Returns [ClassSet] for [cls] used to model the extends and implements | 977 /// Returns [ClassSet] for [cls] used to model the extends and implements |
970 /// relations of known classes. | 978 /// relations of known classes. |
971 /// | 979 /// |
972 /// This method is only provided for testing. For queries on classes, use the | 980 /// This method is only provided for testing. For queries on classes, use the |
973 /// methods defined in [ClosedWorld]. | 981 /// methods defined in [ClosedWorld]. |
974 ClassSet getClassSet(ClassEntity cls) { | 982 ClassSet getClassSet(ClassEntity cls) { |
975 assert(_checkClass(cls)); | 983 assert(checkClass(cls)); |
976 return _classSets[cls]; | 984 return _classSets[cls]; |
977 } | 985 } |
978 | 986 |
979 Iterable<TypedefElement> get allTypedefs => _allTypedefs; | 987 Iterable<TypedefElement> get allTypedefs => _allTypedefs; |
980 | 988 |
981 TypeMask computeReceiverType(Selector selector, TypeMask mask) { | 989 TypeMask computeReceiverType(Selector selector, TypeMask mask) { |
982 return _allFunctions.receiverType(selector, mask, this); | 990 return _allFunctions.receiverType(selector, mask, this); |
983 } | 991 } |
984 | 992 |
985 Iterable<MemberEntity> locateMembers(Selector selector, TypeMask mask) { | 993 Iterable<MemberEntity> locateMembers(Selector selector, TypeMask mask) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1049 sideEffects.setDependsOnSomething(); | 1057 sideEffects.setDependsOnSomething(); |
1050 } | 1058 } |
1051 } else { | 1059 } else { |
1052 sideEffects.add(getSideEffectsOfElement(e)); | 1060 sideEffects.add(getSideEffectsOfElement(e)); |
1053 } | 1061 } |
1054 } | 1062 } |
1055 return sideEffects; | 1063 return sideEffects; |
1056 } | 1064 } |
1057 | 1065 |
1058 SideEffects getSideEffectsOfElement(Entity element) { | 1066 SideEffects getSideEffectsOfElement(Entity element) { |
1059 assert(_checkEntity(element)); | 1067 assert(checkEntity(element)); |
1060 return _sideEffects.putIfAbsent(element, _makeSideEffects); | 1068 return _sideEffects.putIfAbsent(element, _makeSideEffects); |
1061 } | 1069 } |
1062 | 1070 |
1063 static _makeSideEffects() => new SideEffects(); | 1071 static _makeSideEffects() => new SideEffects(); |
1064 | 1072 |
1065 @override | 1073 @override |
1066 SideEffects getCurrentlyKnownSideEffects(Entity element) { | 1074 SideEffects getCurrentlyKnownSideEffects(Entity element) { |
1067 return getSideEffectsOfElement(element); | 1075 return getSideEffectsOfElement(element); |
1068 } | 1076 } |
1069 | 1077 |
1070 void registerSideEffects(Entity element, SideEffects effects) { | 1078 void registerSideEffects(Entity element, SideEffects effects) { |
1071 assert(_checkEntity(element)); | 1079 assert(checkEntity(element)); |
1072 if (_sideEffectsFreeElements.contains(element)) return; | 1080 if (_sideEffectsFreeElements.contains(element)) return; |
1073 _sideEffects[element] = effects; | 1081 _sideEffects[element] = effects; |
1074 } | 1082 } |
1075 | 1083 |
1076 void registerSideEffectsFree(Entity element) { | 1084 void registerSideEffectsFree(Entity element) { |
1077 assert(_checkEntity(element)); | 1085 assert(checkEntity(element)); |
1078 _sideEffects[element] = new SideEffects.empty(); | 1086 _sideEffects[element] = new SideEffects.empty(); |
1079 _sideEffectsFreeElements.add(element); | 1087 _sideEffectsFreeElements.add(element); |
1080 } | 1088 } |
1081 | 1089 |
1082 void addFunctionCalledInLoop(Entity element) { | 1090 void addFunctionCalledInLoop(Entity element) { |
1083 assert(_checkEntity(element)); | 1091 assert(checkEntity(element)); |
1084 _functionsCalledInLoop.add(element); | 1092 _functionsCalledInLoop.add(element); |
1085 } | 1093 } |
1086 | 1094 |
1087 bool isCalledInLoop(Entity element) { | 1095 bool isCalledInLoop(Entity element) { |
1088 assert(_checkEntity(element)); | 1096 assert(checkEntity(element)); |
1089 return _functionsCalledInLoop.contains(element); | 1097 return _functionsCalledInLoop.contains(element); |
1090 } | 1098 } |
1091 | 1099 |
1092 void registerCannotThrow(Entity element) { | 1100 void registerCannotThrow(Entity element) { |
1093 assert(_checkEntity(element)); | 1101 assert(checkEntity(element)); |
1094 _elementsThatCannotThrow.add(element); | 1102 _elementsThatCannotThrow.add(element); |
1095 } | 1103 } |
1096 | 1104 |
1097 bool getCannotThrow(Entity element) { | 1105 bool getCannotThrow(Entity element) { |
1098 return _elementsThatCannotThrow.contains(element); | 1106 return _elementsThatCannotThrow.contains(element); |
1099 } | 1107 } |
1100 | 1108 |
1101 void registerMightBePassedToApply(Entity element) { | 1109 void registerMightBePassedToApply(Entity element) { |
1102 _functionsThatMightBePassedToApply.add(element); | 1110 _functionsThatMightBePassedToApply.add(element); |
1103 } | 1111 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1159 interceptorData: interceptorData, | 1167 interceptorData: interceptorData, |
1160 backendUsage: backendUsage, | 1168 backendUsage: backendUsage, |
1161 resolutionWorldBuilder: resolutionWorldBuilder, | 1169 resolutionWorldBuilder: resolutionWorldBuilder, |
1162 functionSet: functionSet, | 1170 functionSet: functionSet, |
1163 allTypedefs: allTypedefs, | 1171 allTypedefs: allTypedefs, |
1164 mixinUses: mixinUses, | 1172 mixinUses: mixinUses, |
1165 typesImplementedBySubclasses: typesImplementedBySubclasses, | 1173 typesImplementedBySubclasses: typesImplementedBySubclasses, |
1166 classHierarchyNodes: classHierarchyNodes, | 1174 classHierarchyNodes: classHierarchyNodes, |
1167 classSets: classSets); | 1175 classSets: classSets); |
1168 | 1176 |
1169 bool _checkClass(ClassElement cls) => cls.isDeclaration; | 1177 bool checkClass(ClassElement cls) => cls.isDeclaration; |
1170 | 1178 |
1171 bool _checkEntity(Element element) => element.isDeclaration; | 1179 bool checkEntity(Element element) => element.isDeclaration; |
1172 | 1180 |
1173 bool _checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { | 1181 bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { |
1174 assert(cls.isDeclaration, failedAt(cls, '$cls must be the declaration.')); | 1182 assert(cls.isDeclaration, failedAt(cls, '$cls must be the declaration.')); |
1175 assert(cls.isResolved, failedAt(cls, '$cls must be resolved.')); | 1183 assert(cls.isResolved, failedAt(cls, '$cls must be resolved.')); |
1176 | 1184 |
1177 // TODO(johnniwinther): Reinsert this or similar invariant. Currently | 1185 // TODO(johnniwinther): Reinsert this or similar invariant. Currently |
1178 // various call sites use uninstantiated classes for isSubtypeOf or | 1186 // various call sites use uninstantiated classes for isSubtypeOf or |
1179 // isSubclassOf. Some are valid, some are not. Work out better invariants | 1187 // isSubclassOf. Some are valid, some are not. Work out better invariants |
1180 // to catch the latter. | 1188 // to catch the latter. |
1181 // if (mustBeInstantiated) { | 1189 // if (mustBeInstantiated) { |
1182 // assert(isInstantiated(cls), failedAt(cls, '$cls is not instantiated.')); | 1190 // assert(isInstantiated(cls), failedAt(cls, '$cls is not instantiated.')); |
1183 // } | 1191 // } |
1184 return true; | 1192 return true; |
1185 } | 1193 } |
1186 | 1194 |
1187 OrderedTypeSet _getOrderedTypeSet(ClassElement cls) => | 1195 OrderedTypeSet getOrderedTypeSet(ClassElement cls) => |
1188 cls.allSupertypesAndSelf; | 1196 cls.allSupertypesAndSelf; |
1189 | 1197 |
1190 int _getHierarchyDepth(ClassElement cls) => cls.hierarchyDepth; | 1198 int getHierarchyDepth(ClassElement cls) => cls.hierarchyDepth; |
1191 | 1199 |
1192 ClassEntity _getSuperClass(ClassElement cls) => cls.superclass; | 1200 ClassEntity getSuperClass(ClassElement cls) => cls.superclass; |
1193 | 1201 |
1194 Iterable<ClassEntity> _getInterfaces(ClassElement cls) sync* { | 1202 Iterable<ClassEntity> getInterfaces(ClassElement cls) sync* { |
1195 for (Link link = cls.interfaces; !link.isEmpty; link = link.tail) { | 1203 for (Link link = cls.interfaces; !link.isEmpty; link = link.tail) { |
1196 yield link.head.element; | 1204 yield link.head.element; |
1197 } | 1205 } |
1198 } | 1206 } |
1199 | 1207 |
1200 bool _isNamedMixinApplication(ClassElement cls) => | 1208 bool isNamedMixinApplication(ClassElement cls) => cls.isNamedMixinApplication; |
1201 cls.isNamedMixinApplication; | |
1202 | 1209 |
1203 ClassEntity _getAppliedMixin(ClassElement cls) { | 1210 ClassEntity getAppliedMixin(ClassElement cls) { |
1204 if (cls.isMixinApplication) { | 1211 if (cls.isMixinApplication) { |
1205 MixinApplicationElement application = cls; | 1212 MixinApplicationElement application = cls; |
1206 return application.mixin; | 1213 return application.mixin; |
1207 } | 1214 } |
1208 return null; | 1215 return null; |
1209 } | 1216 } |
1210 | 1217 |
1211 @override | 1218 @override |
1212 bool hasElementIn(ClassEntity cls, Selector selector, Element element) { | 1219 bool hasElementIn(ClassEntity cls, Selector selector, Element element) { |
1213 // Use [:implementation:] of [element] | 1220 // Use [:implementation:] of [element] |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1274 // does not see generative constructor bodies because they are | 1281 // does not see generative constructor bodies because they are |
1275 // created by the backend. Also, it does not make any distinction | 1282 // created by the backend. Also, it does not make any distinction |
1276 // between a constructor and its body for side effects. This | 1283 // between a constructor and its body for side effects. This |
1277 // implies that currently, the side effects of a constructor body | 1284 // implies that currently, the side effects of a constructor body |
1278 // contain the side effects of the initializers. | 1285 // contain the side effects of the initializers. |
1279 assert(!element.isGenerativeConstructorBody); | 1286 assert(!element.isGenerativeConstructorBody); |
1280 assert(!element.isField); | 1287 assert(!element.isField); |
1281 return super.getSideEffectsOfElement(element); | 1288 return super.getSideEffectsOfElement(element); |
1282 } | 1289 } |
1283 } | 1290 } |
1284 | |
1285 class KernelClosedWorld extends ClosedWorldBase { | |
1286 KernelClosedWorld( | |
1287 {CommonElements commonElements, | |
1288 ConstantSystem constantSystem, | |
1289 NativeData nativeData, | |
1290 InterceptorData interceptorData, | |
1291 BackendUsage backendUsage, | |
1292 ResolutionWorldBuilder resolutionWorldBuilder, | |
1293 FunctionSet functionSet, | |
1294 Iterable<TypedefElement> allTypedefs, | |
1295 Map<ClassEntity, Set<ClassEntity>> mixinUses, | |
1296 Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses, | |
1297 Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes, | |
1298 Map<ClassEntity, ClassSet> classSets}) | |
1299 : super( | |
1300 commonElements: commonElements, | |
1301 constantSystem: constantSystem, | |
1302 nativeData: nativeData, | |
1303 interceptorData: interceptorData, | |
1304 backendUsage: backendUsage, | |
1305 resolutionWorldBuilder: resolutionWorldBuilder, | |
1306 functionSet: functionSet, | |
1307 allTypedefs: allTypedefs, | |
1308 mixinUses: mixinUses, | |
1309 typesImplementedBySubclasses: typesImplementedBySubclasses, | |
1310 classHierarchyNodes: classHierarchyNodes, | |
1311 classSets: classSets); | |
1312 | |
1313 @override | |
1314 bool hasConcreteMatch(ClassEntity cls, Selector selector, | |
1315 {ClassEntity stopAtSuperclass}) { | |
1316 throw new UnimplementedError('KernelClosedWorld.hasConcreteMatch'); | |
1317 } | |
1318 | |
1319 @override | |
1320 bool _isNamedMixinApplication(ClassEntity cls) { | |
1321 throw new UnimplementedError('KernelClosedWorld._isNamedMixinApplication'); | |
1322 } | |
1323 | |
1324 @override | |
1325 ClassEntity _getAppliedMixin(ClassEntity cls) { | |
1326 throw new UnimplementedError('KernelClosedWorld._getAppliedMixin'); | |
1327 } | |
1328 | |
1329 @override | |
1330 Iterable<ClassEntity> _getInterfaces(ClassEntity cls) { | |
1331 throw new UnimplementedError('KernelClosedWorld._getInterfaces'); | |
1332 } | |
1333 | |
1334 @override | |
1335 ClassEntity _getSuperClass(ClassEntity cls) { | |
1336 throw new UnimplementedError('KernelClosedWorld._getSuperClass'); | |
1337 } | |
1338 | |
1339 @override | |
1340 int _getHierarchyDepth(ClassEntity cls) { | |
1341 throw new UnimplementedError('KernelClosedWorld._getHierarchyDepth'); | |
1342 } | |
1343 | |
1344 @override | |
1345 OrderedTypeSet _getOrderedTypeSet(ClassEntity cls) { | |
1346 throw new UnimplementedError('KernelClosedWorld._getOrderedTypeSet'); | |
1347 } | |
1348 | |
1349 @override | |
1350 bool _checkInvariants(ClassEntity cls, {bool mustBeInstantiated: true}) => | |
1351 true; | |
1352 | |
1353 @override | |
1354 bool _checkClass(ClassEntity cls) => true; | |
1355 | |
1356 @override | |
1357 bool _checkEntity(Entity element) => true; | |
1358 | |
1359 @override | |
1360 void registerClosureClass(ClassElement cls) { | |
1361 throw new UnimplementedError('KernelClosedWorld.registerClosureClass'); | |
1362 } | |
1363 | |
1364 @override | |
1365 bool hasElementIn(ClassEntity cls, Selector selector, Entity element) { | |
1366 throw new UnimplementedError('KernelClosedWorld.hasElementIn'); | |
1367 } | |
1368 } | |
OLD | NEW |