/// </summary>
public abstract class TypeContainer : DeclSpace, IMemberContainer {
+ protected class CircularDepException: Exception
+ {
+ public TypeContainer Container;
+ public CircularDepException (TypeContainer tc)
+ {
+ Container = tc;
+ }
+ }
+
public class MemberCoreArrayList: ArrayList
{
/// <summary>
// Register all the operators we care about.
foreach (Operator op in this){
int reg = 0;
-
+
+ // Skip erroneous code.
+ if (op.OperatorMethod == null)
+ continue;
+
switch (op.OperatorType){
case Operator.OpType.Equality:
reg = 1;
// from classes from the arraylist `type_bases'
//
string base_class_name;
- TypeExpr parent_type;
+ TypeExpr base_type;
ArrayList type_bases;
protected Type [] ifaces;
protected Type ptype;
- // The parent member cache and our member cache
- MemberCache parent_cache;
+ // The base member cache and our member cache
+ MemberCache base_cache;
MemberCache member_cache;
public const string DefaultIndexerName = "Item";
+
+ // This is used to catch recursive definitions in declarations.
+ protected bool InTransit;
public TypeContainer (NamespaceEntry ns, TypeContainer parent, MemberName name,
Attributes attrs, Kind kind, Location l)
: base (ns, parent, name, attrs, l)
{
+ if (parent != null && parent != RootContext.Tree.Types && parent.NamespaceEntry != ns)
+ throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
+
this.Kind = kind;
types = new ArrayList ();
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, symbol.Name);
}
bool AddToTypeContainer (DeclSpace ds)
{
- return AddToContainer (ds, false, ds.Name, ds.Basename);
+ // Parent == null ==> this == RootContext.Tree.Types
+ return AddToContainer (ds, (Parent == null) ? 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)
methods = new MethodArrayList (this);
- if (method.Name.IndexOf ('.') != -1)
+ if (method.MemberName.Left != null)
methods.Insert (0, method);
else
methods.Add (method);
interfaces.Add (iface);
}
- public void AddField (Field field)
+ public void AddField (FieldMember field)
{
- if (!AddToMemberContainer (field, false))
+ if (!AddToMemberContainer (field))
return;
if (fields == null)
fields.Add (field);
- if (field.HasInitializer){
- if ((field.ModFlags & Modifiers.STATIC) != 0){
- if (initialized_static_fields == null)
- initialized_static_fields = new ArrayList ();
-
- initialized_static_fields.Add (field);
- } else {
- if (initialized_fields == null)
- initialized_fields = new ArrayList ();
-
- initialized_fields.Add (field);
- }
- }
+ if (field.HasInitializer)
+ RegisterFieldForInitialization (field);
if ((field.ModFlags & Modifiers.STATIC) == 0)
have_nonstatic_fields = true;
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)
properties = new MemberCoreArrayList ();
- if (prop.Name.IndexOf ('.') != -1)
+ if (prop.MemberName.Left != null)
properties.Insert (0, prop);
else
properties.Add (prop);
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 virtual TypeAttributes TypeAttr {
+ protected override TypeAttributes TypeAttr {
get {
- return Modifiers.TypeAttr (ModFlags, this);
+ return Modifiers.TypeAttr (ModFlags, this) | base.TypeAttr;
}
}
}
}
+ public virtual void RegisterFieldForInitialization (FieldMember field)
+ {
+ if ((field.ModFlags & Modifiers.STATIC) != 0){
+ if (initialized_static_fields == null)
+ initialized_static_fields = new ArrayList ();
+
+ initialized_static_fields.Add (field);
+ } else {
+ if (initialized_fields == null)
+ initialized_fields = new ArrayList ();
+
+ initialized_fields.Add (field);
+ }
+ }
+
//
// Emits the instance field initializers
//
- public bool EmitFieldInitializers (EmitContext ec)
+ public virtual bool EmitFieldInitializers (EmitContext ec)
{
ArrayList fields;
Expression instance_expr;
if (fields == null)
return true;
- foreach (Field f in fields){
+ foreach (FieldMember f in fields){
Expression e = f.GetInitializerExpression (ec);
if (e == null)
return false;
Location l = f.Location;
- FieldExpr fe = new FieldExpr (f.FieldBuilder, l);
+ FieldExpr fe = new FieldExpr (f.FieldBuilder, l, true);
fe.InstanceExpression = instance_expr;
ExpressionStatement a = new Assign (fe, e, l);
if (a == null)
return false;
+ Constant c = e as Constant;
+ if (c != null) {
+ if (c.IsDefaultValue)
+ continue;
+ }
+
a.EmitStatement (ec);
}
else if ((ModFlags & Modifiers.ABSTRACT) != 0)
mods = Modifiers.PROTECTED;
- c = new Constructor (this, Basename, mods, Parameters.EmptyReadOnlyParameters,
+ TypeContainer constructor_parent = this;
+ if (Parts != null)
+ constructor_parent = (TypeContainer) Parts [0];
+
+ c = new Constructor (constructor_parent, Basename, mods,
+ Parameters.EmptyReadOnlyParameters,
new ConstructorBaseInitializer (
null, Parameters.EmptyReadOnlyParameters,
Location),
/// </remarks>
public PendingImplementation Pending;
- public abstract void Register ();
-
public abstract PendingImplementation GetPendingImplementations ();
- TypeExpr[] GetPartialBases (out TypeExpr parent, out bool error)
+ TypeExpr[] GetPartialBases (out TypeExpr base_class)
{
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);
- if (error)
+ new_ifaces = part.GetClassBases (out new_base_class);
+ if (new_ifaces == null && base_type != null)
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)
}
}
- error = false;
-
TypeExpr[] retval = new TypeExpr [ifaces.Count];
ifaces.CopyTo (retval, 0);
return retval;
}
- TypeExpr[] GetNormalBases (out TypeExpr parent, out bool error)
+ TypeExpr[] GetNormalBases (out TypeExpr base_class)
{
- 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){
- error = true;
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;
}
ifaces [j] = resolved;
}
- error = false;
return ifaces;
}
/// 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)
{
int i;
- error = false;
-
TypeExpr[] ifaces;
if (parts != null)
- ifaces = GetPartialBases (out parent, out error);
+ ifaces = GetPartialBases (out base_class);
else if (Bases == null){
- parent = null;
+ base_class = null;
return null;
} else
- ifaces = GetNormalBases (out parent, out error);
+ ifaces = GetNormalBases (out base_class);
- if (error)
+ if (ifaces == null)
return null;
- if ((parent != null) && (Kind == Kind.Class)){
+ if ((base_class != null) && (Kind == Kind.Class)){
- if (parent.Type.IsArray || parent.Type.IsPointer) {
- Report.Error (1521, parent.Location, "Invalid base type");
- error = true;
+ if (base_class.Type.IsArray || base_class.Type.IsPointer) {
+ Report.Error (1521, base_class.Location, "Invalid base type");
return null;
}
- if (parent.IsSealed){
- error = true;
- Report.SymbolRelatedToPreviousError (parent.Type);
- if (parent.Type.IsAbstract) {
+ if (base_class.IsSealed){
+ 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);
- error = true;
+ Name, base_class.Name);
return null;
}
- if (!parent.AsAccessible (this, ModFlags)) {
- Report.SymbolRelatedToPreviousError (parent.Type);
+ 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 (parent.Type), GetSignatureForError ());
+ 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);
- error = true;
- return null;
- }
- if (iface.IsClass) {
- if (parent != null)
+ if (!iface.IsInterface) {
+ if (Kind != Kind.Class) {
+ // TODO: location of symbol related ....
+ Error_TypeInListIsNotInterface (Location, iface.FullName);
+ }
+ else if (base_class != null)
Report.Error (1721, Location,
"In Class `{0}', `{1}' is not an interface, and a base class has already been defined",
Name, iface.Name);
"In Class `{0}', `{1}' is not " +
"an interface, a base class must be listed first", Name, iface.Name);
}
- error = true;
return null;
}
Report.Error (528, Location,
"`{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);
+ return null;
+ }
}
-
return ifaces;
}
- bool error = false;
-
+ protected void Error_TypeInListIsNotInterface (Location loc, string type)
+ {
+ Report.Error (527, loc, "'{0}': type in interface list is not an interface", type);
+ }
+
//
// Defines the type in the appropriate ModuleBuilder or TypeBuilder.
//
{
if (TypeBuilder != null)
return TypeBuilder;
-
- if (error)
- return null;
-
- if (InTransit) {
- Report.Error (146, Location, "Class definition is circular: `{0}'", Name);
- error = true;
- return null;
- }
InTransit = true;
- ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
-
- TypeExpr[] iface_exprs = GetClassBases (out parent_type, out error);
- if (error)
+ TypeExpr[] iface_exprs = GetClassBases (out base_type);
+ if (iface_exprs == null && base_type != null) {
+ InTransit = false;
return null;
+ }
- if (parent_type == null) {
+ if (base_type == null) {
if (Kind == Kind.Class){
if (RootContext.StdLib)
- parent_type = TypeManager.system_object_expr;
+ base_type = TypeManager.system_object_expr;
else if (Name != "System.Object")
- parent_type = 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_type = TypeManager.system_object_expr;
+ base_type = TypeManager.system_object_expr;
else
- parent_type = TypeManager.system_valuetype_expr;
+ base_type = TypeManager.system_valuetype_expr;
}
}
TypeAttributes type_attributes = TypeAttr;
- if (parent_type != null) {
- ptype = parent_type.ResolveType (ec);
+ if (base_type != null) {
+ // FIXME: I think this should be ...ResolveType (Parent.EmitContext).
+ // However, if Parent == RootContext.Tree.Types, its NamespaceEntry will be null.
+ ptype = base_type.ResolveType (TypeResolveEmitContext);
if (ptype == null) {
- error = true;
+ InTransit = false;
return null;
}
}
try {
if (IsTopLevel){
if (TypeManager.NamespaceClash (Name, Location)) {
- error = true;
+ InTransit = false;
return null;
}
Name, type_attributes, ptype, null);
} else {
- TypeBuilder builder = Parent.DefineType ();
- if (builder == null)
+ TypeBuilder builder = Parent.TypeBuilder;
+ if (builder == null) {
+ InTransit = false;
return null;
+ }
TypeBuilder = builder.DefineNestedType (
Basename, type_attributes, ptype, null);
}
catch (ArgumentException) {
Report.RuntimeMissingSupport (Location, "static classes");
+ InTransit = false;
return null;
}
-
- //
- // Structs with no fields need to have at least one byte.
- // The right thing would be to set the PackingSize in a DefineType
- // but there are no functions that allow interfaces *and* the size to
- // be specified.
- //
- if ((Kind == Kind.Struct) && !have_nonstatic_fields){
- TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
- FieldAttributes.Private);
+ if (Parts != null) {
+ ec = null;
+ foreach (ClassPart part in Parts) {
+ part.TypeBuilder = TypeBuilder;
+ part.ptype = ptype;
+ part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags);
+ part.ec.ContainerType = TypeBuilder;
+ }
+ }
+ else {
+ ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
+ ec.ContainerType = TypeBuilder;
}
// add interfaces that were not added at type creation
if (iface_exprs != null) {
- ifaces = TypeManager.ExpandInterfaces (ec, iface_exprs);
+ // FIXME: I think this should be ...ExpandInterfaces (Parent.EmitContext, ...).
+ // However, if Parent == RootContext.Tree.Types, its NamespaceEntry will be null.
+ TypeResolveEmitContext.ContainerType = TypeBuilder;
+ ifaces = TypeManager.ExpandInterfaces (TypeResolveEmitContext, iface_exprs);
if (ifaces == null) {
- error = true;
+ InTransit = false;
return null;
}
TypeManager.RegisterBuilder (TypeBuilder, ifaces);
}
- //
- // Finish the setup for the EmitContext
- //
- ec.ContainerType = TypeBuilder;
-
TypeManager.AddUserType (Name, TypeBuilder, this);
- if ((parent_type != null) && parent_type.IsAttribute) {
- RootContext.RegisterAttribute (this);
- } else if (!(this is Iterator))
+ if (!(this is Iterator))
RootContext.RegisterOrder (this);
+ InTransit = false;
+
if (!DefineNestedTypes ()) {
- error = true;
return null;
}
- InTransit = false;
return TypeBuilder;
}
return false;
}
- if (Parts != null) {
- foreach (ClassPart part in Parts) {
- part.TypeBuilder = TypeBuilder;
- part.ptype = ptype;
- part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags);
- }
- }
-
return true;
}
bool DoDefineMembers ()
{
- //
- // We need to be able to use the member cache while we are checking/defining
- //
- if (TypeBuilder.BaseType != null)
- parent_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
-
- if (TypeBuilder.IsInterface)
- parent_cache = TypeManager.LookupParentInterfacesCache (TypeBuilder);
-
if (IsTopLevel) {
if ((ModFlags & Modifiers.NEW) != 0)
Error_KeywordNotAllowed (Location);
} else {
- // HACK: missing implemenation
- // This is not fully functional. Better way how to handle this is to have recursive definition of containers
- // instead of flat as we have now.
- // Now we are not able to check inner attribute class because its parent had not been defined.
-
- // TODO: remove this if
- if (Parent.MemberCache != null) {
- MemberInfo conflict_symbol = Parent.MemberCache.FindMemberWithSameName (Basename, false, TypeBuilder);
- if (conflict_symbol == null) {
- if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0))
- Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
- } else {
- if ((ModFlags & Modifiers.NEW) == 0) {
- Report.SymbolRelatedToPreviousError (conflict_symbol);
- Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError ());
- }
+ MemberInfo conflict_symbol = Parent.MemberCache.FindMemberWithSameName (Basename, false, TypeBuilder);
+ if (conflict_symbol == null) {
+ if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0))
+ Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
+ } else {
+ if ((ModFlags & Modifiers.NEW) == 0) {
+ Report.SymbolRelatedToPreviousError (conflict_symbol);
+ Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError ());
}
- }
+ }
}
DefineContainerMembers (constants);
DefineContainerMembers (fields);
- if ((Kind == Kind.Class) && !(this is ClassPart) && !(this is StaticClass)){
+ if ((Kind == Kind.Class) && !(this is ClassPart)){
if ((instance_constructors == null) &&
!(this is StaticClass)) {
if (default_constructor == null)
return true;
}
- public MemberInfo FindMemberWithSameName (string name, bool ignore_methods)
+ public MemberInfo FindBaseMemberWithSameName (string name, bool ignore_methods)
{
- return ParentCache.FindMemberWithSameName (name, ignore_methods, null);
+ return BaseCache.FindMemberWithSameName (name, ignore_methods, null);
}
/// <summary>
return false;
}
}
+
+ public override Type FindNestedType (string name)
+ {
+ ArrayList [] lists = { types, enums, delegates, interfaces };
+
+ for (int j = 0; j < lists.Length; ++j) {
+ ArrayList list = lists [j];
+ if (list == null)
+ continue;
+
+ int len = list.Count;
+ for (int i = 0; i < len; ++i) {
+ DeclSpace ds = (DeclSpace) list [i];
+ if (ds.Basename == name) {
+ ds.DefineType ();
+ return ds.TypeBuilder;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private void FindMembers_NestedTypes (int modflags,
+ BindingFlags bf, MemberFilter filter, object criteria,
+ ref ArrayList members)
+ {
+ ArrayList [] lists = { types, enums, delegates, interfaces };
+
+ for (int j = 0; j < lists.Length; ++j) {
+ ArrayList list = lists [j];
+ if (list == null)
+ continue;
+
+ int len = list.Count;
+ for (int i = 0; i < len; i++) {
+ DeclSpace ds = (DeclSpace) list [i];
+
+ if ((ds.ModFlags & modflags) == 0)
+ continue;
+
+ TypeBuilder tb = ds.TypeBuilder;
+ if (tb == null) {
+ if (!(criteria is string) || ds.Basename.Equals (criteria))
+ tb = ds.DefineType ();
+ }
+
+ if (tb != null && (filter (tb, criteria) == true)) {
+ if (members == null)
+ members = new ArrayList ();
+
+ members.Add (tb);
+ }
+ }
+ }
+ }
/// <summary>
/// This method returns the members of this type just like Type.FindMembers would
if (fields != null) {
int len = fields.Count;
for (int i = 0; i < len; i++) {
- Field f = (Field) fields [i];
+ FieldMember f = (FieldMember) fields [i];
if ((f.ModFlags & modflags) == 0)
continue;
continue;
FieldBuilder fb = con.FieldBuilder;
+ if (fb == null) {
+ if (con.Define ())
+ fb = con.FieldBuilder;
+ }
if (fb != null && filter (fb, criteria) == true) {
if (members == null)
members = new ArrayList ();
}
}
- if ((mt & MemberTypes.NestedType) != 0) {
- if (types != null) {
- int len = types.Count;
- for (int i = 0; i < len; i++) {
- TypeContainer t = (TypeContainer) types [i];
-
- if ((t.ModFlags & modflags) == 0)
- continue;
-
- TypeBuilder tb = t.TypeBuilder;
- if (tb != null && (filter (tb, criteria) == true)) {
- if (members == null)
- members = new ArrayList ();
-
- members.Add (tb);
- }
- }
- }
-
- if (enums != null) {
- int len = enums.Count;
- for (int i = 0; i < len; i++) {
- Enum en = (Enum) enums [i];
-
- if ((en.ModFlags & modflags) == 0)
- continue;
-
- TypeBuilder tb = en.TypeBuilder;
- if (tb != null && (filter (tb, criteria) == true)) {
- if (members == null)
- members = new ArrayList ();
-
- members.Add (tb);
- }
- }
- }
-
- if (delegates != null) {
- int len = delegates.Count;
- for (int i = 0; i < len; i++) {
- Delegate d = (Delegate) delegates [i];
-
- if ((d.ModFlags & modflags) == 0)
- continue;
-
- TypeBuilder tb = d.TypeBuilder;
- if (tb != null && (filter (tb, criteria) == true)) {
- if (members == null)
- members = new ArrayList ();
-
- members.Add (tb);
- }
- }
- }
-
- if (interfaces != null) {
- int len = interfaces.Count;
- for (int i = 0; i < len; i++) {
- TypeContainer iface = (TypeContainer) interfaces [i];
-
- if ((iface.ModFlags & modflags) == 0)
- continue;
-
- TypeBuilder tb = iface.TypeBuilder;
- if (tb != null && (filter (tb, criteria) == true)) {
- if (members == null)
- members = new ArrayList ();
-
- members.Add (tb);
- }
- }
- }
- }
+ if ((mt & MemberTypes.NestedType) != 0)
+ FindMembers_NestedTypes (modflags, bf, filter, criteria, ref members);
if ((mt & MemberTypes.Constructor) != 0){
if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
}
//
- // Lookup members in parent if requested.
+ // Lookup members in base if requested.
//
if ((bf & BindingFlags.DeclaredOnly) == 0) {
if (TypeBuilder.BaseType != null) {
return;
}
- protected virtual void VerifyMembers (EmitContext ec)
+ void CheckMemberUsage (MemberCoreArrayList al, string member_type)
+ {
+ if (al == null)
+ return;
+
+ foreach (MemberCore mc in al) {
+ if ((mc.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
+ continue;
+
+ if (!mc.IsUsed) {
+ Report.Warning (169, mc.Location, "The private {0} '{1}' is never used", member_type, mc.GetSignatureForError ());
+ }
+ }
+ }
+
+ public virtual void VerifyMembers ()
{
//
// Check for internal or private fields that were never assigned
//
if (RootContext.WarningLevel >= 3) {
+ CheckMemberUsage (properties, "property");
+ CheckMemberUsage (methods, "method");
+ CheckMemberUsage (constants, "constant");
+
if (fields != null){
- foreach (Field f in fields) {
+ foreach (FieldMember f in fields) {
if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
continue;
- if ((f.status & Field.Status.USED) == 0){
+ if (!f.IsUsed){
Report.Warning (169, f.Location, "The private field '{0}' is never used", f.GetSignatureForError ());
continue;
}
if (OptAttributes != null)
OptAttributes.Emit (ec, this);
+ //
+ // Structs with no fields need to have at least one byte.
+ // The right thing would be to set the PackingSize in a DefineType
+ // but there are no functions that allow interfaces *and* the size to
+ // be specified.
+ //
+
+ if ((Kind == Kind.Struct) && !have_nonstatic_fields){
+ FieldBuilder fb = TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
+ FieldAttributes.Private);
+
+ if (HasExplicitLayout){
+ object [] ctor_args = new object [1];
+ ctor_args [0] = 0;
+
+ CustomAttributeBuilder cba = new CustomAttributeBuilder (
+ TypeManager.field_offset_attribute_ctor, ctor_args);
+ fb.SetCustomAttribute (cba);
+ }
+ }
+
Emit ();
if (instance_constructors != null) {
}
if (fields != null)
- foreach (Field f in fields)
+ foreach (FieldMember f in fields)
f.Emit ();
if (events != null){
if (Pending.VerifyPendingMethods ())
return;
- VerifyMembers (ec);
-
if (iterators != null)
foreach (Iterator iterator in iterators)
iterator.EmitType ();
type_bases = null;
OptAttributes = null;
ifaces = null;
- parent_cache = null;
+ base_cache = null;
member_cache = null;
}
/// </summary>
void VerifyClsName ()
{
- Hashtable parent_members = parent_cache == null ?
+ Hashtable base_members = base_cache == null ?
new Hashtable () :
- parent_cache.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) {
get { return "T:"; }
}
- public virtual MemberCache ParentCache {
+ public virtual MemberCache BaseCache {
get {
- return parent_cache;
+ if (base_cache != null)
+ return base_cache;
+ if (TypeBuilder.BaseType != null)
+ base_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
+ if (TypeBuilder.IsInterface)
+ base_cache = TypeManager.LookupBaseInterfacesCache (TypeBuilder);
+ return base_cache;
}
}
}
Location loc)
{
PartialContainer pc;
- string full_name = member_name.GetName (true);
- DeclSpace ds = (DeclSpace) RootContext.Tree.Decls [full_name];
+ DeclSpace ds = RootContext.Tree.GetDecl (member_name);
if (ds != null) {
pc = ds as PartialContainer;
return pc;
}
- pc = new PartialContainer (ns, parent, member_name, mod_flags, kind, loc);
- RootContext.Tree.RecordDecl (full_name, pc);
- parent.AddType (pc);
- pc.Register ();
+ if (parent is ClassPart)
+ parent = ((ClassPart) parent).PartialContainer;
+
+ pc = new PartialContainer (ns.NS, parent, member_name, mod_flags, kind, loc);
+ RootContext.Tree.RecordDecl (member_name, pc);
+
+ if (kind == Kind.Interface)
+ parent.AddInterface (pc);
+ else if (kind == Kind.Class || kind == Kind.Struct)
+ parent.AddClassOrStruct (pc);
+ else
+ throw new InvalidOperationException ();
+
return pc;
}
if (pc == null) {
// An error occured; create a dummy container, but don't
// register it.
- pc = new PartialContainer (ns, parent, name, mod, kind, loc);
+ pc = new PartialContainer (ns.NS, parent, name, mod, kind, loc);
}
- ClassPart part = new ClassPart (ns, pc, mod, attrs, kind, loc);
+ ClassPart part = new ClassPart (ns, pc, parent, mod, attrs, kind, loc);
pc.AddPart (part);
return part;
}
- protected PartialContainer (NamespaceEntry ns, TypeContainer parent,
+ protected PartialContainer (Namespace ns, TypeContainer parent,
MemberName name, int mod, Kind kind, Location l)
- : base (ns, parent, name, null, kind, l)
+ : base (null, parent, name, null, kind, l)
{
- this.Namespace = ns.NS;
+ this.Namespace = ns;
switch (kind) {
case Kind.Class:
this.OriginalModFlags = mod;
}
- public override void Register ()
- {
- if (Kind == Kind.Interface)
- Parent.AddInterface (this);
- else if (Kind == Kind.Class || Kind == Kind.Struct)
- Parent.AddClassOrStruct (this);
- else
- throw new InvalidOperationException ();
- }
-
public override PendingImplementation GetPendingImplementations ()
{
return PendingImplementation.GetPendingImplementations (this);
}
- public ClassPart AddPart (NamespaceEntry ns, int mod, Attributes attrs,
- Location l)
- {
- ClassPart part = new ClassPart (ns, this, mod, attrs, Kind, l);
- AddPart (part);
- return part;
- }
-
- public override TypeAttributes TypeAttr {
+ protected override TypeAttributes TypeAttr {
get {
return base.TypeAttr | DefaultTypeAttributes;
}
public readonly PartialContainer PartialContainer;
public readonly bool IsPartial;
- public ClassPart (NamespaceEntry ns, PartialContainer parent,
+ public ClassPart (NamespaceEntry ns, PartialContainer pc, TypeContainer parent,
int mod, Attributes attrs, Kind kind, Location l)
- : base (ns, parent.Parent, parent.MemberName, attrs, kind, l)
+ : base (ns, parent, pc.MemberName, attrs, kind, l)
{
- this.PartialContainer = parent;
+ this.PartialContainer = pc;
this.IsPartial = true;
int accmods;
- if (parent.Parent == null)
+ if (parent == null || parent == RootContext.Tree.Types)
accmods = Modifiers.INTERNAL;
else
accmods = Modifiers.PRIVATE;
- this.ModFlags = Modifiers.Check (
- parent.AllowedModifiers, mod, accmods, l);
- }
-
- public override void Register ()
- {
+ this.ModFlags = Modifiers.Check (pc.AllowedModifiers, mod, accmods, l);
}
public override PendingImplementation GetPendingImplementations ()
interface_type, full, name, loc);
}
- public override MemberCache ParentCache {
+
+ public override void RegisterFieldForInitialization (FieldMember field)
+ {
+ PartialContainer.RegisterFieldForInitialization (field);
+ }
+
+ public override bool EmitFieldInitializers (EmitContext ec)
+ {
+ return PartialContainer.EmitFieldInitializers (ec);
+ }
+
+ public override Type FindNestedType (string name)
+ {
+ return PartialContainer.FindNestedType (name);
+ }
+
+ public override MemberCache BaseCache {
get {
- return PartialContainer.ParentCache;
+ return PartialContainer.BaseCache;
}
}
}
public abstract class ClassOrStruct : TypeContainer {
- bool hasExplicitLayout = false;
+ bool has_explicit_layout = false;
ListDictionary declarative_security;
public ClassOrStruct (NamespaceEntry ns, TypeContainer parent,
public override bool HasExplicitLayout {
get {
- return hasExplicitLayout;
+ return has_explicit_layout;
}
}
- protected override void VerifyMembers (EmitContext ec)
+ public override void VerifyMembers ()
{
- base.VerifyMembers (ec);
+ base.VerifyMembers ();
if ((events != null) && (RootContext.WarningLevel >= 3)) {
foreach (Event e in events){
return;
}
- if (a.Type == TypeManager.struct_layout_attribute_type
- && (LayoutKind) a.GetPositionalValue (0) == LayoutKind.Explicit)
- hasExplicitLayout = true;
+ if (a.Type == TypeManager.struct_layout_attribute_type && a.GetLayoutKindValue () == LayoutKind.Explicit)
+ has_explicit_layout = true;
base.ApplyAttributeBuilder (a, cb);
}
}
}
}
-
- public override void Register ()
- {
- Parent.AddClassOrStruct (this);
- }
}
/// <summary>
{
if (RootContext.Version == LanguageVersion.ISO_1) {
Report.FeatureIsNotStandardized (l, "static classes");
- Environment.Exit (1);
}
}
continue;
}
- if ((m.ModFlags & Modifiers.STATIC) != 0)
+ if ((m.ModFlags & Modifiers.PROTECTED) != 0)
+ Report.Warning (628, 4, m.Location, "'{0}': new protected member declared in static class", m.GetSignatureForError (this));
+
+ if (m is Indexer) {
+ Report.Error (720, m.Location, "'{0}': cannot declare indexers in a static class", m.GetSignatureForError (this));
+ continue;
+ }
+
+ if ((m.ModFlags & Modifiers.STATIC) != 0 || m is Enum || m is Delegate)
continue;
if (m is Constructor) {
return tb;
}
- public override TypeAttributes TypeAttr {
+ protected override TypeAttributes TypeAttr {
get {
return base.TypeAttr | TypeAttributes.Abstract | TypeAttributes.Sealed;
}
Modifiers.SEALED |
Modifiers.UNSAFE;
- // Information in the case we are an attribute type
- AttributeUsageAttribute attribute_usage;
+ bool WasTransitError;
public Class (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
Attributes attrs, Location l)
: base (ns, parent, name, attrs, Kind.Class, l)
{
this.ModFlags = mod;
- attribute_usage = new AttributeUsageAttribute (AttributeTargets.All);
}
virtual protected int AllowedModifiersProp {
}
}
- public override AttributeTargets AttributeTargets {
- get {
- return AttributeTargets.Class;
- }
- }
-
public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
{
- if (a.UsageAttribute != null) {
+ if (a.Type == TypeManager.attribute_usage_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);
}
- attribute_usage = a.UsageAttribute;
}
- base.ApplyAttributeBuilder (a, cb);
- }
-
- public AttributeUsageAttribute AttributeUsage {
- get {
- return attribute_usage;
+ if (a.Type == TypeManager.conditional_attribute_type &&
+ !(ptype == TypeManager.attribute_type || ptype.IsSubclassOf (TypeManager.attribute_type))) {
+ Report.Error (1689, a.Location, "Attribute 'System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
+ return;
}
+
+ if (AttributeTester.IsAttributeExcluded (a.Type))
+ return;
+
+ base.ApplyAttributeBuilder (a, cb);
}
public const TypeAttributes DefaultTypeAttributes =
public override TypeBuilder DefineType()
{
+ if (InTransit) {
+ if (WasTransitError)
+ return null;
+ throw new CircularDepException (this);
+ }
+
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 ();
+ try {
+ return base.DefineType ();
+ }
+ catch (CircularDepException e) {
+ Report.SymbolRelatedToPreviousError (e.Container);
+ Report.Error (146, Location, "Circular base class dependency involving '{0}' and '{1}'",
+ GetSignatureForError (), e.Container.GetSignatureForError ());
+ WasTransitError = true;
+ return null;
+ }
+ }
+
+ /// Search for at least one defined condition in ConditionalAttribute of attribute class
+ /// Valid only for attribute classes.
+ public bool IsExcluded ()
+ {
+ if ((caching_flags & Flags.Excluded_Undetected) == 0)
+ return (caching_flags & Flags.Excluded) != 0;
+
+ caching_flags &= ~Flags.Excluded_Undetected;
+
+ if (OptAttributes == null)
+ return false;
+
+ Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type, ec);
+
+ if (attrs == null)
+ return false;
+
+ foreach (Attribute a in attrs) {
+ string condition = a.GetConditionalAttributeValue (Parent.EmitContext);
+ if (RootContext.AllDefines.Contains (condition))
+ return false;
+ }
+
+ caching_flags |= Flags.Excluded;
+ return true;
}
//
// FIXME: How do we deal with the user specifying a different
// layout?
//
- public override TypeAttributes TypeAttr {
+ protected override TypeAttributes TypeAttr {
get {
return base.TypeAttr | DefaultTypeAttributes;
}
this.ModFlags |= Modifiers.SEALED;
}
- public override AttributeTargets AttributeTargets {
- get {
- return AttributeTargets.Struct;
- }
- }
-
public const TypeAttributes DefaultTypeAttributes =
TypeAttributes.SequentialLayout |
TypeAttributes.Sealed |
// in some cases (Sealed for example is mandatory for a class,
// but what SequentialLayout can be changed
//
- public override TypeAttributes TypeAttr {
+ protected override TypeAttributes TypeAttr {
get {
return base.TypeAttr | DefaultTypeAttributes;
}
}
+
+ public override TypeBuilder DefineType()
+ {
+ if (InTransit) {
+ InTransit = false;
+ throw new CircularDepException (this);
+ }
+
+ try {
+ return base.DefineType ();
+ }
+ catch (CircularDepException e) {
+ InTransit = false;
+ Report.SymbolRelatedToPreviousError (this);
+ Error_TypeInListIsNotInterface (e.Container.Location, GetSignatureForError ());
+ return null;
+ }
+ }
}
/// <summary>
/// Interfaces
/// </summary>
public class Interface : TypeContainer, IMemberContainer {
+
+ bool WasTransitError;
+
/// <summary>
/// Modifiers allowed in a class declaration
/// </summary>
this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
}
- public override void Register ()
- {
- Parent.AddInterface (this);
- }
-
public override PendingImplementation GetPendingImplementations ()
{
return null;
}
- public override AttributeTargets AttributeTargets {
- get {
- return AttributeTargets.Interface;
- }
- }
-
public const TypeAttributes DefaultTypeAttributes =
TypeAttributes.AutoLayout |
TypeAttributes.Abstract |
TypeAttributes.Interface;
- public override TypeAttributes TypeAttr {
+ protected override TypeAttributes TypeAttr {
get {
return base.TypeAttr | DefaultTypeAttributes;
}
}
+
+ public override TypeBuilder DefineType()
+ {
+ if (InTransit) {
+ if (WasTransitError)
+ return null;
+ throw new CircularDepException (this);
+ }
+
+ try {
+ return base.DefineType ();
+ }
+ catch (CircularDepException e) {
+ Report.SymbolRelatedToPreviousError (e.Container);
+ Report.Error (529, Location, "Inherited interface '{0}' causes a cycle in the interface hierarchy of '{1}'",
+ e.Container.GetSignatureForError (), GetSignatureForError ());
+ WasTransitError = true;
+ return null;
+ }
+ }
+
+ protected override bool VerifyClsCompliance (DeclSpace ds)
+ {
+ if (!base.VerifyClsCompliance (ds))
+ return false;
+
+ if (ifaces != null) {
+ foreach (Type t in ifaces) {
+ if (AttributeTester.IsClsCompliant (t))
+ continue;
+
+ Report.SymbolRelatedToPreviousError (t);
+ Report.Warning (3027, 1, Location, "'{0}' is not CLS-compliant because base interface '{1}' is not CLS-compliant",
+ GetSignatureForError (), TypeManager.CSharpName (t));
+ }
+ }
+
+ return true;
+ }
}
public abstract class MethodCore : MemberBase {
//
// 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.ParentCache == 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);
- Report.Error (508, Location, GetSignatureForError (Parent) + ": cannot " +
- "change return type when overriding inherited member");
+ if (MemberType != TypeManager.TypeToCoreType (base_ret_type)) {
+ Report.SymbolRelatedToPreviousError (base_method);
+ if (this is PropertyBase) {
+ Report.Error (1715, Location, "'{0}': type must be '{1}' to match overridden member '{2}'",
+ GetSignatureForError (), TypeManager.CSharpName (base_ret_type), TypeManager.CSharpSignature (base_method));
+ }
+ else {
+ 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) {
- // This happens when implementing interface methods.
- if (parent_method.IsHideBySig && parent_method.IsVirtual) {
- Report.Error (
- 506, Location, Parent.MakeName (Name) +
- ": cannot override inherited member `" +
- name + "' because it is not " +
- "virtual, abstract or override");
- } else
- Report.Error (239, Location, Parent.MakeName (Name) + " : cannot " +
- "override inherited member `" + name +
- "' because it is sealed.");
+ if (base_method.IsFinal) {
+ Report.SymbolRelatedToPreviousError (base_method);
+ Report.Error (239, Location, "'{0}': cannot override inherited member '{1}' because it is sealed",
+ GetSignatureForError (), TypeManager.CSharpSignature (base_method));
ok = false;
}
//
// Check that the permissions are not being changed
//
MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
- MethodAttributes parentp = parent_method.Attributes & MethodAttributes.MemberAccessMask;
+ MethodAttributes base_classp = base_method.Attributes & MethodAttributes.MemberAccessMask;
- if (!CheckAccessModifiers (thisp, parentp, parent_method)) {
- Error_CannotChangeAccessModifiers (Parent, parent_method, name);
+ 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 parentp, MethodInfo base_method)
+ protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes base_classp, MethodInfo base_method)
{
- if ((parentp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
+ if ((base_classp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
//
// when overriding protected internal, the method can be declared
// protected internal only within the same assembly
//
return false;
- } else if (thisp != parentp) {
+ } else if (thisp != base_classp) {
//
// same assembly, but other attributes differ - report an error
//
//
return false;
} else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) !=
- (parentp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
+ (base_classp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
//
// protected ok, but other attributes differ - report an error
//
}
return true;
} else {
- return (thisp == parentp);
+ return (thisp == base_classp);
}
}
- void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo parent_method, string name)
+ 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 ()
{
}
Report.SymbolRelatedToPreviousError (method);
- Report.Error (111, Location, TypeContainer.Error111, Parent.Name, Name);
+ if (this is Operator && method is Operator)
+ Report.Error (557, Location, "Duplicate user-defined conversion in type '{0}'", Parent.Name);
+ else
+ Report.Error (111, Location, TypeContainer.Error111, Parent.Name, Name);
return true;
}
+ public override bool IsUsed
+ {
+ get {
+ if (IsExplicitImpl)
+ return true;
+
+ return base.IsUsed;
+ }
+ }
+
//
// Returns a string that represents the signature for this
// member which should be used in XML documentation.
return;
}
- if (a.Type == TypeManager.methodimpl_attr_type && a.IsInternalCall) {
+ if (a.Type == TypeManager.methodimpl_attr_type &&
+ (a.GetMethodImplOptions () & MethodImplOptions.InternalCall) != 0) {
MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
}
}
if (ReturnType != TypeManager.void_type) {
- Report.Error (578, Location, "Conditional not valid on '{0}' because its return new ErrorData ( type is not void", GetSignatureForError ());
+ Report.Error (578, Location, "Conditional not valid on '{0}' because its return type is not void", GetSignatureForError ());
return;
}
if (!DoDefine ())
return false;
+ if (RootContext.StdLib && (ReturnType == TypeManager.arg_iterator_type || ReturnType == TypeManager.typed_reference_type)) {
+ Error1599 (Location, ReturnType);
+ return false;
+ }
+
if (!CheckBase ())
return false;
if (!MethodData.Define (Parent))
return false;
+ if (ReturnType == TypeManager.void_type && ParameterTypes.Length == 0 &&
+ Name == "Finalize" && !(this is Destructor)) {
+ Report.Warning (465, 1, Location, "Introducing a 'Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
+ }
+
//
// Setup iterator if we are one
//
if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
Iterator iterator = new Iterator (
- Parent, Name, MemberType, ParameterTypes,
+ Parent, Name, MemberType,
ParameterInfo, ModFlags, block, Location);
if (!iterator.DefineIterator ())
(RootContext.MainClass == null ||
RootContext.MainClass == Parent.TypeBuilder.FullName)){
if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
+ IMethodData md = TypeManager.GetMethod (MethodBuilder);
+ md.SetMemberIsUsed ();
+
if (RootContext.EntryPoint == null) {
RootContext.EntryPoint = MethodBuilder;
RootContext.EntryPointLocation = Location;
MethodData = null;
}
- protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
+ public static void Error1599 (Location loc, Type t)
{
- MethodInfo mi = (MethodInfo) container.ParentCache.FindMemberToOverride (
+ Report.Error (1599, loc, "Method or delegate cannot return type '{0}'", TypeManager.CSharpName (t));
+ }
+
+ protected override MethodInfo FindOutBaseMethod (TypeContainer container, ref Type base_ret_type)
+ {
+ 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))
}
}
+ protected override bool CheckBase() {
+ if (!base.CheckBase ())
+ return false;
+
+ // TODO: Destructor should derive from MethodCore
+ if (base_method != null && (ModFlags & Modifiers.OVERRIDE) != 0 && Name == "Finalize" &&
+ base_method.DeclaringType == TypeManager.object_type && !(this is Destructor)) {
+ Report.Error (249, Location, "Do not override object.Finalize. Instead, provide a destructor");
+ return false;
+ }
+
+ return true;
+ }
+
public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
{
return new EmitContext (
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)
+ public bool Resolve (ConstructorBuilder caller_builder, Block block, EmitContext ec)
{
- Expression parent_constructor_group;
+ Expression base_constructor_group;
Type t;
+ bool error = false;
- ec.CurrentBlock = new ToplevelBlock (Block.Flags.Implicit, parameters, loc);
+ ec.CurrentBlock = block;
if (argument_list != null){
foreach (Argument a in argument_list){
} 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 (
- ec, t, ".ctor", MemberTypes.Constructor,
+ if (base_constructor_group == null){
+ error = true;
+ base_constructor_group = Expression.MemberLookup (
+ ec, t, null, t, ".ctor", MemberTypes.Constructor,
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
loc);
+ }
- if (parent_constructor_group != null)
- Report.Error (
- 112, loc, "`{0}.{1}' is inaccessible due to " +
- "its protection level", t.FullName, t.Name);
- else
- Report.Error (
- 1501, loc, "Can not find a constructor for " +
- "this argument list");
+ int errors = Report.Errors;
+ if (base_constructor_group != null)
+ base_constructor = (ConstructorInfo) Invocation.OverloadResolve (
+ ec, (MethodGroupExpr) base_constructor_group, argument_list,
+ false, loc);
+
+ if (base_constructor == null) {
+ if (errors == Report.Errors)
+ Report.Error (1501, loc, "Can not find a constructor for this argument list");
return false;
}
-
- parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (
- ec, (MethodGroupExpr) parent_constructor_group, argument_list,
- false, loc);
-
- if (parent_constructor == null){
- Report.Error (1501, loc,
- "Can not find a constructor for this argument list");
+
+ if (error) {
+ Report.Error (122, loc, "`{0}' is inaccessible due to its protection level",
+ TypeManager.CSharpSignature (base_constructor));
+ base_constructor = null;
return false;
}
- if (parent_constructor == caller_builder){
- Report.Error (516, String.Format ("Constructor `{0}' can not call itself", TypeManager.CSharpSignature (caller_builder)));
+ if (base_constructor == caller_builder){
+ Report.Error (516, loc, "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);
- }
- }
-
- /// <summary>
- /// Method search for base ctor. (We do not cache it).
- /// </summary>
- Constructor GetOverloadedConstructor (TypeContainer tc)
- {
- if (tc.InstanceConstructors == null)
- return null;
-
- foreach (Constructor c in tc.InstanceConstructors) {
- if (Arguments == null) {
- if (c.ParameterTypes.Length == 0)
- return c;
-
- continue;
- }
-
- bool ok = true;
-
- int count = c.ParameterInfo.Count;
- if ((count > 0) &&
- c.ParameterInfo.ParameterModifier (count - 1) == Parameter.Modifier.PARAMS) {
- for (int i = 0; i < count-1; i++)
- if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
- ok = false;
- break;
- }
- } else {
- if (c.ParameterTypes.Length != Arguments.Count)
- continue;
-
- for (int i = 0; i < Arguments.Count; ++i)
- if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
- ok = false;
- break;
- }
- }
-
- if (!ok)
- continue;
-
- return c;
+ Invocation.EmitCall (ec, true, false, ec.GetThis (loc), base_constructor, argument_list, loc);
}
-
- return null;
- }
-
- //TODO: implement caching when it will be necessary
- public virtual void CheckObsoleteAttribute (TypeContainer tc, Location loc)
- {
- Constructor ctor = GetOverloadedConstructor (tc);
- if (ctor == null)
- return;
-
- ObsoleteAttribute oa = ctor.GetObsoleteAttribute (tc);
- if (oa == null)
- return;
-
- AttributeTester.Report_ObsoleteMessage (oa, ctor.GetSignatureForError (), loc);
- }
- }
-
- public class ConstructorBaseInitializer : ConstructorInitializer {
- public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
- base (argument_list, pars, l)
- {
- }
-
- public override void CheckObsoleteAttribute(TypeContainer tc, Location loc) {
- if (parent_constructor == null)
- return;
-
- TypeContainer type_ds = TypeManager.LookupTypeContainer (tc.TypeBuilder.BaseType);
- if (type_ds == null) {
- ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (parent_constructor);
-
- if (oa != null)
- AttributeTester.Report_ObsoleteMessage (oa, TypeManager.CSharpSignature (parent_constructor), loc);
-
- return;
- }
-
- base.CheckObsoleteAttribute (type_ds, loc);
}
+ }
+ public class ConstructorBaseInitializer : ConstructorInitializer {
+ public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
+ base (argument_list, pars, l)
+ {
+ }
}
public class ConstructorThisInitializer : ConstructorInitializer {
return;
}
+ // If this is a non-static `struct' constructor and doesn't have any
+ // initializer, it must initialize all of the struct's fields.
+ if ((Parent.Kind == Kind.Struct) &&
+ ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
+ Block.AddThisVariable (Parent, Location);
+
+ if (block != null)
+ block.ResolveMeta (ec, ParameterInfo);
+
if ((ModFlags & Modifiers.STATIC) == 0){
if (Parent.Kind == Kind.Class && Initializer == null)
Initializer = new ConstructorBaseInitializer (
// `this' access
//
ec.IsStatic = true;
- if (Initializer != null && !Initializer.Resolve (ConstructorBuilder, ec))
+ if ((Initializer != null) &&
+ !Initializer.Resolve (ConstructorBuilder, block, ec))
return;
ec.IsStatic = false;
}
- Parameters.LabelParameters (ec, ConstructorBuilder, Location);
+ Parameters.LabelParameters (ec, ConstructorBuilder);
SourceMethod source = SourceMethod.Create (
Parent, ConstructorBuilder, block);
}
}
if (Initializer != null) {
- if (GetObsoleteAttribute (Parent) == null && Parent.GetObsoleteAttribute (Parent.Parent) == null)
- Initializer.CheckObsoleteAttribute (Parent, Location);
- else
+ if (GetObsoleteAttribute () != null || Parent.GetObsoleteAttribute (Parent) != null)
ec.TestObsoleteMethodUsage = false;
+
Initializer.Emit (ec);
}
if (OptAttributes != null)
OptAttributes.Emit (ec, this);
- // If this is a non-static `struct' constructor and doesn't have any
- // initializer, it must initialize all of the struct's fields.
- if ((Parent.Kind == Kind.Struct) &&
- ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
- Block.AddThisVariable (Parent, Location);
-
ec.EmitTopBlock (block, ParameterInfo, Location);
if (source != null)
}
// 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;
}
public ObsoleteAttribute GetObsoleteAttribute ()
{
- return null;
+ return GetObsoleteAttribute (Parent);
}
public bool IsExcluded(EmitContext ec)
string GetSignatureForError (TypeContainer tc);
bool IsExcluded (EmitContext ec);
bool IsClsCompliaceRequired (DeclSpace ds);
+ void SetMemberIsUsed ();
}
//
Type[] ParameterTypes = method.ParameterTypes;
if (container.Pending != null){
- if (member is Indexer)
+ if (member is Indexer) // TODO: test it, but it should work without this IF
implementing = container.Pending.IsInterfaceIndexer (
- member.InterfaceType, method.ReturnType, ParameterTypes);
+ member.InterfaceType, method.ReturnType, ParameterInfo);
else
implementing = container.Pending.IsInterfaceMethod (
- member.InterfaceType, name, method.ReturnType, ParameterTypes);
+ member.InterfaceType, name, method.ReturnType, ParameterInfo);
if (member.InterfaceType != null){
if (implementing == null){
- Report.Error (539, method.Location,
- "'{0}' in explicit interface declaration is not a member of interface", member.GetSignatureForError () );
+ if (member is PropertyBase) {
+ Report.Error (550, method.Location, "'{0}' is an accessor not found in interface member '{1}'",
+ method.GetSignatureForError (container), member.Name);
+
+ } else {
+ Report.Error (539, method.Location,
+ "'{0}' in explicit interface declaration is not a member of interface", member.GetSignatureForError () );
+ }
+ return false;
+ }
+ if (implementing.IsSpecialName && !((member is PropertyBase || member is EventProperty))) {
+ Report.SymbolRelatedToPreviousError (implementing);
+ Report.Error (683, method.Location, "'{0}' explicit method implementation cannot implement '{1}' because it is an accessor",
+ member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
return false;
}
method_name = member.InterfaceType.FullName + "." + name;
+ } else {
+ if (implementing != null && method is AbstractPropertyEventMethod && !implementing.IsSpecialName) {
+ Report.SymbolRelatedToPreviousError (implementing);
+ Report.Error (686, method.Location, "Accessor '{0}' cannot implement interface member '{1}' for type '{2}'. Use an explicit interface implementation",
+ method.GetSignatureForError (container), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
+ return false;
+ }
}
}
if (member is Indexer) {
container.Pending.ImplementIndexer (
member.InterfaceType, builder, method.ReturnType,
- ParameterTypes, member.IsExplicitImpl);
+ ParameterInfo, member.IsExplicitImpl);
} else
container.Pending.ImplementMethod (
member.InterfaceType, name, method.ReturnType,
- ParameterTypes, member.IsExplicitImpl);
+ ParameterInfo, member.IsExplicitImpl);
if (member.IsExplicitImpl)
container.TypeBuilder.DefineMethodOverride (
else
ec = method.CreateEmitContext (container, null);
- if (method.GetObsoleteAttribute () != null || container.GetObsoleteAttribute (container.Parent) != null)
+ if (method.GetObsoleteAttribute () != null || container.GetObsoleteAttribute (container) != null)
ec.TestObsoleteMethodUsage = false;
Location loc = method.Location;
OptAttributes.Emit (ec, kind);
if (member is MethodCore)
- ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc);
+ ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder);
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]);
}
}
}
}
+ // Should derive from MethodCore
public class Destructor : Method {
public Destructor (TypeContainer ds, Expression return_type, int mod,
// The "short" name of this property / indexer / event. This is the
// name without the explicit interface.
//
- public string ShortName;
+ public string ShortName {
+ get { return MemberName.Name; }
+ set {
+ SetMemberName (new MemberName (MemberName.Left, value));
+ }
+ }
//
// The type of this property / indexer / event
//
- public Type MemberType;
+ Type member_type;
+ public Type MemberType {
+ get {
+ if (member_type == null && Type != null) {
+ EmitContext ec = Parent.EmitContext;
+ bool old_unsafe = ec.InUnsafe;
+ ec.InUnsafe = InUnsafe;
+ Type = Type.ResolveAsTypeTerminal (ec, false);
+ ec.InUnsafe = old_unsafe;
- //
- // If true, this is an explicit interface implementation
- //
- public bool IsExplicitImpl = false;
+ member_type = Type == null ? null : Type.Type;
+ }
+ return member_type;
+ }
+ }
//
- // The name of the interface we are explicitly implementing
+ // Whether this is an interface member.
//
- public MemberName ExplicitInterfaceName = null;
+ public bool IsInterface;
//
- // Whether this is an interface member.
+ // If true, this is an explicit interface implementation
//
- public bool IsInterface;
+ public bool IsExplicitImpl;
//
- // If true, the interface type we are explicitly implementing
+ // The interface type we are explicitly implementing
//
public Type InterfaceType = null;
explicit_mod_flags = mod;
Type = type;
ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, loc);
-
- // Check for explicit interface implementation
- if (MemberName.Left != null) {
- ExplicitInterfaceName = MemberName.Left;
- ShortName = MemberName.Name;
- IsExplicitImpl = true;
- } else
- ShortName = Name;
+ IsExplicitImpl = (MemberName.Left != null);
}
protected virtual bool CheckBase ()
flags = Modifiers.MethodAttr (ModFlags);
}
- // Lookup Type, verify validity
- bool old_unsafe = ec.InUnsafe;
- ec.InUnsafe = InUnsafe;
- Type = Type.ResolveAsTypeTerminal (ec, false);
- ec.InUnsafe = old_unsafe;
-
- if (Type == null)
+ if (MemberType == null)
return false;
- MemberType = Type.Type;
-
if ((Parent.ModFlags & Modifiers.SEALED) != 0){
if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){
Report.Error (549, Location, "Virtual method can not be contained in sealed class");
return false;
if (IsExplicitImpl) {
- Expression expr = ExplicitInterfaceName.GetTypeExpression (Location);
+ Expression expr = MemberName.Left.GetTypeExpression (Location);
TypeExpr texpr = expr.ResolveAsTypeTerminal (ec, false);
if (texpr == null)
return false;
Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
return false;
}
-
-#if FIXME
- // Compute the full name that we need to export.
- if (InterfaceType.FullName != ExplicitInterfaceName) {
- ExplicitInterfaceName = InterfaceType.FullName;
- UpdateMemberName ();
- }
-#endif
if (!Parent.VerifyImplements (InterfaceType, ShortName, Name, Location))
return false;
return true;
}
- /// <summary>
- /// The name of the member can be changed during definition (see IndexerName attribute)
- /// </summary>
- protected virtual void UpdateMemberName ()
- {
- MemberName.Name = ShortName;
- }
-
public override string GetSignatureForError (TypeContainer tc)
{
return String.Concat (tc.Name, '.', base.GetSignatureForError (tc));
[Flags]
public enum Status : byte {
ASSIGNED = 1,
- 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;
else
e = new ArrayCreation (Type, "", (ArrayList)init, Location);
- ec.IsFieldInitializer = true;
- e = e.DoResolve (ec);
- ec.IsFieldInitializer = false;
+ EmitContext parent_ec = Parent.EmitContext;
+
+ bool old_is_static = parent_ec.IsStatic;
+ parent_ec.IsStatic = ec.IsStatic;
+ parent_ec.IsFieldInitializer = true;
+ e = e.DoResolve (parent_ec);
+ parent_ec.IsFieldInitializer = false;
+ parent_ec.IsStatic = old_is_static;
init_expr = e;
init_expr_initialized = true;
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));
}
if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
- Report.SymbolRelatedToPreviousError (conflict_symbol);
- Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
- }
+ Report.SymbolRelatedToPreviousError (conflict_symbol);
+ Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
+ }
return true;
}
return TypeManager.GetFullNameSignature (FieldBuilder);
}
+ protected virtual bool IsFieldClsCompliant {
+ get {
+ if (FieldBuilder == null)
+ return true;
+
+ return AttributeTester.IsClsCompliant (FieldBuilder.FieldType);
+ }
+ }
+
public override string[] ValidAttributeTargets {
get {
return attribute_targets;
if (!base.VerifyClsCompliance (ds))
return false;
- if (FieldBuilder == null) {
- return true;
- }
-
- if (!AttributeTester.IsClsCompliant (FieldBuilder.FieldType)) {
+ if (!IsFieldClsCompliant) {
Report.Error (3003, Location, "Type of '{0}' is not CLS-compliant", GetSignatureForError ());
}
return true;
public abstract class FieldMember: FieldBase
{
-
-
protected FieldMember (TypeContainer parent, Expression type, int mod,
int allowed_mod, MemberName name, object init, Attributes attrs, Location loc)
- : base (parent, type, mod, allowed_mod, name, init, attrs, loc)
+ : base (parent, type, mod, allowed_mod | Modifiers.ABSTRACT, name, init, attrs, loc)
{
+ if ((mod & Modifiers.ABSTRACT) != 0)
+ Report.Error (681, loc, "The modifier 'abstract' is not valid on fields. Try using a property instead");
}
public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
return;
}
}
+
+#if NET_2_0
+ if (a.Type == TypeManager.fixed_buffer_attr_type) {
+ Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
+ return;
+ }
+#endif
+
base.ApplyAttributeBuilder (a, cb);
}
if (ec == null)
throw new InternalErrorException ("FieldMember.Define called too early");
- bool old_unsafe = ec.InUnsafe;
- ec.InUnsafe = InUnsafe;
- TypeExpr texpr = Type.ResolveAsTypeTerminal (ec, false);
- if (texpr == null)
+ if (MemberType == null)
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 ())
return false;
public override void Emit ()
{
+ if (OptAttributes != null) {
+ EmitContext ec = new EmitContext (Parent, Location, null, FieldBuilder.FieldType, ModFlags);
+ OptAttributes.Emit (ec, this);
+ }
+
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 ());
}
}
}
+ interface IFixedBuffer
+ {
+ FieldInfo Element { get; }
+ Type ElementType { get; }
+ }
+
+ public class FixedFieldExternal: IFixedBuffer
+ {
+ FieldInfo element_field;
+
+ public FixedFieldExternal (FieldInfo fi)
+ {
+ element_field = fi.FieldType.GetField (FixedField.FixedElementName);
+ }
+
+ #region IFixedField Members
+
+ public FieldInfo Element {
+ get {
+ return element_field;
+ }
+ }
+
+ public Type ElementType {
+ get {
+ return element_field.FieldType;
+ }
+ }
+
+ #endregion
+ }
+
+ /// <summary>
+ /// Fixed buffer implementation
+ /// </summary>
+ public class FixedField: FieldMember, IFixedBuffer
+ {
+ public const string FixedElementName = "FixedElementField";
+ static int GlobalCounter = 0;
+ static object[] ctor_args = new object[] { (short)LayoutKind.Sequential };
+ static FieldInfo[] fi;
+
+ TypeBuilder fixed_buffer_type;
+ FieldBuilder element;
+ Expression size_expr;
+ int buffer_size;
+
+ const int AllowedModifiers =
+ Modifiers.NEW |
+ Modifiers.PUBLIC |
+ Modifiers.PROTECTED |
+ Modifiers.INTERNAL |
+ Modifiers.PRIVATE;
+
+ public FixedField (TypeContainer parent, Expression type, int mod, string name,
+ Expression size_expr, Attributes attrs, Location loc):
+ base (parent, type, mod, AllowedModifiers, new MemberName (name), null, attrs, loc)
+ {
+ if (RootContext.Version == LanguageVersion.ISO_1)
+ Report.FeatureIsNotStandardized (loc, "fixed sized buffers");
+
+ this.size_expr = size_expr;
+ }
+
+ public override bool Define()
+ {
+#if !NET_2_0
+ if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) != 0)
+ Report.Warning (-23, Location, "Only private or internal fixed sized buffers are supported by .NET 1.x");
+#endif
+
+ if (Parent.Kind != Kind.Struct) {
+ Report.Error (1642, Location, "Fixed buffer fields may only be members of structs");
+ return false;
+ }
+
+ if (!base.Define ())
+ return false;
+
+ if (!TypeManager.IsPrimitiveType (MemberType)) {
+ Report.Error (1663, Location, "Fixed sized buffer type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double");
+ return false;
+ }
+
+ Expression e = size_expr.Resolve (Parent.EmitContext);
+ if (e == null)
+ return false;
+
+ Constant c = e as Constant;
+ if (c == null) {
+ Report.Error (133, Location, "The expression being assigned to '{0}' must be constant", GetSignatureForError ());
+ return false;
+ }
+
+ IntConstant buffer_size_const = c.ToInt (Location);
+ if (buffer_size_const == null)
+ return false;
+
+ buffer_size = buffer_size_const.Value;
+
+ if (buffer_size <= 0) {
+ Report.Error (1665, Location, "Fixed sized buffer '{0}' must have a length greater than zero", GetSignatureForError ());
+ return false;
+ }
+
+ int type_size = Expression.GetTypeSize (MemberType);
+
+ if (buffer_size > int.MaxValue / type_size) {
+ Report.Error (1664, Location, "Fixed sized buffer of length '{0}' and type '{1}' exceeded 2^31 limit",
+ buffer_size.ToString (), TypeManager.CSharpName (MemberType));
+ return false;
+ }
+
+ buffer_size *= type_size;
+
+ // Define nested
+ string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++);
+
+ fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name,
+ TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, TypeManager.value_type);
+ element = fixed_buffer_type.DefineField (FixedElementName, MemberType, FieldAttributes.Public);
+ RootContext.RegisterCompilerGeneratedType (fixed_buffer_type);
+
+ FieldBuilder = Parent.TypeBuilder.DefineField (Name, fixed_buffer_type, Modifiers.FieldAttr (ModFlags));
+ TypeManager.RegisterFieldBase (FieldBuilder, this);
+
+ return true;
+ }
+
+ public override void Emit()
+ {
+ if (fi == null)
+ fi = new FieldInfo [] { TypeManager.struct_layout_attribute_type.GetField ("Size") };
+
+ object[] fi_val = new object[1];
+ fi_val [0] = buffer_size;
+
+ CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.struct_layout_attribute_ctor,
+ ctor_args, fi, fi_val);
+ fixed_buffer_type.SetCustomAttribute (cab);
+
+#if NET_2_0
+ cab = new CustomAttributeBuilder (TypeManager.fixed_buffer_attr_ctor, new object[] { MemberType, buffer_size } );
+ FieldBuilder.SetCustomAttribute (cab);
+#endif
+ base.Emit ();
+ }
+
+ protected override bool IsFieldClsCompliant {
+ get {
+ return false;
+ }
+ }
+
+ #region IFixedField Members
+
+ public FieldInfo Element {
+ get {
+ return element;
+ }
+ }
+
+ public Type ElementType {
+ get {
+ return MemberType;
+ }
+ }
+
+ #endregion
+ }
+
//
// The Field class is used to represents class/struct fields during parsing.
//
return true;
}
- public override void Emit ()
+ protected override bool VerifyClsCompliance (DeclSpace ds)
{
- if (OptAttributes != null) {
- EmitContext ec = new EmitContext (
- Parent, Location, null, FieldBuilder.FieldType,
- ModFlags);
- OptAttributes.Emit (ec, this);
+ if (!base.VerifyClsCompliance (ds))
+ return false;
+
+ if ((ModFlags & Modifiers.VOLATILE) != 0) {
+ Report.Warning (3026, 1, Location, "CLS-compliant field '{0}' cannot be volatile", GetSignatureForError ());
}
- base.Emit ();
+ return true;
}
}
static MemberName SetupName (string prefix, MemberBase member)
{
- MemberName name = member.MemberName.Clone ();
- name.Name = prefix + member.ShortName;
- return name;
+ return new MemberName (member.MemberName.Left, prefix + member.ShortName);
}
public void UpdateName (MemberBase member)
{
- MemberName.Name = prefix + member.ShortName;
+ SetMemberName (SetupName (prefix, member));
}
#region IMethodData Members
public virtual void Emit (TypeContainer container)
{
- method_data.Emit (container, this);
+ EmitMethod (container);
if (declarative_security != null) {
foreach (DictionaryEntry de in declarative_security) {
block = null;
}
+ protected virtual void EmitMethod (TypeContainer container)
+ {
+ method_data.Emit (container, this);
+ }
+
public override bool IsClsCompliaceRequired(DeclSpace ds)
{
return false;
return true;
}
+ public override bool IsUsed
+ {
+ get {
+ if (IsDummy)
+ return false;
+
+ return base.IsUsed;
+ }
+ }
+
public new Location Location {
get {
return base.Location;
{
if (a.Target == AttributeTargets.Parameter) {
if (param_attr == null)
- param_attr = new ImplicitParameter (method_data.MethodBuilder);
+ param_attr = new ImplicitParameter (method_data.MethodBuilder, method.Location);
param_attr.ApplyAttributeBuilder (a, cb);
return;
protected virtual InternalParameters GetParameterInfo (EmitContext ec)
{
Parameter [] parms = new Parameter [1];
- parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null);
- Parameters parameters = new Parameters (parms, null, method.Location);
+ parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null, method.Location);
+ Parameters parameters = new Parameters (parms, null);
+
+ 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");
: 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);
}
}
ModFlags = method.ModFlags;
flags = method.flags;
} else {
+ if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
+ Report.Error (442, Location, "{0}': abstract properties cannot have private accessors", GetSignatureForError (container));
+ }
+
CheckModifiers (container, ModFlags);
ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
+ ModFlags |= Modifiers.PROPERTY_CUSTOM;
flags = Modifiers.MethodAttr (ModFlags);
flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
}
}
+ public bool HasCustomAccessModifier
+ {
+ get {
+ return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
+ }
+ }
+
public override Type[] ParameterTypes {
get {
return TypeManager.NoTypes;
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;
+ }
}
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.ParentCache.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));
}
}
//
- // Check parent accessors access
+ // Check base class accessors access
//
get_accessor_access = set_accessor_access = 0;
if ((ModFlags & Modifiers.NEW) == 0) {
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 (parent_property));
+ GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
}
if (set_accessor != null) {
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 (parent_property));
+ GetSignatureForError (container), TypeManager.GetFullNameSignature (base_property));
}
}
return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
}
- protected override void UpdateMemberName ()
+ public override bool IsUsed
{
- base.UpdateMemberName ();
+ get {
+ if (IsExplicitImpl)
+ return true;
- Get.UpdateName (this);
- Set.UpdateName (this);
+ return Get.IsUsed | Set.IsUsed;
+ }
}
- protected override bool VerifyClsCompliance (DeclSpace ds)
+ protected override void SetMemberName (MemberName new_name)
{
- if (!base.VerifyClsCompliance (ds))
- return false;
+ base.SetMemberName (new_name);
- 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;
+ Get.UpdateName (this);
+ Set.UpdateName (this);
}
public override string[] ValidAttributeTargets {
if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
Iterator iterator = new Iterator (
Parent, "get", MemberType,
- TypeManager.NoTypes, Get.ParameterInfo,
+ Get.ParameterInfo,
ModFlags, Get.Block, Location);
if (!iterator.DefineIterator ())
public void SetUsed ()
{
- if (my_event != null)
- my_event.status = (FieldBase.Status.ASSIGNED | FieldBase.Status.USED);
+ if (my_event != null) {
+ my_event.status = FieldBase.Status.ASSIGNED;
+ my_event.SetMemberIsUsed ();
+ }
}
}
{
if (a.Target == AttributeTargets.Parameter) {
if (param_attr == null)
- param_attr = new ImplicitParameter (method_data.MethodBuilder);
+ param_attr = new ImplicitParameter (method_data.MethodBuilder, method.Location);
param_attr.ApplyAttributeBuilder (a, cb);
return;
}
- public override void Emit (TypeContainer tc)
+ protected override void EmitMethod (TypeContainer tc)
{
if (block != null) {
- base.Emit (tc);
+ base.EmitMethod (tc);
return;
}
+ if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
+ return;
+
ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
FieldInfo field_info = (FieldInfo)method.FieldBuilder;
ec.InUnsafe = InUnsafe;
Parameter [] parms = new Parameter [1];
- parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
- Parameters parameters = new Parameters (parms, null, Location);
+ parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null, Location);
+ Parameters parameters = new Parameters (parms, null);
Type [] types = parameters.GetParameterInfo (ec);
InternalParameters ip = new InternalParameters (types, parameters);
OptAttributes.Emit (ec, this);
}
- if (!IsInterface) {
- Add.Emit (Parent);
- Remove.Emit (Parent);
- }
+ Add.Emit (Parent);
+ Remove.Emit (Parent);
base.Emit ();
}
{
}
+ // TODO: one GetSignatureForError is enough (reuse Parent member)
+ public override string GetSignatureForError (TypeContainer tc)
+ {
+ string core = base.GetSignatureForError (tc);
+ return core.Replace (TypeContainer.DefaultIndexerName,
+ String.Format ("this[{0}]", TypeManager.CSharpName (ParameterTypes)));
+ }
+
public override Type[] ParameterTypes {
get {
return method.ParameterTypes;
fixed_parms.CopyTo (tmp, 0);
tmp [fixed_parms.Length] = new Parameter (
- method.Type, "value", Parameter.Modifier.NONE, null);
+ method.Type, "value", Parameter.Modifier.NONE, null, method.Location);
- Parameters set_formal_params = new Parameters (tmp, null, method.Location);
+ Parameters set_formal_params = new Parameters (tmp, null);
Type [] types = set_formal_params.GetParameterInfo (ec);
return new InternalParameters (types, set_formal_params);
if (IsExplicitImpl) {
Report.Error (415, indexer_attr.Location,
- "The 'IndexerName' attribute is valid only on an" +
+ "The 'IndexerName' attribute is valid only on an " +
"indexer that is not an explicit interface member declaration");
return false;
}
"The argument to the 'IndexerName' attribute must be a valid identifier");
return false;
}
-
- UpdateMemberName ();
}
}
if (InterfaceType != null) {
- string parent_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
- if (parent_IndexerName != Name)
- ShortName = parent_IndexerName;
- UpdateMemberName ();
+ string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
+ if (base_IndexerName != Name)
+ ShortName = base_IndexerName;
}
- 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 ())
{
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 {
}
// 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)