OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library compiler.src.inferrer.type_graph_nodes; | 5 library compiler.src.inferrer.type_graph_nodes; |
6 | 6 |
7 import 'dart:collection' show IterableBase; | 7 import 'dart:collection' show IterableBase; |
8 | 8 |
9 import '../common.dart'; | 9 import '../common.dart'; |
10 import '../common/names.dart' show Identifiers; | 10 import '../common/names.dart' show Identifiers; |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 int other = assignments[replacement]; | 303 int other = assignments[replacement]; |
304 if (other != null) existing += other; | 304 if (other != null) existing += other; |
305 assignments[replacement] = existing; | 305 assignments[replacement] = existing; |
306 assignments.remove(old); | 306 assignments.remove(old); |
307 } | 307 } |
308 } | 308 } |
309 | 309 |
310 Iterator<TypeInformation> get iterator => assignments.keys.iterator; | 310 Iterator<TypeInformation> get iterator => assignments.keys.iterator; |
311 Iterable<TypeInformation> where(Function f) => assignments.keys.where(f); | 311 Iterable<TypeInformation> where(Function f) => assignments.keys.where(f); |
312 | 312 |
313 bool contains(TypeInformation info) => assignments.containsKey(info); | 313 bool contains(Object info) => assignments.containsKey(info); |
314 | 314 |
315 String toString() => assignments.keys.toList().toString(); | 315 String toString() => assignments.keys.toList().toString(); |
316 } | 316 } |
317 | 317 |
318 /** | 318 /** |
319 * A node representing a resolved element of the program. The kind of | 319 * A node representing a resolved element of the program. The kind of |
320 * elements that need an [ElementTypeInformation] are: | 320 * elements that need an [ElementTypeInformation] are: |
321 * | 321 * |
322 * - Functions (including getters and setters) | 322 * - Functions (including getters and setters) |
323 * - Constructors (factory or generative) | 323 * - Constructors (factory or generative) |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 * The global information is summarized in [cleanup], after which [_callers] | 401 * The global information is summarized in [cleanup], after which [_callers] |
402 * is set to `null`. | 402 * is set to `null`. |
403 */ | 403 */ |
404 Map<Element, Setlet<Spannable>> _callers; | 404 Map<Element, Setlet<Spannable>> _callers; |
405 | 405 |
406 MemberTypeInformation._internal(Element element) | 406 MemberTypeInformation._internal(Element element) |
407 : super._internal(null, element); | 407 : super._internal(null, element); |
408 | 408 |
409 void addCall(Element caller, Spannable node) { | 409 void addCall(Element caller, Spannable node) { |
410 assert(node is ast.Node || node is Element); | 410 assert(node is ast.Node || node is Element); |
411 _callers ??= <Element, Setlet>{}; | 411 _callers ??= <Element, Setlet<Spannable>>{}; |
412 _callers.putIfAbsent(caller, () => new Setlet()).add(node); | 412 _callers.putIfAbsent(caller, () => new Setlet()).add(node); |
413 } | 413 } |
414 | 414 |
415 void removeCall(Element caller, node) { | 415 void removeCall(Element caller, node) { |
416 if (_callers == null) return; | 416 if (_callers == null) return; |
417 Setlet calls = _callers[caller]; | 417 Setlet calls = _callers[caller]; |
418 if (calls == null) return; | 418 if (calls == null) return; |
419 calls.remove(node); | 419 calls.remove(node); |
420 if (calls.isEmpty) { | 420 if (calls.isEmpty) { |
421 _callers.remove(caller); | 421 _callers.remove(caller); |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 for (MemberElement element in targets) { | 830 for (MemberElement element in targets) { |
831 MemberTypeInformation callee = inferrer.types.getInferredTypeOf(element); | 831 MemberTypeInformation callee = inferrer.types.getInferredTypeOf(element); |
832 callee.addCall(caller, call); | 832 callee.addCall(caller, call); |
833 callee.addUser(this); | 833 callee.addUser(this); |
834 inferrer.updateParameterAssignments( | 834 inferrer.updateParameterAssignments( |
835 this, element, arguments, selector, typeMask, | 835 this, element, arguments, selector, typeMask, |
836 remove: false, addToQueue: false); | 836 remove: false, addToQueue: false); |
837 } | 837 } |
838 } | 838 } |
839 | 839 |
840 Iterable<Element> get callees => | 840 Iterable<Element> get callees => targets.map((_e) { |
841 targets.map((MemberElement e) => e.implementation); | 841 MemberElement e = _e; |
| 842 return e.implementation; |
| 843 }); |
842 | 844 |
843 TypeMask computeTypedSelector(InferrerEngine inferrer) { | 845 TypeMask computeTypedSelector(InferrerEngine inferrer) { |
844 TypeMask receiverType = receiver.type; | 846 TypeMask receiverType = receiver.type; |
845 | 847 |
846 if (mask != receiverType) { | 848 if (mask != receiverType) { |
847 return receiverType == inferrer.commonMasks.dynamicType | 849 return receiverType == inferrer.commonMasks.dynamicType |
848 ? null | 850 ? null |
849 : receiverType; | 851 : receiverType; |
850 } else { | 852 } else { |
851 return mask; | 853 return mask; |
852 } | 854 } |
853 } | 855 } |
854 | 856 |
855 bool targetsIncludeComplexNoSuchMethod(InferrerEngine inferrer) { | 857 bool targetsIncludeComplexNoSuchMethod(InferrerEngine inferrer) { |
856 return targets.any((MemberElement e) { | 858 return targets.any((_e) { |
| 859 MemberElement e = _e; |
857 return e is MethodElement && | 860 return e is MethodElement && |
858 e.isInstanceMember && | 861 e.isInstanceMember && |
859 e.name == Identifiers.noSuchMethod_ && | 862 e.name == Identifiers.noSuchMethod_ && |
860 inferrer.backend.noSuchMethodRegistry.isComplex(e); | 863 inferrer.backend.noSuchMethodRegistry.isComplex(e); |
861 }); | 864 }); |
862 } | 865 } |
863 | 866 |
864 /** | 867 /** |
865 * We optimize certain operations on the [int] class because we know more | 868 * We optimize certain operations on the [int] class because we know more |
866 * about their return type than the actual Dart code. For example, we know int | 869 * about their return type than the actual Dart code. For example, we know int |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 callee.removeCall(caller, call); | 1018 callee.removeCall(caller, call); |
1016 callee.removeUser(this); | 1019 callee.removeUser(this); |
1017 inferrer.updateParameterAssignments( | 1020 inferrer.updateParameterAssignments( |
1018 this, element, arguments, selector, typeMask, | 1021 this, element, arguments, selector, typeMask, |
1019 remove: true, addToQueue: true); | 1022 remove: true, addToQueue: true); |
1020 }); | 1023 }); |
1021 } | 1024 } |
1022 | 1025 |
1023 // Walk over the found targets, and compute the joined union type mask | 1026 // Walk over the found targets, and compute the joined union type mask |
1024 // for all these targets. | 1027 // for all these targets. |
1025 TypeMask result = | 1028 TypeMask result = inferrer.types.joinTypeMasks(targets.map((_element) { |
1026 inferrer.types.joinTypeMasks(targets.map((MemberElement element) { | 1029 MemberElement element = _element; |
1027 // If [canReachAll] is true, then we are iterating over all | 1030 // If [canReachAll] is true, then we are iterating over all |
1028 // targets that satisfy the untyped selector. We skip the return | 1031 // targets that satisfy the untyped selector. We skip the return |
1029 // type of the targets that can only be reached through | 1032 // type of the targets that can only be reached through |
1030 // `Invocation.delegate`. Note that the `noSuchMethod` targets | 1033 // `Invocation.delegate`. Note that the `noSuchMethod` targets |
1031 // are included in [typedTargets]. | 1034 // are included in [typedTargets]. |
1032 if (canReachAll && !typedTargets.contains(element)) { | 1035 if (canReachAll && !typedTargets.contains(element)) { |
1033 return const TypeMask.nonNullEmpty(); | 1036 return const TypeMask.nonNullEmpty(); |
1034 } | 1037 } |
1035 if (inferrer.returnsListElementType(selector, typeMask)) { | 1038 if (inferrer.returnsListElementType(selector, typeMask)) { |
1036 ContainerTypeMask containerTypeMask = receiver.type; | 1039 ContainerTypeMask containerTypeMask = receiver.type; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 } | 1114 } |
1112 | 1115 |
1113 String toString() => 'Call site $call on ${receiver.type} $type'; | 1116 String toString() => 'Call site $call on ${receiver.type} $type'; |
1114 | 1117 |
1115 accept(TypeInformationVisitor visitor) { | 1118 accept(TypeInformationVisitor visitor) { |
1116 return visitor.visitDynamicCallSiteTypeInformation(this); | 1119 return visitor.visitDynamicCallSiteTypeInformation(this); |
1117 } | 1120 } |
1118 | 1121 |
1119 bool hasStableType(InferrerEngine inferrer) { | 1122 bool hasStableType(InferrerEngine inferrer) { |
1120 return receiver.isStable && | 1123 return receiver.isStable && |
1121 targets.every((MemberElement element) => | 1124 targets.every((_element) { |
1122 inferrer.types.getInferredTypeOf(element).isStable) && | 1125 MemberElement element = _element; |
| 1126 return inferrer.types.getInferredTypeOf(element).isStable; |
| 1127 }) && |
1123 (arguments == null || arguments.every((info) => info.isStable)) && | 1128 (arguments == null || arguments.every((info) => info.isStable)) && |
1124 super.hasStableType(inferrer); | 1129 super.hasStableType(inferrer); |
1125 } | 1130 } |
1126 } | 1131 } |
1127 | 1132 |
1128 class ClosureCallSiteTypeInformation extends CallSiteTypeInformation { | 1133 class ClosureCallSiteTypeInformation extends CallSiteTypeInformation { |
1129 final TypeInformation closure; | 1134 final TypeInformation closure; |
1130 | 1135 |
1131 ClosureCallSiteTypeInformation( | 1136 ClosureCallSiteTypeInformation( |
1132 MemberTypeInformation context, | 1137 MemberTypeInformation context, |
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1758 // TODO(ngeoffray): Narrow to bound. | 1763 // TODO(ngeoffray): Narrow to bound. |
1759 return type; | 1764 return type; |
1760 } else { | 1765 } else { |
1761 ResolutionInterfaceType interfaceType = annotation; | 1766 ResolutionInterfaceType interfaceType = annotation; |
1762 otherType = new TypeMask.nonNullSubtype(interfaceType.element, closedWorld); | 1767 otherType = new TypeMask.nonNullSubtype(interfaceType.element, closedWorld); |
1763 } | 1768 } |
1764 if (isNullable) otherType = otherType.nullable(); | 1769 if (isNullable) otherType = otherType.nullable(); |
1765 if (type == null) return otherType; | 1770 if (type == null) return otherType; |
1766 return type.intersection(otherType, closedWorld); | 1771 return type.intersection(otherType, closedWorld); |
1767 } | 1772 } |
OLD | NEW |