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 |