| 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.resolution.compute_members; | 5 library dart2js.resolution.compute_members; |
| 6 | 6 |
| 7 import '../common/names.dart' show |
| 8 Identifiers; |
| 7 import '../compiler.dart' show | 9 import '../compiler.dart' show |
| 8 Compiler, | 10 Compiler, |
| 9 isPrivateName; | 11 isPrivateName; |
| 10 import '../dart_types.dart'; | 12 import '../dart_types.dart'; |
| 11 import '../diagnostics/invariant.dart' show | 13 import '../diagnostics/invariant.dart' show |
| 12 invariant; | 14 invariant; |
| 13 import '../diagnostics/messages.dart' show | 15 import '../diagnostics/messages.dart' show |
| 14 MessageKind; | 16 MessageKind; |
| 15 import '../elements/elements.dart' show | 17 import '../elements/elements.dart' show |
| 16 ClassElement, | 18 ClassElement, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 } | 55 } |
| 54 } | 56 } |
| 55 | 57 |
| 56 bool shouldSkipMember(MemberSignature member) { | 58 bool shouldSkipMember(MemberSignature member) { |
| 57 return member == null || shouldSkipName(member.name.text); | 59 return member == null || shouldSkipName(member.name.text); |
| 58 | 60 |
| 59 } | 61 } |
| 60 | 62 |
| 61 bool shouldSkipName(String name) { | 63 bool shouldSkipName(String name) { |
| 62 return computedMemberNames != null && | 64 return computedMemberNames != null && |
| 63 computedMemberNames.contains(name); | 65 // 'call' is implicitly contained in [computedMemberNames]. |
| 66 (name == Identifiers.call || computedMemberNames.contains(name)); |
| 64 } | 67 } |
| 65 | 68 |
| 66 /// Compute all members of [cls] with the given names. | 69 /// Compute all members of [cls] with the given names. |
| 67 void computeMembersByName(String name, Setlet<Name> names) { | 70 void computeMembersByName(String name, Setlet<Name> names) { |
| 68 computeMembers(name, names); | 71 computeMembers(name, names); |
| 69 } | 72 } |
| 70 | 73 |
| 71 /// Compute all members of [cls] and checked that [cls] implements its | 74 /// Compute all members of [cls] and checked that [cls] implements its |
| 72 /// interface unless it is abstract or declares a `noSuchMethod` method. | 75 /// interface unless it is abstract or declares a `noSuchMethod` method. |
| 73 void computeAllMembers() { | 76 void computeAllMembers() { |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 // TODO(johnniwinther): If [cls] is not abstract, check that for all | 302 // TODO(johnniwinther): If [cls] is not abstract, check that for all |
| 300 // interface members, there is a class member whose type is a subtype of | 303 // interface members, there is a class member whose type is a subtype of |
| 301 // the interface member. | 304 // the interface member. |
| 302 } | 305 } |
| 303 | 306 |
| 304 /// Checks that [cls], if it implements Function, has defined call(). | 307 /// Checks that [cls], if it implements Function, has defined call(). |
| 305 void checkImplementsFunctionWithCall() { | 308 void checkImplementsFunctionWithCall() { |
| 306 assert(!cls.isAbstract); | 309 assert(!cls.isAbstract); |
| 307 | 310 |
| 308 if (cls.asInstanceOf(compiler.functionClass) == null) return; | 311 if (cls.asInstanceOf(compiler.functionClass) == null) return; |
| 309 if (cls.lookupMember(Compiler.CALL_OPERATOR_NAME) != null) return; | 312 if (cls.lookupMember(Identifiers.call) != null) return; |
| 310 // TODO(johnniwinther): Make separate methods for backend exceptions. | 313 // TODO(johnniwinther): Make separate methods for backend exceptions. |
| 311 // Avoid warnings on backend implementation classes for closures. | 314 // Avoid warnings on backend implementation classes for closures. |
| 312 if (compiler.backend.isBackendLibrary(cls.library)) return; | 315 if (compiler.backend.isBackendLibrary(cls.library)) return; |
| 313 | 316 |
| 314 reportMessage(compiler.functionClass, MessageKind.UNIMPLEMENTED_METHOD, () { | 317 reportMessage(compiler.functionClass, MessageKind.UNIMPLEMENTED_METHOD, () { |
| 315 compiler.reportWarning(cls, MessageKind.UNIMPLEMENTED_METHOD_ONE, | 318 compiler.reportWarning(cls, MessageKind.UNIMPLEMENTED_METHOD_ONE, |
| 316 {'class': cls.name, | 319 {'class': cls.name, |
| 317 'name': Compiler.CALL_OPERATOR_NAME, | 320 'name': Identifiers.call, |
| 318 'method': Compiler.CALL_OPERATOR_NAME, | 321 'method': Identifiers.call, |
| 319 'declarer': compiler.functionClass.name}); | 322 'declarer': compiler.functionClass.name}); |
| 320 }); | 323 }); |
| 321 } | 324 } |
| 322 | 325 |
| 323 /// Checks that a class member exists for every interface member. | 326 /// Checks that a class member exists for every interface member. |
| 324 void checkInterfaceImplementation(); | 327 void checkInterfaceImplementation(); |
| 325 | 328 |
| 326 /// Check that [declared] is a valid override of [superMember]. | 329 /// Check that [declared] is a valid override of [superMember]. |
| 327 void checkValidOverride(Member declared, MemberSignature superMember) { | 330 void checkValidOverride(Member declared, MemberSignature superMember) { |
| 328 if (superMember == null) { | 331 if (superMember == null) { |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 if (isMemberComputed(name)) return; | 841 if (isMemberComputed(name)) return; |
| 839 if (isPrivateName(name)) { | 842 if (isPrivateName(name)) { |
| 840 names..add(new Name(name, library)) | 843 names..add(new Name(name, library)) |
| 841 ..add(new Name(name, library, isSetter: true)); | 844 ..add(new Name(name, library, isSetter: true)); |
| 842 } | 845 } |
| 843 MembersCreator creator = _prepareCreator(compiler); | 846 MembersCreator creator = _prepareCreator(compiler); |
| 844 creator.computeMembersByName(name, names); | 847 creator.computeMembersByName(name, names); |
| 845 if (computedMemberNames == null) { | 848 if (computedMemberNames == null) { |
| 846 computedMemberNames = _EMPTY_MEMBERS_NAMES; | 849 computedMemberNames = _EMPTY_MEMBERS_NAMES; |
| 847 } | 850 } |
| 848 if (name != Compiler.CALL_OPERATOR_NAME) { | 851 if (name != Identifiers.call) { |
| 849 Setlet<String> set; | 852 Setlet<String> set; |
| 850 if (identical(computedMemberNames, _EMPTY_MEMBERS_NAMES)) { | 853 if (identical(computedMemberNames, _EMPTY_MEMBERS_NAMES)) { |
| 851 computedMemberNames = set = new Setlet<String>(); | 854 computedMemberNames = set = new Setlet<String>(); |
| 852 } else { | 855 } else { |
| 853 set = computedMemberNames; | 856 set = computedMemberNames; |
| 854 } | 857 } |
| 855 set.add(name); | 858 set.add(name); |
| 856 } | 859 } |
| 857 } | 860 } |
| 858 | 861 |
| 859 void computeAllClassMembers(Compiler compiler) { | 862 void computeAllClassMembers(Compiler compiler) { |
| 860 if (areAllMembersComputed()) return; | 863 if (areAllMembersComputed()) return; |
| 861 MembersCreator creator = _prepareCreator(compiler); | 864 MembersCreator creator = _prepareCreator(compiler); |
| 862 creator.computeAllMembers(); | 865 creator.computeAllMembers(); |
| 863 computedMemberNames = null; | 866 computedMemberNames = null; |
| 864 assert(invariant(this, areAllMembersComputed())); | 867 assert(invariant(this, areAllMembersComputed())); |
| 865 } | 868 } |
| 866 | 869 |
| 867 bool areAllMembersComputed() { | 870 bool areAllMembersComputed() { |
| 868 return computedMemberNames == null && classMembers != null; | 871 return computedMemberNames == null && classMembers != null; |
| 869 } | 872 } |
| 870 | 873 |
| 871 bool isMemberComputed(String name) { | 874 bool isMemberComputed(String name) { |
| 872 if (computedMemberNames == null) { | 875 if (computedMemberNames == null) { |
| 873 return classMembers != null; | 876 return classMembers != null; |
| 874 } else { | 877 } else { |
| 875 return name == Compiler.CALL_OPERATOR_NAME || | 878 return name == Identifiers.call || |
| 876 computedMemberNames.contains(name); | 879 computedMemberNames.contains(name); |
| 877 } | 880 } |
| 878 } | 881 } |
| 879 | 882 |
| 880 Member lookupClassMember(Name name) { | 883 Member lookupClassMember(Name name) { |
| 881 assert(invariant(this, | 884 assert(invariant(this, |
| 882 isMemberComputed(name.text), | 885 isMemberComputed(name.text), |
| 883 message: "Member ${name} has not been computed for $this.")); | 886 message: "Member ${name} has not been computed for $this.")); |
| 884 return classMembers[name]; | 887 return classMembers[name]; |
| 885 } | 888 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 906 message: "Members have not been fully computed for $this.")); | 909 message: "Members have not been fully computed for $this.")); |
| 907 if (interfaceMembersAreClassMembers) { | 910 if (interfaceMembersAreClassMembers) { |
| 908 classMembers.forEach((_, member) { | 911 classMembers.forEach((_, member) { |
| 909 if (!member.isStatic) f(member); | 912 if (!member.isStatic) f(member); |
| 910 }); | 913 }); |
| 911 } else { | 914 } else { |
| 912 interfaceMembers.forEach((_, member) => f(member)); | 915 interfaceMembers.forEach((_, member) => f(member)); |
| 913 } | 916 } |
| 914 } | 917 } |
| 915 } | 918 } |
| OLD | NEW |