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 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 * A call site is either an AST [ast.Node], an [Element] (see uses of | 386 * A call site is either an AST [ast.Node], an [Element] (see uses of |
387 * [synthesizeForwardingCall] in [SimpleTypeInferrerVisitor]). | 387 * [synthesizeForwardingCall] in [SimpleTypeInferrerVisitor]). |
388 * | 388 * |
389 * The global information is summarized in [cleanup], after which [_callers] | 389 * The global information is summarized in [cleanup], after which [_callers] |
390 * is set to `null`. | 390 * is set to `null`. |
391 */ | 391 */ |
392 Map<MemberEntity, Setlet<Spannable>> _callers; | 392 Map<MemberEntity, Setlet<Spannable>> _callers; |
393 | 393 |
394 MemberTypeInformation._internal(this._member) : super._internal(null); | 394 MemberTypeInformation._internal(this._member) : super._internal(null); |
395 | 395 |
396 MemberElement get member => _member; | 396 MemberEntity get member => _member; |
397 | 397 |
398 String get debugName => '$member'; | 398 String get debugName => '$member'; |
399 | 399 |
400 void addCall(MemberEntity caller, Spannable node) { | 400 void addCall(MemberEntity caller, Spannable node) { |
401 assert(node is ast.Node || node is Element); | 401 assert(node is ast.Node || node is Element); |
402 _callers ??= <MemberEntity, Setlet<Spannable>>{}; | 402 _callers ??= <MemberEntity, Setlet<Spannable>>{}; |
403 _callers.putIfAbsent(caller, () => new Setlet()).add(node); | 403 _callers.putIfAbsent(caller, () => new Setlet()).add(node); |
404 } | 404 } |
405 | 405 |
406 void removeCall(MemberEntity caller, node) { | 406 void removeCall(MemberEntity caller, node) { |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 /** | 669 /** |
670 * A node representing parameters: | 670 * A node representing parameters: |
671 * | 671 * |
672 * - Parameters | 672 * - Parameters |
673 * - Initializing formals | 673 * - Initializing formals |
674 * | 674 * |
675 * These should never be created directly but instead are constructed by | 675 * These should never be created directly but instead are constructed by |
676 * the [ElementTypeInformation] factory. | 676 * the [ElementTypeInformation] factory. |
677 */ | 677 */ |
678 class ParameterTypeInformation extends ElementTypeInformation { | 678 class ParameterTypeInformation extends ElementTypeInformation { |
679 final ParameterElement _parameter; | 679 final Local _parameter; |
680 final MethodElement _method; | 680 final DartType _type; |
681 bool _isInstanceMemberParameter; | 681 final FunctionEntity _method; |
682 bool _isClosureParameter; | 682 final bool _isInstanceMemberParameter; |
| 683 final bool _isClosureParameter; |
| 684 final bool _isInitializingFormal; |
683 bool _isTearOffClosureParameter = false; | 685 bool _isTearOffClosureParameter = false; |
684 | 686 |
685 ParameterTypeInformation.localFunction( | 687 ParameterTypeInformation.localFunction( |
686 MemberTypeInformation context, this._parameter, this._method) | 688 MemberTypeInformation context, this._parameter, this._type, this._method) |
687 : _isInstanceMemberParameter = false, | 689 : _isInstanceMemberParameter = false, |
688 _isClosureParameter = true, | 690 _isClosureParameter = true, |
| 691 _isInitializingFormal = false, |
689 super._internal(context); | 692 super._internal(context); |
690 | 693 |
691 ParameterTypeInformation.static( | 694 ParameterTypeInformation.static( |
692 MemberTypeInformation context, this._parameter, this._method) | 695 MemberTypeInformation context, this._parameter, this._type, this._method, |
| 696 {bool isInitializingFormal: false}) |
693 : _isInstanceMemberParameter = false, | 697 : _isInstanceMemberParameter = false, |
694 _isClosureParameter = false, | 698 _isClosureParameter = false, |
| 699 _isInitializingFormal = isInitializingFormal, |
695 super._internal(context); | 700 super._internal(context); |
696 | 701 |
697 ParameterTypeInformation.instanceMember(MemberTypeInformation context, | 702 ParameterTypeInformation.instanceMember( |
698 this._parameter, this._method, ParameterAssignments assignments) | 703 MemberTypeInformation context, |
| 704 this._parameter, |
| 705 this._type, |
| 706 this._method, |
| 707 ParameterAssignments assignments) |
699 : _isInstanceMemberParameter = true, | 708 : _isInstanceMemberParameter = true, |
700 _isClosureParameter = false, | 709 _isClosureParameter = false, |
| 710 _isInitializingFormal = false, |
701 super._withAssignments(context, assignments); | 711 super._withAssignments(context, assignments); |
702 | 712 |
703 MethodElement get method => _method; | 713 FunctionEntity get method => _method; |
704 | 714 |
705 Local get parameter => _parameter; | 715 Local get parameter => _parameter; |
706 | 716 |
707 String get debugName => '$parameter'; | 717 String get debugName => '$parameter'; |
708 | 718 |
709 void tagAsTearOffClosureParameter(InferrerEngine inferrer) { | 719 void tagAsTearOffClosureParameter(InferrerEngine inferrer) { |
710 assert(_parameter.isRegularParameter); | 720 assert(!_isInitializingFormal); |
711 _isTearOffClosureParameter = true; | 721 _isTearOffClosureParameter = true; |
712 // We have to add a flow-edge for the default value (if it exists), as we | 722 // We have to add a flow-edge for the default value (if it exists), as we |
713 // might not see all call-sites and thus miss the use of it. | 723 // might not see all call-sites and thus miss the use of it. |
714 TypeInformation defaultType = | 724 TypeInformation defaultType = |
715 inferrer.getDefaultTypeOfParameter(_parameter); | 725 inferrer.getDefaultTypeOfParameter(_parameter); |
716 if (defaultType != null) defaultType.addUser(this); | 726 if (defaultType != null) defaultType.addUser(this); |
717 } | 727 } |
718 | 728 |
719 // TODO(herhut): Cleanup into one conditional. | 729 // TODO(herhut): Cleanup into one conditional. |
720 TypeMask handleSpecialCases(InferrerEngine inferrer) { | 730 TypeMask handleSpecialCases(InferrerEngine inferrer) { |
721 if (!inferrer.backend.canFunctionParametersBeUsedForGlobalOptimizations( | 731 if (!inferrer.backend.canFunctionParametersBeUsedForGlobalOptimizations( |
722 _method, inferrer.closedWorld) || | 732 _method, inferrer.closedWorld) || |
723 inferrer.optimizerHints.assumeDynamic(_method)) { | 733 inferrer.optimizerHints.assumeDynamic(_method)) { |
724 // Do not infer types for parameters that have a corresponding annotation | 734 // Do not infer types for parameters that have a corresponding annotation |
725 // or that are assigned by synthesized calls. | 735 // or that are assigned by synthesized calls. |
726 giveUp(inferrer); | 736 giveUp(inferrer); |
727 return safeType(inferrer); | 737 return safeType(inferrer); |
728 } | 738 } |
729 | 739 |
730 // The below do not apply to parameters of constructors, so skip | 740 // The below do not apply to parameters of constructors, so skip |
731 // initializing formals. | 741 // initializing formals. |
732 if (_parameter.isInitializingFormal) return null; | 742 if (_isInitializingFormal) return null; |
733 | 743 |
734 if ((_isTearOffClosureParameter || _isClosureParameter) && | 744 if ((_isTearOffClosureParameter || _isClosureParameter) && |
735 disableInferenceForClosures) { | 745 disableInferenceForClosures) { |
736 // Do not infer types for parameters of closures. We do not | 746 // Do not infer types for parameters of closures. We do not |
737 // clear the assignments in case the closure is successfully | 747 // clear the assignments in case the closure is successfully |
738 // traced. | 748 // traced. |
739 giveUp(inferrer, clearAssignments: false); | 749 giveUp(inferrer, clearAssignments: false); |
740 return safeType(inferrer); | 750 return safeType(inferrer); |
741 } | 751 } |
742 if (_isInstanceMemberParameter && | 752 if (_isInstanceMemberParameter && |
(...skipping 26 matching lines...) Expand all Loading... |
769 TypeMask potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) { | 779 TypeMask potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) { |
770 Compiler compiler = inferrer.compiler; | 780 Compiler compiler = inferrer.compiler; |
771 if (!compiler.options.trustTypeAnnotations && | 781 if (!compiler.options.trustTypeAnnotations && |
772 !inferrer.optimizerHints.trustTypeAnnotations(_method)) { | 782 !inferrer.optimizerHints.trustTypeAnnotations(_method)) { |
773 return mask; | 783 return mask; |
774 } | 784 } |
775 // When type assertions are enabled (aka checked mode), we have to always | 785 // When type assertions are enabled (aka checked mode), we have to always |
776 // ignore type annotations to ensure that the checks are actually inserted | 786 // ignore type annotations to ensure that the checks are actually inserted |
777 // into the function body and retained until runtime. | 787 // into the function body and retained until runtime. |
778 assert(!compiler.options.enableTypeAssertions); | 788 assert(!compiler.options.enableTypeAssertions); |
779 return _narrowType(inferrer.closedWorld, mask, _parameter.type); | 789 return _narrowType(inferrer.closedWorld, mask, _type); |
780 } | 790 } |
781 | 791 |
782 TypeMask computeType(InferrerEngine inferrer) { | 792 TypeMask computeType(InferrerEngine inferrer) { |
783 TypeMask special = handleSpecialCases(inferrer); | 793 TypeMask special = handleSpecialCases(inferrer); |
784 if (special != null) return special; | 794 if (special != null) return special; |
785 return potentiallyNarrowType( | 795 return potentiallyNarrowType( |
786 inferrer.types.computeTypeMask(assignments), inferrer); | 796 inferrer.types.computeTypeMask(assignments), inferrer); |
787 } | 797 } |
788 | 798 |
789 TypeMask safeType(InferrerEngine inferrer) { | 799 TypeMask safeType(InferrerEngine inferrer) { |
(...skipping 1099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1889 // TODO(ngeoffray): Narrow to bound. | 1899 // TODO(ngeoffray): Narrow to bound. |
1890 return type; | 1900 return type; |
1891 } else { | 1901 } else { |
1892 ResolutionInterfaceType interfaceType = annotation; | 1902 ResolutionInterfaceType interfaceType = annotation; |
1893 otherType = new TypeMask.nonNullSubtype(interfaceType.element, closedWorld); | 1903 otherType = new TypeMask.nonNullSubtype(interfaceType.element, closedWorld); |
1894 } | 1904 } |
1895 if (isNullable) otherType = otherType.nullable(); | 1905 if (isNullable) otherType = otherType.nullable(); |
1896 if (type == null) return otherType; | 1906 if (type == null) return otherType; |
1897 return type.intersection(otherType, closedWorld); | 1907 return type.intersection(otherType, closedWorld); |
1898 } | 1908 } |
OLD | NEW |