| 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 |