Index: pkg/compiler/lib/src/resolution/class_members.dart |
diff --git a/pkg/compiler/lib/src/resolution/class_members.dart b/pkg/compiler/lib/src/resolution/class_members.dart |
deleted file mode 100644 |
index 5e753f8c812b4219625d94d5199b184da27c701c..0000000000000000000000000000000000000000 |
--- a/pkg/compiler/lib/src/resolution/class_members.dart |
+++ /dev/null |
@@ -1,898 +0,0 @@ |
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE file. |
- |
-library resolution.compute_members; |
- |
-import '../elements/elements.dart' |
- show Element, |
- Name, |
- PublicName, |
- Member, |
- MemberSignature, |
- LibraryElement, |
- ClassElement, |
- MixinApplicationElement; |
-import '../dart_types.dart'; |
-import '../dart2jslib.dart' |
- show Compiler, |
- MessageKind, |
- invariant, |
- isPrivateName; |
-import '../helpers/helpers.dart'; // Included for debug helpers. |
-import '../util/util.dart'; |
- |
-part 'member_impl.dart'; |
- |
-abstract class MembersCreator { |
- final ClassElement cls; |
- final Compiler compiler; |
- |
- final Iterable<String> computedMemberNames; |
- final Map<Name, Member> classMembers; |
- |
- Map<dynamic/* Member | Element */, Set<MessageKind>> reportedMessages = |
- new Map<dynamic, Set<MessageKind>>(); |
- |
- MembersCreator(Compiler this.compiler, |
- ClassElement this.cls, |
- Iterable<String> this.computedMemberNames, |
- Map<Name, Member> this.classMembers) { |
- assert(invariant(cls, cls.isDeclaration, |
- message: "Members may only be computed on declarations.")); |
- } |
- |
- void reportMessage(var marker, MessageKind kind, report()) { |
- Set<MessageKind> messages = |
- reportedMessages.putIfAbsent(marker, |
- () => new Set<MessageKind>()); |
- if (messages.add(kind)) { |
- report(); |
- } |
- } |
- |
- bool shouldSkipMember(MemberSignature member) { |
- return member == null || shouldSkipName(member.name.text); |
- |
- } |
- |
- bool shouldSkipName(String name) { |
- return computedMemberNames != null && |
- computedMemberNames.contains(name); |
- } |
- |
- /// Compute all members of [cls] with the given names. |
- void computeMembersByName(String name, Setlet<Name> names) { |
- computeMembers(name, names); |
- } |
- |
- /// Compute all members of [cls] and checked that [cls] implements its |
- /// interface unless it is abstract or declares a `noSuchMethod` method. |
- void computeAllMembers() { |
- Map<Name, Member> declaredMembers = computeMembers(null, null); |
- if (!cls.isAbstract && |
- !declaredMembers.containsKey(const PublicName('noSuchMethod'))) { |
- // Check for unimplemented members on concrete classes that neither have |
- // a `@proxy` annotation nor declare a `noSuchMethod` method. |
- checkInterfaceImplementation(); |
- } |
- } |
- |
- /// Compute declared and inherited members of [cls] and return a map of the |
- /// declared members. |
- /// |
- /// If [name] and [names] are not null, the computation is restricted to |
- /// members with these names. |
- Map<Name, Member> computeMembers(String name, Setlet<Name> names); |
- |
- /// Compute the members of the super type(s) of [cls] and store them in |
- /// [classMembers]. |
- /// |
- /// If [name] and [names] are not null, the computation is restricted to |
- /// members with these names. |
- void computeSuperMembers(String name, Setlet<Name> names); |
- |
- /// Compute the members of the super class of [cls] and store them in |
- /// [classMembers]. |
- /// |
- /// If [name] and [names] are not null, the computation is restricted to |
- /// members with these names. |
- void computeSuperClassMembers(String name, Setlet<Name> names) { |
- InterfaceType supertype = cls.supertype; |
- if (supertype == null) return; |
- ClassElement superclass = supertype.element; |
- |
- // Inherit class and interface members from superclass. |
- void inheritClassMember(DeclaredMember member) { |
- if (shouldSkipMember(member)) return; |
- if (!member.isStatic) { |
- DeclaredMember inherited = member.inheritFrom(supertype); |
- classMembers[member.name] = inherited; |
- } |
- } |
- |
- if (names != null) { |
- _computeClassMember(compiler, superclass, name, names); |
- for (Name memberName in names) { |
- inheritClassMember(superclass.lookupClassMember(memberName)); |
- } |
- } else { |
- computeAllClassMembers(compiler, superclass); |
- superclass.forEachClassMember(inheritClassMember); |
- } |
- } |
- |
- /// Compute the members declared or directly mixed in [cls]. |
- /// |
- /// If [name] and [names] are not null, the computation is restricted to |
- /// members with these names. |
- Map<Name, Member> computeClassMembers(String nameText, Setlet<Name> names) { |
- Map<Name, Member> declaredMembers = new Map<Name, Member>(); |
- |
- if (cls.isMixinApplication) { |
- MixinApplicationElement mixinApplication = cls; |
- if (mixinApplication.mixin != null) { |
- // Only mix in class members when the mixin type is not malformed. |
- |
- void inheritMixinMember(DeclaredMember member) { |
- if (shouldSkipMember(member)) return; |
- Name name = member.name; |
- if (!member.isAbstract && !member.isStatic) { |
- // Abstract and static members are not mixed in. |
- DeclaredMember mixedInMember = |
- member.inheritFrom(mixinApplication.mixinType); |
- DeclaredMember inherited = classMembers[name]; |
- classMembers[name] = mixedInMember; |
- checkValidOverride(mixedInMember, inherited); |
- } |
- } |
- |
- if (names != null) { |
- _computeClassMember(compiler, mixinApplication.mixin, |
- nameText, names); |
- for (Name memberName in names) { |
- inheritMixinMember( |
- mixinApplication.mixin.lookupClassMember(memberName)); |
- } |
- } else { |
- computeAllClassMembers(compiler, mixinApplication.mixin); |
- mixinApplication.mixin.forEachClassMember(inheritMixinMember); |
- } |
- } |
- } else { |
- LibraryElement library = cls.library; |
- InterfaceType thisType = cls.thisType; |
- |
- void createMember(Element element) { |
- if (element.isConstructor) return; |
- String elementName = element.name; |
- if (shouldSkipName(elementName)) return; |
- if (nameText != null && elementName != nameText) return; |
- |
- void addDeclaredMember(Name name, |
- DartType type, FunctionType functionType) { |
- DeclaredMember inherited = classMembers[name]; |
- DeclaredMember declared; |
- if (element.isAbstract) { |
- declared = new DeclaredAbstractMember( |
- name, element, thisType, type, functionType, |
- inherited); |
- } else { |
- declared = |
- new DeclaredMember(name, element, thisType, type, functionType); |
- } |
- declaredMembers[name] = declared; |
- classMembers[name] = declared; |
- checkValidOverride(declared, inherited); |
- } |
- |
- Name name = new Name(element.name, library); |
- if (element.isField) { |
- DartType type = element.computeType(compiler); |
- addDeclaredMember(name, type, new FunctionType.synthesized(type)); |
- if (!element.isConst && !element.isFinal) { |
- addDeclaredMember(name.setter, type, |
- new FunctionType.synthesized( |
- const VoidType(), |
- <DartType>[type])); |
- } |
- } else if (element.isGetter) { |
- FunctionType functionType = element.computeType(compiler); |
- DartType type = functionType.returnType; |
- addDeclaredMember(name, type, functionType); |
- } else if (element.isSetter) { |
- FunctionType functionType = element.computeType(compiler); |
- DartType type; |
- if (!functionType.parameterTypes.isEmpty) { |
- type = functionType.parameterTypes.first; |
- } else { |
- type = const DynamicType(); |
- } |
- name = name.setter; |
- addDeclaredMember(name, type, functionType); |
- } else { |
- assert(invariant(element, element.isFunction)); |
- FunctionType type = element.computeType(compiler); |
- addDeclaredMember(name, type, type); |
- } |
- } |
- |
- cls.forEachLocalMember(createMember); |
- if (cls.isPatched) { |
- cls.implementation.forEachLocalMember((Element element) { |
- if (element.isDeclaration) { |
- createMember(element); |
- } |
- }); |
- } |
- } |
- |
- return declaredMembers; |
- } |
- |
- /// Checks that [classMember] is a valid implementation for [interfaceMember]. |
- void checkInterfaceMember(Name name, |
- MemberSignature interfaceMember, |
- Member classMember) { |
- if (classMember != null) { |
- // TODO(johnniwinther): Check that the class member is a valid override |
- // of the interface member. |
- return; |
- } |
- if (interfaceMember is DeclaredMember && |
- interfaceMember.declarer.element == cls) { |
- // Abstract method declared in [cls]. |
- MessageKind kind = MessageKind.ABSTRACT_METHOD; |
- if (interfaceMember.isSetter) { |
- kind = MessageKind.ABSTRACT_SETTER; |
- } else if (interfaceMember.isGetter) { |
- kind = MessageKind.ABSTRACT_GETTER; |
- } |
- reportMessage( |
- interfaceMember.element, MessageKind.ABSTRACT_METHOD, () { |
- compiler.reportWarning( |
- interfaceMember.element, kind, |
- {'class': cls.name, 'name': name.text}); |
- }); |
- } else { |
- reportWarning(MessageKind singleKind, |
- MessageKind multipleKind, |
- MessageKind explicitlyDeclaredKind, |
- [MessageKind implicitlyDeclaredKind]) { |
- Member inherited = interfaceMember.declarations.first; |
- reportMessage( |
- interfaceMember, MessageKind.UNIMPLEMENTED_METHOD, () { |
- compiler.reportWarning(cls, |
- interfaceMember.declarations.length == 1 |
- ? singleKind : multipleKind, |
- {'class': cls.name, |
- 'name': name.text, |
- 'method': interfaceMember, |
- 'declarer': inherited.declarer}); |
- for (Member inherited in interfaceMember.declarations) { |
- compiler.reportInfo(inherited.element, |
- inherited.isDeclaredByField ? |
- implicitlyDeclaredKind : explicitlyDeclaredKind, |
- {'class': inherited.declarer.name, |
- 'name': name.text}); |
- } |
- }); |
- } |
- if (interfaceMember.isSetter) { |
- reportWarning(MessageKind.UNIMPLEMENTED_SETTER_ONE, |
- MessageKind.UNIMPLEMENTED_SETTER, |
- MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER, |
- MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER); |
- } else if (interfaceMember.isGetter) { |
- reportWarning(MessageKind.UNIMPLEMENTED_GETTER_ONE, |
- MessageKind.UNIMPLEMENTED_GETTER, |
- MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER, |
- MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER); |
- } else if (interfaceMember.isMethod) { |
- reportWarning(MessageKind.UNIMPLEMENTED_METHOD_ONE, |
- MessageKind.UNIMPLEMENTED_METHOD, |
- MessageKind.UNIMPLEMENTED_METHOD_CONT); |
- } |
- } |
- // TODO(johnniwinther): If [cls] is not abstract, check that for all |
- // interface members, there is a class member whose type is a subtype of |
- // the interface member. |
- } |
- |
- /// Checks that [cls], if it implements Function, has defined call(). |
- void checkImplementsFunctionWithCall() { |
- assert(!cls.isAbstract); |
- |
- if (cls.asInstanceOf(compiler.functionClass) == null) return; |
- if (cls.lookupMember(Compiler.CALL_OPERATOR_NAME) != null) return; |
- // TODO(johnniwinther): Make separate methods for backend exceptions. |
- // Avoid warnings on backend implementation classes for closures. |
- if (compiler.backend.isBackendLibrary(cls.library)) return; |
- |
- reportMessage(compiler.functionClass, MessageKind.UNIMPLEMENTED_METHOD, () { |
- compiler.reportWarning(cls, MessageKind.UNIMPLEMENTED_METHOD_ONE, |
- {'class': cls.name, |
- 'name': Compiler.CALL_OPERATOR_NAME, |
- 'method': Compiler.CALL_OPERATOR_NAME, |
- 'declarer': compiler.functionClass.name}); |
- }); |
- } |
- |
- /// Checks that a class member exists for every interface member. |
- void checkInterfaceImplementation(); |
- |
- /// Check that [declared] is a valid override of [superMember]. |
- void checkValidOverride(Member declared, MemberSignature superMember) { |
- if (superMember == null) { |
- // No override. |
- if (!declared.isStatic) { |
- ClassElement superclass = cls.superclass; |
- while (superclass != null) { |
- Member superMember = |
- superclass.lookupClassMember(declared.name); |
- if (superMember != null && superMember.isStatic) { |
- reportMessage(superMember, MessageKind.INSTANCE_STATIC_SAME_NAME, |
- () { |
- compiler.reportWarning( |
- declared.element, |
- MessageKind.INSTANCE_STATIC_SAME_NAME, |
- {'memberName': declared.name, |
- 'className': superclass.name}); |
- compiler.reportInfo(superMember.element, |
- MessageKind.INSTANCE_STATIC_SAME_NAME_CONT); |
- }); |
- break; |
- } |
- superclass = superclass.superclass; |
- } |
- } |
- } else { |
- assert(declared.name == superMember.name); |
- if (declared.isStatic) { |
- for (Member inherited in superMember.declarations) { |
- reportMessage( |
- inherited.element, MessageKind.NO_STATIC_OVERRIDE, () { |
- reportErrorWithContext( |
- declared.element, MessageKind.NO_STATIC_OVERRIDE, |
- inherited.element, MessageKind.NO_STATIC_OVERRIDE_CONT); |
- }); |
- } |
- } |
- |
- DartType declaredType = declared.functionType; |
- for (Member inherited in superMember.declarations) { |
- |
- void reportError(MessageKind errorKind, MessageKind infoKind) { |
- reportMessage( |
- inherited.element, MessageKind.INVALID_OVERRIDE_METHOD, () { |
- compiler.reportError(declared.element, errorKind, |
- {'name': declared.name.text, |
- 'class': cls.thisType, |
- 'inheritedClass': inherited.declarer}); |
- compiler.reportInfo(inherited.element, infoKind, |
- {'name': declared.name.text, |
- 'class': inherited.declarer}); |
- }); |
- } |
- |
- if (declared.isDeclaredByField && inherited.isMethod) { |
- reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD, |
- MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT); |
- } else if (declared.isMethod && inherited.isDeclaredByField) { |
- reportError(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD, |
- MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT); |
- } else if (declared.isGetter && inherited.isMethod) { |
- reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER, |
- MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT); |
- } else if (declared.isMethod && inherited.isGetter) { |
- reportError(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD, |
- MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT); |
- } else { |
- DartType inheritedType = inherited.functionType; |
- if (!compiler.types.isSubtype(declaredType, inheritedType)) { |
- void reportWarning(var marker, |
- MessageKind warningKind, |
- MessageKind infoKind) { |
- reportMessage(marker, MessageKind.INVALID_OVERRIDE_METHOD, () { |
- compiler.reportWarning(declared.element, warningKind, |
- {'declaredType': declared.type, |
- 'name': declared.name.text, |
- 'class': cls.thisType, |
- 'inheritedType': inherited.type, |
- 'inheritedClass': inherited.declarer}); |
- compiler.reportInfo(inherited.element, infoKind, |
- {'name': declared.name.text, |
- 'class': inherited.declarer}); |
- }); |
- } |
- if (declared.isDeclaredByField) { |
- if (inherited.isDeclaredByField) { |
- reportWarning(inherited.element, |
- MessageKind.INVALID_OVERRIDE_FIELD, |
- MessageKind.INVALID_OVERRIDDEN_FIELD); |
- } else if (inherited.isGetter) { |
- reportWarning(inherited, |
- MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD, |
- MessageKind.INVALID_OVERRIDDEN_GETTER); |
- } else if (inherited.isSetter) { |
- reportWarning(inherited, |
- MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD, |
- MessageKind.INVALID_OVERRIDDEN_SETTER); |
- } |
- } else if (declared.isGetter) { |
- if (inherited.isDeclaredByField) { |
- reportWarning(inherited, |
- MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER, |
- MessageKind.INVALID_OVERRIDDEN_FIELD); |
- } else { |
- reportWarning(inherited, |
- MessageKind.INVALID_OVERRIDE_GETTER, |
- MessageKind.INVALID_OVERRIDDEN_GETTER); |
- } |
- } else if (declared.isSetter) { |
- if (inherited.isDeclaredByField) { |
- reportWarning(inherited, |
- MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER, |
- MessageKind.INVALID_OVERRIDDEN_FIELD); |
- } else { |
- reportWarning(inherited, |
- MessageKind.INVALID_OVERRIDE_SETTER, |
- MessageKind.INVALID_OVERRIDDEN_SETTER); |
- } |
- } else { |
- reportWarning(inherited, |
- MessageKind.INVALID_OVERRIDE_METHOD, |
- MessageKind.INVALID_OVERRIDDEN_METHOD); |
- } |
- } |
- } |
- } |
- } |
- } |
- |
- void reportErrorWithContext(Element errorneousElement, |
- MessageKind errorMessage, |
- Element contextElement, |
- MessageKind contextMessage) { |
- compiler.reportError( |
- errorneousElement, |
- errorMessage, |
- {'memberName': contextElement.name, |
- 'className': contextElement.enclosingClass.name}); |
- compiler.reportInfo(contextElement, contextMessage); |
- } |
- |
- /// Compute all class and interface names by the [name] in [cls]. |
- static void computeClassMembersByName(Compiler compiler, |
- ClassMemberMixin cls, |
- String name) { |
- if (cls.isMemberComputed(name)) return; |
- LibraryElement library = cls.library; |
- _computeClassMember(compiler, cls, name, |
- new Setlet<Name>()..add(new Name(name, library)) |
- ..add(new Name(name, library, isSetter: true))); |
- } |
- |
- static void _computeClassMember(Compiler compiler, |
- ClassMemberMixin cls, |
- String name, |
- Setlet<Name> names) { |
- cls.computeClassMember(compiler, name, names); |
- } |
- |
- /// Compute all class and interface names in [cls]. |
- static void computeAllClassMembers(Compiler compiler, ClassMemberMixin cls) { |
- cls.computeAllClassMembers(compiler); |
- } |
-} |
- |
-/// Class member creator for classes where the interface members are known to |
-/// be a subset of the class members. |
-class ClassMembersCreator extends MembersCreator { |
- ClassMembersCreator(Compiler compiler, |
- ClassElement cls, |
- Iterable<String> computedMemberNames, |
- Map<Name, Member> classMembers) |
- : super(compiler, cls, computedMemberNames, classMembers); |
- |
- Map<Name, Member> computeMembers(String name, Setlet<Name> names) { |
- computeSuperMembers(name, names); |
- return computeClassMembers(name, names); |
- } |
- |
- void computeSuperMembers(String name, Setlet<Name> names) { |
- computeSuperClassMembers(name, names); |
- } |
- |
- void checkInterfaceImplementation() { |
- LibraryElement library = cls.library; |
- classMembers.forEach((Name name, Member classMember) { |
- if (!name.isAccessibleFrom(library)) return; |
- checkInterfaceMember(name, classMember, classMember.implementation); |
- }); |
- } |
-} |
- |
-/// Class Member creator for classes where the interface members might be |
-/// different from the class members. |
-class InterfaceMembersCreator extends MembersCreator { |
- final Map<Name, MemberSignature> interfaceMembers; |
- |
- InterfaceMembersCreator(Compiler compiler, |
- ClassElement cls, |
- Iterable<String> computedMemberNames, |
- Map<Name, Member> classMembers, |
- Map<Name, MemberSignature> this.interfaceMembers) |
- : super(compiler, cls, computedMemberNames, classMembers); |
- |
- Map<Name, Member> computeMembers(String name, Setlet<Name> names) { |
- Map<Name, Setlet<Member>> inheritedInterfaceMembers = |
- computeSuperMembers(name, names); |
- Map<Name, Member> declaredMembers = computeClassMembers(name, names); |
- computeInterfaceMembers(inheritedInterfaceMembers, declaredMembers); |
- return declaredMembers; |
- } |
- |
- /// Compute the members of the super type(s) of [cls]. The class members are |
- /// stored if the [classMembers] map and the inherited interface members are |
- /// returned. |
- /// |
- /// If [name] and [names] are not null, the computation is restricted to |
- /// members with these names. |
- Map<Name, Setlet<Member>> computeSuperMembers(String name, |
- Setlet<Name> names) { |
- computeSuperClassMembers(name, names); |
- return computeSuperInterfaceMembers(name, names); |
- } |
- |
- Map<Name, Setlet<Member>> computeSuperInterfaceMembers(String name, |
- Setlet<Name> names) { |
- |
- |
- InterfaceType supertype = cls.supertype; |
- assert(invariant(cls, supertype != null, |
- message: "Interface members computed for $cls.")); |
- ClassElement superclass = supertype.element; |
- |
- Map<Name, Setlet<Member>> inheritedInterfaceMembers = |
- new Map<Name, Setlet<Member>>(); |
- |
- void inheritInterfaceMember(InterfaceType supertype, |
- MemberSignature member) { |
- if (shouldSkipMember(member)) return; |
- Setlet<Member> members = |
- inheritedInterfaceMembers.putIfAbsent( |
- member.name, () => new Setlet<Member>()); |
- for (DeclaredMember declaredMember in member.declarations) { |
- members.add(declaredMember.inheritFrom(supertype)); |
- } |
- } |
- |
- void inheritInterfaceMembers(InterfaceType supertype) { |
- supertype.element.forEachInterfaceMember((MemberSignature member) { |
- inheritInterfaceMember(supertype, member); |
- }); |
- } |
- |
- if (names != null) { |
- for (Name memberName in names) { |
- inheritInterfaceMember(supertype, |
- superclass.lookupInterfaceMember(memberName)); |
- } |
- } else { |
- inheritInterfaceMembers(supertype); |
- } |
- |
- // Inherit interface members from superinterfaces. |
- for (Link<DartType> link = cls.interfaces; |
- !link.isEmpty; |
- link = link.tail) { |
- InterfaceType superinterface = link.head; |
- if (names != null) { |
- MembersCreator._computeClassMember( |
- compiler, superinterface.element, name, names); |
- for (Name memberName in names) { |
- inheritInterfaceMember(superinterface, |
- superinterface.element.lookupInterfaceMember(memberName)); |
- } |
- } else { |
- MembersCreator.computeAllClassMembers(compiler, superinterface.element); |
- inheritInterfaceMembers(superinterface); |
- } |
- } |
- |
- return inheritedInterfaceMembers; |
- } |
- |
- /// Checks that a class member exists for every interface member. |
- void checkInterfaceImplementation() { |
- LibraryElement library = cls.library; |
- checkImplementsFunctionWithCall(); |
- interfaceMembers.forEach((Name name, MemberSignature interfaceMember) { |
- if (!name.isAccessibleFrom(library)) return; |
- Member classMember = classMembers[name]; |
- if (classMember != null) classMember = classMember.implementation; |
- checkInterfaceMember(name, interfaceMember, classMember); |
- }); |
- } |
- |
- /// Compute the interface members of [cls] given the set of inherited |
- /// interface members [inheritedInterfaceMembers] and declared members |
- /// [declaredMembers]. The computed members are stored in [interfaceMembers]. |
- void computeInterfaceMembers( |
- Map<Name, Setlet<Member>> inheritedInterfaceMembers, |
- Map<Name, Member> declaredMembers) { |
- InterfaceType thisType = cls.thisType; |
- // Compute the interface members by overriding the inherited members with |
- // a declared member or by computing a single, possibly synthesized, |
- // inherited member. |
- inheritedInterfaceMembers.forEach( |
- (Name name, Setlet<Member> inheritedMembers) { |
- Member declared = declaredMembers[name]; |
- if (declared != null) { |
- // Check that [declaredMember] is a valid override |
- for (Member inherited in inheritedMembers) { |
- checkValidOverride(declared, inherited); |
- } |
- if (!declared.isStatic) { |
- interfaceMembers[name] = declared; |
- } |
- } else if (inheritedMembers.length == 1) { |
- interfaceMembers[name] = inheritedMembers.single; |
- } else { |
- bool someAreGetters = false; |
- bool allAreGetters = true; |
- Map<DartType, Setlet<Member>> subtypesOfAllInherited = |
- new Map<DartType, Setlet<Member>>(); |
- outer: for (Member inherited in inheritedMembers) { |
- if (inherited.isGetter) { |
- someAreGetters = true; |
- if (!allAreGetters) break outer; |
- } else { |
- allAreGetters = false; |
- if (someAreGetters) break outer; |
- } |
- for (MemberSignature other in inheritedMembers) { |
- if (!compiler.types.isSubtype(inherited.functionType, |
- other.functionType)) { |
- continue outer; |
- } |
- } |
- subtypesOfAllInherited.putIfAbsent(inherited.functionType, |
- () => new Setlet<Member>()).add(inherited); |
- } |
- if (someAreGetters && !allAreGetters) { |
- compiler.reportWarning(cls, |
- MessageKind.INHERIT_GETTER_AND_METHOD, |
- {'class': thisType, 'name': name.text }); |
- for (Member inherited in inheritedMembers) { |
- MessageKind kind; |
- if (inherited.isMethod) { |
- kind = MessageKind.INHERITED_METHOD; |
- } else { |
- assert(invariant(cls, inherited.isGetter, |
- message: 'Conflicting member is neither a method nor a ' |
- 'getter.')); |
- if (inherited.isDeclaredByField) { |
- kind = MessageKind.INHERITED_IMPLICIT_GETTER; |
- } else { |
- kind = MessageKind.INHERITED_EXPLICIT_GETTER; |
- } |
- } |
- compiler.reportInfo(inherited.element, kind, |
- {'class': inherited.declarer, 'name': name.text }); |
- } |
- interfaceMembers[name] = new ErroneousMember(inheritedMembers); |
- } else if (subtypesOfAllInherited.length == 1) { |
- // All signatures have the same type. |
- Setlet<Member> members = subtypesOfAllInherited.values.first; |
- MemberSignature inherited = members.first; |
- if (members.length != 1) { |
- // Multiple signatures with the same type => return a |
- // synthesized signature. |
- inherited = new SyntheticMember( |
- members, inherited.type, inherited.functionType); |
- } |
- interfaceMembers[name] = inherited; |
- } else { |
- _inheritedSynthesizedMember(name, inheritedMembers); |
- } |
- } |
- }); |
- |
- // Add the non-overriding instance methods to the interface members. |
- declaredMembers.forEach((Name name, Member member) { |
- if (!member.isStatic) { |
- interfaceMembers.putIfAbsent(name, () => member); |
- } |
- }); |
- } |
- |
- /// Create and inherit a synthesized member for [inheritedMembers]. |
- void _inheritedSynthesizedMember(Name name, |
- Setlet<Member> inheritedMembers) { |
- // Multiple signatures with different types => create the synthesized |
- // version. |
- int minRequiredParameters; |
- int maxPositionalParameters; |
- Set<String> names = new Set<String>(); |
- for (MemberSignature member in inheritedMembers) { |
- int requiredParameters = 0; |
- int optionalParameters = 0; |
- if (member.isSetter) { |
- requiredParameters = 1; |
- } |
- if (member.type.isFunctionType) { |
- FunctionType type = member.type; |
- type.namedParameters.forEach( |
- (String name) => names.add(name)); |
- requiredParameters = type.parameterTypes.length; |
- optionalParameters = type.optionalParameterTypes.length; |
- } |
- int positionalParameters = requiredParameters + optionalParameters; |
- if (minRequiredParameters == null || |
- minRequiredParameters > requiredParameters) { |
- minRequiredParameters = requiredParameters; |
- } |
- if (maxPositionalParameters == null || |
- maxPositionalParameters < positionalParameters) { |
- maxPositionalParameters = positionalParameters; |
- } |
- } |
- int optionalParameters = |
- maxPositionalParameters - minRequiredParameters; |
- // TODO(johnniwinther): Support function types with both optional |
- // and named parameters? |
- if (optionalParameters == 0 || names.isEmpty) { |
- DartType dynamic = const DynamicType(); |
- List<DartType> requiredParameterTypes = |
- new List.filled(minRequiredParameters, dynamic); |
- List<DartType> optionalParameterTypes = |
- new List.filled(optionalParameters, dynamic); |
- List<String> namedParameters = |
- names.toList()..sort((a, b) => a.compareTo(b)); |
- List<DartType> namedParameterTypes = |
- new List.filled(namedParameters.length, dynamic); |
- FunctionType memberType = new FunctionType.synthesized( |
- const DynamicType(), |
- requiredParameterTypes, |
- optionalParameterTypes, |
- namedParameters, namedParameterTypes); |
- DartType type = memberType; |
- if (inheritedMembers.first.isGetter || |
- inheritedMembers.first.isSetter) { |
- type = const DynamicType(); |
- } |
- interfaceMembers[name] = |
- new SyntheticMember(inheritedMembers, type, memberType); |
- } |
- } |
-} |
- |
-abstract class ClassMemberMixin implements ClassElement { |
- /// When [classMembers] and [interfaceMembers] have not been fully computed |
- /// [computedMembersNames] holds the names for which members have already been |
- /// computed. |
- /// |
- /// If [computedMemberNames], [classMembers] and [interfaceMembers] are `null` |
- /// no members have been computed, if only [computedMemberNames] is `null` all |
- /// members have been computed. A non-null [computedMemberNames] implicitly |
- /// includes `call`. |
- Iterable<String> computedMemberNames; |
- |
- /// If `true` interface members are the non-static class member. |
- bool interfaceMembersAreClassMembers = true; |
- |
- Map<Name, Member> classMembers; |
- Map<Name, MemberSignature> interfaceMembers; |
- |
- /// Creates the necessary maps and [MembersCreator] for compute members of |
- /// this class. |
- MembersCreator _prepareCreator(Compiler compiler) { |
- if (classMembers == null) { |
- classMembers = new Map<Name, Member>(); |
- |
- if (interfaceMembersAreClassMembers) { |
- ClassMemberMixin superclass = this.superclass; |
- if ((superclass != null && |
- (!superclass.interfaceMembersAreClassMembers || |
- superclass.isMixinApplication)) || |
- !interfaces.isEmpty) { |
- interfaceMembersAreClassMembers = false; |
- } |
- } |
- if (!interfaceMembersAreClassMembers) { |
- interfaceMembers = new Map<Name, MemberSignature>(); |
- } |
- } |
- return interfaceMembersAreClassMembers |
- ? new ClassMembersCreator(compiler, this, |
- computedMemberNames, classMembers) |
- : new InterfaceMembersCreator(compiler, this, |
- computedMemberNames, classMembers, interfaceMembers); |
- } |
- |
- static Iterable<String> _EMPTY_MEMBERS_NAMES = const <String>[]; |
- |
- /// Compute the members by the name [name] for this class. [names] collects |
- /// the set of possible variations of [name], including getter, setter and |
- /// and private names. |
- void computeClassMember(Compiler compiler, String name, Setlet<Name> names) { |
- if (isMemberComputed(name)) return; |
- if (isPrivateName(name)) { |
- names..add(new Name(name, library)) |
- ..add(new Name(name, library, isSetter: true)); |
- } |
- MembersCreator creator = _prepareCreator(compiler); |
- creator.computeMembersByName(name, names); |
- if (computedMemberNames == null) { |
- computedMemberNames = _EMPTY_MEMBERS_NAMES; |
- } |
- if (name != Compiler.CALL_OPERATOR_NAME) { |
- Setlet<String> set; |
- if (identical(computedMemberNames, _EMPTY_MEMBERS_NAMES)) { |
- computedMemberNames = set = new Setlet<String>(); |
- } else { |
- set = computedMemberNames; |
- } |
- set.add(name); |
- } |
- } |
- |
- void computeAllClassMembers(Compiler compiler) { |
- if (areAllMembersComputed()) return; |
- MembersCreator creator = _prepareCreator(compiler); |
- creator.computeAllMembers(); |
- computedMemberNames = null; |
- assert(invariant(this, areAllMembersComputed())); |
- } |
- |
- bool areAllMembersComputed() { |
- return computedMemberNames == null && classMembers != null; |
- } |
- |
- bool isMemberComputed(String name) { |
- if (computedMemberNames == null) { |
- return classMembers != null; |
- } else { |
- return name == Compiler.CALL_OPERATOR_NAME || |
- computedMemberNames.contains(name); |
- } |
- } |
- |
- Member lookupClassMember(Name name) { |
- assert(invariant(this, |
- isMemberComputed(name.text), |
- message: "Member ${name} has not been computed for $this.")); |
- return classMembers[name]; |
- } |
- |
- void forEachClassMember(f(Member member)) { |
- assert(invariant(this, areAllMembersComputed(), |
- message: "Members have not been fully computed for $this.")); |
- classMembers.forEach((_, member) => f(member)); |
- } |
- |
- MemberSignature lookupInterfaceMember(Name name) { |
- assert(invariant(this, isMemberComputed(name.text), |
- message: "Member ${name.text} has not been computed for $this.")); |
- if (interfaceMembersAreClassMembers) { |
- Member member = classMembers[name]; |
- if (member != null && member.isStatic) return null; |
- return member; |
- } |
- return interfaceMembers[name]; |
- } |
- |
- void forEachInterfaceMember(f(MemberSignature member)) { |
- assert(invariant(this, areAllMembersComputed(), |
- message: "Members have not been fully computed for $this.")); |
- if (interfaceMembersAreClassMembers) { |
- classMembers.forEach((_, member) { |
- if (!member.isStatic) f(member); |
- }); |
- } else { |
- interfaceMembers.forEach((_, member) => f(member)); |
- } |
- } |
-} |