Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(545)

Side by Side Diff: pkg/analyzer/lib/src/generated/element.dart

Issue 1488383004: Fixes incorrect generic function type capture (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/resolver.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
4533 * general form <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i>. 4533 * general form <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; 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>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub> 4535 * general form <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>
4536 * &hellip;, T<sub>n+k</sub>]) &rarr; T</i>. 4536 * &hellip;, T<sub>n+k</sub>]) &rarr; 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>, &hellip;, T<sub>n</sub>, {T<sub>x1</sub> x1, &hellip;, 4538 * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>x1</sub> x1, &hellip;,
4539 * T<sub>xk</sub> xk}) &rarr; T</i>. 4539 * T<sub>xk</sub> xk}) &rarr; 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
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>, &hellip;, T<sub>n</sub>) &rarr; T</i> is 4597 * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i> is
4583 * a subtype of the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>) 4598 * a subtype of the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>)
4584 * &rarr; S</i>, if all of the following conditions are met: 4599 * &rarr; 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 &hArr; S</i>. 4603 * * <i>T &hArr; S</i>.
4589 * 4604 *
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/resolver.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698