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

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

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

Powered by Google App Engine
This is Rietveld 408576698