OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 part of types; | 5 part of types; |
6 | 6 |
7 class CancelTypeInferenceException { | 7 class CancelTypeInferenceException { |
8 final Node node; | 8 final Node node; |
9 final String reason; | 9 final String reason; |
10 | 10 |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 UnionType otherUnion = other; // cast | 164 UnionType otherUnion = other; // cast |
165 Set<BaseType> newBaseTypes = new Set<BaseType>.from(baseTypes); | 165 Set<BaseType> newBaseTypes = new Set<BaseType>.from(baseTypes); |
166 newBaseTypes.addAll(otherUnion.baseTypes); | 166 newBaseTypes.addAll(otherUnion.baseTypes); |
167 return newBaseTypes.length > maxConcreteTypeSize | 167 return newBaseTypes.length > maxConcreteTypeSize |
168 ? const UnknownConcreteType() | 168 ? const UnknownConcreteType() |
169 : new UnionType(newBaseTypes); | 169 : new UnionType(newBaseTypes); |
170 } | 170 } |
171 | 171 |
172 ClassElement getUniqueType() { | 172 ClassElement getUniqueType() { |
173 if (baseTypes.length == 1) { | 173 if (baseTypes.length == 1) { |
174 BaseType uniqueBaseType = baseTypes.iterator().next(); | 174 var iterator = baseTypes.iterator; |
| 175 iterator.moveNext(); |
| 176 BaseType uniqueBaseType = iterator.current; |
175 if (uniqueBaseType.isClass()) { | 177 if (uniqueBaseType.isClass()) { |
176 ClassBaseType uniqueClassType = uniqueBaseType; | 178 ClassBaseType uniqueClassType = uniqueBaseType; |
177 return uniqueClassType.element; | 179 return uniqueClassType.element; |
178 } | 180 } |
179 } | 181 } |
180 return null; | 182 return null; |
181 } | 183 } |
182 | 184 |
183 String toString() => baseTypes.toString(); | 185 String toString() => baseTypes.toString(); |
184 } | 186 } |
185 | 187 |
186 /** | 188 /** |
187 * The cartesian product of concrete types: an iterable of [BaseTypeTuple]s. For | 189 * The cartesian product of concrete types: an iterable of [BaseTypeTuple]s. For |
188 * instance, the cartesian product of the concrete types [: {A, B} :] and | 190 * instance, the cartesian product of the concrete types [: {A, B} :] and |
189 * [: {C, D} :] is an itearble whose iterators will yield [: (A, C) :], | 191 * [: {C, D} :] is an itearble whose iterators will yield [: (A, C) :], |
190 * [: (A, D) :], [: (B, C) :] and finally [: (B, D) :]. | 192 * [: (A, D) :], [: (B, C) :] and finally [: (B, D) :]. |
191 */ | 193 */ |
192 class ConcreteTypeCartesianProduct | 194 class ConcreteTypeCartesianProduct |
193 implements Iterable<ConcreteTypesEnvironment> { | 195 extends Iterable<ConcreteTypesEnvironment> { |
194 final ConcreteTypesInferrer inferrer; | 196 final ConcreteTypesInferrer inferrer; |
195 final BaseType baseTypeOfThis; | 197 final BaseType baseTypeOfThis; |
196 final Map<Element, ConcreteType> concreteTypes; | 198 final Map<Element, ConcreteType> concreteTypes; |
197 ConcreteTypeCartesianProduct(this.inferrer, this.baseTypeOfThis, | 199 ConcreteTypeCartesianProduct(this.inferrer, this.baseTypeOfThis, |
198 this.concreteTypes); | 200 this.concreteTypes); |
199 Iterator iterator() => concreteTypes.isEmpty | 201 Iterator get iterator => concreteTypes.isEmpty |
200 ? [new ConcreteTypesEnvironment(inferrer, baseTypeOfThis)].iterator() | 202 ? [new ConcreteTypesEnvironment(inferrer, baseTypeOfThis)].iterator |
201 : new ConcreteTypeCartesianProductIterator(inferrer, baseTypeOfThis, | 203 : new ConcreteTypeCartesianProductIterator(inferrer, baseTypeOfThis, |
202 concreteTypes); | 204 concreteTypes); |
203 String toString() { | 205 String toString() { |
204 List<ConcreteTypesEnvironment> cartesianProduct = | 206 List<ConcreteTypesEnvironment> cartesianProduct = |
205 new List<ConcreteTypesEnvironment>.from(this); | 207 new List<ConcreteTypesEnvironment>.from(this); |
206 return cartesianProduct.toString(); | 208 return cartesianProduct.toString(); |
207 } | 209 } |
208 } | 210 } |
209 | 211 |
210 /** | 212 /** |
211 * An helper class for [ConcreteTypeCartesianProduct]. | 213 * An helper class for [ConcreteTypeCartesianProduct]. |
212 */ | 214 */ |
213 class ConcreteTypeCartesianProductIterator implements Iterator { | 215 class ConcreteTypeCartesianProductIterator |
| 216 implements Iterator<ConcreteTypesEnvironment> { |
214 final ConcreteTypesInferrer inferrer; | 217 final ConcreteTypesInferrer inferrer; |
215 final BaseType baseTypeOfThis; | 218 final BaseType baseTypeOfThis; |
216 final Map<Element, ConcreteType> concreteTypes; | 219 final Map<Element, ConcreteType> concreteTypes; |
217 final Map<Element, BaseType> nextValues; | 220 final Map<Element, BaseType> nextValues; |
218 final Map<Element, Iterator> state; | 221 final Map<Element, Iterator> state; |
219 int size = 1; | 222 int size = 1; |
220 int counter = 0; | 223 int counter = 0; |
| 224 ConcreteTypesEnvironment _current; |
221 | 225 |
222 ConcreteTypeCartesianProductIterator(this.inferrer, this.baseTypeOfThis, | 226 ConcreteTypeCartesianProductIterator(this.inferrer, this.baseTypeOfThis, |
223 Map<Element, ConcreteType> concreteTypes) | 227 Map<Element, ConcreteType> concreteTypes) |
224 : this.concreteTypes = concreteTypes, | 228 : this.concreteTypes = concreteTypes, |
225 nextValues = new Map<Element, BaseType>(), | 229 nextValues = new Map<Element, BaseType>(), |
226 state = new Map<Element, Iterator>() { | 230 state = new Map<Element, Iterator>() { |
227 if (concreteTypes.isEmpty) { | 231 if (concreteTypes.isEmpty) { |
228 size = 0; | 232 size = 0; |
229 return; | 233 return; |
230 } | 234 } |
231 for (final e in concreteTypes.keys) { | 235 for (final e in concreteTypes.keys) { |
232 final baseTypes = concreteTypes[e].baseTypes; | 236 final baseTypes = concreteTypes[e].baseTypes; |
233 size *= baseTypes.length; | 237 size *= baseTypes.length; |
234 } | 238 } |
235 } | 239 } |
236 | 240 |
237 bool get hasNext { | 241 ConcreteTypesEnvironment get current => _current; |
238 return counter < size; | |
239 } | |
240 | 242 |
241 ConcreteTypesEnvironment takeSnapshot() { | 243 ConcreteTypesEnvironment takeSnapshot() { |
242 Map<Element, ConcreteType> result = new Map<Element, ConcreteType>(); | 244 Map<Element, ConcreteType> result = new Map<Element, ConcreteType>(); |
243 nextValues.forEach((k, v) { | 245 nextValues.forEach((k, v) { |
244 result[k] = inferrer.singletonConcreteType(v); | 246 result[k] = inferrer.singletonConcreteType(v); |
245 }); | 247 }); |
246 return new ConcreteTypesEnvironment.of(inferrer, result, baseTypeOfThis); | 248 return new ConcreteTypesEnvironment.of(inferrer, result, baseTypeOfThis); |
247 } | 249 } |
248 | 250 |
249 ConcreteTypesEnvironment next() { | 251 bool moveNext() { |
250 if (!hasNext) throw new StateError("No more elements"); | 252 if (counter >= size) { |
| 253 _current = null; |
| 254 return false; |
| 255 } |
251 Element keyToIncrement = null; | 256 Element keyToIncrement = null; |
252 for (final key in concreteTypes.keys) { | 257 for (final key in concreteTypes.keys) { |
253 final iterator = state[key]; | 258 final iterator = state[key]; |
254 if (iterator != null && iterator.hasNext) { | 259 if (iterator != null && iterator.moveNext()) { |
255 nextValues[key] = state[key].next(); | 260 nextValues[key] = state[key].current; |
256 break; | 261 break; |
257 } | 262 } |
258 Iterator newIterator = concreteTypes[key].baseTypes.iterator(); | 263 Iterator newIterator = concreteTypes[key].baseTypes.iterator; |
259 state[key] = newIterator; | 264 state[key] = newIterator; |
260 nextValues[key] = newIterator.next(); | 265 newIterator.moveNext(); |
| 266 nextValues[key] = newIterator.current; |
261 } | 267 } |
262 counter++; | 268 counter++; |
263 return takeSnapshot(); | 269 _current = takeSnapshot(); |
| 270 return true; |
264 } | 271 } |
265 } | 272 } |
266 | 273 |
267 /** | 274 /** |
268 * [BaseType] Constants. | 275 * [BaseType] Constants. |
269 */ | 276 */ |
270 class BaseTypes { | 277 class BaseTypes { |
271 final BaseType intBaseType; | 278 final BaseType intBaseType; |
272 final BaseType doubleBaseType; | 279 final BaseType doubleBaseType; |
273 final BaseType numBaseType; | 280 final BaseType numBaseType; |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 final Map<Element, ConcreteType> result = new Map<Element, ConcreteType>(); | 676 final Map<Element, ConcreteType> result = new Map<Element, ConcreteType>(); |
670 final FunctionSignature signature = function.computeSignature(compiler); | 677 final FunctionSignature signature = function.computeSignature(compiler); |
671 // too many arguments | 678 // too many arguments |
672 if (argumentsTypes.length > signature.parameterCount) { | 679 if (argumentsTypes.length > signature.parameterCount) { |
673 return null; | 680 return null; |
674 } | 681 } |
675 // not enough arguments | 682 // not enough arguments |
676 if (argumentsTypes.positional.length < signature.requiredParameterCount) { | 683 if (argumentsTypes.positional.length < signature.requiredParameterCount) { |
677 return null; | 684 return null; |
678 } | 685 } |
679 final Iterator<ConcreteType> remainingPositionalArguments = | 686 final HasNextIterator<ConcreteType> remainingPositionalArguments = |
680 argumentsTypes.positional.iterator(); | 687 new HasNextIterator<ConcreteType>(argumentsTypes.positional.iterator); |
681 // we attach each positional parameter to its corresponding positional | 688 // we attach each positional parameter to its corresponding positional |
682 // argument | 689 // argument |
683 for (Link<Element> requiredParameters = signature.requiredParameters; | 690 for (Link<Element> requiredParameters = signature.requiredParameters; |
684 !requiredParameters.isEmpty; | 691 !requiredParameters.isEmpty; |
685 requiredParameters = requiredParameters.tail) { | 692 requiredParameters = requiredParameters.tail) { |
686 final Element requiredParameter = requiredParameters.head; | 693 final Element requiredParameter = requiredParameters.head; |
687 // we know next() is defined because of the guard above | 694 // we know next() is defined because of the guard above |
688 result[requiredParameter] = remainingPositionalArguments.next(); | 695 result[requiredParameter] = remainingPositionalArguments.next(); |
689 } | 696 } |
690 // we attach the remaining positional arguments to their corresponding | 697 // we attach the remaining positional arguments to their corresponding |
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1515 } | 1522 } |
1516 | 1523 |
1517 void internalError(String reason, {Node node}) { | 1524 void internalError(String reason, {Node node}) { |
1518 inferrer.fail(node, reason); | 1525 inferrer.fail(node, reason); |
1519 } | 1526 } |
1520 | 1527 |
1521 ConcreteType visitTypeReferenceSend(Send) { | 1528 ConcreteType visitTypeReferenceSend(Send) { |
1522 return inferrer.singletonConcreteType(inferrer.baseTypes.typeBaseType); | 1529 return inferrer.singletonConcreteType(inferrer.baseTypes.typeBaseType); |
1523 } | 1530 } |
1524 } | 1531 } |
OLD | NEW |