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 universe; | 5 library universe; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import '../cache_strategy.dart'; | 9 import '../cache_strategy.dart'; |
10 import '../common.dart'; | 10 import '../common.dart'; |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 final Map<String, Map<Selector, SelectorConstraints>> _invokedNames = | 368 final Map<String, Map<Selector, SelectorConstraints>> _invokedNames = |
369 <String, Map<Selector, SelectorConstraints>>{}; | 369 <String, Map<Selector, SelectorConstraints>>{}; |
370 final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters = | 370 final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters = |
371 <String, Map<Selector, SelectorConstraints>>{}; | 371 <String, Map<Selector, SelectorConstraints>>{}; |
372 final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters = | 372 final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters = |
373 <String, Map<Selector, SelectorConstraints>>{}; | 373 <String, Map<Selector, SelectorConstraints>>{}; |
374 | 374 |
375 final Map<ClassElement, _ClassUsage> _processedClasses = | 375 final Map<ClassElement, _ClassUsage> _processedClasses = |
376 <ClassElement, _ClassUsage>{}; | 376 <ClassElement, _ClassUsage>{}; |
377 | 377 |
378 /// Map of registers usage of instance members of live classes. | 378 /// Map of registered usage of static members of live classes. |
| 379 final Map<Entity, _StaticMemberUsage> _staticMemberUsage = |
| 380 <Entity, _StaticMemberUsage>{}; |
| 381 |
| 382 /// Map of registered usage of instance members of live classes. |
379 final Map<MemberEntity, _MemberUsage> _instanceMemberUsage = | 383 final Map<MemberEntity, _MemberUsage> _instanceMemberUsage = |
380 <MemberEntity, _MemberUsage>{}; | 384 <MemberEntity, _MemberUsage>{}; |
381 | 385 |
382 /// Map containing instance members of live classes that are not yet live | 386 /// Map containing instance members of live classes that are not yet live |
383 /// themselves. | 387 /// themselves. |
384 final Map<String, Set<_MemberUsage>> _instanceMembersByName = | 388 final Map<String, Set<_MemberUsage>> _instanceMembersByName = |
385 <String, Set<_MemberUsage>>{}; | 389 <String, Set<_MemberUsage>>{}; |
386 | 390 |
387 /// Map containing instance methods of live classes that are not yet | 391 /// Map containing instance methods of live classes that are not yet |
388 /// closurized. | 392 /// closurized. |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 | 616 |
613 bool _hasInvokedGetter(Element member) { | 617 bool _hasInvokedGetter(Element member) { |
614 return _hasMatchingSelector(_invokedGetters[member.name], member) || | 618 return _hasMatchingSelector(_invokedGetters[member.name], member) || |
615 member.isFunction && methodsNeedingSuperGetter.contains(member); | 619 member.isFunction && methodsNeedingSuperGetter.contains(member); |
616 } | 620 } |
617 | 621 |
618 bool hasInvokedSetter(Element member) { | 622 bool hasInvokedSetter(Element member) { |
619 return _hasMatchingSelector(_invokedSetters[member.name], member); | 623 return _hasMatchingSelector(_invokedSetters[member.name], member); |
620 } | 624 } |
621 | 625 |
622 void registerDynamicUse(DynamicUse dynamicUse, MemberUsed memberUsed) { | 626 void registerDynamicUse( |
| 627 DynamicUse dynamicUse, MemberUsedCallback memberUsed) { |
623 Selector selector = dynamicUse.selector; | 628 Selector selector = dynamicUse.selector; |
624 String methodName = selector.name; | 629 String methodName = selector.name; |
625 switch (dynamicUse.kind) { | 630 switch (dynamicUse.kind) { |
626 case DynamicUseKind.INVOKE: | 631 case DynamicUseKind.INVOKE: |
627 if (_registerNewSelector(dynamicUse, _invokedNames)) { | 632 if (_registerNewSelector(dynamicUse, _invokedNames)) { |
628 _processInstanceMembers(methodName, (_MemberUsage usage) { | 633 _processInstanceMembers(methodName, (_MemberUsage usage) { |
629 if (dynamicUse.appliesUnnamed(usage.entity, _openWorld)) { | 634 if (dynamicUse.appliesUnnamed(usage.entity, _openWorld)) { |
630 memberUsed(usage.entity, usage.invoke()); | 635 memberUsed(usage.entity, usage.invoke()); |
631 return true; | 636 return true; |
632 } | 637 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 DartType registerIsCheck(DartType type, Resolution resolution) { | 688 DartType registerIsCheck(DartType type, Resolution resolution) { |
684 type.computeUnaliased(resolution); | 689 type.computeUnaliased(resolution); |
685 type = type.unaliased; | 690 type = type.unaliased; |
686 // Even in checked mode, type annotations for return type and argument | 691 // Even in checked mode, type annotations for return type and argument |
687 // types do not imply type checks, so there should never be a check | 692 // types do not imply type checks, so there should never be a check |
688 // against the type variable of a typedef. | 693 // against the type variable of a typedef. |
689 isChecks.add(type); | 694 isChecks.add(type); |
690 return type; | 695 return type; |
691 } | 696 } |
692 | 697 |
693 void registerStaticUse(StaticUse staticUse) { | 698 void registerStaticUse(StaticUse staticUse, MemberUsedCallback memberUsed) { |
694 Element element = staticUse.element; | 699 Element element = staticUse.element; |
| 700 assert(invariant(element, element.isDeclaration, |
| 701 message: "Element ${element} is not the declaration.")); |
| 702 _StaticMemberUsage usage = _staticMemberUsage.putIfAbsent(element, () { |
| 703 if ((element.isStatic || element.isTopLevel) && element.isFunction) { |
| 704 return new _StaticFunctionUsage(element); |
| 705 } else { |
| 706 return new _GeneralStaticMemberUsage(element); |
| 707 } |
| 708 }); |
| 709 EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); |
| 710 |
695 if (Elements.isStaticOrTopLevel(element) && element.isField) { | 711 if (Elements.isStaticOrTopLevel(element) && element.isField) { |
696 allReferencedStaticFields.add(element); | 712 allReferencedStaticFields.add(element); |
697 } | 713 } |
| 714 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and |
| 715 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. |
| 716 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot |
| 717 // enqueue. |
698 switch (staticUse.kind) { | 718 switch (staticUse.kind) { |
699 case StaticUseKind.SUPER_FIELD_SET: | 719 case StaticUseKind.FIELD_GET: |
| 720 break; |
700 case StaticUseKind.FIELD_SET: | 721 case StaticUseKind.FIELD_SET: |
701 fieldSetters.add(element); | 722 fieldSetters.add(element); |
702 break; | 723 break; |
| 724 case StaticUseKind.CLOSURE: |
| 725 LocalFunctionElement closure = staticUse.element; |
| 726 if (closure.type.containsTypeVariables) { |
| 727 closuresWithFreeTypeVariables.add(closure); |
| 728 } |
| 729 allClosures.add(element); |
| 730 break; |
703 case StaticUseKind.SUPER_TEAR_OFF: | 731 case StaticUseKind.SUPER_TEAR_OFF: |
| 732 useSet.addAll(usage.tearOff()); |
704 methodsNeedingSuperGetter.add(element); | 733 methodsNeedingSuperGetter.add(element); |
705 break; | 734 break; |
| 735 case StaticUseKind.SUPER_FIELD_SET: |
| 736 fieldSetters.add(element); |
| 737 useSet.addAll(usage.normalUse()); |
| 738 break; |
| 739 case StaticUseKind.STATIC_TEAR_OFF: |
| 740 useSet.addAll(usage.tearOff()); |
| 741 break; |
706 case StaticUseKind.GENERAL: | 742 case StaticUseKind.GENERAL: |
707 case StaticUseKind.DIRECT_USE: | 743 case StaticUseKind.DIRECT_USE: |
708 case StaticUseKind.STATIC_TEAR_OFF: | |
709 case StaticUseKind.FIELD_GET: | |
710 case StaticUseKind.CONSTRUCTOR_INVOKE: | 744 case StaticUseKind.CONSTRUCTOR_INVOKE: |
711 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: | 745 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: |
712 case StaticUseKind.REDIRECTION: | 746 case StaticUseKind.REDIRECTION: |
713 break; | 747 useSet.addAll(usage.normalUse()); |
714 case StaticUseKind.CLOSURE: | |
715 allClosures.add(element); | |
716 break; | 748 break; |
717 case StaticUseKind.DIRECT_INVOKE: | 749 case StaticUseKind.DIRECT_INVOKE: |
718 invariant( | 750 invariant( |
719 element, 'Direct static use is not supported for resolution.'); | 751 element, 'Direct static use is not supported for resolution.'); |
720 break; | 752 break; |
721 } | 753 } |
| 754 if (useSet.isNotEmpty) { |
| 755 memberUsed(usage.entity, useSet); |
| 756 } |
722 } | 757 } |
723 | 758 |
724 void forgetEntity(Entity entity, Compiler compiler) { | 759 void forgetEntity(Entity entity, Compiler compiler) { |
725 allClosures.remove(entity); | 760 allClosures.remove(entity); |
726 slowDirectlyNestedClosures(entity).forEach(compiler.forgetElement); | 761 slowDirectlyNestedClosures(entity).forEach(compiler.forgetElement); |
727 closurizedMembers.remove(entity); | 762 closurizedMembers.remove(entity); |
728 fieldSetters.remove(entity); | 763 fieldSetters.remove(entity); |
729 _instantiationInfo.remove(entity); | 764 _instantiationInfo.remove(entity); |
730 | 765 |
731 void removeUsage(Set<_MemberUsage> set, Entity entity) { | 766 void removeUsage(Set<_MemberUsage> set, Entity entity) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 return false; | 808 return false; |
774 } | 809 } |
775 | 810 |
776 while (cls != null && processClass(cls)) { | 811 while (cls != null && processClass(cls)) { |
777 cls = cls.superclass; | 812 cls = cls.superclass; |
778 } | 813 } |
779 } | 814 } |
780 | 815 |
781 /// Computes usage for all members declared by [cls]. Calls [membersUsed] with | 816 /// Computes usage for all members declared by [cls]. Calls [membersUsed] with |
782 /// the usage changes for each member. | 817 /// the usage changes for each member. |
783 void processClassMembers(ClassElement cls, MemberUsed memberUsed) { | 818 void processClassMembers(ClassElement cls, MemberUsedCallback memberUsed) { |
784 cls.implementation.forEachMember((ClassElement cls, MemberElement member) { | 819 cls.implementation.forEachMember((ClassElement cls, MemberElement member) { |
785 _processInstantiatedClassMember(cls, member, memberUsed); | 820 _processInstantiatedClassMember(cls, member, memberUsed); |
786 }); | 821 }); |
787 } | 822 } |
788 | 823 |
789 /// Call [updateUsage] on all [MemberUsage]s in the set in [map] for | 824 /// Call [updateUsage] on all [MemberUsage]s in the set in [map] for |
790 /// [memberName]. If [updateUsage] returns `true` the usage is removed from | 825 /// [memberName]. If [updateUsage] returns `true` the usage is removed from |
791 /// the set. | 826 /// the set. |
792 void _processSet(Map<String, Set<_MemberUsage>> map, String memberName, | 827 void _processSet(Map<String, Set<_MemberUsage>> map, String memberName, |
793 bool updateUsage(_MemberUsage e)) { | 828 bool updateUsage(_MemberUsage e)) { |
(...skipping 13 matching lines...) Expand all Loading... |
807 void _processInstanceMembers(String name, bool updateUsage(_MemberUsage e)) { | 842 void _processInstanceMembers(String name, bool updateUsage(_MemberUsage e)) { |
808 _processSet(_instanceMembersByName, name, updateUsage); | 843 _processSet(_instanceMembersByName, name, updateUsage); |
809 } | 844 } |
810 | 845 |
811 void _processInstanceFunctions( | 846 void _processInstanceFunctions( |
812 String name, bool updateUsage(_MemberUsage e)) { | 847 String name, bool updateUsage(_MemberUsage e)) { |
813 _processSet(_instanceFunctionsByName, name, updateUsage); | 848 _processSet(_instanceFunctionsByName, name, updateUsage); |
814 } | 849 } |
815 | 850 |
816 void _processInstantiatedClassMember( | 851 void _processInstantiatedClassMember( |
817 ClassElement cls, MemberElement member, MemberUsed memberUsed) { | 852 ClassElement cls, MemberElement member, MemberUsedCallback memberUsed) { |
818 assert(invariant(member, member.isDeclaration)); | 853 assert(invariant(member, member.isDeclaration)); |
819 if (!member.isInstanceMember) return; | 854 if (!member.isInstanceMember) return; |
820 String memberName = member.name; | 855 String memberName = member.name; |
821 member.computeType(_resolution); | 856 member.computeType(_resolution); |
822 EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); | 857 EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); |
823 // The obvious thing to test here would be "member.isNative", | 858 // The obvious thing to test here would be "member.isNative", |
824 // however, that only works after metadata has been parsed/analyzed, | 859 // however, that only works after metadata has been parsed/analyzed, |
825 // and that may not have happened yet. | 860 // and that may not have happened yet. |
826 // So instead we use the enclosing class, which we know have had | 861 // So instead we use the enclosing class, which we know have had |
827 // its metadata parsed and analyzed. | 862 // its metadata parsed and analyzed. |
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1394 /// Common [EnumSet]s used for [MemberUse]. | 1429 /// Common [EnumSet]s used for [MemberUse]. |
1395 class MemberUses { | 1430 class MemberUses { |
1396 static const EnumSet<MemberUse> NONE = const EnumSet<MemberUse>.fixed(0); | 1431 static const EnumSet<MemberUse> NONE = const EnumSet<MemberUse>.fixed(0); |
1397 static const EnumSet<MemberUse> NORMAL_ONLY = | 1432 static const EnumSet<MemberUse> NORMAL_ONLY = |
1398 const EnumSet<MemberUse>.fixed(1); | 1433 const EnumSet<MemberUse>.fixed(1); |
1399 static const EnumSet<MemberUse> CLOSURIZE_ONLY = | 1434 static const EnumSet<MemberUse> CLOSURIZE_ONLY = |
1400 const EnumSet<MemberUse>.fixed(2); | 1435 const EnumSet<MemberUse>.fixed(2); |
1401 static const EnumSet<MemberUse> ALL = const EnumSet<MemberUse>.fixed(3); | 1436 static const EnumSet<MemberUse> ALL = const EnumSet<MemberUse>.fixed(3); |
1402 } | 1437 } |
1403 | 1438 |
1404 typedef void MemberUsed(MemberEntity member, EnumSet<MemberUse> useSet); | 1439 typedef void MemberUsedCallback(MemberEntity member, EnumSet<MemberUse> useSet); |
1405 | 1440 |
1406 /// Registry for the observed use of a class [entity] in the open world. | 1441 /// Registry for the observed use of a class [entity] in the open world. |
1407 // TODO(johnniwinther): Merge this with [InstantiationInfo]. | 1442 // TODO(johnniwinther): Merge this with [InstantiationInfo]. |
1408 class _ClassUsage extends _AbstractUsage<ClassUse> { | 1443 class _ClassUsage extends _AbstractUsage<ClassUse> { |
1409 bool isInstantiated = false; | 1444 bool isInstantiated = false; |
1410 bool isImplemented = false; | 1445 bool isImplemented = false; |
1411 | 1446 |
1412 final ClassEntity cls; | 1447 final ClassEntity cls; |
1413 | 1448 |
1414 _ClassUsage(this.cls); | 1449 _ClassUsage(this.cls); |
(...skipping 27 matching lines...) Expand all Loading... |
1442 class ClassUses { | 1477 class ClassUses { |
1443 static const EnumSet<ClassUse> NONE = const EnumSet<ClassUse>.fixed(0); | 1478 static const EnumSet<ClassUse> NONE = const EnumSet<ClassUse>.fixed(0); |
1444 static const EnumSet<ClassUse> INSTANTIATED_ONLY = | 1479 static const EnumSet<ClassUse> INSTANTIATED_ONLY = |
1445 const EnumSet<ClassUse>.fixed(1); | 1480 const EnumSet<ClassUse>.fixed(1); |
1446 static const EnumSet<ClassUse> IMPLEMENTED_ONLY = | 1481 static const EnumSet<ClassUse> IMPLEMENTED_ONLY = |
1447 const EnumSet<ClassUse>.fixed(2); | 1482 const EnumSet<ClassUse>.fixed(2); |
1448 static const EnumSet<ClassUse> ALL = const EnumSet<ClassUse>.fixed(3); | 1483 static const EnumSet<ClassUse> ALL = const EnumSet<ClassUse>.fixed(3); |
1449 } | 1484 } |
1450 | 1485 |
1451 typedef void ClassUsed(ClassEntity cls, EnumSet<ClassUse> useSet); | 1486 typedef void ClassUsed(ClassEntity cls, EnumSet<ClassUse> useSet); |
| 1487 |
| 1488 // TODO(johnniwinther): Merge this with [_MemberUsage]. |
| 1489 abstract class _StaticMemberUsage extends _AbstractUsage<MemberUse> { |
| 1490 final Entity entity; |
| 1491 |
| 1492 bool hasNormalUse = false; |
| 1493 bool get hasClosurization => false; |
| 1494 |
| 1495 _StaticMemberUsage.internal(this.entity); |
| 1496 |
| 1497 EnumSet<MemberUse> normalUse() { |
| 1498 if (hasNormalUse) { |
| 1499 return MemberUses.NONE; |
| 1500 } |
| 1501 hasNormalUse = true; |
| 1502 return _pendingUse.removeAll(MemberUses.NORMAL_ONLY); |
| 1503 } |
| 1504 |
| 1505 EnumSet<MemberUse> tearOff(); |
| 1506 |
| 1507 @override |
| 1508 EnumSet<MemberUse> get _originalUse => MemberUses.NORMAL_ONLY; |
| 1509 |
| 1510 String toString() => entity.toString(); |
| 1511 } |
| 1512 |
| 1513 class _GeneralStaticMemberUsage extends _StaticMemberUsage { |
| 1514 _GeneralStaticMemberUsage(Entity entity) : super.internal(entity); |
| 1515 |
| 1516 EnumSet<MemberUse> tearOff() => normalUse(); |
| 1517 } |
| 1518 |
| 1519 class _StaticFunctionUsage extends _StaticMemberUsage { |
| 1520 bool hasClosurization = false; |
| 1521 |
| 1522 _StaticFunctionUsage(Entity entity) : super.internal(entity); |
| 1523 |
| 1524 EnumSet<MemberUse> tearOff() { |
| 1525 if (hasClosurization) { |
| 1526 return MemberUses.NONE; |
| 1527 } |
| 1528 hasNormalUse = hasClosurization = true; |
| 1529 return _pendingUse.removeAll(MemberUses.ALL); |
| 1530 } |
| 1531 |
| 1532 @override |
| 1533 EnumSet<MemberUse> get _originalUse => MemberUses.ALL; |
| 1534 } |
OLD | NEW |