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 library engine.element; | 5 library engine.element; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 import 'dart:math' show min; | 8 import 'dart:math' show min; |
9 | 9 |
10 import 'package:analyzer/src/generated/utilities_general.dart'; | 10 import 'package:analyzer/src/generated/utilities_general.dart'; |
(...skipping 4559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4570 * of the function. | 4570 * of the function. |
4571 */ | 4571 */ |
4572 List<ParameterElement> get parameters; | 4572 List<ParameterElement> get parameters; |
4573 | 4573 |
4574 /** | 4574 /** |
4575 * Return the type of object returned by this type of function. | 4575 * Return the type of object returned by this type of function. |
4576 */ | 4576 */ |
4577 DartType get returnType; | 4577 DartType get returnType; |
4578 | 4578 |
4579 /** | 4579 /** |
4580 * The type parameters of this generic function. For example `<T> T -> T`. | |
4581 * | |
4582 * These are distinct from the [typeParameters] list, which contains type | |
4583 * parameters from surrounding contexts, and thus are free type variables from | |
4584 * the perspective of this function type. | |
4585 */ | |
4586 List<TypeParameterElement> get boundTypeParameters; | |
4587 | |
4588 /** | |
4589 * Return the type resulting from instantiating (replacing) the given | |
4590 * [argumentTypes] for this function's bound type parameters. | |
4591 */ | |
4592 FunctionType instantiate(List<DartType> argumentTypes); | |
4593 | |
4594 /** | |
4580 * Return `true` if this type is a subtype of the given [type]. | 4595 * Return `true` if this type is a subtype of the given [type]. |
4581 * | 4596 * |
4582 * A function type <i>(T<sub>1</sub>, …, T<sub>n</sub>) → T</i> is | 4597 * A function type <i>(T<sub>1</sub>, …, T<sub>n</sub>) → T</i> is |
4583 * a subtype of the function type <i>(S<sub>1</sub>, …, S<sub>n</sub>) | 4598 * a subtype of the function type <i>(S<sub>1</sub>, …, S<sub>n</sub>) |
4584 * → S</i>, if all of the following conditions are met: | 4599 * → S</i>, if all of the following conditions are met: |
4585 * | 4600 * |
4586 * * Either | 4601 * * Either |
4587 * * <i>S</i> is void, or | 4602 * * <i>S</i> is void, or |
4588 * * <i>T ⇔ S</i>. | 4603 * * <i>T ⇔ S</i>. |
4589 * | 4604 * |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4640 | 4655 |
4641 @override | 4656 @override |
4642 FunctionType substitute2( | 4657 FunctionType substitute2( |
4643 List<DartType> argumentTypes, List<DartType> parameterTypes); | 4658 List<DartType> argumentTypes, List<DartType> parameterTypes); |
4644 | 4659 |
4645 /** | 4660 /** |
4646 * Return the type resulting from substituting the given [argumentTypes] for | 4661 * Return the type resulting from substituting the given [argumentTypes] for |
4647 * this type's parameters. This is fully equivalent to | 4662 * this type's parameters. This is fully equivalent to |
4648 * `substitute(argumentTypes, getTypeArguments())`. | 4663 * `substitute(argumentTypes, getTypeArguments())`. |
4649 */ | 4664 */ |
4665 @deprecated // use instantiate | |
4650 FunctionType substitute3(List<DartType> argumentTypes); | 4666 FunctionType substitute3(List<DartType> argumentTypes); |
4651 } | 4667 } |
4652 | 4668 |
4653 /** | 4669 /** |
4654 * A function type alias (`typedef`). | 4670 * A function type alias (`typedef`). |
4655 */ | 4671 */ |
4656 abstract class FunctionTypeAliasElement | 4672 abstract class FunctionTypeAliasElement |
4657 implements TypeDefiningElement, TypeParameterizedElement { | 4673 implements TypeDefiningElement, TypeParameterizedElement { |
4658 /** | 4674 /** |
4659 * An empty array of type alias elements. | 4675 * An empty array of type alias elements. |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4837 } | 4853 } |
4838 } | 4854 } |
4839 | 4855 |
4840 /** | 4856 /** |
4841 * The type of a function, method, constructor, getter, or setter. | 4857 * The type of a function, method, constructor, getter, or setter. |
4842 */ | 4858 */ |
4843 class FunctionTypeImpl extends TypeImpl implements FunctionType { | 4859 class FunctionTypeImpl extends TypeImpl implements FunctionType { |
4844 /** | 4860 /** |
4845 * The list of [typeArguments]. | 4861 * The list of [typeArguments]. |
4846 */ | 4862 */ |
4847 List<DartType> _typeArguments = DartType.EMPTY_LIST; | 4863 List<DartType> _typeArguments; |
4864 | |
4865 /** | |
4866 * The list of [typeParameters]. | |
4867 */ | |
4868 List<TypeParameterElement> _typeParameters; | |
4869 | |
4870 /** | |
4871 * The list of [boundTypeParameters]. | |
4872 */ | |
4873 List<TypeParameterElement> _boundTypeParameters; | |
4848 | 4874 |
4849 /** | 4875 /** |
4850 * The set of typedefs which should not be expanded when exploring this type, | 4876 * The set of typedefs which should not be expanded when exploring this type, |
4851 * to avoid creating infinite types in response to self-referential typedefs. | 4877 * to avoid creating infinite types in response to self-referential typedefs. |
4852 */ | 4878 */ |
4853 final List<FunctionTypeAliasElement> prunedTypedefs; | 4879 final List<FunctionTypeAliasElement> prunedTypedefs; |
4854 | 4880 |
4855 /** | 4881 /** |
4856 * Initialize a newly created function type to be declared by the given | 4882 * Initialize a newly created function type to be declared by the given |
4857 * [element], and also initialize [typeArguments] to match the | 4883 * [element], and also initialize [typeArguments] to match the |
4858 * [typeParameters], which permits later substitution. | 4884 * [typeParameters], which permits later substitution. |
4859 */ | 4885 */ |
4860 FunctionTypeImpl(ExecutableElement element, | 4886 FunctionTypeImpl(ExecutableElement element, |
4861 [List<FunctionTypeAliasElement> prunedTypedefs]) | 4887 [List<FunctionTypeAliasElement> prunedTypedefs]) |
4862 : this._(element, null, prunedTypedefs, null); | 4888 : this._(element, null, prunedTypedefs, null, null, null); |
4863 | 4889 |
4864 /** | 4890 /** |
4865 * Initialize a newly created function type to be declared by the given | 4891 * Initialize a newly created function type to be declared by the given |
4866 * [element]. | 4892 * [element]. |
4867 */ | 4893 */ |
4868 @deprecated // Use new FunctionTypeImpl(element) | 4894 @deprecated // Use new FunctionTypeImpl(element) |
4869 FunctionTypeImpl.con1(ExecutableElement element) : this(element); | 4895 FunctionTypeImpl.con1(ExecutableElement element) : this(element); |
4870 | 4896 |
4871 /** | 4897 /** |
4872 * Initialize a newly created function type to be declared by the given | 4898 * Initialize a newly created function type to be declared by the given |
4873 * [element]. | 4899 * [element]. |
4874 */ | 4900 */ |
4875 @deprecated // Use new FunctionTypeImpl.forTypedef(element) | 4901 @deprecated // Use new FunctionTypeImpl.forTypedef(element) |
4876 FunctionTypeImpl.con2(FunctionTypeAliasElement element) | 4902 FunctionTypeImpl.con2(FunctionTypeAliasElement element) |
4877 : this.forTypedef(element); | 4903 : this.forTypedef(element); |
4878 | 4904 |
4879 /** | 4905 /** |
4880 * Initialize a newly created function type to be declared by the given | 4906 * Initialize a newly created function type to be declared by the given |
4881 * [element]. | 4907 * [element]. |
4882 */ | 4908 */ |
4883 FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element, | 4909 FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element, |
4884 [List<FunctionTypeAliasElement> prunedTypedefs]) | 4910 [List<FunctionTypeAliasElement> prunedTypedefs]) |
4885 : this._(element, element?.name, prunedTypedefs, null); | 4911 : this._(element, element?.name, prunedTypedefs, null, null, null); |
4886 | 4912 |
4887 /** | 4913 /** |
4888 * Private constructor. | 4914 * Private constructor. |
4889 */ | 4915 */ |
4890 FunctionTypeImpl._(Element element, String name, this.prunedTypedefs, | 4916 FunctionTypeImpl._( |
4891 List<DartType> typeArguments) | 4917 TypeParameterizedElement element, String name, this.prunedTypedefs, |
4918 List<DartType> typeArguments, | |
4919 List<TypeParameterElement> typeParameters, | |
4920 List<TypeParameterElement> boundTypeParameters) | |
4892 : super(element, name) { | 4921 : super(element, name) { |
4893 if (typeArguments != null) { | 4922 _boundTypeParameters = boundTypeParameters ?? |
4894 _typeArguments = typeArguments; | 4923 element?.typeParameters ?? |
4895 } else { | 4924 TypeParameterElement.EMPTY_LIST; |
4896 List<TypeParameterElement> typeParameters = this.typeParameters; | 4925 |
4926 if (typeParameters == null) { | |
4927 // Combine the generic type variables from all enclosing contexts, except | |
4928 // for this generic function's type variables. Those variables are | |
4929 // tracked in [boundTypeParameters]. | |
4930 typeParameters = <TypeParameterElement>[]; | |
4931 Element e = element?.enclosingElement; | |
4932 while (e != null) { | |
4933 if (e is TypeParameterizedElement) { | |
4934 typeParameters.addAll((e as TypeParameterizedElement).typeParameters); | |
4935 } | |
4936 e = e.enclosingElement; | |
4937 } | |
4938 } | |
4939 _typeParameters = typeParameters; | |
4940 | |
4941 if (typeArguments == null) { | |
4897 // TODO(jmesserly): reuse TypeParameterTypeImpl.getTypes once we can | 4942 // TODO(jmesserly): reuse TypeParameterTypeImpl.getTypes once we can |
4898 // make it generic, which will allow it to return List<DartType> instead | 4943 // make it generic, which will allow it to return List<DartType> instead |
4899 // of List<TypeParameterType>. | 4944 // of List<TypeParameterType>. |
4900 if (typeParameters.isEmpty) { | 4945 if (typeParameters.isEmpty) { |
4901 _typeArguments = DartType.EMPTY_LIST; | 4946 typeArguments = DartType.EMPTY_LIST; |
4902 } else { | 4947 } else { |
4903 _typeArguments = new List<DartType>.from( | 4948 typeArguments = new List<DartType>.from( |
4904 typeParameters.map((t) => t.type), | 4949 typeParameters.map((t) => t.type), |
4905 growable: false); | 4950 growable: false); |
4906 } | 4951 } |
4907 } | 4952 } |
4953 _typeArguments = typeArguments; | |
4908 } | 4954 } |
4909 | 4955 |
4910 /** | 4956 /** |
4911 * Return the base parameter elements of this function element. | 4957 * Return the base parameter elements of this function element. |
4912 */ | 4958 */ |
4913 List<ParameterElement> get baseParameters { | 4959 List<ParameterElement> get baseParameters { |
4914 Element element = this.element; | 4960 Element element = this.element; |
4915 if (element is ExecutableElement) { | 4961 if (element is ExecutableElement) { |
4916 return element.parameters; | 4962 return element.parameters; |
4917 } else { | 4963 } else { |
4918 return (element as FunctionTypeAliasElement).parameters; | 4964 return (element as FunctionTypeAliasElement).parameters; |
4919 } | 4965 } |
4920 } | 4966 } |
4921 | 4967 |
4922 /** | 4968 /** |
4923 * Return the return type defined by this function's element. | 4969 * Return the return type defined by this function's element. |
4924 */ | 4970 */ |
4925 DartType get baseReturnType { | 4971 DartType get baseReturnType { |
4926 Element element = this.element; | 4972 Element element = this.element; |
4927 if (element is ExecutableElement) { | 4973 if (element is ExecutableElement) { |
4928 return element.returnType; | 4974 return element.returnType; |
4929 } else { | 4975 } else { |
4930 return (element as FunctionTypeAliasElement).returnType; | 4976 return (element as FunctionTypeAliasElement).returnType; |
4931 } | 4977 } |
4932 } | 4978 } |
4933 | 4979 |
4934 @override | 4980 @override |
4981 List<TypeParameterElement> get boundTypeParameters => _boundTypeParameters; | |
4982 | |
4983 @override | |
4935 String get displayName { | 4984 String get displayName { |
4936 String name = this.name; | 4985 String name = this.name; |
4937 if (name == null || name.length == 0) { | 4986 if (name == null || name.length == 0) { |
4938 // Function types have an empty name when they are defined implicitly by | 4987 // Function types have an empty name when they are defined implicitly by |
4939 // either a closure or as part of a parameter declaration. | 4988 // either a closure or as part of a parameter declaration. |
4940 List<DartType> normalParameterTypes = this.normalParameterTypes; | 4989 List<DartType> normalParameterTypes = this.normalParameterTypes; |
4941 List<DartType> optionalParameterTypes = this.optionalParameterTypes; | 4990 List<DartType> optionalParameterTypes = this.optionalParameterTypes; |
4942 Map<String, DartType> namedParameterTypes = this.namedParameterTypes; | 4991 Map<String, DartType> namedParameterTypes = this.namedParameterTypes; |
4943 DartType returnType = this.returnType; | 4992 DartType returnType = this.returnType; |
4944 StringBuffer buffer = new StringBuffer(); | 4993 StringBuffer buffer = new StringBuffer(); |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5156 return (baseReturnType as TypeImpl).substitute2(typeArguments, | 5205 return (baseReturnType as TypeImpl).substitute2(typeArguments, |
5157 TypeParameterTypeImpl.getTypes(typeParameters), newPrune); | 5206 TypeParameterTypeImpl.getTypes(typeParameters), newPrune); |
5158 } | 5207 } |
5159 | 5208 |
5160 /** | 5209 /** |
5161 * A list containing the actual types of the type arguments. | 5210 * A list containing the actual types of the type arguments. |
5162 */ | 5211 */ |
5163 List<DartType> get typeArguments => _typeArguments; | 5212 List<DartType> get typeArguments => _typeArguments; |
5164 | 5213 |
5165 @override | 5214 @override |
5166 List<TypeParameterElement> get typeParameters { | 5215 List<TypeParameterElement> get typeParameters => _typeParameters; |
5167 // Combine the generic type arguments from all enclosing contexts. | |
5168 // For example, this could be a generic method in a class, or a local | |
5169 // function within another function. | |
5170 List<TypeParameterElement> typeParams = <TypeParameterElement>[]; | |
5171 for (Element e = element; e != null; e = e.enclosingElement) { | |
5172 if (e is TypeParameterizedElement) { | |
5173 typeParams.addAll(e.typeParameters); | |
5174 } | |
5175 } | |
5176 return typeParams; | |
5177 } | |
5178 | 5216 |
5179 @override | 5217 @override |
5180 bool operator ==(Object object) { | 5218 bool operator ==(Object object) { |
Leaf
2015/12/03 18:46:35
It doesn't seem to have been done before either, b
Jennifer Messerly
2015/12/03 19:20:56
Done.
| |
5181 if (object is! FunctionTypeImpl) { | 5219 if (object is! FunctionTypeImpl) { |
5182 return false; | 5220 return false; |
5183 } | 5221 } |
5184 FunctionTypeImpl otherType = object as FunctionTypeImpl; | 5222 FunctionTypeImpl otherType = object as FunctionTypeImpl; |
5223 if (boundTypeParameters.length != otherType.boundTypeParameters.length) { | |
5224 return false; | |
5225 } | |
5226 // `<T>T -> T` should be equal to `<U>U -> U` | |
5227 // To test this, we instantiate both types with the same (unique) type | |
5228 // variables, and see if the result is equal. | |
5229 if (boundTypeParameters.isNotEmpty) { | |
5230 List<DartType> instantiateTypeArgs = new List<DartType>(); | |
5231 for (TypeParameterElement e in boundTypeParameters) { | |
5232 instantiateTypeArgs.add(new TypeParameterTypeImpl( | |
5233 new TypeParameterElementImpl(e.name, -1))); | |
5234 } | |
5235 // After instantiation, they will no longer have boundTypeParameters, | |
5236 // so we will continue below. | |
5237 return this.instantiate(instantiateTypeArgs) == | |
5238 otherType.instantiate(instantiateTypeArgs); | |
5239 } | |
5240 | |
5185 return returnType == otherType.returnType && | 5241 return returnType == otherType.returnType && |
5186 TypeImpl.equalArrays( | 5242 TypeImpl.equalArrays( |
5187 normalParameterTypes, otherType.normalParameterTypes) && | 5243 normalParameterTypes, otherType.normalParameterTypes) && |
5188 TypeImpl.equalArrays( | 5244 TypeImpl.equalArrays( |
5189 optionalParameterTypes, otherType.optionalParameterTypes) && | 5245 optionalParameterTypes, otherType.optionalParameterTypes) && |
5190 _equals(namedParameterTypes, otherType.namedParameterTypes); | 5246 _equals(namedParameterTypes, otherType.namedParameterTypes); |
5191 } | 5247 } |
5192 | 5248 |
5193 @override | 5249 @override |
5194 void appendTo(StringBuffer buffer) { | 5250 void appendTo(StringBuffer buffer) { |
5251 if (boundTypeParameters.isNotEmpty) { | |
5252 // To print a type with type variables, first make sure we have unique | |
5253 // variable names to print. | |
5254 Set<String> namesToAvoid = new HashSet<String>(); | |
5255 for (DartType arg in typeArguments) { | |
Leaf
2015/12/03 18:46:35
I think you're re-inventing Simon Peyton Jones' ra
Jennifer Messerly
2015/12/03 19:20:56
DOH. You're right... I was hoping not to have to v
Jennifer Messerly
2015/12/03 22:48:07
Done.
| |
5256 if (arg is TypeParameterType) { | |
5257 namesToAvoid.add(arg.displayName); | |
5258 } | |
5259 } | |
5260 | |
5261 List<DartType> instantiateTypeArgs = new List<DartType>(); | |
5262 buffer.write("<"); | |
5263 for (TypeParameterElement e in boundTypeParameters) { | |
5264 if (e != boundTypeParameters[0]) { | |
5265 buffer.write(","); | |
5266 } | |
5267 String name = e.name; | |
5268 int counter = 0; | |
5269 while (!namesToAvoid.add(name)) { | |
5270 // Unicode subscript-zero is U+2080, zero is U+0030. Other digits | |
5271 // are sequential from there. Thus +0x2050 will get us the subscript. | |
5272 String subscript = new String.fromCharCodes( | |
5273 counter.toString().codeUnits.map((n) => n + 0x2050)); | |
5274 | |
5275 name = e.name + subscript; | |
5276 counter++; | |
5277 } | |
5278 TypeParameterTypeImpl t = | |
5279 new TypeParameterTypeImpl(new TypeParameterElementImpl(name, -1)); | |
5280 t.appendTo(buffer); | |
5281 instantiateTypeArgs.add(t); | |
5282 } | |
5283 buffer.write(">"); | |
5284 | |
5285 // Instantiate it and print the resulting type. After instantiation, it | |
5286 // will no longer have boundTypeParameters, so we will continue below. | |
5287 this.instantiate(instantiateTypeArgs).appendTo(buffer); | |
5288 return; | |
5289 } | |
5290 | |
5195 List<DartType> normalParameterTypes = this.normalParameterTypes; | 5291 List<DartType> normalParameterTypes = this.normalParameterTypes; |
5196 List<DartType> optionalParameterTypes = this.optionalParameterTypes; | 5292 List<DartType> optionalParameterTypes = this.optionalParameterTypes; |
5197 Map<String, DartType> namedParameterTypes = this.namedParameterTypes; | 5293 Map<String, DartType> namedParameterTypes = this.namedParameterTypes; |
5198 DartType returnType = this.returnType; | 5294 DartType returnType = this.returnType; |
5199 buffer.write("("); | 5295 buffer.write("("); |
5200 bool needsComma = false; | 5296 bool needsComma = false; |
5201 if (normalParameterTypes.length > 0) { | 5297 if (normalParameterTypes.isNotEmpty) { |
5202 for (DartType type in normalParameterTypes) { | 5298 for (DartType type in normalParameterTypes) { |
5203 if (needsComma) { | 5299 if (needsComma) { |
5204 buffer.write(", "); | 5300 buffer.write(", "); |
5205 } else { | 5301 } else { |
5206 needsComma = true; | 5302 needsComma = true; |
5207 } | 5303 } |
5208 (type as TypeImpl).appendTo(buffer); | 5304 (type as TypeImpl).appendTo(buffer); |
5209 } | 5305 } |
5210 } | 5306 } |
5211 if (optionalParameterTypes.length > 0) { | 5307 if (optionalParameterTypes.isNotEmpty) { |
5212 if (needsComma) { | 5308 if (needsComma) { |
5213 buffer.write(", "); | 5309 buffer.write(", "); |
5214 needsComma = false; | 5310 needsComma = false; |
5215 } | 5311 } |
5216 buffer.write("["); | 5312 buffer.write("["); |
5217 for (DartType type in optionalParameterTypes) { | 5313 for (DartType type in optionalParameterTypes) { |
5218 if (needsComma) { | 5314 if (needsComma) { |
5219 buffer.write(", "); | 5315 buffer.write(", "); |
5220 } else { | 5316 } else { |
5221 needsComma = true; | 5317 needsComma = true; |
5222 } | 5318 } |
5223 (type as TypeImpl).appendTo(buffer); | 5319 (type as TypeImpl).appendTo(buffer); |
5224 } | 5320 } |
5225 buffer.write("]"); | 5321 buffer.write("]"); |
5226 needsComma = true; | 5322 needsComma = true; |
5227 } | 5323 } |
5228 if (namedParameterTypes.length > 0) { | 5324 if (namedParameterTypes.isNotEmpty) { |
5229 if (needsComma) { | 5325 if (needsComma) { |
5230 buffer.write(", "); | 5326 buffer.write(", "); |
5231 needsComma = false; | 5327 needsComma = false; |
5232 } | 5328 } |
5233 buffer.write("{"); | 5329 buffer.write("{"); |
5234 namedParameterTypes.forEach((String name, DartType type) { | 5330 namedParameterTypes.forEach((String name, DartType type) { |
5235 if (needsComma) { | 5331 if (needsComma) { |
5236 buffer.write(", "); | 5332 buffer.write(", "); |
5237 } else { | 5333 } else { |
5238 needsComma = true; | 5334 needsComma = true; |
5239 } | 5335 } |
5240 buffer.write(name); | 5336 buffer.write(name); |
5241 buffer.write(": "); | 5337 buffer.write(": "); |
5242 (type as TypeImpl).appendTo(buffer); | 5338 (type as TypeImpl).appendTo(buffer); |
5243 }); | 5339 }); |
5244 buffer.write("}"); | 5340 buffer.write("}"); |
5245 needsComma = true; | 5341 needsComma = true; |
5246 } | 5342 } |
5247 buffer.write(")"); | 5343 buffer.write(")"); |
5248 buffer.write(Element.RIGHT_ARROW); | 5344 buffer.write(Element.RIGHT_ARROW); |
5249 if (returnType == null) { | 5345 if (returnType == null) { |
5250 buffer.write("null"); | 5346 buffer.write("null"); |
5251 } else { | 5347 } else { |
5252 (returnType as TypeImpl).appendTo(buffer); | 5348 (returnType as TypeImpl).appendTo(buffer); |
5253 } | 5349 } |
5254 } | 5350 } |
5255 | 5351 |
5256 @override | 5352 @override |
5353 FunctionTypeImpl instantiate(List<DartType> argumentTypes) { | |
5354 if (argumentTypes.length != boundTypeParameters.length) { | |
5355 throw new IllegalArgumentException( | |
5356 "argumentTypes.length (${argumentTypes.length}) != " | |
5357 "boundTypeParameters.length (${boundTypeParameters.length})"); | |
5358 } | |
5359 if (argumentTypes.isEmpty) { | |
5360 return this; | |
5361 } | |
5362 | |
5363 // Given: | |
5364 // {U/T} <S> T -> S | |
5365 // Where {U/T} represents the typeArguments (U) and typeParameters (T) list, | |
5366 // and <S> represents the boundTypeParameters. | |
5367 // | |
5368 // Now instantiate([V]), and the result should be: | |
5369 // {U/T, V/S} T -> S. | |
5370 List<TypeParameterElement> newTypeParams = typeParameters.toList(); | |
5371 List<DartType> newTypeArgs = typeArguments.toList(); | |
5372 newTypeParams.addAll(boundTypeParameters); | |
5373 newTypeArgs.addAll(argumentTypes); | |
5374 | |
5375 return new FunctionTypeImpl._(element, name, prunedTypedefs, newTypeArgs, | |
5376 newTypeParams, TypeParameterElement.EMPTY_LIST); | |
5377 } | |
5378 | |
5379 @override | |
5257 bool isAssignableTo(DartType type) { | 5380 bool isAssignableTo(DartType type) { |
5258 // A function type T may be assigned to a function type S, written T <=> S, | 5381 // A function type T may be assigned to a function type S, written T <=> S, |
5259 // iff T <: S. | 5382 // iff T <: S. |
5260 return isSubtypeOf(type); | 5383 return isSubtypeOf(type); |
5261 } | 5384 } |
5262 | 5385 |
5263 @override | 5386 @override |
5264 bool isMoreSpecificThan(DartType type, | 5387 bool isMoreSpecificThan(DartType type, |
5265 [bool withDynamic = false, Set<Element> visitedElements]) { | 5388 [bool withDynamic = false, Set<Element> visitedElements]) { |
5266 // Note: visitedElements is only used for breaking recursion in the type | 5389 // Note: visitedElements is only used for breaking recursion in the type |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5495 return new CircularTypeImpl(); | 5618 return new CircularTypeImpl(); |
5496 } else { | 5619 } else { |
5497 // There should never be a reason to prune a type that has already been | 5620 // There should never be a reason to prune a type that has already been |
5498 // pruned, since pruning is only done when expanding a function type | 5621 // pruned, since pruning is only done when expanding a function type |
5499 // alias, and function type aliases are always expanded by starting with | 5622 // alias, and function type aliases are always expanded by starting with |
5500 // base types. | 5623 // base types. |
5501 assert(this.prunedTypedefs == null); | 5624 assert(this.prunedTypedefs == null); |
5502 List<DartType> typeArgs = typeArguments | 5625 List<DartType> typeArgs = typeArguments |
5503 .map((TypeImpl t) => t.pruned(prune)) | 5626 .map((TypeImpl t) => t.pruned(prune)) |
5504 .toList(growable: false); | 5627 .toList(growable: false); |
5505 return new FunctionTypeImpl._(element, name, prune, typeArgs); | 5628 return new FunctionTypeImpl._(element, name, prune, typeArgs, |
5629 _typeParameters, _boundTypeParameters); | |
5506 } | 5630 } |
5507 } | 5631 } |
5508 | 5632 |
5509 @override | 5633 @override |
5510 DartType substitute2( | 5634 DartType substitute2( |
5511 List<DartType> argumentTypes, List<DartType> parameterTypes, | 5635 List<DartType> argumentTypes, List<DartType> parameterTypes, |
5512 [List<FunctionTypeAliasElement> prune]) { | 5636 [List<FunctionTypeAliasElement> prune]) { |
5513 // Pruned types should only ever result from performing type variable | 5637 // Pruned types should only ever result from performing type variable |
5514 // substitution, and it doesn't make sense to substitute again after | 5638 // substitution, and it doesn't make sense to substitute again after |
5515 // substituting once. | 5639 // substituting once. |
5516 assert(this.prunedTypedefs == null); | 5640 assert(this.prunedTypedefs == null); |
5517 if (argumentTypes.length != parameterTypes.length) { | 5641 if (argumentTypes.length != parameterTypes.length) { |
5518 throw new IllegalArgumentException( | 5642 throw new IllegalArgumentException( |
5519 "argumentTypes.length (${argumentTypes.length}) != parameterTypes.leng th (${parameterTypes.length})"); | 5643 "argumentTypes.length (${argumentTypes.length}) != parameterTypes.leng th (${parameterTypes.length})"); |
5520 } | 5644 } |
5521 Element element = this.element; | 5645 Element element = this.element; |
5522 if (prune != null && prune.contains(element)) { | 5646 if (prune != null && prune.contains(element)) { |
5523 // Circularity found. Prune the type declaration. | 5647 // Circularity found. Prune the type declaration. |
5524 return new CircularTypeImpl(); | 5648 return new CircularTypeImpl(); |
5525 } | 5649 } |
5526 if (argumentTypes.length == 0) { | 5650 if (argumentTypes.length == 0) { |
5527 return this.pruned(prune); | 5651 return this.pruned(prune); |
5528 } | 5652 } |
5529 List<DartType> typeArgs = | 5653 List<DartType> typeArgs = |
5530 TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes); | 5654 TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes); |
5531 return new FunctionTypeImpl._(element, name, prune, typeArgs); | 5655 return new FunctionTypeImpl._( |
5656 element, name, prune, typeArgs, _typeParameters, _boundTypeParameters); | |
5532 } | 5657 } |
5533 | 5658 |
5534 @override | 5659 @override |
5535 FunctionTypeImpl substitute3(List<DartType> argumentTypes) => | 5660 FunctionTypeImpl substitute3(List<DartType> argumentTypes) => |
5536 substitute2(argumentTypes, typeArguments); | 5661 substitute2(argumentTypes, typeArguments); |
5537 | 5662 |
5538 /** | 5663 /** |
5539 * Compute the least upper bound of types [f] and [g], both of which are | 5664 * Compute the least upper bound of types [f] and [g], both of which are |
5540 * known to be function types. | 5665 * known to be function types. |
5541 * | 5666 * |
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6349 * to <i>L</i>. Otherwise, we say that the lookup has failed. | 6474 * to <i>L</i>. Otherwise, we say that the lookup has failed. |
6350 * </blockquote> | 6475 * </blockquote> |
6351 */ | 6476 */ |
6352 PropertyAccessorElement lookUpSetterInSuperclass( | 6477 PropertyAccessorElement lookUpSetterInSuperclass( |
6353 String name, LibraryElement library); | 6478 String name, LibraryElement library); |
6354 | 6479 |
6355 @override | 6480 @override |
6356 InterfaceType substitute2( | 6481 InterfaceType substitute2( |
6357 List<DartType> argumentTypes, List<DartType> parameterTypes); | 6482 List<DartType> argumentTypes, List<DartType> parameterTypes); |
6358 | 6483 |
6484 // TODO(jmesserly): introduce a new "instantiate" and deprecate this. | |
6485 // The new "instantiate" should work similar to FunctionType.instantiate, | |
6486 // which uses [boundTypeParameters] to model type parameters that haven't been | |
6487 // filled in yet. Those are kept separate from already-substituted type | |
6488 // parameters or free variables from the enclosing scopes, which allows nested | |
6489 // generics to work, such as a generic method in a generic class. | |
6359 /** | 6490 /** |
6360 * Return the type resulting from substituting the given arguments for this | 6491 * Return the type resulting from substituting the given arguments for this |
6361 * type's parameters. This is fully equivalent to `substitute2(argumentTypes, | 6492 * type's parameters. This is fully equivalent to `substitute2(argumentTypes, |
6362 * getTypeArguments())`. | 6493 * getTypeArguments())`. |
6363 */ | 6494 */ |
6364 InterfaceType substitute4(List<DartType> argumentTypes); | 6495 InterfaceType substitute4(List<DartType> argumentTypes); |
6365 | 6496 |
6366 /** | 6497 /** |
6367 * Returns a "smart" version of the "least upper bound" of the given types. | 6498 * Returns a "smart" version of the "least upper bound" of the given types. |
6368 * | 6499 * |
(...skipping 4779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11148 | 11279 |
11149 @override | 11280 @override |
11150 void visitElement(Element element) { | 11281 void visitElement(Element element) { |
11151 int offset = element.nameOffset; | 11282 int offset = element.nameOffset; |
11152 if (offset != -1) { | 11283 if (offset != -1) { |
11153 map[offset] = element; | 11284 map[offset] = element; |
11154 } | 11285 } |
11155 super.visitElement(element); | 11286 super.visitElement(element); |
11156 } | 11287 } |
11157 } | 11288 } |
OLD | NEW |