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

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