OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 // This code was auto-generated, is not intended to be edited, and is subject to | 5 // This code was auto-generated, is not intended to be edited, and is subject to |
6 // significant change. Please see the README file for more information. | 6 // significant change. Please see the README file for more information. |
7 | 7 |
8 library engine.element; | 8 library engine.element; |
9 | 9 |
10 import 'dart:collection'; | 10 import 'dart:collection'; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 @override | 77 @override |
78 int get hashCode => 0; | 78 int get hashCode => 0; |
79 | 79 |
80 @override | 80 @override |
81 bool get isBottom => true; | 81 bool get isBottom => true; |
82 | 82 |
83 @override | 83 @override |
84 bool operator ==(Object object) => identical(object, this); | 84 bool operator ==(Object object) => identical(object, this); |
85 | 85 |
86 @override | 86 @override |
87 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => | 87 bool isMoreSpecificThan(DartType type, |
88 identical(object, this); | 88 [bool withDynamic = false, Set<Element> visitedElements]) => true; |
89 | 89 |
90 @override | 90 @override |
91 int internalHashCode(List<DartType> visitedTypes) => hashCode; | 91 bool isSubtypeOf(DartType type) => true; |
92 | |
93 @override | |
94 bool isMoreSpecificThan(DartType type, [Set<Element> thisExpansions, | |
95 Set<Element> typeExpansions, bool withDynamic = false, | |
96 Set<Element> visitedElements]) => true; | |
97 | |
98 @override | |
99 bool isSubtypeOf(DartType type, | |
100 [Set<Element> thisExpansions, Set<Element> typeExpansions]) => true; | |
101 | 92 |
102 @override | 93 @override |
103 bool isSupertypeOf(DartType type) => false; | 94 bool isSupertypeOf(DartType type) => false; |
104 | 95 |
105 @override | 96 @override |
| 97 TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this; |
| 98 |
| 99 @override |
106 BottomTypeImpl substitute2( | 100 BottomTypeImpl substitute2( |
107 List<DartType> argumentTypes, List<DartType> parameterTypes) => this; | 101 List<DartType> argumentTypes, List<DartType> parameterTypes, |
| 102 [List<FunctionTypeAliasElement> prune]) => this; |
108 } | 103 } |
109 | 104 |
110 /** | 105 /** |
| 106 * Type created internally if a circular reference is ever detected. Behaves |
| 107 * like `dynamic`, except that when converted to a string it is displayed as |
| 108 * `...`. |
| 109 */ |
| 110 class CircularTypeImpl extends DynamicTypeImpl { |
| 111 CircularTypeImpl() : super._circular(); |
| 112 |
| 113 @override |
| 114 int get hashCode => 1; |
| 115 |
| 116 @override |
| 117 bool operator ==(Object object) => object is CircularTypeImpl; |
| 118 |
| 119 @override |
| 120 void appendTo(StringBuffer buffer) { |
| 121 buffer.write('...'); |
| 122 } |
| 123 |
| 124 @override |
| 125 TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this; |
| 126 } |
| 127 |
| 128 /** |
111 * An element that represents a class. | 129 * An element that represents a class. |
112 */ | 130 */ |
113 abstract class ClassElement implements Element { | 131 abstract class ClassElement implements Element { |
114 /** | 132 /** |
115 * An empty list of class elements. | 133 * An empty list of class elements. |
116 */ | 134 */ |
117 static const List<ClassElement> EMPTY_LIST = const <ClassElement>[]; | 135 static const List<ClassElement> EMPTY_LIST = const <ClassElement>[]; |
118 | 136 |
119 /** | 137 /** |
120 * Return a list containing all of the accessors (getters and setters) | 138 * Return a list containing all of the accessors (getters and setters) |
(...skipping 1951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2072 * The notation <i>[x<sub>1</sub>, ..., x<sub>n</sub>/y<sub>1</sub>, ..., | 2090 * The notation <i>[x<sub>1</sub>, ..., x<sub>n</sub>/y<sub>1</sub>, ..., |
2073 * y<sub>n</sub>]E</i> denotes a copy of <i>E</i> in which all occurrences of | 2091 * y<sub>n</sub>]E</i> denotes a copy of <i>E</i> in which all occurrences of |
2074 * <i>y<sub>i</sub>, 1 <= i <= n</i> have been replaced with | 2092 * <i>y<sub>i</sub>, 1 <= i <= n</i> have been replaced with |
2075 * <i>x<sub>i</sub></i>. | 2093 * <i>x<sub>i</sub></i>. |
2076 * </blockquote> | 2094 * </blockquote> |
2077 * Note that, contrary to the specification, this method will not create a | 2095 * Note that, contrary to the specification, this method will not create a |
2078 * copy of this type if no substitutions were required, but will return this | 2096 * copy of this type if no substitutions were required, but will return this |
2079 * type directly. | 2097 * type directly. |
2080 * | 2098 * |
2081 * Note too that the current implementation of this method is only guaranteed | 2099 * Note too that the current implementation of this method is only guaranteed |
2082 * to work when the argument types are type variables. | 2100 * to work when the parameter types are type variables. |
2083 */ | 2101 */ |
2084 DartType substitute2( | 2102 DartType substitute2( |
2085 List<DartType> argumentTypes, List<DartType> parameterTypes); | 2103 List<DartType> argumentTypes, List<DartType> parameterTypes); |
2086 } | 2104 } |
2087 | 2105 |
2088 /** | 2106 /** |
2089 * A [FieldFormalParameterElementImpl] for parameters that have an initializer. | 2107 * A [FieldFormalParameterElementImpl] for parameters that have an initializer. |
2090 */ | 2108 */ |
2091 class DefaultFieldFormalParameterElementImpl | 2109 class DefaultFieldFormalParameterElementImpl |
2092 extends FieldFormalParameterElementImpl with ConstVariableElement { | 2110 extends FieldFormalParameterElementImpl with ConstVariableElement { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2184 static DynamicTypeImpl get instance => _INSTANCE; | 2202 static DynamicTypeImpl get instance => _INSTANCE; |
2185 | 2203 |
2186 /** | 2204 /** |
2187 * Prevent the creation of instances of this class. | 2205 * Prevent the creation of instances of this class. |
2188 */ | 2206 */ |
2189 DynamicTypeImpl._() | 2207 DynamicTypeImpl._() |
2190 : super(new DynamicElementImpl(), Keyword.DYNAMIC.syntax) { | 2208 : super(new DynamicElementImpl(), Keyword.DYNAMIC.syntax) { |
2191 (element as DynamicElementImpl).type = this; | 2209 (element as DynamicElementImpl).type = this; |
2192 } | 2210 } |
2193 | 2211 |
| 2212 /** |
| 2213 * Constructor used by [CircularTypeImpl]. |
| 2214 */ |
| 2215 DynamicTypeImpl._circular() |
| 2216 : super(_INSTANCE.element, Keyword.DYNAMIC.syntax); |
| 2217 |
2194 @override | 2218 @override |
2195 int get hashCode => 1; | 2219 int get hashCode => 1; |
2196 | 2220 |
2197 @override | 2221 @override |
2198 bool get isDynamic => true; | 2222 bool get isDynamic => true; |
2199 | 2223 |
2200 @override | 2224 @override |
2201 bool operator ==(Object object) => identical(object, this); | 2225 bool operator ==(Object object) => identical(object, this); |
2202 | 2226 |
2203 @override | 2227 @override |
2204 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => | 2228 bool isMoreSpecificThan(DartType type, |
2205 identical(object, this); | 2229 [bool withDynamic = false, Set<Element> visitedElements]) { |
2206 | |
2207 @override | |
2208 int internalHashCode(List<DartType> visitedTypes) => hashCode; | |
2209 | |
2210 @override | |
2211 bool isMoreSpecificThan(DartType type, [Set<Element> thisExpansions, | |
2212 Set<Element> typeExpansions, bool withDynamic = false, | |
2213 Set<Element> visitedElements]) { | |
2214 // T is S | 2230 // T is S |
2215 if (identical(this, type)) { | 2231 if (identical(this, type)) { |
2216 return true; | 2232 return true; |
2217 } | 2233 } |
2218 // else | 2234 // else |
2219 return withDynamic; | 2235 return withDynamic; |
2220 } | 2236 } |
2221 | 2237 |
2222 @override | 2238 @override |
2223 bool isSubtypeOf(DartType type, | 2239 bool isSubtypeOf(DartType type) => true; |
2224 [Set<Element> thisExpansions, Set<Element> typeExpansions]) => true; | |
2225 | 2240 |
2226 @override | 2241 @override |
2227 bool isSupertypeOf(DartType type) => true; | 2242 bool isSupertypeOf(DartType type) => true; |
2228 | 2243 |
2229 @override | 2244 @override |
| 2245 TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this; |
| 2246 |
| 2247 @override |
2230 DartType substitute2( | 2248 DartType substitute2( |
2231 List<DartType> argumentTypes, List<DartType> parameterTypes) { | 2249 List<DartType> argumentTypes, List<DartType> parameterTypes, |
| 2250 [List<FunctionTypeAliasElement> prune]) { |
2232 int length = parameterTypes.length; | 2251 int length = parameterTypes.length; |
2233 for (int i = 0; i < length; i++) { | 2252 for (int i = 0; i < length; i++) { |
2234 if (parameterTypes[i] == this) { | 2253 if (parameterTypes[i] == this) { |
2235 return argumentTypes[i]; | 2254 return argumentTypes[i]; |
2236 } | 2255 } |
2237 } | 2256 } |
2238 return this; | 2257 return this; |
2239 } | 2258 } |
2240 } | 2259 } |
2241 | 2260 |
(...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3230 int currentChar = component.codeUnitAt(i); | 3249 int currentChar = component.codeUnitAt(i); |
3231 if (currentChar == _SEPARATOR_CHAR) { | 3250 if (currentChar == _SEPARATOR_CHAR) { |
3232 buffer.writeCharCode(_SEPARATOR_CHAR); | 3251 buffer.writeCharCode(_SEPARATOR_CHAR); |
3233 } | 3252 } |
3234 buffer.writeCharCode(currentChar); | 3253 buffer.writeCharCode(currentChar); |
3235 } | 3254 } |
3236 } | 3255 } |
3237 } | 3256 } |
3238 | 3257 |
3239 /** | 3258 /** |
3240 * A pair of [Element]s. [Object.==] and | |
3241 * [Object.hashCode] so this class can be used in hashed data structures. | |
3242 */ | |
3243 class ElementPair { | |
3244 /** | |
3245 * The first [Element]. | |
3246 */ | |
3247 final Element _first; | |
3248 | |
3249 /** | |
3250 * The second [Element]. | |
3251 */ | |
3252 final Element _second; | |
3253 | |
3254 /** | |
3255 * A cached copy of the calculated hashCode for this element. | |
3256 */ | |
3257 int _cachedHashCode; | |
3258 | |
3259 /** | |
3260 * Initialize a newly created pair of elements consisting of the [_first] and | |
3261 * [_second] elements. | |
3262 */ | |
3263 ElementPair(this._first, this._second) { | |
3264 _cachedHashCode = JenkinsSmiHash.hash2(_first.hashCode, _second.hashCode); | |
3265 } | |
3266 | |
3267 /** | |
3268 * Return the first element. | |
3269 */ | |
3270 Element get firstElt => _first; | |
3271 | |
3272 @override | |
3273 int get hashCode { | |
3274 return _cachedHashCode; | |
3275 } | |
3276 | |
3277 /** | |
3278 * Return the second element | |
3279 */ | |
3280 Element get secondElt => _second; | |
3281 | |
3282 @override | |
3283 bool operator ==(Object object) { | |
3284 if (identical(object, this)) { | |
3285 return true; | |
3286 } | |
3287 return object is ElementPair && | |
3288 _first == object._first && | |
3289 _second == object._second; | |
3290 } | |
3291 } | |
3292 | |
3293 /** | |
3294 * An object that can be used to visit an element structure. | 3259 * An object that can be used to visit an element structure. |
3295 */ | 3260 */ |
3296 abstract class ElementVisitor<R> { | 3261 abstract class ElementVisitor<R> { |
3297 R visitClassElement(ClassElement element); | 3262 R visitClassElement(ClassElement element); |
3298 | 3263 |
3299 R visitCompilationUnitElement(CompilationUnitElement element); | 3264 R visitCompilationUnitElement(CompilationUnitElement element); |
3300 | 3265 |
3301 R visitConstructorElement(ConstructorElement element); | 3266 R visitConstructorElement(ConstructorElement element); |
3302 | 3267 |
3303 R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element); | 3268 R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element); |
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4601 /** | 4566 /** |
4602 * The type of a function, method, constructor, getter, or setter. | 4567 * The type of a function, method, constructor, getter, or setter. |
4603 */ | 4568 */ |
4604 class FunctionTypeImpl extends TypeImpl implements FunctionType { | 4569 class FunctionTypeImpl extends TypeImpl implements FunctionType { |
4605 /** | 4570 /** |
4606 * A list containing the actual types of the type arguments. | 4571 * A list containing the actual types of the type arguments. |
4607 */ | 4572 */ |
4608 List<DartType> typeArguments = DartType.EMPTY_LIST; | 4573 List<DartType> typeArguments = DartType.EMPTY_LIST; |
4609 | 4574 |
4610 /** | 4575 /** |
| 4576 * The set of typedefs which should not be expanded when exploring this type, |
| 4577 * to avoid creating infinite types in response to self-referential typedefs. |
| 4578 */ |
| 4579 final List<FunctionTypeAliasElement> prunedTypedefs; |
| 4580 |
| 4581 /** |
4611 * Initialize a newly created function type to be declared by the given | 4582 * Initialize a newly created function type to be declared by the given |
4612 * [element]. | 4583 * [element]. |
4613 */ | 4584 */ |
4614 FunctionTypeImpl(ExecutableElement element) : super(element, null); | 4585 FunctionTypeImpl(ExecutableElement element, [this.prunedTypedefs]) |
| 4586 : super(element, null); |
4615 | 4587 |
4616 /** | 4588 /** |
4617 * Initialize a newly created function type to be declared by the given | 4589 * Initialize a newly created function type to be declared by the given |
4618 * [element]. | 4590 * [element]. |
4619 */ | 4591 */ |
4620 @deprecated // Use new FunctionTypeImpl(element) | 4592 @deprecated // Use new FunctionTypeImpl(element) |
4621 FunctionTypeImpl.con1(ExecutableElement element) : super(element, null); | 4593 FunctionTypeImpl.con1(ExecutableElement element) |
| 4594 : prunedTypedefs = null, |
| 4595 super(element, null); |
4622 | 4596 |
4623 /** | 4597 /** |
4624 * Initialize a newly created function type to be declared by the given | 4598 * Initialize a newly created function type to be declared by the given |
4625 * [element]. | 4599 * [element]. |
4626 */ | 4600 */ |
4627 @deprecated // Use new FunctionTypeImpl.forTypedef(element) | 4601 @deprecated // Use new FunctionTypeImpl.forTypedef(element) |
4628 FunctionTypeImpl.con2(FunctionTypeAliasElement element) | 4602 FunctionTypeImpl.con2(FunctionTypeAliasElement element) |
4629 : super(element, element == null ? null : element.name); | 4603 : prunedTypedefs = null, |
| 4604 super(element, element == null ? null : element.name); |
4630 | 4605 |
4631 /** | 4606 /** |
4632 * Initialize a newly created function type to be declared by the given | 4607 * Initialize a newly created function type to be declared by the given |
4633 * [element]. | 4608 * [element]. |
4634 */ | 4609 */ |
4635 FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element) | 4610 FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element, |
| 4611 [this.prunedTypedefs]) |
4636 : super(element, element == null ? null : element.name); | 4612 : super(element, element == null ? null : element.name); |
4637 | 4613 |
4638 /** | 4614 /** |
| 4615 * Private constructor. |
| 4616 */ |
| 4617 FunctionTypeImpl._(Element element, String name, this.prunedTypedefs) |
| 4618 : super(element, name); |
| 4619 |
| 4620 /** |
4639 * Return the base parameter elements of this function element. | 4621 * Return the base parameter elements of this function element. |
4640 */ | 4622 */ |
4641 List<ParameterElement> get baseParameters { | 4623 List<ParameterElement> get baseParameters { |
4642 Element element = this.element; | 4624 Element element = this.element; |
4643 if (element is ExecutableElement) { | 4625 if (element is ExecutableElement) { |
4644 return element.parameters; | 4626 return element.parameters; |
4645 } else { | 4627 } else { |
4646 return (element as FunctionTypeAliasElement).parameters; | 4628 return (element as FunctionTypeAliasElement).parameters; |
4647 } | 4629 } |
4648 } | 4630 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4724 buffer.write("null"); | 4706 buffer.write("null"); |
4725 } else { | 4707 } else { |
4726 buffer.write(returnType.displayName); | 4708 buffer.write(returnType.displayName); |
4727 } | 4709 } |
4728 name = buffer.toString(); | 4710 name = buffer.toString(); |
4729 } | 4711 } |
4730 return name; | 4712 return name; |
4731 } | 4713 } |
4732 | 4714 |
4733 @override | 4715 @override |
4734 int get hashCode => internalHashCode(<DartType>[]); | 4716 int get hashCode { |
| 4717 if (element == null) { |
| 4718 return 0; |
| 4719 } |
| 4720 // Reference the arrays of parameters |
| 4721 List<DartType> normalParameterTypes = this.normalParameterTypes; |
| 4722 List<DartType> optionalParameterTypes = this.optionalParameterTypes; |
| 4723 Iterable<DartType> namedParameterTypes = this.namedParameterTypes.values; |
| 4724 // Generate the hashCode |
| 4725 int code = (returnType as TypeImpl).hashCode; |
| 4726 for (int i = 0; i < normalParameterTypes.length; i++) { |
| 4727 code = (code << 1) + (normalParameterTypes[i] as TypeImpl).hashCode; |
| 4728 } |
| 4729 for (int i = 0; i < optionalParameterTypes.length; i++) { |
| 4730 code = (code << 1) + (optionalParameterTypes[i] as TypeImpl).hashCode; |
| 4731 } |
| 4732 for (DartType type in namedParameterTypes) { |
| 4733 code = (code << 1) + (type as TypeImpl).hashCode; |
| 4734 } |
| 4735 return code; |
| 4736 } |
4735 | 4737 |
4736 @override | 4738 @override |
4737 Map<String, DartType> get namedParameterTypes { | 4739 Map<String, DartType> get namedParameterTypes { |
4738 LinkedHashMap<String, DartType> namedParameterTypes = | 4740 LinkedHashMap<String, DartType> namedParameterTypes = |
4739 new LinkedHashMap<String, DartType>(); | 4741 new LinkedHashMap<String, DartType>(); |
4740 List<ParameterElement> parameters = baseParameters; | 4742 List<ParameterElement> parameters = baseParameters; |
4741 if (parameters.length == 0) { | 4743 if (parameters.length == 0) { |
4742 return namedParameterTypes; | 4744 return namedParameterTypes; |
4743 } | 4745 } |
4744 List<DartType> typeParameters = | 4746 List<DartType> typeParameters = |
4745 TypeParameterTypeImpl.getTypes(this.typeParameters); | 4747 TypeParameterTypeImpl.getTypes(this.typeParameters); |
4746 for (ParameterElement parameter in parameters) { | 4748 for (ParameterElement parameter in parameters) { |
4747 if (parameter.parameterKind == ParameterKind.NAMED) { | 4749 if (parameter.parameterKind == ParameterKind.NAMED) { |
4748 DartType type = parameter.type; | 4750 DartType type = parameter.type; |
4749 if (typeArguments.length != 0 && | 4751 if (typeArguments.length != 0 && |
4750 typeArguments.length == typeParameters.length) { | 4752 typeArguments.length == typeParameters.length) { |
4751 type = type.substitute2(typeArguments, typeParameters); | 4753 type = (type as TypeImpl).substitute2( |
| 4754 typeArguments, typeParameters, newPrune); |
| 4755 } else { |
| 4756 type = (type as TypeImpl).pruned(newPrune); |
4752 } | 4757 } |
4753 namedParameterTypes[parameter.name] = type; | 4758 namedParameterTypes[parameter.name] = type; |
4754 } | 4759 } |
4755 } | 4760 } |
4756 return namedParameterTypes; | 4761 return namedParameterTypes; |
4757 } | 4762 } |
4758 | 4763 |
| 4764 /** |
| 4765 * Determine the new set of typedefs which should be pruned when expanding |
| 4766 * this function type. |
| 4767 */ |
| 4768 List<FunctionTypeAliasElement> get newPrune { |
| 4769 Element element = this.element; |
| 4770 if (element is FunctionTypeAliasElement && !element.isSynthetic) { |
| 4771 // This typedef should be pruned, along with anything that was previously |
| 4772 // pruned. |
| 4773 if (prunedTypedefs == null) { |
| 4774 return <FunctionTypeAliasElement>[element]; |
| 4775 } else { |
| 4776 return new List<FunctionTypeAliasElement>.from(prunedTypedefs) |
| 4777 ..add(element); |
| 4778 } |
| 4779 } else { |
| 4780 // This is not a typedef, so nothing additional needs to be pruned. |
| 4781 return prunedTypedefs; |
| 4782 } |
| 4783 } |
| 4784 |
4759 @override | 4785 @override |
4760 List<DartType> get normalParameterTypes { | 4786 List<DartType> get normalParameterTypes { |
4761 List<ParameterElement> parameters = baseParameters; | 4787 List<ParameterElement> parameters = baseParameters; |
4762 if (parameters.length == 0) { | 4788 if (parameters.length == 0) { |
4763 return DartType.EMPTY_LIST; | 4789 return DartType.EMPTY_LIST; |
4764 } | 4790 } |
4765 List<DartType> typeParameters = | 4791 List<DartType> typeParameters = |
4766 TypeParameterTypeImpl.getTypes(this.typeParameters); | 4792 TypeParameterTypeImpl.getTypes(this.typeParameters); |
4767 List<DartType> types = new List<DartType>(); | 4793 List<DartType> types = new List<DartType>(); |
4768 for (ParameterElement parameter in parameters) { | 4794 for (ParameterElement parameter in parameters) { |
4769 if (parameter.parameterKind == ParameterKind.REQUIRED) { | 4795 if (parameter.parameterKind == ParameterKind.REQUIRED) { |
4770 DartType type = parameter.type; | 4796 DartType type = parameter.type; |
4771 if (typeArguments.length != 0 && | 4797 if (typeArguments.length != 0 && |
4772 typeArguments.length == typeParameters.length) { | 4798 typeArguments.length == typeParameters.length) { |
4773 type = type.substitute2(typeArguments, typeParameters); | 4799 type = (type as TypeImpl).substitute2( |
| 4800 typeArguments, typeParameters, newPrune); |
| 4801 } else { |
| 4802 type = (type as TypeImpl).pruned(newPrune); |
4774 } | 4803 } |
4775 types.add(type); | 4804 types.add(type); |
4776 } | 4805 } |
4777 } | 4806 } |
4778 return types; | 4807 return types; |
4779 } | 4808 } |
4780 | 4809 |
4781 @override | 4810 @override |
4782 List<DartType> get optionalParameterTypes { | 4811 List<DartType> get optionalParameterTypes { |
4783 List<ParameterElement> parameters = baseParameters; | 4812 List<ParameterElement> parameters = baseParameters; |
4784 if (parameters.length == 0) { | 4813 if (parameters.length == 0) { |
4785 return DartType.EMPTY_LIST; | 4814 return DartType.EMPTY_LIST; |
4786 } | 4815 } |
4787 List<DartType> typeParameters = | 4816 List<DartType> typeParameters = |
4788 TypeParameterTypeImpl.getTypes(this.typeParameters); | 4817 TypeParameterTypeImpl.getTypes(this.typeParameters); |
4789 List<DartType> types = new List<DartType>(); | 4818 List<DartType> types = new List<DartType>(); |
4790 for (ParameterElement parameter in parameters) { | 4819 for (ParameterElement parameter in parameters) { |
4791 if (parameter.parameterKind == ParameterKind.POSITIONAL) { | 4820 if (parameter.parameterKind == ParameterKind.POSITIONAL) { |
4792 DartType type = parameter.type; | 4821 DartType type = parameter.type; |
4793 if (typeArguments.length != 0 && | 4822 if (typeArguments.length != 0 && |
4794 typeArguments.length == typeParameters.length) { | 4823 typeArguments.length == typeParameters.length) { |
4795 type = type.substitute2(typeArguments, typeParameters); | 4824 type = (type as TypeImpl).substitute2( |
| 4825 typeArguments, typeParameters, newPrune); |
| 4826 } else { |
| 4827 type = (type as TypeImpl).pruned(newPrune); |
4796 } | 4828 } |
4797 types.add(type); | 4829 types.add(type); |
4798 } | 4830 } |
4799 } | 4831 } |
4800 return types; | 4832 return types; |
4801 } | 4833 } |
4802 | 4834 |
4803 @override | 4835 @override |
4804 List<ParameterElement> get parameters { | 4836 List<ParameterElement> get parameters { |
4805 List<ParameterElement> baseParameters = this.baseParameters; | 4837 List<ParameterElement> baseParameters = this.baseParameters; |
(...skipping 16 matching lines...) Expand all Loading... |
4822 DartType baseReturnType = this.baseReturnType; | 4854 DartType baseReturnType = this.baseReturnType; |
4823 if (baseReturnType == null) { | 4855 if (baseReturnType == null) { |
4824 // TODO(brianwilkerson) This is a patch. The return type should never be | 4856 // TODO(brianwilkerson) This is a patch. The return type should never be |
4825 // null and we need to understand why it is and fix it. | 4857 // null and we need to understand why it is and fix it. |
4826 return DynamicTypeImpl.instance; | 4858 return DynamicTypeImpl.instance; |
4827 } | 4859 } |
4828 // If there are no arguments to substitute, or if the arguments size doesn't | 4860 // If there are no arguments to substitute, or if the arguments size doesn't |
4829 // match the parameter size, return the base return type. | 4861 // match the parameter size, return the base return type. |
4830 if (typeArguments.length == 0 || | 4862 if (typeArguments.length == 0 || |
4831 typeArguments.length != typeParameters.length) { | 4863 typeArguments.length != typeParameters.length) { |
4832 return baseReturnType; | 4864 return (baseReturnType as TypeImpl).pruned(newPrune); |
4833 } | 4865 } |
4834 return baseReturnType.substitute2( | 4866 return (baseReturnType as TypeImpl).substitute2(typeArguments, |
4835 typeArguments, TypeParameterTypeImpl.getTypes(typeParameters)); | 4867 TypeParameterTypeImpl.getTypes(typeParameters), newPrune); |
4836 } | 4868 } |
4837 | 4869 |
4838 @override | 4870 @override |
4839 List<TypeParameterElement> get typeParameters { | 4871 List<TypeParameterElement> get typeParameters { |
4840 Element element = this.element; | 4872 Element element = this.element; |
4841 if (element is FunctionTypeAliasElement) { | 4873 if (element is FunctionTypeAliasElement) { |
4842 return element.typeParameters; | 4874 return element.typeParameters; |
4843 } | 4875 } |
4844 ClassElement definingClass = | 4876 ClassElement definingClass = |
4845 element.getAncestor((element) => element is ClassElement); | 4877 element.getAncestor((element) => element is ClassElement); |
4846 if (definingClass != null) { | 4878 if (definingClass != null) { |
4847 return definingClass.typeParameters; | 4879 return definingClass.typeParameters; |
4848 } | 4880 } |
4849 return TypeParameterElement.EMPTY_LIST; | 4881 return TypeParameterElement.EMPTY_LIST; |
4850 } | 4882 } |
4851 | 4883 |
4852 @override | 4884 @override |
4853 bool operator ==(Object object) => | 4885 bool operator ==(Object object) { |
4854 internalEquals(object, new HashSet<ElementPair>()); | 4886 if (object is! FunctionTypeImpl) { |
| 4887 return false; |
| 4888 } |
| 4889 FunctionTypeImpl otherType = object as FunctionTypeImpl; |
| 4890 return TypeImpl.equalArrays( |
| 4891 normalParameterTypes, otherType.normalParameterTypes) && |
| 4892 TypeImpl.equalArrays( |
| 4893 optionalParameterTypes, otherType.optionalParameterTypes) && |
| 4894 _equals(namedParameterTypes, otherType.namedParameterTypes) && |
| 4895 returnType == otherType.returnType; |
| 4896 } |
4855 | 4897 |
4856 @override | 4898 @override |
4857 void appendTo(StringBuffer buffer, Set<DartType> visitedTypes) { | 4899 void appendTo(StringBuffer buffer) { |
4858 if (!visitedTypes.add(this)) { | |
4859 buffer.write(name == null ? '...' : name); | |
4860 return; | |
4861 } | |
4862 List<DartType> normalParameterTypes = this.normalParameterTypes; | 4900 List<DartType> normalParameterTypes = this.normalParameterTypes; |
4863 List<DartType> optionalParameterTypes = this.optionalParameterTypes; | 4901 List<DartType> optionalParameterTypes = this.optionalParameterTypes; |
4864 Map<String, DartType> namedParameterTypes = this.namedParameterTypes; | 4902 Map<String, DartType> namedParameterTypes = this.namedParameterTypes; |
4865 DartType returnType = this.returnType; | 4903 DartType returnType = this.returnType; |
4866 buffer.write("("); | 4904 buffer.write("("); |
4867 bool needsComma = false; | 4905 bool needsComma = false; |
4868 if (normalParameterTypes.length > 0) { | 4906 if (normalParameterTypes.length > 0) { |
4869 for (DartType type in normalParameterTypes) { | 4907 for (DartType type in normalParameterTypes) { |
4870 if (needsComma) { | 4908 if (needsComma) { |
4871 buffer.write(", "); | 4909 buffer.write(", "); |
4872 } else { | 4910 } else { |
4873 needsComma = true; | 4911 needsComma = true; |
4874 } | 4912 } |
4875 (type as TypeImpl).appendTo(buffer, visitedTypes); | 4913 (type as TypeImpl).appendTo(buffer); |
4876 } | 4914 } |
4877 } | 4915 } |
4878 if (optionalParameterTypes.length > 0) { | 4916 if (optionalParameterTypes.length > 0) { |
4879 if (needsComma) { | 4917 if (needsComma) { |
4880 buffer.write(", "); | 4918 buffer.write(", "); |
4881 needsComma = false; | 4919 needsComma = false; |
4882 } | 4920 } |
4883 buffer.write("["); | 4921 buffer.write("["); |
4884 for (DartType type in optionalParameterTypes) { | 4922 for (DartType type in optionalParameterTypes) { |
4885 if (needsComma) { | 4923 if (needsComma) { |
4886 buffer.write(", "); | 4924 buffer.write(", "); |
4887 } else { | 4925 } else { |
4888 needsComma = true; | 4926 needsComma = true; |
4889 } | 4927 } |
4890 (type as TypeImpl).appendTo(buffer, visitedTypes); | 4928 (type as TypeImpl).appendTo(buffer); |
4891 } | 4929 } |
4892 buffer.write("]"); | 4930 buffer.write("]"); |
4893 needsComma = true; | 4931 needsComma = true; |
4894 } | 4932 } |
4895 if (namedParameterTypes.length > 0) { | 4933 if (namedParameterTypes.length > 0) { |
4896 if (needsComma) { | 4934 if (needsComma) { |
4897 buffer.write(", "); | 4935 buffer.write(", "); |
4898 needsComma = false; | 4936 needsComma = false; |
4899 } | 4937 } |
4900 buffer.write("{"); | 4938 buffer.write("{"); |
4901 namedParameterTypes.forEach((String name, DartType type) { | 4939 namedParameterTypes.forEach((String name, DartType type) { |
4902 if (needsComma) { | 4940 if (needsComma) { |
4903 buffer.write(", "); | 4941 buffer.write(", "); |
4904 } else { | 4942 } else { |
4905 needsComma = true; | 4943 needsComma = true; |
4906 } | 4944 } |
4907 buffer.write(name); | 4945 buffer.write(name); |
4908 buffer.write(": "); | 4946 buffer.write(": "); |
4909 (type as TypeImpl).appendTo(buffer, visitedTypes); | 4947 (type as TypeImpl).appendTo(buffer); |
4910 }); | 4948 }); |
4911 buffer.write("}"); | 4949 buffer.write("}"); |
4912 needsComma = true; | 4950 needsComma = true; |
4913 } | 4951 } |
4914 buffer.write(")"); | 4952 buffer.write(")"); |
4915 buffer.write(Element.RIGHT_ARROW); | 4953 buffer.write(Element.RIGHT_ARROW); |
4916 if (returnType == null) { | 4954 if (returnType == null) { |
4917 buffer.write("null"); | 4955 buffer.write("null"); |
4918 } else { | 4956 } else { |
4919 (returnType as TypeImpl).appendTo(buffer, visitedTypes); | 4957 (returnType as TypeImpl).appendTo(buffer); |
4920 } | 4958 } |
4921 } | 4959 } |
4922 | 4960 |
4923 @override | 4961 @override |
4924 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) { | 4962 bool isAssignableTo(DartType type) { |
4925 if (object is! FunctionTypeImpl) { | 4963 // A function type T may be assigned to a function type S, written T <=> S, |
4926 return false; | 4964 // iff T <: S. |
4927 } | 4965 return isSubtypeOf(type); |
4928 FunctionTypeImpl otherType = object as FunctionTypeImpl; | |
4929 // If the visitedTypePairs already has the pair (this, type), | |
4930 // use the elements to determine equality | |
4931 ElementPair elementPair = new ElementPair(element, otherType.element); | |
4932 if (!visitedElementPairs.add(elementPair)) { | |
4933 return elementPair.firstElt == elementPair.secondElt; | |
4934 } | |
4935 // Compute the result | |
4936 bool result = TypeImpl.equalArrays(normalParameterTypes, | |
4937 otherType.normalParameterTypes, visitedElementPairs) && | |
4938 TypeImpl.equalArrays(optionalParameterTypes, | |
4939 otherType.optionalParameterTypes, visitedElementPairs) && | |
4940 _equals(namedParameterTypes, otherType.namedParameterTypes, | |
4941 visitedElementPairs) && | |
4942 (returnType as TypeImpl).internalEquals( | |
4943 otherType.returnType, visitedElementPairs); | |
4944 // Remove the pair from our visited pairs list | |
4945 visitedElementPairs.remove(elementPair); | |
4946 // Return the result | |
4947 return result; | |
4948 } | 4966 } |
4949 | 4967 |
4950 @override | 4968 @override |
4951 int internalHashCode(List<DartType> visitedTypes) { | 4969 bool isMoreSpecificThan(DartType type, |
4952 if (element == null) { | 4970 [bool withDynamic = false, Set<Element> visitedElements]) { |
4953 return 0; | |
4954 } else if (visitedTypes.contains(this)) { | |
4955 return 3; | |
4956 } | |
4957 visitedTypes.add(this); | |
4958 // Reference the arrays of parameters | |
4959 List<DartType> normalParameterTypes = this.normalParameterTypes; | |
4960 List<DartType> optionalParameterTypes = this.optionalParameterTypes; | |
4961 Iterable<DartType> namedParameterTypes = this.namedParameterTypes.values; | |
4962 // Generate the hashCode | |
4963 int code = (returnType as TypeImpl).internalHashCode(visitedTypes); | |
4964 for (int i = 0; i < normalParameterTypes.length; i++) { | |
4965 code = (code << 1) + | |
4966 (normalParameterTypes[i] as TypeImpl).internalHashCode(visitedTypes); | |
4967 } | |
4968 for (int i = 0; i < optionalParameterTypes.length; i++) { | |
4969 code = (code << 1) + | |
4970 (optionalParameterTypes[i] as TypeImpl) | |
4971 .internalHashCode(visitedTypes); | |
4972 } | |
4973 for (DartType type in namedParameterTypes) { | |
4974 code = (code << 1) + (type as TypeImpl).internalHashCode(visitedTypes); | |
4975 } | |
4976 return code; | |
4977 } | |
4978 | |
4979 @override | |
4980 bool isAssignableTo(DartType type, | |
4981 [Set<Element> thisExpansions, Set<Element> typeExpansions]) { | |
4982 // A function type T may be assigned to a function type S, written T <=> S, | |
4983 // iff T <: S. | |
4984 return isSubtypeOf(type, thisExpansions, typeExpansions); | |
4985 } | |
4986 | |
4987 @override | |
4988 bool isMoreSpecificThan(DartType type, [Set<Element> thisExpansions, | |
4989 Set<Element> typeExpansions, bool withDynamic = false, | |
4990 Set<Element> visitedElements]) { | |
4991 // Note: visitedElements is only used for breaking recursion in the type | 4971 // Note: visitedElements is only used for breaking recursion in the type |
4992 // hierarchy; we don't use it when recursing into the function type. | 4972 // hierarchy; we don't use it when recursing into the function type. |
4993 | 4973 |
4994 // trivial base cases | 4974 // trivial base cases |
4995 if (type == null) { | 4975 if (type == null) { |
4996 return false; | 4976 return false; |
4997 } else if (identical(this, type) || | 4977 } else if (identical(this, type) || |
4998 type.isDynamic || | 4978 type.isDynamic || |
4999 type.isDartCoreFunction || | 4979 type.isDartCoreFunction || |
5000 type.isObject) { | 4980 type.isObject) { |
5001 return true; | 4981 return true; |
5002 } else if (type is! FunctionType) { | 4982 } else if (type is! FunctionType) { |
5003 return false; | 4983 return false; |
5004 } else if (this == type) { | 4984 } else if (this == type) { |
5005 return true; | 4985 return true; |
5006 } | 4986 } |
5007 FunctionType t = this; | 4987 FunctionType t = this; |
5008 FunctionType s = type as FunctionType; | 4988 FunctionType s = type as FunctionType; |
5009 if (thisExpansions == null) { | 4989 List<DartType> tTypes = t.normalParameterTypes; |
5010 thisExpansions = new HashSet<Element>(); | 4990 List<DartType> tOpTypes = t.optionalParameterTypes; |
5011 } else if (thisExpansions.contains(this.element)) { | 4991 List<DartType> sTypes = s.normalParameterTypes; |
5012 // [this] contains a reference to itself, which is illegal (and is | 4992 List<DartType> sOpTypes = s.optionalParameterTypes; |
5013 // checked elsewhere). To avoid cascading errors, consider T to be a | 4993 // If one function has positional and the other has named parameters, |
5014 // subtype of S. | 4994 // return false. |
5015 return true; | 4995 if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) || |
| 4996 (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) { |
| 4997 return false; |
5016 } | 4998 } |
5017 if (typeExpansions == null) { | 4999 // named parameters case |
5018 typeExpansions = new HashSet<Element>(); | 5000 if (t.namedParameterTypes.length > 0) { |
5019 } else if (typeExpansions.contains(type.element)) { | 5001 // check that the number of required parameters are equal, and check that |
5020 // [type] contains a reference to itself, which is illegal (and is | 5002 // every t_i is more specific than every s_i |
5021 // checked elsewhere). To avoid cascading errors, consider T to be a | 5003 if (t.normalParameterTypes.length != s.normalParameterTypes.length) { |
5022 // subtype of S. | |
5023 return true; | |
5024 } | |
5025 thisExpansions.add(this.element); | |
5026 typeExpansions.add(type.element); | |
5027 try { | |
5028 List<DartType> tTypes = t.normalParameterTypes; | |
5029 List<DartType> tOpTypes = t.optionalParameterTypes; | |
5030 List<DartType> sTypes = s.normalParameterTypes; | |
5031 List<DartType> sOpTypes = s.optionalParameterTypes; | |
5032 // If one function has positional and the other has named parameters, | |
5033 // return false. | |
5034 if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) || | |
5035 (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) { | |
5036 return false; | 5004 return false; |
5037 } | 5005 } else if (t.normalParameterTypes.length > 0) { |
5038 // named parameters case | 5006 for (int i = 0; i < tTypes.length; i++) { |
5039 if (t.namedParameterTypes.length > 0) { | 5007 if (!(tTypes[i] as TypeImpl).isMoreSpecificThan( |
5040 // check that the number of required parameters are equal, and check tha
t | 5008 sTypes[i], withDynamic)) { |
5041 // every t_i is more specific than every s_i | |
5042 if (t.normalParameterTypes.length != s.normalParameterTypes.length) { | |
5043 return false; | |
5044 } else if (t.normalParameterTypes.length > 0) { | |
5045 for (int i = 0; i < tTypes.length; i++) { | |
5046 if (!(tTypes[i] as TypeImpl).isMoreSpecificThan( | |
5047 sTypes[i], thisExpansions, typeExpansions, withDynamic)) { | |
5048 return false; | |
5049 } | |
5050 } | |
5051 } | |
5052 Map<String, DartType> namedTypesT = t.namedParameterTypes; | |
5053 Map<String, DartType> namedTypesS = s.namedParameterTypes; | |
5054 // if k >= m is false, return false: the passed function type has more | |
5055 // named parameter types than this | |
5056 if (namedTypesT.length < namedTypesS.length) { | |
5057 return false; | |
5058 } | |
5059 // Loop through each element in S verifying that T has a matching | |
5060 // parameter name and that the corresponding type is more specific then | |
5061 // the type in S. | |
5062 for (String keyS in namedTypesS.keys) { | |
5063 DartType typeT = namedTypesT[keyS]; | |
5064 if (typeT == null) { | |
5065 return false; | |
5066 } | |
5067 if (!(typeT as TypeImpl).isMoreSpecificThan( | |
5068 namedTypesS[keyS], thisExpansions, typeExpansions, withDynamic)) { | |
5069 return false; | 5009 return false; |
5070 } | 5010 } |
5071 } | 5011 } |
5072 } else if (s.namedParameterTypes.length > 0) { | 5012 } |
| 5013 Map<String, DartType> namedTypesT = t.namedParameterTypes; |
| 5014 Map<String, DartType> namedTypesS = s.namedParameterTypes; |
| 5015 // if k >= m is false, return false: the passed function type has more |
| 5016 // named parameter types than this |
| 5017 if (namedTypesT.length < namedTypesS.length) { |
5073 return false; | 5018 return false; |
5074 } else { | 5019 } |
5075 // positional parameter case | 5020 // Loop through each element in S verifying that T has a matching |
5076 int tArgLength = tTypes.length + tOpTypes.length; | 5021 // parameter name and that the corresponding type is more specific then |
5077 int sArgLength = sTypes.length + sOpTypes.length; | 5022 // the type in S. |
5078 // Check that the total number of parameters in t is greater than or equ
al | 5023 for (String keyS in namedTypesS.keys) { |
5079 // to the number of parameters in s and that the number of required | 5024 DartType typeT = namedTypesT[keyS]; |
5080 // parameters in s is greater than or equal to the number of required | 5025 if (typeT == null) { |
5081 // parameters in t. | |
5082 if (tArgLength < sArgLength || sTypes.length < tTypes.length) { | |
5083 return false; | 5026 return false; |
5084 } | 5027 } |
5085 if (tOpTypes.length == 0 && sOpTypes.length == 0) { | 5028 if (!(typeT as TypeImpl).isMoreSpecificThan( |
5086 // No positional arguments, don't copy contents to new array | 5029 namedTypesS[keyS], withDynamic)) { |
5087 for (int i = 0; i < sTypes.length; i++) { | 5030 return false; |
5088 if (!(tTypes[i] as TypeImpl).isMoreSpecificThan( | 5031 } |
5089 sTypes[i], thisExpansions, typeExpansions, withDynamic)) { | 5032 } |
5090 return false; | 5033 } else if (s.namedParameterTypes.length > 0) { |
5091 } | 5034 return false; |
| 5035 } else { |
| 5036 // positional parameter case |
| 5037 int tArgLength = tTypes.length + tOpTypes.length; |
| 5038 int sArgLength = sTypes.length + sOpTypes.length; |
| 5039 // Check that the total number of parameters in t is greater than or equal |
| 5040 // to the number of parameters in s and that the number of required |
| 5041 // parameters in s is greater than or equal to the number of required |
| 5042 // parameters in t. |
| 5043 if (tArgLength < sArgLength || sTypes.length < tTypes.length) { |
| 5044 return false; |
| 5045 } |
| 5046 if (tOpTypes.length == 0 && sOpTypes.length == 0) { |
| 5047 // No positional arguments, don't copy contents to new array |
| 5048 for (int i = 0; i < sTypes.length; i++) { |
| 5049 if (!(tTypes[i] as TypeImpl).isMoreSpecificThan( |
| 5050 sTypes[i], withDynamic)) { |
| 5051 return false; |
5092 } | 5052 } |
5093 } else { | 5053 } |
5094 // Else, we do have positional parameters, copy required and positiona
l | 5054 } else { |
5095 // parameter types into arrays to do the compare (for loop below). | 5055 // Else, we do have positional parameters, copy required and positional |
5096 List<DartType> tAllTypes = new List<DartType>(sArgLength); | 5056 // parameter types into arrays to do the compare (for loop below). |
5097 for (int i = 0; i < tTypes.length; i++) { | 5057 List<DartType> tAllTypes = new List<DartType>(sArgLength); |
5098 tAllTypes[i] = tTypes[i]; | 5058 for (int i = 0; i < tTypes.length; i++) { |
5099 } | 5059 tAllTypes[i] = tTypes[i]; |
5100 for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) { | 5060 } |
5101 tAllTypes[i] = tOpTypes[j]; | 5061 for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) { |
5102 } | 5062 tAllTypes[i] = tOpTypes[j]; |
5103 List<DartType> sAllTypes = new List<DartType>(sArgLength); | 5063 } |
5104 for (int i = 0; i < sTypes.length; i++) { | 5064 List<DartType> sAllTypes = new List<DartType>(sArgLength); |
5105 sAllTypes[i] = sTypes[i]; | 5065 for (int i = 0; i < sTypes.length; i++) { |
5106 } | 5066 sAllTypes[i] = sTypes[i]; |
5107 for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) { | 5067 } |
5108 sAllTypes[i] = sOpTypes[j]; | 5068 for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) { |
5109 } | 5069 sAllTypes[i] = sOpTypes[j]; |
5110 for (int i = 0; i < sAllTypes.length; i++) { | 5070 } |
5111 if (!(tAllTypes[i] as TypeImpl).isMoreSpecificThan( | 5071 for (int i = 0; i < sAllTypes.length; i++) { |
5112 sAllTypes[i], thisExpansions, typeExpansions, withDynamic)) { | 5072 if (!(tAllTypes[i] as TypeImpl).isMoreSpecificThan( |
5113 return false; | 5073 sAllTypes[i], withDynamic)) { |
5114 } | 5074 return false; |
5115 } | 5075 } |
5116 } | 5076 } |
5117 } | 5077 } |
5118 DartType tRetType = t.returnType; | |
5119 DartType sRetType = s.returnType; | |
5120 return sRetType.isVoid || | |
5121 (tRetType as TypeImpl).isMoreSpecificThan( | |
5122 sRetType, thisExpansions, typeExpansions, withDynamic); | |
5123 } finally { | |
5124 thisExpansions.remove(this.element); | |
5125 typeExpansions.remove(type.element); | |
5126 } | 5078 } |
| 5079 DartType tRetType = t.returnType; |
| 5080 DartType sRetType = s.returnType; |
| 5081 return sRetType.isVoid || |
| 5082 (tRetType as TypeImpl).isMoreSpecificThan(sRetType, withDynamic); |
5127 } | 5083 } |
5128 | 5084 |
5129 @override | 5085 @override |
5130 bool isSubtypeOf(DartType type, | 5086 bool isSubtypeOf(DartType type) { |
5131 [Set<Element> thisExpansions, Set<Element> typeExpansions]) { | |
5132 // trivial base cases | 5087 // trivial base cases |
5133 if (type == null) { | 5088 if (type == null) { |
5134 return false; | 5089 return false; |
5135 } else if (identical(this, type) || | 5090 } else if (identical(this, type) || |
5136 type.isDynamic || | 5091 type.isDynamic || |
5137 type.isDartCoreFunction || | 5092 type.isDartCoreFunction || |
5138 type.isObject) { | 5093 type.isObject) { |
5139 return true; | 5094 return true; |
5140 } else if (type is! FunctionType) { | 5095 } else if (type is! FunctionType) { |
5141 return false; | 5096 return false; |
5142 } else if (this == type) { | 5097 } else if (this == type) { |
5143 return true; | 5098 return true; |
5144 } | 5099 } |
5145 FunctionType t = this; | 5100 FunctionType t = this; |
5146 FunctionType s = type as FunctionType; | 5101 FunctionType s = type as FunctionType; |
5147 if (thisExpansions == null) { | 5102 List<DartType> tTypes = t.normalParameterTypes; |
5148 thisExpansions = new HashSet<Element>(); | 5103 List<DartType> tOpTypes = t.optionalParameterTypes; |
5149 } else if (thisExpansions.contains(this.element)) { | 5104 List<DartType> sTypes = s.normalParameterTypes; |
5150 // [this] contains a reference to itself, which is illegal (and is | 5105 List<DartType> sOpTypes = s.optionalParameterTypes; |
5151 // checked elsewhere). To avoid cascading errors, consider T to be a | 5106 // If one function has positional and the other has named parameters, |
5152 // subtype of S. | 5107 // return false. |
5153 return true; | 5108 if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) || |
| 5109 (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) { |
| 5110 return false; |
5154 } | 5111 } |
5155 if (typeExpansions == null) { | 5112 // named parameters case |
5156 typeExpansions = new HashSet<Element>(); | 5113 if (t.namedParameterTypes.length > 0) { |
5157 } else if (typeExpansions.contains(type.element)) { | 5114 // check that the number of required parameters are equal, |
5158 // [type] contains a reference to itself, which is illegal (and is | 5115 // and check that every t_i is assignable to every s_i |
5159 // checked elsewhere). To avoid cascading errors, consider T to be a | 5116 if (t.normalParameterTypes.length != s.normalParameterTypes.length) { |
5160 // subtype of S. | |
5161 return true; | |
5162 } | |
5163 thisExpansions.add(this.element); | |
5164 typeExpansions.add(type.element); | |
5165 try { | |
5166 List<DartType> tTypes = t.normalParameterTypes; | |
5167 List<DartType> tOpTypes = t.optionalParameterTypes; | |
5168 List<DartType> sTypes = s.normalParameterTypes; | |
5169 List<DartType> sOpTypes = s.optionalParameterTypes; | |
5170 // If one function has positional and the other has named parameters, | |
5171 // return false. | |
5172 if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) || | |
5173 (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) { | |
5174 return false; | 5117 return false; |
5175 } | 5118 } else if (t.normalParameterTypes.length > 0) { |
5176 // named parameters case | 5119 for (int i = 0; i < tTypes.length; i++) { |
5177 if (t.namedParameterTypes.length > 0) { | 5120 if (!(tTypes[i] as TypeImpl).isAssignableTo(sTypes[i])) { |
5178 // check that the number of required parameters are equal, | |
5179 // and check that every t_i is assignable to every s_i | |
5180 if (t.normalParameterTypes.length != s.normalParameterTypes.length) { | |
5181 return false; | |
5182 } else if (t.normalParameterTypes.length > 0) { | |
5183 for (int i = 0; i < tTypes.length; i++) { | |
5184 if (!(tTypes[i] as TypeImpl).isAssignableTo( | |
5185 sTypes[i], thisExpansions, typeExpansions)) { | |
5186 return false; | |
5187 } | |
5188 } | |
5189 } | |
5190 Map<String, DartType> namedTypesT = t.namedParameterTypes; | |
5191 Map<String, DartType> namedTypesS = s.namedParameterTypes; | |
5192 // if k >= m is false, return false: the passed function type has more | |
5193 // named parameter types than this | |
5194 if (namedTypesT.length < namedTypesS.length) { | |
5195 return false; | |
5196 } | |
5197 // Loop through each element in S verifying that T has a matching | |
5198 // parameter name and that the corresponding type is assignable to the | |
5199 // type in S. | |
5200 for (String keyS in namedTypesS.keys) { | |
5201 DartType typeT = namedTypesT[keyS]; | |
5202 if (typeT == null) { | |
5203 return false; | |
5204 } | |
5205 if (!(typeT as TypeImpl).isAssignableTo( | |
5206 namedTypesS[keyS], thisExpansions, typeExpansions)) { | |
5207 return false; | 5121 return false; |
5208 } | 5122 } |
5209 } | 5123 } |
5210 } else if (s.namedParameterTypes.length > 0) { | 5124 } |
| 5125 Map<String, DartType> namedTypesT = t.namedParameterTypes; |
| 5126 Map<String, DartType> namedTypesS = s.namedParameterTypes; |
| 5127 // if k >= m is false, return false: the passed function type has more |
| 5128 // named parameter types than this |
| 5129 if (namedTypesT.length < namedTypesS.length) { |
5211 return false; | 5130 return false; |
5212 } else { | 5131 } |
5213 // positional parameter case | 5132 // Loop through each element in S verifying that T has a matching |
5214 int tArgLength = tTypes.length + tOpTypes.length; | 5133 // parameter name and that the corresponding type is assignable to the |
5215 int sArgLength = sTypes.length + sOpTypes.length; | 5134 // type in S. |
5216 // Check that the total number of parameters in t is greater than or | 5135 for (String keyS in namedTypesS.keys) { |
5217 // equal to the number of parameters in s and that the number of | 5136 DartType typeT = namedTypesT[keyS]; |
5218 // required parameters in s is greater than or equal to the number of | 5137 if (typeT == null) { |
5219 // required parameters in t. | |
5220 if (tArgLength < sArgLength || sTypes.length < tTypes.length) { | |
5221 return false; | 5138 return false; |
5222 } | 5139 } |
5223 if (tOpTypes.length == 0 && sOpTypes.length == 0) { | 5140 if (!(typeT as TypeImpl).isAssignableTo(namedTypesS[keyS])) { |
5224 // No positional arguments, don't copy contents to new array | 5141 return false; |
5225 for (int i = 0; i < sTypes.length; i++) { | 5142 } |
5226 if (!(tTypes[i] as TypeImpl).isAssignableTo( | 5143 } |
5227 sTypes[i], thisExpansions, typeExpansions)) { | 5144 } else if (s.namedParameterTypes.length > 0) { |
5228 return false; | 5145 return false; |
5229 } | 5146 } else { |
| 5147 // positional parameter case |
| 5148 int tArgLength = tTypes.length + tOpTypes.length; |
| 5149 int sArgLength = sTypes.length + sOpTypes.length; |
| 5150 // Check that the total number of parameters in t is greater than or |
| 5151 // equal to the number of parameters in s and that the number of |
| 5152 // required parameters in s is greater than or equal to the number of |
| 5153 // required parameters in t. |
| 5154 if (tArgLength < sArgLength || sTypes.length < tTypes.length) { |
| 5155 return false; |
| 5156 } |
| 5157 if (tOpTypes.length == 0 && sOpTypes.length == 0) { |
| 5158 // No positional arguments, don't copy contents to new array |
| 5159 for (int i = 0; i < sTypes.length; i++) { |
| 5160 if (!(tTypes[i] as TypeImpl).isAssignableTo(sTypes[i])) { |
| 5161 return false; |
5230 } | 5162 } |
5231 } else { | 5163 } |
5232 // Else, we do have positional parameters, copy required and | 5164 } else { |
5233 // positional parameter types into arrays to do the compare (for loop | 5165 // Else, we do have positional parameters, copy required and |
5234 // below). | 5166 // positional parameter types into arrays to do the compare (for loop |
5235 List<DartType> tAllTypes = new List<DartType>(sArgLength); | 5167 // below). |
5236 for (int i = 0; i < tTypes.length; i++) { | 5168 List<DartType> tAllTypes = new List<DartType>(sArgLength); |
5237 tAllTypes[i] = tTypes[i]; | 5169 for (int i = 0; i < tTypes.length; i++) { |
5238 } | 5170 tAllTypes[i] = tTypes[i]; |
5239 for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) { | 5171 } |
5240 tAllTypes[i] = tOpTypes[j]; | 5172 for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) { |
5241 } | 5173 tAllTypes[i] = tOpTypes[j]; |
5242 List<DartType> sAllTypes = new List<DartType>(sArgLength); | 5174 } |
5243 for (int i = 0; i < sTypes.length; i++) { | 5175 List<DartType> sAllTypes = new List<DartType>(sArgLength); |
5244 sAllTypes[i] = sTypes[i]; | 5176 for (int i = 0; i < sTypes.length; i++) { |
5245 } | 5177 sAllTypes[i] = sTypes[i]; |
5246 for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) { | 5178 } |
5247 sAllTypes[i] = sOpTypes[j]; | 5179 for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) { |
5248 } | 5180 sAllTypes[i] = sOpTypes[j]; |
5249 for (int i = 0; i < sAllTypes.length; i++) { | 5181 } |
5250 if (!(tAllTypes[i] as TypeImpl).isAssignableTo( | 5182 for (int i = 0; i < sAllTypes.length; i++) { |
5251 sAllTypes[i], thisExpansions, typeExpansions)) { | 5183 if (!(tAllTypes[i] as TypeImpl).isAssignableTo(sAllTypes[i])) { |
5252 return false; | 5184 return false; |
5253 } | |
5254 } | 5185 } |
5255 } | 5186 } |
5256 } | 5187 } |
5257 DartType tRetType = t.returnType; | 5188 } |
5258 DartType sRetType = s.returnType; | 5189 DartType tRetType = t.returnType; |
5259 return sRetType.isVoid || | 5190 DartType sRetType = s.returnType; |
5260 (tRetType as TypeImpl).isAssignableTo( | 5191 return sRetType.isVoid || (tRetType as TypeImpl).isAssignableTo(sRetType); |
5261 sRetType, thisExpansions, typeExpansions); | 5192 } |
5262 } finally { | 5193 |
5263 thisExpansions.remove(this.element); | 5194 @override |
5264 typeExpansions.remove(type.element); | 5195 TypeImpl pruned(List<FunctionTypeAliasElement> prune) { |
| 5196 if (prune == null) { |
| 5197 return this; |
| 5198 } else if (prune.contains(element)) { |
| 5199 // Circularity found. Prune the type declaration. |
| 5200 return new CircularTypeImpl(); |
| 5201 } else { |
| 5202 // There should never be a reason to prune a type that has already been |
| 5203 // pruned, since pruning is only done when expanding a function type |
| 5204 // alias, and function type aliases are always expanded by starting with |
| 5205 // base types. |
| 5206 assert(this.prunedTypedefs == null); |
| 5207 FunctionTypeImpl result = new FunctionTypeImpl._(element, name, prune); |
| 5208 result.typeArguments = |
| 5209 typeArguments.map((TypeImpl t) => t.pruned(prune)).toList(); |
| 5210 return result; |
5265 } | 5211 } |
5266 } | 5212 } |
5267 | 5213 |
5268 @override | 5214 @override |
5269 FunctionTypeImpl substitute2( | 5215 DartType substitute2( |
5270 List<DartType> argumentTypes, List<DartType> parameterTypes) { | 5216 List<DartType> argumentTypes, List<DartType> parameterTypes, |
| 5217 [List<FunctionTypeAliasElement> prune]) { |
| 5218 // Pruned types should only ever result from peforming type variable |
| 5219 // substitution, and it doesn't make sense to substitute again after |
| 5220 // substituting once. |
| 5221 assert(this.prunedTypedefs == null); |
5271 if (argumentTypes.length != parameterTypes.length) { | 5222 if (argumentTypes.length != parameterTypes.length) { |
5272 throw new IllegalArgumentException( | 5223 throw new IllegalArgumentException( |
5273 "argumentTypes.length (${argumentTypes.length}) != parameterTypes.leng
th (${parameterTypes.length})"); | 5224 "argumentTypes.length (${argumentTypes.length}) != parameterTypes.leng
th (${parameterTypes.length})"); |
5274 } | 5225 } |
| 5226 Element element = this.element; |
| 5227 if (prune != null && prune.contains(element)) { |
| 5228 // Circularity found. Prune the type declaration. |
| 5229 return new CircularTypeImpl(); |
| 5230 } |
5275 if (argumentTypes.length == 0) { | 5231 if (argumentTypes.length == 0) { |
5276 return this; | 5232 return this.pruned(prune); |
5277 } | 5233 } |
5278 Element element = this.element; | |
5279 FunctionTypeImpl newType = (element is ExecutableElement) | 5234 FunctionTypeImpl newType = (element is ExecutableElement) |
5280 ? new FunctionTypeImpl(element) | 5235 ? new FunctionTypeImpl(element, prune) |
5281 : new FunctionTypeImpl.forTypedef(element as FunctionTypeAliasElement); | 5236 : new FunctionTypeImpl.forTypedef( |
| 5237 element as FunctionTypeAliasElement, prune); |
5282 newType.typeArguments = | 5238 newType.typeArguments = |
5283 TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes); | 5239 TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes); |
5284 return newType; | 5240 return newType; |
5285 } | 5241 } |
5286 | 5242 |
5287 @override | 5243 @override |
5288 FunctionTypeImpl substitute3(List<DartType> argumentTypes) => | 5244 FunctionTypeImpl substitute3(List<DartType> argumentTypes) => |
5289 substitute2(argumentTypes, typeArguments); | 5245 substitute2(argumentTypes, typeArguments); |
5290 | 5246 |
5291 /** | 5247 /** |
5292 * Return `true` if all of the name/type pairs in the first map ([firstTypes]) | 5248 * Return `true` if all of the name/type pairs in the first map ([firstTypes]) |
5293 * are equal to the corresponding name/type pairs in the second map | 5249 * are equal to the corresponding name/type pairs in the second map |
5294 * ([secondTypes]). The maps are expected to iterate over their entries in the | 5250 * ([secondTypes]). The maps are expected to iterate over their entries in the |
5295 * same order in which those entries were added to the map. The set of | 5251 * same order in which those entries were added to the map. |
5296 * [visitedElementPairs] is used to prevent infinite recursion in the case of | |
5297 * cyclic type structures. | |
5298 */ | 5252 */ |
5299 static bool _equals(Map<String, DartType> firstTypes, | 5253 static bool _equals( |
5300 Map<String, DartType> secondTypes, Set<ElementPair> visitedElementPairs) { | 5254 Map<String, DartType> firstTypes, Map<String, DartType> secondTypes) { |
5301 if (secondTypes.length != firstTypes.length) { | 5255 if (secondTypes.length != firstTypes.length) { |
5302 return false; | 5256 return false; |
5303 } | 5257 } |
5304 Iterator<String> firstKeys = firstTypes.keys.iterator; | 5258 Iterator<String> firstKeys = firstTypes.keys.iterator; |
5305 Iterator<String> secondKeys = secondTypes.keys.iterator; | 5259 Iterator<String> secondKeys = secondTypes.keys.iterator; |
5306 while (firstKeys.moveNext() && secondKeys.moveNext()) { | 5260 while (firstKeys.moveNext() && secondKeys.moveNext()) { |
5307 String firstKey = firstKeys.current; | 5261 String firstKey = firstKeys.current; |
5308 String secondKey = secondKeys.current; | 5262 String secondKey = secondKeys.current; |
5309 TypeImpl firstType = firstTypes[firstKey]; | 5263 TypeImpl firstType = firstTypes[firstKey]; |
5310 TypeImpl secondType = secondTypes[secondKey]; | 5264 TypeImpl secondType = secondTypes[secondKey]; |
5311 if (firstKey != secondKey || | 5265 if (firstKey != secondKey || firstType != secondType) { |
5312 !firstType.internalEquals(secondType, visitedElementPairs)) { | |
5313 return false; | 5266 return false; |
5314 } | 5267 } |
5315 } | 5268 } |
5316 return true; | 5269 return true; |
5317 } | 5270 } |
5318 } | 5271 } |
5319 | 5272 |
5320 /** | 5273 /** |
5321 * An element visitor that will recursively visit all of the elements in an | 5274 * An element visitor that will recursively visit all of the elements in an |
5322 * element model (like instances of the class [RecursiveElementVisitor]). In | 5275 * element model (like instances of the class [RecursiveElementVisitor]). In |
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6106 /** | 6059 /** |
6107 * A concrete implementation of an [InterfaceType]. | 6060 * A concrete implementation of an [InterfaceType]. |
6108 */ | 6061 */ |
6109 class InterfaceTypeImpl extends TypeImpl implements InterfaceType { | 6062 class InterfaceTypeImpl extends TypeImpl implements InterfaceType { |
6110 /** | 6063 /** |
6111 * A list containing the actual types of the type arguments. | 6064 * A list containing the actual types of the type arguments. |
6112 */ | 6065 */ |
6113 List<DartType> typeArguments = DartType.EMPTY_LIST; | 6066 List<DartType> typeArguments = DartType.EMPTY_LIST; |
6114 | 6067 |
6115 /** | 6068 /** |
| 6069 * The set of typedefs which should not be expanded when exploring this type, |
| 6070 * to avoid creating infinite types in response to self-referential typedefs. |
| 6071 */ |
| 6072 final List<FunctionTypeAliasElement> prunedTypedefs; |
| 6073 |
| 6074 /** |
6116 * Initialize a newly created type to be declared by the given [element]. | 6075 * Initialize a newly created type to be declared by the given [element]. |
6117 */ | 6076 */ |
6118 InterfaceTypeImpl(ClassElement element) : super(element, element.displayName); | 6077 InterfaceTypeImpl(ClassElement element, [this.prunedTypedefs]) |
| 6078 : super(element, element.displayName); |
6119 | 6079 |
6120 /** | 6080 /** |
6121 * Initialize a newly created type to be declared by the given [element]. | 6081 * Initialize a newly created type to be declared by the given [element]. |
6122 */ | 6082 */ |
6123 @deprecated // Use new InterfaceTypeImpl(element) | 6083 @deprecated // Use new InterfaceTypeImpl(element) |
6124 InterfaceTypeImpl.con1(ClassElement element) | 6084 InterfaceTypeImpl.con1(ClassElement element) |
6125 : super(element, element.displayName); | 6085 : prunedTypedefs = null, |
| 6086 super(element, element.displayName); |
6126 | 6087 |
6127 /** | 6088 /** |
6128 * Initialize a newly created type to have the given [name]. This constructor | 6089 * Initialize a newly created type to have the given [name]. This constructor |
6129 * should only be used in cases where there is no declaration of the type. | 6090 * should only be used in cases where there is no declaration of the type. |
6130 */ | 6091 */ |
6131 @deprecated // Use new InterfaceTypeImpl.named(name) | 6092 @deprecated // Use new InterfaceTypeImpl.named(name) |
6132 InterfaceTypeImpl.con2(String name) : super(null, name); | 6093 InterfaceTypeImpl.con2(String name) |
| 6094 : prunedTypedefs = null, |
| 6095 super(null, name); |
6133 | 6096 |
6134 /** | 6097 /** |
6135 * Initialize a newly created type to have the given [name]. This constructor | 6098 * Initialize a newly created type to have the given [name]. This constructor |
6136 * should only be used in cases where there is no declaration of the type. | 6099 * should only be used in cases where there is no declaration of the type. |
6137 */ | 6100 */ |
6138 InterfaceTypeImpl.named(String name) : super(null, name); | 6101 InterfaceTypeImpl.named(String name) |
| 6102 : prunedTypedefs = null, |
| 6103 super(null, name); |
| 6104 |
| 6105 /** |
| 6106 * Private constructor. |
| 6107 */ |
| 6108 InterfaceTypeImpl._(Element element, String name, this.prunedTypedefs) |
| 6109 : super(element, name); |
6139 | 6110 |
6140 @override | 6111 @override |
6141 List<PropertyAccessorElement> get accessors { | 6112 List<PropertyAccessorElement> get accessors { |
6142 List<PropertyAccessorElement> accessors = element.accessors; | 6113 List<PropertyAccessorElement> accessors = element.accessors; |
6143 List<PropertyAccessorElement> members = | 6114 List<PropertyAccessorElement> members = |
6144 new List<PropertyAccessorElement>(accessors.length); | 6115 new List<PropertyAccessorElement>(accessors.length); |
6145 for (int i = 0; i < accessors.length; i++) { | 6116 for (int i = 0; i < accessors.length; i++) { |
6146 members[i] = PropertyAccessorMember.from(accessors[i], this); | 6117 members[i] = PropertyAccessorMember.from(accessors[i], this); |
6147 } | 6118 } |
6148 return members; | 6119 return members; |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6273 } | 6244 } |
6274 | 6245 |
6275 @override | 6246 @override |
6276 List<TypeParameterElement> get typeParameters => element.typeParameters; | 6247 List<TypeParameterElement> get typeParameters => element.typeParameters; |
6277 | 6248 |
6278 @override | 6249 @override |
6279 bool operator ==(Object object) { | 6250 bool operator ==(Object object) { |
6280 if (identical(object, this)) { | 6251 if (identical(object, this)) { |
6281 return true; | 6252 return true; |
6282 } | 6253 } |
6283 return internalEquals(object, new HashSet<ElementPair>()); | 6254 if (object is! InterfaceTypeImpl) { |
| 6255 return false; |
| 6256 } |
| 6257 InterfaceTypeImpl otherType = object as InterfaceTypeImpl; |
| 6258 return (element == otherType.element) && |
| 6259 TypeImpl.equalArrays(typeArguments, otherType.typeArguments); |
6284 } | 6260 } |
6285 | 6261 |
6286 @override | 6262 @override |
6287 void appendTo(StringBuffer buffer, Set<DartType> visitedTypes) { | 6263 void appendTo(StringBuffer buffer) { |
6288 if (!visitedTypes.add(this)) { | |
6289 buffer.write(name == null ? '...' : name); | |
6290 return; | |
6291 } | |
6292 buffer.write(name); | 6264 buffer.write(name); |
6293 int argumentCount = typeArguments.length; | 6265 int argumentCount = typeArguments.length; |
6294 if (argumentCount > 0) { | 6266 if (argumentCount > 0) { |
6295 buffer.write("<"); | 6267 buffer.write("<"); |
6296 for (int i = 0; i < argumentCount; i++) { | 6268 for (int i = 0; i < argumentCount; i++) { |
6297 if (i > 0) { | 6269 if (i > 0) { |
6298 buffer.write(", "); | 6270 buffer.write(", "); |
6299 } | 6271 } |
6300 (typeArguments[i] as TypeImpl).appendTo(buffer, visitedTypes); | 6272 (typeArguments[i] as TypeImpl).appendTo(buffer); |
6301 } | 6273 } |
6302 buffer.write(">"); | 6274 buffer.write(">"); |
6303 } | 6275 } |
6304 } | 6276 } |
6305 | 6277 |
6306 @override | 6278 @override |
6307 PropertyAccessorElement getGetter(String getterName) => PropertyAccessorMember | 6279 PropertyAccessorElement getGetter(String getterName) => PropertyAccessorMember |
6308 .from((element as ClassElementImpl).getGetter(getterName), this); | 6280 .from((element as ClassElementImpl).getGetter(getterName), this); |
6309 | 6281 |
6310 @override | 6282 @override |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6366 | 6338 |
6367 @override | 6339 @override |
6368 MethodElement getMethod(String methodName) => MethodMember.from( | 6340 MethodElement getMethod(String methodName) => MethodMember.from( |
6369 (element as ClassElementImpl).getMethod(methodName), this); | 6341 (element as ClassElementImpl).getMethod(methodName), this); |
6370 | 6342 |
6371 @override | 6343 @override |
6372 PropertyAccessorElement getSetter(String setterName) => PropertyAccessorMember | 6344 PropertyAccessorElement getSetter(String setterName) => PropertyAccessorMember |
6373 .from((element as ClassElementImpl).getSetter(setterName), this); | 6345 .from((element as ClassElementImpl).getSetter(setterName), this); |
6374 | 6346 |
6375 @override | 6347 @override |
6376 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) { | |
6377 if (identical(object, this)) { | |
6378 return true; | |
6379 } | |
6380 if (object is! InterfaceTypeImpl) { | |
6381 return false; | |
6382 } | |
6383 InterfaceTypeImpl otherType = object as InterfaceTypeImpl; | |
6384 return (element == otherType.element) && | |
6385 TypeImpl.equalArrays( | |
6386 typeArguments, otherType.typeArguments, visitedElementPairs); | |
6387 } | |
6388 | |
6389 @override | |
6390 int internalHashCode(List<DartType> visitedTypes) => hashCode; | |
6391 | |
6392 @override | |
6393 bool isDirectSupertypeOf(InterfaceType type) { | 6348 bool isDirectSupertypeOf(InterfaceType type) { |
6394 InterfaceType i = this; | 6349 InterfaceType i = this; |
6395 InterfaceType j = type; | 6350 InterfaceType j = type; |
6396 ClassElement jElement = j.element; | 6351 ClassElement jElement = j.element; |
6397 InterfaceType supertype = jElement.supertype; | 6352 InterfaceType supertype = jElement.supertype; |
6398 // | 6353 // |
6399 // If J has no direct supertype then it is Object, and Object has no direct | 6354 // If J has no direct supertype then it is Object, and Object has no direct |
6400 // supertypes. | 6355 // supertypes. |
6401 // | 6356 // |
6402 if (supertype == null) { | 6357 if (supertype == null) { |
(...skipping 28 matching lines...) Expand all Loading... |
6431 } | 6386 } |
6432 // | 6387 // |
6433 // J is a mixin application of the mixin of I. | 6388 // J is a mixin application of the mixin of I. |
6434 // | 6389 // |
6435 // TODO(brianwilkerson) Determine whether this needs to be implemented or | 6390 // TODO(brianwilkerson) Determine whether this needs to be implemented or |
6436 // whether it is covered by the case above. | 6391 // whether it is covered by the case above. |
6437 return false; | 6392 return false; |
6438 } | 6393 } |
6439 | 6394 |
6440 @override | 6395 @override |
6441 bool isMoreSpecificThan(DartType type, [Set<Element> thisExpansions, | 6396 bool isMoreSpecificThan(DartType type, |
6442 Set<Element> typeExpansions, bool withDynamic = false, | 6397 [bool withDynamic = false, Set<Element> visitedElements]) { |
6443 Set<Element> visitedElements]) { | |
6444 // | 6398 // |
6445 // S is dynamic. | 6399 // S is dynamic. |
6446 // The test to determine whether S is dynamic is done here because dynamic | 6400 // The test to determine whether S is dynamic is done here because dynamic |
6447 // is not an instance of InterfaceType. | 6401 // is not an instance of InterfaceType. |
6448 // | 6402 // |
6449 if (type.isDynamic) { | 6403 if (type.isDynamic) { |
6450 return true; | 6404 return true; |
6451 } | 6405 } |
6452 // | 6406 // |
6453 // A type T is more specific than a type S, written T << S, | 6407 // A type T is more specific than a type S, written T << S, |
(...skipping 20 matching lines...) Expand all Loading... |
6474 ClassElement tElement = this.element; | 6428 ClassElement tElement = this.element; |
6475 ClassElement sElement = type.element; | 6429 ClassElement sElement = type.element; |
6476 if (tElement == sElement) { | 6430 if (tElement == sElement) { |
6477 List<DartType> tArguments = typeArguments; | 6431 List<DartType> tArguments = typeArguments; |
6478 List<DartType> sArguments = type.typeArguments; | 6432 List<DartType> sArguments = type.typeArguments; |
6479 if (tArguments.length != sArguments.length) { | 6433 if (tArguments.length != sArguments.length) { |
6480 return false; | 6434 return false; |
6481 } | 6435 } |
6482 for (int i = 0; i < tArguments.length; i++) { | 6436 for (int i = 0; i < tArguments.length; i++) { |
6483 if (!(tArguments[i] as TypeImpl).isMoreSpecificThan( | 6437 if (!(tArguments[i] as TypeImpl).isMoreSpecificThan( |
6484 sArguments[i], thisExpansions, typeExpansions, withDynamic)) { | 6438 sArguments[i], withDynamic)) { |
6485 return false; | 6439 return false; |
6486 } | 6440 } |
6487 } | 6441 } |
6488 return true; | 6442 return true; |
6489 } | 6443 } |
6490 } | 6444 } |
6491 // | 6445 // |
6492 // Transitivity: T << U and U << S. | 6446 // Transitivity: T << U and U << S. |
6493 // | 6447 // |
6494 // First check for infinite loops | 6448 // First check for infinite loops |
6495 if (element == null) { | 6449 if (element == null) { |
6496 return false; | 6450 return false; |
6497 } | 6451 } |
6498 if (visitedElements == null) { | 6452 if (visitedElements == null) { |
6499 visitedElements = new HashSet<ClassElement>(); | 6453 visitedElements = new HashSet<ClassElement>(); |
6500 } else if (visitedElements.contains(element)) { | 6454 } else if (visitedElements.contains(element)) { |
6501 return false; | 6455 return false; |
6502 } | 6456 } |
6503 visitedElements.add(element); | 6457 visitedElements.add(element); |
6504 try { | 6458 try { |
6505 // Iterate over all of the types U that are more specific than T because | 6459 // Iterate over all of the types U that are more specific than T because |
6506 // they are direct supertypes of T and return true if any of them are more | 6460 // they are direct supertypes of T and return true if any of them are more |
6507 // specific than S. | 6461 // specific than S. |
6508 InterfaceTypeImpl supertype = superclass; | 6462 InterfaceTypeImpl supertype = superclass; |
6509 if (supertype != null && | 6463 if (supertype != null && |
6510 supertype.isMoreSpecificThan(type, thisExpansions, typeExpansions, | 6464 supertype.isMoreSpecificThan(type, withDynamic, visitedElements)) { |
6511 withDynamic, visitedElements)) { | |
6512 return true; | 6465 return true; |
6513 } | 6466 } |
6514 for (InterfaceType interfaceType in interfaces) { | 6467 for (InterfaceType interfaceType in interfaces) { |
6515 if ((interfaceType as InterfaceTypeImpl).isMoreSpecificThan(type, | 6468 if ((interfaceType as InterfaceTypeImpl).isMoreSpecificThan( |
6516 thisExpansions, typeExpansions, withDynamic, visitedElements)) { | 6469 type, withDynamic, visitedElements)) { |
6517 return true; | 6470 return true; |
6518 } | 6471 } |
6519 } | 6472 } |
6520 for (InterfaceType mixinType in mixins) { | 6473 for (InterfaceType mixinType in mixins) { |
6521 if ((mixinType as InterfaceTypeImpl).isMoreSpecificThan(type, | 6474 if ((mixinType as InterfaceTypeImpl).isMoreSpecificThan( |
6522 thisExpansions, typeExpansions, withDynamic, visitedElements)) { | 6475 type, withDynamic, visitedElements)) { |
6523 return true; | 6476 return true; |
6524 } | 6477 } |
6525 } | 6478 } |
6526 // If a type I includes an instance method named `call`, and the type of | 6479 // If a type I includes an instance method named `call`, and the type of |
6527 // `call` is the function type F, then I is considered to be more specific | 6480 // `call` is the function type F, then I is considered to be more specific |
6528 // than F. | 6481 // than F. |
6529 MethodElement callMethod = getMethod('call'); | 6482 MethodElement callMethod = getMethod('call'); |
6530 if (callMethod != null && !callMethod.isStatic) { | 6483 if (callMethod != null && !callMethod.isStatic) { |
6531 FunctionTypeImpl callType = callMethod.type; | 6484 FunctionTypeImpl callType = callMethod.type; |
6532 if (callType.isMoreSpecificThan(type, thisExpansions, typeExpansions, | 6485 if (callType.isMoreSpecificThan(type, withDynamic, visitedElements)) { |
6533 withDynamic, visitedElements)) { | |
6534 return true; | 6486 return true; |
6535 } | 6487 } |
6536 } | 6488 } |
6537 return false; | 6489 return false; |
6538 } finally { | 6490 } finally { |
6539 visitedElements.remove(element); | 6491 visitedElements.remove(element); |
6540 } | 6492 } |
6541 } | 6493 } |
6542 | 6494 |
6543 @override | 6495 @override |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6675 return element; | 6627 return element; |
6676 } | 6628 } |
6677 } | 6629 } |
6678 supertype = supertype.superclass; | 6630 supertype = supertype.superclass; |
6679 supertypeElement = supertype == null ? null : supertype.element; | 6631 supertypeElement = supertype == null ? null : supertype.element; |
6680 } | 6632 } |
6681 return null; | 6633 return null; |
6682 } | 6634 } |
6683 | 6635 |
6684 @override | 6636 @override |
| 6637 InterfaceTypeImpl pruned(List<FunctionTypeAliasElement> prune) { |
| 6638 if (prune == null) { |
| 6639 return this; |
| 6640 } else { |
| 6641 // There should never be a reason to prune a type that has already been |
| 6642 // pruned, since pruning is only done when expanding a function type |
| 6643 // alias, and function type aliases are always expanded by starting with |
| 6644 // base types. |
| 6645 assert(this.prunedTypedefs == null); |
| 6646 InterfaceTypeImpl result = new InterfaceTypeImpl._(element, name, prune); |
| 6647 result.typeArguments = |
| 6648 typeArguments.map((TypeImpl t) => t.pruned(prune)).toList(); |
| 6649 return result; |
| 6650 } |
| 6651 } |
| 6652 |
| 6653 @override |
6685 InterfaceTypeImpl substitute2( | 6654 InterfaceTypeImpl substitute2( |
6686 List<DartType> argumentTypes, List<DartType> parameterTypes) { | 6655 List<DartType> argumentTypes, List<DartType> parameterTypes, |
| 6656 [List<FunctionTypeAliasElement> prune]) { |
| 6657 // Pruned types should only ever result from performing type variable |
| 6658 // substitution, and it doesn't make sense to substitute again after |
| 6659 // substituting once. |
| 6660 assert(this.prunedTypedefs == null); |
6687 if (argumentTypes.length != parameterTypes.length) { | 6661 if (argumentTypes.length != parameterTypes.length) { |
6688 throw new IllegalArgumentException( | 6662 throw new IllegalArgumentException( |
6689 "argumentTypes.length (${argumentTypes.length}) != parameterTypes.leng
th (${parameterTypes.length})"); | 6663 "argumentTypes.length (${argumentTypes.length}) != parameterTypes.leng
th (${parameterTypes.length})"); |
6690 } | 6664 } |
6691 if (argumentTypes.length == 0 || typeArguments.length == 0) { | 6665 if (argumentTypes.length == 0 || typeArguments.length == 0) { |
6692 return this; | 6666 return this.pruned(prune); |
6693 } | 6667 } |
6694 List<DartType> newTypeArguments = | 6668 List<DartType> newTypeArguments = TypeImpl.substitute( |
6695 TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes); | 6669 typeArguments, argumentTypes, parameterTypes, prune); |
6696 if (JavaArrays.equals(newTypeArguments, typeArguments)) { | 6670 if (JavaArrays.equals(newTypeArguments, typeArguments)) { |
6697 return this; | 6671 return this; |
6698 } | 6672 } |
6699 InterfaceTypeImpl newType = new InterfaceTypeImpl(element); | 6673 InterfaceTypeImpl newType = new InterfaceTypeImpl(element, prune); |
6700 newType.typeArguments = newTypeArguments; | 6674 newType.typeArguments = newTypeArguments; |
6701 return newType; | 6675 return newType; |
6702 } | 6676 } |
6703 | 6677 |
6704 @override | 6678 @override |
6705 InterfaceTypeImpl substitute4(List<DartType> argumentTypes) => | 6679 InterfaceTypeImpl substitute4(List<DartType> argumentTypes) => |
6706 substitute2(argumentTypes, typeArguments); | 6680 substitute2(argumentTypes, typeArguments); |
6707 | 6681 |
6708 /** | 6682 /** |
6709 * Return the length of the longest inheritance path from the given [type] to | 6683 * Return the length of the longest inheritance path from the given [type] to |
(...skipping 2973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9683 @override | 9657 @override |
9684 bool get isUndefined => false; | 9658 bool get isUndefined => false; |
9685 | 9659 |
9686 @override | 9660 @override |
9687 bool get isVoid => false; | 9661 bool get isVoid => false; |
9688 | 9662 |
9689 /** | 9663 /** |
9690 * Append a textual representation of this type to the given [buffer]. The set | 9664 * Append a textual representation of this type to the given [buffer]. The set |
9691 * of [visitedTypes] is used to prevent infinite recusion. | 9665 * of [visitedTypes] is used to prevent infinite recusion. |
9692 */ | 9666 */ |
9693 void appendTo(StringBuffer buffer, Set<DartType> visitedTypes) { | 9667 void appendTo(StringBuffer buffer) { |
9694 if (!visitedTypes.add(this)) { | |
9695 buffer.write(name == null ? '...' : name); | |
9696 return; | |
9697 } | |
9698 if (name == null) { | 9668 if (name == null) { |
9699 buffer.write("<unnamed type>"); | 9669 buffer.write("<unnamed type>"); |
9700 } else { | 9670 } else { |
9701 buffer.write(name); | 9671 buffer.write(name); |
9702 } | 9672 } |
9703 } | 9673 } |
9704 | 9674 |
9705 @override | 9675 @override |
9706 DartType getLeastUpperBound(DartType type) => null; | 9676 DartType getLeastUpperBound(DartType type) => null; |
9707 | 9677 |
9708 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs); | |
9709 | |
9710 int internalHashCode(List<DartType> visitedTypes); | |
9711 | |
9712 /** | 9678 /** |
9713 * Return `true` if this type is assignable to the given [type] (written in | 9679 * Return `true` if this type is assignable to the given [type] (written in |
9714 * the spec as "T <=> S", where T=[this] and S=[type]). | 9680 * the spec as "T <=> S", where T=[this] and S=[type]). |
9715 * | 9681 * |
9716 * The sets [thisExpansions] and [typeExpansions], if given, are the sets of | 9682 * The sets [thisExpansions] and [typeExpansions], if given, are the sets of |
9717 * function type aliases that have been expanded so far in the process of | 9683 * function type aliases that have been expanded so far in the process of |
9718 * reaching [this] and [type], respectively. These are used to avoid | 9684 * reaching [this] and [type], respectively. These are used to avoid |
9719 * infinite regress when analyzing invalid code; since the language spec | 9685 * infinite regress when analyzing invalid code; since the language spec |
9720 * forbids a typedef from referring to itself directly or indirectly, we can | 9686 * forbids a typedef from referring to itself directly or indirectly, we can |
9721 * use these as sets of function type aliases that don't need to be expanded. | 9687 * use these as sets of function type aliases that don't need to be expanded. |
9722 */ | 9688 */ |
9723 @override | 9689 @override |
9724 bool isAssignableTo(DartType type, | 9690 bool isAssignableTo(DartType type) { |
9725 [Set<Element> thisExpansions, Set<Element> typeExpansions]) { | |
9726 // An interface type T may be assigned to a type S, written T <=> S, iff | 9691 // An interface type T may be assigned to a type S, written T <=> S, iff |
9727 // either T <: S or S <: T. | 9692 // either T <: S or S <: T. |
9728 return isSubtypeOf(type, thisExpansions, typeExpansions) || | 9693 return isSubtypeOf(type) || (type as TypeImpl).isSubtypeOf(this); |
9729 (type as TypeImpl).isSubtypeOf(this, typeExpansions, thisExpansions); | |
9730 } | 9694 } |
9731 | 9695 |
9732 /** | 9696 /** |
9733 * Return `true` if this type is more specific than the given [type] (written | 9697 * Return `true` if this type is more specific than the given [type] (written |
9734 * in the spec as "T << S", where T=[this] and S=[type]). | 9698 * in the spec as "T << S", where T=[this] and S=[type]). |
9735 * | 9699 * |
9736 * The sets [thisExpansions] and [typeExpansions], if given, are the sets of | |
9737 * function type aliases that have been expanded so far in the process of | |
9738 * reaching [this] and [type], respectively. These are used to avoid | |
9739 * infinite regress when analyzing invalid code; since the language spec | |
9740 * forbids a typedef from referring to itself directly or indirectly, we can | |
9741 * use these as sets of function type aliases that don't need to be expanded. | |
9742 * | |
9743 * If [withDynamic] is `true`, then "dynamic" should be considered as a | 9700 * If [withDynamic] is `true`, then "dynamic" should be considered as a |
9744 * subtype of any type (as though "dynamic" had been replaced with bottom). | 9701 * subtype of any type (as though "dynamic" had been replaced with bottom). |
9745 * | 9702 * |
9746 * The set [visitedElements], if given, is the set of classes and type | 9703 * The set [visitedElements], if given, is the set of classes and type |
9747 * parameters that have been visited so far while examining the class | 9704 * parameters that have been visited so far while examining the class |
9748 * hierarchy of [this]. This is used to avoid infinite regress when | 9705 * hierarchy of [this]. This is used to avoid infinite regress when |
9749 * analyzing invalid code; since the language spec forbids loops in the class | 9706 * analyzing invalid code; since the language spec forbids loops in the class |
9750 * hierarchy, we can use this as a set of classes that don't need to be | 9707 * hierarchy, we can use this as a set of classes that don't need to be |
9751 * examined when walking the class hierarchy. | 9708 * examined when walking the class hierarchy. |
9752 */ | 9709 */ |
9753 @override | 9710 @override |
9754 bool isMoreSpecificThan(DartType type, [Set<Element> thisExpansions, | 9711 bool isMoreSpecificThan(DartType type, |
9755 Set<Element> typeExpansions, bool withDynamic = false, | 9712 [bool withDynamic = false, Set<Element> visitedElements]); |
9756 Set<Element> visitedElements]); | |
9757 | 9713 |
9758 /** | 9714 /** |
9759 * Return `true` if this type is a subtype of the given [type] (written in | 9715 * Return `true` if this type is a subtype of the given [type] (written in |
9760 * the spec as "T <: S", where T=[this] and S=[type]). | 9716 * the spec as "T <: S", where T=[this] and S=[type]). |
9761 * | 9717 * |
9762 * The sets [thisExpansions] and [typeExpansions], if given, are the sets of | 9718 * The sets [thisExpansions] and [typeExpansions], if given, are the sets of |
9763 * function type aliases that have been expanded so far in the process of | 9719 * function type aliases that have been expanded so far in the process of |
9764 * reaching [this] and [type], respectively. These are used to avoid | 9720 * reaching [this] and [type], respectively. These are used to avoid |
9765 * infinite regress when analyzing invalid code; since the language spec | 9721 * infinite regress when analyzing invalid code; since the language spec |
9766 * forbids a typedef from referring to itself directly or indirectly, we can | 9722 * forbids a typedef from referring to itself directly or indirectly, we can |
9767 * use these as sets of function type aliases that don't need to be expanded. | 9723 * use these as sets of function type aliases that don't need to be expanded. |
9768 */ | 9724 */ |
9769 @override | 9725 @override |
9770 bool isSubtypeOf(DartType type, | 9726 bool isSubtypeOf(DartType type) { |
9771 [Set<Element> thisExpansions, Set<Element> typeExpansions]) { | |
9772 // For non-function types, T <: S iff [_|_/dynamic]T << S. | 9727 // For non-function types, T <: S iff [_|_/dynamic]T << S. |
9773 return isMoreSpecificThan(type, thisExpansions, typeExpansions, true); | 9728 return isMoreSpecificThan(type, true); |
9774 } | 9729 } |
9775 | 9730 |
9776 @override | 9731 @override |
9777 bool isSupertypeOf(DartType type) => type.isSubtypeOf(this); | 9732 bool isSupertypeOf(DartType type) => type.isSubtypeOf(this); |
9778 | 9733 |
| 9734 /** |
| 9735 * Create a new [TypeImpl] that is identical to [this] except that when |
| 9736 * visiting type parameters, function parameter types, and function return |
| 9737 * types, function types listed in [prune] will not be expanded. This is |
| 9738 * used to avoid creating infinite types in the presence of circular |
| 9739 * typedefs. |
| 9740 * |
| 9741 * If [prune] is null, then [this] is returned unchanged. |
| 9742 * |
| 9743 * Only legal to call on a [TypeImpl] that is not already subject to pruning. |
| 9744 */ |
| 9745 TypeImpl pruned(List<FunctionTypeAliasElement> prune); |
| 9746 |
| 9747 /** |
| 9748 * Return the type resulting from substituting the given [argumentTypes] for |
| 9749 * the given [parameterTypes] in this type. |
| 9750 * |
| 9751 * In all classes derived from [TypeImpl], a new optional argument |
| 9752 * [prune] is added. If specified, it is a list of function typdefs |
| 9753 * which should not be expanded. This is used to avoid creating infinite |
| 9754 * types in response to self-referential typedefs. |
| 9755 */ |
| 9756 @override |
| 9757 DartType substitute2( |
| 9758 List<DartType> argumentTypes, List<DartType> parameterTypes, |
| 9759 [List<FunctionTypeAliasElement> prune]); |
| 9760 |
9779 @override | 9761 @override |
9780 String toString() { | 9762 String toString() { |
9781 StringBuffer buffer = new StringBuffer(); | 9763 StringBuffer buffer = new StringBuffer(); |
9782 appendTo(buffer, new HashSet<DartType>()); | 9764 appendTo(buffer); |
9783 return buffer.toString(); | 9765 return buffer.toString(); |
9784 } | 9766 } |
9785 | 9767 |
9786 /** | 9768 /** |
9787 * Return `true` if corresponding elements of the [first] and [second] lists | 9769 * Return `true` if corresponding elements of the [first] and [second] lists |
9788 * of type arguments are all equal. Use the set of [visitedElementPairs] to | 9770 * of type arguments are all equal. |
9789 * prevent infinite loops when the types are recursively defined. | |
9790 */ | 9771 */ |
9791 static bool equalArrays(List<DartType> first, List<DartType> second, | 9772 static bool equalArrays(List<DartType> first, List<DartType> second) { |
9792 Set<ElementPair> visitedElementPairs) { | |
9793 if (first.length != second.length) { | 9773 if (first.length != second.length) { |
9794 return false; | 9774 return false; |
9795 } | 9775 } |
9796 for (int i = 0; i < first.length; i++) { | 9776 for (int i = 0; i < first.length; i++) { |
9797 if (first[i] == null) { | 9777 if (first[i] == null) { |
9798 AnalysisEngine.instance.logger | 9778 AnalysisEngine.instance.logger |
9799 .logInformation('Found null type argument in TypeImpl.equalArrays'); | 9779 .logInformation('Found null type argument in TypeImpl.equalArrays'); |
9800 return second[i] == null; | 9780 return second[i] == null; |
9801 } else if (second[i] == null) { | 9781 } else if (second[i] == null) { |
9802 AnalysisEngine.instance.logger | 9782 AnalysisEngine.instance.logger |
9803 .logInformation('Found null type argument in TypeImpl.equalArrays'); | 9783 .logInformation('Found null type argument in TypeImpl.equalArrays'); |
9804 return false; | 9784 return false; |
9805 } | 9785 } |
9806 if (!(first[i] as TypeImpl).internalEquals( | 9786 if (first[i] != second[i]) { |
9807 second[i], visitedElementPairs)) { | |
9808 return false; | 9787 return false; |
9809 } | 9788 } |
9810 } | 9789 } |
9811 return true; | 9790 return true; |
9812 } | 9791 } |
9813 | 9792 |
9814 /** | 9793 /** |
9815 * Return a list containing the results of using the given [argumentTypes] and | 9794 * Return a list containing the results of using the given [argumentTypes] and |
9816 * [parameterTypes] to perform a substitution on all of the given [types]. | 9795 * [parameterTypes] to perform a substitution on all of the given [types]. |
| 9796 * |
| 9797 * If [prune] is specified, it is a list of function typdefs which should not |
| 9798 * be expanded. This is used to avoid creating infinite types in response to |
| 9799 * self-referential typedefs. |
9817 */ | 9800 */ |
9818 static List<DartType> substitute(List<DartType> types, | 9801 static List<DartType> substitute(List<DartType> types, |
9819 List<DartType> argumentTypes, List<DartType> parameterTypes) { | 9802 List<DartType> argumentTypes, List<DartType> parameterTypes, |
| 9803 [List<FunctionTypeAliasElement> prune]) { |
9820 int length = types.length; | 9804 int length = types.length; |
9821 if (length == 0) { | 9805 if (length == 0) { |
9822 return types; | 9806 return types; |
9823 } | 9807 } |
9824 List<DartType> newTypes = new List<DartType>(length); | 9808 List<DartType> newTypes = new List<DartType>(length); |
9825 for (int i = 0; i < length; i++) { | 9809 for (int i = 0; i < length; i++) { |
9826 newTypes[i] = types[i].substitute2(argumentTypes, parameterTypes); | 9810 newTypes[i] = (types[i] as TypeImpl).substitute2( |
| 9811 argumentTypes, parameterTypes, prune); |
9827 } | 9812 } |
9828 return newTypes; | 9813 return newTypes; |
9829 } | 9814 } |
9830 } | 9815 } |
9831 | 9816 |
9832 /** | 9817 /** |
9833 * A type parameter. | 9818 * A type parameter. |
9834 */ | 9819 */ |
9835 abstract class TypeParameterElement implements Element { | 9820 abstract class TypeParameterElement implements Element { |
9836 /** | 9821 /** |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9936 TypeParameterElement get element => super.element as TypeParameterElement; | 9921 TypeParameterElement get element => super.element as TypeParameterElement; |
9937 | 9922 |
9938 @override | 9923 @override |
9939 int get hashCode => element.hashCode; | 9924 int get hashCode => element.hashCode; |
9940 | 9925 |
9941 @override | 9926 @override |
9942 bool operator ==(Object object) => | 9927 bool operator ==(Object object) => |
9943 object is TypeParameterTypeImpl && (element == object.element); | 9928 object is TypeParameterTypeImpl && (element == object.element); |
9944 | 9929 |
9945 @override | 9930 @override |
9946 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => | 9931 bool isMoreSpecificThan(DartType s, |
9947 this == object; | 9932 [bool withDynamic = false, Set<Element> visitedElements]) { |
9948 | |
9949 @override | |
9950 int internalHashCode(List<DartType> visitedTypes) => hashCode; | |
9951 | |
9952 @override | |
9953 bool isMoreSpecificThan(DartType s, [Set<Element> thisExpansions, | |
9954 Set<Element> typeExpansions, bool withDynamic = false, | |
9955 Set<Element> visitedElements]) { | |
9956 // | 9933 // |
9957 // A type T is more specific than a type S, written T << S, | 9934 // A type T is more specific than a type S, written T << S, |
9958 // if one of the following conditions is met: | 9935 // if one of the following conditions is met: |
9959 // | 9936 // |
9960 // Reflexivity: T is S. | 9937 // Reflexivity: T is S. |
9961 // | 9938 // |
9962 if (this == s) { | 9939 if (this == s) { |
9963 return true; | 9940 return true; |
9964 } | 9941 } |
9965 // S is dynamic. | 9942 // S is dynamic. |
(...skipping 25 matching lines...) Expand all Loading... |
9991 if (element == null) { | 9968 if (element == null) { |
9992 return false; | 9969 return false; |
9993 } | 9970 } |
9994 if (visitedElements == null) { | 9971 if (visitedElements == null) { |
9995 visitedElements = new HashSet<Element>(); | 9972 visitedElements = new HashSet<Element>(); |
9996 } else if (visitedElements.contains(element)) { | 9973 } else if (visitedElements.contains(element)) { |
9997 return false; | 9974 return false; |
9998 } | 9975 } |
9999 visitedElements.add(element); | 9976 visitedElements.add(element); |
10000 try { | 9977 try { |
10001 return bound.isMoreSpecificThan( | 9978 return bound.isMoreSpecificThan(s, withDynamic, visitedElements); |
10002 s, thisExpansions, typeExpansions, withDynamic, visitedElements); | |
10003 } finally { | 9979 } finally { |
10004 visitedElements.remove(element); | 9980 visitedElements.remove(element); |
10005 } | 9981 } |
10006 } | 9982 } |
10007 | 9983 |
10008 @override | 9984 @override |
10009 bool isSubtypeOf(DartType type, | 9985 bool isSubtypeOf(DartType type) => isMoreSpecificThan(type, true); |
10010 [Set<Element> thisExpansions, Set<Element> typeExpansions]) => | 9986 |
10011 isMoreSpecificThan(type, thisExpansions, typeExpansions, true); | 9987 @override |
| 9988 TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this; |
10012 | 9989 |
10013 @override | 9990 @override |
10014 DartType substitute2( | 9991 DartType substitute2( |
10015 List<DartType> argumentTypes, List<DartType> parameterTypes) { | 9992 List<DartType> argumentTypes, List<DartType> parameterTypes, |
| 9993 [List<FunctionTypeAliasElement> prune]) { |
10016 int length = parameterTypes.length; | 9994 int length = parameterTypes.length; |
10017 for (int i = 0; i < length; i++) { | 9995 for (int i = 0; i < length; i++) { |
10018 if (parameterTypes[i] == this) { | 9996 if (parameterTypes[i] == this) { |
10019 return argumentTypes[i]; | 9997 return argumentTypes[i]; |
10020 } | 9998 } |
10021 } | 9999 } |
10022 return this; | 10000 return this; |
10023 } | 10001 } |
10024 | 10002 |
10025 /** | 10003 /** |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10078 @override | 10056 @override |
10079 bool get isDynamic => true; | 10057 bool get isDynamic => true; |
10080 | 10058 |
10081 @override | 10059 @override |
10082 bool get isUndefined => true; | 10060 bool get isUndefined => true; |
10083 | 10061 |
10084 @override | 10062 @override |
10085 bool operator ==(Object object) => identical(object, this); | 10063 bool operator ==(Object object) => identical(object, this); |
10086 | 10064 |
10087 @override | 10065 @override |
10088 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => | 10066 bool isMoreSpecificThan(DartType type, |
10089 identical(object, this); | 10067 [bool withDynamic = false, Set<Element> visitedElements]) { |
10090 | |
10091 @override | |
10092 int internalHashCode(List<DartType> visitedTypes) => hashCode; | |
10093 | |
10094 @override | |
10095 bool isMoreSpecificThan(DartType type, [Set<Element> thisExpansions, | |
10096 Set<Element> typeExpansions, bool withDynamic = false, | |
10097 Set<Element> visitedElements]) { | |
10098 // T is S | 10068 // T is S |
10099 if (identical(this, type)) { | 10069 if (identical(this, type)) { |
10100 return true; | 10070 return true; |
10101 } | 10071 } |
10102 // else | 10072 // else |
10103 return withDynamic; | 10073 return withDynamic; |
10104 } | 10074 } |
10105 | 10075 |
10106 @override | 10076 @override |
10107 bool isSubtypeOf(DartType type, | 10077 bool isSubtypeOf(DartType type) => true; |
10108 [Set<Element> thisExpansions, Set<Element> typeExpansions]) => true; | |
10109 | 10078 |
10110 @override | 10079 @override |
10111 bool isSupertypeOf(DartType type) => true; | 10080 bool isSupertypeOf(DartType type) => true; |
10112 | 10081 |
10113 @override | 10082 @override |
| 10083 TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this; |
| 10084 |
| 10085 @override |
10114 DartType substitute2( | 10086 DartType substitute2( |
10115 List<DartType> argumentTypes, List<DartType> parameterTypes) { | 10087 List<DartType> argumentTypes, List<DartType> parameterTypes, |
| 10088 [List<FunctionTypeAliasElement> prune]) { |
10116 int length = parameterTypes.length; | 10089 int length = parameterTypes.length; |
10117 for (int i = 0; i < length; i++) { | 10090 for (int i = 0; i < length; i++) { |
10118 if (parameterTypes[i] == this) { | 10091 if (parameterTypes[i] == this) { |
10119 return argumentTypes[i]; | 10092 return argumentTypes[i]; |
10120 } | 10093 } |
10121 } | 10094 } |
10122 return this; | 10095 return this; |
10123 } | 10096 } |
10124 } | 10097 } |
10125 | 10098 |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10413 @override | 10386 @override |
10414 int get hashCode => 2; | 10387 int get hashCode => 2; |
10415 | 10388 |
10416 @override | 10389 @override |
10417 bool get isVoid => true; | 10390 bool get isVoid => true; |
10418 | 10391 |
10419 @override | 10392 @override |
10420 bool operator ==(Object object) => identical(object, this); | 10393 bool operator ==(Object object) => identical(object, this); |
10421 | 10394 |
10422 @override | 10395 @override |
10423 bool internalEquals(Object object, Set<ElementPair> visitedElementPairs) => | 10396 bool isMoreSpecificThan(DartType type, |
10424 identical(object, this); | 10397 [bool withDynamic = false, Set<Element> visitedElements]) => |
| 10398 isSubtypeOf(type); |
10425 | 10399 |
10426 @override | 10400 @override |
10427 int internalHashCode(List<DartType> visitedTypes) => hashCode; | 10401 bool isSubtypeOf(DartType type) { |
10428 | |
10429 @override | |
10430 bool isMoreSpecificThan(DartType type, [Set<Element> thisExpansions, | |
10431 Set<Element> typeExpansions, bool withDynamic = false, | |
10432 Set<Element> visitedElements]) => isSubtypeOf(type); | |
10433 | |
10434 @override | |
10435 bool isSubtypeOf(DartType type, | |
10436 [Set<Element> thisExpansions, Set<Element> typeExpansions]) { | |
10437 // The only subtype relations that pertain to void are therefore: | 10402 // The only subtype relations that pertain to void are therefore: |
10438 // void <: void (by reflexivity) | 10403 // void <: void (by reflexivity) |
10439 // bottom <: void (as bottom is a subtype of all types). | 10404 // bottom <: void (as bottom is a subtype of all types). |
10440 // void <: dynamic (as dynamic is a supertype of all types) | 10405 // void <: dynamic (as dynamic is a supertype of all types) |
10441 return identical(type, this) || type.isDynamic; | 10406 return identical(type, this) || type.isDynamic; |
10442 } | 10407 } |
10443 | 10408 |
10444 @override | 10409 @override |
| 10410 TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this; |
| 10411 |
| 10412 @override |
10445 VoidTypeImpl substitute2( | 10413 VoidTypeImpl substitute2( |
10446 List<DartType> argumentTypes, List<DartType> parameterTypes) => this; | 10414 List<DartType> argumentTypes, List<DartType> parameterTypes, |
| 10415 [List<FunctionTypeAliasElement> prune]) => this; |
10447 } | 10416 } |
10448 | 10417 |
10449 /** | 10418 /** |
10450 * A visitor that visit all the elements recursively and fill the given [map]. | 10419 * A visitor that visit all the elements recursively and fill the given [map]. |
10451 */ | 10420 */ |
10452 class _BuildOffsetToElementMap extends GeneralizingElementVisitor { | 10421 class _BuildOffsetToElementMap extends GeneralizingElementVisitor { |
10453 final Map<int, Element> map; | 10422 final Map<int, Element> map; |
10454 | 10423 |
10455 _BuildOffsetToElementMap(this.map); | 10424 _BuildOffsetToElementMap(this.map); |
10456 | 10425 |
10457 @override | 10426 @override |
10458 void visitElement(Element element) { | 10427 void visitElement(Element element) { |
10459 int offset = element.nameOffset; | 10428 int offset = element.nameOffset; |
10460 if (offset != -1) { | 10429 if (offset != -1) { |
10461 map[offset] = element; | 10430 map[offset] = element; |
10462 } | 10431 } |
10463 super.visitElement(element); | 10432 super.visitElement(element); |
10464 } | 10433 } |
10465 } | 10434 } |
OLD | NEW |