3 // class.cs: Class and Struct handlers
5 // Authors: Miguel de Icaza (miguel@gnu.org)
6 // Martin Baulig (martin@gnome.org)
8 // Licensed under the terms of the GNU GPL
10 // (C) 2001, 2002 Ximian, Inc (http://www.ximian.com)
15 using System.Collections;
16 using System.Reflection;
17 using System.Reflection.Emit;
18 using System.Runtime.CompilerServices;
19 using System.Diagnostics.SymbolStore;
21 namespace Mono.CSharp {
24 /// This is the base class for structs and classes.
26 public class TypeContainer : DeclSpace {
27 // Holds a list of classes and structures
30 // Holds the list of properties
33 // Holds the list of enumerations
36 // Holds the list of delegates
39 // Holds the list of constructors
40 ArrayList instance_constructors;
42 // Holds the list of fields
45 // Holds a list of fields that have initializers
46 ArrayList initialized_fields;
48 // Holds a list of static fields that have initializers
49 ArrayList initialized_static_fields;
51 // Holds the list of constants
57 // Holds order in which interfaces must be closed
58 ArrayList interface_order;
69 // Holds the operators
72 // The emit context for toplevel objects.
76 // Pointers to the default constructor and the default static constructor
78 Constructor default_constructor;
79 Constructor default_static_constructor;
82 // Whether we have seen a static constructor for this class or not
84 bool have_static_constructor = false;
87 // Whether we have at least one non-static field
89 bool have_nonstatic_fields = false;
92 // This one is computed after we can distinguish interfaces
93 // from classes from the arraylist `type_bases'
95 string base_class_name;
99 // Attributes for this type
100 protected Attributes attributes;
102 // Information in the case we are an attribute type
104 public AttributeTargets Targets = AttributeTargets.All;
105 public bool AllowMultiple = false;
106 public bool Inherited;
108 // The interfaces we implement.
112 // The indexer name for this class
114 public string IndexerName;
116 public TypeContainer (TypeContainer parent, string name, Location l)
117 : base (parent, name, l)
120 types = new ArrayList ();
127 base_class_name = null;
129 //Console.WriteLine ("New class " + name + " inside " + n);
132 public AdditionResult AddConstant (Const constant)
135 string name = constant.Name;
137 if ((res = IsValid (name)) != AdditionResult.Success)
140 if (constants == null)
141 constants = new ArrayList ();
143 constants.Add (constant);
144 DefineName (name, constant);
146 return AdditionResult.Success;
149 public AdditionResult AddEnum (Mono.CSharp.Enum e)
152 string name = e.Name;
154 if ((res = IsValid (name)) != AdditionResult.Success)
158 enums = new ArrayList ();
161 DefineName (name, e);
163 return AdditionResult.Success;
166 public AdditionResult AddClass (Class c)
169 string name = c.Name;
172 if ((res = IsValid (name)) != AdditionResult.Success)
175 DefineName (name, c);
178 return AdditionResult.Success;
181 public AdditionResult AddStruct (Struct s)
184 string name = s.Name;
186 if ((res = IsValid (name)) != AdditionResult.Success)
189 DefineName (name, s);
192 return AdditionResult.Success;
195 public AdditionResult AddDelegate (Delegate d)
198 string name = d.Name;
200 if ((res = IsValid (name)) != AdditionResult.Success)
203 if (delegates == null)
204 delegates = new ArrayList ();
206 DefineName (name, d);
209 return AdditionResult.Success;
212 public AdditionResult AddMethod (Method method)
214 string name = method.Name;
215 Object value = defined_names [name];
217 if (value != null && (!(value is Method)))
218 return AdditionResult.NameExists;
220 if (name == Basename)
221 return AdditionResult.EnclosingClash;
224 methods = new ArrayList ();
226 if (method.Name.IndexOf (".") != -1)
227 methods.Insert (0, method);
229 methods.Add (method);
232 DefineName (name, method);
234 return AdditionResult.Success;
237 public AdditionResult AddConstructor (Constructor c)
239 if (c.Name != Basename)
240 return AdditionResult.NotAConstructor;
242 bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
245 have_static_constructor = true;
246 if (default_static_constructor != null){
247 Console.WriteLine ("I have a static constructor already");
248 Console.WriteLine (" " + default_static_constructor);
249 return AdditionResult.MethodExists;
252 default_static_constructor = c;
255 if (default_constructor != null)
256 return AdditionResult.MethodExists;
257 default_constructor = c;
260 if (instance_constructors == null)
261 instance_constructors = new ArrayList ();
263 instance_constructors.Add (c);
266 return AdditionResult.Success;
269 public AdditionResult AddInterface (Interface iface)
272 string name = iface.Name;
274 if ((res = IsValid (name)) != AdditionResult.Success)
277 if (interfaces == null)
278 interfaces = new ArrayList ();
279 interfaces.Add (iface);
280 DefineName (name, iface);
282 return AdditionResult.Success;
285 public AdditionResult AddField (Field field)
288 string name = field.Name;
290 if ((res = IsValid (name)) != AdditionResult.Success)
294 fields = new ArrayList ();
298 if (field.HasInitializer){
299 if ((field.ModFlags & Modifiers.STATIC) != 0){
300 if (initialized_static_fields == null)
301 initialized_static_fields = new ArrayList ();
303 initialized_static_fields.Add (field);
306 // We have not seen a static constructor,
307 // but we will provide static initialization of fields
309 have_static_constructor = true;
311 if (initialized_fields == null)
312 initialized_fields = new ArrayList ();
314 initialized_fields.Add (field);
318 if ((field.ModFlags & Modifiers.STATIC) == 0)
319 have_nonstatic_fields = true;
321 DefineName (name, field);
322 return AdditionResult.Success;
325 public AdditionResult AddProperty (Property prop)
328 string name = prop.Name;
330 if ((res = IsValid (name)) != AdditionResult.Success)
333 if (properties == null)
334 properties = new ArrayList ();
336 if (prop.Name.IndexOf (".") != -1)
337 properties.Insert (0, prop);
339 properties.Add (prop);
340 DefineName (name, prop);
342 return AdditionResult.Success;
345 public AdditionResult AddEvent (Event e)
348 string name = e.Name;
350 if ((res = IsValid (name)) != AdditionResult.Success)
354 events = new ArrayList ();
357 DefineName (name, e);
359 return AdditionResult.Success;
362 public AdditionResult AddIndexer (Indexer i)
364 if (indexers == null)
365 indexers = new ArrayList ();
367 if (i.InterfaceType != null)
368 indexers.Insert (0, i);
372 return AdditionResult.Success;
375 public AdditionResult AddOperator (Operator op)
377 if (operators == null)
378 operators = new ArrayList ();
382 return AdditionResult.Success;
385 public void RegisterOrder (Interface iface)
387 if (interface_order == null)
388 interface_order = new ArrayList ();
390 interface_order.Add (iface);
393 public ArrayList Types {
399 public ArrayList Methods {
405 public ArrayList Constants {
411 public ArrayList Interfaces {
419 return base_class_name;
423 public ArrayList Bases {
433 public ArrayList Fields {
443 public ArrayList InstanceConstructors {
445 return instance_constructors;
449 public ArrayList Properties {
455 public ArrayList Events {
461 public ArrayList Enums {
467 public ArrayList Indexers {
473 public ArrayList Operators {
479 public ArrayList Delegates {
485 public Attributes OptAttributes {
491 public bool HaveStaticConstructor {
493 return have_static_constructor;
497 public virtual TypeAttributes TypeAttr {
499 return Modifiers.TypeAttr (ModFlags, this);
504 // Emits the instance field initializers
506 public bool EmitFieldInitializers (EmitContext ec)
509 ILGenerator ig = ec.ig;
510 Expression instance_expr;
513 fields = initialized_static_fields;
514 instance_expr = null;
516 fields = initialized_fields;
517 instance_expr = new This (Location.Null).Resolve (ec);
523 foreach (Field f in fields){
524 Expression e = f.GetInitializerExpression (ec);
528 Location l = f.Location;
529 FieldExpr fe = new FieldExpr (f.FieldBuilder, l);
530 fe.InstanceExpression = instance_expr;
531 Expression a = new Assign (fe, e, l);
537 if (a is ExpressionStatement)
538 ((ExpressionStatement) a).EmitStatement (ec);
540 throw new Exception ("Assign.Resolve returned a non ExpressionStatement");
548 // Defines the default constructors
550 void DefineDefaultConstructor (bool is_static)
555 c = new Constructor (Basename, Parameters.EmptyReadOnlyParameters,
556 new ConstructorBaseInitializer (
557 null, Parameters.EmptyReadOnlyParameters,
562 mods = Modifiers.STATIC;
568 c.Block = new Block (null);
572 public void ReportStructInitializedInstanceError ()
574 string n = TypeBuilder.FullName;
576 foreach (Field f in initialized_fields){
579 "`" + n + "." + f.Name + "': can not have " +
580 "instance field initializers in structs");
585 /// The pending methods that need to be implemented (interfaces or abstract methods)
587 public PendingImplementation Pending;
590 /// This function computes the Base class and also the
591 /// list of interfaces that the class or struct @c implements.
593 /// The return value is an array (might be null) of
594 /// interfaces implemented (as Types).
596 /// The @parent argument is set to the parent object or null
597 /// if this is `System.Object'.
599 Type [] GetClassBases (bool is_class, out Type parent, out bool error)
601 ArrayList bases = Bases;
610 parent = TypeManager.value_type;
614 if (RootContext.StdLib)
615 parent = TypeManager.object_type;
616 else if (Name != "System.Object")
617 parent = TypeManager.object_type;
620 // If we are compiling our runtime,
621 // and we are defining ValueType, then our
622 // parent is `System.Object'.
624 if (!RootContext.StdLib && Name == "System.ValueType")
625 parent = TypeManager.object_type;
632 // Bases should be null if there are no bases at all
637 Expression name = (Expression) bases [0];
638 name = ResolveTypeExpr (name, false, Location);
645 Type first = name.Type;
651 parent = TypeManager.object_type;
655 if (!AsAccessible (parent, ModFlags))
656 Report.Error (60, Location,
657 "Inconsistent accessibility: base class `" +
658 TypeManager.CSharpName (parent) + "' is less " +
659 "accessible than class `" +
666 Type [] ifaces = new Type [count-start];
668 for (i = start, j = 0; i < count; i++, j++){
669 Expression name = (Expression) bases [i];
670 Expression resolved = ResolveTypeExpr (name, false, Location);
671 bases [i] = resolved;
672 Type t = resolved.Type;
679 if (is_class == false && !t.IsInterface){
680 Report.Error (527, "In Struct `" + Name + "', type `"+
681 name +"' is not an interface");
690 detail = " (a class can not inherit from a struct/enum)";
692 Report.Error (509, "class `"+ Name +
693 "': Cannot inherit from sealed class `"+
694 bases [i]+"'"+detail);
701 Report.Error (527, "In Class `" + Name + "', type `"+
702 name+"' is not an interface");
708 for (int x = 0; x < j; x++) {
709 if (t == ifaces [x]) {
710 Report.Error (528, "`" + name + "' is already listed in interface list");
719 return TypeManager.ExpandInterfaces (ifaces);
723 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
725 public override TypeBuilder DefineType ()
731 if (TypeBuilder != null)
744 ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
746 ifaces = GetClassBases (is_class, out parent, out error);
751 if (is_class && parent != null){
752 if (parent == TypeManager.enum_type ||
753 (parent == TypeManager.value_type && RootContext.StdLib) ||
754 parent == TypeManager.delegate_type ||
755 parent == TypeManager.array_type){
757 644, Location, "`" + Name + "' cannot inherit from " +
758 "special class `" + TypeManager.CSharpName (parent) + "'");
763 if (!is_class && TypeManager.value_type == null)
764 throw new Exception ();
766 TypeAttributes type_attributes = TypeAttr;
768 // if (parent_builder is ModuleBuilder) {
770 ModuleBuilder builder = CodeGen.ModuleBuilder;
773 // Structs with no fields need to have a ".size 1"
777 if (!is_class && !have_nonstatic_fields)
778 TypeBuilder = builder.DefineType (Name,
781 PackingSize.Unspecified, 1);
784 // classes or structs with fields
786 TypeBuilder = builder.DefineType (Name,
791 TypeBuilder builder = Parent.TypeBuilder;
794 // Structs with no fields need to have a ".size 1"
797 if (!is_class && !have_nonstatic_fields)
798 TypeBuilder = builder.DefineNestedType (Basename,
801 PackingSize.Unspecified);
804 // classes or structs with fields
806 TypeBuilder = builder.DefineNestedType (Basename,
813 // add interfaces that were not added at type creation (weird API issue)
814 if (!is_class && !have_nonstatic_fields && (ifaces != null)) {
815 foreach (Type i in ifaces)
816 TypeBuilder.AddInterfaceImplementation (i);
820 // Finish the setup for the EmitContext
822 ec.ContainerType = TypeBuilder;
824 TypeManager.AddUserType (Name, TypeBuilder, this, ifaces);
826 if ((parent != null) &&
827 (parent == TypeManager.attribute_type ||
828 parent.IsSubclassOf (TypeManager.attribute_type))) {
829 RootContext.RegisterAttribute (this);
830 TypeManager.RegisterAttrType (TypeBuilder, this);
832 RootContext.RegisterOrder (this);
834 if (Interfaces != null) {
835 foreach (Interface iface in Interfaces)
840 foreach (TypeContainer tc in Types)
844 if (Delegates != null) {
845 foreach (Delegate d in Delegates)
850 foreach (Enum en in Enums)
860 /// Defines the MemberCore objects that are in the `list' Arraylist
862 /// The `defined_names' array contains a list of members defined in
865 static ArrayList remove_list = new ArrayList ();
866 void DefineMembers (ArrayList list, MemberInfo [] defined_names)
870 remove_list.Clear ();
872 foreach (MemberCore mc in list){
873 if (!mc.Define (this)){
874 remove_list.Add (mc);
878 if (defined_names == null)
881 idx = Array.BinarySearch (defined_names, mc.Name, mif_compare);
883 if (RootContext.WarningLevel >= 4){
884 if ((mc.ModFlags & Modifiers.NEW) != 0)
885 Warning_KewywordNewNotRequired (mc.Location, mc);
890 MemberInfo match = defined_names [idx];
892 if (match is PropertyInfo && ((mc.ModFlags & Modifiers.OVERRIDE) != 0))
896 // If we are both methods, let the method resolution emit warnings
898 if (match is MethodBase && mc is MethodCore)
901 if ((mc.ModFlags & Modifiers.NEW) == 0)
902 Warning_KeywordNewRequired (mc.Location, defined_names [idx]);
905 foreach (object o in remove_list)
908 remove_list.Clear ();
912 // Defines the indexers, and also verifies that the IndexerNameAttribute in the
913 // class is consisten. Either it is `Item' or it is the name defined by all the
914 // indexers with the `IndexerName' attribute.
916 // Turns out that the IndexerNameAttribute is applied to each indexer,
917 // but it is never emitted, instead a DefaultName attribute is attached
920 void DefineIndexers ()
922 string class_indexer_name = null;
924 foreach (Indexer i in Indexers){
929 name = i.IndexerName;
931 if (i.InterfaceType != null)
934 if (class_indexer_name == null){
935 class_indexer_name = name;
939 if (name == class_indexer_name)
943 668, "Two indexers have different names, " +
944 " you should use the same name for all your indexers");
946 if (class_indexer_name == null)
947 class_indexer_name = "Item";
948 IndexerName = class_indexer_name;
951 static void Report1530 (Location loc)
953 Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
957 /// Populates our TypeBuilder with fields and methods
959 public override bool DefineMembers (TypeContainer parent)
961 MemberInfo [] defined_names = null;
963 if (interface_order != null){
964 foreach (Interface iface in interface_order)
965 if ((iface.ModFlags & Modifiers.NEW) == 0)
966 iface.DefineMembers (this);
968 Report1530 (iface.Location);
971 if (RootContext.WarningLevel > 1){
975 // This code throws an exception in the comparer
976 // I guess the string is not an object?
978 ptype = TypeBuilder.BaseType;
980 defined_names = (MemberInfo []) FindMembers (
981 ptype, MemberTypes.All & ~MemberTypes.Constructor,
982 BindingFlags.Public | BindingFlags.Instance |
983 BindingFlags.Static, null, null);
985 Array.Sort (defined_names, mif_compare);
989 if (constants != null)
990 DefineMembers (constants, defined_names);
993 DefineMembers (fields, defined_names);
996 if (instance_constructors == null){
997 if (default_constructor == null)
998 DefineDefaultConstructor (false);
1001 if (initialized_static_fields != null &&
1002 default_static_constructor == null)
1003 DefineDefaultConstructor (true);
1006 if (this is Struct){
1008 // Structs can not have initialized instance
1011 if (initialized_static_fields != null &&
1012 default_static_constructor == null)
1013 DefineDefaultConstructor (true);
1015 if (initialized_fields != null)
1016 ReportStructInitializedInstanceError ();
1019 Pending = PendingImplementation.GetPendingImplementations (this);
1022 // Constructors are not in the defined_names array
1024 if (instance_constructors != null)
1025 DefineMembers (instance_constructors, null);
1027 if (default_static_constructor != null)
1028 default_static_constructor.Define (this);
1030 if (methods != null)
1031 DefineMembers (methods, defined_names);
1033 if (properties != null)
1034 DefineMembers (properties, defined_names);
1037 DefineMembers (events, defined_names);
1039 if (indexers != null) {
1042 IndexerName = "Item";
1044 if (operators != null)
1045 DefineMembers (operators, null);
1048 DefineMembers (enums, defined_names);
1050 if (delegates != null)
1051 DefineMembers (delegates, defined_names);
1056 public override bool Define (TypeContainer parent)
1058 if (interface_order != null){
1059 foreach (Interface iface in interface_order)
1060 if ((iface.ModFlags & Modifiers.NEW) == 0)
1061 iface.Define (this);
1068 /// This function is based by a delegate to the FindMembers routine
1070 static bool AlwaysAccept (MemberInfo m, object filterCriteria)
1076 /// This filter is used by FindMembers, and we just keep
1077 /// a global for the filter to `AlwaysAccept'
1079 static MemberFilter accepting_filter;
1083 /// A member comparission method based on name only
1085 static IComparer mif_compare;
1087 static TypeContainer ()
1089 accepting_filter = new MemberFilter (AlwaysAccept);
1090 mif_compare = new MemberInfoCompare ();
1094 /// This method returns the members of this type just like Type.FindMembers would
1095 /// Only, we need to use this for types which are _being_ defined because MS'
1096 /// implementation can't take care of that.
1099 // FIXME: return an empty static array instead of null, that cleans up
1100 // some code and is consistent with some coding conventions I just found
1104 // Notice that in various cases we check if our field is non-null,
1105 // something that would normally mean that there was a bug elsewhere.
1107 // The problem happens while we are defining p-invoke methods, as those
1108 // will trigger a FindMembers, but this happens before things are defined
1110 // Since the whole process is a no-op, it is fine to check for null here.
1112 internal override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1113 MemberFilter filter, object criteria)
1115 ArrayList members = new ArrayList ();
1116 bool priv = (bf & BindingFlags.NonPublic) != 0;
1119 filter = accepting_filter;
1121 if ((mt & MemberTypes.Field) != 0) {
1122 if (fields != null) {
1123 foreach (Field f in fields) {
1124 if ((f.ModFlags & Modifiers.PRIVATE) != 0)
1128 FieldBuilder fb = f.FieldBuilder;
1129 if (fb != null && filter (fb, criteria) == true)
1134 if (constants != null) {
1135 foreach (Const con in constants) {
1136 if ((con.ModFlags & Modifiers.PRIVATE) != 0)
1140 FieldBuilder fb = con.FieldBuilder;
1141 if (fb != null && filter (fb, criteria) == true)
1147 if ((mt & MemberTypes.Method) != 0) {
1148 if (methods != null) {
1149 foreach (Method m in methods) {
1150 if ((m.ModFlags & Modifiers.PRIVATE) != 0)
1154 MethodBuilder mb = m.MethodBuilder;
1156 if (mb != null && filter (mb, criteria) == true)
1161 if (operators != null){
1162 foreach (Operator o in operators) {
1163 if ((o.ModFlags & Modifiers.PRIVATE) != 0)
1167 MethodBuilder ob = o.OperatorMethodBuilder;
1168 if (ob != null && filter (ob, criteria) == true)
1173 if (properties != null){
1174 foreach (Property p in properties){
1175 if ((p.ModFlags & Modifiers.PRIVATE) != 0)
1182 if (b != null && filter (b, criteria) == true)
1186 if (b != null && filter (b, criteria) == true)
1192 if ((mt & MemberTypes.Event) != 0) {
1194 foreach (Event e in events) {
1195 if ((e.ModFlags & Modifiers.PRIVATE) != 0)
1199 MemberInfo eb = e.EventBuilder;
1200 if (eb != null && filter (eb, criteria) == true)
1201 members.Add (e.EventBuilder);
1205 if ((mt & MemberTypes.Property) != 0){
1206 if (properties != null)
1207 foreach (Property p in properties) {
1208 if ((p.ModFlags & Modifiers.PRIVATE) != 0)
1212 MemberInfo pb = p.PropertyBuilder;
1213 if (pb != null && filter (pb, criteria) == true) {
1214 members.Add (p.PropertyBuilder);
1218 if (indexers != null)
1219 foreach (Indexer ix in indexers) {
1220 if ((ix.ModFlags & Modifiers.PRIVATE) != 0)
1224 MemberInfo ib = ix.PropertyBuilder;
1225 if (ib != null && filter (ib, criteria) == true) {
1226 members.Add (ix.PropertyBuilder);
1231 if ((mt & MemberTypes.NestedType) != 0) {
1233 foreach (TypeContainer t in types) {
1234 TypeBuilder tb = t.TypeBuilder;
1236 if (tb != null && (filter (tb, criteria) == true))
1242 foreach (Enum en in enums){
1243 TypeBuilder tb = en.TypeBuilder;
1245 if (tb != null && (filter (tb, criteria) == true))
1250 if (delegates != null){
1251 foreach (Delegate d in delegates){
1252 TypeBuilder tb = d.TypeBuilder;
1254 if (tb != null && (filter (tb, criteria) == true))
1260 if ((mt & MemberTypes.Constructor) != 0){
1261 if (instance_constructors != null){
1262 foreach (Constructor c in instance_constructors){
1263 ConstructorBuilder cb = c.ConstructorBuilder;
1266 if (filter (cb, criteria) == true)
1271 if (default_static_constructor != null){
1272 ConstructorBuilder cb =
1273 default_static_constructor.ConstructorBuilder;
1276 if (filter (cb, criteria) == true)
1282 // Lookup members in parent if requested.
1284 if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
1285 MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
1286 members.AddRange (list);
1289 return new MemberList (members);
1294 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
1295 MemberFilter filter, object criteria)
1297 TypeContainer tc = TypeManager.LookupTypeContainer (t);
1300 return tc.FindMembers (mt, bf, filter, criteria);
1302 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
1306 // FindMethods will look for methods not only in the type `t', but in
1307 // any interfaces implemented by the type.
1309 public static MethodInfo [] FindMethods (Type t, BindingFlags bf,
1310 MemberFilter filter, object criteria)
1316 /// Emits the values for the constants
1318 public void EmitConstants ()
1320 if (constants != null)
1321 foreach (Const con in constants)
1322 con.EmitConstant (this);
1327 /// Emits the code, this step is performed after all
1328 /// the types, enumerations, constructors
1332 if (instance_constructors != null)
1333 foreach (Constructor c in instance_constructors)
1336 if (default_static_constructor != null)
1337 default_static_constructor.Emit (this);
1339 if (methods != null)
1340 foreach (Method m in methods)
1343 if (operators != null)
1344 foreach (Operator o in operators)
1347 if (properties != null)
1348 foreach (Property p in properties)
1351 if (indexers != null){
1352 foreach (Indexer ix in indexers)
1355 CustomAttributeBuilder cb = Interface.EmitDefaultMemberAttr (
1356 this, IndexerName, ModFlags, Location);
1357 TypeBuilder.SetCustomAttribute (cb);
1361 foreach (Field f in fields)
1364 if (events != null){
1365 foreach (Event e in Events)
1369 if (Pending != null)
1370 if (Pending.VerifyPendingMethods ())
1373 Attribute.ApplyAttributes (ec, TypeBuilder, this, OptAttributes, Location);
1376 // Check for internal or private fields that were never assigned
1378 if (fields != null && RootContext.WarningLevel >= 3) {
1379 foreach (Field f in fields) {
1380 if ((f.ModFlags & Modifiers.PUBLIC) != 0)
1385 169, f.Location, "Private field " +
1386 MakeName (f.Name) + " is never used");
1391 // Only report 649 on level 4
1393 if (RootContext.WarningLevel < 4)
1396 if ((f.status & Field.Status.ASSIGNED) != 0)
1401 "Field " + MakeName (f.Name) + " is never assigned " +
1402 " to and will always have its default value");
1406 // if (types != null)
1407 // foreach (TypeContainer tc in types)
1411 public override void CloseType ()
1416 TypeBuilder.CreateType ();
1418 } catch (TypeLoadException){
1420 // This is fine, the code still created the type
1422 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
1423 // Console.WriteLine (e.Message);
1425 Console.WriteLine ("In type: " + Name);
1430 foreach (Enum en in Enums)
1433 if (interface_order != null){
1434 foreach (Interface iface in interface_order)
1439 foreach (TypeContainer tc in Types)
1443 foreach (TypeContainer tc in Types)
1444 if (!(tc is Struct))
1448 if (Delegates != null)
1449 foreach (Delegate d in Delegates)
1453 public string MakeName (string n)
1455 return "`" + Name + "." + n + "'";
1458 public void Warning_KeywordNewRequired (Location l, MemberInfo mi)
1461 108, l, "The keyword new is required on " +
1462 MakeName (mi.Name) + " because it hides `" +
1463 mi.ReflectedType.Name + "." + mi.Name + "'");
1466 public void Warning_KewywordNewNotRequired (Location l, MemberCore mc)
1469 109, l, "The member " + MakeName (mc.Name) + " does not hide an " +
1470 "inherited member, the keyword new is not required");
1473 public static int CheckMember (string name, MemberInfo mi, int ModFlags)
1479 // Performs the validation on a Method's modifiers (properties have
1480 // the same properties).
1482 public bool MethodModifiersValid (int flags, string n, Location loc)
1484 const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
1485 const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
1486 const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
1488 string name = MakeName (n);
1491 // At most one of static, virtual or override
1493 if ((flags & Modifiers.STATIC) != 0){
1494 if ((flags & vao) != 0){
1496 112, loc, "static method " + name + "can not be marked " +
1497 "as virtual, abstract or override");
1502 if (this is Struct){
1503 if ((flags & va) != 0){
1504 Modifiers.Error_InvalidModifier (loc, "virtual or abstract");
1509 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
1512 " marked as override cannot be marked as new or virtual");
1517 // If the declaration includes the abstract modifier, then the
1518 // declaration does not include static, virtual or extern
1520 if ((flags & Modifiers.ABSTRACT) != 0){
1521 if ((flags & Modifiers.EXTERN) != 0){
1523 180, loc, name + " can not be both abstract and extern");
1527 if ((flags & Modifiers.VIRTUAL) != 0){
1529 503, loc, name + " can not be both abstract and virtual");
1533 if ((ModFlags & Modifiers.ABSTRACT) == 0){
1536 " is abstract but its container class is not");
1542 if ((flags & Modifiers.PRIVATE) != 0){
1543 if ((flags & vao) != 0){
1546 " virtual or abstract members can not be private");
1551 if ((flags & Modifiers.SEALED) != 0){
1552 if ((flags & Modifiers.OVERRIDE) == 0){
1555 " cannot be sealed because it is not an override");
1563 // Access level of a type.
1566 ProtectedInternal = 1,
1572 // Check whether `flags' denotes a more restricted access than `level'
1573 // and return the new level.
1574 static AccessLevel CheckAccessLevel (AccessLevel level, int flags)
1576 AccessLevel old_level = level;
1578 if ((flags & Modifiers.INTERNAL) != 0) {
1579 if ((flags & Modifiers.PROTECTED) != 0) {
1580 if ((int) level < (int) AccessLevel.ProtectedInternal)
1581 level = AccessLevel.ProtectedInternal;
1583 if ((int) level < (int) AccessLevel.Internal)
1584 level = AccessLevel.Internal;
1586 } else if ((flags & Modifiers.PROTECTED) != 0) {
1587 if ((int) level < (int) AccessLevel.Protected)
1588 level = AccessLevel.Protected;
1589 } else if ((flags & Modifiers.PRIVATE) != 0)
1590 level = AccessLevel.Private;
1595 // Return the access level for a new member which is defined in the current
1596 // TypeContainer with access modifiers `flags'.
1597 AccessLevel GetAccessLevel (int flags)
1599 if ((flags & Modifiers.PRIVATE) != 0)
1600 return AccessLevel.Private;
1603 if (!IsTopLevel && (Parent != null))
1604 level = Parent.GetAccessLevel (flags);
1606 level = AccessLevel.Public;
1608 return CheckAccessLevel (CheckAccessLevel (level, flags), ModFlags);
1611 // Return the access level for type `t', but don't give more access than `flags'.
1612 static AccessLevel GetAccessLevel (Type t, int flags)
1614 if (((flags & Modifiers.PRIVATE) != 0) || t.IsNestedPrivate)
1615 return AccessLevel.Private;
1618 if (TypeManager.IsBuiltinType (t))
1619 return AccessLevel.Public;
1620 else if ((t.DeclaringType != null) && (t != t.DeclaringType))
1621 level = GetAccessLevel (t.DeclaringType, flags);
1623 level = CheckAccessLevel (AccessLevel.Public, flags);
1626 if (t.IsNestedPublic)
1629 if (t.IsNestedAssembly || t.IsNotPublic) {
1630 if ((int) level < (int) AccessLevel.Internal)
1631 level = AccessLevel.Internal;
1634 if (t.IsNestedFamily) {
1635 if ((int) level < (int) AccessLevel.Protected)
1636 level = AccessLevel.Protected;
1639 if (t.IsNestedFamORAssem) {
1640 if ((int) level < (int) AccessLevel.ProtectedInternal)
1641 level = AccessLevel.ProtectedInternal;
1648 // Returns true if `parent' is as accessible as the flags `flags'
1649 // given for this member.
1651 public bool AsAccessible (Type parent, int flags)
1653 while (parent.IsArray || parent.IsPointer || parent.IsByRef)
1654 parent = parent.GetElementType ();
1656 AccessLevel level = GetAccessLevel (flags);
1657 AccessLevel level2 = GetAccessLevel (parent, flags);
1659 return (int) level >= (int) level2;
1662 Hashtable builder_and_args;
1664 public bool RegisterMethod (MethodBuilder mb, InternalParameters ip, Type [] args)
1666 if (builder_and_args == null)
1667 builder_and_args = new Hashtable ();
1672 /// Performs checks for an explicit interface implementation. First it
1673 /// checks whether the `interface_type' is a base inteface implementation.
1674 /// Then it checks whether `name' exists in the interface type.
1676 public bool VerifyImplements (Type interface_type, string full, string name, Location loc)
1680 if (ifaces != null){
1681 foreach (Type t in ifaces){
1682 if (t == interface_type){
1690 Report.Error (540, "`" + full + "': containing class does not implement interface `" + interface_type.FullName + "'");
1697 public static void Error_ExplicitInterfaceNotMemberInterface (Location loc, string name)
1699 Report.Error (539, loc, "Explicit implementation: `" + name + "' is not a member of the interface");
1702 public override MemberCache MemberCache {
1709 public class Class : TypeContainer {
1711 // Modifiers allowed in a class declaration
1713 public const int AllowedModifiers =
1716 Modifiers.PROTECTED |
1717 Modifiers.INTERNAL |
1719 Modifiers.ABSTRACT |
1723 public Class (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
1724 : base (parent, name, l)
1728 if (parent.Parent == null)
1729 accmods = Modifiers.INTERNAL;
1731 accmods = Modifiers.PRIVATE;
1733 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
1734 this.attributes = attrs;
1738 // FIXME: How do we deal with the user specifying a different
1741 public override TypeAttributes TypeAttr {
1743 return base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
1748 public class Struct : TypeContainer {
1750 // Modifiers allowed in a struct declaration
1752 public const int AllowedModifiers =
1755 Modifiers.PROTECTED |
1756 Modifiers.INTERNAL |
1760 public Struct (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
1761 : base (parent, name, l)
1765 if (parent.Parent == null)
1766 accmods = Modifiers.INTERNAL;
1768 accmods = Modifiers.PRIVATE;
1770 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
1772 this.ModFlags |= Modifiers.SEALED;
1773 this.attributes = attrs;
1778 // FIXME: Allow the user to specify a different set of attributes
1779 // in some cases (Sealed for example is mandatory for a class,
1780 // but what SequentialLayout can be changed
1782 public override TypeAttributes TypeAttr {
1784 return base.TypeAttr |
1785 TypeAttributes.SequentialLayout |
1786 TypeAttributes.Sealed |
1787 TypeAttributes.BeforeFieldInit;
1792 public abstract class MethodCore : MemberBase {
1793 public readonly Parameters Parameters;
1797 // Parameters, cached for semantic analysis.
1799 protected InternalParameters parameter_info;
1800 protected Type [] parameter_types;
1802 public MethodCore (Expression type, int mod, int allowed_mod, string name,
1803 Attributes attrs, Parameters parameters, Location loc)
1804 : base (type, mod, allowed_mod, name, attrs, loc)
1806 Parameters = parameters;
1810 // Returns the System.Type array for the parameters of this method
1812 public Type [] ParameterTypes {
1814 return parameter_types;
1818 public InternalParameters ParameterInfo
1821 return parameter_info;
1825 public Block Block {
1835 protected virtual bool DoDefineParameters (TypeContainer parent)
1837 // Check if arguments were correct
1838 parameter_types = Parameters.GetParameterInfo (parent);
1839 if ((parameter_types == null) || !CheckParameters (parent, parameter_types))
1842 parameter_info = new InternalParameters (parent, Parameters);
1847 public CallingConventions GetCallingConvention (bool is_class)
1849 CallingConventions cc = 0;
1851 cc = Parameters.GetCallingConvention ();
1854 if ((ModFlags & Modifiers.STATIC) == 0)
1855 cc |= CallingConventions.HasThis;
1857 // FIXME: How is `ExplicitThis' used in C#?
1862 public void LabelParameters (EmitContext ec, Type [] parameters, MethodBase builder)
1865 // Define each type attribute (in/out/ref) and
1866 // the argument names.
1868 Parameter [] p = Parameters.FixedParameters;
1871 MethodBuilder mb = null;
1872 ConstructorBuilder cb = null;
1874 if (builder is MethodBuilder)
1875 mb = (MethodBuilder) builder;
1877 cb = (ConstructorBuilder) builder;
1880 for (i = 0; i < p.Length; i++) {
1881 ParameterBuilder pb;
1884 pb = cb.DefineParameter (
1885 i + 1, p [i].Attributes, p [i].Name);
1887 pb = mb.DefineParameter (
1888 i + 1, p [i].Attributes, p [i].Name);
1890 Attributes attr = p [i].OptAttributes;
1892 Attribute.ApplyAttributes (ec, pb, pb, attr, Location);
1896 if (Parameters.ArrayParameter != null){
1897 ParameterBuilder pb;
1898 Parameter array_param = Parameters.ArrayParameter;
1901 pb = cb.DefineParameter (
1902 i + 1, array_param.Attributes,
1905 pb = mb.DefineParameter (
1906 i + 1, array_param.Attributes,
1909 CustomAttributeBuilder a = new CustomAttributeBuilder (
1910 TypeManager.cons_param_array_attribute, new object [0]);
1912 pb.SetCustomAttribute (a);
1917 public class Method : MethodCore {
1918 public MethodBuilder MethodBuilder;
1919 public MethodData MethodData;
1922 /// Modifiers allowed in a class declaration
1924 const int AllowedModifiers =
1927 Modifiers.PROTECTED |
1928 Modifiers.INTERNAL |
1933 Modifiers.OVERRIDE |
1934 Modifiers.ABSTRACT |
1939 // return_type can be "null" for VOID values.
1941 public Method (Expression return_type, int mod, string name, Parameters parameters,
1942 Attributes attrs, Location l)
1943 : base (return_type, mod, AllowedModifiers, name, attrs, parameters, l)
1947 // Returns the `System.Type' for the ReturnType of this
1948 // function. Provides a nice cache. (used between semantic analysis
1949 // and actual code generation
1951 public Type GetReturnType (TypeContainer parent)
1956 // Whether this is an operator method.
1957 public bool IsOperator;
1959 void DuplicateEntryPoint (MethodInfo b, Location location)
1963 "Program `" + CodeGen.FileName +
1964 "' has more than one entry point defined: `" +
1965 TypeManager.CSharpSignature(b) + "'");
1968 void Report28 (MethodInfo b)
1970 if (RootContext.WarningLevel < 4)
1975 "`" + TypeManager.CSharpSignature(b) +
1976 "' has the wrong signature to be an entry point");
1979 public bool IsEntryPoint (MethodBuilder b, InternalParameters pinfo)
1981 if (b.ReturnType != TypeManager.void_type &&
1982 b.ReturnType != TypeManager.int32_type)
1985 if (pinfo.Count == 0)
1988 if (pinfo.Count > 1)
1991 Type t = pinfo.ParameterType(0);
1993 (t.GetArrayRank() == 1) &&
1994 (t.GetElementType() == TypeManager.string_type) &&
1995 (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
2002 // Checks our base implementation if any
2004 protected override bool CheckBase (TypeContainer parent)
2006 // Check whether arguments were correct.
2007 if (!DoDefineParameters (parent))
2010 MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
2014 mi_this = TypeContainer.FindMembers (
2015 parent.TypeBuilder, MemberTypes.Method,
2016 BindingFlags.NonPublic | BindingFlags.Public |
2017 BindingFlags.Static | BindingFlags.Instance |
2018 BindingFlags.DeclaredOnly,
2019 MethodSignature.method_signature_filter, ms);
2021 if (mi_this.Count > 0) {
2022 Report.Error (111, Location, "Class `" + parent.Name + "' " +
2023 "already defines a member called `" + Name + "' " +
2024 "with the same parameter types");
2030 // Verify if the parent has a type with the same name, and then
2031 // check whether we have to create a new slot for it or not.
2033 Type ptype = parent.TypeBuilder.BaseType;
2035 // ptype is only null for System.Object while compiling corlib.
2037 MemberList mi, mi_static, mi_instance;
2039 mi_static = TypeContainer.FindMembers (
2040 ptype, MemberTypes.Method,
2041 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static,
2042 MethodSignature.inheritable_method_signature_filter, ms);
2044 mi_instance = TypeContainer.FindMembers (
2045 ptype, MemberTypes.Method,
2046 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
2047 MethodSignature.inheritable_method_signature_filter,
2050 if (mi_instance.Count > 0){
2052 } else if (mi_static.Count > 0)
2057 if (mi != null && mi.Count > 0){
2058 parent_method = (MethodInfo) mi [0];
2059 string name = parent_method.DeclaringType.Name + "." +
2062 if (!CheckMethodAgainstBase (parent, flags, parent_method, name))
2065 if ((ModFlags & Modifiers.NEW) == 0) {
2066 Type parent_ret = TypeManager.TypeToCoreType (
2067 parent_method.ReturnType);
2069 if (parent_ret != MemberType) {
2071 508, parent.MakeName (Name) + ": cannot " +
2072 "change return type when overriding " +
2073 "inherited member " + name);
2078 if ((ModFlags & Modifiers.NEW) != 0)
2079 WarningNotHiding (parent);
2081 if ((ModFlags & Modifiers.OVERRIDE) != 0){
2082 Report.Error (115, Location,
2083 parent.MakeName (Name) +
2084 " no suitable methods found to override");
2087 } else if ((ModFlags & Modifiers.NEW) != 0)
2088 WarningNotHiding (parent);
2096 public override bool Define (TypeContainer parent)
2098 if (!DoDefine (parent))
2101 if (!CheckBase (parent))
2104 CallingConventions cc = GetCallingConvention (parent is Class);
2106 MethodData = new MethodData (this, null, MemberType, ParameterTypes,
2107 ParameterInfo, cc, OptAttributes,
2108 ModFlags, flags, true);
2110 if (!MethodData.Define (parent))
2113 MethodBuilder = MethodData.MethodBuilder;
2116 // This is used to track the Entry Point,
2118 if (Name == "Main" &&
2119 ((ModFlags & Modifiers.STATIC) != 0) &&
2120 (RootContext.MainClass == null ||
2121 RootContext.MainClass == parent.TypeBuilder.FullName)){
2122 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
2123 if (RootContext.EntryPoint == null) {
2124 RootContext.EntryPoint = MethodBuilder;
2125 RootContext.EntryPointLocation = Location;
2127 DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
2128 DuplicateEntryPoint (MethodBuilder, Location);
2131 Report28(MethodBuilder);
2140 public void Emit (TypeContainer parent)
2142 MethodData.Emit (parent, Block, this);
2146 public abstract class ConstructorInitializer {
2147 ArrayList argument_list;
2148 ConstructorInfo parent_constructor;
2149 Parameters parameters;
2152 public ConstructorInitializer (ArrayList argument_list, Parameters parameters,
2155 this.argument_list = argument_list;
2156 this.parameters = parameters;
2160 public ArrayList Arguments {
2162 return argument_list;
2166 public bool Resolve (EmitContext ec)
2168 Expression parent_constructor_group;
2171 ec.CurrentBlock = new Block (null, true, parameters);
2173 if (argument_list != null){
2174 foreach (Argument a in argument_list){
2175 if (!a.Resolve (ec, loc))
2180 ec.CurrentBlock = null;
2182 if (this is ConstructorBaseInitializer) {
2183 if (ec.ContainerType.BaseType == null)
2186 t = ec.ContainerType.BaseType;
2187 if (ec.ContainerType.IsValueType) {
2188 Report.Error (522, loc,
2189 "structs cannot call base class constructors");
2193 t = ec.ContainerType;
2195 parent_constructor_group = Expression.MemberLookup (
2197 MemberTypes.Constructor,
2198 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
2201 if (parent_constructor_group == null){
2202 Report.Error (1501, loc,
2203 "Can not find a constructor for this argument list");
2207 parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (ec,
2208 (MethodGroupExpr) parent_constructor_group, argument_list, loc);
2210 if (parent_constructor == null){
2211 Report.Error (1501, loc,
2212 "Can not find a constructor for this argument list");
2219 public void Emit (EmitContext ec)
2221 if (parent_constructor != null)
2222 ec.ig.Emit (OpCodes.Ldarg_0);
2223 if (argument_list != null)
2224 Invocation.EmitArguments (ec, null, argument_list);
2225 if (parent_constructor != null)
2226 ec.ig.Emit (OpCodes.Call, parent_constructor);
2230 public class ConstructorBaseInitializer : ConstructorInitializer {
2231 public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
2232 base (argument_list, pars, l)
2237 public class ConstructorThisInitializer : ConstructorInitializer {
2238 public ConstructorThisInitializer (ArrayList argument_list, Parameters pars, Location l) :
2239 base (argument_list, pars, l)
2244 public class Constructor : MethodCore {
2245 public ConstructorBuilder ConstructorBuilder;
2246 public ConstructorInitializer Initializer;
2247 new public Attributes OptAttributes;
2250 // Modifiers allowed for a constructor.
2252 const int AllowedModifiers =
2254 Modifiers.PROTECTED |
2255 Modifiers.INTERNAL |
2261 // The spec claims that static is not permitted, but
2262 // my very own code has static constructors.
2264 public Constructor (string name, Parameters args, ConstructorInitializer init, Location l)
2265 : base (null, 0, AllowedModifiers, name, null, args, l)
2271 // Returns true if this is a default constructor
2273 public bool IsDefault ()
2275 if ((ModFlags & Modifiers.STATIC) != 0)
2276 return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
2277 (Parameters.ArrayParameter == null ? true : Parameters.Empty);
2280 return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
2281 (Parameters.ArrayParameter == null ? true : Parameters.Empty) &&
2282 (Initializer is ConstructorBaseInitializer) &&
2283 (Initializer.Arguments == null);
2287 // Creates the ConstructorBuilder
2289 public override bool Define (TypeContainer parent)
2291 MethodAttributes ca = (MethodAttributes.RTSpecialName |
2292 MethodAttributes.SpecialName);
2294 // Check if arguments were correct.
2295 if (!DoDefineParameters (parent))
2298 if ((ModFlags & Modifiers.STATIC) != 0)
2299 ca |= MethodAttributes.Static;
2301 if (parent is Struct && ParameterTypes.Length == 0){
2304 "Structs can not contain explicit parameterless " +
2308 ca |= MethodAttributes.Public | MethodAttributes.HideBySig;
2311 ConstructorBuilder = parent.TypeBuilder.DefineConstructor (
2312 ca, GetCallingConvention (parent is Class), ParameterTypes);
2315 // HACK because System.Reflection.Emit is lame
2317 if (!TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes)) {
2320 "Class `" +parent.Name+ "' already contains a definition with the " +
2321 "same return value and parameter types for constructor `" + Name
2332 public void Emit (TypeContainer parent)
2334 ILGenerator ig = ConstructorBuilder.GetILGenerator ();
2335 EmitContext ec = new EmitContext (parent, Location, ig, null, ModFlags, true);
2337 if ((ModFlags & Modifiers.STATIC) == 0){
2338 if (parent is Class && Initializer == null)
2339 Initializer = new ConstructorBaseInitializer (
2340 null, Parameters.EmptyReadOnlyParameters, parent.Location);
2344 // Spec mandates that Initializers will not have
2348 if (Initializer != null && !Initializer.Resolve (ec))
2350 ec.IsStatic = false;
2353 LabelParameters (ec, ParameterTypes, ConstructorBuilder);
2356 // Classes can have base initializers and instance field initializers.
2358 if (parent is Class){
2359 if ((ModFlags & Modifiers.STATIC) == 0)
2360 parent.EmitFieldInitializers (ec);
2362 if (Initializer != null)
2363 Initializer.Emit (ec);
2365 if ((ModFlags & Modifiers.STATIC) != 0)
2366 parent.EmitFieldInitializers (ec);
2368 Attribute.ApplyAttributes (ec, ConstructorBuilder, this, OptAttributes, Location);
2370 // If this is a non-static `struct' constructor and doesn't have any
2371 // initializer, it must initialize all of the struct's fields.
2372 if ((parent is Struct) && ((ModFlags & Modifiers.STATIC) == 0) &&
2373 (Initializer == null))
2374 Block.AddThisVariable (parent, Location);
2376 ec.EmitTopBlock (Block, ParameterInfo, Location);
2380 public class MethodData {
2382 // The return type of this method
2384 public readonly Type ReturnType;
2385 public readonly Type[] ParameterTypes;
2386 public readonly InternalParameters ParameterInfo;
2387 public readonly CallingConventions CallingConventions;
2388 public readonly Attributes OptAttributes;
2389 public readonly Location Location;
2392 // Are we implementing an interface ?
2394 public bool IsImplementing = false;
2399 protected MemberBase member;
2400 protected int modifiers;
2401 protected MethodAttributes flags;
2402 protected bool is_method;
2403 protected string accessor_name;
2404 ArrayList conditionals;
2406 MethodBuilder builder = null;
2407 public MethodBuilder MethodBuilder {
2413 public MethodData (MemberBase member, string name, Type return_type,
2414 Type [] parameter_types, InternalParameters parameters,
2415 CallingConventions cc, Attributes opt_attrs,
2416 int modifiers, MethodAttributes flags, bool is_method)
2418 this.member = member;
2419 this.accessor_name = name;
2420 this.ReturnType = return_type;
2421 this.ParameterTypes = parameter_types;
2422 this.ParameterInfo = parameters;
2423 this.CallingConventions = cc;
2424 this.OptAttributes = opt_attrs;
2425 this.modifiers = modifiers;
2427 this.is_method = is_method;
2428 this.Location = member.Location;
2429 this.conditionals = new ArrayList ();
2435 Attribute dllimport_attribute = null;
2436 string obsolete = null;
2437 bool obsolete_error = false;
2439 public virtual bool ApplyAttributes (Attributes opt_attrs, bool is_method)
2441 if ((opt_attrs == null) || (opt_attrs.AttributeSections == null))
2444 foreach (AttributeSection asec in opt_attrs.AttributeSections) {
2445 if (asec.Attributes == null)
2448 foreach (Attribute a in asec.Attributes) {
2449 if (a.Name == "Conditional") {
2450 if (!ApplyConditionalAttribute (a))
2452 } else if (a.Name == "Obsolete") {
2453 if (!ApplyObsoleteAttribute (a))
2455 } else if (a.Name.IndexOf ("DllImport") != -1) {
2457 a.Type = TypeManager.dllimport_type;
2458 Attribute.Error_AttributeNotValidForElement (a, Location);
2461 if (!ApplyDllImportAttribute (a))
2471 // Applies the `DllImport' attribute to the method.
2473 protected virtual bool ApplyDllImportAttribute (Attribute a)
2475 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
2476 if ((modifiers & extern_static) != extern_static) {
2477 Report.Error (601, Location,
2478 "The DllImport attribute must be specified on a method " +
2479 "marked `static' and `extern'.");
2483 flags |= MethodAttributes.PinvokeImpl;
2484 dllimport_attribute = a;
2489 // Applies the `Obsolete' attribute to the method.
2491 protected virtual bool ApplyObsoleteAttribute (Attribute a)
2493 if (obsolete != null) {
2494 Report.Error (579, Location, "Duplicate `Obsolete' attribute");
2498 obsolete = a.Obsolete_GetObsoleteMessage (out obsolete_error);
2499 return obsolete != null;
2503 // Applies the `Conditional' attribute to the method.
2505 protected virtual bool ApplyConditionalAttribute (Attribute a)
2507 // The Conditional attribute is only valid on methods.
2509 Attribute.Error_AttributeNotValidForElement (a, Location);
2513 string condition = a.Conditional_GetConditionName ();
2515 if (condition == null)
2518 if (ReturnType != TypeManager.void_type) {
2519 Report.Error (578, Location,
2520 "Conditional not valid on `" + member.Name + "' " +
2521 "because its return type is not void");
2525 if ((modifiers & Modifiers.OVERRIDE) != 0) {
2526 Report.Error (243, Location,
2527 "Conditional not valid on `" + member.Name + "' " +
2528 "because it is an override method");
2532 if (member.IsExplicitImpl) {
2533 Report.Error (577, Location,
2534 "Conditional not valid on `" + member.Name + "' " +
2535 "because it is an explicit interface implementation");
2539 if (IsImplementing) {
2540 Report.Error (623, Location,
2541 "Conditional not valid on `" + member.Name + "' " +
2542 "because it is an interface method");
2546 conditionals.Add (condition);
2552 // Checks whether this method should be ignored due to its Conditional attributes.
2554 bool ShouldIgnore (Location loc)
2556 // When we're overriding a virtual method, we implicitly inherit the
2557 // Conditional attributes from our parent.
2558 if (member.ParentMethod != null) {
2559 TypeManager.MethodFlags flags = TypeManager.GetMethodFlags (
2560 member.ParentMethod, loc);
2562 if ((flags & TypeManager.MethodFlags.ShouldIgnore) != 0)
2566 foreach (string condition in conditionals)
2567 if (RootContext.AllDefines [condition] == null)
2574 // Returns the TypeManager.MethodFlags for this method.
2575 // This emits an error 619 / warning 618 if the method is obsolete.
2576 // In the former case, TypeManager.MethodFlags.IsObsoleteError is returned.
2578 public virtual TypeManager.MethodFlags GetMethodFlags (Location loc)
2580 TypeManager.MethodFlags flags = 0;
2582 if (obsolete != null) {
2583 if (obsolete_error) {
2584 Report.Error (619, loc, "Method `" + member.Name +
2585 "' is obsolete: `" + obsolete + "'");
2586 return TypeManager.MethodFlags.IsObsoleteError;
2588 Report.Warning (618, loc, "Method `" + member.Name +
2589 "' is obsolete: `" + obsolete + "'");
2591 flags |= TypeManager.MethodFlags.IsObsolete;
2594 if (ShouldIgnore (loc))
2595 flags |= TypeManager.MethodFlags.ShouldIgnore;
2600 public virtual bool Define (TypeContainer parent)
2602 MethodInfo implementing = null;
2603 string method_name, name, prefix;
2605 if (OptAttributes != null)
2606 if (!ApplyAttributes (OptAttributes, is_method))
2609 if (member.IsExplicitImpl)
2610 prefix = member.InterfaceType.FullName + ".";
2614 if (accessor_name != null)
2615 name = accessor_name + "_" + member.ShortName;
2617 name = member.ShortName;
2618 method_name = prefix + name;
2620 if (parent.Pending != null){
2621 if (member is Indexer)
2622 implementing = parent.Pending.IsInterfaceIndexer (
2623 member.InterfaceType, ReturnType, ParameterTypes);
2625 implementing = parent.Pending.IsInterfaceMethod (
2626 member.InterfaceType, name, ReturnType, ParameterTypes);
2628 if (member.InterfaceType != null && implementing == null){
2629 TypeContainer.Error_ExplicitInterfaceNotMemberInterface (
2636 // For implicit implementations, make sure we are public, for
2637 // explicit implementations, make sure we are private.
2639 if (implementing != null){
2641 // Setting null inside this block will trigger a more
2642 // verbose error reporting for missing interface implementations
2644 // The "candidate" function has been flagged already
2645 // but it wont get cleared
2647 if (!member.IsExplicitImpl){
2649 // We already catch different accessibility settings
2650 // so we just need to check that we are not private
2652 if ((modifiers & Modifiers.PRIVATE) != 0)
2653 implementing = null;
2656 // Static is not allowed
2658 if ((modifiers & Modifiers.STATIC) != 0)
2659 implementing = null;
2661 if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
2662 Modifiers.Error_InvalidModifier (Location, "public, virtual or abstract");
2663 implementing = null;
2669 // If implementing is still valid, set flags
2671 if (implementing != null){
2673 // When implementing interface methods, set NewSlot.
2675 if (implementing.DeclaringType.IsInterface)
2676 flags |= MethodAttributes.NewSlot;
2679 MethodAttributes.Virtual |
2680 MethodAttributes.HideBySig;
2682 // Get the method name from the explicit interface.
2683 if (member.InterfaceType != null) {
2684 name = implementing.Name;
2685 method_name = prefix + name;
2688 IsImplementing = true;
2692 // Create the MethodBuilder for the method
2694 if ((flags & MethodAttributes.PinvokeImpl) != 0) {
2695 if ((modifiers & Modifiers.STATIC) == 0) {
2696 Report.Error (601, Location,
2697 "The DllImport attribute must be specified on " +
2698 "a method marked 'static' and 'extern'.");
2702 EmitContext ec = new EmitContext (
2703 parent, Location, null, ReturnType, modifiers);
2705 builder = dllimport_attribute.DefinePInvokeMethod (
2706 ec, parent.TypeBuilder, method_name, flags,
2707 ReturnType, ParameterTypes);
2709 builder = parent.TypeBuilder.DefineMethod (
2710 method_name, flags, CallingConventions,
2711 ReturnType, ParameterTypes);
2713 if (builder == null)
2716 if (IsImplementing) {
2718 // clear the pending implemntation flag
2720 if (member is Indexer) {
2721 parent.Pending.ImplementIndexer (
2722 member.InterfaceType, builder, ReturnType,
2723 ParameterTypes, true);
2725 parent.Pending.ImplementMethod (
2726 member.InterfaceType, name, ReturnType,
2727 ParameterTypes, member.IsExplicitImpl);
2729 if (member.IsExplicitImpl)
2730 parent.TypeBuilder.DefineMethodOverride (
2731 builder, implementing);
2734 if (!TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes)) {
2735 Report.Error (111, Location,
2736 "Class `" + parent.Name +
2737 "' already contains a definition with the " +
2738 "same return value and parameter types as the " +
2739 "'get' method of property `" + member.Name + "'");
2743 TypeManager.AddMethod (builder, this);
2751 public virtual void Emit (TypeContainer parent, Block block, object kind)
2756 if ((flags & MethodAttributes.PinvokeImpl) == 0)
2757 ig = builder.GetILGenerator ();
2761 ec = new EmitContext (parent, Location, ig, ReturnType, modifiers);
2763 if (OptAttributes != null)
2764 Attribute.ApplyAttributes (ec, builder, kind, OptAttributes, Location);
2766 if (member is MethodCore)
2767 ((MethodCore) member).LabelParameters (ec, ParameterTypes, MethodBuilder);
2770 // abstract or extern methods have no bodies
2772 if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
2777 // abstract or extern methods have no bodies.
2779 if ((modifiers & Modifiers.ABSTRACT) != 0)
2781 500, Location, "Abstract method `" +
2782 TypeManager.CSharpSignature (builder) +
2783 "' can not have a body");
2785 if ((modifiers & Modifiers.EXTERN) != 0)
2787 179, Location, "External method `" +
2788 TypeManager.CSharpSignature (builder) +
2789 "' can not have a body");
2795 // Methods must have a body unless they're extern or abstract
2797 if (block == null) {
2799 501, Location, "Method `" +
2800 TypeManager.CSharpSignature (builder) +
2801 "' must declare a body since it is not marked " +
2802 "abstract or extern");
2807 // Handle destructors specially
2809 // FIXME: This code generates buggy code
2811 if (member.Name == "Finalize" && ReturnType == TypeManager.void_type)
2812 EmitDestructor (ec, block);
2814 ISymbolWriter sw = CodeGen.SymbolWriter;
2816 if ((sw != null) && !Location.IsNull (Location) &&
2817 !Location.IsNull (block.EndLocation)) {
2818 Location end = block.EndLocation;
2819 MethodToken token = MethodBuilder.GetToken ();
2820 sw.OpenMethod (new SymbolToken (token.Token));
2821 sw.SetMethodSourceRange (Location.SymbolDocument,
2826 ec.EmitTopBlock (block, ParameterInfo, Location);
2830 ec.EmitTopBlock (block, ParameterInfo, Location);
2834 void EmitDestructor (EmitContext ec, Block block)
2836 ILGenerator ig = ec.ig;
2838 Label finish = ig.DefineLabel ();
2839 bool old_in_try = ec.InTry;
2841 ig.BeginExceptionBlock ();
2843 ec.ReturnLabel = finish;
2844 ec.HasReturnLabel = true;
2845 ec.EmitTopBlock (block, null, Location);
2846 ec.InTry = old_in_try;
2848 // ig.MarkLabel (finish);
2849 bool old_in_finally = ec.InFinally;
2850 ec.InFinally = true;
2851 ig.BeginFinallyBlock ();
2853 if (ec.ContainerType.BaseType != null) {
2854 Expression member_lookup = Expression.MemberLookup (
2855 ec, ec.ContainerType.BaseType, "Finalize",
2856 MemberTypes.Method, Expression.AllBindingFlags, Location);
2858 if (member_lookup != null){
2859 MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
2861 ig.Emit (OpCodes.Ldarg_0);
2862 ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
2865 ec.InFinally = old_in_finally;
2867 ig.EndExceptionBlock ();
2868 //ig.MarkLabel (ec.ReturnLabel);
2869 ig.Emit (OpCodes.Ret);
2873 abstract public class MemberBase : MemberCore {
2874 public Expression Type;
2875 public readonly Attributes OptAttributes;
2877 protected MethodAttributes flags;
2880 // The "short" name of this property / indexer / event. This is the
2881 // name without the explicit interface.
2883 public string ShortName;
2886 // The type of this property / indexer / event
2888 public Type MemberType;
2891 // If true, this is an explicit interface implementation
2893 public bool IsExplicitImpl = false;
2896 // The name of the interface we are explicitly implementing
2898 public string ExplicitInterfaceName = null;
2901 // If true, the interface type we are explicitly implementing
2903 public Type InterfaceType = null;
2906 // The method we're overriding if this is an override method.
2908 protected MethodInfo parent_method = null;
2909 public MethodInfo ParentMethod {
2911 return parent_method;
2916 // The constructor is only exposed to our children
2918 protected MemberBase (Expression type, int mod, int allowed_mod, string name,
2919 Attributes attrs, Location loc)
2923 ModFlags = Modifiers.Check (allowed_mod, mod, Modifiers.PRIVATE, loc);
2924 OptAttributes = attrs;
2927 protected virtual bool CheckBase (TypeContainer parent)
2932 protected virtual bool CheckParameters (TypeContainer parent, Type [] parameters)
2936 foreach (Type partype in parameters){
2937 if (partype.IsPointer && !UnsafeOK (parent))
2940 if (parent.AsAccessible (partype, ModFlags))
2943 if (this is Indexer)
2944 Report.Error (55, Location,
2945 "Inconsistent accessibility: parameter type `" +
2946 TypeManager.CSharpName (partype) + "' is less " +
2947 "accessible than indexer `" + Name + "'");
2949 Report.Error (51, Location,
2950 "Inconsistent accessibility: parameter type `" +
2951 TypeManager.CSharpName (partype) + "' is less " +
2952 "accessible than method `" + Name + "'");
2959 protected virtual bool DoDefine (TypeContainer parent)
2964 if (!parent.MethodModifiersValid (ModFlags, Name, Location))
2967 flags = Modifiers.MethodAttr (ModFlags);
2969 // Lookup Type, verify validity
2970 MemberType = parent.ResolveType (Type, false, Location);
2971 if (MemberType == null)
2974 // verify accessibility
2975 if (!parent.AsAccessible (MemberType, ModFlags)) {
2976 if (this is Property)
2977 Report.Error (53, Location,
2978 "Inconsistent accessibility: property type `" +
2979 TypeManager.CSharpName (MemberType) + "' is less " +
2980 "accessible than property `" + Name + "'");
2981 else if (this is Indexer)
2982 Report.Error (54, Location,
2983 "Inconsistent accessibility: indexer return type `" +
2984 TypeManager.CSharpName (MemberType) + "' is less " +
2985 "accessible than indexer `" + Name + "'");
2986 else if (this is Method)
2987 Report.Error (50, Location,
2988 "Inconsistent accessibility: return type `" +
2989 TypeManager.CSharpName (MemberType) + "' is less " +
2990 "accessible than method `" + Name + "'");
2992 Report.Error (52, Location,
2993 "Inconsistent accessibility: field type `" +
2994 TypeManager.CSharpName (MemberType) + "' is less " +
2995 "accessible than field `" + Name + "'");
2999 if (MemberType.IsPointer && !UnsafeOK (parent))
3003 // Check for explicit interface implementation
3005 if ((ExplicitInterfaceName == null) && (Name.IndexOf (".") != -1)){
3006 int pos = Name.LastIndexOf (".");
3008 ExplicitInterfaceName = Name.Substring (0, pos);
3009 ShortName = Name.Substring (pos + 1);
3013 if (ExplicitInterfaceName != null) {
3014 InterfaceType = RootContext.LookupType (
3015 parent, ExplicitInterfaceName, false, Location);
3016 if (InterfaceType == null)
3019 // Compute the full name that we need to export.
3020 Name = InterfaceType.FullName + "." + ShortName;
3022 if (!parent.VerifyImplements (InterfaceType, ShortName, Name, Location))
3025 IsExplicitImpl = true;
3027 IsExplicitImpl = false;
3034 // Fields and Events both generate FieldBuilders, we use this to share
3035 // their common bits. This is also used to flag usage of the field
3037 abstract public class FieldBase : MemberBase {
3038 public FieldBuilder FieldBuilder;
3039 public Status status;
3042 public enum Status : byte { ASSIGNED = 1, USED = 2 }
3045 // The constructor is only exposed to our children
3047 protected FieldBase (Expression type, int mod, int allowed_mod, string name,
3048 object init, Attributes attrs, Location loc)
3049 : base (type, mod, allowed_mod, name, attrs, loc)
3055 // Whether this field has an initializer.
3057 public bool HasInitializer {
3059 return init != null;
3064 readonly Object init;
3065 Expression init_expr;
3066 bool init_expr_initialized = false;
3069 // Resolves and returns the field initializer.
3071 public Expression GetInitializerExpression (EmitContext ec)
3073 if (init_expr_initialized)
3077 if (init is Expression)
3078 e = (Expression) init;
3080 e = new ArrayCreation (Type, "", (ArrayList)init, Location);
3082 ec.IsFieldInitializer = true;
3083 e = e.DoResolve (ec);
3084 ec.IsFieldInitializer = false;
3087 init_expr_initialized = true;
3094 // The Field class is used to represents class/struct fields during parsing.
3096 public class Field : FieldBase {
3098 // Modifiers allowed in a class declaration
3100 const int AllowedModifiers =
3103 Modifiers.PROTECTED |
3104 Modifiers.INTERNAL |
3107 Modifiers.VOLATILE |
3111 public Field (Expression type, int mod, string name, Object expr_or_array_init,
3112 Attributes attrs, Location loc)
3113 : base (type, mod, AllowedModifiers, name, expr_or_array_init, attrs, loc)
3117 public override bool Define (TypeContainer parent)
3119 Type t = parent.ResolveType (Type, false, Location);
3124 if (!parent.AsAccessible (t, ModFlags)) {
3125 Report.Error (52, Location,
3126 "Inconsistent accessibility: field type `" +
3127 TypeManager.CSharpName (t) + "' is less " +
3128 "accessible than field `" + Name + "'");
3132 if (t.IsPointer && !UnsafeOK (parent))
3135 if (RootContext.WarningLevel > 1){
3136 Type ptype = parent.TypeBuilder.BaseType;
3138 // ptype is only null for System.Object while compiling corlib.
3140 TypeContainer.FindMembers (
3141 ptype, MemberTypes.Method,
3142 BindingFlags.Public |
3143 BindingFlags.Static | BindingFlags.Instance,
3144 System.Type.FilterName, Name);
3148 if ((ModFlags & Modifiers.VOLATILE) != 0){
3150 if (TypeManager.IsEnumType (t))
3151 t = TypeManager.EnumToUnderlying (t);
3153 if (!((t == TypeManager.bool_type) ||
3154 (t == TypeManager.sbyte_type) ||
3155 (t == TypeManager.byte_type) ||
3156 (t == TypeManager.short_type) ||
3157 (t == TypeManager.ushort_type) ||
3158 (t == TypeManager.int32_type) ||
3159 (t == TypeManager.uint32_type) ||
3160 (t == TypeManager.char_type) ||
3161 (t == TypeManager.float_type))){
3163 677, Location, parent.MakeName (Name) +
3164 " A volatile field can not be of type `" +
3165 TypeManager.CSharpName (t) + "'");
3171 FieldBuilder = parent.TypeBuilder.DefineField (
3172 Name, t, Modifiers.FieldAttr (ModFlags));
3174 TypeManager.RegisterFieldBase (FieldBuilder, this);
3178 public void Emit (TypeContainer tc)
3180 EmitContext ec = new EmitContext (tc, Location, null,
3181 FieldBuilder.FieldType, ModFlags);
3183 Attribute.ApplyAttributes (ec, FieldBuilder, this, OptAttributes, Location);
3188 // `set' and `get' accessors are represented with an Accessor.
3190 public class Accessor {
3192 // Null if the accessor is empty, or a Block if not
3195 public Attributes OptAttributes;
3197 public Accessor (Block b, Attributes attrs)
3200 OptAttributes = attrs;
3205 // Properties and Indexers both generate PropertyBuilders, we use this to share
3206 // their common bits.
3208 abstract public class PropertyBase : MethodCore {
3209 public Accessor Get, Set;
3210 public PropertyBuilder PropertyBuilder;
3211 public MethodBuilder GetBuilder, SetBuilder;
3212 public MethodData GetData, SetData;
3214 protected EmitContext ec;
3216 public PropertyBase (Expression type, string name, int mod_flags, int allowed_mod,
3217 Parameters parameters, Accessor get_block, Accessor set_block,
3218 Attributes attrs, Location loc)
3219 : base (type, mod_flags, allowed_mod, name, attrs, parameters, loc)
3225 protected override bool DoDefine (TypeContainer parent)
3227 if (!base.DoDefine (parent))
3230 ec = new EmitContext (parent, Location, null, MemberType, ModFlags);
3236 // Checks our base implementation if any
3238 protected override bool CheckBase (TypeContainer parent)
3240 // Check whether arguments were correct.
3241 if (!DoDefineParameters (parent))
3244 MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
3245 MemberList props_this;
3247 props_this = TypeContainer.FindMembers (
3248 parent.TypeBuilder, MemberTypes.Property,
3249 BindingFlags.NonPublic | BindingFlags.Public |
3250 BindingFlags.Static | BindingFlags.Instance |
3251 BindingFlags.DeclaredOnly,
3252 MethodSignature.method_signature_filter, ms);
3254 if (props_this.Count > 0) {
3255 Report.Error (111, Location, "Class `" + parent.Name + "' " +
3256 "already defines a member called `" + Name + "' " +
3257 "with the same parameter types");
3262 // Find properties with the same name on the base class
3265 MemberList props_static = TypeContainer.FindMembers (
3266 parent.TypeBuilder.BaseType, MemberTypes.Property,
3267 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static,
3268 MethodSignature.inheritable_property_signature_filter, ms);
3270 MemberList props_instance = TypeContainer.FindMembers (
3271 parent.TypeBuilder.BaseType, MemberTypes.Property,
3272 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
3273 MethodSignature.inheritable_property_signature_filter,
3277 // Find if we have anything
3279 if (props_static.Count > 0)
3280 props = props_static;
3281 else if (props_instance.Count > 0)
3282 props = props_instance;
3287 // If we have something on the base.
3288 if (props != null && props.Count > 0){
3289 PropertyInfo pi = (PropertyInfo) props [0];
3291 MethodInfo inherited_get = TypeManager.GetPropertyGetter (pi);
3292 MethodInfo inherited_set = TypeManager.GetPropertySetter (pi);
3294 MethodInfo reference = inherited_get == null ?
3295 inherited_set : inherited_get;
3297 if (reference != null) {
3298 string name = reference.DeclaringType.Name + "." + Name;
3300 if (!CheckMethodAgainstBase (parent, flags, reference, name))
3304 if (((ModFlags & Modifiers.NEW) == 0) && (pi.PropertyType != MemberType)) {
3305 Report.Error (508, parent.MakeName (Name) + ": cannot " +
3306 "change return type when overriding inherited " +
3307 "member `" + pi.DeclaringType + "." + pi.Name + "'");
3311 if ((ModFlags & Modifiers.NEW) != 0)
3312 WarningNotHiding (parent);
3314 if ((ModFlags & Modifiers.OVERRIDE) != 0){
3315 if (this is Indexer)
3316 Report.Error (115, Location,
3317 parent.MakeName (Name) +
3318 " no suitable indexers found to override");
3320 Report.Error (115, Location,
3321 parent.MakeName (Name) +
3322 " no suitable properties found to override");
3329 public void Emit (TypeContainer tc)
3332 // The PropertyBuilder can be null for explicit implementations, in that
3333 // case, we do not actually emit the ".property", so there is nowhere to
3334 // put the attribute
3336 if (PropertyBuilder != null)
3337 Attribute.ApplyAttributes (ec, PropertyBuilder, this, OptAttributes, Location);
3339 if (GetData != null)
3340 GetData.Emit (tc, Get.Block, Get);
3342 if (SetData != null)
3343 SetData.Emit (tc, Set.Block, Set);
3347 public class Property : PropertyBase {
3348 const int AllowedModifiers =
3351 Modifiers.PROTECTED |
3352 Modifiers.INTERNAL |
3356 Modifiers.OVERRIDE |
3357 Modifiers.ABSTRACT |
3362 public Property (Expression type, string name, int mod_flags,
3363 Accessor get_block, Accessor set_block,
3364 Attributes attrs, Location loc)
3365 : base (type, name, mod_flags, AllowedModifiers,
3366 Parameters.EmptyReadOnlyParameters,
3367 get_block, set_block, attrs, loc)
3371 public override bool Define (TypeContainer parent)
3373 if (!DoDefine (parent))
3376 if (!CheckBase (parent))
3379 flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
3382 Type [] parameters = TypeManager.NoTypes;
3384 InternalParameters ip = new InternalParameters (
3385 parent, Parameters.EmptyReadOnlyParameters);
3387 GetData = new MethodData (this, "get", MemberType,
3388 parameters, ip, CallingConventions.Standard,
3389 Get.OptAttributes, ModFlags, flags, false);
3391 if (!GetData.Define (parent))
3394 GetBuilder = GetData.MethodBuilder;
3398 Type [] parameters = new Type [1];
3399 parameters [0] = MemberType;
3401 Parameter [] parms = new Parameter [1];
3402 parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
3403 InternalParameters ip = new InternalParameters (
3404 parent, new Parameters (parms, null, Location));
3406 SetData = new MethodData (this, "set", TypeManager.void_type,
3407 parameters, ip, CallingConventions.Standard,
3408 Set.OptAttributes, ModFlags, flags, false);
3410 if (!SetData.Define (parent))
3413 SetBuilder = SetData.MethodBuilder;
3414 SetBuilder.DefineParameter (1, ParameterAttributes.None, "value");
3417 // FIXME - PropertyAttributes.HasDefault ?
3419 PropertyAttributes prop_attr =
3420 PropertyAttributes.RTSpecialName |
3421 PropertyAttributes.SpecialName;
3423 if (!IsExplicitImpl){
3424 PropertyBuilder = parent.TypeBuilder.DefineProperty (
3425 Name, prop_attr, MemberType, null);
3428 PropertyBuilder.SetGetMethod (GetBuilder);
3431 PropertyBuilder.SetSetMethod (SetBuilder);
3434 // HACK for the reasons exposed above
3436 if (!TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder)) {
3439 "Class `" + parent.Name +
3440 "' already contains a definition for the property `" +
3450 /// Gigantic workaround for lameness in SRE follows :
3451 /// This class derives from EventInfo and attempts to basically
3452 /// wrap around the EventBuilder so that FindMembers can quickly
3453 /// return this in it search for members
3455 public class MyEventBuilder : EventInfo {
3458 // We use this to "point" to our Builder which is
3459 // not really a MemberInfo
3461 EventBuilder MyBuilder;
3464 // We "catch" and wrap these methods
3466 MethodInfo raise, remove, add;
3468 EventAttributes attributes;
3469 Type declaring_type, reflected_type, event_type;
3472 public MyEventBuilder (TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
3474 MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
3476 // And now store the values in our own fields.
3478 declaring_type = type_builder;
3480 reflected_type = type_builder;
3482 attributes = event_attr;
3484 this.event_type = event_type;
3488 // Methods that you have to override. Note that you only need
3489 // to "implement" the variants that take the argument (those are
3490 // the "abstract" methods, the others (GetAddMethod()) are
3493 public override MethodInfo GetAddMethod (bool nonPublic)
3498 public override MethodInfo GetRemoveMethod (bool nonPublic)
3503 public override MethodInfo GetRaiseMethod (bool nonPublic)
3509 // These methods make "MyEventInfo" look like a Builder
3511 public void SetRaiseMethod (MethodBuilder raiseMethod)
3513 raise = raiseMethod;
3514 MyBuilder.SetRaiseMethod (raiseMethod);
3517 public void SetRemoveOnMethod (MethodBuilder removeMethod)
3519 remove = removeMethod;
3520 MyBuilder.SetRemoveOnMethod (removeMethod);
3523 public void SetAddOnMethod (MethodBuilder addMethod)
3526 MyBuilder.SetAddOnMethod (addMethod);
3529 public void SetCustomAttribute (CustomAttributeBuilder cb)
3531 MyBuilder.SetCustomAttribute (cb);
3534 public override object [] GetCustomAttributes (bool inherit)
3536 // FIXME : There's nothing which can be seemingly done here because
3537 // we have no way of getting at the custom attribute objects of the
3542 public override object [] GetCustomAttributes (Type t, bool inherit)
3544 // FIXME : Same here !
3548 public override bool IsDefined (Type t, bool b)
3553 public override EventAttributes Attributes {
3559 public override string Name {
3565 public override Type DeclaringType {
3567 return declaring_type;
3571 public override Type ReflectedType {
3573 return reflected_type;
3577 public Type EventType {
3584 public class Event : FieldBase {
3585 const int AllowedModifiers =
3588 Modifiers.PROTECTED |
3589 Modifiers.INTERNAL |
3594 Modifiers.OVERRIDE |
3598 public readonly Accessor Add;
3599 public readonly Accessor Remove;
3600 public MyEventBuilder EventBuilder;
3602 MethodBuilder AddBuilder, RemoveBuilder;
3603 MethodData AddData, RemoveData;
3605 public Event (Expression type, string name, Object init, int mod, Accessor add,
3606 Accessor remove, Attributes attrs, Location loc)
3607 : base (type, mod, AllowedModifiers, name, init, attrs, loc)
3613 public override bool Define (TypeContainer parent)
3615 EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
3617 if (!DoDefine (parent))
3620 if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
3621 Report.Error (66, Location, "'" + parent.Name + "." + Name +
3622 "' : event must be of a delegate type");
3626 Type [] parameter_types = new Type [1];
3627 parameter_types [0] = MemberType;
3629 Parameter [] parms = new Parameter [1];
3630 parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
3631 InternalParameters ip = new InternalParameters (
3632 parent, new Parameters (parms, null, Location));
3634 if (!CheckBase (parent))
3638 // Now define the accessors
3640 AddData = new MethodData (this, "add", TypeManager.void_type,
3641 parameter_types, ip, CallingConventions.Standard,
3642 (Add != null) ? Add.OptAttributes : null,
3643 ModFlags, flags, false);
3645 if (!AddData.Define (parent))
3648 AddBuilder = AddData.MethodBuilder;
3649 AddBuilder.DefineParameter (1, ParameterAttributes.None, "value");
3651 RemoveData = new MethodData (this, "remove", TypeManager.void_type,
3652 parameter_types, ip, CallingConventions.Standard,
3653 (Remove != null) ? Remove.OptAttributes : null,
3654 ModFlags, flags, false);
3656 if (!RemoveData.Define (parent))
3659 RemoveBuilder = RemoveData.MethodBuilder;
3660 RemoveBuilder.DefineParameter (1, ParameterAttributes.None, "value");
3662 if (!IsExplicitImpl){
3663 EventBuilder = new MyEventBuilder (
3664 parent.TypeBuilder, Name, e_attr, MemberType);
3666 if (Add == null && Remove == null) {
3667 FieldBuilder = parent.TypeBuilder.DefineField (
3668 Name, MemberType, FieldAttributes.FamANDAssem);
3669 TypeManager.RegisterPrivateFieldOfEvent (
3670 (EventInfo) EventBuilder, FieldBuilder);
3671 TypeManager.RegisterFieldBase (FieldBuilder, this);
3674 EventBuilder.SetAddOnMethod (AddBuilder);
3675 EventBuilder.SetRemoveOnMethod (RemoveBuilder);
3677 if (!TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder)) {
3678 Report.Error (111, Location,
3679 "Class `" + parent.Name +
3680 "' already contains a definition for the event `" +
3689 void EmitDefaultMethod (EmitContext ec, bool is_add)
3691 ILGenerator ig = ec.ig;
3692 MethodInfo method = null;
3695 method = TypeManager.delegate_combine_delegate_delegate;
3697 method = TypeManager.delegate_remove_delegate_delegate;
3699 if ((ModFlags & Modifiers.STATIC) != 0) {
3700 ig.Emit (OpCodes.Ldsfld, (FieldInfo) FieldBuilder);
3701 ig.Emit (OpCodes.Ldarg_0);
3702 ig.Emit (OpCodes.Call, method);
3703 ig.Emit (OpCodes.Castclass, MemberType);
3704 ig.Emit (OpCodes.Stsfld, (FieldInfo) FieldBuilder);
3706 ig.Emit (OpCodes.Ldarg_0);
3707 ig.Emit (OpCodes.Ldarg_0);
3708 ig.Emit (OpCodes.Ldfld, (FieldInfo) FieldBuilder);
3709 ig.Emit (OpCodes.Ldarg_1);
3710 ig.Emit (OpCodes.Call, method);
3711 ig.Emit (OpCodes.Castclass, MemberType);
3712 ig.Emit (OpCodes.Stfld, (FieldInfo) FieldBuilder);
3714 ig.Emit (OpCodes.Ret);
3717 public void Emit (TypeContainer tc)
3721 ec = new EmitContext (tc, Location, null, MemberType, ModFlags);
3722 Attribute.ApplyAttributes (ec, EventBuilder, this, OptAttributes, Location);
3725 AddData.Emit (tc, Add.Block, Add);
3727 ILGenerator ig = AddData.MethodBuilder.GetILGenerator ();
3728 ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
3729 EmitDefaultMethod (ec, true);
3733 RemoveData.Emit (tc, Remove.Block, Remove);
3735 ILGenerator ig = RemoveData.MethodBuilder.GetILGenerator ();
3736 ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
3737 EmitDefaultMethod (ec, false);
3744 // FIXME: This does not handle:
3746 // int INTERFACENAME [ args ]
3751 // int this [ args ]
3753 public class Indexer : PropertyBase {
3755 const int AllowedModifiers =
3758 Modifiers.PROTECTED |
3759 Modifiers.INTERNAL |
3763 Modifiers.OVERRIDE |
3768 public string IndexerName;
3769 public string InterfaceIndexerName;
3772 // Are we implementing an interface ?
3774 bool IsImplementing = false;
3776 public Indexer (Expression type, string int_type, int flags, Parameters parameters,
3777 Accessor get_block, Accessor set_block, Attributes attrs, Location loc)
3778 : base (type, "", flags, AllowedModifiers, parameters, get_block, set_block,
3781 ExplicitInterfaceName = int_type;
3784 public override bool Define (TypeContainer parent)
3786 PropertyAttributes prop_attr =
3787 PropertyAttributes.RTSpecialName |
3788 PropertyAttributes.SpecialName;
3790 if (!DoDefine (parent))
3793 IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
3794 if (IndexerName == null)
3795 IndexerName = "Item";
3796 else if (IsExplicitImpl)
3797 Report.Error (592, Location,
3798 "Attribute 'IndexerName' is not valid on this declaration " +
3799 "type. It is valid on `property' declarations only.");
3801 ShortName = IndexerName;
3802 if (IsExplicitImpl) {
3803 InterfaceIndexerName = TypeManager.IndexerPropertyName (InterfaceType);
3804 Name = InterfaceType.FullName + "." + IndexerName;
3806 InterfaceIndexerName = IndexerName;
3810 if (!CheckBase (parent))
3814 InternalParameters ip = new InternalParameters (parent, Parameters);
3816 GetData = new MethodData (this, "get", MemberType,
3817 ParameterTypes, ip, CallingConventions.Standard,
3818 Get.OptAttributes, ModFlags, flags, false);
3820 if (!GetData.Define (parent))
3823 GetBuilder = GetData.MethodBuilder;
3827 int top = ParameterTypes.Length;
3828 Type [] set_pars = new Type [top + 1];
3829 ParameterTypes.CopyTo (set_pars, 0);
3830 set_pars [top] = MemberType;
3832 Parameter [] fixed_parms = Parameters.FixedParameters;
3834 if (fixed_parms == null){
3835 throw new Exception ("We currently do not support only array arguments in an indexer");
3836 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
3837 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
3839 // Here is the problem: the `value' parameter has
3840 // to come *after* the array parameter in the declaration
3842 // X (object [] x, Type value)
3845 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
3846 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
3850 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
3853 fixed_parms.CopyTo (tmp, 0);
3854 tmp [fixed_parms.Length] = new Parameter (
3855 Type, "value", Parameter.Modifier.NONE, null);
3857 Parameters set_formal_params = new Parameters (tmp, null, Location);
3859 InternalParameters ip = new InternalParameters (parent, set_formal_params);
3861 SetData = new MethodData (this, "set", TypeManager.void_type,
3862 set_pars, ip, CallingConventions.Standard,
3863 Set.OptAttributes, ModFlags, flags, false);
3865 if (!SetData.Define (parent))
3868 SetBuilder = SetData.MethodBuilder;
3872 // Now name the parameters
3874 Parameter [] p = Parameters.FixedParameters;
3878 for (i = 0; i < p.Length; ++i) {
3880 GetBuilder.DefineParameter (
3881 i + 1, p [i].Attributes, p [i].Name);
3884 SetBuilder.DefineParameter (
3885 i + 1, p [i].Attributes, p [i].Name);
3889 SetBuilder.DefineParameter (
3890 i + 1, ParameterAttributes.None, "value");
3892 if (i != ParameterTypes.Length) {
3893 Parameter array_param = Parameters.ArrayParameter;
3894 SetBuilder.DefineParameter (
3895 i + 1, array_param.Attributes, array_param.Name);
3899 if (GetData != null)
3900 IsImplementing = GetData.IsImplementing;
3901 else if (SetData != null)
3902 IsImplementing = SetData.IsImplementing;
3905 // Define the PropertyBuilder if one of the following conditions are met:
3906 // a) we're not implementing an interface indexer.
3907 // b) the indexer has a different IndexerName and this is no
3908 // explicit interface implementation.
3910 if (!IsExplicitImpl) {
3911 PropertyBuilder = parent.TypeBuilder.DefineProperty (
3912 IndexerName, prop_attr, MemberType, ParameterTypes);
3914 if (GetData != null)
3915 PropertyBuilder.SetGetMethod (GetBuilder);
3917 if (SetData != null)
3918 PropertyBuilder.SetSetMethod (SetBuilder);
3920 TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
3928 public class Operator : MemberCore {
3930 const int AllowedModifiers =
3936 const int RequiredModifiers =
3940 public enum OpType : byte {
3950 // Unary and Binary operators
3973 // Implicit and Explicit
3978 public readonly OpType OperatorType;
3979 public readonly Expression ReturnType;
3980 public readonly Expression FirstArgType, SecondArgType;
3981 public readonly string FirstArgName, SecondArgName;
3982 public readonly Block Block;
3983 public Attributes OptAttributes;
3984 public MethodBuilder OperatorMethodBuilder;
3986 public string MethodName;
3987 public Method OperatorMethod;
3989 public Operator (OpType type, Expression ret_type, int flags,
3990 Expression arg1type, string arg1name,
3991 Expression arg2type, string arg2name,
3992 Block block, Attributes attrs, Location loc)
3995 OperatorType = type;
3996 ReturnType = ret_type;
3997 ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PUBLIC, loc);
3998 FirstArgType = arg1type;
3999 FirstArgName = arg1name;
4000 SecondArgType = arg2type;
4001 SecondArgName = arg2name;
4003 OptAttributes = attrs;
4006 string Prototype (TypeContainer parent)
4008 return parent.Name + ".operator " + OperatorType + " (" + FirstArgType + "," +
4009 SecondArgType + ")";
4012 public override bool Define (TypeContainer parent)
4015 MethodName = "op_" + OperatorType;
4017 if (SecondArgType != null)
4020 Parameter [] param_list = new Parameter [length];
4022 if ((ModFlags & RequiredModifiers) != RequiredModifiers){
4025 "User defined operators `" +
4026 Prototype (parent) +
4027 "' must be declared static and public");
4031 param_list[0] = new Parameter (FirstArgType, FirstArgName,
4032 Parameter.Modifier.NONE, null);
4033 if (SecondArgType != null)
4034 param_list[1] = new Parameter (SecondArgType, SecondArgName,
4035 Parameter.Modifier.NONE, null);
4037 OperatorMethod = new Method (ReturnType, ModFlags, MethodName,
4038 new Parameters (param_list, null, Location),
4039 OptAttributes, Mono.CSharp.Location.Null);
4041 OperatorMethod.IsOperator = true;
4042 OperatorMethod.Define (parent);
4044 if (OperatorMethod.MethodBuilder == null)
4047 OperatorMethodBuilder = OperatorMethod.MethodBuilder;
4049 Type [] param_types = OperatorMethod.ParameterTypes;
4050 Type declaring_type = OperatorMethodBuilder.DeclaringType;
4051 Type return_type = OperatorMethod.GetReturnType (parent);
4052 Type first_arg_type = param_types [0];
4054 // Rules for conversion operators
4056 if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
4057 if (first_arg_type == return_type && first_arg_type == declaring_type){
4060 "User-defined conversion cannot take an object of the " +
4061 "enclosing type and convert to an object of the enclosing" +
4066 if (first_arg_type != declaring_type && return_type != declaring_type){
4069 "User-defined conversion must convert to or from the " +
4074 if (first_arg_type == TypeManager.object_type ||
4075 return_type == TypeManager.object_type){
4078 "User-defined conversion cannot convert to or from " +
4083 if (first_arg_type.IsInterface || return_type.IsInterface){
4086 "User-defined conversion cannot convert to or from an " +
4091 if (first_arg_type.IsSubclassOf (return_type) ||
4092 return_type.IsSubclassOf (first_arg_type)){
4095 "User-defined conversion cannot convert between types " +
4096 "that derive from each other");
4099 } else if (SecondArgType == null) {
4100 // Checks for Unary operators
4102 if (first_arg_type != declaring_type){
4105 "The parameter of a unary operator must be the " +
4110 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
4111 if (return_type != declaring_type){
4114 "The parameter and return type for ++ and -- " +
4115 "must be the containing type");
4121 if (OperatorType == OpType.True || OperatorType == OpType.False) {
4122 if (return_type != TypeManager.bool_type){
4125 "The return type of operator True or False " +
4132 // Checks for Binary operators
4134 if (first_arg_type != declaring_type &&
4135 param_types [1] != declaring_type){
4138 "One of the parameters of a binary operator must " +
4139 "be the containing type");
4147 public void Emit (TypeContainer parent)
4149 EmitContext ec = new EmitContext (parent, Location, null, null, ModFlags);
4150 Attribute.ApplyAttributes (ec, OperatorMethodBuilder, this, OptAttributes, Location);
4153 // abstract or extern methods have no bodies
4155 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
4158 OperatorMethod.Block = Block;
4159 OperatorMethod.Emit (parent);
4164 // This is used to compare method signatures
4166 struct MethodSignature {
4168 public Type RetType;
4169 public Type [] Parameters;
4172 /// This delegate is used to extract methods which have the
4173 /// same signature as the argument
4175 public static MemberFilter method_signature_filter;
4178 /// This delegate is used to extract inheritable methods which
4179 /// have the same signature as the argument. By inheritable,
4180 /// this means that we have permissions to override the method
4181 /// from the current assembly and class
4183 public static MemberFilter inheritable_method_signature_filter;
4186 /// This delegate is used to extract inheritable methods which
4187 /// have the same signature as the argument. By inheritable,
4188 /// this means that we have permissions to override the method
4189 /// from the current assembly and class
4191 public static MemberFilter inheritable_property_signature_filter;
4193 static MethodSignature ()
4195 method_signature_filter = new MemberFilter (MemberSignatureCompare);
4196 inheritable_method_signature_filter = new MemberFilter (
4197 InheritableMemberSignatureCompare);
4198 inheritable_property_signature_filter = new MemberFilter (
4199 InheritablePropertySignatureCompare);
4202 public MethodSignature (string name, Type ret_type, Type [] parameters)
4207 if (parameters == null)
4208 Parameters = TypeManager.NoTypes;
4210 Parameters = parameters;
4213 public override int GetHashCode ()
4215 return Name.GetHashCode ();
4218 public override bool Equals (Object o)
4220 MethodSignature other = (MethodSignature) o;
4222 if (other.Name != Name)
4225 if (other.RetType != RetType)
4228 if (Parameters == null){
4229 if (other.Parameters == null)
4234 if (other.Parameters == null)
4237 int c = Parameters.Length;
4238 if (other.Parameters.Length != c)
4241 for (int i = 0; i < c; i++)
4242 if (other.Parameters [i] != Parameters [i])
4248 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
4250 MethodSignature sig = (MethodSignature) filter_criteria;
4252 if (m.Name != sig.Name)
4256 MethodInfo mi = m as MethodInfo;
4257 PropertyInfo pi = m as PropertyInfo;
4260 ReturnType = mi.ReturnType;
4261 else if (pi != null)
4262 ReturnType = pi.PropertyType;
4267 // we use sig.RetType == null to mean `do not check the
4268 // method return value.
4270 if (sig.RetType != null)
4271 if (ReturnType != sig.RetType)
4276 args = TypeManager.GetArgumentTypes (mi);
4278 args = TypeManager.GetArgumentTypes (pi);
4279 Type [] sigp = sig.Parameters;
4281 if (args.Length != sigp.Length)
4284 for (int i = args.Length; i > 0; ){
4286 if (args [i] != sigp [i])
4293 // This filter should be used when we are requesting methods that
4294 // we want to override.
4296 // This makes a number of assumptions, for example
4297 // that the methods being extracted are of a parent
4298 // class (this means we know implicitly that we are
4299 // being called to find out about members by a derived
4302 static bool InheritableMemberSignatureCompare (MemberInfo m, object filter_criteria)
4304 if (MemberSignatureCompare (m, filter_criteria)){
4305 MethodInfo mi = (MethodInfo) m;
4306 MethodAttributes prot = mi.Attributes & MethodAttributes.MemberAccessMask;
4308 // If only accessible to the current class.
4309 if (prot == MethodAttributes.Private)
4312 // If only accessible to the defining assembly or
4313 if (prot == MethodAttributes.FamANDAssem ||
4314 prot == MethodAttributes.Assembly){
4315 if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
4321 // Anything else (FamOrAssembly and Public) is fine
4328 // This filter should be used when we are requesting properties that
4329 // we want to override.
4331 // This makes a number of assumptions, for example
4332 // that the methods being extracted are of a parent
4333 // class (this means we know implicitly that we are
4334 // being called to find out about members by a derived
4337 static bool InheritablePropertySignatureCompare (MemberInfo m, object filter_criteria)
4339 if (MemberSignatureCompare (m, filter_criteria)){
4340 PropertyInfo pi = (PropertyInfo) m;
4342 MethodInfo inherited_get = TypeManager.GetPropertyGetter (pi);
4343 MethodInfo inherited_set = TypeManager.GetPropertySetter (pi);
4345 MethodInfo mi = inherited_get == null ? inherited_set : inherited_get;
4347 MethodAttributes prot = mi.Attributes & MethodAttributes.MemberAccessMask;
4349 // If only accessible to the current class.
4350 if (prot == MethodAttributes.Private)
4353 // If only accessible to the defining assembly or
4354 if (prot == MethodAttributes.FamANDAssem ||
4355 prot == MethodAttributes.Assembly){
4356 if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
4362 // Anything else (FamOrAssembly and Public) is fine