| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 dart2js.typechecker; | 5 library dart2js.typechecker; |
| 6 | 6 |
| 7 import 'common/tasks.dart' show | 7 import 'common/tasks.dart' show |
| 8 CompilerTask; | 8 CompilerTask; |
| 9 import 'compiler.dart' show | 9 import 'compiler.dart' show |
| 10 Compiler; | 10 Compiler; |
| (...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 ElementAccess lookupMember(Node node, DartType receiverType, String name, | 734 ElementAccess lookupMember(Node node, DartType receiverType, String name, |
| 735 MemberKind memberKind, Element receiverElement, | 735 MemberKind memberKind, Element receiverElement, |
| 736 {bool lookupClassMember: false}) { | 736 {bool lookupClassMember: false}) { |
| 737 if (receiverType.treatAsDynamic) { | 737 if (receiverType.treatAsDynamic) { |
| 738 return const DynamicAccess(); | 738 return const DynamicAccess(); |
| 739 } | 739 } |
| 740 | 740 |
| 741 Name memberName = new Name(name, currentLibrary, | 741 Name memberName = new Name(name, currentLibrary, |
| 742 isSetter: memberKind == MemberKind.SETTER); | 742 isSetter: memberKind == MemberKind.SETTER); |
| 743 | 743 |
| 744 // Compute the unaliased type of the first non type variable bound of | |
| 745 // [type]. | |
| 746 DartType computeUnaliasedBound(DartType type) { | |
| 747 DartType originalType = type; | |
| 748 while (identical(type.kind, TypeKind.TYPE_VARIABLE)) { | |
| 749 TypeVariableType variable = type; | |
| 750 type = variable.element.bound; | |
| 751 if (type == originalType) { | |
| 752 type = compiler.objectClass.rawType; | |
| 753 } | |
| 754 } | |
| 755 if (type.isMalformed) { | |
| 756 return const DynamicType(); | |
| 757 } | |
| 758 return type.unalias(compiler); | |
| 759 } | |
| 760 | |
| 761 // Compute the interface type of [type]. For type variable it is the | |
| 762 // interface type of the bound, for function types and typedefs it is the | |
| 763 // `Function` type. | |
| 764 InterfaceType computeInterfaceType(DartType type) { | |
| 765 if (type.isFunctionType) { | |
| 766 type = compiler.functionClass.rawType; | |
| 767 } | |
| 768 assert(invariant(node, type.isInterfaceType, | |
| 769 message: "unexpected type kind ${type.kind}.")); | |
| 770 return type; | |
| 771 } | |
| 772 | |
| 773 // Lookup the class or interface member [name] in [interface]. | 744 // Lookup the class or interface member [name] in [interface]. |
| 774 MemberSignature lookupMemberSignature(Name name, InterfaceType interface) { | 745 MemberSignature lookupMemberSignature(Name name, InterfaceType interface) { |
| 775 MembersCreator.computeClassMembersByName( | 746 MembersCreator.computeClassMembersByName( |
| 776 compiler, interface.element, name.text); | 747 compiler, interface.element, name.text); |
| 777 return lookupClassMember || analyzingInitializer | 748 return lookupClassMember || analyzingInitializer |
| 778 ? interface.lookupClassMember(name) | 749 ? interface.lookupClassMember(name) |
| 779 : interface.lookupInterfaceMember(name); | 750 : interface.lookupInterfaceMember(name); |
| 780 } | 751 } |
| 781 | 752 |
| 782 // Compute the access of [name] on [type]. This function takes the special | 753 // Compute the access of [name] on [type]. This function takes the special |
| (...skipping 12 matching lines...) Expand all Loading... |
| 795 if (types.isSubtype(interface, compiler.functionClass.rawType)) { | 766 if (types.isSubtype(interface, compiler.functionClass.rawType)) { |
| 796 // This is an access of the special 'call' method implicitly defined | 767 // This is an access of the special 'call' method implicitly defined |
| 797 // on 'Function'. This method can be called with any arguments, which | 768 // on 'Function'. This method can be called with any arguments, which |
| 798 // we ensure by giving it the type 'dynamic'. | 769 // we ensure by giving it the type 'dynamic'. |
| 799 return new FunctionCallAccess(null, const DynamicType()); | 770 return new FunctionCallAccess(null, const DynamicType()); |
| 800 } | 771 } |
| 801 } | 772 } |
| 802 return null; | 773 return null; |
| 803 } | 774 } |
| 804 | 775 |
| 805 DartType unaliasedBound = computeUnaliasedBound(receiverType); | 776 DartType unaliasedBound = |
| 777 Types.computeUnaliasedBound(compiler, receiverType); |
| 806 if (unaliasedBound.treatAsDynamic) { | 778 if (unaliasedBound.treatAsDynamic) { |
| 807 return new DynamicAccess(); | 779 return new DynamicAccess(); |
| 808 } | 780 } |
| 809 InterfaceType interface = computeInterfaceType(unaliasedBound); | 781 InterfaceType interface = |
| 782 Types.computeInterfaceType(compiler, unaliasedBound); |
| 810 ElementAccess access = getAccess(memberName, unaliasedBound, interface); | 783 ElementAccess access = getAccess(memberName, unaliasedBound, interface); |
| 811 if (access != null) { | 784 if (access != null) { |
| 812 return access; | 785 return access; |
| 813 } | 786 } |
| 814 if (receiverElement != null && | 787 if (receiverElement != null && |
| 815 (receiverElement.isVariable || receiverElement.isParameter)) { | 788 (receiverElement.isVariable || receiverElement.isParameter)) { |
| 816 Link<TypePromotion> typePromotions = typePromotionsMap[receiverElement]; | 789 Link<TypePromotion> typePromotions = typePromotionsMap[receiverElement]; |
| 817 if (typePromotions != null) { | 790 if (typePromotions != null) { |
| 818 while (!typePromotions.isEmpty) { | 791 while (!typePromotions.isEmpty) { |
| 819 TypePromotion typePromotion = typePromotions.head; | 792 TypePromotion typePromotion = typePromotions.head; |
| 820 if (!typePromotion.isValid) { | 793 if (!typePromotion.isValid) { |
| 821 DartType unaliasedBound = computeUnaliasedBound(typePromotion.type); | 794 DartType unaliasedBound = |
| 795 Types.computeUnaliasedBound(compiler, typePromotion.type); |
| 822 if (!unaliasedBound.treatAsDynamic) { | 796 if (!unaliasedBound.treatAsDynamic) { |
| 823 InterfaceType interface = computeInterfaceType(unaliasedBound); | 797 InterfaceType interface = |
| 798 Types.computeInterfaceType(compiler, unaliasedBound); |
| 824 if (getAccess(memberName, unaliasedBound, interface) != null) { | 799 if (getAccess(memberName, unaliasedBound, interface) != null) { |
| 825 reportTypePromotionHint(typePromotion); | 800 reportTypePromotionHint(typePromotion); |
| 826 } | 801 } |
| 827 } | 802 } |
| 828 } | 803 } |
| 829 typePromotions = typePromotions.tail; | 804 typePromotions = typePromotions.tail; |
| 830 } | 805 } |
| 831 } | 806 } |
| 832 } | 807 } |
| 833 // We didn't find a member with the correct name. If this lookup is for a | 808 // We didn't find a member with the correct name. If this lookup is for a |
| (...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1926 | 1901 |
| 1927 visitTypedef(Typedef node) { | 1902 visitTypedef(Typedef node) { |
| 1928 // Do not typecheck [Typedef] nodes. | 1903 // Do not typecheck [Typedef] nodes. |
| 1929 } | 1904 } |
| 1930 | 1905 |
| 1931 visitNode(Node node) { | 1906 visitNode(Node node) { |
| 1932 compiler.internalError(node, | 1907 compiler.internalError(node, |
| 1933 'Unexpected node ${node.getObjectDescription()} in the type checker.'); | 1908 'Unexpected node ${node.getObjectDescription()} in the type checker.'); |
| 1934 } | 1909 } |
| 1935 } | 1910 } |
| OLD | NEW |