X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fclass.cs;h=a1743872a6d08925e7e16df67c0940498ef13b58;hb=10cb6579aaac6b4704cc0ad324dc4fcefbb085a9;hp=bbf1c658b8275aa507b09aec6f6d98d163b810dd;hpb=51390733045784b6ca9a24ef5469c2a1e7f70a07;p=mono.git diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs old mode 100755 new mode 100644 index bbf1c658b82..a1743872a6d --- a/mcs/mcs/class.cs +++ b/mcs/mcs/class.cs @@ -2,12 +2,13 @@ // class.cs: Class and Struct handlers // // Authors: Miguel de Icaza (miguel@gnu.org) -// Martin Baulig (martin@gnome.org) +// Martin Baulig (martin@ximian.com) // Marek Safar (marek.safar@seznam.cz) // // Licensed under the terms of the GNU GPL // // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com) +// (C) 2004 Novell, Inc // // // 2002-10-11 Miguel de Icaza @@ -41,6 +42,12 @@ using System.Security; using System.Security.Permissions; using System.Text; +#if BOOTSTRAP_WITH_OLDLIB +using XmlElement = System.Object; +#else +using System.Xml; +#endif + using Mono.CompilerServices.SymbolWriter; namespace Mono.CSharp { @@ -421,13 +428,6 @@ namespace Mono.CSharp { // Holds the parts of a partial class; ArrayList parts; - // The emit context for toplevel objects. - EmitContext ec; - - public EmitContext EmitContext { - get { return ec; } - } - // // Pointers to the default constructor and the default static constructor // @@ -444,7 +444,7 @@ namespace Mono.CSharp { // from classes from the arraylist `type_bases' // string base_class_name; - public Type base_class_type; + TypeExpr base_type; ArrayList type_bases; @@ -452,11 +452,11 @@ namespace Mono.CSharp { bool members_defined_ok; // The interfaces we implement. - TypeExpr [] ifaces; - protected Type[] base_inteface_types; + protected Type [] ifaces; + protected Type ptype; - // The parent member container and our member cache - IMemberContainer parent_container; + // The base member cache and our member cache + MemberCache base_cache; MemberCache member_cache; public const string DefaultIndexerName = "Item"; @@ -472,19 +472,19 @@ namespace Mono.CSharp { base_class_name = null; } - public bool AddToMemberContainer (MemberCore symbol, bool is_method) + public bool AddToMemberContainer (MemberCore symbol) { - return AddToContainer (symbol, is_method, String.Concat (Name, '.', symbol.Name), symbol.Name); + return AddToContainer (symbol, String.Concat (Name, '.', symbol.Name), symbol.Name); } bool AddToTypeContainer (DeclSpace ds) { - return AddToContainer (ds, false, ds.Name, ds.Basename); + return AddToContainer (ds, ds.Name, ds.Basename); } public void AddConstant (Const constant) { - if (!AddToMemberContainer (constant, false)) + if (!AddToMemberContainer (constant)) return; if (constants == null) @@ -525,7 +525,7 @@ namespace Mono.CSharp { public void AddMethod (Method method) { - if (!AddToMemberContainer (method, true)) + if (!AddToMemberContainer (method)) return; if (methods == null) @@ -590,7 +590,7 @@ namespace Mono.CSharp { public void AddField (Field field) { - if (!AddToMemberContainer (field, false)) + if (!AddToMemberContainer (field)) return; if (fields == null) @@ -618,8 +618,8 @@ namespace Mono.CSharp { public void AddProperty (Property prop) { - if (!AddToMemberContainer (prop, false) || - !AddToMemberContainer (prop.Get, true) || !AddToMemberContainer (prop.Set, true)) + if (!AddToMemberContainer (prop) || + !AddToMemberContainer (prop.Get) || !AddToMemberContainer (prop.Set)) return; if (properties == null) @@ -633,14 +633,14 @@ namespace Mono.CSharp { public void AddEvent (Event e) { - if (!AddToMemberContainer (e, false)) + if (!AddToMemberContainer (e)) return; if (e is EventProperty) { - if (!AddToMemberContainer (e.Add, true)) + if (!AddToMemberContainer (e.Add)) return; - if (!AddToMemberContainer (e.Remove, true)) + if (!AddToMemberContainer (e.Remove)) return; } @@ -667,7 +667,7 @@ namespace Mono.CSharp { public void AddOperator (Operator op) { - if (!AddToMemberContainer (op, true)) + if (!AddToMemberContainer (op)) return; if (operators == null) @@ -713,7 +713,16 @@ namespace Mono.CSharp { public override AttributeTargets AttributeTargets { get { - throw new NotSupportedException (); + switch (Kind) { + case Kind.Class: + return AttributeTargets.Class; + case Kind.Struct: + return AttributeTargets.Struct; + case Kind.Interface: + return AttributeTargets.Interface; + default: + throw new NotSupportedException (); + } } } @@ -907,38 +916,38 @@ namespace Mono.CSharp { public abstract PendingImplementation GetPendingImplementations (); - TypeExpr[] GetPartialBases (out TypeExpr parent, out bool error) + TypeExpr[] GetPartialBases (out TypeExpr base_class, out bool error) { ArrayList ifaces = new ArrayList (); - parent = null; - Location parent_loc = Location.Null; + base_class = null; + Location base_loc = Location.Null; foreach (ClassPart part in parts) { - TypeExpr new_parent; + TypeExpr new_base_class; TypeExpr[] new_ifaces; - new_ifaces = part.GetClassBases (out new_parent, out error); + new_ifaces = part.GetClassBases (out new_base_class, out error); if (error) return null; - if ((parent != null) && (new_parent != null) && - !parent.Equals (new_parent)) { + if ((base_class != null) && (new_base_class != null) && + !base_class.Equals (new_base_class)) { Report.Error (263, part.Location, "Partial declarations of `{0}' must " + "not specify different base classes", Name); - if (!Location.IsNull (parent_loc)) - Report.LocationOfPreviousError (parent_loc); + if (!Location.IsNull (base_loc)) + Report.LocationOfPreviousError (base_loc); error = true; return null; } - if ((parent == null) && (new_parent != null)) { - parent = new_parent; - parent_loc = part.Location; + if ((base_class == null) && (new_base_class != null)) { + base_class = new_base_class; + base_loc = part.Location; } if (new_ifaces == null) @@ -965,15 +974,15 @@ namespace Mono.CSharp { return retval; } - TypeExpr[] GetNormalBases (out TypeExpr parent, out bool error) + TypeExpr[] GetNormalBases (out TypeExpr base_class, out bool error) { - parent = null; + base_class = null; int count = Bases.Count; - int start, i, j; + int start = 0, i, j; if (Kind == Kind.Class){ - TypeExpr name = ResolveTypeExpr ( + TypeExpr name = ResolveBaseTypeExpr ( (Expression) Bases [0], false, Location); if (name == null){ @@ -981,21 +990,18 @@ namespace Mono.CSharp { return null; } - if (name.IsClass){ - parent = name; + if (!name.IsInterface) { + // base_class could be a class, struct, enum, delegate. + // This is validated in GetClassBases. + base_class = name; start = 1; - } else { - start = 0; } - } else { - start = 0; } TypeExpr [] ifaces = new TypeExpr [count-start]; for (i = start, j = 0; i < count; i++, j++){ - Expression name = (Expression) Bases [i]; - TypeExpr resolved = ResolveTypeExpr (name, false, Location); + TypeExpr resolved = ResolveBaseTypeExpr ((Expression) Bases [i], false, Location); if (resolved == null) { error = true; return null; @@ -1015,10 +1021,10 @@ namespace Mono.CSharp { /// The return value is an array (might be null) of /// interfaces implemented (as Types). /// - /// The @parent argument is set to the parent object or null + /// The @base_class argument is set to the base object or null /// if this is `System.Object'. /// - TypeExpr [] GetClassBases (out TypeExpr parent, out bool error) + TypeExpr [] GetClassBases (out TypeExpr base_class, out bool error) { int i; @@ -1027,21 +1033,28 @@ namespace Mono.CSharp { TypeExpr[] ifaces; if (parts != null) - ifaces = GetPartialBases (out parent, out error); + ifaces = GetPartialBases (out base_class, out error); else if (Bases == null){ - parent = null; + base_class = null; return null; } else - ifaces = GetNormalBases (out parent, out error); + ifaces = GetNormalBases (out base_class, out error); if (error) return null; - if ((parent != null) && (Kind == Kind.Class)){ - if (parent.IsSealed){ + 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"); error = true; - Report.SymbolRelatedToPreviousError (parent.Type); - if (parent.Type.IsAbstract) { + return null; + } + + if (base_class.IsSealed){ + error = true; + Report.SymbolRelatedToPreviousError (base_class.Type); + if (base_class.Type.IsAbstract) { Report.Error (709, Location, "'{0}': Cannot derive from static class", GetSignatureForError ()); } else { Report.Error (509, Location, "'{0}': Cannot derive from sealed class", GetSignatureForError ()); @@ -1049,23 +1062,23 @@ namespace Mono.CSharp { return null; } - if (!parent.CanInheritFrom ()){ + if (!base_class.CanInheritFrom ()){ Report.Error (644, Location, "`{0}' cannot inherit from special class `{1}'", - Name, parent.Name); + Name, base_class.Name); error = true; return null; } - if (!parent.AsAccessible (this, ModFlags)) - Report.Error (60, Location, - "Inconsistent accessibility: base class `" + - parent.Name + "' is less accessible than class `" + - Name + "'"); + 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 (parent != null) - base_class_name = parent.Name; + if (base_class != null) + base_class_name = base_class.Name; if (ifaces == null) return null; @@ -1075,25 +1088,25 @@ namespace Mono.CSharp { for (i = 0; i < count; i++) { TypeExpr iface = (TypeExpr) ifaces [i]; - if ((Kind != Kind.Class) && !iface.IsInterface){ - string what = Kind == Kind.Struct ? - "Struct" : "Interface"; - - Report.Error (527, Location, - "In {0} `{1}', type `{2}' is not "+ - "an interface", what, Name, iface.Name); + if (!iface.IsInterface) { error = true; - return null; - } - - if (iface.IsClass) { - if (parent != null){ + if (Kind != Kind.Class) { + string what = Kind == Kind.Struct ? "Struct" : "Interface"; + Report.Error (527, Location, + "In {0} `{1}', type `{2}' is not "+ + "an interface", what, Name, iface.Name); + } + else if (base_class != null) + Report.Error (1721, Location, + "In Class `{0}', `{1}' is not an interface, and a base class has already been defined", + Name, iface.Name); + else { + Report.Error (1722, Location, "In Class `{0}', `{1}' is not " + - "an interface", Name, iface.Name); - error = true; - return null; + "an interface, a base class must be listed first", Name, iface.Name); } + continue; } for (int x = 0; x < i; x++) { @@ -1102,20 +1115,24 @@ namespace Mono.CSharp { "`{0}' is already listed in " + "interface list", iface.Name); error = true; - return null; } } if ((Kind == Kind.Interface) && - !iface.AsAccessible (Parent, ModFlags)) + !iface.AsAccessible (Parent, ModFlags)) { Report.Error (61, Location, "Inconsistent accessibility: base " + "interface `{0}' is less accessible " + "than interface `{1}'", iface.Name, Name); + error = true; + } } - return TypeManager.ExpandInterfaces (ifaces); + if (error) + return null; + + return ifaces; } bool error = false; @@ -1125,8 +1142,6 @@ namespace Mono.CSharp { // public override TypeBuilder DefineType () { - TypeExpr parent; - if (TypeBuilder != null) return TypeBuilder; @@ -1143,26 +1158,26 @@ namespace Mono.CSharp { ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags); - ifaces = GetClassBases (out parent, out error); + TypeExpr[] iface_exprs = GetClassBases (out base_type, out error); if (error) return null; - if (parent == null) { + if (base_type == null) { if (Kind == Kind.Class){ if (RootContext.StdLib) - parent = TypeManager.system_object_expr; + base_type = TypeManager.system_object_expr; else if (Name != "System.Object") - parent = TypeManager.system_object_expr; + base_type = TypeManager.system_object_expr; } else if (Kind == Kind.Struct) { // // If we are compiling our runtime, // and we are defining ValueType, then our - // parent is `System.Object'. + // base is `System.Object'. // if (!RootContext.StdLib && Name == "System.ValueType") - parent = TypeManager.system_object_expr; + base_type = TypeManager.system_object_expr; else - parent = TypeManager.system_valuetype_expr; + base_type = TypeManager.system_valuetype_expr; } } @@ -1171,9 +1186,11 @@ namespace Mono.CSharp { TypeAttributes type_attributes = TypeAttr; - if (parent != null) { - base_class_type = parent.ResolveType (ec); - if (base_class_type == null) { + 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 (ec); + if (ptype == null) { error = true; return null; } @@ -1188,7 +1205,7 @@ namespace Mono.CSharp { ModuleBuilder builder = CodeGen.Module.Builder; TypeBuilder = builder.DefineType ( - Name, type_attributes, base_class_type, null); + Name, type_attributes, ptype, null); } else { TypeBuilder builder = Parent.DefineType (); @@ -1196,7 +1213,7 @@ namespace Mono.CSharp { return null; TypeBuilder = builder.DefineNestedType ( - Basename, type_attributes, base_class_type, null); + Basename, type_attributes, ptype, null); } } catch (ArgumentException) { @@ -1217,20 +1234,19 @@ namespace Mono.CSharp { } // add interfaces that were not added at type creation - if (ifaces != null) { - base_inteface_types = new Type[ifaces.Length]; - for (int i = 0; i < ifaces.Length; ++i) { - Type itype = ifaces [i].ResolveType (ec); - if (itype == null) { - error = true; - continue; - } - TypeBuilder.AddInterfaceImplementation (itype); - base_inteface_types [i] = itype; + if (iface_exprs != null) { + // FIXME: I think this should be ...ExpandInterfaces (Parent.EmitContext, ...). + // However, if Parent == RootContext.Tree.Types, its NamespaceEntry will be null. + ifaces = TypeManager.ExpandInterfaces (ec, iface_exprs); + if (ifaces == null) { + error = true; + return null; } - if (error) - return null; + foreach (Type itype in ifaces) + TypeBuilder.AddInterfaceImplementation (itype); + + TypeManager.RegisterBuilder (TypeBuilder, ifaces); } // @@ -1238,9 +1254,9 @@ namespace Mono.CSharp { // ec.ContainerType = TypeBuilder; - TypeManager.AddUserType (Name, TypeBuilder, this, ifaces); + TypeManager.AddUserType (Name, TypeBuilder, this); - if ((parent != null) && parent.IsAttribute) { + if ((base_type != null) && base_type.IsAttribute) { RootContext.RegisterAttribute (this); } else if (!(this is Iterator)) RootContext.RegisterOrder (this); @@ -1283,7 +1299,7 @@ namespace Mono.CSharp { if (Parts != null) { foreach (ClassPart part in Parts) { part.TypeBuilder = TypeBuilder; - part.base_class_type = base_class_type; + part.ptype = ptype; part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags); } } @@ -1316,10 +1332,10 @@ namespace Mono.CSharp { // We need to be able to use the member cache while we are checking/defining // if (TypeBuilder.BaseType != null) - parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType); + base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType); if (TypeBuilder.IsInterface) - parent_container = TypeManager.LookupInterfaceContainer (base_inteface_types); + base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder); if (IsTopLevel) { if ((ModFlags & Modifiers.NEW) != 0) @@ -1400,7 +1416,7 @@ namespace Mono.CSharp { #if CACHE if (!(this is ClassPart)) - member_cache = new MemberCache (this, false); + member_cache = new MemberCache (this); #endif if (parts != null) { @@ -1453,9 +1469,9 @@ namespace Mono.CSharp { return true; } - public MemberInfo FindMemberWithSameName (string name, bool ignore_methods) + public MemberInfo FindBaseMemberWithSameName (string name, bool ignore_methods) { - return ParentContainer.MemberCache.FindMemberWithSameName (name, ignore_methods, null); + return BaseCache.FindMemberWithSameName (name, ignore_methods, null); } /// @@ -1915,7 +1931,7 @@ namespace Mono.CSharp { } // - // Lookup members in parent if requested. + // Lookup members in base if requested. // if ((bf & BindingFlags.DeclaredOnly) == 0) { if (TypeBuilder.BaseType != null) { @@ -1927,8 +1943,8 @@ namespace Mono.CSharp { members.AddRange (list); } } - if (base_inteface_types != null) { - foreach (Type base_type in base_inteface_types) { + if (ifaces != null) { + foreach (Type base_type in ifaces) { MemberList list = TypeContainer.FindMembers (base_type, mt, bf, filter, criteria); if (list.Count > 0) { @@ -1992,7 +2008,7 @@ namespace Mono.CSharp { // // Check for internal or private fields that were never assigned // - if (RootContext.WarningLevel >= 3) { + if (RootContext.WarningLevel >= 4) { if (fields != null){ foreach (Field f in fields) { if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE) @@ -2172,7 +2188,7 @@ namespace Mono.CSharp { type_bases = null; OptAttributes = null; ifaces = null; - parent_container = null; + base_cache = null; member_cache = null; } @@ -2186,36 +2202,34 @@ namespace Mono.CSharp { // Performs the validation on a Method's modifiers (properties have // the same properties). // - public bool MethodModifiersValid (int flags, string n, Location loc) + public bool MethodModifiersValid (MemberCore mc) { const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE); const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT); const int nv = (Modifiers.NEW | Modifiers.VIRTUAL); bool ok = true; + int flags = mc.ModFlags; // // At most one of static, virtual or override // if ((flags & Modifiers.STATIC) != 0){ if ((flags & vao) != 0){ - Report.Error ( - 112, loc, "static method " + MakeName (n) + "can not be marked " + - "as virtual, abstract or override"); + Report.Error (112, mc.Location, "static method '{0}' can not be marked as virtual, abstract or override", + GetSignatureForError ()); ok = false; } } if (Kind == Kind.Struct){ if ((flags & va) != 0){ - Modifiers.Error_InvalidModifier (loc, "virtual or abstract"); + Modifiers.Error_InvalidModifier (mc.Location, "virtual or abstract"); ok = false; } } if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){ - Report.Error ( - 113, loc, MakeName (n) + - " marked as override cannot be marked as new or virtual"); + Report.Error (113, mc.Location, "'{0}' marked as override cannot be marked as new or virtual", mc.GetSignatureForError ()); ok = false; } @@ -2226,39 +2240,36 @@ namespace Mono.CSharp { if ((flags & Modifiers.ABSTRACT) != 0){ if ((flags & Modifiers.EXTERN) != 0){ Report.Error ( - 180, loc, MakeName (n) + " can not be both abstract and extern"); + 180, mc.Location, "'{0}' can not be both abstract and extern", mc.GetSignatureForError ()); + ok = false; + } + + if ((flags & Modifiers.SEALED) != 0) { + Report.Error (502, mc.Location, "'{0}' cannot be both abstract and sealed", mc.GetSignatureForError ()); ok = false; } if ((flags & Modifiers.VIRTUAL) != 0){ - Report.Error ( - 503, loc, MakeName (n) + " can not be both abstract and virtual"); + Report.Error (503, mc.Location, "'{0}' can not be both abstract and virtual", mc.GetSignatureForError ()); ok = false; } if ((ModFlags & Modifiers.ABSTRACT) == 0){ - Report.Error ( - 513, loc, MakeName (n) + - " is abstract but its container class is not"); + Report.Error (513, mc.Location, "'{0}' is abstract but its container class is not", mc.GetSignatureForError ()); ok = false; - } } if ((flags & Modifiers.PRIVATE) != 0){ if ((flags & vao) != 0){ - Report.Error ( - 621, loc, MakeName (n) + - " virtual or abstract members can not be private"); + Report.Error (621, mc.Location, "'{0}' virtual or abstract members can not be private", mc.GetSignatureForError ()); ok = false; } } if ((flags & Modifiers.SEALED) != 0){ if ((flags & Modifiers.OVERRIDE) == 0){ - Report.Error ( - 238, loc, MakeName (n) + - " cannot be sealed because it is not an override"); + Report.Error (238, mc.Location, "'{0}' cannot be sealed because it is not an override", mc.GetSignatureForError ()); ok = false; } } @@ -2272,6 +2283,10 @@ namespace Mono.CSharp { } } + public Constructor DefaultStaticConstructor { + get { return default_static_constructor; } + } + protected override bool VerifyClsCompliance (DeclSpace ds) { if (!base.VerifyClsCompliance (ds)) @@ -2279,9 +2294,14 @@ namespace Mono.CSharp { VerifyClsName (); - // parent_container is null for System.Object - if (parent_container != null && !AttributeTester.IsClsCompliant (parent_container.Type)) { - Report.Error (3009, Location, "'{0}': base type '{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (parent_container.Type)); + Type base_type = TypeBuilder.BaseType; + if (base_type != null && !AttributeTester.IsClsCompliant (base_type)) { + Report.Error (3009, Location, "'{0}': base type '{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (base_type)); + } + + if (!Parent.IsClsCompliaceRequired (ds)) { + Report.Error (3018, Location, "'{0}' cannot be marked as CLS-Compliant because it is a member of non CLS-Compliant type '{1}'", + GetSignatureForError (), Parent.GetSignatureForError ()); } return true; } @@ -2292,9 +2312,9 @@ namespace Mono.CSharp { /// void VerifyClsName () { - Hashtable parent_members = parent_container == null ? + Hashtable base_members = base_cache == null ? new Hashtable () : - parent_container.MemberCache.GetPublicMembers (); + base_cache.GetPublicMembers (); Hashtable this_members = new Hashtable (); foreach (DictionaryEntry entry in defined_names) { @@ -2306,7 +2326,7 @@ namespace Mono.CSharp { string basename = name.Substring (name.LastIndexOf ('.') + 1); string lcase = basename.ToLower (System.Globalization.CultureInfo.InvariantCulture); - object found = parent_members [lcase]; + object found = base_members [lcase]; if (found == null) { found = this_members [lcase]; if (found == null) { @@ -2341,8 +2361,8 @@ namespace Mono.CSharp { bool found = false; if (ifaces != null){ - foreach (TypeExpr t in ifaces){ - if (t.Type == interface_type){ + foreach (Type t in ifaces){ + if (t == interface_type){ found = true; break; } @@ -2350,7 +2370,8 @@ namespace Mono.CSharp { } if (!found){ - Report.Error (540, "`" + full + "': containing class does not implement interface `" + interface_type.FullName + "'"); + Report.Error (540, loc, "`{0}': containing class does not implement interface `{1}'", + full, interface_type.FullName); return false; } @@ -2359,13 +2380,13 @@ namespace Mono.CSharp { protected override void VerifyObsoleteAttribute() { - CheckUsageOfObsoleteAttribute (base_class_type); + CheckUsageOfObsoleteAttribute (ptype); if (ifaces == null) return; - foreach (TypeExpr expr in ifaces) { - CheckUsageOfObsoleteAttribute (expr.Type); + foreach (Type iface in ifaces) { + CheckUsageOfObsoleteAttribute (iface); } } @@ -2403,9 +2424,22 @@ namespace Mono.CSharp { return FindMembers (mt, bf | BindingFlags.DeclaredOnly, null, null); } - public virtual IMemberContainer ParentContainer { + // + // Generates xml doc comments (if any), and if required, + // handle warning report. + // + internal override void GenerateDocComment (DeclSpace ds) + { + DocUtil.GenerateTypeDocComment (this, ds); + } + + public override string DocCommentHeader { + get { return "T:"; } + } + + public virtual MemberCache BaseCache { get { - return parent_container; + return base_cache; } } } @@ -2418,11 +2452,11 @@ namespace Mono.CSharp { public readonly TypeAttributes DefaultTypeAttributes; static PartialContainer Create (NamespaceEntry ns, TypeContainer parent, - MemberName name, int mod_flags, Kind kind, + MemberName member_name, int mod_flags, Kind kind, Location loc) { PartialContainer pc; - string full_name = name.GetName (true); + string full_name = member_name.GetName (true); DeclSpace ds = (DeclSpace) RootContext.Tree.Decls [full_name]; if (ds != null) { pc = ds as PartialContainer; @@ -2432,7 +2466,7 @@ namespace Mono.CSharp { 260, ds.Location, "Missing partial modifier " + "on declaration of type `{0}'; another " + "partial implementation of this type exists", - name); + member_name.GetPartialName()); Report.LocationOfPreviousError (loc); return null; @@ -2442,7 +2476,7 @@ namespace Mono.CSharp { Report.Error ( 261, loc, "Partial declarations of `{0}' " + "must be all classes, all structs or " + - "all interfaces", name); + "all interfaces", member_name.GetPartialName ()); return null; } @@ -2450,14 +2484,14 @@ namespace Mono.CSharp { Report.Error ( 262, loc, "Partial declarations of `{0}' " + "have conflicting accessibility modifiers", - name); + member_name.GetPartialName ()); return null; } return pc; } - pc = new PartialContainer (ns, parent, name, mod_flags, kind, loc); + pc = new PartialContainer (ns, parent, member_name, mod_flags, kind, loc); RootContext.Tree.RecordDecl (full_name, pc); parent.AddType (pc); pc.Register (); @@ -2583,9 +2617,9 @@ namespace Mono.CSharp { interface_type, full, name, loc); } - public override IMemberContainer ParentContainer { + public override MemberCache BaseCache { get { - return PartialContainer.ParentContainer; + return PartialContainer.BaseCache; } } } @@ -2664,7 +2698,7 @@ namespace Mono.CSharp { public sealed class StaticClass: Class { public StaticClass (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod, Attributes attrs, Location l) - : base (ns, parent, name, mod & ~Modifiers.STATIC, attrs, l) + : base (ns, parent, name, mod, attrs, l) { if (RootContext.Version == LanguageVersion.ISO_1) { Report.FeatureIsNotStandardized (l, "static classes"); @@ -2672,6 +2706,13 @@ namespace Mono.CSharp { } } + protected override int AllowedModifiersProp { + get { + return Modifiers.NEW | Modifiers.PUBLIC | Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE | + Modifiers.STATIC | Modifiers.UNSAFE; + } + } + protected override void DefineContainerMembers (MemberCoreArrayList list) { if (list == null) @@ -2683,7 +2724,7 @@ namespace Mono.CSharp { continue; } - if ((m.ModFlags & Modifiers.STATIC) != 0) + if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate) continue; if (m is Constructor) { @@ -2704,17 +2745,22 @@ namespace Mono.CSharp { public override TypeBuilder DefineType() { + if ((ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) == (Modifiers.SEALED | Modifiers.STATIC)) { + Report.Error (441, Location, "'{0}': a class cannot be both static and sealed", GetSignatureForError ()); + return null; + } + TypeBuilder tb = base.DefineType (); if (tb == null) return null; - if (base_class_type != TypeManager.object_type) { - Report.Error (713, Location, "Static class '{0}' cannot derive from type '{1}'. Static classes must derive from object", GetSignatureForError (), TypeManager.CSharpName (base_class_type)); + if (ptype != TypeManager.object_type) { + Report.Error (713, Location, "Static class '{0}' cannot derive from type '{1}'. Static classes must derive from object", GetSignatureForError (), TypeManager.CSharpName (ptype)); return null; } - if (base_inteface_types != null) { - foreach (Type t in base_inteface_types) + if (ifaces != null) { + foreach (Type t in ifaces) Report.SymbolRelatedToPreviousError (t); Report.Error (714, Location, "'{0}': static classes cannot implement interfaces", GetSignatureForError ()); } @@ -2729,9 +2775,7 @@ namespace Mono.CSharp { } public class Class : ClassOrStruct { - // - // Modifiers allowed in a class declaration - // + // TODO: remove this and use only AllowedModifiersProp to fix partial classes bugs public const int AllowedModifiers = Modifiers.NEW | Modifiers.PUBLIC | @@ -2749,31 +2793,20 @@ namespace Mono.CSharp { Attributes attrs, Location l) : base (ns, parent, name, attrs, Kind.Class, l) { - int accmods; - - if (parent.Parent == null) - accmods = Modifiers.INTERNAL; - else - accmods = Modifiers.PRIVATE; - - this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l); - if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.SEALED)) == (Modifiers.ABSTRACT | Modifiers.SEALED)) { - Report.Error (502, Location, "'{0}' cannot be both abstract and sealed", GetSignatureForError ()); - } - + this.ModFlags = mod; attribute_usage = new AttributeUsageAttribute (AttributeTargets.All); } - public override AttributeTargets AttributeTargets { + virtual protected int AllowedModifiersProp { get { - return AttributeTargets.Class; + return AllowedModifiers; } } public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb) { if (a.UsageAttribute != null) { - if (base_class_type != TypeManager.attribute_type && !base_class_type.IsSubclassOf (TypeManager.attribute_type) && + if (ptype != TypeManager.attribute_type && !ptype.IsSubclassOf (TypeManager.attribute_type) && TypeBuilder.FullName != "System.Attribute") { Report.Error (641, a.Location, "Attribute '{0}' is only valid on classes derived from System.Attribute", a.Name); } @@ -2792,6 +2825,19 @@ namespace Mono.CSharp { public const TypeAttributes DefaultTypeAttributes = TypeAttributes.AutoLayout | TypeAttributes.Class; + public override TypeBuilder DefineType() + { + if ((ModFlags & Modifiers.ABSTRACT) == Modifiers.ABSTRACT && (ModFlags & (Modifiers.SEALED | Modifiers.STATIC)) != 0) { + Report.Error (418, Location, "'{0}': an abstract class cannot be sealed or static", GetSignatureForError ()); + return null; + } + + int accmods = Parent.Parent == null ? Modifiers.INTERNAL : Modifiers.PRIVATE; + ModFlags = Modifiers.Check (AllowedModifiersProp, ModFlags, accmods, Location); + + return base.DefineType (); + } + // // FIXME: How do we deal with the user specifying a different // layout? @@ -2831,12 +2877,6 @@ namespace Mono.CSharp { this.ModFlags |= Modifiers.SEALED; } - public override AttributeTargets AttributeTargets { - get { - return AttributeTargets.Struct; - } - } - public const TypeAttributes DefaultTypeAttributes = TypeAttributes.SequentialLayout | TypeAttributes.Sealed | @@ -2893,12 +2933,6 @@ namespace Mono.CSharp { return null; } - public override AttributeTargets AttributeTargets { - get { - return AttributeTargets.Interface; - } - } - public const TypeAttributes DefaultTypeAttributes = TypeAttributes.AutoLayout | TypeAttributes.Abstract | @@ -2927,7 +2961,7 @@ namespace Mono.CSharp { // // The method we're overriding if this is an override method. // - protected MethodInfo parent_method = null; + protected MethodInfo base_method = null; static string[] attribute_targets = new string [] { "method", "return" }; @@ -2983,39 +3017,39 @@ namespace Mono.CSharp { return true; // Is null for System.Object while compiling corlib and base interfaces - if (Parent.ParentContainer == null) { + if (Parent.BaseCache == 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 (Parent)); } return true; } - Type parent_ret_type = null; - parent_method = FindOutParentMethod (Parent, ref parent_ret_type); + Type base_ret_type = null; + base_method = FindOutBaseMethod (Parent, ref base_ret_type); // method is override - if (parent_method != null) { + if (base_method != null) { if (!CheckMethodAgainstBase ()) return false; if ((ModFlags & Modifiers.NEW) == 0) { - if (MemberType != TypeManager.TypeToCoreType (parent_ret_type)) { - Report.SymbolRelatedToPreviousError (parent_method); + if (MemberType != TypeManager.TypeToCoreType (base_ret_type)) { + Report.SymbolRelatedToPreviousError (base_method); Report.Error (508, Location, GetSignatureForError (Parent) + ": cannot " + "change return type when overriding inherited member"); return false; } } else { - if (parent_method.IsAbstract && !IsInterface) { - Report.SymbolRelatedToPreviousError (parent_method); + if (base_method.IsAbstract && !IsInterface) { + Report.SymbolRelatedToPreviousError (base_method); Report.Error (533, Location, "'{0}' hides inherited abstract member", GetSignatureForError (Parent)); return false; } } - if (parent_method.IsSpecialName && !(this is PropertyBase)) { - Report.Error (561, Location, "'{0}': cannot override '{1}' because it is a special compiler-generated method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (parent_method)); + if (base_method.IsSpecialName && !(this is PropertyBase)) { + Report.Error (561, Location, "'{0}': cannot override '{1}' because it is a special compiler-generated method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (base_method)); return false; } @@ -3026,18 +3060,20 @@ namespace Mono.CSharp { Parent.Methods.HasGetHashCode = true; } - ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (parent_method); - if (oa != null) { - EmitContext ec = new EmitContext (this.Parent, this.Parent, Location, null, null, ModFlags, false); - if (OptAttributes == null || !OptAttributes.Contains (TypeManager.obsolete_attribute_type, ec)) { - Report.SymbolRelatedToPreviousError (parent_method); - Report.Warning (672, 1, Location, "Member '{0}' overrides obsolete member. Add the Obsolete attribute to '{0}'", GetSignatureForError (Parent)); + if ((ModFlags & Modifiers.OVERRIDE) != 0) { + ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (base_method); + if (oa != null) { + EmitContext ec = new EmitContext (this.Parent, this.Parent, Location, null, null, ModFlags, false); + if (OptAttributes == null || !OptAttributes.Contains (TypeManager.obsolete_attribute_type, ec)) { + Report.SymbolRelatedToPreviousError (base_method); + Report.Warning (672, 1, Location, "Member '{0}' overrides obsolete member. Add the Obsolete attribute to '{0}'", GetSignatureForError (Parent)); + } } } return true; } - MemberInfo conflict_symbol = Parent.FindMemberWithSameName (Name, !(this is Property)); + MemberInfo conflict_symbol = Parent.FindBaseMemberWithSameName (Name, !(this is Property)); if ((ModFlags & Modifiers.OVERRIDE) != 0) { if (conflict_symbol != null) { Report.SymbolRelatedToPreviousError (conflict_symbol); @@ -3081,10 +3117,10 @@ namespace Mono.CSharp { bool ok = true; // TODO: replace with GetSignatureForError - string name = parent_method.DeclaringType.Name + "." + parent_method.Name; + string name = base_method.DeclaringType.Name + "." + base_method.Name; if ((ModFlags & Modifiers.OVERRIDE) != 0){ - if (!(parent_method.IsAbstract || parent_method.IsVirtual)){ + if (!(base_method.IsAbstract || base_method.IsVirtual)){ Report.Error ( 506, Location, Parent.MakeName (Name) + ": cannot override inherited member `" + @@ -3095,9 +3131,9 @@ namespace Mono.CSharp { // Now we check that the overriden method is not final - if (parent_method.IsFinal) { + if (base_method.IsFinal) { // This happens when implementing interface methods. - if (parent_method.IsHideBySig && parent_method.IsVirtual) { + if (base_method.IsHideBySig && base_method.IsVirtual) { Report.Error ( 506, Location, Parent.MakeName (Name) + ": cannot override inherited member `" + @@ -3113,77 +3149,74 @@ namespace Mono.CSharp { // Check that the permissions are not being changed // MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask; - MethodAttributes parentp = parent_method.Attributes & MethodAttributes.MemberAccessMask; - - // - // special case for "protected internal" - // + MethodAttributes base_classp = base_method.Attributes & MethodAttributes.MemberAccessMask; - if ((parentp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){ - // - // when overriding protected internal, the method can be declared - // protected internal only within the same assembly - // - - if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){ - if (Parent.TypeBuilder.Assembly != parent_method.DeclaringType.Assembly){ - // - // assemblies differ - report an error - // - - Error_CannotChangeAccessModifiers (Parent, parent_method, name); - ok = false; - } else if (thisp != parentp) { - // - // same assembly, but other attributes differ - report an error - // - - Error_CannotChangeAccessModifiers (Parent, parent_method, name); - ok = false; - }; - } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) { - // - // if it's not "protected internal", it must be "protected" - // - - Error_CannotChangeAccessModifiers (Parent, parent_method, name); - ok = false; - } else if (Parent.TypeBuilder.Assembly == parent_method.DeclaringType.Assembly) { - // - // protected within the same assembly - an error - // - Error_CannotChangeAccessModifiers (Parent, parent_method, name); - ok = false; - } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) != - (parentp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) { - // - // protected ok, but other attributes differ - report an error - // - Error_CannotChangeAccessModifiers (Parent, parent_method, name); - ok = false; - } - } else { - if (thisp != parentp){ - Error_CannotChangeAccessModifiers (Parent, parent_method, name); - ok = false; - } + if (!CheckAccessModifiers (thisp, base_classp, base_method)) { + Error_CannotChangeAccessModifiers (Parent, base_method, name); + ok = false; } } if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0 && Name != "Finalize") { ModFlags |= Modifiers.NEW; - Report.SymbolRelatedToPreviousError (parent_method); - if (!IsInterface && (parent_method.IsVirtual || parent_method.IsAbstract)) { + Report.SymbolRelatedToPreviousError (base_method); + if (!IsInterface && (base_method.IsVirtual || base_method.IsAbstract)) { if (RootContext.WarningLevel >= 2) - Report.Warning (114, Location, "'{0}' hides inherited member '{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword", GetSignatureForError (Parent), TypeManager.CSharpSignature (parent_method)); + Report.Warning (114, Location, "'{0}' hides inherited member '{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword", GetSignatureForError (Parent), TypeManager.CSharpSignature (base_method)); } else Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent)); } return ok; } + + protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes base_classp, MethodInfo base_method) + { + if ((base_classp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){ + // + // when overriding protected internal, the method can be declared + // protected internal only within the same assembly + // - void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo parent_method, string name) + if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){ + if (Parent.TypeBuilder.Assembly != base_method.DeclaringType.Assembly){ + // + // assemblies differ - report an error + // + + return false; + } else if (thisp != base_classp) { + // + // same assembly, but other attributes differ - report an error + // + + return false; + }; + } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) { + // + // if it's not "protected internal", it must be "protected" + // + + return false; + } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) { + // + // protected within the same assembly - an error + // + return false; + } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) != + (base_classp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) { + // + // protected ok, but other attributes differ - report an error + // + return false; + } + return true; + } else { + return (thisp == base_classp); + } + } + + void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo base_method, string name) { // // FIXME: report the old/new permissions? @@ -3206,9 +3239,9 @@ namespace Mono.CSharp { protected abstract bool CheckForDuplications (); /// - /// Gets parent method and its return type + /// Gets base method and its return type /// - protected abstract MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type); + protected abstract MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type); protected virtual bool DoDefineParameters () { @@ -3259,7 +3292,12 @@ namespace Mono.CSharp { } if (!AttributeTester.IsClsCompliant (MemberType)) { - Report.Error (3002, Location, "Return type of '{0}' is not CLS-compliant", GetSignatureForError ()); + if (this is PropertyBase) + Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant", + GetSignatureForError ()); + else + Report.Error (3002, Location, "Return type of '{0}' is not CLS-compliant", + GetSignatureForError ()); } AttributeTester.AreParametersCompliant (Parameters.FixedParameters, Location); @@ -3306,6 +3344,34 @@ namespace Mono.CSharp { return true; } + // + // Returns a string that represents the signature for this + // member which should be used in XML documentation. + // + public override string GetDocCommentName (DeclSpace ds) + { + return DocUtil.GetMethodDocCommentName (this, ds); + } + + // + // Raised (and passed an XmlElement that contains the comment) + // when GenerateDocComment is writing documentation expectedly. + // + // FIXME: with a few effort, it could be done with XmlReader, + // that means removal of DOM use. + // + internal override void OnGenerateDocComment (DeclSpace ds, XmlElement el) + { + DocUtil.OnMethodGenerateDocComment (this, ds, el); + } + + // + // Represents header string for documentation comment. + // + public override string DocCommentHeader { + get { return "M:"; } + } + protected override void VerifyObsoleteAttribute() { base.VerifyObsoleteAttribute (); @@ -3684,18 +3750,24 @@ namespace Mono.CSharp { MethodData = null; } - protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type) + protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type) { - MethodInfo mi = (MethodInfo) container.ParentContainer.MemberCache.FindMemberToOverride ( + MethodInfo mi = (MethodInfo) container.BaseCache.FindMemberToOverride ( container.TypeBuilder, Name, ParameterTypes, false); if (mi == null) return null; - parent_ret_type = mi.ReturnType; + base_ret_type = mi.ReturnType; return mi; } + public override bool MarkForDuplicationCheck () + { + caching_flags |= Flags.TestMethodDuplication; + return true; + } + protected override bool VerifyClsCompliance(DeclSpace ds) { if (!base.VerifyClsCompliance (ds)) @@ -3773,7 +3845,7 @@ namespace Mono.CSharp { caching_flags &= ~Flags.Excluded_Undetected; - if (parent_method == null) { + if (base_method == null) { if (OptAttributes == null) return false; @@ -3783,8 +3855,7 @@ namespace Mono.CSharp { return false; foreach (Attribute a in attrs) { - string condition = a.GetConditionalAttributeValue ( - Parent); + string condition = a.GetConditionalAttributeValue (Parent.EmitContext); if (RootContext.AllDefines.Contains (condition)) return false; } @@ -3793,9 +3864,9 @@ namespace Mono.CSharp { return true; } - IMethodData md = TypeManager.GetMethod (parent_method); + IMethodData md = TypeManager.GetMethod (base_method); if (md == null) { - if (AttributeTester.IsConditionalMethodExcluded (parent_method)) { + if (AttributeTester.IsConditionalMethodExcluded (base_method)) { caching_flags |= Flags.Excluded; return true; } @@ -3814,7 +3885,7 @@ namespace Mono.CSharp { public abstract class ConstructorInitializer { ArrayList argument_list; - protected ConstructorInfo parent_constructor; + protected ConstructorInfo base_constructor; Parameters parameters; Location loc; @@ -3834,7 +3905,7 @@ namespace Mono.CSharp { public bool Resolve (ConstructorBuilder caller_builder, EmitContext ec) { - Expression parent_constructor_group; + Expression base_constructor_group; Type t; ec.CurrentBlock = new ToplevelBlock (Block.Flags.Implicit, parameters, loc); @@ -3860,18 +3931,18 @@ namespace Mono.CSharp { } else t = ec.ContainerType; - parent_constructor_group = Expression.MemberLookup ( + base_constructor_group = Expression.MemberLookup ( ec, t, ".ctor", MemberTypes.Constructor, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, loc); - if (parent_constructor_group == null){ - parent_constructor_group = Expression.MemberLookup ( + if (base_constructor_group == null){ + base_constructor_group = Expression.MemberLookup ( ec, t, ".ctor", MemberTypes.Constructor, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly, loc); - if (parent_constructor_group != null) + if (base_constructor_group != null) Report.Error ( 112, loc, "`{0}.{1}' is inaccessible due to " + "its protection level", t.FullName, t.Name); @@ -3882,17 +3953,17 @@ namespace Mono.CSharp { return false; } - parent_constructor = (ConstructorInfo) Invocation.OverloadResolve ( - ec, (MethodGroupExpr) parent_constructor_group, argument_list, + base_constructor = (ConstructorInfo) Invocation.OverloadResolve ( + ec, (MethodGroupExpr) base_constructor_group, argument_list, false, loc); - if (parent_constructor == null){ + if (base_constructor == null){ Report.Error (1501, loc, "Can not find a constructor for this argument list"); return false; } - if (parent_constructor == caller_builder){ + if (base_constructor == caller_builder){ Report.Error (516, String.Format ("Constructor `{0}' can not call itself", TypeManager.CSharpSignature (caller_builder))); return false; } @@ -3902,12 +3973,12 @@ namespace Mono.CSharp { public void Emit (EmitContext ec) { - if (parent_constructor != null){ + if (base_constructor != null){ ec.Mark (loc, false); if (ec.IsStatic) - Invocation.EmitCall (ec, true, true, null, parent_constructor, argument_list, loc); + Invocation.EmitCall (ec, true, true, null, base_constructor, argument_list, loc); else - Invocation.EmitCall (ec, true, false, ec.GetThis (loc), parent_constructor, argument_list, loc); + Invocation.EmitCall (ec, true, false, ec.GetThis (loc), base_constructor, argument_list, loc); } } @@ -3979,15 +4050,15 @@ namespace Mono.CSharp { } public override void CheckObsoleteAttribute(TypeContainer tc, Location loc) { - if (parent_constructor == null) + if (base_constructor == null) return; - TypeContainer type_ds = TypeManager.LookupTypeContainer (tc.base_class_type); + TypeContainer type_ds = TypeManager.LookupTypeContainer (tc.TypeBuilder.BaseType); if (type_ds == null) { - ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (parent_constructor); + ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (base_constructor); if (oa != null) - AttributeTester.Report_ObsoleteMessage (oa, TypeManager.CSharpSignature (parent_constructor), loc); + AttributeTester.Report_ObsoleteMessage (oa, TypeManager.CSharpSignature (base_constructor), loc); return; } @@ -4280,7 +4351,7 @@ namespace Mono.CSharp { } // Is never override - protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type) + protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type) { return null; } @@ -4444,7 +4515,7 @@ namespace Mono.CSharp { if (member.InterfaceType != null){ if (implementing == null){ Report.Error (539, method.Location, - "'{0}' in explicit interface declaration is not an interface", method_name); + "'{0}' in explicit interface declaration is not a member of interface", member.GetSignatureForError () ); return false; } method_name = member.InterfaceType.FullName + "." + name; @@ -4612,7 +4683,6 @@ namespace Mono.CSharp { if (member is MethodCore) ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc); - SymbolWriter sw = CodeGen.SymbolWriter; ToplevelBlock block = method.Block; // @@ -4691,10 +4761,10 @@ namespace Mono.CSharp { "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location); if (member_lookup != null){ - MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup); + MethodGroupExpr base_destructor = ((MethodGroupExpr) member_lookup); ig.Emit (OpCodes.Ldarg_0); - ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]); + ig.Emit (OpCodes.Call, (MethodInfo) base_destructor.Methods [0]); } } @@ -4862,7 +4932,7 @@ namespace Mono.CSharp { MethodAttributes.NewSlot | MethodAttributes.Virtual; } else { - if (!Parent.MethodModifiersValid (ModFlags, Name, Location)) + if (!Parent.MethodModifiersValid (this)) return false; flags = Modifiers.MethodAttr (ModFlags); @@ -4888,18 +4958,19 @@ namespace Mono.CSharp { // verify accessibility if (!Parent.AsAccessible (MemberType, ModFlags)) { + Report.SymbolRelatedToPreviousError (MemberType); if (this is Property) Report.Error (53, Location, "Inconsistent accessibility: property type `" + TypeManager.CSharpName (MemberType) + "' is less " + - "accessible than property `" + Name + "'"); + "accessible than property `" + GetSignatureForError () + "'"); else if (this is Indexer) Report.Error (54, Location, "Inconsistent accessibility: indexer return type `" + TypeManager.CSharpName (MemberType) + "' is less " + "accessible than indexer `" + Name + "'"); - else if (this is Method) { - if (((Method) this).IsOperator) + else if (this is MethodCore) { + if (this is Operator) Report.Error (56, Location, "Inconsistent accessibility: return type `" + TypeManager.CSharpName (MemberType) + "' is less " + @@ -4909,11 +4980,12 @@ namespace Mono.CSharp { "Inconsistent accessibility: return type `" + TypeManager.CSharpName (MemberType) + "' is less " + "accessible than method `" + Name + "'"); - } else + } else { Report.Error (52, Location, "Inconsistent accessibility: field type `" + TypeManager.CSharpName (MemberType) + "' is less " + "accessible than field `" + Name + "'"); + } return false; } @@ -4928,8 +5000,8 @@ namespace Mono.CSharp { InterfaceType = texpr.ResolveType (ec); - if (InterfaceType.IsClass) { - Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName); + if (!InterfaceType.IsInterface) { + Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType)); return false; } @@ -5001,13 +5073,14 @@ namespace Mono.CSharp { [Flags] public enum Status : byte { ASSIGNED = 1, - USED = 2 + USED = 2, + HAS_OFFSET = 4 // Used by FieldMember. } static string[] attribute_targets = new string [] { "field" }; /// - /// Symbol with same name in parent class/struct + /// Symbol with same name in base class/struct /// public MemberInfo conflict_symbol; @@ -5095,7 +5168,7 @@ namespace Mono.CSharp { if (IsInterface) return true; - conflict_symbol = Parent.FindMemberWithSameName (Name, false); + conflict_symbol = Parent.FindBaseMemberWithSameName (Name, false); 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 (Parent)); @@ -5111,19 +5184,6 @@ namespace Mono.CSharp { return true; } - protected override bool DoDefine () - { - if (!base.DoDefine ()) - return false; - - if (MemberType == TypeManager.void_type) { - Report.Error (1547, Location, - "Keyword 'void' cannot be used in this context"); - return false; - } - return true; - } - public override string GetSignatureForError () { if (FieldBuilder == null) { @@ -5162,7 +5222,7 @@ namespace Mono.CSharp { public abstract class FieldMember: FieldBase { - bool has_field_offset = false; + protected FieldMember (TypeContainer parent, Expression type, int mod, int allowed_mod, MemberName name, object init, Attributes attrs, Location loc) @@ -5174,7 +5234,7 @@ namespace Mono.CSharp { { if (a.Type == TypeManager.field_offset_attribute_type) { - has_field_offset = true; + status |= Status.HAS_OFFSET; if (!Parent.HasExplicitLayout) { Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)"); @@ -5203,6 +5263,12 @@ namespace Mono.CSharp { return false; MemberType = texpr.ResolveType (ec); + + if (MemberType == TypeManager.void_type) { + Report.Error (1547, Location, "Keyword 'void' cannot be used in this context"); + return false; + } + ec.InUnsafe = old_unsafe; if (!CheckBase ()) @@ -5227,12 +5293,19 @@ namespace Mono.CSharp { public override void Emit () { - if (Parent.HasExplicitLayout && !has_field_offset && (ModFlags & Modifiers.STATIC) == 0) { + if (Parent.HasExplicitLayout && ((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0) { Report.Error (625, Location, "'{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ()); } base.Emit (); } + + // + // Represents header string for documentation comment. + // + public override string DocCommentHeader { + get { return "F:"; } + } } // @@ -5356,15 +5429,23 @@ namespace Mono.CSharp { // // Null if the accessor is empty, or a Block if not // + public const int AllowedModifiers = + Modifiers.PUBLIC | + Modifiers.PROTECTED | + Modifiers.INTERNAL | + Modifiers.PRIVATE; + public ToplevelBlock Block; public Attributes Attributes; public Location Location; + public int ModFlags; - public Accessor (ToplevelBlock b, Attributes attrs, Location loc) + public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc) { Block = b; Attributes = attrs; Location = loc; + ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc); } } @@ -5453,7 +5534,7 @@ namespace Mono.CSharp { { if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type || a.Type == TypeManager.conditional_attribute_type) { - Report.Error (1667, a.Location, "'{0}' is not valid on property or event accessors. It is valid on '{1}' declarations only", TypeManager.CSharpName (a.Type), a.GetValidTargets ()); + Report.Error (1667, a.Location, "'{0}' is not valid on property or event accessors. It is valid on {1} declarations only", TypeManager.CSharpName (a.Type), a.GetValidTargets ()); return; } @@ -5487,7 +5568,7 @@ namespace Mono.CSharp { public override bool Define() { - return false; + throw new NotSupportedException (); } public virtual void Emit (TypeContainer container) @@ -5533,6 +5614,13 @@ namespace Mono.CSharp { } } + // + // Represents header string for documentation comment. + // + public override string DocCommentHeader { + get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); } + } + protected override void VerifyObsoleteAttribute() { } @@ -5561,7 +5649,9 @@ namespace Mono.CSharp { public override MethodBuilder Define(TypeContainer container) { - method_data = new MethodData (method, method.ParameterInfo, method.ModFlags, method.flags, this); + base.Define (container); + + method_data = new MethodData (method, method.ParameterInfo, ModFlags, flags, this); if (!method_data.Define (container)) return null; @@ -5620,15 +5710,23 @@ namespace Mono.CSharp { Parameter [] parms = new Parameter [1]; parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null); Parameters parameters = new Parameters (parms, null, method.Location); + + bool old_unsafe = ec.InUnsafe; + ec.InUnsafe = InUnsafe; Type [] types = parameters.GetParameterInfo (ec); + ec.InUnsafe = old_unsafe; + return new InternalParameters (types, parameters); } - public override MethodBuilder Define(TypeContainer container) + public override MethodBuilder Define (TypeContainer container) { if (container.EmitContext == null) throw new InternalErrorException ("SetMethod.Define called too early"); - method_data = new MethodData (method, GetParameterInfo (container.EmitContext), method.ModFlags, method.flags, this); + + base.Define (container); + + method_data = new MethodData (method, GetParameterInfo (container.EmitContext), ModFlags, flags, this); if (!method_data.Define (container)) return null; @@ -5665,11 +5763,13 @@ namespace Mono.CSharp { public abstract class PropertyMethod: AbstractPropertyEventMethod { protected readonly MethodCore method; + protected MethodAttributes flags; public PropertyMethod (MethodCore method, string prefix) : base (method, prefix) { this.method = method; + Parent = method.Parent; } public PropertyMethod (MethodCore method, Accessor accessor, @@ -5677,6 +5777,13 @@ namespace Mono.CSharp { : base (method, accessor, prefix) { this.method = method; + Parent = method.Parent; + this.ModFlags = accessor.ModFlags; + + if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) { + Report.FeatureIsNotStandardized (Location, "accessor modifiers"); + Environment.Exit (1); + } } public override AttributeTargets AttributeTargets { @@ -5697,7 +5804,24 @@ namespace Mono.CSharp { } } - public abstract MethodBuilder Define (TypeContainer container); + public virtual MethodBuilder Define (TypeContainer container) + { + // + // Check for custom access modifier + // + if (ModFlags == 0) { + ModFlags = method.ModFlags; + flags = method.flags; + } else { + CheckModifiers (container, ModFlags); + ModFlags |= (method.ModFlags & (~Modifiers.Accessibility)); + flags = Modifiers.MethodAttr (ModFlags); + flags |= (method.flags & (~MethodAttributes.MemberAccessMask)); + } + + return null; + + } public override Type[] ParameterTypes { get { @@ -5722,6 +5846,34 @@ namespace Mono.CSharp { { return String.Concat (tc.Name, '.', method.Name); } + + void CheckModifiers (TypeContainer container, int modflags) + { + int flags = 0; + int mflags = method.ModFlags & Modifiers.Accessibility; + + if ((mflags & Modifiers.PUBLIC) != 0) { + flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE; + } + else if ((mflags & Modifiers.PROTECTED) != 0) { + if ((mflags & Modifiers.INTERNAL) != 0) + flags |= Modifiers.PROTECTED | Modifiers.INTERNAL; + + flags |= Modifiers.PRIVATE; + } + else if ((mflags & Modifiers.INTERNAL) != 0) + flags |= Modifiers.PRIVATE; + + if ((mflags == modflags) || (modflags & (~flags)) != 0) + Report.Error (273, Location, "{0}: accessibility modifier must be more restrictive than the property or indexer", + GetSignatureForError (container)); + } + + public override bool MarkForDuplicationCheck () + { + caching_flags |= Flags.TestMethodDuplication; + return true; + } } @@ -5772,6 +5924,23 @@ namespace Mono.CSharp { if (!base.DoDefine ()) return false; + // + // Accessors modifiers check + // + if (Get.ModFlags != 0 && Set.ModFlags != 0) { + Report.Error (274, Location, "'{0}': cannot specify accessibility modifiers for both accessors of the property or indexer.", + GetSignatureForError ()); + return false; + } + + if ((Get.IsDummy || Set.IsDummy) + && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) { + Report.Error (276, Location, + "'{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor.", + GetSignatureForError ()); + return false; + } + if (MemberType.IsAbstract && MemberType.IsSealed) { Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType)); return false; @@ -5789,7 +5958,6 @@ namespace Mono.CSharp { return TypeManager.CSharpSignature (PropertyBuilder, false); } - protected override bool CheckForDuplications () { ArrayList ar = Parent.Indexers; @@ -5818,31 +5986,59 @@ namespace Mono.CSharp { } // TODO: rename to Resolve...... - protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type) + protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type) { - PropertyInfo parent_property = container.ParentContainer.MemberCache.FindMemberToOverride ( + PropertyInfo base_property = container.BaseCache.FindMemberToOverride ( container.TypeBuilder, Name, ParameterTypes, true) as PropertyInfo; - if (parent_property == null) + if (base_property == null) return null; - parent_ret_type = parent_property.PropertyType; - MethodInfo get_accessor = parent_property.GetGetMethod (true); - MethodInfo set_accessor = parent_property.GetSetMethod (true); + base_ret_type = base_property.PropertyType; + MethodInfo get_accessor = base_property.GetGetMethod (true); + MethodInfo set_accessor = base_property.GetSetMethod (true); + MethodAttributes get_accessor_access, set_accessor_access; if ((ModFlags & Modifiers.OVERRIDE) != 0) { if (Get != null && !Get.IsDummy && get_accessor == null) { - Report.SymbolRelatedToPreviousError (parent_property); - Report.Error (545, Location, "'{0}': cannot override because '{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property)); + Report.SymbolRelatedToPreviousError (base_property); + Report.Error (545, Location, "'{0}': cannot override because '{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property)); } if (Set != null && !Set.IsDummy && set_accessor == null) { - Report.SymbolRelatedToPreviousError (parent_property); - Report.Error (546, Location, "'{0}': cannot override because '{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property)); + Report.SymbolRelatedToPreviousError (base_property); + Report.Error (546, Location, "'{0}': cannot override because '{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (base_property)); } } - return get_accessor != null ? get_accessor : set_accessor; + // + // Check base class accessors access + // + get_accessor_access = set_accessor_access = 0; + if ((ModFlags & Modifiers.NEW) == 0) { + if (get_accessor != null) { + MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags); + get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask); + + if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor)) + Report.Error (507, Location, "'{0}' can't change the access modifiers when overriding inherited member '{1}'", + GetSignatureForError (), TypeManager.GetFullNameSignature (base_property)); + } + + if (set_accessor != null) { + MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags); + set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask); + + if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor)) + Report.Error (507, Location, "'{0}' can't change the access modifiers when overriding inherited member '{1}'", + GetSignatureForError (container), TypeManager.GetFullNameSignature (base_property)); + } + } + + // + // Get the less restrictive access + // + return get_accessor_access > set_accessor_access ? get_accessor : set_accessor; } public override void Emit () @@ -5880,12 +6076,30 @@ namespace Mono.CSharp { Set.UpdateName (this); } + protected override bool VerifyClsCompliance (DeclSpace ds) + { + if (!base.VerifyClsCompliance (ds)) + return false; + + if ((Get.ModFlags != ModFlags && !Get.IsDummy) || (Set.ModFlags != ModFlags && !Set.IsDummy)) { + Report.Error (3025, Get.ModFlags != ModFlags ? Get.Location : Set.Location, + "CLS-compliant accessors must have the same accessibility as their property"); + } + return true; + } public override string[] ValidAttributeTargets { get { return attribute_targets; } } + + // + // Represents header string for documentation comment. + // + public override string DocCommentHeader { + get { return "P:"; } + } } public class Property : PropertyBase, IIteratorContainer { @@ -5972,18 +6186,16 @@ namespace Mono.CSharp { prop_attr |= PropertyAttributes.RTSpecialName | PropertyAttributes.SpecialName; - if (!IsExplicitImpl){ - PropertyBuilder = Parent.TypeBuilder.DefineProperty ( - Name, prop_attr, MemberType, null); - - if (!Get.IsDummy) - PropertyBuilder.SetGetMethod (GetBuilder); + PropertyBuilder = Parent.TypeBuilder.DefineProperty ( + Name, prop_attr, MemberType, null); + + if (!Get.IsDummy) + PropertyBuilder.SetGetMethod (GetBuilder); - if (!Set.IsDummy) - PropertyBuilder.SetSetMethod (SetBuilder); - - TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder); - } + if (!Set.IsDummy) + PropertyBuilder.SetSetMethod (SetBuilder); + + TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder); return true; } @@ -6152,6 +6364,10 @@ namespace Mono.CSharp { { Add = new AddDelegateMethod (this, add); Remove = new RemoveDelegateMethod (this, remove); + + // For this event syntax we don't report error CS0067 + // because it is hard to do it. + SetAssigned (); } public override string[] ValidAttributeTargets { @@ -6167,6 +6383,7 @@ namespace Mono.CSharp { public class EventField: Event { static string[] attribute_targets = new string [] { "event", "field", "method" }; + static string[] attribute_targets_interface = new string[] { "event", "method" }; public EventField (TypeContainer parent, Expression type, int mod_flags, bool is_iface, MemberName name, Object init, @@ -6185,8 +6402,8 @@ namespace Mono.CSharp { } if (a.Target == AttributeTargets.Method) { - AddBuilder.SetCustomAttribute (cb); - RemoveBuilder.SetCustomAttribute (cb); + Add.ApplyAttributeBuilder (a, cb); + Remove.ApplyAttributeBuilder (a, cb); return; } @@ -6195,7 +6412,7 @@ namespace Mono.CSharp { public override string[] ValidAttributeTargets { get { - return attribute_targets; + return IsInterface ? attribute_targets_interface : attribute_targets; } } } @@ -6308,7 +6525,6 @@ namespace Mono.CSharp { } ILGenerator ig = method_data.MethodBuilder.GetILGenerator (); - EmitContext ec = CreateEmitContext (tc, ig); FieldInfo field_info = (FieldInfo)method.FieldBuilder; method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized); @@ -6470,26 +6686,21 @@ namespace Mono.CSharp { if (RemoveBuilder == null) return false; - if (!IsExplicitImpl){ - EventBuilder = new MyEventBuilder (this, - Parent.TypeBuilder, Name, e_attr, MemberType); - - if (Add.Block == null && Remove.Block == null && - !IsInterface) { - FieldBuilder = Parent.TypeBuilder.DefineField ( - Name, MemberType, - FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0)); - TypeManager.RegisterPrivateFieldOfEvent ( - (EventInfo) EventBuilder, FieldBuilder); - TypeManager.RegisterFieldBase (FieldBuilder, this); - } + EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, e_attr, MemberType); - EventBuilder.SetAddOnMethod (AddBuilder); - EventBuilder.SetRemoveOnMethod (RemoveBuilder); - - TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder); + if (Add.Block == null && Remove.Block == null && !IsInterface) { + FieldBuilder = Parent.TypeBuilder.DefineField ( + Name, MemberType, + FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0)); + TypeManager.RegisterPrivateFieldOfEvent ( + (EventInfo) EventBuilder, FieldBuilder); + TypeManager.RegisterFieldBase (FieldBuilder, this); } + EventBuilder.SetAddOnMethod (AddBuilder); + EventBuilder.SetRemoveOnMethod (RemoveBuilder); + + TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder); return true; } @@ -6532,6 +6743,13 @@ namespace Mono.CSharp { return TypeManager.GetFullNameSignature (EventBuilder); } + + // + // Represents header string for documentation comment. + // + public override string DocCommentHeader { + get { return "E:"; } + } } @@ -6659,23 +6877,35 @@ namespace Mono.CSharp { if (!base.Define ()) return false; + if (MemberType == TypeManager.void_type) { + Report.Error (620, Location, "Indexers cannot have void type"); + return false; + } + if (OptAttributes != null) { - Attribute indexer_attr = OptAttributes.GetIndexerNameAttribute (ec); + Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type, ec); if (indexer_attr != null) { + // Remove the attribute from the list because it is not emitted + OptAttributes.Attrs.Remove (indexer_attr); + ShortName = indexer_attr.GetIndexerAttributeValue (ec); if (IsExplicitImpl) { - Report.Error (415, indexer_attr.Location, "The 'IndexerName' attribute is valid only on an indexer that is not an explicit interface member declaration"); + Report.Error (415, indexer_attr.Location, + "The 'IndexerName' attribute is valid only on an" + + "indexer that is not an explicit interface member declaration"); return false; } if ((ModFlags & Modifiers.OVERRIDE) != 0) { - Report.Error (609, indexer_attr.Location, "Cannot set the 'IndexerName' attribute on an indexer marked override"); + Report.Error (609, indexer_attr.Location, + "Cannot set the 'IndexerName' attribute on an indexer marked override"); return false; } if (!Tokenizer.IsValidIdentifier (ShortName)) { - Report.Error (633, indexer_attr.Location, "The argument to the 'IndexerName' attribute must be a valid identifier"); + Report.Error (633, indexer_attr.Location, + "The argument to the 'IndexerName' attribute must be a valid identifier"); return false; } @@ -6684,14 +6914,14 @@ namespace Mono.CSharp { } if (InterfaceType != null) { - string parent_IndexerName = TypeManager.IndexerPropertyName (InterfaceType); - if (parent_IndexerName != Name) - ShortName = parent_IndexerName; + string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType); + if (base_IndexerName != Name) + ShortName = base_IndexerName; UpdateMemberName (); } - if (!Parent.AddToMemberContainer (this, true) || - !Parent.AddToMemberContainer (Get, true) || !Parent.AddToMemberContainer (Set, true)) + if (!Parent.AddToMemberContainer (this) || + !Parent.AddToMemberContainer (Get) || !Parent.AddToMemberContainer (Set)) return false; if (!CheckBase ()) @@ -6744,25 +6974,16 @@ namespace Mono.CSharp { } } - // - // Define the PropertyBuilder if one of the following conditions are met: - // a) we're not implementing an interface indexer. - // b) the indexer has a different IndexerName and this is no - // explicit interface implementation. - // - if (!IsExplicitImpl) { - PropertyBuilder = Parent.TypeBuilder.DefineProperty ( - ShortName, prop_attr, MemberType, ParameterTypes); - - if (!Get.IsDummy) - PropertyBuilder.SetGetMethod (GetBuilder); + PropertyBuilder = Parent.TypeBuilder.DefineProperty ( + Name, prop_attr, MemberType, ParameterTypes); + + if (!Get.IsDummy) + PropertyBuilder.SetGetMethod (GetBuilder); - if (!Set.IsDummy) - PropertyBuilder.SetSetMethod (SetBuilder); + if (!Set.IsDummy) + PropertyBuilder.SetSetMethod (SetBuilder); - TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, - ParameterTypes); - } + TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, ParameterTypes); return true; } @@ -6779,6 +7000,13 @@ namespace Mono.CSharp { { return String.Concat (tc.Name, ".this[", Parameters.FixedParameters [0].TypeName.ToString (), ']'); } + + public override bool MarkForDuplicationCheck () + { + caching_flags |= Flags.TestMethodDuplication; + return true; + } + } public class Operator : MethodCore, IIteratorContainer { @@ -6894,6 +7122,11 @@ namespace Mono.CSharp { if (!DoDefine ()) return false; + if (MemberType == TypeManager.void_type) { + Report.Error (590, Location, "User-defined operators cannot return void"); + return false; + } + OperatorMethod = new Method ( Parent, Type, ModFlags, false, MemberName, Parameters, OptAttributes, Location); @@ -7030,7 +7263,7 @@ namespace Mono.CSharp { } // Operator cannot be override - protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type) + protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type) { return null; } @@ -7113,6 +7346,12 @@ namespace Mono.CSharp { return ToString (); } + public override bool MarkForDuplicationCheck () + { + caching_flags |= Flags.TestMethodDuplication; + return true; + } + public override string ToString () { if (OperatorMethod == null)