📄 class.cs
字号:
if (name == null){ return null; } if (!name.IsInterface) { // base_class could be a class, struct, enum, delegate. // This is validated in GetClassBases. base_class = name; start = 1; } } TypeExpr [] ifaces = new TypeExpr [count-start]; for (i = start, j = 0; i < count; i++, j++){ TypeExpr resolved = ResolveBaseTypeExpr ((Expression) Bases [i], false, Location); if (resolved == null) { return null; } ifaces [j] = resolved; } return ifaces; } /// <summary> /// This function computes the Base class and also the /// list of interfaces that the class or struct @c implements. /// /// The return value is an array (might be null) of /// interfaces implemented (as Types). /// /// The @base_class argument is set to the base object or null /// if this is `System.Object'. /// </summary> TypeExpr [] GetClassBases (out TypeExpr base_class) { int i; TypeExpr[] ifaces; if (parts != null) ifaces = GetPartialBases (out base_class); else if (Bases == null){ base_class = null; return null; } else ifaces = GetNormalBases (out base_class); if (ifaces == null) return null; if ((base_class != null) && (Kind == Kind.Class)){ if (base_class.Type.IsArray || base_class.Type.IsPointer) { Report.Error (1521, base_class.Location, "Invalid base type"); return null; } if (base_class.IsSealed){ Report.SymbolRelatedToPreviousError (base_class.Type); if (base_class.Type.IsAbstract) { Report.Error (709, Location, "`{0}': Cannot derive from static class `{1}'", GetSignatureForError (), TypeManager.CSharpName (base_class.Type)); } else { Report.Error (509, Location, "`{0}': cannot derive from sealed class `{1}'", GetSignatureForError (), TypeManager.CSharpName (base_class.Type)); } return null; } if (!base_class.CanInheritFrom ()){ Report.Error (644, Location, "`{0}' cannot derive from special class `{1}'", GetSignatureForError (), base_class.GetSignatureForError ()); return null; } if (!base_class.AsAccessible (this, ModFlags)) { Report.SymbolRelatedToPreviousError (base_class.Type); Report.Error (60, Location, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'", TypeManager.CSharpName (base_class.Type), GetSignatureForError ()); } } if (base_class != null) base_class_name = base_class.Name; if (ifaces == null) return null; int count = ifaces != null ? ifaces.Length : 0; for (i = 0; i < count; i++) { TypeExpr iface = (TypeExpr) ifaces [i]; if (!iface.IsInterface) { if (Kind != Kind.Class) { // TODO: location of symbol related .... Error_TypeInListIsNotInterface (Location, iface.FullName); } else if (base_class != null) Report.Error (1721, Location, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')", GetSignatureForError (), base_class.GetSignatureForError (), iface.GetSignatureForError ()); else { Report.Error (1722, Location, "`{0}': Base class `{1}' must be specified as first", GetSignatureForError (), iface.GetSignatureForError ()); } return null; } for (int x = 0; x < i; x++) { if (iface.Equals (ifaces [x])) { Report.Error (528, Location, "`{0}' is already listed in " + "interface list", iface.Name); return null; } } if ((Kind == Kind.Interface) && !iface.AsAccessible (Parent, ModFlags)) { Report.Error (61, Location, "Inconsistent accessibility: base " + "interface `{0}' is less accessible " + "than interface `{1}'", iface.Name, Name); return null; } } return ifaces; } bool error = false; protected void Error_TypeInListIsNotInterface (Location loc, string type) { Report.Error (527, loc, "Type `{0}' in interface list is not an interface", type); } // // Defines the type in the appropriate ModuleBuilder or TypeBuilder. // public override TypeBuilder DefineType () { if (error) return null; if (TypeBuilder != null) return TypeBuilder; TypeAttributes type_attributes = TypeAttr; try { if (IsTopLevel){ if (TypeManager.NamespaceClash (Name, Location)) { error = true; return null; } ModuleBuilder builder = CodeGen.Module.Builder; TypeBuilder = builder.DefineType ( Name, type_attributes, null, null); } else { TypeBuilder builder = Parent.TypeBuilder; if (builder == null) { error = true; return null; } TypeBuilder = builder.DefineNestedType ( Basename, type_attributes, ptype, null); } } catch (ArgumentException) { Report.RuntimeMissingSupport (Location, "static classes"); error = true; return null; } TypeManager.AddUserType (this); if (Parts != null) { ec = null; foreach (ClassPart part in Parts) { part.TypeBuilder = TypeBuilder; part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags); part.ec.ContainerType = TypeBuilder; } } else { // // Normally, we create the EmitContext here. // The only exception is if we're an Iterator - in this case, // we already have the `ec', so we don't want to create a new one. // if (ec == null) ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags); ec.ContainerType = TypeBuilder; } iface_exprs = GetClassBases (out base_type); if (iface_exprs == null && base_type != null) { error = true; return null; } // // GetClassBases calls ResolveBaseTypeExpr() on the various type expressions involved, // which in turn should have called DefineType()s on base types if necessary. // // None of the code below should trigger DefineType()s on classes that we depend on. // Thus, we are eligible to be on the topological sort `type_container_resolve_order'. // // Let's do it as soon as possible, since code below can call DefineType() on classes // that depend on us to be populated before they are. // if (!(this is Iterator)) RootContext.RegisterOrder (this); if (base_type == null) { if (Kind == Kind.Class){ if (RootContext.StdLib) base_type = TypeManager.system_object_expr; else if (Name != "System.Object") base_type = TypeManager.system_object_expr; } else if (Kind == Kind.Struct) { // // If we are compiling our runtime, // and we are defining ValueType, then our // base is `System.Object'. // if (!RootContext.StdLib && Name == "System.ValueType") base_type = TypeManager.system_object_expr; else base_type = TypeManager.system_valuetype_expr; } } if ((Kind == Kind.Struct) && TypeManager.value_type == null) throw new Exception (); // Avoid attributes check when parent is not set TypeResolveEmitContext.TestObsoleteMethodUsage = false; if (base_type != null) { // FIXME: I think this should be ...ResolveType (Parent.EmitContext). // However, if Parent == RootContext.Tree.Types, its NamespaceEntry will be null. ptype = base_type.ResolveType (TypeResolveEmitContext); if (ptype == null) { error = true; return null; } } if (!CheckRecursiveDefinition (this)) { error = true; return null; } if (ptype != null) { TypeBuilder.SetParent (ptype); } // Attribute is undefined at the begining of corlib compilation if (TypeManager.obsolete_attribute_type != null) { TypeResolveEmitContext.TestObsoleteMethodUsage = GetObsoleteAttribute () == null; if (ptype != null && TypeResolveEmitContext.TestObsoleteMethodUsage) { CheckObsoleteType (base_type); } } // add interfaces that were not added at type creation if (iface_exprs != null) { // FIXME: I think this should be ...ExpandInterfaces (Parent.EmitContext, ...). // However, if Parent == RootContext.Tree.Types, its NamespaceEntry will be null. TypeResolveEmitContext.ContainerType = TypeBuilder; ifaces = TypeManager.ExpandInterfaces (TypeResolveEmitContext, iface_exprs); if (ifaces == null) { error = true; return null; } foreach (Type itype in ifaces) TypeBuilder.AddInterfaceImplementation (itype); TypeManager.RegisterBuilder (TypeBuilder, ifaces); } if (!DefineNestedTypes ()) { error = true; return null; } return TypeBuilder; } protected virtual bool DefineNestedTypes () { if (Interfaces != null) { foreach (TypeContainer iface in Interfaces) if (iface.DefineType () == null) return false; } if (Types != null) { foreach (TypeContainer tc in Types) if (tc.DefineType () == null) return false; } if (Delegates != null) { foreach (Delegate d in Delegates) if (d.DefineType () == null) return false; } if (Enums != null) { foreach (Enum en in Enums) if (en.DefineType () == null) return false; } return true; } TypeContainer InTransit; protected bool CheckRecursiveDefinition (TypeContainer tc) { if (InTransit != null) { Report.SymbolRelatedToPreviousError (this); if (this is Interface) Report.Error ( 529, tc.Location, "Inherited interface `{0}' causes a " + "cycle in the interface hierarchy of `{1}'", GetSignatureForError (), tc.GetSignatureForError ()); else Report.Error ( 146, tc.Location, "Circular base class dependency " + "involving `{0}' and `{1}'", tc.GetSignatureForError (), GetSignatureForError ()); return false; } InTransit = tc; Type parent = ptype; if (parent != null) { TypeContainer ptc = TypeManager.LookupTypeContainer (parent); if ((ptc != null) && !ptc.CheckRecursiveDefinition (this)) return false; } if (iface_exprs != null) { foreach (TypeExpr iface in iface_exprs) { Type itype = iface.Type; TypeContainer ptc = TypeManager.LookupTypeContainer (itype); if ((ptc != null) && !ptc.CheckRecursiveDefinition (this)) return false; } } InTransit = null; return true; } public static void Error_KeywordNotAllowed (Location loc) { Report.Error (1530, loc, "Keyword `new' is not allowed on namespace elements"); } /// <summary> /// Populates our TypeBuilder with fields and methods /// </summary> public override bool DefineMembers (TypeContainer container) { if (members_defined) return members_defined_ok; if (!base.DefineMembers (container)) return false; members_defined_ok = DoDefineMembers (); members_defined = true; return members_defined_ok; } protected virtual bool DoDefineMembers () { if (!IsTopLevel) { MemberInfo conflict_symbol = Parent.MemberCache.FindMemberWithSameName (Basename, false, TypeBuilder); if (conflict_symbol == null) { if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) Report.Warning (109, 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, 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.Class) && !(this is ClassPart)){ if ((instance_constructors == null) && !(this is StaticClass)) { if (default_constructor == null) DefineDefaultConstructor (false); } if (initialized_static_fields != null && default_static_constructor == null) DefineDefaultConstructor (true); } if (Kind == Kind.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 = GetPendingImplementations (); if (parts != null) { foreach (ClassPart part in parts) { if (!part.DefineMembers (this)) return false; } } // // Constructors are not in the defined_names array // DefineContainerMembers (instance_constructors); if (default_static_constructor != null) default_static_constructor.Define (); DefineContainerMembers (properties); DefineContainerMembers (events); DefineContainerMembers (indexers); DefineContainerMembers (methods); DefineContainerMembers (operators); DefineContainerMembers (enums); DefineContainerMembers (delegates); #if CACHE if (!(this is ClassPart)) member_cache = new MemberCache (this);#endif if (parts != null) { foreach (ClassPart part in parts) part.member_cache = member_cache; } if (iterators != null) { foreach (Iterator iterator in iterators) { if (iterator.DefineType () == null) return false; } foreach (Iterator iterator in iterators) { if (!iterator.DefineMembers (this)) return false; } } return true; } void ReportStructInitializedInstanceError () { foreach (Field f in initialized_fields){ Report.Error (573, Location, "`{0}': Structs cannot have instance field initializers", f.GetSignatureForError ()); } } protected virtual void DefineContainerMembers (MemberCoreArrayList mcal) { if (mcal != null) mcal.DefineContainerMembers (); } public override bool Define () { if (parts != null) { foreach (ClassPart part in parts) { if (!part.Define ()) return false; } } if (iterators != null) { foreach (Iterator iterator in iterators) { if (!iterator.Define ()) return false; } } return true; } public MemberInfo FindBaseMemberWithSameName (string name, bool ignore_methods) { return BaseCache.FindMemberWithSameName (name, ignore_methods, null); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -