| 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 4522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4533 * general form <i>(T<sub>1</sub>, …, T<sub>n</sub>) → T</i>. | 4533 * general form <i>(T<sub>1</sub>, …, T<sub>n</sub>) → T</i>. |
| 4534 * * The types of functions with optional positional parameters. These have the | 4534 * * The types of functions with optional positional parameters. These have the |
| 4535 * general form <i>(T<sub>1</sub>, …, T<sub>n</sub>, [T<sub>n+1</sub> | 4535 * general form <i>(T<sub>1</sub>, …, T<sub>n</sub>, [T<sub>n+1</sub> |
| 4536 * …, T<sub>n+k</sub>]) → T</i>. | 4536 * …, T<sub>n+k</sub>]) → T</i>. |
| 4537 * * The types of functions with named parameters. These have the general form | 4537 * * The types of functions with named parameters. These have the general form |
| 4538 * <i>(T<sub>1</sub>, …, T<sub>n</sub>, {T<sub>x1</sub> x1, …, | 4538 * <i>(T<sub>1</sub>, …, T<sub>n</sub>, {T<sub>x1</sub> x1, …, |
| 4539 * T<sub>xk</sub> xk}) → T</i>. | 4539 * T<sub>xk</sub> xk}) → T</i>. |
| 4540 */ | 4540 */ |
| 4541 abstract class FunctionType implements ParameterizedType { | 4541 abstract class FunctionType implements ParameterizedType { |
| 4542 /** | 4542 /** |
| 4543 * The type parameters of this generic function. For example `<T> T -> T`. |
| 4544 * |
| 4545 * These are distinct from the [typeParameters] list, which contains type |
| 4546 * parameters from surrounding contexts, and thus are free type variables from |
| 4547 * the perspective of this function type. |
| 4548 */ |
| 4549 List<TypeParameterElement> get boundTypeParameters; |
| 4550 |
| 4551 /** |
| 4543 * Return a map from the names of named parameters to the types of the named | 4552 * Return a map from the names of named parameters to the types of the named |
| 4544 * parameters of this type of function. The entries in the map will be | 4553 * parameters of this type of function. The entries in the map will be |
| 4545 * iterated in the same order as the order in which the named parameters were | 4554 * iterated in the same order as the order in which the named parameters were |
| 4546 * defined. If there were no named parameters declared then the map will be | 4555 * defined. If there were no named parameters declared then the map will be |
| 4547 * empty. | 4556 * empty. |
| 4548 */ | 4557 */ |
| 4549 Map<String, DartType> get namedParameterTypes; | 4558 Map<String, DartType> get namedParameterTypes; |
| 4550 | 4559 |
| 4551 /** | 4560 /** |
| 4552 * Return a list containing the types of the normal parameters of this type of | 4561 * Return a list containing the types of the normal parameters of this type of |
| (...skipping 17 matching lines...) Expand all Loading... |
| 4570 * of the function. | 4579 * of the function. |
| 4571 */ | 4580 */ |
| 4572 List<ParameterElement> get parameters; | 4581 List<ParameterElement> get parameters; |
| 4573 | 4582 |
| 4574 /** | 4583 /** |
| 4575 * Return the type of object returned by this type of function. | 4584 * Return the type of object returned by this type of function. |
| 4576 */ | 4585 */ |
| 4577 DartType get returnType; | 4586 DartType get returnType; |
| 4578 | 4587 |
| 4579 /** | 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, |
| 4918 String name, |
| 4919 this.prunedTypedefs, |
| 4920 List<DartType> typeArguments, |
| 4921 List<TypeParameterElement> typeParameters, |
| 4922 List<TypeParameterElement> boundTypeParameters) |
| 4892 : super(element, name) { | 4923 : super(element, name) { |
| 4893 if (typeArguments != null) { | 4924 _boundTypeParameters = boundTypeParameters ?? |
| 4894 _typeArguments = typeArguments; | 4925 element?.typeParameters ?? |
| 4895 } else { | 4926 TypeParameterElement.EMPTY_LIST; |
| 4896 List<TypeParameterElement> typeParameters = this.typeParameters; | 4927 |
| 4928 if (typeParameters == null) { |
| 4929 // Combine the generic type variables from all enclosing contexts, except |
| 4930 // for this generic function's type variables. Those variables are |
| 4931 // tracked in [boundTypeParameters]. |
| 4932 typeParameters = <TypeParameterElement>[]; |
| 4933 Element e = element?.enclosingElement; |
| 4934 while (e != null) { |
| 4935 if (e is TypeParameterizedElement) { |
| 4936 typeParameters.addAll((e as TypeParameterizedElement).typeParameters); |
| 4937 } |
| 4938 e = e.enclosingElement; |
| 4939 } |
| 4940 } |
| 4941 _typeParameters = typeParameters; |
| 4942 |
| 4943 if (typeArguments == null) { |
| 4897 // TODO(jmesserly): reuse TypeParameterTypeImpl.getTypes once we can | 4944 // TODO(jmesserly): reuse TypeParameterTypeImpl.getTypes once we can |
| 4898 // make it generic, which will allow it to return List<DartType> instead | 4945 // make it generic, which will allow it to return List<DartType> instead |
| 4899 // of List<TypeParameterType>. | 4946 // of List<TypeParameterType>. |
| 4900 if (typeParameters.isEmpty) { | 4947 if (typeParameters.isEmpty) { |
| 4901 _typeArguments = DartType.EMPTY_LIST; | 4948 typeArguments = DartType.EMPTY_LIST; |
| 4902 } else { | 4949 } else { |
| 4903 _typeArguments = new List<DartType>.from( | 4950 typeArguments = new List<DartType>.from( |
| 4904 typeParameters.map((t) => t.type), | 4951 typeParameters.map((t) => t.type), |
| 4905 growable: false); | 4952 growable: false); |
| 4906 } | 4953 } |
| 4907 } | 4954 } |
| 4955 _typeArguments = typeArguments; |
| 4908 } | 4956 } |
| 4909 | 4957 |
| 4910 /** | 4958 /** |
| 4911 * Return the base parameter elements of this function element. | 4959 * Return the base parameter elements of this function element. |
| 4912 */ | 4960 */ |
| 4913 List<ParameterElement> get baseParameters { | 4961 List<ParameterElement> get baseParameters { |
| 4914 Element element = this.element; | 4962 Element element = this.element; |
| 4915 if (element is ExecutableElement) { | 4963 if (element is ExecutableElement) { |
| 4916 return element.parameters; | 4964 return element.parameters; |
| 4917 } else { | 4965 } else { |
| 4918 return (element as FunctionTypeAliasElement).parameters; | 4966 return (element as FunctionTypeAliasElement).parameters; |
| 4919 } | 4967 } |
| 4920 } | 4968 } |
| 4921 | 4969 |
| 4922 /** | 4970 /** |
| 4923 * Return the return type defined by this function's element. | 4971 * Return the return type defined by this function's element. |
| 4924 */ | 4972 */ |
| 4925 DartType get baseReturnType { | 4973 DartType get baseReturnType { |
| 4926 Element element = this.element; | 4974 Element element = this.element; |
| 4927 if (element is ExecutableElement) { | 4975 if (element is ExecutableElement) { |
| 4928 return element.returnType; | 4976 return element.returnType; |
| 4929 } else { | 4977 } else { |
| 4930 return (element as FunctionTypeAliasElement).returnType; | 4978 return (element as FunctionTypeAliasElement).returnType; |
| 4931 } | 4979 } |
| 4932 } | 4980 } |
| 4933 | 4981 |
| 4934 @override | 4982 @override |
| 4983 List<TypeParameterElement> get boundTypeParameters => _boundTypeParameters; |
| 4984 |
| 4985 @override |
| 4935 String get displayName { | 4986 String get displayName { |
| 4936 String name = this.name; | 4987 String name = this.name; |
| 4937 if (name == null || name.length == 0) { | 4988 if (name == null || name.length == 0) { |
| 4938 // Function types have an empty name when they are defined implicitly by | 4989 // Function types have an empty name when they are defined implicitly by |
| 4939 // either a closure or as part of a parameter declaration. | 4990 // either a closure or as part of a parameter declaration. |
| 4940 List<DartType> normalParameterTypes = this.normalParameterTypes; | 4991 List<DartType> normalParameterTypes = this.normalParameterTypes; |
| 4941 List<DartType> optionalParameterTypes = this.optionalParameterTypes; | 4992 List<DartType> optionalParameterTypes = this.optionalParameterTypes; |
| 4942 Map<String, DartType> namedParameterTypes = this.namedParameterTypes; | 4993 Map<String, DartType> namedParameterTypes = this.namedParameterTypes; |
| 4943 DartType returnType = this.returnType; | 4994 DartType returnType = this.returnType; |
| 4944 StringBuffer buffer = new StringBuffer(); | 4995 StringBuffer buffer = new StringBuffer(); |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5156 return (baseReturnType as TypeImpl).substitute2(typeArguments, | 5207 return (baseReturnType as TypeImpl).substitute2(typeArguments, |
| 5157 TypeParameterTypeImpl.getTypes(typeParameters), newPrune); | 5208 TypeParameterTypeImpl.getTypes(typeParameters), newPrune); |
| 5158 } | 5209 } |
| 5159 | 5210 |
| 5160 /** | 5211 /** |
| 5161 * A list containing the actual types of the type arguments. | 5212 * A list containing the actual types of the type arguments. |
| 5162 */ | 5213 */ |
| 5163 List<DartType> get typeArguments => _typeArguments; | 5214 List<DartType> get typeArguments => _typeArguments; |
| 5164 | 5215 |
| 5165 @override | 5216 @override |
| 5166 List<TypeParameterElement> get typeParameters { | 5217 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 | 5218 |
| 5179 @override | 5219 @override |
| 5180 bool operator ==(Object object) { | 5220 bool operator ==(Object object) { |
| 5181 if (object is! FunctionTypeImpl) { | 5221 if (object is! FunctionTypeImpl) { |
| 5182 return false; | 5222 return false; |
| 5183 } | 5223 } |
| 5184 FunctionTypeImpl otherType = object as FunctionTypeImpl; | 5224 FunctionTypeImpl otherType = object as FunctionTypeImpl; |
| 5225 if (boundTypeParameters.length != otherType.boundTypeParameters.length) { |
| 5226 return false; |
| 5227 } |
| 5228 // `<T>T -> T` should be equal to `<U>U -> U` |
| 5229 // To test this, we instantiate both types with the same (unique) type |
| 5230 // variables, and see if the result is equal. |
| 5231 if (boundTypeParameters.isNotEmpty) { |
| 5232 List<DartType> instantiateTypeArgs = new List<DartType>(); |
| 5233 for (TypeParameterElement e in boundTypeParameters) { |
| 5234 instantiateTypeArgs.add(new TypeParameterTypeImpl( |
| 5235 new TypeParameterElementImpl(e.name, -1))); |
| 5236 } |
| 5237 // After instantiation, they will no longer have boundTypeParameters, |
| 5238 // so we will continue below. |
| 5239 return this.instantiate(instantiateTypeArgs) == |
| 5240 otherType.instantiate(instantiateTypeArgs); |
| 5241 } |
| 5242 |
| 5185 return returnType == otherType.returnType && | 5243 return returnType == otherType.returnType && |
| 5186 TypeImpl.equalArrays( | 5244 TypeImpl.equalArrays( |
| 5187 normalParameterTypes, otherType.normalParameterTypes) && | 5245 normalParameterTypes, otherType.normalParameterTypes) && |
| 5188 TypeImpl.equalArrays( | 5246 TypeImpl.equalArrays( |
| 5189 optionalParameterTypes, otherType.optionalParameterTypes) && | 5247 optionalParameterTypes, otherType.optionalParameterTypes) && |
| 5190 _equals(namedParameterTypes, otherType.namedParameterTypes); | 5248 _equals(namedParameterTypes, otherType.namedParameterTypes); |
| 5191 } | 5249 } |
| 5192 | 5250 |
| 5193 @override | 5251 @override |
| 5194 void appendTo(StringBuffer buffer) { | 5252 void appendTo(StringBuffer buffer) { |
| 5253 if (boundTypeParameters.isNotEmpty) { |
| 5254 // To print a type with type variables, first make sure we have unique |
| 5255 // variable names to print. |
| 5256 Set<TypeParameterType> freeVariables = new HashSet<TypeParameterType>(); |
| 5257 _freeVariablesInFunctionType(this, freeVariables); |
| 5258 |
| 5259 Set<String> namesToAvoid = new HashSet<String>(); |
| 5260 for (DartType arg in freeVariables) { |
| 5261 if (arg is TypeParameterType) { |
| 5262 namesToAvoid.add(arg.displayName); |
| 5263 } |
| 5264 } |
| 5265 |
| 5266 List<DartType> instantiateTypeArgs = new List<DartType>(); |
| 5267 buffer.write("<"); |
| 5268 for (TypeParameterElement e in boundTypeParameters) { |
| 5269 if (e != boundTypeParameters[0]) { |
| 5270 buffer.write(","); |
| 5271 } |
| 5272 String name = e.name; |
| 5273 int counter = 0; |
| 5274 while (!namesToAvoid.add(name)) { |
| 5275 // Unicode subscript-zero is U+2080, zero is U+0030. Other digits |
| 5276 // are sequential from there. Thus +0x2050 will get us the subscript. |
| 5277 String subscript = new String.fromCharCodes( |
| 5278 counter.toString().codeUnits.map((n) => n + 0x2050)); |
| 5279 |
| 5280 name = e.name + subscript; |
| 5281 counter++; |
| 5282 } |
| 5283 TypeParameterTypeImpl t = |
| 5284 new TypeParameterTypeImpl(new TypeParameterElementImpl(name, -1)); |
| 5285 t.appendTo(buffer); |
| 5286 instantiateTypeArgs.add(t); |
| 5287 } |
| 5288 buffer.write(">"); |
| 5289 |
| 5290 // Instantiate it and print the resulting type. After instantiation, it |
| 5291 // will no longer have boundTypeParameters, so we will continue below. |
| 5292 this.instantiate(instantiateTypeArgs).appendTo(buffer); |
| 5293 return; |
| 5294 } |
| 5295 |
| 5195 List<DartType> normalParameterTypes = this.normalParameterTypes; | 5296 List<DartType> normalParameterTypes = this.normalParameterTypes; |
| 5196 List<DartType> optionalParameterTypes = this.optionalParameterTypes; | 5297 List<DartType> optionalParameterTypes = this.optionalParameterTypes; |
| 5197 Map<String, DartType> namedParameterTypes = this.namedParameterTypes; | 5298 Map<String, DartType> namedParameterTypes = this.namedParameterTypes; |
| 5198 DartType returnType = this.returnType; | 5299 DartType returnType = this.returnType; |
| 5199 buffer.write("("); | 5300 buffer.write("("); |
| 5200 bool needsComma = false; | 5301 bool needsComma = false; |
| 5201 if (normalParameterTypes.length > 0) { | 5302 if (normalParameterTypes.isNotEmpty) { |
| 5202 for (DartType type in normalParameterTypes) { | 5303 for (DartType type in normalParameterTypes) { |
| 5203 if (needsComma) { | 5304 if (needsComma) { |
| 5204 buffer.write(", "); | 5305 buffer.write(", "); |
| 5205 } else { | 5306 } else { |
| 5206 needsComma = true; | 5307 needsComma = true; |
| 5207 } | 5308 } |
| 5208 (type as TypeImpl).appendTo(buffer); | 5309 (type as TypeImpl).appendTo(buffer); |
| 5209 } | 5310 } |
| 5210 } | 5311 } |
| 5211 if (optionalParameterTypes.length > 0) { | 5312 if (optionalParameterTypes.isNotEmpty) { |
| 5212 if (needsComma) { | 5313 if (needsComma) { |
| 5213 buffer.write(", "); | 5314 buffer.write(", "); |
| 5214 needsComma = false; | 5315 needsComma = false; |
| 5215 } | 5316 } |
| 5216 buffer.write("["); | 5317 buffer.write("["); |
| 5217 for (DartType type in optionalParameterTypes) { | 5318 for (DartType type in optionalParameterTypes) { |
| 5218 if (needsComma) { | 5319 if (needsComma) { |
| 5219 buffer.write(", "); | 5320 buffer.write(", "); |
| 5220 } else { | 5321 } else { |
| 5221 needsComma = true; | 5322 needsComma = true; |
| 5222 } | 5323 } |
| 5223 (type as TypeImpl).appendTo(buffer); | 5324 (type as TypeImpl).appendTo(buffer); |
| 5224 } | 5325 } |
| 5225 buffer.write("]"); | 5326 buffer.write("]"); |
| 5226 needsComma = true; | 5327 needsComma = true; |
| 5227 } | 5328 } |
| 5228 if (namedParameterTypes.length > 0) { | 5329 if (namedParameterTypes.isNotEmpty) { |
| 5229 if (needsComma) { | 5330 if (needsComma) { |
| 5230 buffer.write(", "); | 5331 buffer.write(", "); |
| 5231 needsComma = false; | 5332 needsComma = false; |
| 5232 } | 5333 } |
| 5233 buffer.write("{"); | 5334 buffer.write("{"); |
| 5234 namedParameterTypes.forEach((String name, DartType type) { | 5335 namedParameterTypes.forEach((String name, DartType type) { |
| 5235 if (needsComma) { | 5336 if (needsComma) { |
| 5236 buffer.write(", "); | 5337 buffer.write(", "); |
| 5237 } else { | 5338 } else { |
| 5238 needsComma = true; | 5339 needsComma = true; |
| 5239 } | 5340 } |
| 5240 buffer.write(name); | 5341 buffer.write(name); |
| 5241 buffer.write(": "); | 5342 buffer.write(": "); |
| 5242 (type as TypeImpl).appendTo(buffer); | 5343 (type as TypeImpl).appendTo(buffer); |
| 5243 }); | 5344 }); |
| 5244 buffer.write("}"); | 5345 buffer.write("}"); |
| 5245 needsComma = true; | 5346 needsComma = true; |
| 5246 } | 5347 } |
| 5247 buffer.write(")"); | 5348 buffer.write(")"); |
| 5248 buffer.write(Element.RIGHT_ARROW); | 5349 buffer.write(Element.RIGHT_ARROW); |
| 5249 if (returnType == null) { | 5350 if (returnType == null) { |
| 5250 buffer.write("null"); | 5351 buffer.write("null"); |
| 5251 } else { | 5352 } else { |
| 5252 (returnType as TypeImpl).appendTo(buffer); | 5353 (returnType as TypeImpl).appendTo(buffer); |
| 5253 } | 5354 } |
| 5254 } | 5355 } |
| 5255 | 5356 |
| 5256 @override | 5357 @override |
| 5358 FunctionTypeImpl instantiate(List<DartType> argumentTypes) { |
| 5359 if (argumentTypes.length != boundTypeParameters.length) { |
| 5360 throw new IllegalArgumentException( |
| 5361 "argumentTypes.length (${argumentTypes.length}) != " |
| 5362 "boundTypeParameters.length (${boundTypeParameters.length})"); |
| 5363 } |
| 5364 if (argumentTypes.isEmpty) { |
| 5365 return this; |
| 5366 } |
| 5367 |
| 5368 // Given: |
| 5369 // {U/T} <S> T -> S |
| 5370 // Where {U/T} represents the typeArguments (U) and typeParameters (T) list, |
| 5371 // and <S> represents the boundTypeParameters. |
| 5372 // |
| 5373 // Now instantiate([V]), and the result should be: |
| 5374 // {U/T, V/S} T -> S. |
| 5375 List<TypeParameterElement> newTypeParams = typeParameters.toList(); |
| 5376 List<DartType> newTypeArgs = typeArguments.toList(); |
| 5377 newTypeParams.addAll(boundTypeParameters); |
| 5378 newTypeArgs.addAll(argumentTypes); |
| 5379 |
| 5380 return new FunctionTypeImpl._(element, name, prunedTypedefs, newTypeArgs, |
| 5381 newTypeParams, TypeParameterElement.EMPTY_LIST); |
| 5382 } |
| 5383 |
| 5384 @override |
| 5257 bool isAssignableTo(DartType type) { | 5385 bool isAssignableTo(DartType type) { |
| 5258 // A function type T may be assigned to a function type S, written T <=> S, | 5386 // A function type T may be assigned to a function type S, written T <=> S, |
| 5259 // iff T <: S. | 5387 // iff T <: S. |
| 5260 return isSubtypeOf(type); | 5388 return isSubtypeOf(type); |
| 5261 } | 5389 } |
| 5262 | 5390 |
| 5263 @override | 5391 @override |
| 5264 bool isMoreSpecificThan(DartType type, | 5392 bool isMoreSpecificThan(DartType type, |
| 5265 [bool withDynamic = false, Set<Element> visitedElements]) { | 5393 [bool withDynamic = false, Set<Element> visitedElements]) { |
| 5266 // Note: visitedElements is only used for breaking recursion in the type | 5394 // 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(); | 5623 return new CircularTypeImpl(); |
| 5496 } else { | 5624 } else { |
| 5497 // There should never be a reason to prune a type that has already been | 5625 // 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 | 5626 // pruned, since pruning is only done when expanding a function type |
| 5499 // alias, and function type aliases are always expanded by starting with | 5627 // alias, and function type aliases are always expanded by starting with |
| 5500 // base types. | 5628 // base types. |
| 5501 assert(this.prunedTypedefs == null); | 5629 assert(this.prunedTypedefs == null); |
| 5502 List<DartType> typeArgs = typeArguments | 5630 List<DartType> typeArgs = typeArguments |
| 5503 .map((TypeImpl t) => t.pruned(prune)) | 5631 .map((TypeImpl t) => t.pruned(prune)) |
| 5504 .toList(growable: false); | 5632 .toList(growable: false); |
| 5505 return new FunctionTypeImpl._(element, name, prune, typeArgs); | 5633 return new FunctionTypeImpl._(element, name, prune, typeArgs, |
| 5634 _typeParameters, _boundTypeParameters); |
| 5506 } | 5635 } |
| 5507 } | 5636 } |
| 5508 | 5637 |
| 5509 @override | 5638 @override |
| 5510 DartType substitute2( | 5639 DartType substitute2( |
| 5511 List<DartType> argumentTypes, List<DartType> parameterTypes, | 5640 List<DartType> argumentTypes, List<DartType> parameterTypes, |
| 5512 [List<FunctionTypeAliasElement> prune]) { | 5641 [List<FunctionTypeAliasElement> prune]) { |
| 5513 // Pruned types should only ever result from performing type variable | 5642 // Pruned types should only ever result from performing type variable |
| 5514 // substitution, and it doesn't make sense to substitute again after | 5643 // substitution, and it doesn't make sense to substitute again after |
| 5515 // substituting once. | 5644 // substituting once. |
| 5516 assert(this.prunedTypedefs == null); | 5645 assert(this.prunedTypedefs == null); |
| 5517 if (argumentTypes.length != parameterTypes.length) { | 5646 if (argumentTypes.length != parameterTypes.length) { |
| 5518 throw new IllegalArgumentException( | 5647 throw new IllegalArgumentException( |
| 5519 "argumentTypes.length (${argumentTypes.length}) != parameterTypes.leng
th (${parameterTypes.length})"); | 5648 "argumentTypes.length (${argumentTypes.length}) != parameterTypes.leng
th (${parameterTypes.length})"); |
| 5520 } | 5649 } |
| 5521 Element element = this.element; | 5650 Element element = this.element; |
| 5522 if (prune != null && prune.contains(element)) { | 5651 if (prune != null && prune.contains(element)) { |
| 5523 // Circularity found. Prune the type declaration. | 5652 // Circularity found. Prune the type declaration. |
| 5524 return new CircularTypeImpl(); | 5653 return new CircularTypeImpl(); |
| 5525 } | 5654 } |
| 5526 if (argumentTypes.length == 0) { | 5655 if (argumentTypes.length == 0) { |
| 5527 return this.pruned(prune); | 5656 return this.pruned(prune); |
| 5528 } | 5657 } |
| 5529 List<DartType> typeArgs = | 5658 List<DartType> typeArgs = |
| 5530 TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes); | 5659 TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes); |
| 5531 return new FunctionTypeImpl._(element, name, prune, typeArgs); | 5660 return new FunctionTypeImpl._( |
| 5661 element, name, prune, typeArgs, _typeParameters, _boundTypeParameters); |
| 5532 } | 5662 } |
| 5533 | 5663 |
| 5534 @override | 5664 @override |
| 5535 FunctionTypeImpl substitute3(List<DartType> argumentTypes) => | 5665 FunctionTypeImpl substitute3(List<DartType> argumentTypes) => |
| 5536 substitute2(argumentTypes, typeArguments); | 5666 substitute2(argumentTypes, typeArguments); |
| 5537 | 5667 |
| 5668 void _freeVariablesInFunctionType( |
| 5669 FunctionType type, Set<TypeParameterType> free) { |
| 5670 // Make some fresh variables to avoid capture. |
| 5671 List<DartType> typeArgs = DartType.EMPTY_LIST; |
| 5672 if (type.boundTypeParameters.isNotEmpty) { |
| 5673 typeArgs = new List<DartType>.from(type.boundTypeParameters.map((e) => |
| 5674 new TypeParameterTypeImpl(new TypeParameterElementImpl(e.name, -1)))); |
| 5675 |
| 5676 type = type.instantiate(typeArgs); |
| 5677 } |
| 5678 |
| 5679 for (ParameterElement p in type.parameters) { |
| 5680 _freeVariablesInType(p.type, free); |
| 5681 } |
| 5682 _freeVariablesInType(type.returnType, free); |
| 5683 |
| 5684 // Remove all of our bound variables. |
| 5685 free.removeAll(typeArgs); |
| 5686 } |
| 5687 |
| 5688 void _freeVariablesInInterfaceType( |
| 5689 InterfaceType type, Set<TypeParameterType> free) { |
| 5690 for (DartType typeArg in type.typeArguments) { |
| 5691 _freeVariablesInType(typeArg, free); |
| 5692 } |
| 5693 } |
| 5694 |
| 5695 void _freeVariablesInType(DartType type, Set<TypeParameterType> free) { |
| 5696 if (type is TypeParameterType) { |
| 5697 free.add(type); |
| 5698 } else if (type is FunctionType) { |
| 5699 _freeVariablesInFunctionType(type, free); |
| 5700 } else if (type is InterfaceType) { |
| 5701 _freeVariablesInInterfaceType(type, free); |
| 5702 } |
| 5703 } |
| 5704 |
| 5538 /** | 5705 /** |
| 5539 * Compute the least upper bound of types [f] and [g], both of which are | 5706 * Compute the least upper bound of types [f] and [g], both of which are |
| 5540 * known to be function types. | 5707 * known to be function types. |
| 5541 * | 5708 * |
| 5542 * In the event that f and g have different numbers of required parameters, | 5709 * In the event that f and g have different numbers of required parameters, |
| 5543 * `null` is returned, in which case the least upper bound is the interface | 5710 * `null` is returned, in which case the least upper bound is the interface |
| 5544 * type `Function`. | 5711 * type `Function`. |
| 5545 */ | 5712 */ |
| 5546 static FunctionType computeLeastUpperBound(FunctionType f, FunctionType g) { | 5713 static FunctionType computeLeastUpperBound(FunctionType f, FunctionType g) { |
| 5547 // TODO(paulberry): implement this. | 5714 // TODO(paulberry): implement this. |
| (...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6349 * to <i>L</i>. Otherwise, we say that the lookup has failed. | 6516 * to <i>L</i>. Otherwise, we say that the lookup has failed. |
| 6350 * </blockquote> | 6517 * </blockquote> |
| 6351 */ | 6518 */ |
| 6352 PropertyAccessorElement lookUpSetterInSuperclass( | 6519 PropertyAccessorElement lookUpSetterInSuperclass( |
| 6353 String name, LibraryElement library); | 6520 String name, LibraryElement library); |
| 6354 | 6521 |
| 6355 @override | 6522 @override |
| 6356 InterfaceType substitute2( | 6523 InterfaceType substitute2( |
| 6357 List<DartType> argumentTypes, List<DartType> parameterTypes); | 6524 List<DartType> argumentTypes, List<DartType> parameterTypes); |
| 6358 | 6525 |
| 6526 // TODO(jmesserly): introduce a new "instantiate" and deprecate this. |
| 6527 // The new "instantiate" should work similar to FunctionType.instantiate, |
| 6528 // which uses [boundTypeParameters] to model type parameters that haven't been |
| 6529 // filled in yet. Those are kept separate from already-substituted type |
| 6530 // parameters or free variables from the enclosing scopes, which allows nested |
| 6531 // generics to work, such as a generic method in a generic class. |
| 6359 /** | 6532 /** |
| 6360 * Return the type resulting from substituting the given arguments for this | 6533 * Return the type resulting from substituting the given arguments for this |
| 6361 * type's parameters. This is fully equivalent to `substitute2(argumentTypes, | 6534 * type's parameters. This is fully equivalent to `substitute2(argumentTypes, |
| 6362 * getTypeArguments())`. | 6535 * getTypeArguments())`. |
| 6363 */ | 6536 */ |
| 6364 InterfaceType substitute4(List<DartType> argumentTypes); | 6537 InterfaceType substitute4(List<DartType> argumentTypes); |
| 6365 | 6538 |
| 6366 /** | 6539 /** |
| 6367 * Returns a "smart" version of the "least upper bound" of the given types. | 6540 * Returns a "smart" version of the "least upper bound" of the given types. |
| 6368 * | 6541 * |
| (...skipping 4779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11148 | 11321 |
| 11149 @override | 11322 @override |
| 11150 void visitElement(Element element) { | 11323 void visitElement(Element element) { |
| 11151 int offset = element.nameOffset; | 11324 int offset = element.nameOffset; |
| 11152 if (offset != -1) { | 11325 if (offset != -1) { |
| 11153 map[offset] = element; | 11326 map[offset] = element; |
| 11154 } | 11327 } |
| 11155 super.visitElement(element); | 11328 super.visitElement(element); |
| 11156 } | 11329 } |
| 11157 } | 11330 } |
| OLD | NEW |