OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import '../common.dart'; | 5 import '../common.dart'; |
6 import '../elements/elements.dart'; | 6 import '../elements/elements.dart'; |
7 import '../elements/entities.dart'; | 7 import '../elements/entities.dart'; |
8 import '../elements/resolution_types.dart' | 8 import '../elements/types.dart'; |
9 show ResolutionDartType, ResolutionInterfaceType; | |
10 import '../tree/nodes.dart' as ast; | 9 import '../tree/nodes.dart' as ast; |
11 import '../types/masks.dart'; | 10 import '../types/masks.dart'; |
12 import '../universe/selector.dart'; | 11 import '../universe/selector.dart'; |
13 import '../world.dart'; | 12 import '../world.dart'; |
14 import 'type_graph_nodes.dart'; | 13 import 'type_graph_nodes.dart'; |
15 | 14 |
16 /** | 15 /** |
17 * The class [SimpleInferrerVisitor] will use when working on types. | 16 * The class [SimpleInferrerVisitor] will use when working on types. |
18 */ | 17 */ |
19 class TypeSystem { | 18 class TypeSystem { |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 TypeInformation newType = new NarrowTypeInformation(receiver, otherType); | 283 TypeInformation newType = new NarrowTypeInformation(receiver, otherType); |
285 allocatedTypes.add(newType); | 284 allocatedTypes.add(newType); |
286 return newType; | 285 return newType; |
287 } | 286 } |
288 | 287 |
289 /** | 288 /** |
290 * Returns the intersection between [type] and [annotation]. | 289 * Returns the intersection between [type] and [annotation]. |
291 * [isNullable] indicates whether the annotation implies a null | 290 * [isNullable] indicates whether the annotation implies a null |
292 * type. | 291 * type. |
293 */ | 292 */ |
294 TypeInformation narrowType( | 293 TypeInformation narrowType(TypeInformation type, DartType annotation, |
295 TypeInformation type, ResolutionDartType annotation, | |
296 {bool isNullable: true}) { | 294 {bool isNullable: true}) { |
297 if (annotation.treatAsDynamic) return type; | 295 if (annotation.treatAsDynamic) return type; |
298 if (annotation.isVoid) return type; | 296 if (annotation.isVoid) return type; |
299 if (annotation.element == closedWorld.commonElements.objectClass && | |
300 isNullable) { | |
301 return type; | |
302 } | |
303 TypeMask otherType; | 297 TypeMask otherType; |
304 if (annotation.isTypedef || annotation.isFunctionType) { | 298 if (annotation.isInterfaceType) { |
| 299 InterfaceType interface = annotation; |
| 300 if (interface.element == closedWorld.commonElements.objectClass) { |
| 301 if (isNullable) { |
| 302 return type; |
| 303 } |
| 304 otherType = dynamicType.type.nonNullable(); |
| 305 } else { |
| 306 otherType = new TypeMask.nonNullSubtype(interface.element, closedWorld); |
| 307 } |
| 308 } else if (annotation.isTypedef || annotation.isFunctionType) { |
305 otherType = functionType.type; | 309 otherType = functionType.type; |
306 } else if (annotation.isTypeVariable) { | 310 } else { |
| 311 assert(annotation.isTypeVariable); |
307 // TODO(ngeoffray): Narrow to bound. | 312 // TODO(ngeoffray): Narrow to bound. |
308 return type; | 313 return type; |
309 } else { | |
310 ResolutionInterfaceType interface = annotation; | |
311 otherType = annotation.element == closedWorld.commonElements.objectClass | |
312 ? dynamicType.type.nonNullable() | |
313 : new TypeMask.nonNullSubtype(interface.element, closedWorld); | |
314 } | 314 } |
315 if (isNullable) otherType = otherType.nullable(); | 315 if (isNullable) otherType = otherType.nullable(); |
316 if (type.type.isExact) { | 316 if (type.type.isExact) { |
317 return type; | 317 return type; |
318 } else { | 318 } else { |
319 assert(TypeMask.assertIsNormalized(otherType, closedWorld)); | 319 assert(TypeMask.assertIsNormalized(otherType, closedWorld)); |
320 TypeInformation newType = new NarrowTypeInformation(type, otherType); | 320 TypeInformation newType = new NarrowTypeInformation(type, otherType); |
321 allocatedTypes.add(newType); | 321 allocatedTypes.add(newType); |
322 return newType; | 322 return newType; |
323 } | 323 } |
(...skipping 14 matching lines...) Expand all Loading... |
338 | 338 |
339 ParameterTypeInformation getInferredTypeOfParameter( | 339 ParameterTypeInformation getInferredTypeOfParameter( |
340 ParameterElement parameter) { | 340 ParameterElement parameter) { |
341 parameter = parameter.implementation; | 341 parameter = parameter.implementation; |
342 | 342 |
343 ParameterTypeInformation createTypeInformation() { | 343 ParameterTypeInformation createTypeInformation() { |
344 if (parameter.functionDeclaration.isLocal) { | 344 if (parameter.functionDeclaration.isLocal) { |
345 LocalFunctionElement localFunction = parameter.functionDeclaration; | 345 LocalFunctionElement localFunction = parameter.functionDeclaration; |
346 MethodElement callMethod = localFunction.callMethod; | 346 MethodElement callMethod = localFunction.callMethod; |
347 return new ParameterTypeInformation.localFunction( | 347 return new ParameterTypeInformation.localFunction( |
348 getInferredTypeOfMember(callMethod), | 348 getInferredTypeOfMember(callMethod), parameter, callMethod); |
349 parameter, | |
350 localFunction, | |
351 callMethod); | |
352 } else if (parameter.functionDeclaration.isInstanceMember) { | 349 } else if (parameter.functionDeclaration.isInstanceMember) { |
353 MethodElement method = parameter.functionDeclaration; | 350 MethodElement method = parameter.functionDeclaration; |
354 return new ParameterTypeInformation.instanceMember( | 351 return new ParameterTypeInformation.instanceMember( |
355 getInferredTypeOfMember(method), | 352 getInferredTypeOfMember(method), |
356 parameter, | 353 parameter, |
357 method, | 354 method, |
358 new ParameterAssignments()); | 355 new ParameterAssignments()); |
359 } else { | 356 } else { |
360 MethodElement method = parameter.functionDeclaration; | 357 MethodElement method = parameter.functionDeclaration; |
361 return new ParameterTypeInformation.static( | 358 return new ParameterTypeInformation.static( |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 TypeMask newType = null; | 602 TypeMask newType = null; |
606 for (TypeMask mask in list) { | 603 for (TypeMask mask in list) { |
607 newType = newType == null ? mask : newType.union(mask, closedWorld); | 604 newType = newType == null ? mask : newType.union(mask, closedWorld); |
608 // Likewise - stop early if we already reach dynamic. | 605 // Likewise - stop early if we already reach dynamic. |
609 if (newType.containsAll(closedWorld)) return dynamicType; | 606 if (newType.containsAll(closedWorld)) return dynamicType; |
610 } | 607 } |
611 | 608 |
612 return newType ?? const TypeMask.nonNullEmpty(); | 609 return newType ?? const TypeMask.nonNullEmpty(); |
613 } | 610 } |
614 } | 611 } |
OLD | NEW |