// // Populates type parameter members using type parameter constraints // The trick here is to be called late enough but not too late to // populate member cache with all members from other types // protected override void InitializeMemberCache (bool onlyTypes) { cache = new MemberCache (); if (ifaces != null) { foreach (var iface_type in Interfaces) { cache.AddInterface (iface_type); } } }
protected virtual bool DoDefineMembers () { if (iface_exprs != null) { foreach (TypeExpr iface in iface_exprs) { ObsoleteAttribute oa = AttributeTester.GetObsoleteAttribute (iface.Type); if ((oa != null) && !IsObsolete) AttributeTester.Report_ObsoleteMessage ( oa, iface.GetSignatureForError (), Location, Report); GenericTypeExpr ct = iface as GenericTypeExpr; if (ct != null) { // TODO: passing `this' is wrong, should be base type iface instead TypeManager.CheckTypeVariance (ct.Type, Variance.Covariant, this); if (!ct.CheckConstraints (this)) return false; } } } if (base_type != null) { ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (base_type.Type); if (obsolete_attr != null && !IsObsolete) AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), Location, Report); GenericTypeExpr ct = base_type as GenericTypeExpr; if ((ct != null) && !ct.CheckConstraints (this)) return false; TypeContainer baseContainer = TypeManager.LookupTypeContainer(base_type.Type); if (baseContainer != null) baseContainer.Define(); member_cache = new MemberCache (base_type.Type, this); } else if (Kind == Kind.Interface) { member_cache = new MemberCache (null, this); Type [] ifaces = TypeManager.GetInterfaces (TypeBuilder); for (int i = 0; i < ifaces.Length; ++i) member_cache.AddInterface (TypeManager.LookupMemberCache (ifaces [i])); } else { member_cache = new MemberCache (null, this); } if (types != null) foreach (TypeContainer tc in types) member_cache.AddNestedType (tc); if (delegates != null) foreach (Delegate d in delegates) member_cache.AddNestedType (d); if (partial_parts != null) { foreach (TypeContainer part in partial_parts) part.member_cache = member_cache; } if (!IsTopLevel) { MemberInfo conflict_symbol = Parent.PartialContainer.FindBaseMemberWithSameName (Basename, false); if (conflict_symbol == null) { if ((ModFlags & Modifiers.NEW) != 0) Report.Warning (109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ()); } else { if ((ModFlags & Modifiers.NEW) == 0) { Report.SymbolRelatedToPreviousError (conflict_symbol); Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol)); } } } DefineContainerMembers (constants); DefineContainerMembers (fields); if (Kind == Kind.Struct || Kind == Kind.Class) { pending = PendingImplementation.GetPendingImplementations (this); if (requires_delayed_unmanagedtype_check) { requires_delayed_unmanagedtype_check = false; foreach (FieldBase f in fields) { if (f.MemberType != null && f.MemberType.IsPointer) TypeManager.VerifyUnManaged (f.MemberType, f.Location); } } } // // Constructors are not in the defined_names array // DefineContainerMembers (instance_constructors); DefineContainerMembers (events); DefineContainerMembers (ordered_explicit_member_list); DefineContainerMembers (ordered_member_list); DefineContainerMembers (operators); DefineContainerMembers (delegates); ComputeIndexerName(); CheckEqualsAndGetHashCode(); if (CurrentType != null) { GenericType = CurrentType; } // // FIXME: This hack is needed because member cache does not work // with generic types, we rely on runtime to inflate dynamic types. // TODO: This hack requires member cache refactoring to be removed // if (TypeManager.IsGenericType (TypeBuilder)) member_cache = new MemberCache (this); return true; }