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