Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/resolution/class_members.dart

Issue 152593002: Version 1.2.0-dev.3.1 (Closed) Base URL: http://dart.googlecode.com/svn/trunk/dart/
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 resolution.compute_members; 5 library resolution.compute_members;
6 6
7 import '../elements/elements.dart' 7 import '../elements/elements.dart'
8 show Element, 8 show Element,
9 Name, 9 Name,
10 PublicName, 10 PublicName,
(...skipping 14 matching lines...) Expand all
25 part 'member_impl.dart'; 25 part 'member_impl.dart';
26 26
27 class MembersCreator { 27 class MembersCreator {
28 final ClassElement cls; 28 final ClassElement cls;
29 final Compiler compiler; 29 final Compiler compiler;
30 30
31 Map<Name, Member> classMembers = new Map<Name, Member>(); 31 Map<Name, Member> classMembers = new Map<Name, Member>();
32 Map<Name, MemberSignature> interfaceMembers = 32 Map<Name, MemberSignature> interfaceMembers =
33 new Map<Name, MemberSignature>(); 33 new Map<Name, MemberSignature>();
34 34
35 Map<dynamic/* Member | Element */, Set<MessageKind>> reportedMessages =
36 new Map<dynamic, Set<MessageKind>>();
37
35 MembersCreator(Compiler this.compiler, ClassElement this.cls); 38 MembersCreator(Compiler this.compiler, ClassElement this.cls);
36 39
40 void reportMessage(var marker, MessageKind kind, report()) {
41 Set<MessageKind> messages =
42 reportedMessages.putIfAbsent(marker,
43 () => new Set<MessageKind>());
44 if (messages.add(kind)) {
45 report();
46 }
47 }
48
37 void computeMembers() { 49 void computeMembers() {
38 Map<Name, Set<Member>> inheritedInterfaceMembers = 50 Map<Name, Set<Member>> inheritedInterfaceMembers =
39 _computeSuperMembers(); 51 _computeSuperMembers();
40 Map<Name, Member> declaredMembers = _computeClassMembers(); 52 Map<Name, Member> declaredMembers = _computeClassMembers();
41 _computeInterfaceMembers(inheritedInterfaceMembers, declaredMembers); 53 _computeInterfaceMembers(inheritedInterfaceMembers, declaredMembers);
54
55 if (!cls.modifiers.isAbstract() &&
56 !declaredMembers.containsKey(const PublicName('noSuchMethod'))) {
57 // Check for unimplemented members on concrete classes that neither have
58 // a `@proxy` annotation nor declare a `noSuchMethod` method.
59 checkInterfaceImplementation();
60 }
42 } 61 }
43 62
44 Map<Name, Set<Member>> _computeSuperMembers() { 63 Map<Name, Set<Member>> _computeSuperMembers() {
45 Map<Name, Set<Member>> inheritedInterfaceMembers = 64 Map<Name, Set<Member>> inheritedInterfaceMembers =
46 new Map<Name, Set<Member>>(); 65 new Map<Name, Set<Member>>();
47 66
48 void inheritInterfaceMembers(InterfaceType supertype) { 67 void inheritInterfaceMembers(InterfaceType supertype) {
49 supertype.element.forEachInterfaceMember((MemberSignature member) { 68 supertype.element.forEachInterfaceMember((MemberSignature member) {
50 Set<Member> members = 69 Set<Member> members =
51 inheritedInterfaceMembers.putIfAbsent( 70 inheritedInterfaceMembers.putIfAbsent(
(...skipping 26 matching lines...) Expand all
78 inheritInterfaceMembers(superinterface); 97 inheritInterfaceMembers(superinterface);
79 } 98 }
80 99
81 return inheritedInterfaceMembers; 100 return inheritedInterfaceMembers;
82 } 101 }
83 102
84 Map<Name, Member> _computeClassMembers() { 103 Map<Name, Member> _computeClassMembers() {
85 Map<Name, Member> declaredMembers = new Map<Name, Member>(); 104 Map<Name, Member> declaredMembers = new Map<Name, Member>();
86 105
87 void overrideMember(DeclaredMember declared) { 106 void overrideMember(DeclaredMember declared) {
107 DeclaredMember inherited = classMembers[declared.name];
88 classMembers[declared.name] = declared; 108 classMembers[declared.name] = declared;
109 checkValidOverride(declared, inherited);
89 } 110 }
90 111
91 if (cls.isMixinApplication) { 112 if (cls.isMixinApplication) {
92 MixinApplicationElement mixinApplication = cls; 113 MixinApplicationElement mixinApplication = cls;
93 if (mixinApplication.mixin != null) { 114 if (mixinApplication.mixin != null) {
94 // Only mix in class members when the mixin type is not malformed. 115 // Only mix in class members when the mixin type is not malformed.
95 computeClassMembers(compiler, mixinApplication.mixin); 116 computeClassMembers(compiler, mixinApplication.mixin);
96 117
97 mixinApplication.mixin.forEachClassMember((DeclaredMember member) { 118 mixinApplication.mixin.forEachClassMember((DeclaredMember member) {
98 if (!member.isStatic) { 119 if (!member.isStatic) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 Map<Name, Set<Member>> inheritedInterfaceMembers, 184 Map<Name, Set<Member>> inheritedInterfaceMembers,
164 Map<Name, Member> declaredMembers) { 185 Map<Name, Member> declaredMembers) {
165 InterfaceType thisType = cls.thisType; 186 InterfaceType thisType = cls.thisType;
166 // Compute the interface members by overriding the inherited members with 187 // Compute the interface members by overriding the inherited members with
167 // a declared member or by computing a single, possibly synthesized, 188 // a declared member or by computing a single, possibly synthesized,
168 // inherited member. 189 // inherited member.
169 inheritedInterfaceMembers.forEach( 190 inheritedInterfaceMembers.forEach(
170 (Name name, Set<Member> inheritedMembers) { 191 (Name name, Set<Member> inheritedMembers) {
171 Member declared = declaredMembers[name]; 192 Member declared = declaredMembers[name];
172 if (declared != null) { 193 if (declared != null) {
194 // Check that [declaredMember] is a valid override
195 for (Member inherited in inheritedMembers) {
196 checkValidOverride(declared, inherited);
197 }
173 if (!declared.isStatic) { 198 if (!declared.isStatic) {
174 interfaceMembers[name] = declared; 199 interfaceMembers[name] = declared;
175 } 200 }
176 } else { 201 } else {
177 bool someAreGetters = false; 202 bool someAreGetters = false;
178 bool allAreGetters = true; 203 bool allAreGetters = true;
179 Map<DartType, Set<Member>> subtypesOfAllInherited = 204 Map<DartType, Set<Member>> subtypesOfAllInherited =
180 new Map<DartType, Set<Member>>(); 205 new Map<DartType, Set<Member>>();
181 outer: for (Member inherited in inheritedMembers) { 206 outer: for (Member inherited in inheritedMembers) {
182 if (inherited.isGetter) { 207 if (inherited.isGetter) {
183 someAreGetters = true; 208 someAreGetters = true;
184 if (!allAreGetters) break outer; 209 if (!allAreGetters) break outer;
185 } else { 210 } else {
186 allAreGetters = false; 211 allAreGetters = false;
187 if (someAreGetters) break outer; 212 if (someAreGetters) break outer;
188 } 213 }
189 for (MemberSignature other in inheritedMembers) { 214 for (MemberSignature other in inheritedMembers) {
190 if (!compiler.types.isSubtype(inherited.functionType, 215 if (!compiler.types.isSubtype(inherited.functionType,
191 other.functionType)) { 216 other.functionType)) {
192 continue outer; 217 continue outer;
193 } 218 }
194 } 219 }
195 subtypesOfAllInherited.putIfAbsent(inherited.functionType, 220 subtypesOfAllInherited.putIfAbsent(inherited.functionType,
196 () => new Set<Member>()).add(inherited); 221 () => new Set<Member>()).add(inherited);
197 } 222 }
198 if (someAreGetters && !allAreGetters) { 223 if (someAreGetters && !allAreGetters) {
224 compiler.reportWarningCode(cls,
225 MessageKind.INHERIT_GETTER_AND_METHOD,
226 {'class': thisType, 'name': name.text });
227 for (Member inherited in inheritedMembers) {
228 MessageKind kind;
229 if (inherited.isMethod) {
230 kind = MessageKind.INHERITED_METHOD;
231 } else {
232 assert(invariant(cls, inherited.isGetter,
233 message: 'Conflicting member is neither a method nor a '
234 'getter.'));
235 if (inherited.isDeclaredByField) {
236 kind = MessageKind.INHERITED_IMPLICIT_GETTER;
237 } else {
238 kind = MessageKind.INHERITED_EXPLICIT_GETTER;
239 }
240 }
241 compiler.reportInfo(inherited.element, kind,
242 {'class': inherited.declarer, 'name': name.text });
243 }
199 interfaceMembers[name] = new ErroneousMember(inheritedMembers); 244 interfaceMembers[name] = new ErroneousMember(inheritedMembers);
200 } else if (subtypesOfAllInherited.length == 1) { 245 } else if (subtypesOfAllInherited.length == 1) {
201 // All signatures have the same type. 246 // All signatures have the same type.
202 Set<Member> members = subtypesOfAllInherited.values.first; 247 Set<Member> members = subtypesOfAllInherited.values.first;
203 MemberSignature inherited = members.first; 248 MemberSignature inherited = members.first;
204 if (members.length != 1) { 249 if (members.length != 1) {
205 // Multiple signatures with the same type => return a 250 // Multiple signatures with the same type => return a
206 // synthesized signature. 251 // synthesized signature.
207 inherited = new SyntheticMember( 252 inherited = new SyntheticMember(
208 members, inherited.type, inherited.functionType); 253 members, inherited.type, inherited.functionType);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 DartType type = memberType; 331 DartType type = memberType;
287 if (inheritedMembers.first.isGetter || 332 if (inheritedMembers.first.isGetter ||
288 inheritedMembers.first.isSetter) { 333 inheritedMembers.first.isSetter) {
289 type = compiler.types.dynamicType; 334 type = compiler.types.dynamicType;
290 } 335 }
291 interfaceMembers[name] = new SyntheticMember( 336 interfaceMembers[name] = new SyntheticMember(
292 inheritedMembers, type, memberType); 337 inheritedMembers, type, memberType);
293 } 338 }
294 } 339 }
295 340
341 /// Checks that a class member exists for every interface member.
342 void checkInterfaceImplementation() {
343 LibraryElement library = cls.getLibrary();
344
345 interfaceMembers.forEach((Name name, MemberSignature interfaceMember) {
346 if (!name.isAccessibleFrom(library)) return;
347 Member classMember = classMembers[name];
348 if (classMember != null) return;
349 if (interfaceMember is DeclaredMember &&
350 interfaceMember.declarer.element == cls) {
351 // Abstract method declared in [cls].
352 MessageKind kind = MessageKind.ABSTRACT_METHOD;
353 if (interfaceMember.isSetter) {
354 kind = MessageKind.ABSTRACT_SETTER;
355 } else if (interfaceMember.isGetter) {
356 kind = MessageKind.ABSTRACT_GETTER;
357 }
358 reportMessage(
359 interfaceMember.element, MessageKind.ABSTRACT_METHOD, () {
360 compiler.reportWarningCode(
361 interfaceMember.element, kind,
362 {'class': cls.name, 'name': name.text});
363 });
364 } else {
365 reportWarning(MessageKind singleKind,
366 MessageKind multipleKind,
367 MessageKind explicitlyDeclaredKind,
368 [MessageKind implicitlyDeclaredKind]) {
369 Member inherited = interfaceMember.declarations.first;
370 reportMessage(
371 interfaceMember, MessageKind.UNIMPLEMENTED_METHOD, () {
372 compiler.reportWarningCode(cls,
373 interfaceMember.declarations.length == 1
374 ? singleKind : multipleKind,
375 {'class': cls.name,
376 'name': name.text,
377 'method': interfaceMember,
378 'declarer': inherited.declarer});
379 for (Member inherited in interfaceMember.declarations) {
380 compiler.reportInfo(inherited.element,
381 inherited.isDeclaredByField ?
382 implicitlyDeclaredKind : explicitlyDeclaredKind,
383 {'class': inherited.declarer.name,
384 'name': name.text});
385 }
386 });
387 }
388 if (interfaceMember.isSetter) {
389 reportWarning(MessageKind.UNIMPLEMENTED_SETTER_ONE,
390 MessageKind.UNIMPLEMENTED_SETTER,
391 MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
392 MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER);
393 } else if (interfaceMember.isGetter) {
394 reportWarning(MessageKind.UNIMPLEMENTED_GETTER_ONE,
395 MessageKind.UNIMPLEMENTED_GETTER,
396 MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
397 MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER);
398 } else if (interfaceMember.isMethod) {
399 reportWarning(MessageKind.UNIMPLEMENTED_METHOD_ONE,
400 MessageKind.UNIMPLEMENTED_METHOD,
401 MessageKind.UNIMPLEMENTED_METHOD_CONT);
402 }
403 }
404 // TODO(johnniwinther): If [cls] is not abstract, check that for all
405 // interface members, there is a class member whose type is a subtype of
406 // the interface member.
407 });
408 }
409
410 void checkValidOverride(Member declared, MemberSignature superMember) {
411 if (superMember == null) {
412 // No override.
413 if (!declared.isStatic) {
414 ClassElement superclass = cls.superclass;
415 while (superclass != null) {
416 Member superMember =
417 superclass.lookupClassMember(declared.name);
418 if (superMember != null && superMember.isStatic) {
419 reportMessage(superMember, MessageKind.INSTANCE_STATIC_SAME_NAME,
420 () {
421 compiler.reportWarningCode(
422 declared.element,
423 MessageKind.INSTANCE_STATIC_SAME_NAME,
424 {'memberName': declared.name,
425 'className': superclass.name});
426 compiler.reportInfo(superMember.element,
427 MessageKind.INSTANCE_STATIC_SAME_NAME_CONT);
428 });
429 break;
430 }
431 superclass = superclass.superclass;
432 }
433 }
434 } else {
435 assert(declared.name == superMember.name);
436 if (declared.isStatic) {
437 for (Member inherited in superMember.declarations) {
438 reportMessage(
439 inherited.element, MessageKind.NO_STATIC_OVERRIDE, () {
440 reportErrorWithContext(
441 declared.element, MessageKind.NO_STATIC_OVERRIDE,
442 inherited.element, MessageKind.NO_STATIC_OVERRIDE_CONT);
443 });
444 }
445 }
446
447 DartType declaredType = declared.functionType;
448 for (Member inherited in superMember.declarations) {
449
450 void reportError(MessageKind errorKind, MessageKind infoKind) {
451 reportMessage(
452 inherited.element, MessageKind.INVALID_OVERRIDE_METHOD, () {
453 compiler.reportError(declared.element, errorKind,
454 {'name': declared.name.text,
455 'class': cls.thisType,
456 'inheritedClass': inherited.declarer});
457 compiler.reportInfo(inherited.element, infoKind,
458 {'name': declared.name.text,
459 'class': inherited.declarer});
460 });
461 }
462
463 if (declared.isDeclaredByField && inherited.isMethod) {
464 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD,
465 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT);
466 } else if (declared.isMethod && inherited.isDeclaredByField) {
467 reportError(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD,
468 MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT);
469 } else if (declared.isGetter && inherited.isMethod) {
470 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER,
471 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT);
472 } else if (declared.isMethod && inherited.isGetter) {
473 reportError(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD,
474 MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT);
475 } else {
476 DartType inheritedType = inherited.functionType;
477 if (!compiler.types.isSubtype(declaredType, inheritedType)) {
478 void reportWarning(var marker,
479 MessageKind warningKind,
480 MessageKind infoKind) {
481 reportMessage(marker, MessageKind.INVALID_OVERRIDE_METHOD, () {
482 compiler.reportWarningCode(declared.element, warningKind,
483 {'declaredType': declared.type,
484 'name': declared.name.text,
485 'class': cls.thisType,
486 'inheritedType': inherited.type,
487 'inheritedClass': inherited.declarer});
488 compiler.reportInfo(inherited.element, infoKind,
489 {'name': declared.name.text,
490 'class': inherited.declarer});
491 });
492 }
493 if (declared.isDeclaredByField) {
494 if (inherited.isDeclaredByField) {
495 reportWarning(inherited.element,
496 MessageKind.INVALID_OVERRIDE_FIELD,
497 MessageKind.INVALID_OVERRIDDEN_FIELD);
498 } else if (inherited.isGetter) {
499 reportWarning(inherited,
500 MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD,
501 MessageKind.INVALID_OVERRIDDEN_GETTER);
502 } else if (inherited.isSetter) {
503 reportWarning(inherited,
504 MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD,
505 MessageKind.INVALID_OVERRIDDEN_SETTER);
506 }
507 } else if (declared.isGetter) {
508 if (inherited.isDeclaredByField) {
509 reportWarning(inherited,
510 MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER,
511 MessageKind.INVALID_OVERRIDDEN_FIELD);
512 } else {
513 reportWarning(inherited,
514 MessageKind.INVALID_OVERRIDE_GETTER,
515 MessageKind.INVALID_OVERRIDDEN_GETTER);
516 }
517 } else if (declared.isSetter) {
518 if (inherited.isDeclaredByField) {
519 reportWarning(inherited,
520 MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER,
521 MessageKind.INVALID_OVERRIDDEN_FIELD);
522 } else {
523 reportWarning(inherited,
524 MessageKind.INVALID_OVERRIDE_SETTER,
525 MessageKind.INVALID_OVERRIDDEN_SETTER);
526 }
527 } else {
528 reportWarning(inherited,
529 MessageKind.INVALID_OVERRIDE_METHOD,
530 MessageKind.INVALID_OVERRIDDEN_METHOD);
531 }
532 }
533 }
534 }
535 }
536 }
537
538 void reportErrorWithContext(Element errorneousElement,
539 MessageKind errorMessage,
540 Element contextElement,
541 MessageKind contextMessage) {
542 compiler.reportError(
543 errorneousElement,
544 errorMessage,
545 {'memberName': contextElement.name,
546 'className': contextElement.getEnclosingClass().name});
547 compiler.reportInfo(contextElement, contextMessage);
548 }
549
296 static void computeClassMembers(Compiler compiler, BaseClassElementX cls) { 550 static void computeClassMembers(Compiler compiler, BaseClassElementX cls) {
297 if (cls.classMembers != null) return; 551 if (cls.classMembers != null) return;
298 MembersCreator creator = new MembersCreator(compiler, cls); 552 MembersCreator creator = new MembersCreator(compiler, cls);
299 creator.computeMembers(); 553 creator.computeMembers();
300 cls.classMembers = creator.classMembers; 554 cls.classMembers = creator.classMembers;
301 cls.interfaceMembers = creator.interfaceMembers; 555 cls.interfaceMembers = creator.interfaceMembers;
302 } 556 }
303 } 557 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698