protected virtual bool DoDefineMembers () { Debug.Assert (!IsPartialPart); if (iface_exprs != null) { foreach (var iface_type in iface_exprs) { if (iface_type == null) continue; // Ensure the base is always setup var compiled_iface = iface_type.MemberDefinition as Interface; if (compiled_iface != null) compiled_iface.Define (); ObsoleteAttribute oa = iface_type.GetAttributeObsolete (); if (oa != null && !IsObsolete) AttributeTester.Report_ObsoleteMessage (oa, iface_type.GetSignatureForError (), Location, Report); if (iface_type.Arity > 0) { // TODO: passing `this' is wrong, should be base type iface instead TypeManager.CheckTypeVariance (iface_type, Variance.Covariant, this); if (((InflatedTypeSpec) iface_type).HasDynamicArgument () && !IsCompilerGenerated) { Report.Error (1966, Location, "`{0}': cannot implement a dynamic interface `{1}'", GetSignatureForError (), iface_type.GetSignatureForError ()); return false; } } if (iface_type.IsGenericOrParentIsGeneric) { foreach (var prev_iface in iface_exprs) { if (prev_iface == iface_type || prev_iface == null) break; if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface)) continue; Report.Error (695, Location, "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions", GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ()); } } } if (Kind == MemberKind.Interface) { foreach (var iface in spec.Interfaces) { MemberCache.AddInterface (iface); } } } if (base_type != null) { // // Run checks skipped during DefineType (e.g FullNamedExpression::ResolveAsType) // if (base_type_expr != null) { ObsoleteAttribute obsolete_attr = base_type.GetAttributeObsolete (); if (obsolete_attr != null && !IsObsolete) AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), base_type_expr.Location, Report); if (IsGenericOrParentIsGeneric && base_type.IsAttribute) { Report.Error (698, base_type_expr.Location, "A generic type cannot derive from `{0}' because it is an attribute class", base_type.GetSignatureForError ()); } } var baseContainer = base_type.MemberDefinition as ClassOrStruct; if (baseContainer != null) { baseContainer.Define (); // // It can trigger define of this type (for generic types only) // if (HasMembersDefined) return true; } } if (Kind == MemberKind.Struct || Kind == MemberKind.Class) { pending = PendingImplementation.GetPendingImplementations (this); } var count = members.Count; for (int i = 0; i < count; ++i) { var mc = members[i] as InterfaceMemberBase; if (mc == null || !mc.IsExplicitImpl) continue; try { mc.Define (); } catch (Exception e) { throw new InternalErrorException (mc, e); } } for (int i = 0; i < count; ++i) { var mc = members[i] as InterfaceMemberBase; if (mc != null && mc.IsExplicitImpl) continue; if (members[i] is TypeContainer) continue; try { members[i].Define (); } catch (Exception e) { throw new InternalErrorException (members[i], e); } } if (HasOperators) { CheckPairedOperators (); } if (requires_delayed_unmanagedtype_check) { requires_delayed_unmanagedtype_check = false; foreach (var member in members) { var f = member as Field; if (f != null && f.MemberType != null && f.MemberType.IsPointer) TypeManager.VerifyUnmanaged (Module, f.MemberType, f.Location); } } ComputeIndexerName(); if (HasEquals && !HasGetHashCode) { Report.Warning (659, 3, Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", GetSignatureForError ()); } if (Kind == MemberKind.Interface && iface_exprs != null) { MemberCache.RemoveHiddenMembers (spec); } return true; }
protected virtual bool DoDefineMembers () { if (iface_exprs != null) { foreach (var iface_type in iface_exprs) { if (iface_type == null) continue; // Ensure the base is always setup var compiled_iface = iface_type.MemberDefinition as Interface; if (compiled_iface != null) compiled_iface.Define (); if (Kind == MemberKind.Interface) MemberCache.AddInterface (iface_type); ObsoleteAttribute oa = iface_type.GetAttributeObsolete (); if (oa != null && !IsObsolete) AttributeTester.Report_ObsoleteMessage (oa, iface_type.GetSignatureForError (), Location, Report); if (iface_type.Arity > 0) { // TODO: passing `this' is wrong, should be base type iface instead TypeManager.CheckTypeVariance (iface_type, Variance.Covariant, this); if (((InflatedTypeSpec) iface_type).HasDynamicArgument () && !IsCompilerGenerated) { Report.Error (1966, Location, "`{0}': cannot implement a dynamic interface `{1}'", GetSignatureForError (), iface_type.GetSignatureForError ()); return false; } } if (iface_type.IsGenericOrParentIsGeneric) { if (spec.Interfaces != null) { foreach (var prev_iface in iface_exprs) { if (prev_iface == iface_type) break; if (!TypeSpecComparer.Unify.IsEqual (iface_type, prev_iface)) continue; Report.Error (695, Location, "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some type parameter substitutions", GetSignatureForError (), prev_iface.GetSignatureForError (), iface_type.GetSignatureForError ()); } } } } } if (base_type != null) { // // Run checks skipped during DefineType (e.g FullNamedExpression::ResolveAsType) // if (base_type_expr != null) { ObsoleteAttribute obsolete_attr = base_type.GetAttributeObsolete (); if (obsolete_attr != null && !IsObsolete) AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), base_type_expr.Location, Report); if (IsGeneric && base_type.IsAttribute) { Report.Error (698, base_type_expr.Location, "A generic type cannot derive from `{0}' because it is an attribute class", base_type.GetSignatureForError ()); } } if (base_type.Interfaces != null) { foreach (var iface in base_type.Interfaces) spec.AddInterface (iface); } var baseContainer = base_type.MemberDefinition as ClassOrStruct; if (baseContainer != null) { baseContainer.Define (); // // It can trigger define of this type (for generic types only) // if (HasMembersDefined) return true; } } DefineContainerMembers (constants); DefineContainerMembers (fields); if (Kind == MemberKind.Struct || Kind == MemberKind.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 (Module, 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); if (operators != null) { DefineContainerMembers (operators); CheckPairedOperators (); } ComputeIndexerName(); CheckEqualsAndGetHashCode(); if (Kind == MemberKind.Interface && iface_exprs != null) { MemberCache.RemoveHiddenMembers (spec); } return true; }
// // Factory method: if there are pending implementation methods, we return a PendingImplementation // object, otherwise we return null. // // Register method implementations are either abstract methods // flagged as such on the base class or interface methods // static public PendingImplementation GetPendingImplementations(TypeDefinition container) { TypeSpec b = container.BaseType; var missing_interfaces = GetMissingInterfaces(container); // // If we are implementing an abstract class, and we are not // ourselves abstract, and there are abstract methods (C# allows // abstract classes that have no abstract methods), then allocate // one slot. // // We also pre-compute the methods. // bool implementing_abstract = ((b != null) && b.IsAbstract && (container.ModFlags & Modifiers.ABSTRACT) == 0); MethodSpec[] abstract_methods = null; if (implementing_abstract) { var am = MemberCache.GetNotImplementedAbstractMethods(b); if (am == null) { implementing_abstract = false; } else { abstract_methods = new MethodSpec[am.Count]; am.CopyTo(abstract_methods, 0); } } int total = missing_interfaces.Length + (implementing_abstract ? 1 : 0); if (total == 0) { return(null); } var pending = new PendingImplementation(container, missing_interfaces, abstract_methods, total); // // check for inherited conflicting methods // foreach (var p in pending.pending_implementations) { // // It can happen for generic interfaces only // if (!p.type.IsGeneric) { continue; } // // CLR does not distinguishes between ref and out // for (int i = 0; i < p.methods.Count; ++i) { MethodSpec compared_method = p.methods[i]; if (compared_method.Parameters.IsEmpty) { continue; } for (int ii = i + 1; ii < p.methods.Count; ++ii) { MethodSpec tested_method = p.methods[ii]; if (compared_method.Name != tested_method.Name) { continue; } if (p.type != tested_method.DeclaringType) { continue; } if (!TypeSpecComparer.Override.IsSame(compared_method.Parameters.Types, tested_method.Parameters.Types)) { continue; } bool exact_match = true; bool ref_only_difference = false; var cp = compared_method.Parameters.FixedParameters; var tp = tested_method.Parameters.FixedParameters; for (int pi = 0; pi < cp.Length; ++pi) { // // First check exact modifiers match // if ((cp[pi].ModFlags & Parameter.Modifier.RefOutMask) == (tp[pi].ModFlags & Parameter.Modifier.RefOutMask)) { continue; } if (((cp[pi].ModFlags | tp[pi].ModFlags) & Parameter.Modifier.RefOutMask) == Parameter.Modifier.RefOutMask) { ref_only_difference = true; continue; } exact_match = false; break; } if (!exact_match || !ref_only_difference) { continue; } pending.Report.SymbolRelatedToPreviousError(compared_method); pending.Report.SymbolRelatedToPreviousError(tested_method); pending.Report.Error(767, container.Location, "Cannot implement interface `{0}' with the specified type parameters because it causes method `{1}' to differ on parameter modifiers only", p.type.GetDefinition().GetSignatureForError(), compared_method.GetSignatureForError()); break; } } } return(pending); }
// // Factory method: if there are pending implementation methods, we return a PendingImplementation // object, otherwise we return null. // // Register method implementations are either abstract methods // flagged as such on the base class or interface methods // static public PendingImplementation GetPendingImplementations (TypeContainer container) { TypeSpec b = container.BaseType; var missing_interfaces = GetMissingInterfaces (container); // // If we are implementing an abstract class, and we are not // ourselves abstract, and there are abstract methods (C# allows // abstract classes that have no abstract methods), then allocate // one slot. // // We also pre-compute the methods. // bool implementing_abstract = ((b != null) && b.IsAbstract && (container.ModFlags & Modifiers.ABSTRACT) == 0); MethodSpec[] abstract_methods = null; if (implementing_abstract){ var am = MemberCache.GetNotImplementedAbstractMethods (b); if (am == null) { implementing_abstract = false; } else { abstract_methods = new MethodSpec[am.Count]; am.CopyTo (abstract_methods, 0); } } int total = missing_interfaces.Length + (implementing_abstract ? 1 : 0); if (total == 0) return null; var pending = new PendingImplementation (container, missing_interfaces, abstract_methods, total); // // check for inherited conflicting methods // foreach (var p in pending.pending_implementations) { // // It can happen for generic interfaces only // if (!p.type.IsGeneric) continue; // // CLR does not distinguishes between ref and out // for (int i = 0; i < p.methods.Count; ++i) { MethodSpec compared_method = p.methods[i]; if (compared_method.Parameters.IsEmpty) continue; for (int ii = i + 1; ii < p.methods.Count; ++ii) { MethodSpec tested_method = p.methods[ii]; if (compared_method.Name != tested_method.Name) continue; if (p.type != tested_method.DeclaringType) continue; if (!TypeSpecComparer.Override.IsSame (compared_method.Parameters.Types, tested_method.Parameters.Types)) continue; bool exact_match = true; bool ref_only_difference = false; var cp = compared_method.Parameters.FixedParameters; var tp = tested_method.Parameters.FixedParameters; for (int pi = 0; pi < cp.Length; ++pi) { // // First check exact modifiers match // const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT; if ((cp[pi].ModFlags & ref_out) == (tp[pi].ModFlags & ref_out)) continue; if ((cp[pi].ModFlags & tp[pi].ModFlags & Parameter.Modifier.ISBYREF) != 0) { ref_only_difference = true; continue; } exact_match = false; break; } if (!exact_match || !ref_only_difference) continue; pending.Report.SymbolRelatedToPreviousError (compared_method); pending.Report.SymbolRelatedToPreviousError (tested_method); pending.Report.Error (767, container.Location, "Cannot implement interface `{0}' with the specified type parameters because it causes method `{1}' to differ on parameter modifiers only", p.type.GetDefinition().GetSignatureForError (), compared_method.GetSignatureForError ()); break; } } } return pending; }
protected virtual bool DoDefineMembers () { if (iface_exprs != null) { foreach (TypeExpr iface in iface_exprs) { if (iface == null) continue; var iface_type = iface.Type; // Ensure the base is always setup var compiled_iface = iface_type.MemberDefinition as Interface; if (compiled_iface != null) compiled_iface.Define (); if (Kind == MemberKind.Interface) MemberCache.AddInterface (iface_type); ObsoleteAttribute oa = iface_type.GetAttributeObsolete (); 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); ct.CheckConstraints (this); if (ct.HasDynamicArguments () && !IsCompilerGenerated) { Report.Error (1966, iface.Location, "`{0}': cannot implement a dynamic interface `{1}'", GetSignatureForError (), iface.GetSignatureForError ()); return false; } } } } if (base_type != null) { ObsoleteAttribute obsolete_attr = base_type.GetAttributeObsolete (); if (obsolete_attr != null && !IsObsolete) AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), Location, Report); var ct = base_type_expr as GenericTypeExpr; if (ct != null) ct.CheckConstraints (this); if (base_type.Interfaces != null) { foreach (var iface in base_type.Interfaces) spec.AddInterface (iface); } var baseContainer = base_type.MemberDefinition as ClassOrStruct; if (baseContainer != null) { baseContainer.Define (); // // It can trigger define of this type (for generic types only) // if (HasMembersDefined) return true; } } if (type_params != null) { foreach (var tp in type_params) { tp.CheckGenericConstraints (); } } DefineContainerMembers (constants); DefineContainerMembers (fields); if (Kind == MemberKind.Struct || Kind == MemberKind.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 (Module, 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); if (operators != null) { DefineContainerMembers (operators); CheckPairedOperators (); } ComputeIndexerName(); CheckEqualsAndGetHashCode(); if (Kind == MemberKind.Interface && iface_exprs != null) { MemberCache.RemoveHiddenMembers (spec); } return true; }
protected virtual bool DoDefineMembers () { if (iface_exprs != null) { foreach (TypeExpr iface in iface_exprs) { var iface_type = iface.Type; // Ensure the base is always setup var compiled_iface = iface_type.MemberDefinition as Interface; if (compiled_iface != null) compiled_iface.Define (); if (Kind == MemberKind.Interface) MemberCache.AddInterface (iface_type); ObsoleteAttribute oa = iface_type.GetAttributeObsolete (); 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); ct.CheckConstraints (this); if (ct.HasDynamicArguments ()) { Report.Error (1966, iface.Location, "`{0}': cannot implement a dynamic interface `{1}'", GetSignatureForError (), iface.GetSignatureForError ()); return false; } } } } if (base_type_expr != null) { ObsoleteAttribute obsolete_attr = base_type.GetAttributeObsolete (); if (obsolete_attr != null && !IsObsolete) AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), Location, Report); var ct = base_type_expr as GenericTypeExpr; if (ct != null) ct.CheckConstraints (this); } if (base_type != null) { var baseContainer = base_type.MemberDefinition as ClassOrStruct; if (baseContainer != null) { baseContainer.Define (); // // It can trigger define of this type (for generic types only) // if (HasMembersDefined) return true; } } if (type_params != null) { foreach (var tp in type_params) { tp.CheckGenericConstraints (); } } if (!IsTopLevel) { MemberSpec candidate; var conflict_symbol = MemberCache.FindBaseMember (this, out candidate); if (conflict_symbol == null && candidate == 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) { if (candidate == null) candidate = conflict_symbol; Report.SymbolRelatedToPreviousError (candidate); Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended", GetSignatureForError (), candidate.GetSignatureForError ()); } } } DefineContainerMembers (constants); DefineContainerMembers (fields); if (Kind == MemberKind.Struct || Kind == MemberKind.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 (Compiler, 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); if (operators != null) { DefineContainerMembers (operators); CheckPairedOperators (); } ComputeIndexerName(); CheckEqualsAndGetHashCode(); return true; }
/// <summary> /// Populates our TypeBuilder with fields and methods /// </summary> public override bool DefineMembers (TypeContainer parent) { MemberInfo [] defined_names = null; if (interface_order != null){ foreach (Interface iface in interface_order) if ((iface.ModFlags & Modifiers.NEW) == 0) iface.DefineMembers (this); else Error_KeywordNotAllowed (iface.Location); } if (RootContext.WarningLevel > 1){ Type ptype; // // This code throws an exception in the comparer // I guess the string is not an object? // ptype = TypeBuilder.BaseType; if (ptype != null){ defined_names = (MemberInfo []) FindMembers ( ptype, MemberTypes.All & ~MemberTypes.Constructor, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static, null, null); Array.Sort (defined_names, mif_compare); } } if (constants != null) DefineMembers (constants, defined_names); if (fields != null) DefineMembers (fields, defined_names); if (this is Class){ if (instance_constructors == null){ if (default_constructor == null) DefineDefaultConstructor (false); } if (initialized_static_fields != null && default_static_constructor == null) DefineDefaultConstructor (true); } if (this is Struct){ // // Structs can not have initialized instance // fields // if (initialized_static_fields != null && default_static_constructor == null) DefineDefaultConstructor (true); if (initialized_fields != null) ReportStructInitializedInstanceError (); } Pending = PendingImplementation.GetPendingImplementations (this); // // Constructors are not in the defined_names array // if (instance_constructors != null) DefineMembers (instance_constructors, null); if (default_static_constructor != null) default_static_constructor.Define (this); if (methods != null) DefineMembers (methods, defined_names); if (properties != null) DefineMembers (properties, defined_names); if (events != null) DefineMembers (events, defined_names); if (indexers != null) { DefineIndexers (); } else IndexerName = "Item"; if (operators != null){ DefineMembers (operators, null); CheckPairedOperators (); } if (enums != null) DefineMembers (enums, defined_names); if (delegates != null) DefineMembers (delegates, defined_names); #if CACHE if (TypeBuilder.BaseType != null) parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType); member_cache = new MemberCache (this); #endif return true; }
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; }