| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library resolution.compute_members; |
| 6 |
| 7 import '../elements/elements.dart' |
| 8 show Element, |
| 9 Name, |
| 10 PublicName, |
| 11 Member, |
| 12 MemberSignature, |
| 13 LibraryElement, |
| 14 ClassElement, |
| 15 MixinApplicationElement; |
| 16 import '../elements/modelx.dart' |
| 17 show BaseClassElementX; |
| 18 import '../dart_types.dart'; |
| 19 import '../dart2jslib.dart' |
| 20 show Compiler, |
| 21 MessageKind, |
| 22 invariant; |
| 23 import '../util/util.dart'; |
| 24 |
| 25 part 'member_impl.dart'; |
| 26 |
| 27 class MembersCreator { |
| 28 final ClassElement cls; |
| 29 final Compiler compiler; |
| 30 |
| 31 Map<Name, Member> classMembers = new Map<Name, Member>(); |
| 32 Map<Name, MemberSignature> interfaceMembers = |
| 33 new Map<Name, MemberSignature>(); |
| 34 |
| 35 MembersCreator(Compiler this.compiler, ClassElement this.cls); |
| 36 |
| 37 void computeMembers() { |
| 38 Map<Name, Set<Member>> inheritedInterfaceMembers = |
| 39 _computeSuperMembers(); |
| 40 Map<Name, Member> declaredMembers = _computeClassMembers(); |
| 41 _computeInterfaceMembers(inheritedInterfaceMembers, declaredMembers); |
| 42 } |
| 43 |
| 44 Map<Name, Set<Member>> _computeSuperMembers() { |
| 45 Map<Name, Set<Member>> inheritedInterfaceMembers = |
| 46 new Map<Name, Set<Member>>(); |
| 47 |
| 48 void inheritInterfaceMembers(InterfaceType supertype) { |
| 49 supertype.element.forEachInterfaceMember((MemberSignature member) { |
| 50 Set<Member> members = |
| 51 inheritedInterfaceMembers.putIfAbsent( |
| 52 member.name, () => new Set<Member>()); |
| 53 for (DeclaredMember declaredMember in member.declarations) { |
| 54 members.add(declaredMember.inheritFrom(supertype)); |
| 55 } |
| 56 }); |
| 57 } |
| 58 |
| 59 // Inherit class and interface members from superclass. |
| 60 InterfaceType superclass = cls.supertype; |
| 61 if (superclass != null) { |
| 62 computeClassMembers(compiler, superclass.element); |
| 63 superclass.element.forEachClassMember((DeclaredMember member) { |
| 64 if (!member.isStatic) { |
| 65 DeclaredMember inherited = member.inheritFrom(superclass); |
| 66 classMembers[member.name] = inherited; |
| 67 } |
| 68 }); |
| 69 inheritInterfaceMembers(superclass); |
| 70 } |
| 71 |
| 72 // Inherit interface members from superinterfaces. |
| 73 for (Link<DartType> link = cls.interfaces; |
| 74 !link.isEmpty; |
| 75 link = link.tail) { |
| 76 InterfaceType superinterface = link.head; |
| 77 computeClassMembers(compiler, superinterface.element); |
| 78 inheritInterfaceMembers(superinterface); |
| 79 } |
| 80 |
| 81 return inheritedInterfaceMembers; |
| 82 } |
| 83 |
| 84 Map<Name, Member> _computeClassMembers() { |
| 85 Map<Name, Member> declaredMembers = new Map<Name, Member>(); |
| 86 |
| 87 void overrideMember(DeclaredMember declared) { |
| 88 classMembers[declared.name] = declared; |
| 89 } |
| 90 |
| 91 if (cls.isMixinApplication) { |
| 92 MixinApplicationElement mixinApplication = cls; |
| 93 if (mixinApplication.mixin != null) { |
| 94 // Only mix in class members when the mixin type is not malformed. |
| 95 computeClassMembers(compiler, mixinApplication.mixin); |
| 96 |
| 97 mixinApplication.mixin.forEachClassMember((DeclaredMember member) { |
| 98 if (!member.isStatic) { |
| 99 // Abstract and static members are not mixed in. |
| 100 DeclaredMember mixedInMember = |
| 101 member.inheritFrom(mixinApplication.mixinType); |
| 102 overrideMember(mixedInMember); |
| 103 } |
| 104 }); |
| 105 } |
| 106 } else { |
| 107 LibraryElement library = cls.getLibrary(); |
| 108 InterfaceType thisType = cls.thisType; |
| 109 |
| 110 cls.forEachLocalMember((Element element) { |
| 111 if (element.isConstructor()) return; |
| 112 |
| 113 Name name = new Name(element.name, library); |
| 114 if (element.isField()) { |
| 115 DartType type = element.computeType(compiler); |
| 116 declaredMembers[name] = new DeclaredMember( |
| 117 name, element, thisType, type, |
| 118 new FunctionType(compiler.functionClass, type)); |
| 119 if (!element.modifiers.isConst() && |
| 120 !element.modifiers.isFinal()) { |
| 121 name = name.setter; |
| 122 declaredMembers[name] = new DeclaredMember( |
| 123 name, element, thisType, type, |
| 124 new FunctionType(compiler.functionClass, |
| 125 compiler.types.voidType, |
| 126 const Link<DartType>().prepend(type))); |
| 127 } |
| 128 } else if (element.isGetter()) { |
| 129 FunctionType functionType = element.computeType(compiler); |
| 130 DartType type = functionType.returnType; |
| 131 declaredMembers[name] = |
| 132 new DeclaredMember(name, element, thisType, type, functionType); |
| 133 } else if (element.isSetter()) { |
| 134 FunctionType functionType = element.computeType(compiler); |
| 135 DartType type; |
| 136 if (!functionType.parameterTypes.isEmpty) { |
| 137 type = functionType.parameterTypes.head; |
| 138 } else { |
| 139 type = compiler.types.dynamicType; |
| 140 } |
| 141 name = name.setter; |
| 142 declaredMembers[name] = new DeclaredMember( |
| 143 name, element, thisType, type, functionType); |
| 144 } else { |
| 145 assert(invariant(element, element.isFunction())); |
| 146 FunctionType type = element.computeType(compiler); |
| 147 declaredMembers[name] = new DeclaredMember( |
| 148 name, element, thisType, type, type); |
| 149 } |
| 150 }); |
| 151 } |
| 152 |
| 153 declaredMembers.values.forEach((Member member) { |
| 154 if (!member.element.isAbstract) { |
| 155 overrideMember(member); |
| 156 } |
| 157 }); |
| 158 |
| 159 return declaredMembers; |
| 160 } |
| 161 |
| 162 void _computeInterfaceMembers( |
| 163 Map<Name, Set<Member>> inheritedInterfaceMembers, |
| 164 Map<Name, Member> declaredMembers) { |
| 165 InterfaceType thisType = cls.thisType; |
| 166 // Compute the interface members by overriding the inherited members with |
| 167 // a declared member or by computing a single, possibly synthesized, |
| 168 // inherited member. |
| 169 inheritedInterfaceMembers.forEach( |
| 170 (Name name, Set<Member> inheritedMembers) { |
| 171 Member declared = declaredMembers[name]; |
| 172 if (declared != null) { |
| 173 if (!declared.isStatic) { |
| 174 interfaceMembers[name] = declared; |
| 175 } |
| 176 } else { |
| 177 bool someAreGetters = false; |
| 178 bool allAreGetters = true; |
| 179 Map<DartType, Set<Member>> subtypesOfAllInherited = |
| 180 new Map<DartType, Set<Member>>(); |
| 181 outer: for (Member inherited in inheritedMembers) { |
| 182 if (inherited.isGetter) { |
| 183 someAreGetters = true; |
| 184 if (!allAreGetters) break outer; |
| 185 } else { |
| 186 allAreGetters = false; |
| 187 if (someAreGetters) break outer; |
| 188 } |
| 189 for (MemberSignature other in inheritedMembers) { |
| 190 if (!compiler.types.isSubtype(inherited.functionType, |
| 191 other.functionType)) { |
| 192 continue outer; |
| 193 } |
| 194 } |
| 195 subtypesOfAllInherited.putIfAbsent(inherited.functionType, |
| 196 () => new Set<Member>()).add(inherited); |
| 197 } |
| 198 if (someAreGetters && !allAreGetters) { |
| 199 interfaceMembers[name] = new ErroneousMember(inheritedMembers); |
| 200 } else if (subtypesOfAllInherited.length == 1) { |
| 201 // All signatures have the same type. |
| 202 Set<Member> members = subtypesOfAllInherited.values.first; |
| 203 MemberSignature inherited = members.first; |
| 204 if (members.length != 1) { |
| 205 // Multiple signatures with the same type => return a |
| 206 // synthesized signature. |
| 207 inherited = new SyntheticMember( |
| 208 members, inherited.type, inherited.functionType); |
| 209 } |
| 210 interfaceMembers[name] = inherited; |
| 211 } else { |
| 212 _inheritedSynthesizedMember(name, inheritedMembers); |
| 213 } |
| 214 } |
| 215 }); |
| 216 |
| 217 // Add the non-overriding instance methods to the interface members. |
| 218 declaredMembers.forEach((Name name, Member member) { |
| 219 if (!member.isStatic) { |
| 220 interfaceMembers.putIfAbsent(name, () => member); |
| 221 } |
| 222 }); |
| 223 } |
| 224 |
| 225 /// Create and inherit a synthesized member for [inheritedMembers]. |
| 226 void _inheritedSynthesizedMember(Name name, |
| 227 Set<Member> inheritedMembers) { |
| 228 // Multiple signatures with different types => create the synthesized |
| 229 // version. |
| 230 int minRequiredParameters; |
| 231 int maxPositionalParameters; |
| 232 Set<String> names = new Set<String>(); |
| 233 for (MemberSignature member in inheritedMembers) { |
| 234 int requiredParameters = 0; |
| 235 int optionalParameters = 0; |
| 236 if (member.isSetter) { |
| 237 requiredParameters = 1; |
| 238 } |
| 239 if (member.type.kind == TypeKind.FUNCTION) { |
| 240 FunctionType type = member.type; |
| 241 type.namedParameters.forEach( |
| 242 (String name) => names.add(name)); |
| 243 requiredParameters = type.parameterTypes.slowLength(); |
| 244 optionalParameters = type.optionalParameterTypes.slowLength(); |
| 245 } |
| 246 int positionalParameters = requiredParameters + optionalParameters; |
| 247 if (minRequiredParameters == null || |
| 248 minRequiredParameters > requiredParameters) { |
| 249 minRequiredParameters = requiredParameters; |
| 250 } |
| 251 if (maxPositionalParameters == null || |
| 252 maxPositionalParameters < positionalParameters) { |
| 253 maxPositionalParameters = positionalParameters; |
| 254 } |
| 255 } |
| 256 int optionalParameters = |
| 257 maxPositionalParameters - minRequiredParameters; |
| 258 // TODO(johnniwinther): Support function types with both optional |
| 259 // and named parameters? |
| 260 if (optionalParameters == 0 || names.isEmpty) { |
| 261 Link<DartType> requiredParameterTypes = const Link<DartType>(); |
| 262 while (--minRequiredParameters >= 0) { |
| 263 requiredParameterTypes = |
| 264 requiredParameterTypes.prepend(compiler.types.dynamicType); |
| 265 } |
| 266 Link<DartType> optionalParameterTypes = const Link<DartType>(); |
| 267 while (--optionalParameters >= 0) { |
| 268 optionalParameterTypes = |
| 269 optionalParameterTypes.prepend(compiler.types.dynamicType); |
| 270 } |
| 271 Link<String> namedParameters = const Link<String>(); |
| 272 Link<DartType> namedParameterTypes = const Link<DartType>(); |
| 273 List<String> namesReversed = |
| 274 names.toList()..sort((a, b) => -a.compareTo(b)); |
| 275 for (String name in namesReversed) { |
| 276 namedParameters = namedParameters.prepend(name); |
| 277 namedParameterTypes = |
| 278 namedParameterTypes.prepend(compiler.types.dynamicType); |
| 279 } |
| 280 FunctionType memberType = new FunctionType( |
| 281 compiler.functionClass, |
| 282 compiler.types.dynamicType, |
| 283 requiredParameterTypes, |
| 284 optionalParameterTypes, |
| 285 namedParameters, namedParameterTypes); |
| 286 DartType type = memberType; |
| 287 if (inheritedMembers.first.isGetter || |
| 288 inheritedMembers.first.isSetter) { |
| 289 type = compiler.types.dynamicType; |
| 290 } |
| 291 interfaceMembers[name] = new SyntheticMember( |
| 292 inheritedMembers, type, memberType); |
| 293 } |
| 294 } |
| 295 |
| 296 static void computeClassMembers(Compiler compiler, BaseClassElementX cls) { |
| 297 if (cls.classMembers != null) return; |
| 298 MembersCreator creator = new MembersCreator(compiler, cls); |
| 299 creator.computeMembers(); |
| 300 cls.classMembers = creator.classMembers; |
| 301 cls.interfaceMembers = creator.interfaceMembers; |
| 302 } |
| 303 } |
| OLD | NEW |