| 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/resolution_types.dart' |
| 9 show ResolutionDartType, ResolutionInterfaceType; | 9 show ResolutionDartType, ResolutionInterfaceType; |
| 10 import '../tree/nodes.dart' as ast; | 10 import '../tree/nodes.dart' as ast; |
| 11 import '../types/masks.dart'; | 11 import '../types/masks.dart'; |
| 12 import '../universe/selector.dart'; | 12 import '../universe/selector.dart'; |
| 13 import '../world.dart'; | 13 import '../world.dart'; |
| 14 import 'type_graph_nodes.dart'; | 14 import 'type_graph_nodes.dart'; |
| 15 | 15 |
| 16 /** | 16 /** |
| 17 * The class [SimpleInferrerVisitor] will use when working on types. | 17 * The class [SimpleInferrerVisitor] will use when working on types. |
| 18 */ | 18 */ |
| 19 class TypeSystem { | 19 class TypeSystem { |
| 20 final ClosedWorld closedWorld; | 20 final ClosedWorld closedWorld; |
| 21 | 21 |
| 22 /// [ElementTypeInformation]s for elements. | 22 /// [parameterTypeInformations] and [memberTypeInformations] ordered by |
| 23 final Map<Element, TypeInformation> typeInformations = | 23 /// creation time. This is used as the inference enqueueing order. |
| 24 new Map<Element, TypeInformation>(); | 24 final List<TypeInformation> _orderedTypeInformations = <TypeInformation>[]; |
| 25 |
| 26 /// [ParameterTypeInformation]s for parameters. |
| 27 final Map<ParameterElement, TypeInformation> parameterTypeInformations = |
| 28 new Map<ParameterElement, TypeInformation>(); |
| 29 |
| 30 /// [MemberTypeInformation]s for members. |
| 31 final Map<MemberElement, TypeInformation> memberTypeInformations = |
| 32 new Map<MemberElement, TypeInformation>(); |
| 25 | 33 |
| 26 /// [ListTypeInformation] for allocated lists. | 34 /// [ListTypeInformation] for allocated lists. |
| 27 final Map<ast.Node, TypeInformation> allocatedLists = | 35 final Map<ast.Node, TypeInformation> allocatedLists = |
| 28 new Map<ast.Node, TypeInformation>(); | 36 new Map<ast.Node, TypeInformation>(); |
| 29 | 37 |
| 30 /// [MapTypeInformation] for allocated Maps. | 38 /// [MapTypeInformation] for allocated Maps. |
| 31 final Map<ast.Node, TypeInformation> allocatedMaps = | 39 final Map<ast.Node, TypeInformation> allocatedMaps = |
| 32 new Map<ast.Node, TypeInformation>(); | 40 new Map<ast.Node, TypeInformation>(); |
| 33 | 41 |
| 34 /// Closures found during the analysis. | 42 /// Closures found during the analysis. |
| 35 final Set<TypeInformation> allocatedClosures = new Set<TypeInformation>(); | 43 final Set<TypeInformation> allocatedClosures = new Set<TypeInformation>(); |
| 36 | 44 |
| 37 /// Cache of [ConcreteTypeInformation]. | 45 /// Cache of [ConcreteTypeInformation]. |
| 38 final Map<TypeMask, TypeInformation> concreteTypes = | 46 final Map<TypeMask, TypeInformation> concreteTypes = |
| 39 new Map<TypeMask, TypeInformation>(); | 47 new Map<TypeMask, TypeInformation>(); |
| 40 | 48 |
| 41 /// List of [TypeInformation]s for calls inside method bodies. | 49 /// List of [TypeInformation]s for calls inside method bodies. |
| 42 final List<CallSiteTypeInformation> allocatedCalls = | 50 final List<CallSiteTypeInformation> allocatedCalls = |
| 43 <CallSiteTypeInformation>[]; | 51 <CallSiteTypeInformation>[]; |
| 44 | 52 |
| 45 /// List of [TypeInformation]s allocated inside method bodies (narrowing, | 53 /// List of [TypeInformation]s allocated inside method bodies (narrowing, |
| 46 /// phis, and containers). | 54 /// phis, and containers). |
| 47 final List<TypeInformation> allocatedTypes = <TypeInformation>[]; | 55 final List<TypeInformation> allocatedTypes = <TypeInformation>[]; |
| 48 | 56 |
| 57 /// [parameterTypeInformations] and [memberTypeInformations] ordered by |
| 58 /// creation time. This is used as the inference enqueueing order. |
| 59 Iterable<TypeInformation> get orderedTypeInformations => |
| 60 _orderedTypeInformations; |
| 61 |
| 49 Iterable<TypeInformation> get allTypes => [ | 62 Iterable<TypeInformation> get allTypes => [ |
| 50 typeInformations.values, | 63 parameterTypeInformations.values, |
| 64 memberTypeInformations.values, |
| 51 allocatedLists.values, | 65 allocatedLists.values, |
| 52 allocatedMaps.values, | 66 allocatedMaps.values, |
| 53 allocatedClosures, | 67 allocatedClosures, |
| 54 concreteTypes.values, | 68 concreteTypes.values, |
| 55 allocatedCalls, | 69 allocatedCalls, |
| 56 allocatedTypes | 70 allocatedTypes |
| 57 ].expand((x) => x); | 71 ].expand((x) => x); |
| 58 | 72 |
| 59 TypeSystem(this.closedWorld) { | 73 TypeSystem(this.closedWorld) { |
| 60 nonNullEmptyType = getConcreteTypeFor(commonMasks.emptyType); | 74 nonNullEmptyType = getConcreteTypeFor(commonMasks.emptyType); |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 TypeInformation narrowNotNull(TypeInformation type) { | 329 TypeInformation narrowNotNull(TypeInformation type) { |
| 316 if (type.type.isExact && !type.type.isNullable) { | 330 if (type.type.isExact && !type.type.isNullable) { |
| 317 return type; | 331 return type; |
| 318 } | 332 } |
| 319 TypeInformation newType = | 333 TypeInformation newType = |
| 320 new NarrowTypeInformation(type, dynamicType.type.nonNullable()); | 334 new NarrowTypeInformation(type, dynamicType.type.nonNullable()); |
| 321 allocatedTypes.add(newType); | 335 allocatedTypes.add(newType); |
| 322 return newType; | 336 return newType; |
| 323 } | 337 } |
| 324 | 338 |
| 325 ElementTypeInformation getInferredTypeOfParameter(ParameterElement element) { | 339 ParameterTypeInformation getInferredTypeOfParameter( |
| 326 return _getInferredTypeOf(element); | 340 ParameterElement parameter) { |
| 341 parameter = parameter.implementation; |
| 342 |
| 343 ParameterTypeInformation createTypeInformation() { |
| 344 if (parameter.functionDeclaration.isLocal) { |
| 345 LocalFunctionElement localFunction = parameter.functionDeclaration; |
| 346 MethodElement callMethod = localFunction.callMethod; |
| 347 return new ParameterTypeInformation.localFunction( |
| 348 getInferredTypeOfMember(callMethod), |
| 349 parameter, |
| 350 localFunction, |
| 351 callMethod); |
| 352 } else if (parameter.functionDeclaration.isInstanceMember) { |
| 353 MethodElement method = parameter.functionDeclaration; |
| 354 return new ParameterTypeInformation.instanceMember( |
| 355 getInferredTypeOfMember(method), |
| 356 parameter, |
| 357 method, |
| 358 new ParameterAssignments()); |
| 359 } else { |
| 360 MethodElement method = parameter.functionDeclaration; |
| 361 return new ParameterTypeInformation.static( |
| 362 getInferredTypeOfMember(method), parameter, method); |
| 363 } |
| 364 } |
| 365 |
| 366 return parameterTypeInformations.putIfAbsent(parameter, () { |
| 367 ParameterTypeInformation typeInformation = createTypeInformation(); |
| 368 _orderedTypeInformations.add(typeInformation); |
| 369 return typeInformation; |
| 370 }); |
| 327 } | 371 } |
| 328 | 372 |
| 329 ElementTypeInformation getInferredTypeOfMember(MemberElement element) { | 373 MemberTypeInformation getInferredTypeOfMember(MemberElement member) { |
| 330 return _getInferredTypeOf(element); | 374 member = member.implementation; |
| 331 } | 375 return memberTypeInformations.putIfAbsent(member, () { |
| 332 | 376 MemberTypeInformation typeInformation = new MemberTypeInformation(member); |
| 333 @deprecated | 377 _orderedTypeInformations.add(typeInformation); |
| 334 ElementTypeInformation _getInferredTypeOf(Element element) { | 378 return typeInformation; |
| 335 element = element.implementation; | 379 }); |
| 336 assert(element.isParameter || element is MemberElement); | |
| 337 return typeInformations[element] ??= | |
| 338 new ElementTypeInformation(element, this); | |
| 339 } | 380 } |
| 340 | 381 |
| 341 /** | 382 /** |
| 342 * Returns the internal inferrer representation for [mask]. | 383 * Returns the internal inferrer representation for [mask]. |
| 343 */ | 384 */ |
| 344 ConcreteTypeInformation getConcreteTypeFor(TypeMask mask) { | 385 ConcreteTypeInformation getConcreteTypeFor(TypeMask mask) { |
| 345 assert(mask != null); | 386 assert(mask != null); |
| 346 return concreteTypes.putIfAbsent(mask, () { | 387 return concreteTypes.putIfAbsent(mask, () { |
| 347 return new ConcreteTypeInformation(mask); | 388 return new ConcreteTypeInformation(mask); |
| 348 }); | 389 }); |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 TypeMask newType = null; | 605 TypeMask newType = null; |
| 565 for (TypeMask mask in list) { | 606 for (TypeMask mask in list) { |
| 566 newType = newType == null ? mask : newType.union(mask, closedWorld); | 607 newType = newType == null ? mask : newType.union(mask, closedWorld); |
| 567 // Likewise - stop early if we already reach dynamic. | 608 // Likewise - stop early if we already reach dynamic. |
| 568 if (newType.containsAll(closedWorld)) return dynamicType; | 609 if (newType.containsAll(closedWorld)) return dynamicType; |
| 569 } | 610 } |
| 570 | 611 |
| 571 return newType ?? const TypeMask.nonNullEmpty(); | 612 return newType ?? const TypeMask.nonNullEmpty(); |
| 572 } | 613 } |
| 573 } | 614 } |
| OLD | NEW |