| 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.dart'; | 7 import '../common.dart'; |
| 8 import '../common/names.dart' show | 8 import '../common/names.dart' show Identifiers, Names; |
| 9 Identifiers, | 9 import '../common/resolution.dart' show Resolution; |
| 10 Names; | 10 import '../compiler.dart' show Compiler; |
| 11 import '../common/resolution.dart' show | |
| 12 Resolution; | |
| 13 import '../compiler.dart' show | |
| 14 Compiler; | |
| 15 import '../dart_types.dart'; | 11 import '../dart_types.dart'; |
| 16 import '../elements/elements.dart' show | 12 import '../elements/elements.dart' |
| 17 ClassElement, | 13 show |
| 18 Element, | 14 ClassElement, |
| 19 LibraryElement, | 15 Element, |
| 20 Member, | 16 LibraryElement, |
| 21 MemberElement, | 17 Member, |
| 22 MemberSignature, | 18 MemberElement, |
| 23 MixinApplicationElement, | 19 MemberSignature, |
| 24 Name, | 20 MixinApplicationElement, |
| 25 PublicName; | 21 Name, |
| 22 PublicName; |
| 26 import '../util/util.dart'; | 23 import '../util/util.dart'; |
| 27 | 24 |
| 28 part 'member_impl.dart'; | 25 part 'member_impl.dart'; |
| 29 | 26 |
| 30 abstract class MembersCreator { | 27 abstract class MembersCreator { |
| 31 final ClassElement cls; | 28 final ClassElement cls; |
| 32 final Compiler compiler; | 29 final Compiler compiler; |
| 33 | 30 |
| 34 final Iterable<String> computedMemberNames; | 31 final Iterable<String> computedMemberNames; |
| 35 final Map<Name, Member> classMembers; | 32 final Map<Name, Member> classMembers; |
| 36 | 33 |
| 37 Map<dynamic/* Member | Element */, Set<MessageKind>> reportedMessages = | 34 Map<dynamic /* Member | Element */, Set<MessageKind>> reportedMessages = |
| 38 new Map<dynamic, Set<MessageKind>>(); | 35 new Map<dynamic, Set<MessageKind>>(); |
| 39 | 36 |
| 40 MembersCreator(Compiler this.compiler, | 37 MembersCreator( |
| 41 ClassElement this.cls, | 38 Compiler this.compiler, |
| 42 Iterable<String> this.computedMemberNames, | 39 ClassElement this.cls, |
| 43 Map<Name, Member> this.classMembers) { | 40 Iterable<String> this.computedMemberNames, |
| 41 Map<Name, Member> this.classMembers) { |
| 44 assert(invariant(cls, cls.isDeclaration, | 42 assert(invariant(cls, cls.isDeclaration, |
| 45 message: "Members may only be computed on declarations.")); | 43 message: "Members may only be computed on declarations.")); |
| 46 } | 44 } |
| 47 | 45 |
| 48 DiagnosticReporter get reporter => compiler.reporter; | 46 DiagnosticReporter get reporter => compiler.reporter; |
| 49 | 47 |
| 50 Resolution get resolution => compiler.resolution; | 48 Resolution get resolution => compiler.resolution; |
| 51 | 49 |
| 52 void reportMessage(var marker, MessageKind kind, report()) { | 50 void reportMessage(var marker, MessageKind kind, report()) { |
| 53 Set<MessageKind> messages = | 51 Set<MessageKind> messages = |
| 54 reportedMessages.putIfAbsent(marker, | 52 reportedMessages.putIfAbsent(marker, () => new Set<MessageKind>()); |
| 55 () => new Set<MessageKind>()); | |
| 56 if (messages.add(kind)) { | 53 if (messages.add(kind)) { |
| 57 report(); | 54 report(); |
| 58 } | 55 } |
| 59 } | 56 } |
| 60 | 57 |
| 61 bool shouldSkipMember(MemberSignature member) { | 58 bool shouldSkipMember(MemberSignature member) { |
| 62 return member == null || shouldSkipName(member.name.text); | 59 return member == null || shouldSkipName(member.name.text); |
| 63 | |
| 64 } | 60 } |
| 65 | 61 |
| 66 bool shouldSkipName(String name) { | 62 bool shouldSkipName(String name) { |
| 67 return computedMemberNames != null && | 63 return computedMemberNames != null && |
| 68 // 'call' is implicitly contained in [computedMemberNames]. | 64 // 'call' is implicitly contained in [computedMemberNames]. |
| 69 (name == Identifiers.call || computedMemberNames.contains(name)); | 65 (name == Identifiers.call || computedMemberNames.contains(name)); |
| 70 } | 66 } |
| 71 | 67 |
| 72 /// Compute all members of [cls] with the given names. | 68 /// Compute all members of [cls] with the given names. |
| 73 void computeMembersByName(String name, Setlet<Name> names) { | 69 void computeMembersByName(String name, Setlet<Name> names) { |
| 74 computeMembers(name, names); | 70 computeMembers(name, names); |
| 75 } | 71 } |
| 76 | 72 |
| 77 /// Compute all members of [cls] and checked that [cls] implements its | 73 /// Compute all members of [cls] and checked that [cls] implements its |
| 78 /// interface unless it is abstract or declares a `noSuchMethod` method. | 74 /// interface unless it is abstract or declares a `noSuchMethod` method. |
| 79 void computeAllMembers() { | 75 void computeAllMembers() { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 // Abstract and static members are not mixed in. | 148 // Abstract and static members are not mixed in. |
| 153 DeclaredMember mixedInMember = | 149 DeclaredMember mixedInMember = |
| 154 member.inheritFrom(mixinApplication.mixinType); | 150 member.inheritFrom(mixinApplication.mixinType); |
| 155 DeclaredMember inherited = classMembers[name]; | 151 DeclaredMember inherited = classMembers[name]; |
| 156 classMembers[name] = mixedInMember; | 152 classMembers[name] = mixedInMember; |
| 157 checkValidOverride(mixedInMember, inherited); | 153 checkValidOverride(mixedInMember, inherited); |
| 158 } | 154 } |
| 159 } | 155 } |
| 160 | 156 |
| 161 if (names != null) { | 157 if (names != null) { |
| 162 _computeClassMember(compiler, mixinApplication.mixin, | 158 _computeClassMember( |
| 163 nameText, names); | 159 compiler, mixinApplication.mixin, nameText, names); |
| 164 for (Name memberName in names) { | 160 for (Name memberName in names) { |
| 165 inheritMixinMember( | 161 inheritMixinMember( |
| 166 mixinApplication.mixin.lookupClassMember(memberName)); | 162 mixinApplication.mixin.lookupClassMember(memberName)); |
| 167 } | 163 } |
| 168 } else { | 164 } else { |
| 169 computeAllClassMembers(compiler, mixinApplication.mixin); | 165 computeAllClassMembers(compiler, mixinApplication.mixin); |
| 170 mixinApplication.mixin.forEachClassMember(inheritMixinMember); | 166 mixinApplication.mixin.forEachClassMember(inheritMixinMember); |
| 171 } | 167 } |
| 172 } | 168 } |
| 173 } else { | 169 } else { |
| 174 LibraryElement library = cls.library; | 170 LibraryElement library = cls.library; |
| 175 InterfaceType thisType = cls.thisType; | 171 InterfaceType thisType = cls.thisType; |
| 176 | 172 |
| 177 void createMember(MemberElement element) { | 173 void createMember(MemberElement element) { |
| 178 if (element.isConstructor) return; | 174 if (element.isConstructor) return; |
| 179 String elementName = element.name; | 175 String elementName = element.name; |
| 180 if (shouldSkipName(elementName)) return; | 176 if (shouldSkipName(elementName)) return; |
| 181 if (nameText != null && elementName != nameText) return; | 177 if (nameText != null && elementName != nameText) return; |
| 182 | 178 |
| 183 void addDeclaredMember(Name name, | 179 void addDeclaredMember( |
| 184 DartType type, FunctionType functionType) { | 180 Name name, DartType type, FunctionType functionType) { |
| 185 DeclaredMember inherited = classMembers[name]; | 181 DeclaredMember inherited = classMembers[name]; |
| 186 DeclaredMember declared; | 182 DeclaredMember declared; |
| 187 if (element.isAbstract) { | 183 if (element.isAbstract) { |
| 188 declared = new DeclaredAbstractMember( | 184 declared = new DeclaredAbstractMember( |
| 189 name, element, thisType, type, functionType, | 185 name, element, thisType, type, functionType, inherited); |
| 190 inherited); | |
| 191 } else { | 186 } else { |
| 192 declared = | 187 declared = |
| 193 new DeclaredMember(name, element, thisType, type, functionType); | 188 new DeclaredMember(name, element, thisType, type, functionType); |
| 194 } | 189 } |
| 195 declaredMembers[name] = declared; | 190 declaredMembers[name] = declared; |
| 196 classMembers[name] = declared; | 191 classMembers[name] = declared; |
| 197 checkValidOverride(declared, inherited); | 192 checkValidOverride(declared, inherited); |
| 198 } | 193 } |
| 199 | 194 |
| 200 Name name = new Name(element.name, library); | 195 Name name = new Name(element.name, library); |
| 201 if (element.isField) { | 196 if (element.isField) { |
| 202 DartType type = element.computeType(resolution); | 197 DartType type = element.computeType(resolution); |
| 203 addDeclaredMember(name, type, new FunctionType.synthesized(type)); | 198 addDeclaredMember(name, type, new FunctionType.synthesized(type)); |
| 204 if (!element.isConst && !element.isFinal) { | 199 if (!element.isConst && !element.isFinal) { |
| 205 addDeclaredMember(name.setter, type, | 200 addDeclaredMember( |
| 201 name.setter, |
| 202 type, |
| 206 new FunctionType.synthesized( | 203 new FunctionType.synthesized( |
| 207 const VoidType(), | 204 const VoidType(), <DartType>[type])); |
| 208 <DartType>[type])); | |
| 209 } | 205 } |
| 210 } else if (element.isGetter) { | 206 } else if (element.isGetter) { |
| 211 FunctionType functionType = element.computeType(resolution); | 207 FunctionType functionType = element.computeType(resolution); |
| 212 DartType type = functionType.returnType; | 208 DartType type = functionType.returnType; |
| 213 addDeclaredMember(name, type, functionType); | 209 addDeclaredMember(name, type, functionType); |
| 214 } else if (element.isSetter) { | 210 } else if (element.isSetter) { |
| 215 FunctionType functionType = element.computeType(resolution); | 211 FunctionType functionType = element.computeType(resolution); |
| 216 DartType type; | 212 DartType type; |
| 217 if (!functionType.parameterTypes.isEmpty) { | 213 if (!functionType.parameterTypes.isEmpty) { |
| 218 type = functionType.parameterTypes.first; | 214 type = functionType.parameterTypes.first; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 235 createMember(element); | 231 createMember(element); |
| 236 } | 232 } |
| 237 }); | 233 }); |
| 238 } | 234 } |
| 239 } | 235 } |
| 240 | 236 |
| 241 return declaredMembers; | 237 return declaredMembers; |
| 242 } | 238 } |
| 243 | 239 |
| 244 /// Checks that [classMember] is a valid implementation for [interfaceMember]. | 240 /// Checks that [classMember] is a valid implementation for [interfaceMember]. |
| 245 void checkInterfaceMember(Name name, | 241 void checkInterfaceMember( |
| 246 MemberSignature interfaceMember, | 242 Name name, MemberSignature interfaceMember, Member classMember) { |
| 247 Member classMember) { | |
| 248 if (classMember != null) { | 243 if (classMember != null) { |
| 249 // TODO(johnniwinther): Check that the class member is a valid override | 244 // TODO(johnniwinther): Check that the class member is a valid override |
| 250 // of the interface member. | 245 // of the interface member. |
| 251 return; | 246 return; |
| 252 } | 247 } |
| 253 if (interfaceMember is DeclaredMember && | 248 if (interfaceMember is DeclaredMember && |
| 254 interfaceMember.declarer.element == cls) { | 249 interfaceMember.declarer.element == cls) { |
| 255 // Abstract method declared in [cls]. | 250 // Abstract method declared in [cls]. |
| 256 MessageKind kind = MessageKind.ABSTRACT_METHOD; | 251 MessageKind kind = MessageKind.ABSTRACT_METHOD; |
| 257 if (interfaceMember.isSetter) { | 252 if (interfaceMember.isSetter) { |
| 258 kind = MessageKind.ABSTRACT_SETTER; | 253 kind = MessageKind.ABSTRACT_SETTER; |
| 259 } else if (interfaceMember.isGetter) { | 254 } else if (interfaceMember.isGetter) { |
| 260 kind = MessageKind.ABSTRACT_GETTER; | 255 kind = MessageKind.ABSTRACT_GETTER; |
| 261 } | 256 } |
| 262 reportMessage( | 257 reportMessage(interfaceMember.element, MessageKind.ABSTRACT_METHOD, () { |
| 263 interfaceMember.element, MessageKind.ABSTRACT_METHOD, () { | 258 reporter.reportWarningMessage(interfaceMember.element, kind, |
| 264 reporter.reportWarningMessage( | |
| 265 interfaceMember.element, kind, | |
| 266 {'class': cls.name, 'name': name.text}); | 259 {'class': cls.name, 'name': name.text}); |
| 267 }); | 260 }); |
| 268 } else { | 261 } else { |
| 269 reportWarning(MessageKind singleKind, | 262 reportWarning(MessageKind singleKind, MessageKind multipleKind, |
| 270 MessageKind multipleKind, | 263 MessageKind explicitlyDeclaredKind, |
| 271 MessageKind explicitlyDeclaredKind, | 264 [MessageKind implicitlyDeclaredKind]) { |
| 272 [MessageKind implicitlyDeclaredKind]) { | |
| 273 Member inherited = interfaceMember.declarations.first; | 265 Member inherited = interfaceMember.declarations.first; |
| 274 reportMessage( | 266 reportMessage(interfaceMember, MessageKind.UNIMPLEMENTED_METHOD, () { |
| 275 interfaceMember, MessageKind.UNIMPLEMENTED_METHOD, () { | |
| 276 DiagnosticMessage warning = reporter.createMessage( | 267 DiagnosticMessage warning = reporter.createMessage( |
| 277 cls, | 268 cls, |
| 278 interfaceMember.declarations.length == 1 | 269 interfaceMember.declarations.length == 1 |
| 279 ? singleKind : multipleKind, | 270 ? singleKind |
| 280 {'class': cls.name, | 271 : multipleKind, |
| 281 'name': name.text, | 272 { |
| 282 'method': interfaceMember, | 273 'class': cls.name, |
| 283 'declarer': inherited.declarer}); | 274 'name': name.text, |
| 275 'method': interfaceMember, |
| 276 'declarer': inherited.declarer |
| 277 }); |
| 284 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; | 278 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; |
| 285 for (Member inherited in interfaceMember.declarations) { | 279 for (Member inherited in interfaceMember.declarations) { |
| 286 infos.add(reporter.createMessage( | 280 infos.add(reporter.createMessage( |
| 287 inherited.element, | 281 inherited.element, |
| 288 inherited.isDeclaredByField ? | 282 inherited.isDeclaredByField |
| 289 implicitlyDeclaredKind : explicitlyDeclaredKind, | 283 ? implicitlyDeclaredKind |
| 290 {'class': inherited.declarer.name, | 284 : explicitlyDeclaredKind, |
| 291 'name': name.text})); | 285 {'class': inherited.declarer.name, 'name': name.text})); |
| 292 } | 286 } |
| 293 reporter.reportWarning(warning, infos); | 287 reporter.reportWarning(warning, infos); |
| 294 }); | 288 }); |
| 295 } | 289 } |
| 296 if (interfaceMember.isSetter) { | 290 if (interfaceMember.isSetter) { |
| 297 reportWarning(MessageKind.UNIMPLEMENTED_SETTER_ONE, | 291 reportWarning( |
| 298 MessageKind.UNIMPLEMENTED_SETTER, | 292 MessageKind.UNIMPLEMENTED_SETTER_ONE, |
| 299 MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER, | 293 MessageKind.UNIMPLEMENTED_SETTER, |
| 300 MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER); | 294 MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER, |
| 295 MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER); |
| 301 } else if (interfaceMember.isGetter) { | 296 } else if (interfaceMember.isGetter) { |
| 302 reportWarning(MessageKind.UNIMPLEMENTED_GETTER_ONE, | 297 reportWarning( |
| 303 MessageKind.UNIMPLEMENTED_GETTER, | 298 MessageKind.UNIMPLEMENTED_GETTER_ONE, |
| 304 MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER, | 299 MessageKind.UNIMPLEMENTED_GETTER, |
| 305 MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER); | 300 MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER, |
| 301 MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER); |
| 306 } else if (interfaceMember.isMethod) { | 302 } else if (interfaceMember.isMethod) { |
| 307 reportWarning(MessageKind.UNIMPLEMENTED_METHOD_ONE, | 303 reportWarning( |
| 308 MessageKind.UNIMPLEMENTED_METHOD, | 304 MessageKind.UNIMPLEMENTED_METHOD_ONE, |
| 309 MessageKind.UNIMPLEMENTED_METHOD_CONT); | 305 MessageKind.UNIMPLEMENTED_METHOD, |
| 306 MessageKind.UNIMPLEMENTED_METHOD_CONT); |
| 310 } | 307 } |
| 311 } | 308 } |
| 312 // TODO(johnniwinther): If [cls] is not abstract, check that for all | 309 // TODO(johnniwinther): If [cls] is not abstract, check that for all |
| 313 // interface members, there is a class member whose type is a subtype of | 310 // interface members, there is a class member whose type is a subtype of |
| 314 // the interface member. | 311 // the interface member. |
| 315 } | 312 } |
| 316 | 313 |
| 317 /// Checks that [cls], if it implements Function, has defined call(). | 314 /// Checks that [cls], if it implements Function, has defined call(). |
| 318 void checkImplementsFunctionWithCall() { | 315 void checkImplementsFunctionWithCall() { |
| 319 assert(!cls.isAbstract); | 316 assert(!cls.isAbstract); |
| 320 | 317 |
| 321 ClassElement functionClass = compiler.coreClasses.functionClass; | 318 ClassElement functionClass = compiler.coreClasses.functionClass; |
| 322 if (cls.asInstanceOf(functionClass) == null) return; | 319 if (cls.asInstanceOf(functionClass) == null) return; |
| 323 if (cls.lookupMember(Identifiers.call) != null) return; | 320 if (cls.lookupMember(Identifiers.call) != null) return; |
| 324 // TODO(johnniwinther): Make separate methods for backend exceptions. | 321 // TODO(johnniwinther): Make separate methods for backend exceptions. |
| 325 // Avoid warnings on backend implementation classes for closures. | 322 // Avoid warnings on backend implementation classes for closures. |
| 326 if (compiler.backend.isBackendLibrary(cls.library)) return; | 323 if (compiler.backend.isBackendLibrary(cls.library)) return; |
| 327 | 324 |
| 328 reportMessage(functionClass, MessageKind.UNIMPLEMENTED_METHOD, () { | 325 reportMessage(functionClass, MessageKind.UNIMPLEMENTED_METHOD, () { |
| 329 reporter.reportWarningMessage( | 326 reporter.reportWarningMessage(cls, MessageKind.UNIMPLEMENTED_METHOD_ONE, { |
| 330 cls, | 327 'class': cls.name, |
| 331 MessageKind.UNIMPLEMENTED_METHOD_ONE, | 328 'name': Identifiers.call, |
| 332 {'class': cls.name, | 329 'method': Identifiers.call, |
| 333 'name': Identifiers.call, | 330 'declarer': functionClass.name |
| 334 'method': Identifiers.call, | 331 }); |
| 335 'declarer': functionClass.name}); | |
| 336 }); | 332 }); |
| 337 } | 333 } |
| 338 | 334 |
| 339 /// Checks that a class member exists for every interface member. | 335 /// Checks that a class member exists for every interface member. |
| 340 void checkInterfaceImplementation(); | 336 void checkInterfaceImplementation(); |
| 341 | 337 |
| 342 /// Check that [declared] is a valid override of [superMember]. | 338 /// Check that [declared] is a valid override of [superMember]. |
| 343 void checkValidOverride(Member declared, MemberSignature superMember) { | 339 void checkValidOverride(Member declared, MemberSignature superMember) { |
| 344 if (superMember == null) { | 340 if (superMember == null) { |
| 345 // No override. | 341 // No override. |
| 346 if (!declared.isStatic) { | 342 if (!declared.isStatic) { |
| 347 ClassElement superclass = cls.superclass; | 343 ClassElement superclass = cls.superclass; |
| 348 while (superclass != null) { | 344 while (superclass != null) { |
| 349 Member superMember = | 345 Member superMember = superclass.lookupClassMember(declared.name); |
| 350 superclass.lookupClassMember(declared.name); | |
| 351 if (superMember != null && superMember.isStatic) { | 346 if (superMember != null && superMember.isStatic) { |
| 352 reportMessage(superMember, MessageKind.INSTANCE_STATIC_SAME_NAME, | 347 reportMessage(superMember, MessageKind.INSTANCE_STATIC_SAME_NAME, |
| 353 () { | 348 () { |
| 354 reporter.reportWarning( | 349 reporter.reportWarning( |
| 355 reporter.createMessage( | 350 reporter.createMessage( |
| 356 declared.element, | 351 declared.element, MessageKind.INSTANCE_STATIC_SAME_NAME, { |
| 357 MessageKind.INSTANCE_STATIC_SAME_NAME, | 352 'memberName': declared.name, |
| 358 {'memberName': declared.name, | 353 'className': superclass.name |
| 359 'className': superclass.name}), | 354 }), |
| 360 <DiagnosticMessage>[ | 355 <DiagnosticMessage>[ |
| 361 reporter.createMessage( | 356 reporter.createMessage(superMember.element, |
| 362 superMember.element, | 357 MessageKind.INSTANCE_STATIC_SAME_NAME_CONT), |
| 363 MessageKind.INSTANCE_STATIC_SAME_NAME_CONT), | |
| 364 ]); | 358 ]); |
| 365 | |
| 366 }); | 359 }); |
| 367 break; | 360 break; |
| 368 } | 361 } |
| 369 superclass = superclass.superclass; | 362 superclass = superclass.superclass; |
| 370 } | 363 } |
| 371 } | 364 } |
| 372 } else { | 365 } else { |
| 373 assert(declared.name == superMember.name); | 366 assert(declared.name == superMember.name); |
| 374 | 367 |
| 375 if (declared.isStatic) { | 368 if (declared.isStatic) { |
| 376 for (Member inherited in superMember.declarations) { | 369 for (Member inherited in superMember.declarations) { |
| 377 if (cls == inherited.declarer.element) { | 370 if (cls == inherited.declarer.element) { |
| 378 // An error should already have been reported. | 371 // An error should already have been reported. |
| 379 assert(invariant(declared.element, compiler.compilationFailed)); | 372 assert(invariant(declared.element, compiler.compilationFailed)); |
| 380 continue; | 373 continue; |
| 381 } | 374 } |
| 382 | 375 |
| 383 reportMessage( | 376 reportMessage(inherited.element, MessageKind.NO_STATIC_OVERRIDE, () { |
| 384 inherited.element, MessageKind.NO_STATIC_OVERRIDE, () { | |
| 385 reportErrorWithContext( | 377 reportErrorWithContext( |
| 386 declared.element, MessageKind.NO_STATIC_OVERRIDE, | 378 declared.element, |
| 387 inherited.element, MessageKind.NO_STATIC_OVERRIDE_CONT); | 379 MessageKind.NO_STATIC_OVERRIDE, |
| 380 inherited.element, |
| 381 MessageKind.NO_STATIC_OVERRIDE_CONT); |
| 388 }); | 382 }); |
| 389 } | 383 } |
| 390 } | 384 } |
| 391 | 385 |
| 392 DartType declaredType = declared.functionType; | 386 DartType declaredType = declared.functionType; |
| 393 for (Member inherited in superMember.declarations) { | 387 for (Member inherited in superMember.declarations) { |
| 394 if (inherited.element == declared.element) { | 388 if (inherited.element == declared.element) { |
| 395 // TODO(ahe): For some reason, "call" elements are repeated in | 389 // TODO(ahe): For some reason, "call" elements are repeated in |
| 396 // superMember.declarations. Investigate why. | 390 // superMember.declarations. Investigate why. |
| 397 } else if (cls == inherited.declarer.element) { | 391 } else if (cls == inherited.declarer.element) { |
| 398 // An error should already have been reported. | 392 // An error should already have been reported. |
| 399 assert(invariant(declared.element, compiler.compilationFailed, | 393 assert(invariant(declared.element, compiler.compilationFailed, |
| 400 message: "Member $inherited inherited from its " | 394 message: "Member $inherited inherited from its " |
| 401 "declaring class: ${cls}.")); | 395 "declaring class: ${cls}.")); |
| 402 continue; | 396 continue; |
| 403 } | 397 } |
| 404 | 398 |
| 405 void reportError(MessageKind errorKind, MessageKind infoKind) { | 399 void reportError(MessageKind errorKind, MessageKind infoKind) { |
| 406 reportMessage( | 400 reportMessage(inherited.element, MessageKind.INVALID_OVERRIDE_METHOD, |
| 407 inherited.element, MessageKind.INVALID_OVERRIDE_METHOD, () { | 401 () { |
| 408 reporter.reportError( | 402 reporter.reportError( |
| 409 reporter.createMessage( | 403 reporter.createMessage(declared.element, errorKind, { |
| 410 declared.element, | 404 'name': declared.name.text, |
| 411 errorKind, | 405 'class': cls.thisType, |
| 412 {'name': declared.name.text, | 406 'inheritedClass': inherited.declarer |
| 413 'class': cls.thisType, | 407 }), |
| 414 'inheritedClass': inherited.declarer}), | |
| 415 <DiagnosticMessage>[ | 408 <DiagnosticMessage>[ |
| 416 reporter.createMessage( | 409 reporter.createMessage(inherited.element, infoKind, { |
| 417 inherited.element, | 410 'name': declared.name.text, |
| 418 infoKind, | 411 'class': inherited.declarer |
| 419 {'name': declared.name.text, | 412 }), |
| 420 'class': inherited.declarer}), | |
| 421 ]); | 413 ]); |
| 422 }); | 414 }); |
| 423 } | 415 } |
| 424 | 416 |
| 425 if (declared.isDeclaredByField && inherited.isMethod) { | 417 if (declared.isDeclaredByField && inherited.isMethod) { |
| 426 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD, | 418 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD, |
| 427 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT); | 419 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT); |
| 428 } else if (declared.isMethod && inherited.isDeclaredByField) { | 420 } else if (declared.isMethod && inherited.isDeclaredByField) { |
| 429 reportError(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD, | 421 reportError(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD, |
| 430 MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT); | 422 MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT); |
| 431 } else if (declared.isGetter && inherited.isMethod) { | 423 } else if (declared.isGetter && inherited.isMethod) { |
| 432 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER, | 424 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER, |
| 433 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT); | 425 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT); |
| 434 } else if (declared.isMethod && inherited.isGetter) { | 426 } else if (declared.isMethod && inherited.isGetter) { |
| 435 reportError(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD, | 427 reportError(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD, |
| 436 MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT); | 428 MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT); |
| 437 } else { | 429 } else { |
| 438 DartType inheritedType = inherited.functionType; | 430 DartType inheritedType = inherited.functionType; |
| 439 if (!compiler.types.isSubtype(declaredType, inheritedType)) { | 431 if (!compiler.types.isSubtype(declaredType, inheritedType)) { |
| 440 void reportWarning(var marker, | 432 void reportWarning( |
| 441 MessageKind warningKind, | 433 var marker, MessageKind warningKind, MessageKind infoKind) { |
| 442 MessageKind infoKind) { | |
| 443 reportMessage(marker, MessageKind.INVALID_OVERRIDE_METHOD, () { | 434 reportMessage(marker, MessageKind.INVALID_OVERRIDE_METHOD, () { |
| 444 reporter.reportWarning( | 435 reporter.reportWarning( |
| 445 reporter.createMessage( | 436 reporter.createMessage(declared.element, warningKind, { |
| 446 declared.element, | 437 'declaredType': declared.type, |
| 447 warningKind, | 438 'name': declared.name.text, |
| 448 {'declaredType': declared.type, | 439 'class': cls.thisType, |
| 449 'name': declared.name.text, | 440 'inheritedType': inherited.type, |
| 450 'class': cls.thisType, | 441 'inheritedClass': inherited.declarer |
| 451 'inheritedType': inherited.type, | 442 }), |
| 452 'inheritedClass': inherited.declarer}), | |
| 453 <DiagnosticMessage>[ | 443 <DiagnosticMessage>[ |
| 454 reporter.createMessage( | 444 reporter.createMessage(inherited.element, infoKind, { |
| 455 inherited.element, | 445 'name': declared.name.text, |
| 456 infoKind, | 446 'class': inherited.declarer |
| 457 {'name': declared.name.text, | 447 }), |
| 458 'class': inherited.declarer}), | |
| 459 ]); | 448 ]); |
| 460 }); | 449 }); |
| 461 } | 450 } |
| 462 if (declared.isDeclaredByField) { | 451 if (declared.isDeclaredByField) { |
| 463 if (inherited.isDeclaredByField) { | 452 if (inherited.isDeclaredByField) { |
| 464 reportWarning(inherited.element, | 453 reportWarning( |
| 465 MessageKind.INVALID_OVERRIDE_FIELD, | 454 inherited.element, |
| 466 MessageKind.INVALID_OVERRIDDEN_FIELD); | 455 MessageKind.INVALID_OVERRIDE_FIELD, |
| 456 MessageKind.INVALID_OVERRIDDEN_FIELD); |
| 467 } else if (inherited.isGetter) { | 457 } else if (inherited.isGetter) { |
| 468 reportWarning(inherited, | 458 reportWarning( |
| 469 MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD, | 459 inherited, |
| 470 MessageKind.INVALID_OVERRIDDEN_GETTER); | 460 MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD, |
| 461 MessageKind.INVALID_OVERRIDDEN_GETTER); |
| 471 } else if (inherited.isSetter) { | 462 } else if (inherited.isSetter) { |
| 472 reportWarning(inherited, | 463 reportWarning( |
| 473 MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD, | 464 inherited, |
| 474 MessageKind.INVALID_OVERRIDDEN_SETTER); | 465 MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD, |
| 466 MessageKind.INVALID_OVERRIDDEN_SETTER); |
| 475 } | 467 } |
| 476 } else if (declared.isGetter) { | 468 } else if (declared.isGetter) { |
| 477 if (inherited.isDeclaredByField) { | 469 if (inherited.isDeclaredByField) { |
| 478 reportWarning(inherited, | 470 reportWarning( |
| 479 MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER, | 471 inherited, |
| 480 MessageKind.INVALID_OVERRIDDEN_FIELD); | 472 MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER, |
| 473 MessageKind.INVALID_OVERRIDDEN_FIELD); |
| 481 } else { | 474 } else { |
| 482 reportWarning(inherited, | 475 reportWarning(inherited, MessageKind.INVALID_OVERRIDE_GETTER, |
| 483 MessageKind.INVALID_OVERRIDE_GETTER, | 476 MessageKind.INVALID_OVERRIDDEN_GETTER); |
| 484 MessageKind.INVALID_OVERRIDDEN_GETTER); | |
| 485 } | 477 } |
| 486 } else if (declared.isSetter) { | 478 } else if (declared.isSetter) { |
| 487 if (inherited.isDeclaredByField) { | 479 if (inherited.isDeclaredByField) { |
| 488 reportWarning(inherited, | 480 reportWarning( |
| 489 MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER, | 481 inherited, |
| 490 MessageKind.INVALID_OVERRIDDEN_FIELD); | 482 MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER, |
| 483 MessageKind.INVALID_OVERRIDDEN_FIELD); |
| 491 } else { | 484 } else { |
| 492 reportWarning(inherited, | 485 reportWarning(inherited, MessageKind.INVALID_OVERRIDE_SETTER, |
| 493 MessageKind.INVALID_OVERRIDE_SETTER, | 486 MessageKind.INVALID_OVERRIDDEN_SETTER); |
| 494 MessageKind.INVALID_OVERRIDDEN_SETTER); | |
| 495 } | 487 } |
| 496 } else { | 488 } else { |
| 497 reportWarning(inherited, | 489 reportWarning(inherited, MessageKind.INVALID_OVERRIDE_METHOD, |
| 498 MessageKind.INVALID_OVERRIDE_METHOD, | 490 MessageKind.INVALID_OVERRIDDEN_METHOD); |
| 499 MessageKind.INVALID_OVERRIDDEN_METHOD); | |
| 500 } | 491 } |
| 501 } | 492 } |
| 502 } | 493 } |
| 503 } | 494 } |
| 504 } | 495 } |
| 505 } | 496 } |
| 506 | 497 |
| 507 void reportErrorWithContext(Element errorneousElement, | 498 void reportErrorWithContext( |
| 508 MessageKind errorMessage, | 499 Element errorneousElement, |
| 509 Element contextElement, | 500 MessageKind errorMessage, |
| 510 MessageKind contextMessage) { | 501 Element contextElement, |
| 502 MessageKind contextMessage) { |
| 511 reporter.reportError( | 503 reporter.reportError( |
| 512 reporter.createMessage( | 504 reporter.createMessage(errorneousElement, errorMessage, { |
| 513 errorneousElement, | 505 'memberName': contextElement.name, |
| 514 errorMessage, | 506 'className': contextElement.enclosingClass.name |
| 515 {'memberName': contextElement.name, | 507 }), |
| 516 'className': contextElement.enclosingClass.name}), | |
| 517 <DiagnosticMessage>[ | 508 <DiagnosticMessage>[ |
| 518 reporter.createMessage(contextElement, contextMessage), | 509 reporter.createMessage(contextElement, contextMessage), |
| 519 ]); | 510 ]); |
| 520 } | 511 } |
| 521 | 512 |
| 522 /// Compute all class and interface names by the [name] in [cls]. | 513 /// Compute all class and interface names by the [name] in [cls]. |
| 523 static void computeClassMembersByName(Compiler compiler, | 514 static void computeClassMembersByName( |
| 524 ClassMemberMixin cls, | 515 Compiler compiler, ClassMemberMixin cls, String name) { |
| 525 String name) { | |
| 526 if (cls.isMemberComputed(name)) return; | 516 if (cls.isMemberComputed(name)) return; |
| 527 LibraryElement library = cls.library; | 517 LibraryElement library = cls.library; |
| 528 _computeClassMember(compiler, cls, name, | 518 _computeClassMember( |
| 529 new Setlet<Name>()..add(new Name(name, library)) | 519 compiler, |
| 530 ..add(new Name(name, library, isSetter: true))); | 520 cls, |
| 521 name, |
| 522 new Setlet<Name>() |
| 523 ..add(new Name(name, library)) |
| 524 ..add(new Name(name, library, isSetter: true))); |
| 531 } | 525 } |
| 532 | 526 |
| 533 static void _computeClassMember(Compiler compiler, | 527 static void _computeClassMember(Compiler compiler, ClassMemberMixin cls, |
| 534 ClassMemberMixin cls, | 528 String name, Setlet<Name> names) { |
| 535 String name, | |
| 536 Setlet<Name> names) { | |
| 537 cls.computeClassMember(compiler, name, names); | 529 cls.computeClassMember(compiler, name, names); |
| 538 } | 530 } |
| 539 | 531 |
| 540 /// Compute all class and interface names in [cls]. | 532 /// Compute all class and interface names in [cls]. |
| 541 static void computeAllClassMembers(Compiler compiler, ClassMemberMixin cls) { | 533 static void computeAllClassMembers(Compiler compiler, ClassMemberMixin cls) { |
| 542 cls.computeAllClassMembers(compiler); | 534 cls.computeAllClassMembers(compiler); |
| 543 } | 535 } |
| 544 } | 536 } |
| 545 | 537 |
| 546 /// Class member creator for classes where the interface members are known to | 538 /// Class member creator for classes where the interface members are known to |
| 547 /// be a subset of the class members. | 539 /// be a subset of the class members. |
| 548 class ClassMembersCreator extends MembersCreator { | 540 class ClassMembersCreator extends MembersCreator { |
| 549 ClassMembersCreator(Compiler compiler, | 541 ClassMembersCreator(Compiler compiler, ClassElement cls, |
| 550 ClassElement cls, | 542 Iterable<String> computedMemberNames, Map<Name, Member> classMembers) |
| 551 Iterable<String> computedMemberNames, | |
| 552 Map<Name, Member> classMembers) | |
| 553 : super(compiler, cls, computedMemberNames, classMembers); | 543 : super(compiler, cls, computedMemberNames, classMembers); |
| 554 | 544 |
| 555 Map<Name, Member> computeMembers(String name, Setlet<Name> names) { | 545 Map<Name, Member> computeMembers(String name, Setlet<Name> names) { |
| 556 computeSuperMembers(name, names); | 546 computeSuperMembers(name, names); |
| 557 return computeClassMembers(name, names); | 547 return computeClassMembers(name, names); |
| 558 } | 548 } |
| 559 | 549 |
| 560 void computeSuperMembers(String name, Setlet<Name> names) { | 550 void computeSuperMembers(String name, Setlet<Name> names) { |
| 561 computeSuperClassMembers(name, names); | 551 computeSuperClassMembers(name, names); |
| 562 } | 552 } |
| 563 | 553 |
| 564 void checkInterfaceImplementation() { | 554 void checkInterfaceImplementation() { |
| 565 LibraryElement library = cls.library; | 555 LibraryElement library = cls.library; |
| 566 classMembers.forEach((Name name, Member classMember) { | 556 classMembers.forEach((Name name, Member classMember) { |
| 567 if (!name.isAccessibleFrom(library)) return; | 557 if (!name.isAccessibleFrom(library)) return; |
| 568 checkInterfaceMember(name, classMember, classMember.implementation); | 558 checkInterfaceMember(name, classMember, classMember.implementation); |
| 569 }); | 559 }); |
| 570 } | 560 } |
| 571 } | 561 } |
| 572 | 562 |
| 573 /// Class Member creator for classes where the interface members might be | 563 /// Class Member creator for classes where the interface members might be |
| 574 /// different from the class members. | 564 /// different from the class members. |
| 575 class InterfaceMembersCreator extends MembersCreator { | 565 class InterfaceMembersCreator extends MembersCreator { |
| 576 final Map<Name, MemberSignature> interfaceMembers; | 566 final Map<Name, MemberSignature> interfaceMembers; |
| 577 | 567 |
| 578 InterfaceMembersCreator(Compiler compiler, | 568 InterfaceMembersCreator( |
| 579 ClassElement cls, | 569 Compiler compiler, |
| 580 Iterable<String> computedMemberNames, | 570 ClassElement cls, |
| 581 Map<Name, Member> classMembers, | 571 Iterable<String> computedMemberNames, |
| 582 Map<Name, MemberSignature> this.interfaceMembers) | 572 Map<Name, Member> classMembers, |
| 573 Map<Name, MemberSignature> this.interfaceMembers) |
| 583 : super(compiler, cls, computedMemberNames, classMembers); | 574 : super(compiler, cls, computedMemberNames, classMembers); |
| 584 | 575 |
| 585 Map<Name, Member> computeMembers(String name, Setlet<Name> names) { | 576 Map<Name, Member> computeMembers(String name, Setlet<Name> names) { |
| 586 Map<Name, Setlet<Member>> inheritedInterfaceMembers = | 577 Map<Name, Setlet<Member>> inheritedInterfaceMembers = |
| 587 computeSuperMembers(name, names); | 578 computeSuperMembers(name, names); |
| 588 Map<Name, Member> declaredMembers = computeClassMembers(name, names); | 579 Map<Name, Member> declaredMembers = computeClassMembers(name, names); |
| 589 computeInterfaceMembers(inheritedInterfaceMembers, declaredMembers); | 580 computeInterfaceMembers(inheritedInterfaceMembers, declaredMembers); |
| 590 return declaredMembers; | 581 return declaredMembers; |
| 591 } | 582 } |
| 592 | 583 |
| 593 /// Compute the members of the super type(s) of [cls]. The class members are | 584 /// Compute the members of the super type(s) of [cls]. The class members are |
| 594 /// stored if the [classMembers] map and the inherited interface members are | 585 /// stored if the [classMembers] map and the inherited interface members are |
| 595 /// returned. | 586 /// returned. |
| 596 /// | 587 /// |
| 597 /// If [name] and [names] are not null, the computation is restricted to | 588 /// If [name] and [names] are not null, the computation is restricted to |
| 598 /// members with these names. | 589 /// members with these names. |
| 599 Map<Name, Setlet<Member>> computeSuperMembers(String name, | 590 Map<Name, Setlet<Member>> computeSuperMembers( |
| 600 Setlet<Name> names) { | 591 String name, Setlet<Name> names) { |
| 601 computeSuperClassMembers(name, names); | 592 computeSuperClassMembers(name, names); |
| 602 return computeSuperInterfaceMembers(name, names); | 593 return computeSuperInterfaceMembers(name, names); |
| 603 } | 594 } |
| 604 | 595 |
| 605 Map<Name, Setlet<Member>> computeSuperInterfaceMembers(String name, | 596 Map<Name, Setlet<Member>> computeSuperInterfaceMembers( |
| 606 Setlet<Name> names) { | 597 String name, Setlet<Name> names) { |
| 607 | |
| 608 | |
| 609 InterfaceType supertype = cls.supertype; | 598 InterfaceType supertype = cls.supertype; |
| 610 assert(invariant(cls, supertype != null, | 599 assert(invariant(cls, supertype != null, |
| 611 message: "Interface members computed for $cls.")); | 600 message: "Interface members computed for $cls.")); |
| 612 ClassElement superclass = supertype.element; | 601 ClassElement superclass = supertype.element; |
| 613 | 602 |
| 614 Map<Name, Setlet<Member>> inheritedInterfaceMembers = | 603 Map<Name, Setlet<Member>> inheritedInterfaceMembers = |
| 615 new Map<Name, Setlet<Member>>(); | 604 new Map<Name, Setlet<Member>>(); |
| 616 | 605 |
| 617 void inheritInterfaceMember(InterfaceType supertype, | 606 void inheritInterfaceMember( |
| 618 MemberSignature member) { | 607 InterfaceType supertype, MemberSignature member) { |
| 619 if (shouldSkipMember(member)) return; | 608 if (shouldSkipMember(member)) return; |
| 620 Setlet<Member> members = | 609 Setlet<Member> members = inheritedInterfaceMembers.putIfAbsent( |
| 621 inheritedInterfaceMembers.putIfAbsent( | 610 member.name, () => new Setlet<Member>()); |
| 622 member.name, () => new Setlet<Member>()); | |
| 623 for (DeclaredMember declaredMember in member.declarations) { | 611 for (DeclaredMember declaredMember in member.declarations) { |
| 624 members.add(declaredMember.inheritFrom(supertype)); | 612 members.add(declaredMember.inheritFrom(supertype)); |
| 625 } | 613 } |
| 626 } | 614 } |
| 627 | 615 |
| 628 void inheritInterfaceMembers(InterfaceType supertype) { | 616 void inheritInterfaceMembers(InterfaceType supertype) { |
| 629 supertype.element.forEachInterfaceMember((MemberSignature member) { | 617 supertype.element.forEachInterfaceMember((MemberSignature member) { |
| 630 inheritInterfaceMember(supertype, member); | 618 inheritInterfaceMember(supertype, member); |
| 631 }); | 619 }); |
| 632 } | 620 } |
| 633 | 621 |
| 634 if (names != null) { | 622 if (names != null) { |
| 635 for (Name memberName in names) { | 623 for (Name memberName in names) { |
| 636 inheritInterfaceMember(supertype, | 624 inheritInterfaceMember( |
| 637 superclass.lookupInterfaceMember(memberName)); | 625 supertype, superclass.lookupInterfaceMember(memberName)); |
| 638 } | 626 } |
| 639 } else { | 627 } else { |
| 640 inheritInterfaceMembers(supertype); | 628 inheritInterfaceMembers(supertype); |
| 641 } | 629 } |
| 642 | 630 |
| 643 // Inherit interface members from superinterfaces. | 631 // Inherit interface members from superinterfaces. |
| 644 for (Link<DartType> link = cls.interfaces; | 632 for (Link<DartType> link = cls.interfaces; |
| 645 !link.isEmpty; | 633 !link.isEmpty; |
| 646 link = link.tail) { | 634 link = link.tail) { |
| 647 InterfaceType superinterface = link.head; | 635 InterfaceType superinterface = link.head; |
| 648 if (names != null) { | 636 if (names != null) { |
| 649 MembersCreator._computeClassMember( | 637 MembersCreator._computeClassMember( |
| 650 compiler, superinterface.element, name, names); | 638 compiler, superinterface.element, name, names); |
| 651 for (Name memberName in names) { | 639 for (Name memberName in names) { |
| 652 inheritInterfaceMember(superinterface, | 640 inheritInterfaceMember(superinterface, |
| 653 superinterface.element.lookupInterfaceMember(memberName)); | 641 superinterface.element.lookupInterfaceMember(memberName)); |
| 654 } | 642 } |
| 655 } else { | 643 } else { |
| 656 MembersCreator.computeAllClassMembers(compiler, superinterface.element); | 644 MembersCreator.computeAllClassMembers(compiler, superinterface.element); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 670 Member classMember = classMembers[name]; | 658 Member classMember = classMembers[name]; |
| 671 if (classMember != null) classMember = classMember.implementation; | 659 if (classMember != null) classMember = classMember.implementation; |
| 672 checkInterfaceMember(name, interfaceMember, classMember); | 660 checkInterfaceMember(name, interfaceMember, classMember); |
| 673 }); | 661 }); |
| 674 } | 662 } |
| 675 | 663 |
| 676 /// Compute the interface members of [cls] given the set of inherited | 664 /// Compute the interface members of [cls] given the set of inherited |
| 677 /// interface members [inheritedInterfaceMembers] and declared members | 665 /// interface members [inheritedInterfaceMembers] and declared members |
| 678 /// [declaredMembers]. The computed members are stored in [interfaceMembers]. | 666 /// [declaredMembers]. The computed members are stored in [interfaceMembers]. |
| 679 void computeInterfaceMembers( | 667 void computeInterfaceMembers( |
| 680 Map<Name, Setlet<Member>> inheritedInterfaceMembers, | 668 Map<Name, Setlet<Member>> inheritedInterfaceMembers, |
| 681 Map<Name, Member> declaredMembers) { | 669 Map<Name, Member> declaredMembers) { |
| 682 InterfaceType thisType = cls.thisType; | 670 InterfaceType thisType = cls.thisType; |
| 683 // Compute the interface members by overriding the inherited members with | 671 // Compute the interface members by overriding the inherited members with |
| 684 // a declared member or by computing a single, possibly synthesized, | 672 // a declared member or by computing a single, possibly synthesized, |
| 685 // inherited member. | 673 // inherited member. |
| 686 inheritedInterfaceMembers.forEach( | 674 inheritedInterfaceMembers |
| 687 (Name name, Setlet<Member> inheritedMembers) { | 675 .forEach((Name name, Setlet<Member> inheritedMembers) { |
| 688 Member declared = declaredMembers[name]; | 676 Member declared = declaredMembers[name]; |
| 689 if (declared != null) { | 677 if (declared != null) { |
| 690 // Check that [declaredMember] is a valid override | 678 // Check that [declaredMember] is a valid override |
| 691 for (Member inherited in inheritedMembers) { | 679 for (Member inherited in inheritedMembers) { |
| 692 checkValidOverride(declared, inherited); | 680 checkValidOverride(declared, inherited); |
| 693 } | 681 } |
| 694 if (!declared.isStatic) { | 682 if (!declared.isStatic) { |
| 695 interfaceMembers[name] = declared; | 683 interfaceMembers[name] = declared; |
| 696 } | 684 } |
| 697 } else if (inheritedMembers.length == 1) { | 685 } else if (inheritedMembers.length == 1) { |
| 698 interfaceMembers[name] = inheritedMembers.single; | 686 interfaceMembers[name] = inheritedMembers.single; |
| 699 } else { | 687 } else { |
| 700 bool someAreGetters = false; | 688 bool someAreGetters = false; |
| 701 bool allAreGetters = true; | 689 bool allAreGetters = true; |
| 702 Map<DartType, Setlet<Member>> subtypesOfAllInherited = | 690 Map<DartType, Setlet<Member>> subtypesOfAllInherited = |
| 703 new Map<DartType, Setlet<Member>>(); | 691 new Map<DartType, Setlet<Member>>(); |
| 704 outer: for (Member inherited in inheritedMembers) { | 692 outer: for (Member inherited in inheritedMembers) { |
| 705 if (inherited.isGetter) { | 693 if (inherited.isGetter) { |
| 706 someAreGetters = true; | 694 someAreGetters = true; |
| 707 if (!allAreGetters) break outer; | 695 if (!allAreGetters) break outer; |
| 708 } else { | 696 } else { |
| 709 allAreGetters = false; | 697 allAreGetters = false; |
| 710 if (someAreGetters) break outer; | 698 if (someAreGetters) break outer; |
| 711 } | 699 } |
| 712 for (MemberSignature other in inheritedMembers) { | 700 for (MemberSignature other in inheritedMembers) { |
| 713 if (!compiler.types.isSubtype(inherited.functionType, | 701 if (!compiler.types |
| 714 other.functionType)) { | 702 .isSubtype(inherited.functionType, other.functionType)) { |
| 715 continue outer; | 703 continue outer; |
| 716 } | 704 } |
| 717 } | 705 } |
| 718 subtypesOfAllInherited.putIfAbsent(inherited.functionType, | 706 subtypesOfAllInherited |
| 719 () => new Setlet<Member>()).add(inherited); | 707 .putIfAbsent(inherited.functionType, () => new Setlet<Member>()) |
| 708 .add(inherited); |
| 720 } | 709 } |
| 721 if (someAreGetters && !allAreGetters) { | 710 if (someAreGetters && !allAreGetters) { |
| 722 DiagnosticMessage warning = reporter.createMessage( | 711 DiagnosticMessage warning = reporter.createMessage( |
| 723 cls, | 712 cls, |
| 724 MessageKind.INHERIT_GETTER_AND_METHOD, | 713 MessageKind.INHERIT_GETTER_AND_METHOD, |
| 725 {'class': thisType, 'name': name.text }); | 714 {'class': thisType, 'name': name.text}); |
| 726 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; | 715 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; |
| 727 for (Member inherited in inheritedMembers) { | 716 for (Member inherited in inheritedMembers) { |
| 728 MessageKind kind; | 717 MessageKind kind; |
| 729 if (inherited.isMethod) { | 718 if (inherited.isMethod) { |
| 730 kind = MessageKind.INHERITED_METHOD; | 719 kind = MessageKind.INHERITED_METHOD; |
| 731 } else { | 720 } else { |
| 732 assert(invariant(cls, inherited.isGetter, | 721 assert(invariant(cls, inherited.isGetter, |
| 733 message: 'Conflicting member is neither a method nor a ' | 722 message: 'Conflicting member is neither a method nor a ' |
| 734 'getter.')); | 723 'getter.')); |
| 735 if (inherited.isDeclaredByField) { | 724 if (inherited.isDeclaredByField) { |
| 736 kind = MessageKind.INHERITED_IMPLICIT_GETTER; | 725 kind = MessageKind.INHERITED_IMPLICIT_GETTER; |
| 737 } else { | 726 } else { |
| 738 kind = MessageKind.INHERITED_EXPLICIT_GETTER; | 727 kind = MessageKind.INHERITED_EXPLICIT_GETTER; |
| 739 } | 728 } |
| 740 } | 729 } |
| 741 infos.add(reporter.createMessage( | 730 infos.add(reporter.createMessage(inherited.element, kind, |
| 742 inherited.element, | |
| 743 kind, | |
| 744 {'class': inherited.declarer, 'name': name.text})); | 731 {'class': inherited.declarer, 'name': name.text})); |
| 745 } | 732 } |
| 746 reporter.reportWarning(warning, infos); | 733 reporter.reportWarning(warning, infos); |
| 747 interfaceMembers[name] = new ErroneousMember(inheritedMembers); | 734 interfaceMembers[name] = new ErroneousMember(inheritedMembers); |
| 748 } else if (subtypesOfAllInherited.length == 1) { | 735 } else if (subtypesOfAllInherited.length == 1) { |
| 749 // All signatures have the same type. | 736 // All signatures have the same type. |
| 750 Setlet<Member> members = subtypesOfAllInherited.values.first; | 737 Setlet<Member> members = subtypesOfAllInherited.values.first; |
| 751 MemberSignature inherited = members.first; | 738 MemberSignature inherited = members.first; |
| 752 if (members.length != 1) { | 739 if (members.length != 1) { |
| 753 // Multiple signatures with the same type => return a | 740 // Multiple signatures with the same type => return a |
| (...skipping 10 matching lines...) Expand all Loading... |
| 764 | 751 |
| 765 // Add the non-overriding instance methods to the interface members. | 752 // Add the non-overriding instance methods to the interface members. |
| 766 declaredMembers.forEach((Name name, Member member) { | 753 declaredMembers.forEach((Name name, Member member) { |
| 767 if (!member.isStatic) { | 754 if (!member.isStatic) { |
| 768 interfaceMembers.putIfAbsent(name, () => member); | 755 interfaceMembers.putIfAbsent(name, () => member); |
| 769 } | 756 } |
| 770 }); | 757 }); |
| 771 } | 758 } |
| 772 | 759 |
| 773 /// Create and inherit a synthesized member for [inheritedMembers]. | 760 /// Create and inherit a synthesized member for [inheritedMembers]. |
| 774 void _inheritedSynthesizedMember(Name name, | 761 void _inheritedSynthesizedMember(Name name, Setlet<Member> inheritedMembers) { |
| 775 Setlet<Member> inheritedMembers) { | |
| 776 // Multiple signatures with different types => create the synthesized | 762 // Multiple signatures with different types => create the synthesized |
| 777 // version. | 763 // version. |
| 778 int minRequiredParameters; | 764 int minRequiredParameters; |
| 779 int maxPositionalParameters; | 765 int maxPositionalParameters; |
| 780 Set<String> names = new Set<String>(); | 766 Set<String> names = new Set<String>(); |
| 781 for (MemberSignature member in inheritedMembers) { | 767 for (MemberSignature member in inheritedMembers) { |
| 782 int requiredParameters = 0; | 768 int requiredParameters = 0; |
| 783 int optionalParameters = 0; | 769 int optionalParameters = 0; |
| 784 if (member.isSetter) { | 770 if (member.isSetter) { |
| 785 requiredParameters = 1; | 771 requiredParameters = 1; |
| 786 } | 772 } |
| 787 if (member.type.isFunctionType) { | 773 if (member.type.isFunctionType) { |
| 788 FunctionType type = member.type; | 774 FunctionType type = member.type; |
| 789 type.namedParameters.forEach( | 775 type.namedParameters.forEach((String name) => names.add(name)); |
| 790 (String name) => names.add(name)); | |
| 791 requiredParameters = type.parameterTypes.length; | 776 requiredParameters = type.parameterTypes.length; |
| 792 optionalParameters = type.optionalParameterTypes.length; | 777 optionalParameters = type.optionalParameterTypes.length; |
| 793 } | 778 } |
| 794 int positionalParameters = requiredParameters + optionalParameters; | 779 int positionalParameters = requiredParameters + optionalParameters; |
| 795 if (minRequiredParameters == null || | 780 if (minRequiredParameters == null || |
| 796 minRequiredParameters > requiredParameters) { | 781 minRequiredParameters > requiredParameters) { |
| 797 minRequiredParameters = requiredParameters; | 782 minRequiredParameters = requiredParameters; |
| 798 } | 783 } |
| 799 if (maxPositionalParameters == null || | 784 if (maxPositionalParameters == null || |
| 800 maxPositionalParameters < positionalParameters) { | 785 maxPositionalParameters < positionalParameters) { |
| 801 maxPositionalParameters = positionalParameters; | 786 maxPositionalParameters = positionalParameters; |
| 802 } | 787 } |
| 803 } | 788 } |
| 804 int optionalParameters = | 789 int optionalParameters = maxPositionalParameters - minRequiredParameters; |
| 805 maxPositionalParameters - minRequiredParameters; | |
| 806 // TODO(johnniwinther): Support function types with both optional | 790 // TODO(johnniwinther): Support function types with both optional |
| 807 // and named parameters? | 791 // and named parameters? |
| 808 if (optionalParameters == 0 || names.isEmpty) { | 792 if (optionalParameters == 0 || names.isEmpty) { |
| 809 DartType dynamic = const DynamicType(); | 793 DartType dynamic = const DynamicType(); |
| 810 List<DartType> requiredParameterTypes = | 794 List<DartType> requiredParameterTypes = |
| 811 new List.filled(minRequiredParameters, dynamic); | 795 new List.filled(minRequiredParameters, dynamic); |
| 812 List<DartType> optionalParameterTypes = | 796 List<DartType> optionalParameterTypes = |
| 813 new List.filled(optionalParameters, dynamic); | 797 new List.filled(optionalParameters, dynamic); |
| 814 List<String> namedParameters = | 798 List<String> namedParameters = names.toList() |
| 815 names.toList()..sort((a, b) => a.compareTo(b)); | 799 ..sort((a, b) => a.compareTo(b)); |
| 816 List<DartType> namedParameterTypes = | 800 List<DartType> namedParameterTypes = |
| 817 new List.filled(namedParameters.length, dynamic); | 801 new List.filled(namedParameters.length, dynamic); |
| 818 FunctionType memberType = new FunctionType.synthesized( | 802 FunctionType memberType = new FunctionType.synthesized( |
| 819 const DynamicType(), | 803 const DynamicType(), |
| 820 requiredParameterTypes, | 804 requiredParameterTypes, |
| 821 optionalParameterTypes, | 805 optionalParameterTypes, |
| 822 namedParameters, namedParameterTypes); | 806 namedParameters, |
| 807 namedParameterTypes); |
| 823 DartType type = memberType; | 808 DartType type = memberType; |
| 824 if (inheritedMembers.first.isGetter || | 809 if (inheritedMembers.first.isGetter || inheritedMembers.first.isSetter) { |
| 825 inheritedMembers.first.isSetter) { | |
| 826 type = const DynamicType(); | 810 type = const DynamicType(); |
| 827 } | 811 } |
| 828 interfaceMembers[name] = | 812 interfaceMembers[name] = |
| 829 new SyntheticMember(inheritedMembers, type, memberType); | 813 new SyntheticMember(inheritedMembers, type, memberType); |
| 830 } | 814 } |
| 831 } | 815 } |
| 832 } | 816 } |
| 833 | 817 |
| 834 abstract class ClassMemberMixin implements ClassElement { | 818 abstract class ClassMemberMixin implements ClassElement { |
| 835 /// When [classMembers] and [interfaceMembers] have not been fully computed | 819 /// When [classMembers] and [interfaceMembers] have not been fully computed |
| (...skipping 15 matching lines...) Expand all Loading... |
| 851 /// Creates the necessary maps and [MembersCreator] for compute members of | 835 /// Creates the necessary maps and [MembersCreator] for compute members of |
| 852 /// this class. | 836 /// this class. |
| 853 MembersCreator _prepareCreator(Compiler compiler) { | 837 MembersCreator _prepareCreator(Compiler compiler) { |
| 854 if (classMembers == null) { | 838 if (classMembers == null) { |
| 855 ensureResolved(compiler.resolution); | 839 ensureResolved(compiler.resolution); |
| 856 classMembers = new Map<Name, Member>(); | 840 classMembers = new Map<Name, Member>(); |
| 857 | 841 |
| 858 if (interfaceMembersAreClassMembers) { | 842 if (interfaceMembersAreClassMembers) { |
| 859 ClassMemberMixin superclass = this.superclass; | 843 ClassMemberMixin superclass = this.superclass; |
| 860 if ((superclass != null && | 844 if ((superclass != null && |
| 861 (!superclass.interfaceMembersAreClassMembers || | 845 (!superclass.interfaceMembersAreClassMembers || |
| 862 superclass.isMixinApplication)) || | 846 superclass.isMixinApplication)) || |
| 863 !interfaces.isEmpty) { | 847 !interfaces.isEmpty) { |
| 864 interfaceMembersAreClassMembers = false; | 848 interfaceMembersAreClassMembers = false; |
| 865 } | 849 } |
| 866 } | 850 } |
| 867 if (!interfaceMembersAreClassMembers) { | 851 if (!interfaceMembersAreClassMembers) { |
| 868 interfaceMembers = new Map<Name, MemberSignature>(); | 852 interfaceMembers = new Map<Name, MemberSignature>(); |
| 869 } | 853 } |
| 870 } | 854 } |
| 871 return interfaceMembersAreClassMembers | 855 return interfaceMembersAreClassMembers |
| 872 ? new ClassMembersCreator(compiler, this, | 856 ? new ClassMembersCreator( |
| 873 computedMemberNames, classMembers) | 857 compiler, this, computedMemberNames, classMembers) |
| 874 : new InterfaceMembersCreator(compiler, this, | 858 : new InterfaceMembersCreator(compiler, this, computedMemberNames, |
| 875 computedMemberNames, classMembers, interfaceMembers); | 859 classMembers, interfaceMembers); |
| 876 } | 860 } |
| 877 | 861 |
| 878 static Iterable<String> _EMPTY_MEMBERS_NAMES = const <String>[]; | 862 static Iterable<String> _EMPTY_MEMBERS_NAMES = const <String>[]; |
| 879 | 863 |
| 880 /// Compute the members by the name [name] for this class. [names] collects | 864 /// Compute the members by the name [name] for this class. [names] collects |
| 881 /// the set of possible variations of [name], including getter, setter and | 865 /// the set of possible variations of [name], including getter, setter and |
| 882 /// and private names. | 866 /// and private names. |
| 883 void computeClassMember(Compiler compiler, String name, Setlet<Name> names) { | 867 void computeClassMember(Compiler compiler, String name, Setlet<Name> names) { |
| 884 if (isMemberComputed(name)) return; | 868 if (isMemberComputed(name)) return; |
| 885 if (Name.isPrivateName(name)) { | 869 if (Name.isPrivateName(name)) { |
| 886 names..add(new Name(name, library)) | 870 names |
| 887 ..add(new Name(name, library, isSetter: true)); | 871 ..add(new Name(name, library)) |
| 872 ..add(new Name(name, library, isSetter: true)); |
| 888 } | 873 } |
| 889 MembersCreator creator = _prepareCreator(compiler); | 874 MembersCreator creator = _prepareCreator(compiler); |
| 890 creator.computeMembersByName(name, names); | 875 creator.computeMembersByName(name, names); |
| 891 if (computedMemberNames == null) { | 876 if (computedMemberNames == null) { |
| 892 computedMemberNames = _EMPTY_MEMBERS_NAMES; | 877 computedMemberNames = _EMPTY_MEMBERS_NAMES; |
| 893 } | 878 } |
| 894 if (name != Identifiers.call) { | 879 if (name != Identifiers.call) { |
| 895 Setlet<String> set; | 880 Setlet<String> set; |
| 896 if (identical(computedMemberNames, _EMPTY_MEMBERS_NAMES)) { | 881 if (identical(computedMemberNames, _EMPTY_MEMBERS_NAMES)) { |
| 897 computedMemberNames = set = new Setlet<String>(); | 882 computedMemberNames = set = new Setlet<String>(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 911 } | 896 } |
| 912 | 897 |
| 913 bool areAllMembersComputed() { | 898 bool areAllMembersComputed() { |
| 914 return computedMemberNames == null && classMembers != null; | 899 return computedMemberNames == null && classMembers != null; |
| 915 } | 900 } |
| 916 | 901 |
| 917 bool isMemberComputed(String name) { | 902 bool isMemberComputed(String name) { |
| 918 if (computedMemberNames == null) { | 903 if (computedMemberNames == null) { |
| 919 return classMembers != null; | 904 return classMembers != null; |
| 920 } else { | 905 } else { |
| 921 return name == Identifiers.call || | 906 return name == Identifiers.call || computedMemberNames.contains(name); |
| 922 computedMemberNames.contains(name); | |
| 923 } | 907 } |
| 924 } | 908 } |
| 925 | 909 |
| 926 Member lookupClassMember(Name name) { | 910 Member lookupClassMember(Name name) { |
| 927 assert(invariant(this, | 911 assert(invariant(this, isMemberComputed(name.text), |
| 928 isMemberComputed(name.text), | |
| 929 message: "Member ${name} has not been computed for $this.")); | 912 message: "Member ${name} has not been computed for $this.")); |
| 930 return classMembers[name]; | 913 return classMembers[name]; |
| 931 } | 914 } |
| 932 | 915 |
| 933 void forEachClassMember(f(Member member)) { | 916 void forEachClassMember(f(Member member)) { |
| 934 assert(invariant(this, areAllMembersComputed(), | 917 assert(invariant(this, areAllMembersComputed(), |
| 935 message: "Members have not been fully computed for $this.")); | 918 message: "Members have not been fully computed for $this.")); |
| 936 classMembers.forEach((_, member) => f(member)); | 919 classMembers.forEach((_, member) => f(member)); |
| 937 } | 920 } |
| 938 | 921 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 952 message: "Members have not been fully computed for $this.")); | 935 message: "Members have not been fully computed for $this.")); |
| 953 if (interfaceMembersAreClassMembers) { | 936 if (interfaceMembersAreClassMembers) { |
| 954 classMembers.forEach((_, member) { | 937 classMembers.forEach((_, member) { |
| 955 if (!member.isStatic) f(member); | 938 if (!member.isStatic) f(member); |
| 956 }); | 939 }); |
| 957 } else { | 940 } else { |
| 958 interfaceMembers.forEach((_, member) => f(member)); | 941 interfaceMembers.forEach((_, member) => f(member)); |
| 959 } | 942 } |
| 960 } | 943 } |
| 961 } | 944 } |
| OLD | NEW |