| 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 |