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 '../common/resolution.dart' show | 9 import '../common/resolution.dart' show |
10 Resolution; | 10 Resolution; |
11 import '../compiler.dart' show | 11 import '../compiler.dart' show |
12 Compiler; | 12 Compiler; |
13 import '../dart_types.dart'; | 13 import '../dart_types.dart'; |
14 import '../diagnostics/diagnostic_listener.dart' show | 14 import '../diagnostics/diagnostic_listener.dart' show |
15 DiagnosticMessage; | 15 DiagnosticMessage, |
| 16 DiagnosticReporter; |
16 import '../diagnostics/invariant.dart' show | 17 import '../diagnostics/invariant.dart' show |
17 invariant; | 18 invariant; |
18 import '../diagnostics/messages.dart' show | 19 import '../diagnostics/messages.dart' show |
19 MessageKind; | 20 MessageKind; |
20 import '../elements/elements.dart' show | 21 import '../elements/elements.dart' show |
21 ClassElement, | 22 ClassElement, |
22 Element, | 23 Element, |
23 LibraryElement, | 24 LibraryElement, |
24 Member, | 25 Member, |
25 MemberElement, | 26 MemberElement, |
(...skipping 16 matching lines...) Expand all Loading... |
42 new Map<dynamic, Set<MessageKind>>(); | 43 new Map<dynamic, Set<MessageKind>>(); |
43 | 44 |
44 MembersCreator(Compiler this.compiler, | 45 MembersCreator(Compiler this.compiler, |
45 ClassElement this.cls, | 46 ClassElement this.cls, |
46 Iterable<String> this.computedMemberNames, | 47 Iterable<String> this.computedMemberNames, |
47 Map<Name, Member> this.classMembers) { | 48 Map<Name, Member> this.classMembers) { |
48 assert(invariant(cls, cls.isDeclaration, | 49 assert(invariant(cls, cls.isDeclaration, |
49 message: "Members may only be computed on declarations.")); | 50 message: "Members may only be computed on declarations.")); |
50 } | 51 } |
51 | 52 |
| 53 DiagnosticReporter get reporter => compiler.reporter; |
| 54 |
52 Resolution get resolution => compiler.resolution; | 55 Resolution get resolution => compiler.resolution; |
53 | 56 |
54 void reportMessage(var marker, MessageKind kind, report()) { | 57 void reportMessage(var marker, MessageKind kind, report()) { |
55 Set<MessageKind> messages = | 58 Set<MessageKind> messages = |
56 reportedMessages.putIfAbsent(marker, | 59 reportedMessages.putIfAbsent(marker, |
57 () => new Set<MessageKind>()); | 60 () => new Set<MessageKind>()); |
58 if (messages.add(kind)) { | 61 if (messages.add(kind)) { |
59 report(); | 62 report(); |
60 } | 63 } |
61 } | 64 } |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 interfaceMember.declarer.element == cls) { | 256 interfaceMember.declarer.element == cls) { |
254 // Abstract method declared in [cls]. | 257 // Abstract method declared in [cls]. |
255 MessageKind kind = MessageKind.ABSTRACT_METHOD; | 258 MessageKind kind = MessageKind.ABSTRACT_METHOD; |
256 if (interfaceMember.isSetter) { | 259 if (interfaceMember.isSetter) { |
257 kind = MessageKind.ABSTRACT_SETTER; | 260 kind = MessageKind.ABSTRACT_SETTER; |
258 } else if (interfaceMember.isGetter) { | 261 } else if (interfaceMember.isGetter) { |
259 kind = MessageKind.ABSTRACT_GETTER; | 262 kind = MessageKind.ABSTRACT_GETTER; |
260 } | 263 } |
261 reportMessage( | 264 reportMessage( |
262 interfaceMember.element, MessageKind.ABSTRACT_METHOD, () { | 265 interfaceMember.element, MessageKind.ABSTRACT_METHOD, () { |
263 compiler.reportWarningMessage( | 266 reporter.reportWarningMessage( |
264 interfaceMember.element, kind, | 267 interfaceMember.element, kind, |
265 {'class': cls.name, 'name': name.text}); | 268 {'class': cls.name, 'name': name.text}); |
266 }); | 269 }); |
267 } else { | 270 } else { |
268 reportWarning(MessageKind singleKind, | 271 reportWarning(MessageKind singleKind, |
269 MessageKind multipleKind, | 272 MessageKind multipleKind, |
270 MessageKind explicitlyDeclaredKind, | 273 MessageKind explicitlyDeclaredKind, |
271 [MessageKind implicitlyDeclaredKind]) { | 274 [MessageKind implicitlyDeclaredKind]) { |
272 Member inherited = interfaceMember.declarations.first; | 275 Member inherited = interfaceMember.declarations.first; |
273 reportMessage( | 276 reportMessage( |
274 interfaceMember, MessageKind.UNIMPLEMENTED_METHOD, () { | 277 interfaceMember, MessageKind.UNIMPLEMENTED_METHOD, () { |
275 DiagnosticMessage warning = compiler.createMessage( | 278 DiagnosticMessage warning = reporter.createMessage( |
276 cls, | 279 cls, |
277 interfaceMember.declarations.length == 1 | 280 interfaceMember.declarations.length == 1 |
278 ? singleKind : multipleKind, | 281 ? singleKind : multipleKind, |
279 {'class': cls.name, | 282 {'class': cls.name, |
280 'name': name.text, | 283 'name': name.text, |
281 'method': interfaceMember, | 284 'method': interfaceMember, |
282 'declarer': inherited.declarer}); | 285 'declarer': inherited.declarer}); |
283 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; | 286 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; |
284 for (Member inherited in interfaceMember.declarations) { | 287 for (Member inherited in interfaceMember.declarations) { |
285 infos.add(compiler.createMessage( | 288 infos.add(reporter.createMessage( |
286 inherited.element, | 289 inherited.element, |
287 inherited.isDeclaredByField ? | 290 inherited.isDeclaredByField ? |
288 implicitlyDeclaredKind : explicitlyDeclaredKind, | 291 implicitlyDeclaredKind : explicitlyDeclaredKind, |
289 {'class': inherited.declarer.name, | 292 {'class': inherited.declarer.name, |
290 'name': name.text})); | 293 'name': name.text})); |
291 } | 294 } |
292 compiler.reportWarning(warning, infos); | 295 reporter.reportWarning(warning, infos); |
293 }); | 296 }); |
294 } | 297 } |
295 if (interfaceMember.isSetter) { | 298 if (interfaceMember.isSetter) { |
296 reportWarning(MessageKind.UNIMPLEMENTED_SETTER_ONE, | 299 reportWarning(MessageKind.UNIMPLEMENTED_SETTER_ONE, |
297 MessageKind.UNIMPLEMENTED_SETTER, | 300 MessageKind.UNIMPLEMENTED_SETTER, |
298 MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER, | 301 MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER, |
299 MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER); | 302 MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER); |
300 } else if (interfaceMember.isGetter) { | 303 } else if (interfaceMember.isGetter) { |
301 reportWarning(MessageKind.UNIMPLEMENTED_GETTER_ONE, | 304 reportWarning(MessageKind.UNIMPLEMENTED_GETTER_ONE, |
302 MessageKind.UNIMPLEMENTED_GETTER, | 305 MessageKind.UNIMPLEMENTED_GETTER, |
(...skipping 14 matching lines...) Expand all Loading... |
317 void checkImplementsFunctionWithCall() { | 320 void checkImplementsFunctionWithCall() { |
318 assert(!cls.isAbstract); | 321 assert(!cls.isAbstract); |
319 | 322 |
320 if (cls.asInstanceOf(compiler.functionClass) == null) return; | 323 if (cls.asInstanceOf(compiler.functionClass) == null) return; |
321 if (cls.lookupMember(Identifiers.call) != null) return; | 324 if (cls.lookupMember(Identifiers.call) != null) return; |
322 // TODO(johnniwinther): Make separate methods for backend exceptions. | 325 // TODO(johnniwinther): Make separate methods for backend exceptions. |
323 // Avoid warnings on backend implementation classes for closures. | 326 // Avoid warnings on backend implementation classes for closures. |
324 if (compiler.backend.isBackendLibrary(cls.library)) return; | 327 if (compiler.backend.isBackendLibrary(cls.library)) return; |
325 | 328 |
326 reportMessage(compiler.functionClass, MessageKind.UNIMPLEMENTED_METHOD, () { | 329 reportMessage(compiler.functionClass, MessageKind.UNIMPLEMENTED_METHOD, () { |
327 compiler.reportWarningMessage( | 330 reporter.reportWarningMessage( |
328 cls, | 331 cls, |
329 MessageKind.UNIMPLEMENTED_METHOD_ONE, | 332 MessageKind.UNIMPLEMENTED_METHOD_ONE, |
330 {'class': cls.name, | 333 {'class': cls.name, |
331 'name': Identifiers.call, | 334 'name': Identifiers.call, |
332 'method': Identifiers.call, | 335 'method': Identifiers.call, |
333 'declarer': compiler.functionClass.name}); | 336 'declarer': compiler.functionClass.name}); |
334 }); | 337 }); |
335 } | 338 } |
336 | 339 |
337 /// Checks that a class member exists for every interface member. | 340 /// Checks that a class member exists for every interface member. |
338 void checkInterfaceImplementation(); | 341 void checkInterfaceImplementation(); |
339 | 342 |
340 /// Check that [declared] is a valid override of [superMember]. | 343 /// Check that [declared] is a valid override of [superMember]. |
341 void checkValidOverride(Member declared, MemberSignature superMember) { | 344 void checkValidOverride(Member declared, MemberSignature superMember) { |
342 if (superMember == null) { | 345 if (superMember == null) { |
343 // No override. | 346 // No override. |
344 if (!declared.isStatic) { | 347 if (!declared.isStatic) { |
345 ClassElement superclass = cls.superclass; | 348 ClassElement superclass = cls.superclass; |
346 while (superclass != null) { | 349 while (superclass != null) { |
347 Member superMember = | 350 Member superMember = |
348 superclass.lookupClassMember(declared.name); | 351 superclass.lookupClassMember(declared.name); |
349 if (superMember != null && superMember.isStatic) { | 352 if (superMember != null && superMember.isStatic) { |
350 reportMessage(superMember, MessageKind.INSTANCE_STATIC_SAME_NAME, | 353 reportMessage(superMember, MessageKind.INSTANCE_STATIC_SAME_NAME, |
351 () { | 354 () { |
352 compiler.reportWarning( | 355 reporter.reportWarning( |
353 compiler.createMessage( | 356 reporter.createMessage( |
354 declared.element, | 357 declared.element, |
355 MessageKind.INSTANCE_STATIC_SAME_NAME, | 358 MessageKind.INSTANCE_STATIC_SAME_NAME, |
356 {'memberName': declared.name, | 359 {'memberName': declared.name, |
357 'className': superclass.name}), | 360 'className': superclass.name}), |
358 <DiagnosticMessage>[ | 361 <DiagnosticMessage>[ |
359 compiler.createMessage( | 362 reporter.createMessage( |
360 superMember.element, | 363 superMember.element, |
361 MessageKind.INSTANCE_STATIC_SAME_NAME_CONT), | 364 MessageKind.INSTANCE_STATIC_SAME_NAME_CONT), |
362 ]); | 365 ]); |
363 | 366 |
364 }); | 367 }); |
365 break; | 368 break; |
366 } | 369 } |
367 superclass = superclass.superclass; | 370 superclass = superclass.superclass; |
368 } | 371 } |
369 } | 372 } |
(...skipping 26 matching lines...) Expand all Loading... |
396 // An error should already have been reported. | 399 // An error should already have been reported. |
397 assert(invariant(declared.element, compiler.compilationFailed, | 400 assert(invariant(declared.element, compiler.compilationFailed, |
398 message: "Member $inherited inherited from its " | 401 message: "Member $inherited inherited from its " |
399 "declaring class: ${cls}.")); | 402 "declaring class: ${cls}.")); |
400 continue; | 403 continue; |
401 } | 404 } |
402 | 405 |
403 void reportError(MessageKind errorKind, MessageKind infoKind) { | 406 void reportError(MessageKind errorKind, MessageKind infoKind) { |
404 reportMessage( | 407 reportMessage( |
405 inherited.element, MessageKind.INVALID_OVERRIDE_METHOD, () { | 408 inherited.element, MessageKind.INVALID_OVERRIDE_METHOD, () { |
406 compiler.reportError( | 409 reporter.reportError( |
407 compiler.createMessage( | 410 reporter.createMessage( |
408 declared.element, | 411 declared.element, |
409 errorKind, | 412 errorKind, |
410 {'name': declared.name.text, | 413 {'name': declared.name.text, |
411 'class': cls.thisType, | 414 'class': cls.thisType, |
412 'inheritedClass': inherited.declarer}), | 415 'inheritedClass': inherited.declarer}), |
413 <DiagnosticMessage>[ | 416 <DiagnosticMessage>[ |
414 compiler.createMessage( | 417 reporter.createMessage( |
415 inherited.element, | 418 inherited.element, |
416 infoKind, | 419 infoKind, |
417 {'name': declared.name.text, | 420 {'name': declared.name.text, |
418 'class': inherited.declarer}), | 421 'class': inherited.declarer}), |
419 ]); | 422 ]); |
420 }); | 423 }); |
421 } | 424 } |
422 | 425 |
423 if (declared.isDeclaredByField && inherited.isMethod) { | 426 if (declared.isDeclaredByField && inherited.isMethod) { |
424 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD, | 427 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD, |
425 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT); | 428 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT); |
426 } else if (declared.isMethod && inherited.isDeclaredByField) { | 429 } else if (declared.isMethod && inherited.isDeclaredByField) { |
427 reportError(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD, | 430 reportError(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD, |
428 MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT); | 431 MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT); |
429 } else if (declared.isGetter && inherited.isMethod) { | 432 } else if (declared.isGetter && inherited.isMethod) { |
430 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER, | 433 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER, |
431 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT); | 434 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT); |
432 } else if (declared.isMethod && inherited.isGetter) { | 435 } else if (declared.isMethod && inherited.isGetter) { |
433 reportError(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD, | 436 reportError(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD, |
434 MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT); | 437 MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT); |
435 } else { | 438 } else { |
436 DartType inheritedType = inherited.functionType; | 439 DartType inheritedType = inherited.functionType; |
437 if (!compiler.types.isSubtype(declaredType, inheritedType)) { | 440 if (!compiler.types.isSubtype(declaredType, inheritedType)) { |
438 void reportWarning(var marker, | 441 void reportWarning(var marker, |
439 MessageKind warningKind, | 442 MessageKind warningKind, |
440 MessageKind infoKind) { | 443 MessageKind infoKind) { |
441 reportMessage(marker, MessageKind.INVALID_OVERRIDE_METHOD, () { | 444 reportMessage(marker, MessageKind.INVALID_OVERRIDE_METHOD, () { |
442 compiler.reportWarning( | 445 reporter.reportWarning( |
443 compiler.createMessage( | 446 reporter.createMessage( |
444 declared.element, | 447 declared.element, |
445 warningKind, | 448 warningKind, |
446 {'declaredType': declared.type, | 449 {'declaredType': declared.type, |
447 'name': declared.name.text, | 450 'name': declared.name.text, |
448 'class': cls.thisType, | 451 'class': cls.thisType, |
449 'inheritedType': inherited.type, | 452 'inheritedType': inherited.type, |
450 'inheritedClass': inherited.declarer}), | 453 'inheritedClass': inherited.declarer}), |
451 <DiagnosticMessage>[ | 454 <DiagnosticMessage>[ |
452 compiler.createMessage( | 455 reporter.createMessage( |
453 inherited.element, | 456 inherited.element, |
454 infoKind, | 457 infoKind, |
455 {'name': declared.name.text, | 458 {'name': declared.name.text, |
456 'class': inherited.declarer}), | 459 'class': inherited.declarer}), |
457 ]); | 460 ]); |
458 }); | 461 }); |
459 } | 462 } |
460 if (declared.isDeclaredByField) { | 463 if (declared.isDeclaredByField) { |
461 if (inherited.isDeclaredByField) { | 464 if (inherited.isDeclaredByField) { |
462 reportWarning(inherited.element, | 465 reportWarning(inherited.element, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 } | 502 } |
500 } | 503 } |
501 } | 504 } |
502 } | 505 } |
503 } | 506 } |
504 | 507 |
505 void reportErrorWithContext(Element errorneousElement, | 508 void reportErrorWithContext(Element errorneousElement, |
506 MessageKind errorMessage, | 509 MessageKind errorMessage, |
507 Element contextElement, | 510 Element contextElement, |
508 MessageKind contextMessage) { | 511 MessageKind contextMessage) { |
509 compiler.reportError( | 512 reporter.reportError( |
510 compiler.createMessage( | 513 reporter.createMessage( |
511 errorneousElement, | 514 errorneousElement, |
512 errorMessage, | 515 errorMessage, |
513 {'memberName': contextElement.name, | 516 {'memberName': contextElement.name, |
514 'className': contextElement.enclosingClass.name}), | 517 'className': contextElement.enclosingClass.name}), |
515 <DiagnosticMessage>[ | 518 <DiagnosticMessage>[ |
516 compiler.createMessage(contextElement, contextMessage), | 519 reporter.createMessage(contextElement, contextMessage), |
517 ]); | 520 ]); |
518 } | 521 } |
519 | 522 |
520 /// Compute all class and interface names by the [name] in [cls]. | 523 /// Compute all class and interface names by the [name] in [cls]. |
521 static void computeClassMembersByName(Compiler compiler, | 524 static void computeClassMembersByName(Compiler compiler, |
522 ClassMemberMixin cls, | 525 ClassMemberMixin cls, |
523 String name) { | 526 String name) { |
524 if (cls.isMemberComputed(name)) return; | 527 if (cls.isMemberComputed(name)) return; |
525 LibraryElement library = cls.library; | 528 LibraryElement library = cls.library; |
526 _computeClassMember(compiler, cls, name, | 529 _computeClassMember(compiler, cls, name, |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 for (MemberSignature other in inheritedMembers) { | 713 for (MemberSignature other in inheritedMembers) { |
711 if (!compiler.types.isSubtype(inherited.functionType, | 714 if (!compiler.types.isSubtype(inherited.functionType, |
712 other.functionType)) { | 715 other.functionType)) { |
713 continue outer; | 716 continue outer; |
714 } | 717 } |
715 } | 718 } |
716 subtypesOfAllInherited.putIfAbsent(inherited.functionType, | 719 subtypesOfAllInherited.putIfAbsent(inherited.functionType, |
717 () => new Setlet<Member>()).add(inherited); | 720 () => new Setlet<Member>()).add(inherited); |
718 } | 721 } |
719 if (someAreGetters && !allAreGetters) { | 722 if (someAreGetters && !allAreGetters) { |
720 DiagnosticMessage warning = compiler.createMessage( | 723 DiagnosticMessage warning = reporter.createMessage( |
721 cls, | 724 cls, |
722 MessageKind.INHERIT_GETTER_AND_METHOD, | 725 MessageKind.INHERIT_GETTER_AND_METHOD, |
723 {'class': thisType, 'name': name.text }); | 726 {'class': thisType, 'name': name.text }); |
724 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; | 727 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; |
725 for (Member inherited in inheritedMembers) { | 728 for (Member inherited in inheritedMembers) { |
726 MessageKind kind; | 729 MessageKind kind; |
727 if (inherited.isMethod) { | 730 if (inherited.isMethod) { |
728 kind = MessageKind.INHERITED_METHOD; | 731 kind = MessageKind.INHERITED_METHOD; |
729 } else { | 732 } else { |
730 assert(invariant(cls, inherited.isGetter, | 733 assert(invariant(cls, inherited.isGetter, |
731 message: 'Conflicting member is neither a method nor a ' | 734 message: 'Conflicting member is neither a method nor a ' |
732 'getter.')); | 735 'getter.')); |
733 if (inherited.isDeclaredByField) { | 736 if (inherited.isDeclaredByField) { |
734 kind = MessageKind.INHERITED_IMPLICIT_GETTER; | 737 kind = MessageKind.INHERITED_IMPLICIT_GETTER; |
735 } else { | 738 } else { |
736 kind = MessageKind.INHERITED_EXPLICIT_GETTER; | 739 kind = MessageKind.INHERITED_EXPLICIT_GETTER; |
737 } | 740 } |
738 } | 741 } |
739 infos.add(compiler.createMessage( | 742 infos.add(reporter.createMessage( |
740 inherited.element, | 743 inherited.element, |
741 kind, | 744 kind, |
742 {'class': inherited.declarer, 'name': name.text})); | 745 {'class': inherited.declarer, 'name': name.text})); |
743 } | 746 } |
744 compiler.reportWarning(warning, infos); | 747 reporter.reportWarning(warning, infos); |
745 interfaceMembers[name] = new ErroneousMember(inheritedMembers); | 748 interfaceMembers[name] = new ErroneousMember(inheritedMembers); |
746 } else if (subtypesOfAllInherited.length == 1) { | 749 } else if (subtypesOfAllInherited.length == 1) { |
747 // All signatures have the same type. | 750 // All signatures have the same type. |
748 Setlet<Member> members = subtypesOfAllInherited.values.first; | 751 Setlet<Member> members = subtypesOfAllInherited.values.first; |
749 MemberSignature inherited = members.first; | 752 MemberSignature inherited = members.first; |
750 if (members.length != 1) { | 753 if (members.length != 1) { |
751 // Multiple signatures with the same type => return a | 754 // Multiple signatures with the same type => return a |
752 // synthesized signature. | 755 // synthesized signature. |
753 inherited = new SyntheticMember( | 756 inherited = new SyntheticMember( |
754 members, inherited.type, inherited.functionType); | 757 members, inherited.type, inherited.functionType); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 message: "Members have not been fully computed for $this.")); | 952 message: "Members have not been fully computed for $this.")); |
950 if (interfaceMembersAreClassMembers) { | 953 if (interfaceMembersAreClassMembers) { |
951 classMembers.forEach((_, member) { | 954 classMembers.forEach((_, member) { |
952 if (!member.isStatic) f(member); | 955 if (!member.isStatic) f(member); |
953 }); | 956 }); |
954 } else { | 957 } else { |
955 interfaceMembers.forEach((_, member) => f(member)); | 958 interfaceMembers.forEach((_, member) => f(member)); |
956 } | 959 } |
957 } | 960 } |
958 } | 961 } |
OLD | NEW |