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