OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4074 {'type': interfaceType}); | 4079 {'type': interfaceType}); |
4075 } | 4080 } |
4076 } | 4081 } |
4077 } | 4082 } |
4078 } | 4083 } |
4079 return result; | 4084 return result; |
4080 } | 4085 } |
4081 | 4086 |
4082 /** | 4087 /** |
4083 * Compute the list of all supertypes. | 4088 * Compute the list of all supertypes. |
4084 * | |
karlklose
2013/11/21 13:29:10
Please restore this line.
Johnni Winther
2013/11/25 13:58:27
Done.
| |
4085 * The elements of this list are ordered as follows: first the supertype that | 4089 * The elements of this list are ordered as follows: first the supertype that |
4086 * the class extends, then the implemented interfaces, and then the supertypes | 4090 * the class extends, then the implemented interfaces, and then the supertypes |
4087 * of these. The class [Object] appears only once, at the end of the list. | 4091 * of these. The class [Object] appears only once, at the end of the list. |
4088 * | 4092 * |
4089 * For example, for a class `class C extends S implements I1, I2`, we compute | 4093 * For example, for a class `class C extends S implements I1, I2`, we compute |
4090 * supertypes(C) = [S, I1, I2] ++ supertypes(S) ++ supertypes(I1) | 4094 * supertypes(C) = [S, I1, I2] ++ supertypes(S) ++ supertypes(I1) |
karlklose
2013/11/21 13:29:10
Is this invariant still valid?
Johnni Winther
2013/11/25 13:58:27
Yes.
| |
4091 * ++ supertypes(I2), | 4095 * ++ supertypes(I2), |
4092 * where ++ stands for list concatenation. | 4096 * where ++ stands for list concatenation. |
4093 * | 4097 * |
4094 * This order makes sure that if a class implements an interface twice with | 4098 * 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 | 4099 * different type arguments, the type used in the most specific class comes |
4096 * first. | 4100 * first. |
4097 */ | 4101 */ |
4098 void calculateAllSupertypes(ClassElement cls) { | 4102 void calculateAllSupertypes(BaseClassElementX cls) { |
4099 if (cls.allSupertypes != null) return; | 4103 if (cls.allSupertypesAndSelf != null) return; |
4100 final DartType supertype = cls.supertype; | 4104 final DartType supertype = cls.supertype; |
4101 if (supertype != null) { | 4105 if (supertype != null) { |
4102 Map<Element, DartType> instantiations = new Map<Element, DartType>(); | 4106 OrderedTypeSetBuilder allSupertypes = new OrderedTypeSetBuilder(cls); |
karlklose
2013/11/21 13:29:10
Could this iteration be part of the OrderedTypeSet
Johnni Winther
2013/11/25 13:58:27
Added a TODO.
| |
4103 LinkBuilder<DartType> allSupertypes = new LinkBuilder<DartType>(); | 4107 allSupertypes.add(compiler, supertype); |
4104 | |
4105 void addSupertype(DartType type) { | |
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; | 4108 for (Link<DartType> interfaces = cls.interfaces; |
4128 !interfaces.isEmpty; | 4109 !interfaces.isEmpty; |
4129 interfaces = interfaces.tail) { | 4110 interfaces = interfaces.tail) { |
4130 addAllSupertypes(addSupertype, interfaces.head); | 4111 allSupertypes.add(compiler, interfaces.head); |
4131 } | 4112 } |
4132 | 4113 |
4133 allSupertypes.addLast(compiler.objectClass.rawType); | 4114 addAllSupertypes(allSupertypes, supertype); |
4134 cls.allSupertypes = allSupertypes.toLink(); | 4115 for (Link<DartType> interfaces = cls.interfaces; |
4116 !interfaces.isEmpty; | |
4117 interfaces = interfaces.tail) { | |
4118 addAllSupertypes(allSupertypes, interfaces.head); | |
4119 } | |
4120 allSupertypes.add(compiler, cls.computeType(compiler)); | |
karlklose
2013/11/21 13:29:10
Ditto.
Johnni Winther
2013/11/25 13:58:27
Done.
| |
4121 cls.allSupertypesAndSelf = allSupertypes.toSet(); | |
4135 } else { | 4122 } else { |
4136 assert(identical(cls, compiler.objectClass)); | 4123 assert(identical(cls, compiler.objectClass)); |
4137 cls.allSupertypes = const Link<DartType>(); | 4124 cls.allSupertypesAndSelf = |
4125 new OrderedTypeSet.singleton(cls.computeType(compiler)); | |
4138 } | 4126 } |
4139 } | 4127 } |
4140 | 4128 |
4141 /** | 4129 /** |
4142 * Adds [type] and all supertypes of [type] to [allSupertypes] while | 4130 * Adds [type] and all supertypes of [type] to [allSupertypes] while |
4143 * substituting type variables. | 4131 * substituting type variables. |
4144 */ | 4132 */ |
4145 void addAllSupertypes(void addSupertype(DartType supertype), | 4133 void addAllSupertypes(OrderedTypeSetBuilder allSupertypes, |
4146 InterfaceType type) { | 4134 InterfaceType type) { |
4147 Link<DartType> typeArguments = type.typeArguments; | 4135 Link<DartType> typeArguments = type.typeArguments; |
4148 ClassElement classElement = type.element; | 4136 ClassElement classElement = type.element; |
4149 Link<DartType> typeVariables = classElement.typeVariables; | 4137 Link<DartType> typeVariables = classElement.typeVariables; |
4150 Link<DartType> supertypes = classElement.allSupertypes; | 4138 Link<DartType> supertypes = classElement.allSupertypes; |
4151 assert(invariant(element, supertypes != null, | 4139 assert(invariant(element, supertypes != null, |
4152 message: "Supertypes not computed on $classElement " | 4140 message: "Supertypes not computed on $classElement " |
4153 "during resolution of $element")); | 4141 "during resolution of $element")); |
4154 while (!supertypes.isEmpty) { | 4142 while (!supertypes.isEmpty) { |
4155 DartType supertype = supertypes.head; | 4143 DartType supertype = supertypes.head; |
4156 if (supertype.element != compiler.objectClass) { | 4144 allSupertypes.add(compiler, |
4157 DartType substituted = supertype.subst(typeArguments, typeVariables); | 4145 supertype.subst(typeArguments, typeVariables)); |
4158 addSupertype(substituted); | |
4159 } | |
4160 supertypes = supertypes.tail; | 4146 supertypes = supertypes.tail; |
4161 } | 4147 } |
4162 } | 4148 } |
4163 | 4149 |
4164 isBlackListed(DartType type) { | 4150 isBlackListed(DartType type) { |
4165 LibraryElement lib = element.getLibrary(); | 4151 LibraryElement lib = element.getLibrary(); |
4166 return | 4152 return |
4167 !identical(lib, compiler.coreLibrary) && | 4153 !identical(lib, compiler.coreLibrary) && |
4168 !identical(lib, compiler.jsHelperLibrary) && | 4154 !identical(lib, compiler.jsHelperLibrary) && |
4169 !identical(lib, compiler.interceptorsLibrary) && | 4155 !identical(lib, compiler.interceptorsLibrary) && |
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4751 return finishConstructorReference(visit(expression), | 4737 return finishConstructorReference(visit(expression), |
4752 expression, expression); | 4738 expression, expression); |
4753 } | 4739 } |
4754 } | 4740 } |
4755 | 4741 |
4756 /// Looks up [name] in [scope] and unwraps the result. | 4742 /// Looks up [name] in [scope] and unwraps the result. |
4757 Element lookupInScope(Compiler compiler, Node node, | 4743 Element lookupInScope(Compiler compiler, Node node, |
4758 Scope scope, String name) { | 4744 Scope scope, String name) { |
4759 return Elements.unwrap(scope.lookup(name), compiler, node); | 4745 return Elements.unwrap(scope.lookup(name), compiler, node); |
4760 } | 4746 } |
OLD | NEW |