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

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

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

Powered by Google App Engine
This is Rietveld 408576698