// 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 <miguel@ximian.com>
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 {
// 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
//
// from classes from the arraylist `type_bases'
//
string base_class_name;
- public Type base_class_type;
+ TypeExpr base_type;
ArrayList type_bases;
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";
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)
public void AddMethod (Method method)
{
- if (!AddToMemberContainer (method, true))
+ if (!AddToMemberContainer (method))
return;
if (methods == null)
public void AddField (Field field)
{
- if (!AddToMemberContainer (field, false))
+ if (!AddToMemberContainer (field))
return;
if (fields == null)
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)
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;
}
public void AddOperator (Operator op)
{
- if (!AddToMemberContainer (op, true))
+ if (!AddToMemberContainer (op))
return;
if (operators == null)
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 ();
+ }
}
}
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)
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){
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;
/// 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'.
/// </summary>
- TypeExpr [] GetClassBases (out TypeExpr parent, out bool error)
+ TypeExpr [] GetClassBases (out TypeExpr base_class, out bool error)
{
int i;
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 ());
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;
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++) {
"`{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;
//
public override TypeBuilder DefineType ()
{
- TypeExpr parent;
-
if (TypeBuilder != null)
return TypeBuilder;
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;
}
}
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;
}
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 ();
return null;
TypeBuilder = builder.DefineNestedType (
- Basename, type_attributes, base_class_type, null);
+ Basename, type_attributes, ptype, null);
}
}
catch (ArgumentException) {
}
// 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);
}
//
//
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);
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);
}
}
// 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)
#if CACHE
if (!(this is ClassPart))
- member_cache = new MemberCache (this, false);
+ member_cache = new MemberCache (this);
#endif
if (parts != null) {
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);
}
/// <summary>
}
//
- // Lookup members in parent if requested.
+ // Lookup members in base if requested.
//
if ((bf & BindingFlags.DeclaredOnly) == 0) {
if (TypeBuilder.BaseType != null) {
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) {
//
// 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)
type_bases = null;
OptAttributes = null;
ifaces = null;
- parent_container = null;
+ base_cache = null;
member_cache = null;
}
// 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;
}
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;
}
}
}
}
+ public Constructor DefaultStaticConstructor {
+ get { return default_static_constructor; }
+ }
+
protected override bool VerifyClsCompliance (DeclSpace ds)
{
if (!base.VerifyClsCompliance (ds))
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;
}
/// </summary>
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) {
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) {
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;
}
}
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;
}
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);
}
}
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;
}
}
}
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;
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;
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;
}
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 ();
interface_type, full, name, loc);
}
- public override IMemberContainer ParentContainer {
+ public override MemberCache BaseCache {
get {
- return PartialContainer.ParentContainer;
+ return PartialContainer.BaseCache;
}
}
}
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");
}
}
+ 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)
continue;
}
- if ((m.ModFlags & Modifiers.STATIC) != 0)
+ if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate)
continue;
if (m is Constructor) {
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 ());
}
}
public class Class : ClassOrStruct {
- // <summary>
- // Modifiers allowed in a class declaration
- // </summary>
+ // TODO: remove this and use only AllowedModifiersProp to fix partial classes bugs
public const int AllowedModifiers =
Modifiers.NEW |
Modifiers.PUBLIC |
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);
}
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?
this.ModFlags |= Modifiers.SEALED;
}
- public override AttributeTargets AttributeTargets {
- get {
- return AttributeTargets.Struct;
- }
- }
-
public const TypeAttributes DefaultTypeAttributes =
TypeAttributes.SequentialLayout |
TypeAttributes.Sealed |
return null;
}
- public override AttributeTargets AttributeTargets {
- get {
- return AttributeTargets.Interface;
- }
- }
-
public const TypeAttributes DefaultTypeAttributes =
TypeAttributes.AutoLayout |
TypeAttributes.Abstract |
//
// 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" };
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;
}
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);
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 `" +
// 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 `" +
// 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?
protected abstract bool CheckForDuplications ();
/// <summary>
- /// Gets parent method and its return type
+ /// Gets base method and its return type
/// </summary>
- 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 ()
{
}
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);
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 ();
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))
caching_flags &= ~Flags.Excluded_Undetected;
- if (parent_method == null) {
+ if (base_method == null) {
if (OptAttributes == null)
return false;
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;
}
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;
}
public abstract class ConstructorInitializer {
ArrayList argument_list;
- protected ConstructorInfo parent_constructor;
+ protected ConstructorInfo base_constructor;
Parameters parameters;
Location loc;
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);
} 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);
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;
}
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);
}
}
}
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;
}
}
// 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;
}
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;
if (member is MethodCore)
((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc);
- SymbolWriter sw = CodeGen.SymbolWriter;
ToplevelBlock block = method.Block;
//
"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]);
}
}
MethodAttributes.NewSlot |
MethodAttributes.Virtual;
} else {
- if (!Parent.MethodModifiersValid (ModFlags, Name, Location))
+ if (!Parent.MethodModifiersValid (this))
return false;
flags = Modifiers.MethodAttr (ModFlags);
// 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 " +
"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;
}
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;
}
[Flags]
public enum Status : byte {
ASSIGNED = 1,
- USED = 2
+ USED = 2,
+ HAS_OFFSET = 4 // Used by FieldMember.
}
static string[] attribute_targets = new string [] { "field" };
/// <summary>
- /// Symbol with same name in parent class/struct
+ /// Symbol with same name in base class/struct
/// </summary>
public MemberInfo conflict_symbol;
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));
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) {
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)
{
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)");
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 ())
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:"; }
+ }
}
//
//
// 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);
}
}
{
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;
}
public override bool Define()
{
- return false;
+ throw new NotSupportedException ();
}
public virtual void Emit (TypeContainer container)
}
}
+ //
+ // 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()
{
}
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;
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;
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,
: 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 {
}
}
- 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 {
{
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;
+ }
}
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;
return TypeManager.CSharpSignature (PropertyBuilder, false);
}
-
protected override bool CheckForDuplications ()
{
ArrayList ar = Parent.Indexers;
}
// 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 ()
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 {
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;
}
{
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 {
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,
}
if (a.Target == AttributeTargets.Method) {
- AddBuilder.SetCustomAttribute (cb);
- RemoveBuilder.SetCustomAttribute (cb);
+ Add.ApplyAttributeBuilder (a, cb);
+ Remove.ApplyAttributeBuilder (a, cb);
return;
}
public override string[] ValidAttributeTargets {
get {
- return attribute_targets;
+ return IsInterface ? attribute_targets_interface : attribute_targets;
}
}
}
}
ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
- EmitContext ec = CreateEmitContext (tc, ig);
FieldInfo field_info = (FieldInfo)method.FieldBuilder;
method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized);
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;
}
return TypeManager.GetFullNameSignature (EventBuilder);
}
+
+ //
+ // Represents header string for documentation comment.
+ //
+ public override string DocCommentHeader {
+ get { return "E:"; }
+ }
}
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;
}
}
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 ())
}
}
- //
- // 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;
}
{
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 {
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);
}
// 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;
}
return ToString ();
}
+ public override bool MarkForDuplicationCheck ()
+ {
+ caching_flags |= Flags.TestMethodDuplication;
+ return true;
+ }
+
public override string ToString ()
{
if (OperatorMethod == null)