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

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

Issue 2545413002: Move processing of instantiated classes from ResolutionEnqueuer to ResolutionWorldBuilderImpl (Closed)
Patch Set: Updated cf. comments Created 4 years 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 | « pkg/compiler/lib/src/enqueue.dart ('k') | no next file » | 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) 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 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 */ 365 */
366 final Set<FunctionElement> methodsNeedingSuperGetter = 366 final Set<FunctionElement> methodsNeedingSuperGetter =
367 new Set<FunctionElement>(); 367 new Set<FunctionElement>();
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 =
376 <ClassElement, _ClassUsage>{};
377
375 /// Map of registers usage of instance members of live classes. 378 /// Map of registers usage of instance members of live classes.
376 final Map<MemberEntity, MemberUsage> _instanceMemberUsage = 379 final Map<MemberEntity, _MemberUsage> _instanceMemberUsage =
377 <MemberEntity, MemberUsage>{}; 380 <MemberEntity, _MemberUsage>{};
378 381
379 /// Map containing instance members of live classes that are not yet live 382 /// Map containing instance members of live classes that are not yet live
380 /// themselves. 383 /// themselves.
381 final Map<String, Set<MemberUsage>> _instanceMembersByName = 384 final Map<String, Set<_MemberUsage>> _instanceMembersByName =
382 <String, Set<MemberUsage>>{}; 385 <String, Set<_MemberUsage>>{};
383 386
384 /// Map containing instance methods of live classes that are not yet 387 /// Map containing instance methods of live classes that are not yet
385 /// closurized. 388 /// closurized.
386 final Map<String, Set<MemberUsage>> _instanceFunctionsByName = 389 final Map<String, Set<_MemberUsage>> _instanceFunctionsByName =
387 <String, Set<MemberUsage>>{}; 390 <String, Set<_MemberUsage>>{};
388 391
389 /// Fields set. 392 /// Fields set.
390 final Set<Element> fieldSetters = new Set<Element>(); 393 final Set<Element> fieldSetters = new Set<Element>();
391 final Set<DartType> isChecks = new Set<DartType>(); 394 final Set<DartType> isChecks = new Set<DartType>();
392 395
393 /** 396 /**
394 * Set of (live) [:call:] methods whose signatures reference type variables. 397 * Set of (live) [:call:] methods whose signatures reference type variables.
395 * 398 *
396 * A live [:call:] method is one whose enclosing class has been instantiated. 399 * A live [:call:] method is one whose enclosing class has been instantiated.
397 */ 400 */
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 final Resolution _resolution; 436 final Resolution _resolution;
434 437
435 ResolutionWorldBuilderImpl(Backend backend, Resolution resolution, 438 ResolutionWorldBuilderImpl(Backend backend, Resolution resolution,
436 CacheStrategy cacheStrategy, this.selectorConstraintsStrategy) 439 CacheStrategy cacheStrategy, this.selectorConstraintsStrategy)
437 : this._backend = backend, 440 : this._backend = backend,
438 this._resolution = resolution { 441 this._resolution = resolution {
439 _openWorld = 442 _openWorld =
440 new WorldImpl(this, backend, resolution.coreClasses, cacheStrategy); 443 new WorldImpl(this, backend, resolution.coreClasses, cacheStrategy);
441 } 444 }
442 445
446 Iterable<ClassElement> get processedClasses => _processedClasses.keys
447 .where((cls) => _processedClasses[cls].isInstantiated);
448
443 OpenWorld get openWorld => _openWorld; 449 OpenWorld get openWorld => _openWorld;
444 450
445 /// All directly instantiated classes, that is, classes with a generative 451 /// All directly instantiated classes, that is, classes with a generative
446 /// constructor that has been called directly and not only through a 452 /// constructor that has been called directly and not only through a
447 /// super-call. 453 /// super-call.
448 // TODO(johnniwinther): Improve semantic precision. 454 // TODO(johnniwinther): Improve semantic precision.
449 Iterable<ClassElement> get directlyInstantiatedClasses { 455 Iterable<ClassElement> get directlyInstantiatedClasses {
450 Set<ClassElement> classes = new Set<ClassElement>(); 456 Set<ClassElement> classes = new Set<ClassElement>();
451 getInstantiationMap().forEach((ClassElement cls, InstantiationInfo info) { 457 getInstantiationMap().forEach((ClassElement cls, InstantiationInfo info) {
452 if (info.hasInstantiation) { 458 if (info.hasInstantiation) {
(...skipping 30 matching lines...) Expand all
483 bool isImplemented(ClassElement cls) { 489 bool isImplemented(ClassElement cls) {
484 return _implementedClasses.contains(cls.declaration); 490 return _implementedClasses.contains(cls.declaration);
485 } 491 }
486 492
487 /// Register [type] as (directly) instantiated. 493 /// Register [type] as (directly) instantiated.
488 /// 494 ///
489 /// If [byMirrors] is `true`, the instantiation is through mirrors. 495 /// If [byMirrors] is `true`, the instantiation is through mirrors.
490 // TODO(johnniwinther): Fully enforce the separation between exact, through 496 // TODO(johnniwinther): Fully enforce the separation between exact, through
491 // subclass and through subtype instantiated types/classes. 497 // subclass and through subtype instantiated types/classes.
492 // TODO(johnniwinther): Support unknown type arguments for generic types. 498 // TODO(johnniwinther): Support unknown type arguments for generic types.
493 void registerTypeInstantiation(InterfaceType type, 499 void registerTypeInstantiation(InterfaceType type, ClassUsed classUsed,
494 {ConstructorElement constructor, 500 {ConstructorElement constructor,
495 bool byMirrors: false, 501 bool byMirrors: false,
496 bool isNative: false, 502 bool isRedirection: false}) {
497 bool isRedirection: false,
498 void onImplemented(ClassElement cls)}) {
499 ClassElement cls = type.element; 503 ClassElement cls = type.element;
504 cls.ensureResolved(_resolution);
500 InstantiationInfo info = 505 InstantiationInfo info =
501 _instantiationInfo.putIfAbsent(cls, () => new InstantiationInfo()); 506 _instantiationInfo.putIfAbsent(cls, () => new InstantiationInfo());
502 Instantiation kind = Instantiation.UNINSTANTIATED; 507 Instantiation kind = Instantiation.UNINSTANTIATED;
503 if (!cls.isAbstract 508 bool isNative = _backend.isNative(cls);
509 if (!cls.isAbstract ||
504 // We can't use the closed-world assumption with native abstract 510 // We can't use the closed-world assumption with native abstract
505 // classes; a native abstract class may have non-abstract subclasses 511 // classes; a native abstract class may have non-abstract subclasses
506 // not declared to the program. Instances of these classes are 512 // not declared to the program. Instances of these classes are
507 // indistinguishable from the abstract class. 513 // indistinguishable from the abstract class.
508 || 514 isNative ||
509 isNative
510 // Likewise, if this registration comes from the mirror system, 515 // Likewise, if this registration comes from the mirror system,
511 // all bets are off. 516 // all bets are off.
512 // TODO(herhut): Track classes required by mirrors seperately. 517 // TODO(herhut): Track classes required by mirrors seperately.
513 ||
514 byMirrors) { 518 byMirrors) {
515 if (isNative || byMirrors) { 519 if (isNative || byMirrors) {
516 kind = Instantiation.ABSTRACTLY_INSTANTIATED; 520 kind = Instantiation.ABSTRACTLY_INSTANTIATED;
517 } else { 521 } else {
518 kind = Instantiation.DIRECTLY_INSTANTIATED; 522 kind = Instantiation.DIRECTLY_INSTANTIATED;
519 } 523 }
524 _processInstantiatedClass(cls, classUsed);
520 } 525 }
521 info.addInstantiation(constructor, type, kind, 526 info.addInstantiation(constructor, type, kind,
522 isRedirection: isRedirection); 527 isRedirection: isRedirection);
523 528
524 // TODO(johnniwinther): Use [_instantiationInfo] to compute this information 529 // TODO(johnniwinther): Use [_instantiationInfo] to compute this information
525 // instead. 530 // instead.
526 if (_implementedClasses.add(cls)) { 531 if (_implementedClasses.add(cls)) {
532 void onImplemented(ClassElement cls) {
533 _ClassUsage usage = _getClassUsage(cls);
534 classUsed(usage.cls, usage.implement());
535 }
536
527 onImplemented(cls); 537 onImplemented(cls);
528 cls.allSupertypes.forEach((InterfaceType supertype) { 538 cls.allSupertypes.forEach((InterfaceType supertype) {
529 if (_implementedClasses.add(supertype.element)) { 539 if (_implementedClasses.add(supertype.element)) {
530 onImplemented(supertype.element); 540 onImplemented(supertype.element);
531 } 541 }
532 }); 542 });
533 } 543 }
534 } 544 }
535 545
536 @override 546 @override
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 bool hasInvokedSetter(Element member) { 618 bool hasInvokedSetter(Element member) {
609 return _hasMatchingSelector(_invokedSetters[member.name], member); 619 return _hasMatchingSelector(_invokedSetters[member.name], member);
610 } 620 }
611 621
612 void registerDynamicUse(DynamicUse dynamicUse, MemberUsed memberUsed) { 622 void registerDynamicUse(DynamicUse dynamicUse, MemberUsed memberUsed) {
613 Selector selector = dynamicUse.selector; 623 Selector selector = dynamicUse.selector;
614 String methodName = selector.name; 624 String methodName = selector.name;
615 switch (dynamicUse.kind) { 625 switch (dynamicUse.kind) {
616 case DynamicUseKind.INVOKE: 626 case DynamicUseKind.INVOKE:
617 if (_registerNewSelector(dynamicUse, _invokedNames)) { 627 if (_registerNewSelector(dynamicUse, _invokedNames)) {
618 _processInstanceMembers(methodName, (MemberUsage usage) { 628 _processInstanceMembers(methodName, (_MemberUsage usage) {
619 if (dynamicUse.appliesUnnamed(usage.member, _openWorld)) { 629 if (dynamicUse.appliesUnnamed(usage.entity, _openWorld)) {
620 memberUsed(usage.member, usage.invoke()); 630 memberUsed(usage.entity, usage.invoke());
621 return true; 631 return true;
622 } 632 }
623 return false; 633 return false;
624 }); 634 });
625 } 635 }
626 break; 636 break;
627 case DynamicUseKind.GET: 637 case DynamicUseKind.GET:
628 if (_registerNewSelector(dynamicUse, _invokedGetters)) { 638 if (_registerNewSelector(dynamicUse, _invokedGetters)) {
629 _processInstanceMembers(methodName, (MemberUsage usage) { 639 _processInstanceMembers(methodName, (_MemberUsage usage) {
630 if (dynamicUse.appliesUnnamed(usage.member, _openWorld)) { 640 if (dynamicUse.appliesUnnamed(usage.entity, _openWorld)) {
631 memberUsed(usage.member, usage.read()); 641 memberUsed(usage.entity, usage.read());
632 return true; 642 return true;
633 } 643 }
634 return false; 644 return false;
635 }); 645 });
636 _processInstanceFunctions(methodName, (MemberUsage usage) { 646 _processInstanceFunctions(methodName, (_MemberUsage usage) {
637 if (dynamicUse.appliesUnnamed(usage.member, _openWorld)) { 647 if (dynamicUse.appliesUnnamed(usage.entity, _openWorld)) {
638 memberUsed(usage.member, usage.read()); 648 memberUsed(usage.entity, usage.read());
639 return true; 649 return true;
640 } 650 }
641 return false; 651 return false;
642 }); 652 });
643 } 653 }
644 break; 654 break;
645 case DynamicUseKind.SET: 655 case DynamicUseKind.SET:
646 if (_registerNewSelector(dynamicUse, _invokedSetters)) { 656 if (_registerNewSelector(dynamicUse, _invokedSetters)) {
647 _processInstanceMembers(methodName, (MemberUsage usage) { 657 _processInstanceMembers(methodName, (_MemberUsage usage) {
648 if (dynamicUse.appliesUnnamed(usage.member, _openWorld)) { 658 if (dynamicUse.appliesUnnamed(usage.entity, _openWorld)) {
649 memberUsed(usage.member, usage.write()); 659 memberUsed(usage.entity, usage.write());
650 return true; 660 return true;
651 } 661 }
652 return false; 662 return false;
653 }); 663 });
654 } 664 }
655 break; 665 break;
656 } 666 }
657 } 667 }
658 668
659 bool _registerNewSelector(DynamicUse dynamicUse, 669 bool _registerNewSelector(DynamicUse dynamicUse,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 } 721 }
712 } 722 }
713 723
714 void forgetElement(Element element, Compiler compiler) { 724 void forgetElement(Element element, Compiler compiler) {
715 allClosures.remove(element); 725 allClosures.remove(element);
716 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement); 726 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement);
717 closurizedMembers.remove(element); 727 closurizedMembers.remove(element);
718 fieldSetters.remove(element); 728 fieldSetters.remove(element);
719 _instantiationInfo.remove(element); 729 _instantiationInfo.remove(element);
720 730
721 void removeUsage(Set<MemberUsage> set, Element element) { 731 void removeUsage(Set<_MemberUsage> set, Element element) {
722 if (set == null) return; 732 if (set == null) return;
723 set.removeAll( 733 set.removeAll(
724 set.where((MemberUsage usage) => usage.member == element).toList()); 734 set.where((_MemberUsage usage) => usage.entity == element).toList());
725 } 735 }
726 736
737 _processedClasses.remove(element);
727 removeUsage(_instanceMembersByName[element.name], element); 738 removeUsage(_instanceMembersByName[element.name], element);
728 removeUsage(_instanceFunctionsByName[element.name], element); 739 removeUsage(_instanceFunctionsByName[element.name], element);
729 } 740 }
730 741
731 // TODO(ahe): Replace this method with something that is O(1), for example, 742 // TODO(ahe): Replace this method with something that is O(1), for example,
732 // by using a map. 743 // by using a map.
733 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { 744 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) {
734 // Return new list to guard against concurrent modifications. 745 // Return new list to guard against concurrent modifications.
735 return new List<LocalFunctionElement>.from( 746 return new List<LocalFunctionElement>.from(
736 allClosures.where((LocalFunctionElement closure) { 747 allClosures.where((LocalFunctionElement closure) {
737 return closure.executableContext == element; 748 return closure.executableContext == element;
738 })); 749 }));
739 } 750 }
740 751
741 void _processSet(Map<String, Set<MemberUsage>> map, String memberName, 752 /// Return the canonical [_ClassUsage] for [cls].
742 bool f(MemberUsage e)) { 753 _ClassUsage _getClassUsage(ClassElement cls) {
743 Set<MemberUsage> members = map[memberName]; 754 return _processedClasses.putIfAbsent(cls, () {
755 cls.ensureResolved(_resolution);
756 _ClassUsage usage = new _ClassUsage(cls);
757 _resolution.ensureClassMembers(cls);
758 return usage;
759 });
760 }
761
762 /// Register [cls] and all its superclasses as instantiated.
763 void _processInstantiatedClass(ClassElement cls, ClassUsed classUsed) {
764 // Registers [superclass] as instantiated. Returns `true` if it wasn't
765 // already instantiated and we therefore have to process its superclass as
766 // well.
767 bool processClass(ClassElement superclass) {
768 _ClassUsage usage = _getClassUsage(superclass);
769 if (!usage.isInstantiated) {
770 classUsed(usage.cls, usage.instantiate());
771 return true;
772 }
773 return false;
774 }
775
776 while (cls != null && processClass(cls)) {
777 cls = cls.superclass;
778 }
779 }
780
781 /// Computes usage for all members declared by [cls]. Calls [membersUsed] with
782 /// the usage changes for each member.
783 void processClassMembers(ClassElement cls, MemberUsed memberUsed) {
784 cls.implementation.forEachMember((ClassElement cls, MemberElement member) {
785 _processInstantiatedClassMember(cls, member, memberUsed);
786 });
787 }
788
789 void _processSet(Map<String, Set<_MemberUsage>> map, String memberName,
790 bool f(_MemberUsage e)) {
791 Set<_MemberUsage> members = map[memberName];
744 if (members == null) return; 792 if (members == null) return;
745 // [f] might add elements to [: map[memberName] :] during the loop below 793 // [f] might add elements to [: map[memberName] :] during the loop below
746 // so we create a new list for [: map[memberName] :] and prepend the 794 // so we create a new list for [: map[memberName] :] and prepend the
747 // [remaining] members after the loop. 795 // [remaining] members after the loop.
748 map[memberName] = new Set<MemberUsage>(); 796 map[memberName] = new Set<_MemberUsage>();
749 Set<MemberUsage> remaining = new Set<MemberUsage>(); 797 Set<_MemberUsage> remaining = new Set<_MemberUsage>();
750 for (MemberUsage usage in members) { 798 for (_MemberUsage usage in members) {
751 if (!f(usage)) remaining.add(usage); 799 if (!f(usage)) remaining.add(usage);
752 } 800 }
753 map[memberName].addAll(remaining); 801 map[memberName].addAll(remaining);
754 } 802 }
755 803
756 void _processInstanceMembers(String n, bool f(MemberUsage e)) { 804 void _processInstanceMembers(String name, bool f(_MemberUsage e)) {
757 _processSet(_instanceMembersByName, n, f); 805 _processSet(_instanceMembersByName, name, f);
758 } 806 }
759 807
760 void _processInstanceFunctions(String n, bool f(MemberUsage e)) { 808 void _processInstanceFunctions(String n, bool f(_MemberUsage e)) {
761 _processSet(_instanceFunctionsByName, n, f); 809 _processSet(_instanceFunctionsByName, n, f);
762 } 810 }
763 811
764 // TODO(johnniwinther): Make this private when 812 void _processInstantiatedClassMember(
765 // [ResolutionEnqueuer._processClass] is move to [ResolutionWorldBuilderImpl].
766 void processInstantiatedClassMember(
767 ClassElement cls, MemberElement member, MemberUsed memberUsed) { 813 ClassElement cls, MemberElement member, MemberUsed memberUsed) {
768 assert(invariant(member, member.isDeclaration)); 814 assert(invariant(member, member.isDeclaration));
769 if (!member.isInstanceMember) return; 815 if (!member.isInstanceMember) return;
770 String memberName = member.name; 816 String memberName = member.name;
771 member.computeType(_resolution); 817 member.computeType(_resolution);
772 EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); 818 EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
773 // The obvious thing to test here would be "member.isNative", 819 // The obvious thing to test here would be "member.isNative",
774 // however, that only works after metadata has been parsed/analyzed, 820 // however, that only works after metadata has been parsed/analyzed,
775 // and that may not have happened yet. 821 // and that may not have happened yet.
776 // So instead we use the enclosing class, which we know have had 822 // So instead we use the enclosing class, which we know have had
777 // its metadata parsed and analyzed. 823 // its metadata parsed and analyzed.
778 // Note: this assumes that there are no non-native fields on native 824 // Note: this assumes that there are no non-native fields on native
779 // classes, which may not be the case when a native class is subclassed. 825 // classes, which may not be the case when a native class is subclassed.
780 bool isNative = _backend.isNative(cls); 826 bool isNative = _backend.isNative(cls);
781 MemberUsage usage = _instanceMemberUsage.putIfAbsent(member, () { 827 _MemberUsage usage = _instanceMemberUsage.putIfAbsent(member, () {
782 MemberUsage usage = new MemberUsage(member, isNative: isNative); 828 _MemberUsage usage = new _MemberUsage(member, isNative: isNative);
783 useSet.addAll(usage.appliedUse); 829 useSet.addAll(usage.appliedUse);
784 if (member.isField && isNative) { 830 if (member.isField && isNative) {
785 _openWorld.registerUsedElement(member); 831 _openWorld.registerUsedElement(member);
786 } 832 }
787 833
788 if (_hasInvokedGetter(member)) { 834 if (_hasInvokedGetter(member)) {
789 useSet.addAll(usage.read()); 835 useSet.addAll(usage.read());
790 } 836 }
791 if (_hasInvocation(member)) { 837 if (_hasInvocation(member)) {
792 useSet.addAll(usage.invoke()); 838 useSet.addAll(usage.invoke());
793 } 839 }
794 if (hasInvokedSetter(member)) { 840 if (hasInvokedSetter(member)) {
795 useSet.addAll(usage.write()); 841 useSet.addAll(usage.write());
796 } 842 }
797 843
798 if (usage.pendingUse.contains(MemberUse.NORMAL)) { 844 if (usage.pendingUse.contains(MemberUse.NORMAL)) {
799 // The element is not yet used. Add it to the list of instance 845 // The element is not yet used. Add it to the list of instance
800 // members to still be processed. 846 // members to still be processed.
801 _instanceMembersByName 847 _instanceMembersByName
802 .putIfAbsent(memberName, () => new Set<MemberUsage>()) 848 .putIfAbsent(memberName, () => new Set<_MemberUsage>())
803 .add(usage); 849 .add(usage);
804 } 850 }
805 if (usage.pendingUse.contains(MemberUse.CLOSURIZE)) { 851 if (usage.pendingUse.contains(MemberUse.CLOSURIZE)) {
806 // Store the member in [instanceFunctionsByName] to catch 852 // Store the member in [instanceFunctionsByName] to catch
807 // getters on the function. 853 // getters on the function.
808 _instanceFunctionsByName 854 _instanceFunctionsByName
809 .putIfAbsent(memberName, () => new Set<MemberUsage>()) 855 .putIfAbsent(memberName, () => new Set<_MemberUsage>())
810 .add(usage); 856 .add(usage);
811 } 857 }
812 858
813 memberUsed(usage.member, useSet); 859 memberUsed(usage.entity, useSet);
814 return usage; 860 return usage;
815 }); 861 });
816 } 862 }
817 } 863 }
818 864
819 /// World builder specific to codegen. 865 /// World builder specific to codegen.
820 /// 866 ///
821 /// This adds additional access to liveness of selectors and elements. 867 /// This adds additional access to liveness of selectors and elements.
822 abstract class CodegenWorldBuilder implements WorldBuilder { 868 abstract class CodegenWorldBuilder implements WorldBuilder {
823 void forEachInvokedName( 869 void forEachInvokedName(
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 void forgetElement(Element element, Compiler compiler) { 1119 void forgetElement(Element element, Compiler compiler) {
1074 _directlyInstantiatedClasses.remove(element); 1120 _directlyInstantiatedClasses.remove(element);
1075 if (element is ClassElement) { 1121 if (element is ClassElement) {
1076 assert(invariant(element, element.thisType.isRaw, 1122 assert(invariant(element, element.thisType.isRaw,
1077 message: 'Generic classes not supported (${element.thisType}).')); 1123 message: 'Generic classes not supported (${element.thisType}).'));
1078 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); 1124 _instantiatedTypes..remove(element.rawType)..remove(element.thisType);
1079 } 1125 }
1080 } 1126 }
1081 } 1127 }
1082 1128
1083 /// Registry for the observed use of [member] in the open world. 1129 abstract class _AbstractUsage<T> {
1084 abstract class MemberUsage { 1130 final EnumSet<T> _pendingUse = new EnumSet<T>();
1085 // TODO(johnniwinther): Change [Entity] to [MemberEntity].
1086 final Entity member;
1087 final EnumSet<MemberUse> _pendingUse = new EnumSet<MemberUse>();
1088 1131
1089 MemberUsage.internal(this.member) { 1132 _AbstractUsage() {
1090 _pendingUse.addAll(_originalUse); 1133 _pendingUse.addAll(_originalUse);
1091 } 1134 }
1092 1135
1093 factory MemberUsage(MemberEntity member, {bool isNative: false}) { 1136 /// Returns the possible uses of [entity] that have not yet been registered.
1137 EnumSet<T> get pendingUse => _pendingUse;
1138
1139 /// Returns the uses of [entity] that have been registered.
1140 EnumSet<T> get appliedUse => _originalUse.minus(_pendingUse);
1141
1142 EnumSet<T> get _originalUse;
1143 }
1144
1145 /// Registry for the observed use of a member [entity] in the open world.
1146 abstract class _MemberUsage extends _AbstractUsage<MemberUse> {
1147 // TODO(johnniwinther): Change [Entity] to [MemberEntity].
1148 final Entity entity;
1149
1150 _MemberUsage.internal(this.entity);
1151
1152 factory _MemberUsage(MemberEntity member, {bool isNative: false}) {
1094 if (member.isField) { 1153 if (member.isField) {
1095 if (member.isAssignable) { 1154 if (member.isAssignable) {
1096 return new _FieldUsage(member, isNative: isNative); 1155 return new _FieldUsage(member, isNative: isNative);
1097 } else { 1156 } else {
1098 return new _FinalFieldUsage(member, isNative: isNative); 1157 return new _FinalFieldUsage(member, isNative: isNative);
1099 } 1158 }
1100 } else if (member.isGetter) { 1159 } else if (member.isGetter) {
1101 return new _GetterUsage(member); 1160 return new _GetterUsage(member);
1102 } else if (member.isSetter) { 1161 } else if (member.isSetter) {
1103 return new _SetterUsage(member); 1162 return new _SetterUsage(member);
1104 } else { 1163 } else {
1105 assert(member.isFunction); 1164 assert(member.isFunction);
1106 return new _FunctionUsage(member); 1165 return new _FunctionUsage(member);
1107 } 1166 }
1108 } 1167 }
1109 1168
1110 /// `true` if [member] has be read as a value. For a field this is a normal 1169 /// `true` if [entity] has be read as a value. For a field this is a normal
1111 /// read access, for a function this is a closurization. 1170 /// read access, for a function this is a closurization.
1112 bool get hasRead => false; 1171 bool get hasRead => false;
1113 1172
1114 /// `true` if a value as been written to [member]. 1173 /// `true` if a value as been written to [entity].
1115 bool get hasWrite => false; 1174 bool get hasWrite => false;
1116 1175
1117 /// `true` if an invocation has been performed on the value [member]. For a 1176 /// `true` if an invocation has been performed on the value [entity]. For a
1118 /// function this is a normal invocation, for a field this is a read access 1177 /// function this is a normal invocation, for a field this is a read access
1119 /// followed by an invocation of the function-like value. 1178 /// followed by an invocation of the function-like value.
1120 bool get hasInvoke => false; 1179 bool get hasInvoke => false;
1121 1180
1122 /// `true` if [member] has been used in all the ways possible. 1181 /// `true` if [entity] has been used in all the ways possible.
1123 bool get fullyUsed; 1182 bool get fullyUsed;
1124 1183
1125 /// Registers a read of the value of [member] and returns the new [MemberUse]s 1184 /// Registers a read of the value of [entity] and returns the new [MemberUse]s
1126 /// that it caused. 1185 /// that it caused.
1127 /// 1186 ///
1128 /// For a field this is a normal read access, for a function this is a 1187 /// For a field this is a normal read access, for a function this is a
1129 /// closurization. 1188 /// closurization.
1130 EnumSet<MemberUse> read() => MemberUse.NONE; 1189 EnumSet<MemberUse> read() => MemberUse.NONE;
1131 1190
1132 /// Registers a write of a value to [member] and returns the new [MemberUse]s 1191 /// Registers a write of a value to [entity] and returns the new [MemberUse]s
1133 /// that it caused. 1192 /// that it caused.
1134 EnumSet<MemberUse> write() => MemberUse.NONE; 1193 EnumSet<MemberUse> write() => MemberUse.NONE;
1135 1194
1136 /// Registers an invocation on the value of [member] and returns the new 1195 /// Registers an invocation on the value of [entity] and returns the new
1137 /// [MemberUse]s that it caused. 1196 /// [MemberUse]s that it caused.
1138 /// 1197 ///
1139 /// For a function this is a normal invocation, for a field this is a read 1198 /// For a function this is a normal invocation, for a field this is a read
1140 /// access followed by an invocation of the function-like value. 1199 /// access followed by an invocation of the function-like value.
1141 EnumSet<MemberUse> invoke() => MemberUse.NONE; 1200 EnumSet<MemberUse> invoke() => MemberUse.NONE;
1142 1201
1143 /// Registers all possible uses of [member] and returns the new [MemberUse]s 1202 /// Registers all possible uses of [entity] and returns the new [MemberUse]s
1144 /// that it caused. 1203 /// that it caused.
1145 EnumSet<MemberUse> fullyUse() => MemberUse.NONE; 1204 EnumSet<MemberUse> fullyUse() => MemberUse.NONE;
1146 1205
1147 /// Returns the possible [MemberUse]s of [member] that have not yet been 1206 int get hashCode => entity.hashCode;
1148 /// registered.
1149 EnumSet<MemberUse> get pendingUse => _pendingUse;
1150
1151 /// Returns the [MemberUse]s of [member] that have been registered.
1152 EnumSet<MemberUse> get appliedUse => _originalUse.minus(_pendingUse);
1153
1154 EnumSet<MemberUse> get _originalUse;
1155
1156 int get hashCode => member.hashCode;
1157 1207
1158 bool operator ==(other) { 1208 bool operator ==(other) {
1159 if (identical(this, other)) return true; 1209 if (identical(this, other)) return true;
1160 if (other is! MemberUsage) return false; 1210 if (other is! _MemberUsage) return false;
1161 return member == other.member; 1211 return entity == other.entity;
1162 } 1212 }
1163 1213
1164 String toString() => member.toString(); 1214 String toString() => entity.toString();
1165 } 1215 }
1166 1216
1167 class _FieldUsage extends MemberUsage { 1217 class _FieldUsage extends _MemberUsage {
1168 bool hasRead = false; 1218 bool hasRead = false;
1169 bool hasWrite = false; 1219 bool hasWrite = false;
1170 1220
1171 _FieldUsage(FieldEntity field, {bool isNative: false}) 1221 _FieldUsage(FieldEntity field, {bool isNative: false})
1172 : super.internal(field) { 1222 : super.internal(field) {
1173 if (!isNative) { 1223 if (!isNative) {
1174 // All field initializers must be resolved as they could 1224 // All field initializers must be resolved as they could
1175 // have an observable side-effect (and cannot be tree-shaken 1225 // have an observable side-effect (and cannot be tree-shaken
1176 // away). 1226 // away).
1177 fullyUse(); 1227 fullyUse();
(...skipping 29 matching lines...) Expand all
1207 @override 1257 @override
1208 EnumSet<MemberUse> fullyUse() { 1258 EnumSet<MemberUse> fullyUse() {
1209 if (fullyUsed) { 1259 if (fullyUsed) {
1210 return MemberUse.NONE; 1260 return MemberUse.NONE;
1211 } 1261 }
1212 hasRead = hasWrite = true; 1262 hasRead = hasWrite = true;
1213 return _pendingUse.removeAll(MemberUse.NORMAL_ONLY); 1263 return _pendingUse.removeAll(MemberUse.NORMAL_ONLY);
1214 } 1264 }
1215 } 1265 }
1216 1266
1217 class _FinalFieldUsage extends MemberUsage { 1267 class _FinalFieldUsage extends _MemberUsage {
1218 bool hasRead = false; 1268 bool hasRead = false;
1219 1269
1220 _FinalFieldUsage(FieldEntity field, {bool isNative: false}) 1270 _FinalFieldUsage(FieldEntity field, {bool isNative: false})
1221 : super.internal(field) { 1271 : super.internal(field) {
1222 if (!isNative) { 1272 if (!isNative) {
1223 // All field initializers must be resolved as they could 1273 // All field initializers must be resolved as they could
1224 // have an observable side-effect (and cannot be tree-shaken 1274 // have an observable side-effect (and cannot be tree-shaken
1225 // away). 1275 // away).
1226 read(); 1276 read();
1227 } 1277 }
(...skipping 13 matching lines...) Expand all
1241 return _pendingUse.removeAll(MemberUse.NORMAL_ONLY); 1291 return _pendingUse.removeAll(MemberUse.NORMAL_ONLY);
1242 } 1292 }
1243 1293
1244 @override 1294 @override
1245 EnumSet<MemberUse> invoke() => read(); 1295 EnumSet<MemberUse> invoke() => read();
1246 1296
1247 @override 1297 @override
1248 EnumSet<MemberUse> fullyUse() => read(); 1298 EnumSet<MemberUse> fullyUse() => read();
1249 } 1299 }
1250 1300
1251 class _FunctionUsage extends MemberUsage { 1301 class _FunctionUsage extends _MemberUsage {
1252 bool hasInvoke = false; 1302 bool hasInvoke = false;
1253 bool hasRead = false; 1303 bool hasRead = false;
1254 1304
1255 _FunctionUsage(FunctionEntity function) : super.internal(function); 1305 _FunctionUsage(FunctionEntity function) : super.internal(function);
1256 1306
1257 EnumSet<MemberUse> get _originalUse => MemberUse.ALL; 1307 EnumSet<MemberUse> get _originalUse => MemberUse.ALL;
1258 1308
1259 @override 1309 @override
1260 EnumSet<MemberUse> read() => fullyUse(); 1310 EnumSet<MemberUse> read() => fullyUse();
1261 1311
(...skipping 21 matching lines...) Expand all
1283 } else { 1333 } else {
1284 hasRead = hasInvoke = true; 1334 hasRead = hasInvoke = true;
1285 return _pendingUse.removeAll(MemberUse.ALL); 1335 return _pendingUse.removeAll(MemberUse.ALL);
1286 } 1336 }
1287 } 1337 }
1288 1338
1289 @override 1339 @override
1290 bool get fullyUsed => hasInvoke && hasRead; 1340 bool get fullyUsed => hasInvoke && hasRead;
1291 } 1341 }
1292 1342
1293 class _GetterUsage extends MemberUsage { 1343 class _GetterUsage extends _MemberUsage {
1294 bool hasRead = false; 1344 bool hasRead = false;
1295 1345
1296 _GetterUsage(FunctionEntity getter) : super.internal(getter); 1346 _GetterUsage(FunctionEntity getter) : super.internal(getter);
1297 1347
1298 EnumSet<MemberUse> get _originalUse => MemberUse.NORMAL_ONLY; 1348 EnumSet<MemberUse> get _originalUse => MemberUse.NORMAL_ONLY;
1299 1349
1300 @override 1350 @override
1301 bool get fullyUsed => hasRead; 1351 bool get fullyUsed => hasRead;
1302 1352
1303 @override 1353 @override
1304 EnumSet<MemberUse> read() { 1354 EnumSet<MemberUse> read() {
1305 if (hasRead) { 1355 if (hasRead) {
1306 return MemberUse.NONE; 1356 return MemberUse.NONE;
1307 } 1357 }
1308 hasRead = true; 1358 hasRead = true;
1309 return _pendingUse.removeAll(MemberUse.NORMAL_ONLY); 1359 return _pendingUse.removeAll(MemberUse.NORMAL_ONLY);
1310 } 1360 }
1311 1361
1312 @override 1362 @override
1313 EnumSet<MemberUse> invoke() => read(); 1363 EnumSet<MemberUse> invoke() => read();
1314 1364
1315 @override 1365 @override
1316 EnumSet<MemberUse> fullyUse() => read(); 1366 EnumSet<MemberUse> fullyUse() => read();
1317 } 1367 }
1318 1368
1319 class _SetterUsage extends MemberUsage { 1369 class _SetterUsage extends _MemberUsage {
1320 bool hasWrite = false; 1370 bool hasWrite = false;
1321 1371
1322 _SetterUsage(FunctionEntity setter) : super.internal(setter); 1372 _SetterUsage(FunctionEntity setter) : super.internal(setter);
1323 1373
1324 EnumSet<MemberUse> get _originalUse => MemberUse.NORMAL_ONLY; 1374 EnumSet<MemberUse> get _originalUse => MemberUse.NORMAL_ONLY;
1325 1375
1326 @override 1376 @override
1327 bool get fullyUsed => hasWrite; 1377 bool get fullyUsed => hasWrite;
1328 1378
1329 @override 1379 @override
1330 EnumSet<MemberUse> write() { 1380 EnumSet<MemberUse> write() {
1331 if (hasWrite) { 1381 if (hasWrite) {
1332 return MemberUse.NONE; 1382 return MemberUse.NONE;
1333 } 1383 }
1334 hasWrite = true; 1384 hasWrite = true;
1335 return MemberUse.NORMAL_ONLY; 1385 return MemberUse.NORMAL_ONLY;
1336 } 1386 }
1337 1387
1338 @override 1388 @override
1339 EnumSet<MemberUse> fullyUse() => write(); 1389 EnumSet<MemberUse> fullyUse() => write();
1340 } 1390 }
1341 1391
1342 /// Enum-like class for the possible kind of use of [MemberEntity] objects. 1392 /// Enum-like class for the possible kind of use of [MemberEntity] objects.
1343 class MemberUse { 1393 class MemberUse {
1344 final int index; 1394 final int index;
1345 1395
1346 const MemberUse._(this.index); 1396 const MemberUse._(this.index);
1347 1397
1398 String toString() => 'MemberUse($index)';
1399
1348 static const List<MemberUse> values = const <MemberUse>[NORMAL, CLOSURIZE]; 1400 static const List<MemberUse> values = const <MemberUse>[NORMAL, CLOSURIZE];
1349 1401
1350 static const MemberUse NORMAL = const MemberUse._(0); 1402 static const MemberUse NORMAL = const MemberUse._(0);
1351 static const MemberUse CLOSURIZE = const MemberUse._(1); 1403 static const MemberUse CLOSURIZE = const MemberUse._(1);
1352 1404
1353 static const EnumSet<MemberUse> NONE = const EnumSet<MemberUse>.fixed(0); 1405 static const EnumSet<MemberUse> NONE = const EnumSet<MemberUse>.fixed(0);
1354 static const EnumSet<MemberUse> NORMAL_ONLY = 1406 static const EnumSet<MemberUse> NORMAL_ONLY =
1355 const EnumSet<MemberUse>.fixed(1); 1407 const EnumSet<MemberUse>.fixed(1);
1356 static const EnumSet<MemberUse> CLOSURIZE_ONLY = 1408 static const EnumSet<MemberUse> CLOSURIZE_ONLY =
1357 const EnumSet<MemberUse>.fixed(2); 1409 const EnumSet<MemberUse>.fixed(2);
1358 static const EnumSet<MemberUse> ALL = const EnumSet<MemberUse>.fixed(3); 1410 static const EnumSet<MemberUse> ALL = const EnumSet<MemberUse>.fixed(3);
1359 } 1411 }
1360 1412
1361 typedef void MemberUsed(MemberEntity member, EnumSet<MemberUse> useSet); 1413 typedef void MemberUsed(MemberEntity member, EnumSet<MemberUse> useSet);
1414
1415 /// Registry for the observed use of a class [entity] in the open world.
1416 // TODO(johnniwinther): Merge this with [InstantiationInfo].
1417 class _ClassUsage extends _AbstractUsage<ClassUse> {
1418 bool isInstantiated = false;
1419 bool isImplemented = false;
1420
1421 final ClassEntity cls;
1422
1423 _ClassUsage(this.cls);
1424
1425 EnumSet<ClassUse> instantiate() {
1426 if (isInstantiated) {
1427 return ClassUses.NONE;
1428 }
1429 isInstantiated = true;
1430 return _pendingUse.removeAll(ClassUses.INSTANTIATED_ONLY);
1431 }
1432
1433 EnumSet<ClassUse> implement() {
1434 if (isImplemented) {
1435 return ClassUses.NONE;
1436 }
1437 isImplemented = true;
1438 return _pendingUse.removeAll(ClassUses.IMPLEMENTED_ONLY);
1439 }
1440
1441 @override
1442 EnumSet<ClassUse> get _originalUse => ClassUses.ALL;
1443
1444 String toString() => cls.toString();
1445 }
1446
1447 /// Enum class for the possible kind of use of [ClassEntity] objects.
1448 enum ClassUse { INSTANTIATED, IMPLEMENTED }
1449
1450 /// Common [EnumSet]s used for [ClassUse].
1451 class ClassUses {
1452 static const EnumSet<ClassUse> NONE = const EnumSet<ClassUse>.fixed(0);
1453 static const EnumSet<ClassUse> INSTANTIATED_ONLY =
1454 const EnumSet<ClassUse>.fixed(1);
1455 static const EnumSet<ClassUse> IMPLEMENTED_ONLY =
1456 const EnumSet<ClassUse>.fixed(2);
1457 static const EnumSet<ClassUse> ALL = const EnumSet<ClassUse>.fixed(3);
1458 }
1459
1460 typedef void ClassUsed(ClassEntity cls, EnumSet<ClassUse> useSet);
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/enqueue.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698