| 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 |