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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/resolution/members.dart

Issue 52263003: Implement least upper bound. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 7 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 | Annotate | Revision Log
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 part of resolution; 5 part of resolution;
6 6
7 abstract class TreeElements { 7 abstract class TreeElements {
8 Element get currentElement; 8 Element get currentElement;
9 Setlet<Node> get superUses; 9 Setlet<Node> get superUses;
10 10
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 factory.redirectionTargetType = targetType; 654 factory.redirectionTargetType = targetType;
655 } 655 }
656 } 656 }
657 657
658 /** 658 /**
659 * Load and resolve the supertypes of [cls]. 659 * Load and resolve the supertypes of [cls].
660 * 660 *
661 * Warning: do not call this method directly. It should only be 661 * Warning: do not call this method directly. It should only be
662 * called by [resolveClass] and [ClassSupertypeResolver]. 662 * called by [resolveClass] and [ClassSupertypeResolver].
663 */ 663 */
664 void loadSupertypes(ClassElement cls, Spannable from) { 664 void loadSupertypes(BaseClassElementX cls, Spannable from) {
665 compiler.withCurrentElement(cls, () => measure(() { 665 compiler.withCurrentElement(cls, () => measure(() {
666 if (cls.supertypeLoadState == STATE_DONE) return; 666 if (cls.supertypeLoadState == STATE_DONE) return;
667 if (cls.supertypeLoadState == STATE_STARTED) { 667 if (cls.supertypeLoadState == STATE_STARTED) {
668 compiler.reportError(from, MessageKind.CYCLIC_CLASS_HIERARCHY, 668 compiler.reportError(from, MessageKind.CYCLIC_CLASS_HIERARCHY,
669 {'className': cls.name}); 669 {'className': cls.name});
670 cls.supertypeLoadState = STATE_DONE; 670 cls.supertypeLoadState = STATE_DONE;
671 cls.allSupertypes = const Link<DartType>().prepend( 671 cls.allSupertypesAndSelf =
672 compiler.objectClass.computeType(compiler)); 672 compiler.objectClass.allSupertypesAndSelf.extendClass(
673 cls.computeType(compiler));
673 cls.supertype = cls.allSupertypes.head; 674 cls.supertype = cls.allSupertypes.head;
675 assert(invariant(from, cls.supertype != null,
676 message: 'Missing supertype on cyclic class $cls.'));
674 return; 677 return;
675 } 678 }
676 cls.supertypeLoadState = STATE_STARTED; 679 cls.supertypeLoadState = STATE_STARTED;
677 compiler.withCurrentElement(cls, () { 680 compiler.withCurrentElement(cls, () {
678 // TODO(ahe): Cache the node in cls. 681 // TODO(ahe): Cache the node in cls.
679 cls.parseNode(compiler).accept( 682 cls.parseNode(compiler).accept(
680 new ClassSupertypeResolver(compiler, cls)); 683 new ClassSupertypeResolver(compiler, cls));
681 if (cls.supertypeLoadState != STATE_DONE) { 684 if (cls.supertypeLoadState != STATE_DONE) {
682 cls.supertypeLoadState = STATE_DONE; 685 cls.supertypeLoadState = STATE_DONE;
683 } 686 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 } 719 }
717 720
718 void _ensureClassWillBeResolved(ClassElement element) { 721 void _ensureClassWillBeResolved(ClassElement element) {
719 if (currentlyResolvedClass == null) { 722 if (currentlyResolvedClass == null) {
720 element.ensureResolved(compiler); 723 element.ensureResolved(compiler);
721 } else { 724 } else {
722 pendingClassesToBeResolved.add(element); 725 pendingClassesToBeResolved.add(element);
723 } 726 }
724 } 727 }
725 728
726 void resolveClassInternal(ClassElement element, TreeElementMapping mapping) { 729 void resolveClassInternal(BaseClassElementX element,
730 TreeElementMapping mapping) {
727 if (!element.isPatch) { 731 if (!element.isPatch) {
728 compiler.withCurrentElement(element, () => measure(() { 732 compiler.withCurrentElement(element, () => measure(() {
729 assert(element.resolutionState == STATE_NOT_STARTED); 733 assert(element.resolutionState == STATE_NOT_STARTED);
730 element.resolutionState = STATE_STARTED; 734 element.resolutionState = STATE_STARTED;
731 Node tree = element.parseNode(compiler); 735 Node tree = element.parseNode(compiler);
732 loadSupertypes(element, tree); 736 loadSupertypes(element, tree);
733 737
734 ClassResolverVisitor visitor = 738 ClassResolverVisitor visitor =
735 new ClassResolverVisitor(compiler, element, mapping); 739 new ClassResolverVisitor(compiler, element, mapping);
736 visitor.visit(tree); 740 visitor.visit(tree);
737 element.resolutionState = STATE_DONE; 741 element.resolutionState = STATE_DONE;
738 compiler.onClassResolved(element); 742 compiler.onClassResolved(element);
739 })); 743 }));
740 if (element.isPatched) { 744 if (element.isPatched) {
741 // Ensure handling patch after origin. 745 // Ensure handling patch after origin.
742 element.patch.ensureResolved(compiler); 746 element.patch.ensureResolved(compiler);
743 } 747 }
744 } else { // Handle patch classes: 748 } else { // Handle patch classes:
745 element.resolutionState = STATE_STARTED; 749 element.resolutionState = STATE_STARTED;
746 // Ensure handling origin before patch. 750 // Ensure handling origin before patch.
747 element.origin.ensureResolved(compiler); 751 element.origin.ensureResolved(compiler);
748 // Ensure that the type is computed. 752 // Ensure that the type is computed.
749 element.computeType(compiler); 753 element.computeType(compiler);
750 // Copy class hiearchy from origin. 754 // Copy class hiearchy from origin.
751 element.supertype = element.origin.supertype; 755 element.supertype = element.origin.supertype;
752 element.interfaces = element.origin.interfaces; 756 element.interfaces = element.origin.interfaces;
753 element.allSupertypes = element.origin.allSupertypes; 757 element.allSupertypesAndSelf = element.origin.allSupertypesAndSelf;
754 // Stepwise assignment to ensure invariant. 758 // Stepwise assignment to ensure invariant.
755 element.supertypeLoadState = STATE_STARTED; 759 element.supertypeLoadState = STATE_STARTED;
756 element.supertypeLoadState = STATE_DONE; 760 element.supertypeLoadState = STATE_DONE;
757 element.resolutionState = STATE_DONE; 761 element.resolutionState = STATE_DONE;
758 // TODO(johnniwinther): Check matching type variables and 762 // TODO(johnniwinther): Check matching type variables and
759 // empty extends/implements clauses. 763 // empty extends/implements clauses.
760 } 764 }
761 for (MetadataAnnotation metadata in element.metadata) { 765 for (MetadataAnnotation metadata in element.metadata) {
762 metadata.ensureResolved(compiler); 766 metadata.ensureResolved(compiler);
763 } 767 }
(...skipping 3169 matching lines...) Expand 10 before | Expand all | Expand 10 after
3933 return constructor.name == '' && 3937 return constructor.name == '' &&
3934 constructor.computeSignature(compiler).parameterCount == 0; 3938 constructor.computeSignature(compiler).parameterCount == 0;
3935 } 3939 }
3936 3940
3937 FunctionElement createForwardingConstructor(FunctionElement target, 3941 FunctionElement createForwardingConstructor(FunctionElement target,
3938 ClassElement enclosing) { 3942 ClassElement enclosing) {
3939 return new SynthesizedConstructorElementX( 3943 return new SynthesizedConstructorElementX(
3940 target.name, target, enclosing, false); 3944 target.name, target, enclosing, false);
3941 } 3945 }
3942 3946
3943 void doApplyMixinTo(MixinApplicationElement mixinApplication, 3947 void doApplyMixinTo(MixinApplicationElementX mixinApplication,
3944 DartType supertype, 3948 DartType supertype,
3945 DartType mixinType) { 3949 DartType mixinType) {
3946 Node node = mixinApplication.parseNode(compiler); 3950 Node node = mixinApplication.parseNode(compiler);
3947 3951
3948 if (mixinApplication.supertype != null) { 3952 if (mixinApplication.supertype != null) {
3949 // [supertype] is not null if there was a cycle. 3953 // [supertype] is not null if there was a cycle.
3950 assert(invariant(node, compiler.compilationFailed)); 3954 assert(invariant(node, compiler.compilationFailed));
3951 supertype = mixinApplication.supertype; 3955 supertype = mixinApplication.supertype;
3952 assert(invariant(node, supertype.element == compiler.objectClass)); 3956 assert(invariant(node, supertype.element == compiler.objectClass));
3953 } else { 3957 } else {
3954 mixinApplication.supertype = supertype; 3958 mixinApplication.supertype = supertype;
3955 } 3959 }
3956 3960
3957 // Named mixin application may have an 'implements' clause. 3961 // Named mixin application may have an 'implements' clause.
3958 NamedMixinApplication namedMixinApplication = 3962 NamedMixinApplication namedMixinApplication =
3959 node.asNamedMixinApplication(); 3963 node.asNamedMixinApplication();
3960 Link<DartType> interfaces = (namedMixinApplication != null) 3964 Link<DartType> interfaces = (namedMixinApplication != null)
3961 ? resolveInterfaces(namedMixinApplication.interfaces, 3965 ? resolveInterfaces(namedMixinApplication.interfaces,
3962 namedMixinApplication.superclass) 3966 namedMixinApplication.superclass)
3963 : const Link<DartType>(); 3967 : const Link<DartType>();
3964 3968
3965 // The class that is the result of a mixin application implements 3969 // The class that is the result of a mixin application implements
3966 // the interface of the class that was mixed in so always prepend 3970 // the interface of the class that was mixed in so always prepend
3967 // that to the interface list. 3971 // that to the interface list.
3972
3968 interfaces = interfaces.prepend(mixinType); 3973 interfaces = interfaces.prepend(mixinType);
3969 assert(mixinApplication.interfaces == null); 3974 assert(mixinApplication.interfaces == null);
3970 mixinApplication.interfaces = interfaces; 3975 mixinApplication.interfaces = interfaces;
3971 3976
3977 ClassElement superclass = supertype.element;
3972 if (mixinType.kind != TypeKind.INTERFACE) { 3978 if (mixinType.kind != TypeKind.INTERFACE) {
3973 mixinApplication.allSupertypes = const Link<DartType>(); 3979 mixinApplication.allSupertypesAndSelf = superclass.allSupertypesAndSelf;
3974 return; 3980 return;
3975 } 3981 }
3976 3982
3977 assert(mixinApplication.mixinType == null); 3983 assert(mixinApplication.mixinType == null);
3978 mixinApplication.mixinType = resolveMixinFor(mixinApplication, mixinType); 3984 mixinApplication.mixinType = resolveMixinFor(mixinApplication, mixinType);
3979 3985
3980 // Create forwarding constructors for constructor defined in the superclass 3986 // Create forwarding constructors for constructor defined in the superclass
3981 // because they are now hidden by the mixin application. 3987 // because they are now hidden by the mixin application.
3982 ClassElement superclass = supertype.element;
3983 superclass.forEachLocalMember((Element member) { 3988 superclass.forEachLocalMember((Element member) {
3984 if (!member.isGenerativeConstructor()) return; 3989 if (!member.isGenerativeConstructor()) return;
3985 FunctionElement forwarder = 3990 FunctionElement forwarder =
3986 createForwardingConstructor(member, mixinApplication); 3991 createForwardingConstructor(member, mixinApplication);
3987 mixinApplication.addConstructor(forwarder); 3992 mixinApplication.addConstructor(forwarder);
3988 }); 3993 });
3989 calculateAllSupertypes(mixinApplication); 3994 calculateAllSupertypes(mixinApplication);
3990 } 3995 }
3991 3996
3992 InterfaceType resolveMixinFor(MixinApplicationElement mixinApplication, 3997 InterfaceType resolveMixinFor(MixinApplicationElement mixinApplication,
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
4088 * 4093 *
4089 * For example, for a class `class C extends S implements I1, I2`, we compute 4094 * For example, for a class `class C extends S implements I1, I2`, we compute
4090 * supertypes(C) = [S, I1, I2] ++ supertypes(S) ++ supertypes(I1) 4095 * supertypes(C) = [S, I1, I2] ++ supertypes(S) ++ supertypes(I1)
4091 * ++ supertypes(I2), 4096 * ++ supertypes(I2),
4092 * where ++ stands for list concatenation. 4097 * where ++ stands for list concatenation.
4093 * 4098 *
4094 * This order makes sure that if a class implements an interface twice with 4099 * This order makes sure that if a class implements an interface twice with
4095 * different type arguments, the type used in the most specific class comes 4100 * different type arguments, the type used in the most specific class comes
4096 * first. 4101 * first.
4097 */ 4102 */
4098 void calculateAllSupertypes(ClassElement cls) { 4103 void calculateAllSupertypes(BaseClassElementX cls) {
4099 if (cls.allSupertypes != null) return; 4104 if (cls.allSupertypesAndSelf != null) return;
4100 final DartType supertype = cls.supertype; 4105 final DartType supertype = cls.supertype;
4101 if (supertype != null) { 4106 if (supertype != null) {
4102 Map<Element, DartType> instantiations = new Map<Element, DartType>(); 4107 OrderedTypeSetBuilder allSupertypes = new OrderedTypeSetBuilder(cls);
4103 LinkBuilder<DartType> allSupertypes = new LinkBuilder<DartType>(); 4108 // TODO(15296): Collapse these iterations to one when the order is not
4104 4109 // needed.
4105 void addSupertype(DartType type) { 4110 allSupertypes.add(compiler, supertype);
4106 DartType existing =
4107 instantiations.putIfAbsent(type.element, () => type);
4108 if (existing != null && existing != type) {
4109 compiler.reportError(cls,
4110 MessageKind.MULTI_INHERITANCE,
4111 {'thisType': cls.computeType(compiler),
4112 'firstType': existing,
4113 'secondType': type});
4114 }
4115 if (type.element != compiler.objectClass) {
4116 allSupertypes.addLast(type);
4117 }
4118 }
4119
4120 addSupertype(supertype);
4121 for (Link<DartType> interfaces = cls.interfaces;
4122 !interfaces.isEmpty;
4123 interfaces = interfaces.tail) {
4124 addSupertype(interfaces.head);
4125 }
4126 addAllSupertypes(addSupertype, supertype);
4127 for (Link<DartType> interfaces = cls.interfaces; 4111 for (Link<DartType> interfaces = cls.interfaces;
4128 !interfaces.isEmpty; 4112 !interfaces.isEmpty;
4129 interfaces = interfaces.tail) { 4113 interfaces = interfaces.tail) {
4130 addAllSupertypes(addSupertype, interfaces.head); 4114 allSupertypes.add(compiler, interfaces.head);
4131 } 4115 }
4132 4116
4133 allSupertypes.addLast(compiler.objectClass.rawType); 4117 addAllSupertypes(allSupertypes, supertype);
4134 cls.allSupertypes = allSupertypes.toLink(); 4118 for (Link<DartType> interfaces = cls.interfaces;
4119 !interfaces.isEmpty;
4120 interfaces = interfaces.tail) {
4121 addAllSupertypes(allSupertypes, interfaces.head);
4122 }
4123 allSupertypes.add(compiler, cls.computeType(compiler));
4124 cls.allSupertypesAndSelf = allSupertypes.toTypeSet();
4135 } else { 4125 } else {
4136 assert(identical(cls, compiler.objectClass)); 4126 assert(identical(cls, compiler.objectClass));
4137 cls.allSupertypes = const Link<DartType>(); 4127 cls.allSupertypesAndSelf =
4128 new OrderedTypeSet.singleton(cls.computeType(compiler));
4138 } 4129 }
4139 } 4130 }
4140 4131
4141 /** 4132 /**
4142 * Adds [type] and all supertypes of [type] to [allSupertypes] while 4133 * Adds [type] and all supertypes of [type] to [allSupertypes] while
4143 * substituting type variables. 4134 * substituting type variables.
4144 */ 4135 */
4145 void addAllSupertypes(void addSupertype(DartType supertype), 4136 void addAllSupertypes(OrderedTypeSetBuilder allSupertypes,
4146 InterfaceType type) { 4137 InterfaceType type) {
4147 Link<DartType> typeArguments = type.typeArguments; 4138 Link<DartType> typeArguments = type.typeArguments;
4148 ClassElement classElement = type.element; 4139 ClassElement classElement = type.element;
4149 Link<DartType> typeVariables = classElement.typeVariables; 4140 Link<DartType> typeVariables = classElement.typeVariables;
4150 Link<DartType> supertypes = classElement.allSupertypes; 4141 Link<DartType> supertypes = classElement.allSupertypes;
4151 assert(invariant(element, supertypes != null, 4142 assert(invariant(element, supertypes != null,
4152 message: "Supertypes not computed on $classElement " 4143 message: "Supertypes not computed on $classElement "
4153 "during resolution of $element")); 4144 "during resolution of $element"));
4154 while (!supertypes.isEmpty) { 4145 while (!supertypes.isEmpty) {
4155 DartType supertype = supertypes.head; 4146 DartType supertype = supertypes.head;
4156 if (supertype.element != compiler.objectClass) { 4147 allSupertypes.add(compiler,
4157 DartType substituted = supertype.subst(typeArguments, typeVariables); 4148 supertype.subst(typeArguments, typeVariables));
4158 addSupertype(substituted);
4159 }
4160 supertypes = supertypes.tail; 4149 supertypes = supertypes.tail;
4161 } 4150 }
4162 } 4151 }
4163 4152
4164 isBlackListed(DartType type) { 4153 isBlackListed(DartType type) {
4165 LibraryElement lib = element.getLibrary(); 4154 LibraryElement lib = element.getLibrary();
4166 return 4155 return
4167 !identical(lib, compiler.coreLibrary) && 4156 !identical(lib, compiler.coreLibrary) &&
4168 !identical(lib, compiler.jsHelperLibrary) && 4157 !identical(lib, compiler.jsHelperLibrary) &&
4169 !identical(lib, compiler.interceptorsLibrary) && 4158 !identical(lib, compiler.interceptorsLibrary) &&
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
4751 return finishConstructorReference(visit(expression), 4740 return finishConstructorReference(visit(expression),
4752 expression, expression); 4741 expression, expression);
4753 } 4742 }
4754 } 4743 }
4755 4744
4756 /// Looks up [name] in [scope] and unwraps the result. 4745 /// Looks up [name] in [scope] and unwraps the result.
4757 Element lookupInScope(Compiler compiler, Node node, 4746 Element lookupInScope(Compiler compiler, Node node,
4758 Scope scope, String name) { 4747 Scope scope, String name) {
4759 return Elements.unwrap(scope.lookup(name), compiler, node); 4748 return Elements.unwrap(scope.lookup(name), compiler, node);
4760 } 4749 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698