OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart2js.resolution.compute_members; | 5 library dart2js.resolution.compute_members; |
6 | 6 |
7 import '../common/names.dart' show | 7 import '../common/names.dart' show |
8 Identifiers; | 8 Identifiers; |
9 import '../compiler.dart' show | 9 import '../compiler.dart' show |
10 Compiler; | 10 Compiler; |
11 import '../dart_types.dart'; | 11 import '../dart_types.dart'; |
| 12 import '../diagnostics/diagnostic_listener.dart' show |
| 13 DiagnosticMessage; |
12 import '../diagnostics/invariant.dart' show | 14 import '../diagnostics/invariant.dart' show |
13 invariant; | 15 invariant; |
14 import '../diagnostics/messages.dart' show | 16 import '../diagnostics/messages.dart' show |
15 MessageKind; | 17 MessageKind; |
16 import '../elements/elements.dart' show | 18 import '../elements/elements.dart' show |
17 ClassElement, | 19 ClassElement, |
18 Element, | 20 Element, |
19 LibraryElement, | 21 LibraryElement, |
20 Member, | 22 Member, |
21 MemberElement, | 23 MemberElement, |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 interfaceMember.declarer.element == cls) { | 249 interfaceMember.declarer.element == cls) { |
248 // Abstract method declared in [cls]. | 250 // Abstract method declared in [cls]. |
249 MessageKind kind = MessageKind.ABSTRACT_METHOD; | 251 MessageKind kind = MessageKind.ABSTRACT_METHOD; |
250 if (interfaceMember.isSetter) { | 252 if (interfaceMember.isSetter) { |
251 kind = MessageKind.ABSTRACT_SETTER; | 253 kind = MessageKind.ABSTRACT_SETTER; |
252 } else if (interfaceMember.isGetter) { | 254 } else if (interfaceMember.isGetter) { |
253 kind = MessageKind.ABSTRACT_GETTER; | 255 kind = MessageKind.ABSTRACT_GETTER; |
254 } | 256 } |
255 reportMessage( | 257 reportMessage( |
256 interfaceMember.element, MessageKind.ABSTRACT_METHOD, () { | 258 interfaceMember.element, MessageKind.ABSTRACT_METHOD, () { |
257 compiler.reportWarning( | 259 compiler.reportWarningMessage( |
258 interfaceMember.element, kind, | 260 interfaceMember.element, kind, |
259 {'class': cls.name, 'name': name.text}); | 261 {'class': cls.name, 'name': name.text}); |
260 }); | 262 }); |
261 } else { | 263 } else { |
262 reportWarning(MessageKind singleKind, | 264 reportWarning(MessageKind singleKind, |
263 MessageKind multipleKind, | 265 MessageKind multipleKind, |
264 MessageKind explicitlyDeclaredKind, | 266 MessageKind explicitlyDeclaredKind, |
265 [MessageKind implicitlyDeclaredKind]) { | 267 [MessageKind implicitlyDeclaredKind]) { |
266 Member inherited = interfaceMember.declarations.first; | 268 Member inherited = interfaceMember.declarations.first; |
267 reportMessage( | 269 reportMessage( |
268 interfaceMember, MessageKind.UNIMPLEMENTED_METHOD, () { | 270 interfaceMember, MessageKind.UNIMPLEMENTED_METHOD, () { |
269 compiler.reportWarning(cls, | 271 DiagnosticMessage warning = compiler.createMessage( |
| 272 cls, |
270 interfaceMember.declarations.length == 1 | 273 interfaceMember.declarations.length == 1 |
271 ? singleKind : multipleKind, | 274 ? singleKind : multipleKind, |
272 {'class': cls.name, | 275 {'class': cls.name, |
273 'name': name.text, | 276 'name': name.text, |
274 'method': interfaceMember, | 277 'method': interfaceMember, |
275 'declarer': inherited.declarer}); | 278 'declarer': inherited.declarer}); |
| 279 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; |
276 for (Member inherited in interfaceMember.declarations) { | 280 for (Member inherited in interfaceMember.declarations) { |
277 compiler.reportInfo(inherited.element, | 281 infos.add(compiler.createMessage( |
| 282 inherited.element, |
278 inherited.isDeclaredByField ? | 283 inherited.isDeclaredByField ? |
279 implicitlyDeclaredKind : explicitlyDeclaredKind, | 284 implicitlyDeclaredKind : explicitlyDeclaredKind, |
280 {'class': inherited.declarer.name, | 285 {'class': inherited.declarer.name, |
281 'name': name.text}); | 286 'name': name.text})); |
282 } | 287 } |
| 288 compiler.reportWarning(warning, infos); |
283 }); | 289 }); |
284 } | 290 } |
285 if (interfaceMember.isSetter) { | 291 if (interfaceMember.isSetter) { |
286 reportWarning(MessageKind.UNIMPLEMENTED_SETTER_ONE, | 292 reportWarning(MessageKind.UNIMPLEMENTED_SETTER_ONE, |
287 MessageKind.UNIMPLEMENTED_SETTER, | 293 MessageKind.UNIMPLEMENTED_SETTER, |
288 MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER, | 294 MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER, |
289 MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER); | 295 MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER); |
290 } else if (interfaceMember.isGetter) { | 296 } else if (interfaceMember.isGetter) { |
291 reportWarning(MessageKind.UNIMPLEMENTED_GETTER_ONE, | 297 reportWarning(MessageKind.UNIMPLEMENTED_GETTER_ONE, |
292 MessageKind.UNIMPLEMENTED_GETTER, | 298 MessageKind.UNIMPLEMENTED_GETTER, |
(...skipping 14 matching lines...) Expand all Loading... |
307 void checkImplementsFunctionWithCall() { | 313 void checkImplementsFunctionWithCall() { |
308 assert(!cls.isAbstract); | 314 assert(!cls.isAbstract); |
309 | 315 |
310 if (cls.asInstanceOf(compiler.functionClass) == null) return; | 316 if (cls.asInstanceOf(compiler.functionClass) == null) return; |
311 if (cls.lookupMember(Identifiers.call) != null) return; | 317 if (cls.lookupMember(Identifiers.call) != null) return; |
312 // TODO(johnniwinther): Make separate methods for backend exceptions. | 318 // TODO(johnniwinther): Make separate methods for backend exceptions. |
313 // Avoid warnings on backend implementation classes for closures. | 319 // Avoid warnings on backend implementation classes for closures. |
314 if (compiler.backend.isBackendLibrary(cls.library)) return; | 320 if (compiler.backend.isBackendLibrary(cls.library)) return; |
315 | 321 |
316 reportMessage(compiler.functionClass, MessageKind.UNIMPLEMENTED_METHOD, () { | 322 reportMessage(compiler.functionClass, MessageKind.UNIMPLEMENTED_METHOD, () { |
317 compiler.reportWarning(cls, MessageKind.UNIMPLEMENTED_METHOD_ONE, | 323 compiler.reportWarningMessage( |
| 324 cls, |
| 325 MessageKind.UNIMPLEMENTED_METHOD_ONE, |
318 {'class': cls.name, | 326 {'class': cls.name, |
319 'name': Identifiers.call, | 327 'name': Identifiers.call, |
320 'method': Identifiers.call, | 328 'method': Identifiers.call, |
321 'declarer': compiler.functionClass.name}); | 329 'declarer': compiler.functionClass.name}); |
322 }); | 330 }); |
323 } | 331 } |
324 | 332 |
325 /// Checks that a class member exists for every interface member. | 333 /// Checks that a class member exists for every interface member. |
326 void checkInterfaceImplementation(); | 334 void checkInterfaceImplementation(); |
327 | 335 |
328 /// Check that [declared] is a valid override of [superMember]. | 336 /// Check that [declared] is a valid override of [superMember]. |
329 void checkValidOverride(Member declared, MemberSignature superMember) { | 337 void checkValidOverride(Member declared, MemberSignature superMember) { |
330 if (superMember == null) { | 338 if (superMember == null) { |
331 // No override. | 339 // No override. |
332 if (!declared.isStatic) { | 340 if (!declared.isStatic) { |
333 ClassElement superclass = cls.superclass; | 341 ClassElement superclass = cls.superclass; |
334 while (superclass != null) { | 342 while (superclass != null) { |
335 Member superMember = | 343 Member superMember = |
336 superclass.lookupClassMember(declared.name); | 344 superclass.lookupClassMember(declared.name); |
337 if (superMember != null && superMember.isStatic) { | 345 if (superMember != null && superMember.isStatic) { |
338 reportMessage(superMember, MessageKind.INSTANCE_STATIC_SAME_NAME, | 346 reportMessage(superMember, MessageKind.INSTANCE_STATIC_SAME_NAME, |
339 () { | 347 () { |
340 compiler.reportWarning( | 348 compiler.reportWarning( |
341 declared.element, | 349 compiler.createMessage( |
342 MessageKind.INSTANCE_STATIC_SAME_NAME, | 350 declared.element, |
343 {'memberName': declared.name, | 351 MessageKind.INSTANCE_STATIC_SAME_NAME, |
344 'className': superclass.name}); | 352 {'memberName': declared.name, |
345 compiler.reportInfo(superMember.element, | 353 'className': superclass.name}), |
346 MessageKind.INSTANCE_STATIC_SAME_NAME_CONT); | 354 <DiagnosticMessage>[ |
| 355 compiler.createMessage( |
| 356 superMember.element, |
| 357 MessageKind.INSTANCE_STATIC_SAME_NAME_CONT), |
| 358 ]); |
| 359 |
347 }); | 360 }); |
348 break; | 361 break; |
349 } | 362 } |
350 superclass = superclass.superclass; | 363 superclass = superclass.superclass; |
351 } | 364 } |
352 } | 365 } |
353 } else { | 366 } else { |
354 assert(declared.name == superMember.name); | 367 assert(declared.name == superMember.name); |
355 | 368 |
356 if (declared.isStatic) { | 369 if (declared.isStatic) { |
(...skipping 22 matching lines...) Expand all Loading... |
379 // An error should already have been reported. | 392 // An error should already have been reported. |
380 assert(invariant(declared.element, compiler.compilationFailed, | 393 assert(invariant(declared.element, compiler.compilationFailed, |
381 message: "Member $inherited inherited from its " | 394 message: "Member $inherited inherited from its " |
382 "declaring class: ${cls}.")); | 395 "declaring class: ${cls}.")); |
383 continue; | 396 continue; |
384 } | 397 } |
385 | 398 |
386 void reportError(MessageKind errorKind, MessageKind infoKind) { | 399 void reportError(MessageKind errorKind, MessageKind infoKind) { |
387 reportMessage( | 400 reportMessage( |
388 inherited.element, MessageKind.INVALID_OVERRIDE_METHOD, () { | 401 inherited.element, MessageKind.INVALID_OVERRIDE_METHOD, () { |
389 compiler.reportError(declared.element, errorKind, | 402 compiler.reportError( |
390 {'name': declared.name.text, | 403 compiler.createMessage( |
391 'class': cls.thisType, | 404 declared.element, |
392 'inheritedClass': inherited.declarer}); | 405 errorKind, |
393 compiler.reportInfo(inherited.element, infoKind, | 406 {'name': declared.name.text, |
394 {'name': declared.name.text, | 407 'class': cls.thisType, |
395 'class': inherited.declarer}); | 408 'inheritedClass': inherited.declarer}), |
| 409 <DiagnosticMessage>[ |
| 410 compiler.createMessage( |
| 411 inherited.element, |
| 412 infoKind, |
| 413 {'name': declared.name.text, |
| 414 'class': inherited.declarer}), |
| 415 ]); |
396 }); | 416 }); |
397 } | 417 } |
398 | 418 |
399 if (declared.isDeclaredByField && inherited.isMethod) { | 419 if (declared.isDeclaredByField && inherited.isMethod) { |
400 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD, | 420 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD, |
401 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT); | 421 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT); |
402 } else if (declared.isMethod && inherited.isDeclaredByField) { | 422 } else if (declared.isMethod && inherited.isDeclaredByField) { |
403 reportError(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD, | 423 reportError(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD, |
404 MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT); | 424 MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT); |
405 } else if (declared.isGetter && inherited.isMethod) { | 425 } else if (declared.isGetter && inherited.isMethod) { |
406 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER, | 426 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER, |
407 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT); | 427 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT); |
408 } else if (declared.isMethod && inherited.isGetter) { | 428 } else if (declared.isMethod && inherited.isGetter) { |
409 reportError(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD, | 429 reportError(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD, |
410 MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT); | 430 MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT); |
411 } else { | 431 } else { |
412 DartType inheritedType = inherited.functionType; | 432 DartType inheritedType = inherited.functionType; |
413 if (!compiler.types.isSubtype(declaredType, inheritedType)) { | 433 if (!compiler.types.isSubtype(declaredType, inheritedType)) { |
414 void reportWarning(var marker, | 434 void reportWarning(var marker, |
415 MessageKind warningKind, | 435 MessageKind warningKind, |
416 MessageKind infoKind) { | 436 MessageKind infoKind) { |
417 reportMessage(marker, MessageKind.INVALID_OVERRIDE_METHOD, () { | 437 reportMessage(marker, MessageKind.INVALID_OVERRIDE_METHOD, () { |
418 compiler.reportWarning(declared.element, warningKind, | 438 compiler.reportWarning( |
419 {'declaredType': declared.type, | 439 compiler.createMessage( |
420 'name': declared.name.text, | 440 declared.element, |
421 'class': cls.thisType, | 441 warningKind, |
422 'inheritedType': inherited.type, | 442 {'declaredType': declared.type, |
423 'inheritedClass': inherited.declarer}); | 443 'name': declared.name.text, |
424 compiler.reportInfo(inherited.element, infoKind, | 444 'class': cls.thisType, |
425 {'name': declared.name.text, | 445 'inheritedType': inherited.type, |
426 'class': inherited.declarer}); | 446 'inheritedClass': inherited.declarer}), |
| 447 <DiagnosticMessage>[ |
| 448 compiler.createMessage( |
| 449 inherited.element, |
| 450 infoKind, |
| 451 {'name': declared.name.text, |
| 452 'class': inherited.declarer}), |
| 453 ]); |
427 }); | 454 }); |
428 } | 455 } |
429 if (declared.isDeclaredByField) { | 456 if (declared.isDeclaredByField) { |
430 if (inherited.isDeclaredByField) { | 457 if (inherited.isDeclaredByField) { |
431 reportWarning(inherited.element, | 458 reportWarning(inherited.element, |
432 MessageKind.INVALID_OVERRIDE_FIELD, | 459 MessageKind.INVALID_OVERRIDE_FIELD, |
433 MessageKind.INVALID_OVERRIDDEN_FIELD); | 460 MessageKind.INVALID_OVERRIDDEN_FIELD); |
434 } else if (inherited.isGetter) { | 461 } else if (inherited.isGetter) { |
435 reportWarning(inherited, | 462 reportWarning(inherited, |
436 MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD, | 463 MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 } | 496 } |
470 } | 497 } |
471 } | 498 } |
472 } | 499 } |
473 | 500 |
474 void reportErrorWithContext(Element errorneousElement, | 501 void reportErrorWithContext(Element errorneousElement, |
475 MessageKind errorMessage, | 502 MessageKind errorMessage, |
476 Element contextElement, | 503 Element contextElement, |
477 MessageKind contextMessage) { | 504 MessageKind contextMessage) { |
478 compiler.reportError( | 505 compiler.reportError( |
479 errorneousElement, | 506 compiler.createMessage( |
480 errorMessage, | 507 errorneousElement, |
481 {'memberName': contextElement.name, | 508 errorMessage, |
482 'className': contextElement.enclosingClass.name}); | 509 {'memberName': contextElement.name, |
483 compiler.reportInfo(contextElement, contextMessage); | 510 'className': contextElement.enclosingClass.name}), |
| 511 <DiagnosticMessage>[ |
| 512 compiler.createMessage(contextElement, contextMessage), |
| 513 ]); |
484 } | 514 } |
485 | 515 |
486 /// Compute all class and interface names by the [name] in [cls]. | 516 /// Compute all class and interface names by the [name] in [cls]. |
487 static void computeClassMembersByName(Compiler compiler, | 517 static void computeClassMembersByName(Compiler compiler, |
488 ClassMemberMixin cls, | 518 ClassMemberMixin cls, |
489 String name) { | 519 String name) { |
490 if (cls.isMemberComputed(name)) return; | 520 if (cls.isMemberComputed(name)) return; |
491 LibraryElement library = cls.library; | 521 LibraryElement library = cls.library; |
492 _computeClassMember(compiler, cls, name, | 522 _computeClassMember(compiler, cls, name, |
493 new Setlet<Name>()..add(new Name(name, library)) | 523 new Setlet<Name>()..add(new Name(name, library)) |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 for (MemberSignature other in inheritedMembers) { | 706 for (MemberSignature other in inheritedMembers) { |
677 if (!compiler.types.isSubtype(inherited.functionType, | 707 if (!compiler.types.isSubtype(inherited.functionType, |
678 other.functionType)) { | 708 other.functionType)) { |
679 continue outer; | 709 continue outer; |
680 } | 710 } |
681 } | 711 } |
682 subtypesOfAllInherited.putIfAbsent(inherited.functionType, | 712 subtypesOfAllInherited.putIfAbsent(inherited.functionType, |
683 () => new Setlet<Member>()).add(inherited); | 713 () => new Setlet<Member>()).add(inherited); |
684 } | 714 } |
685 if (someAreGetters && !allAreGetters) { | 715 if (someAreGetters && !allAreGetters) { |
686 compiler.reportWarning(cls, | 716 DiagnosticMessage warning = compiler.createMessage( |
687 MessageKind.INHERIT_GETTER_AND_METHOD, | 717 cls, |
688 {'class': thisType, 'name': name.text }); | 718 MessageKind.INHERIT_GETTER_AND_METHOD, |
| 719 {'class': thisType, 'name': name.text }); |
| 720 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; |
689 for (Member inherited in inheritedMembers) { | 721 for (Member inherited in inheritedMembers) { |
690 MessageKind kind; | 722 MessageKind kind; |
691 if (inherited.isMethod) { | 723 if (inherited.isMethod) { |
692 kind = MessageKind.INHERITED_METHOD; | 724 kind = MessageKind.INHERITED_METHOD; |
693 } else { | 725 } else { |
694 assert(invariant(cls, inherited.isGetter, | 726 assert(invariant(cls, inherited.isGetter, |
695 message: 'Conflicting member is neither a method nor a ' | 727 message: 'Conflicting member is neither a method nor a ' |
696 'getter.')); | 728 'getter.')); |
697 if (inherited.isDeclaredByField) { | 729 if (inherited.isDeclaredByField) { |
698 kind = MessageKind.INHERITED_IMPLICIT_GETTER; | 730 kind = MessageKind.INHERITED_IMPLICIT_GETTER; |
699 } else { | 731 } else { |
700 kind = MessageKind.INHERITED_EXPLICIT_GETTER; | 732 kind = MessageKind.INHERITED_EXPLICIT_GETTER; |
701 } | 733 } |
702 } | 734 } |
703 compiler.reportInfo(inherited.element, kind, | 735 infos.add(compiler.createMessage( |
704 {'class': inherited.declarer, 'name': name.text }); | 736 inherited.element, |
| 737 kind, |
| 738 {'class': inherited.declarer, 'name': name.text})); |
705 } | 739 } |
| 740 compiler.reportWarning(warning, infos); |
706 interfaceMembers[name] = new ErroneousMember(inheritedMembers); | 741 interfaceMembers[name] = new ErroneousMember(inheritedMembers); |
707 } else if (subtypesOfAllInherited.length == 1) { | 742 } else if (subtypesOfAllInherited.length == 1) { |
708 // All signatures have the same type. | 743 // All signatures have the same type. |
709 Setlet<Member> members = subtypesOfAllInherited.values.first; | 744 Setlet<Member> members = subtypesOfAllInherited.values.first; |
710 MemberSignature inherited = members.first; | 745 MemberSignature inherited = members.first; |
711 if (members.length != 1) { | 746 if (members.length != 1) { |
712 // Multiple signatures with the same type => return a | 747 // Multiple signatures with the same type => return a |
713 // synthesized signature. | 748 // synthesized signature. |
714 inherited = new SyntheticMember( | 749 inherited = new SyntheticMember( |
715 members, inherited.type, inherited.functionType); | 750 members, inherited.type, inherited.functionType); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
910 message: "Members have not been fully computed for $this.")); | 945 message: "Members have not been fully computed for $this.")); |
911 if (interfaceMembersAreClassMembers) { | 946 if (interfaceMembersAreClassMembers) { |
912 classMembers.forEach((_, member) { | 947 classMembers.forEach((_, member) { |
913 if (!member.isStatic) f(member); | 948 if (!member.isStatic) f(member); |
914 }); | 949 }); |
915 } else { | 950 } else { |
916 interfaceMembers.forEach((_, member) => f(member)); | 951 interfaceMembers.forEach((_, member) => f(member)); |
917 } | 952 } |
918 } | 953 } |
919 } | 954 } |
OLD | NEW |