| 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 resolution.compute_members; | 5 library resolution.compute_members; |
| 6 | 6 |
| 7 import '../elements/elements.dart' | 7 import '../elements/elements.dart' |
| 8 show Element, | 8 show Element, |
| 9 Name, | 9 Name, |
| 10 PublicName, | 10 PublicName, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 | 63 |
| 64 /// Compute all members of [cls] with the given names. | 64 /// Compute all members of [cls] with the given names. |
| 65 void computeMembersByName(String name, Setlet<Name> names) { | 65 void computeMembersByName(String name, Setlet<Name> names) { |
| 66 computeMembers(name, names); | 66 computeMembers(name, names); |
| 67 } | 67 } |
| 68 | 68 |
| 69 /// Compute all members of [cls] and checked that [cls] implements its | 69 /// Compute all members of [cls] and checked that [cls] implements its |
| 70 /// interface unless it is abstract or declares a `noSuchMethod` method. | 70 /// interface unless it is abstract or declares a `noSuchMethod` method. |
| 71 void computeAllMembers() { | 71 void computeAllMembers() { |
| 72 Map<Name, Member> declaredMembers = computeMembers(null, null); | 72 Map<Name, Member> declaredMembers = computeMembers(null, null); |
| 73 if (!cls.modifiers.isAbstract() && | 73 if (!cls.modifiers.isAbstract && |
| 74 !declaredMembers.containsKey(const PublicName('noSuchMethod'))) { | 74 !declaredMembers.containsKey(const PublicName('noSuchMethod'))) { |
| 75 // Check for unimplemented members on concrete classes that neither have | 75 // Check for unimplemented members on concrete classes that neither have |
| 76 // a `@proxy` annotation nor declare a `noSuchMethod` method. | 76 // a `@proxy` annotation nor declare a `noSuchMethod` method. |
| 77 checkInterfaceImplementation(); | 77 checkInterfaceImplementation(); |
| 78 } | 78 } |
| 79 } | 79 } |
| 80 | 80 |
| 81 /// Compute declared and inherited members of [cls] and return a map of the | 81 /// Compute declared and inherited members of [cls] and return a map of the |
| 82 /// declared members. | 82 /// declared members. |
| 83 /// | 83 /// |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 for (Name memberName in names) { | 153 for (Name memberName in names) { |
| 154 inheritMixinMember( | 154 inheritMixinMember( |
| 155 mixinApplication.mixin.lookupClassMember(memberName)); | 155 mixinApplication.mixin.lookupClassMember(memberName)); |
| 156 } | 156 } |
| 157 } else { | 157 } else { |
| 158 computeAllClassMembers(compiler, mixinApplication.mixin); | 158 computeAllClassMembers(compiler, mixinApplication.mixin); |
| 159 mixinApplication.mixin.forEachClassMember(inheritMixinMember); | 159 mixinApplication.mixin.forEachClassMember(inheritMixinMember); |
| 160 } | 160 } |
| 161 } | 161 } |
| 162 } else { | 162 } else { |
| 163 LibraryElement library = cls.getLibrary(); | 163 LibraryElement library = cls.library; |
| 164 InterfaceType thisType = cls.thisType; | 164 InterfaceType thisType = cls.thisType; |
| 165 | 165 |
| 166 void createMember(Element element) { | 166 void createMember(Element element) { |
| 167 if (element.isConstructor()) return; | 167 if (element.isConstructor) return; |
| 168 String elementName = element.name; | 168 String elementName = element.name; |
| 169 if (shouldSkipName(elementName)) return; | 169 if (shouldSkipName(elementName)) return; |
| 170 if (nameText != null && elementName != nameText) return; | 170 if (nameText != null && elementName != nameText) return; |
| 171 | 171 |
| 172 void addDeclaredMember(Name name, | 172 void addDeclaredMember(Name name, |
| 173 DartType type, FunctionType functionType) { | 173 DartType type, FunctionType functionType) { |
| 174 DeclaredMember inherited = classMembers[name]; | 174 DeclaredMember inherited = classMembers[name]; |
| 175 DeclaredMember declared; | 175 DeclaredMember declared; |
| 176 if (element.isAbstract) { | 176 if (element.isAbstract) { |
| 177 declared = new DeclaredAbstractMember( | 177 declared = new DeclaredAbstractMember( |
| 178 name, element, thisType, type, functionType, | 178 name, element, thisType, type, functionType, |
| 179 inherited); | 179 inherited); |
| 180 } else { | 180 } else { |
| 181 declared = | 181 declared = |
| 182 new DeclaredMember(name, element, thisType, type, functionType); | 182 new DeclaredMember(name, element, thisType, type, functionType); |
| 183 } | 183 } |
| 184 declaredMembers[name] = declared; | 184 declaredMembers[name] = declared; |
| 185 classMembers[name] = declared; | 185 classMembers[name] = declared; |
| 186 checkValidOverride(declared, inherited); | 186 checkValidOverride(declared, inherited); |
| 187 } | 187 } |
| 188 | 188 |
| 189 Name name = new Name(element.name, library); | 189 Name name = new Name(element.name, library); |
| 190 if (element.isField()) { | 190 if (element.isField) { |
| 191 DartType type = element.computeType(compiler); | 191 DartType type = element.computeType(compiler); |
| 192 addDeclaredMember(name, type, | 192 addDeclaredMember(name, type, |
| 193 new FunctionType(compiler.functionClass, type)); | 193 new FunctionType(compiler.functionClass, type)); |
| 194 if (!element.modifiers.isConst() && | 194 if (!element.modifiers.isConst && |
| 195 !element.modifiers.isFinal()) { | 195 !element.modifiers.isFinal) { |
| 196 addDeclaredMember(name.setter, type, | 196 addDeclaredMember(name.setter, type, |
| 197 new FunctionType(compiler.functionClass, | 197 new FunctionType(compiler.functionClass, |
| 198 compiler.types.voidType, | 198 compiler.types.voidType, |
| 199 const Link<DartType>().prepend(type))); | 199 const Link<DartType>().prepend(type))); |
| 200 } | 200 } |
| 201 } else if (element.isGetter()) { | 201 } else if (element.isGetter) { |
| 202 FunctionType functionType = element.computeType(compiler); | 202 FunctionType functionType = element.computeType(compiler); |
| 203 DartType type = functionType.returnType; | 203 DartType type = functionType.returnType; |
| 204 addDeclaredMember(name, type, functionType); | 204 addDeclaredMember(name, type, functionType); |
| 205 } else if (element.isSetter()) { | 205 } else if (element.isSetter) { |
| 206 FunctionType functionType = element.computeType(compiler); | 206 FunctionType functionType = element.computeType(compiler); |
| 207 DartType type; | 207 DartType type; |
| 208 if (!functionType.parameterTypes.isEmpty) { | 208 if (!functionType.parameterTypes.isEmpty) { |
| 209 type = functionType.parameterTypes.head; | 209 type = functionType.parameterTypes.head; |
| 210 } else { | 210 } else { |
| 211 type = compiler.types.dynamicType; | 211 type = compiler.types.dynamicType; |
| 212 } | 212 } |
| 213 name = name.setter; | 213 name = name.setter; |
| 214 addDeclaredMember(name, type, functionType); | 214 addDeclaredMember(name, type, functionType); |
| 215 } else { | 215 } else { |
| 216 assert(invariant(element, element.isFunction())); | 216 assert(invariant(element, element.isFunction)); |
| 217 FunctionType type = element.computeType(compiler); | 217 FunctionType type = element.computeType(compiler); |
| 218 addDeclaredMember(name, type, type); | 218 addDeclaredMember(name, type, type); |
| 219 } | 219 } |
| 220 } | 220 } |
| 221 | 221 |
| 222 cls.forEachLocalMember(createMember); | 222 cls.forEachLocalMember(createMember); |
| 223 if (cls.isPatched) { | 223 if (cls.isPatched) { |
| 224 cls.implementation.forEachLocalMember((Element element) { | 224 cls.implementation.forEachLocalMember((Element element) { |
| 225 if (element.isDeclaration) { | 225 if (element.isDeclaration) { |
| 226 createMember(element); | 226 createMember(element); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 } | 434 } |
| 435 | 435 |
| 436 void reportErrorWithContext(Element errorneousElement, | 436 void reportErrorWithContext(Element errorneousElement, |
| 437 MessageKind errorMessage, | 437 MessageKind errorMessage, |
| 438 Element contextElement, | 438 Element contextElement, |
| 439 MessageKind contextMessage) { | 439 MessageKind contextMessage) { |
| 440 compiler.reportError( | 440 compiler.reportError( |
| 441 errorneousElement, | 441 errorneousElement, |
| 442 errorMessage, | 442 errorMessage, |
| 443 {'memberName': contextElement.name, | 443 {'memberName': contextElement.name, |
| 444 'className': contextElement.getEnclosingClass().name}); | 444 'className': contextElement.enclosingClass.name}); |
| 445 compiler.reportInfo(contextElement, contextMessage); | 445 compiler.reportInfo(contextElement, contextMessage); |
| 446 } | 446 } |
| 447 | 447 |
| 448 /// Compute all class and interface names by the [name] in [cls]. | 448 /// Compute all class and interface names by the [name] in [cls]. |
| 449 static void computeClassMembersByName(Compiler compiler, | 449 static void computeClassMembersByName(Compiler compiler, |
| 450 ClassMemberMixin cls, | 450 ClassMemberMixin cls, |
| 451 String name) { | 451 String name) { |
| 452 if (cls.isMemberComputed(name)) return; | 452 if (cls.isMemberComputed(name)) return; |
| 453 LibraryElement library = cls.getLibrary(); | 453 LibraryElement library = cls.library; |
| 454 _computeClassMember(compiler, cls, name, | 454 _computeClassMember(compiler, cls, name, |
| 455 new Setlet<Name>()..add(new Name(name, library)) | 455 new Setlet<Name>()..add(new Name(name, library)) |
| 456 ..add(new Name(name, library, isSetter: true))); | 456 ..add(new Name(name, library, isSetter: true))); |
| 457 } | 457 } |
| 458 | 458 |
| 459 static void _computeClassMember(Compiler compiler, | 459 static void _computeClassMember(Compiler compiler, |
| 460 ClassMemberMixin cls, | 460 ClassMemberMixin cls, |
| 461 String name, | 461 String name, |
| 462 Setlet<Name> names) { | 462 Setlet<Name> names) { |
| 463 cls.computeClassMember(compiler, name, names); | 463 cls.computeClassMember(compiler, name, names); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 481 Map<Name, Member> computeMembers(String name, Setlet<Name> names) { | 481 Map<Name, Member> computeMembers(String name, Setlet<Name> names) { |
| 482 computeSuperMembers(name, names); | 482 computeSuperMembers(name, names); |
| 483 return computeClassMembers(name, names); | 483 return computeClassMembers(name, names); |
| 484 } | 484 } |
| 485 | 485 |
| 486 void computeSuperMembers(String name, Setlet<Name> names) { | 486 void computeSuperMembers(String name, Setlet<Name> names) { |
| 487 computeSuperClassMembers(name, names); | 487 computeSuperClassMembers(name, names); |
| 488 } | 488 } |
| 489 | 489 |
| 490 void checkInterfaceImplementation() { | 490 void checkInterfaceImplementation() { |
| 491 LibraryElement library = cls.getLibrary(); | 491 LibraryElement library = cls.library; |
| 492 classMembers.forEach((Name name, Member classMember) { | 492 classMembers.forEach((Name name, Member classMember) { |
| 493 if (!name.isAccessibleFrom(library)) return; | 493 if (!name.isAccessibleFrom(library)) return; |
| 494 checkInterfaceMember(name, classMember, classMember.implementation); | 494 checkInterfaceMember(name, classMember, classMember.implementation); |
| 495 }); | 495 }); |
| 496 } | 496 } |
| 497 } | 497 } |
| 498 | 498 |
| 499 /// Class Member creator for classes where the interface members might be | 499 /// Class Member creator for classes where the interface members might be |
| 500 /// different from the class members. | 500 /// different from the class members. |
| 501 class InterfaceMembersCreator extends MembersCreator { | 501 class InterfaceMembersCreator extends MembersCreator { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 MembersCreator.computeAllClassMembers(compiler, superinterface.element); | 582 MembersCreator.computeAllClassMembers(compiler, superinterface.element); |
| 583 inheritInterfaceMembers(superinterface); | 583 inheritInterfaceMembers(superinterface); |
| 584 } | 584 } |
| 585 } | 585 } |
| 586 | 586 |
| 587 return inheritedInterfaceMembers; | 587 return inheritedInterfaceMembers; |
| 588 } | 588 } |
| 589 | 589 |
| 590 /// Checks that a class member exists for every interface member. | 590 /// Checks that a class member exists for every interface member. |
| 591 void checkInterfaceImplementation() { | 591 void checkInterfaceImplementation() { |
| 592 LibraryElement library = cls.getLibrary(); | 592 LibraryElement library = cls.library; |
| 593 interfaceMembers.forEach((Name name, MemberSignature interfaceMember) { | 593 interfaceMembers.forEach((Name name, MemberSignature interfaceMember) { |
| 594 if (!name.isAccessibleFrom(library)) return; | 594 if (!name.isAccessibleFrom(library)) return; |
| 595 Member classMember = classMembers[name]; | 595 Member classMember = classMembers[name]; |
| 596 if (classMember != null) classMember = classMember.implementation; | 596 if (classMember != null) classMember = classMember.implementation; |
| 597 checkInterfaceMember(name, interfaceMember, classMember); | 597 checkInterfaceMember(name, interfaceMember, classMember); |
| 598 }); | 598 }); |
| 599 } | 599 } |
| 600 | 600 |
| 601 /// Compute the interface members of [cls] given the set of inherited | 601 /// Compute the interface members of [cls] given the set of inherited |
| 602 /// interface members [inheritedInterfaceMembers] and declared members | 602 /// interface members [inheritedInterfaceMembers] and declared members |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 } | 805 } |
| 806 | 806 |
| 807 static Iterable<String> _EMPTY_MEMBERS_NAMES = const <String>[]; | 807 static Iterable<String> _EMPTY_MEMBERS_NAMES = const <String>[]; |
| 808 | 808 |
| 809 /// Compute the members by the name [name] for this class. [names] collects | 809 /// Compute the members by the name [name] for this class. [names] collects |
| 810 /// the set of possible variations of [name], including getter, setter and | 810 /// the set of possible variations of [name], including getter, setter and |
| 811 /// and private names. | 811 /// and private names. |
| 812 void computeClassMember(Compiler compiler, String name, Setlet<Name> names) { | 812 void computeClassMember(Compiler compiler, String name, Setlet<Name> names) { |
| 813 if (isMemberComputed(name)) return; | 813 if (isMemberComputed(name)) return; |
| 814 if (isPrivateName(name)) { | 814 if (isPrivateName(name)) { |
| 815 LibraryElement library = getLibrary(); | |
| 816 names..add(new Name(name, library)) | 815 names..add(new Name(name, library)) |
| 817 ..add(new Name(name, library, isSetter: true)); | 816 ..add(new Name(name, library, isSetter: true)); |
| 818 } | 817 } |
| 819 MembersCreator creator = _prepareCreator(compiler); | 818 MembersCreator creator = _prepareCreator(compiler); |
| 820 creator.computeMembersByName(name, names); | 819 creator.computeMembersByName(name, names); |
| 821 if (computedMemberNames == null) { | 820 if (computedMemberNames == null) { |
| 822 computedMemberNames = _EMPTY_MEMBERS_NAMES; | 821 computedMemberNames = _EMPTY_MEMBERS_NAMES; |
| 823 } | 822 } |
| 824 if (name != Compiler.CALL_OPERATOR_NAME) { | 823 if (name != Compiler.CALL_OPERATOR_NAME) { |
| 825 Setlet<String> set; | 824 Setlet<String> set; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 882 message: "Members have not been fully computed for $this.")); | 881 message: "Members have not been fully computed for $this.")); |
| 883 if (interfaceMembersAreClassMembers) { | 882 if (interfaceMembersAreClassMembers) { |
| 884 classMembers.forEach((_, member) { | 883 classMembers.forEach((_, member) { |
| 885 if (!member.isStatic) f(member); | 884 if (!member.isStatic) f(member); |
| 886 }); | 885 }); |
| 887 } else { | 886 } else { |
| 888 interfaceMembers.forEach((_, member) => f(member)); | 887 interfaceMembers.forEach((_, member) => f(member)); |
| 889 } | 888 } |
| 890 } | 889 } |
| 891 } | 890 } |
| OLD | NEW |