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, IMemberContainer {
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.
111 // The parent member container and our member cache
112 IMemberContainer parent_container;
113 MemberCache member_cache;
116 // The indexer name for this class
118 public string IndexerName;
120 public TypeContainer (TypeContainer parent, string name, Location l)
121 : base (parent, name, l)
124 types = new ArrayList ();
131 base_class_name = null;
133 //Console.WriteLine ("New class " + name + " inside " + n);
136 public AdditionResult AddConstant (Const constant)
139 string name = constant.Name;
141 if ((res = IsValid (name)) != AdditionResult.Success)
144 if (constants == null)
145 constants = new ArrayList ();
147 constants.Add (constant);
148 DefineName (name, constant);
150 return AdditionResult.Success;
153 public AdditionResult AddEnum (Mono.CSharp.Enum e)
156 string name = e.Name;
158 if ((res = IsValid (name)) != AdditionResult.Success)
162 enums = new ArrayList ();
165 DefineName (name, e);
167 return AdditionResult.Success;
170 public AdditionResult AddClass (Class c)
173 string name = c.Name;
176 if ((res = IsValid (name)) != AdditionResult.Success)
179 DefineName (name, c);
182 return AdditionResult.Success;
185 public AdditionResult AddStruct (Struct s)
188 string name = s.Name;
190 if ((res = IsValid (name)) != AdditionResult.Success)
193 DefineName (name, s);
196 return AdditionResult.Success;
199 public AdditionResult AddDelegate (Delegate d)
202 string name = d.Name;
204 if ((res = IsValid (name)) != AdditionResult.Success)
207 if (delegates == null)
208 delegates = new ArrayList ();
210 DefineName (name, d);
213 return AdditionResult.Success;
216 public AdditionResult AddMethod (Method method)
218 string name = method.Name;
219 Object value = defined_names [name];
221 if (value != null && (!(value is Method)))
222 return AdditionResult.NameExists;
224 if (name == Basename)
225 return AdditionResult.EnclosingClash;
228 methods = new ArrayList ();
230 if (method.Name.IndexOf (".") != -1)
231 methods.Insert (0, method);
233 methods.Add (method);
236 DefineName (name, method);
238 return AdditionResult.Success;
241 public AdditionResult AddConstructor (Constructor c)
243 if (c.Name != Basename)
244 return AdditionResult.NotAConstructor;
246 bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
249 have_static_constructor = true;
250 if (default_static_constructor != null){
251 Console.WriteLine ("I have a static constructor already");
252 Console.WriteLine (" " + default_static_constructor);
253 return AdditionResult.MethodExists;
256 default_static_constructor = c;
259 if (default_constructor != null)
260 return AdditionResult.MethodExists;
261 default_constructor = c;
264 if (instance_constructors == null)
265 instance_constructors = new ArrayList ();
267 instance_constructors.Add (c);
270 return AdditionResult.Success;
273 public AdditionResult AddInterface (Interface iface)
276 string name = iface.Name;
278 if ((res = IsValid (name)) != AdditionResult.Success)
281 if (interfaces == null)
282 interfaces = new ArrayList ();
283 interfaces.Add (iface);
284 DefineName (name, iface);
286 return AdditionResult.Success;
289 public AdditionResult AddField (Field field)
292 string name = field.Name;
294 if ((res = IsValid (name)) != AdditionResult.Success)
298 fields = new ArrayList ();
302 if (field.HasInitializer){
303 if ((field.ModFlags & Modifiers.STATIC) != 0){
304 if (initialized_static_fields == null)
305 initialized_static_fields = new ArrayList ();
307 initialized_static_fields.Add (field);
310 // We have not seen a static constructor,
311 // but we will provide static initialization of fields
313 have_static_constructor = true;
315 if (initialized_fields == null)
316 initialized_fields = new ArrayList ();
318 initialized_fields.Add (field);
322 if ((field.ModFlags & Modifiers.STATIC) == 0)
323 have_nonstatic_fields = true;
325 DefineName (name, field);
326 return AdditionResult.Success;
329 public AdditionResult AddProperty (Property prop)
332 string name = prop.Name;
334 if ((res = IsValid (name)) != AdditionResult.Success)
337 if (properties == null)
338 properties = new ArrayList ();
340 if (prop.Name.IndexOf (".") != -1)
341 properties.Insert (0, prop);
343 properties.Add (prop);
344 DefineName (name, prop);
346 return AdditionResult.Success;
349 public AdditionResult AddEvent (Event e)
352 string name = e.Name;
354 if ((res = IsValid (name)) != AdditionResult.Success)
358 events = new ArrayList ();
361 DefineName (name, e);
363 return AdditionResult.Success;
366 public AdditionResult AddIndexer (Indexer i)
368 if (indexers == null)
369 indexers = new ArrayList ();
371 if (i.InterfaceType != null)
372 indexers.Insert (0, i);
376 return AdditionResult.Success;
379 public AdditionResult AddOperator (Operator op)
381 if (operators == null)
382 operators = new ArrayList ();
386 return AdditionResult.Success;
389 public void RegisterOrder (Interface iface)
391 if (interface_order == null)
392 interface_order = new ArrayList ();
394 interface_order.Add (iface);
397 public ArrayList Types {
403 public ArrayList Methods {
409 public ArrayList Constants {
415 public ArrayList Interfaces {
423 return base_class_name;
427 public ArrayList Bases {
437 public ArrayList Fields {
447 public ArrayList InstanceConstructors {
449 return instance_constructors;
453 public ArrayList Properties {
459 public ArrayList Events {
465 public ArrayList Enums {
471 public ArrayList Indexers {
477 public ArrayList Operators {
483 public ArrayList Delegates {
489 public Attributes OptAttributes {
495 public bool HaveStaticConstructor {
497 return have_static_constructor;
501 public virtual TypeAttributes TypeAttr {
503 return Modifiers.TypeAttr (ModFlags, this);
508 // Emits the instance field initializers
510 public bool EmitFieldInitializers (EmitContext ec)
513 ILGenerator ig = ec.ig;
514 Expression instance_expr;
517 fields = initialized_static_fields;
518 instance_expr = null;
520 fields = initialized_fields;
521 instance_expr = new This (Location.Null).Resolve (ec);
527 foreach (Field f in fields){
528 Expression e = f.GetInitializerExpression (ec);
532 Location l = f.Location;
533 FieldExpr fe = new FieldExpr (f.FieldBuilder, l);
534 fe.InstanceExpression = instance_expr;
535 Expression a = new Assign (fe, e, l);
541 if (a is ExpressionStatement)
542 ((ExpressionStatement) a).EmitStatement (ec);
544 throw new Exception ("Assign.Resolve returned a non ExpressionStatement");
552 // Defines the default constructors
554 void DefineDefaultConstructor (bool is_static)
559 c = new Constructor (Basename, Parameters.EmptyReadOnlyParameters,
560 new ConstructorBaseInitializer (
561 null, Parameters.EmptyReadOnlyParameters,
566 mods = Modifiers.STATIC;
572 c.Block = new Block (null);
576 public void ReportStructInitializedInstanceError ()
578 string n = TypeBuilder.FullName;
580 foreach (Field f in initialized_fields){
583 "`" + n + "." + f.Name + "': can not have " +
584 "instance field initializers in structs");
589 /// The pending methods that need to be implemented (interfaces or abstract methods)
591 public PendingImplementation Pending;
594 /// This function computes the Base class and also the
595 /// list of interfaces that the class or struct @c implements.
597 /// The return value is an array (might be null) of
598 /// interfaces implemented (as Types).
600 /// The @parent argument is set to the parent object or null
601 /// if this is `System.Object'.
603 Type [] GetClassBases (bool is_class, out Type parent, out bool error)
605 ArrayList bases = Bases;
614 parent = TypeManager.value_type;
618 if (RootContext.StdLib)
619 parent = TypeManager.object_type;
620 else if (Name != "System.Object")
621 parent = TypeManager.object_type;
624 // If we are compiling our runtime,
625 // and we are defining ValueType, then our
626 // parent is `System.Object'.
628 if (!RootContext.StdLib && Name == "System.ValueType")
629 parent = TypeManager.object_type;
636 // Bases should be null if there are no bases at all
641 Expression name = (Expression) bases [0];
642 name = ResolveTypeExpr (name, false, Location);
649 Type first = name.Type;
655 parent = TypeManager.object_type;
659 if (!AsAccessible (parent, ModFlags))
660 Report.Error (60, Location,
661 "Inconsistent accessibility: base class `" +
662 TypeManager.CSharpName (parent) + "' is less " +
663 "accessible than class `" +
670 Type [] ifaces = new Type [count-start];
672 for (i = start, j = 0; i < count; i++, j++){
673 Expression name = (Expression) bases [i];
674 Expression resolved = ResolveTypeExpr (name, false, Location);
675 bases [i] = resolved;
676 Type t = resolved.Type;
683 if (is_class == false && !t.IsInterface){
684 Report.Error (527, "In Struct `" + Name + "', type `"+
685 name +"' is not an interface");
694 detail = " (a class can not inherit from a struct/enum)";
696 Report.Error (509, "class `"+ Name +
697 "': Cannot inherit from sealed class `"+
698 bases [i]+"'"+detail);
705 Report.Error (527, "In Class `" + Name + "', type `"+
706 name+"' is not an interface");
712 for (int x = 0; x < j; x++) {
713 if (t == ifaces [x]) {
714 Report.Error (528, "`" + name + "' is already listed in interface list");
723 return TypeManager.ExpandInterfaces (ifaces);
727 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
729 public override TypeBuilder DefineType ()
735 if (TypeBuilder != null)
748 ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
750 ifaces = GetClassBases (is_class, out parent, out error);
755 if (is_class && parent != null){
756 if (parent == TypeManager.enum_type ||
757 (parent == TypeManager.value_type && RootContext.StdLib) ||
758 parent == TypeManager.delegate_type ||
759 parent == TypeManager.array_type){
761 644, Location, "`" + Name + "' cannot inherit from " +
762 "special class `" + TypeManager.CSharpName (parent) + "'");
767 if (!is_class && TypeManager.value_type == null)
768 throw new Exception ();
770 TypeAttributes type_attributes = TypeAttr;
772 // if (parent_builder is ModuleBuilder) {
774 ModuleBuilder builder = CodeGen.ModuleBuilder;
777 // Structs with no fields need to have a ".size 1"
781 if (!is_class && !have_nonstatic_fields)
782 TypeBuilder = builder.DefineType (Name,
785 PackingSize.Unspecified, 1);
788 // classes or structs with fields
790 TypeBuilder = builder.DefineType (Name,
795 TypeBuilder builder = Parent.TypeBuilder;
798 // Structs with no fields need to have a ".size 1"
801 if (!is_class && !have_nonstatic_fields)
802 TypeBuilder = builder.DefineNestedType (Basename,
805 PackingSize.Unspecified);
808 // classes or structs with fields
810 TypeBuilder = builder.DefineNestedType (Basename,
817 // add interfaces that were not added at type creation (weird API issue)
818 if (!is_class && !have_nonstatic_fields && (ifaces != null)) {
819 foreach (Type i in ifaces)
820 TypeBuilder.AddInterfaceImplementation (i);
824 // Finish the setup for the EmitContext
826 ec.ContainerType = TypeBuilder;
828 TypeManager.AddUserType (Name, TypeBuilder, this, ifaces);
830 if ((parent != null) &&
831 (parent == TypeManager.attribute_type ||
832 parent.IsSubclassOf (TypeManager.attribute_type))) {
833 RootContext.RegisterAttribute (this);
834 TypeManager.RegisterAttrType (TypeBuilder, this);
836 RootContext.RegisterOrder (this);
838 if (Interfaces != null) {
839 foreach (Interface iface in Interfaces)
844 foreach (TypeContainer tc in Types)
848 if (Delegates != null) {
849 foreach (Delegate d in Delegates)
854 foreach (Enum en in Enums)
864 /// Defines the MemberCore objects that are in the `list' Arraylist
866 /// The `defined_names' array contains a list of members defined in
869 static ArrayList remove_list = new ArrayList ();
870 void DefineMembers (ArrayList list, MemberInfo [] defined_names)
874 remove_list.Clear ();
876 foreach (MemberCore mc in list){
877 if (!mc.Define (this)){
878 remove_list.Add (mc);
882 if (defined_names == null)
885 idx = Array.BinarySearch (defined_names, mc.Name, mif_compare);
887 if (RootContext.WarningLevel >= 4){
888 if ((mc.ModFlags & Modifiers.NEW) != 0)
889 Warning_KewywordNewNotRequired (mc.Location, mc);
894 MemberInfo match = defined_names [idx];
896 if (match is PropertyInfo && ((mc.ModFlags & Modifiers.OVERRIDE) != 0))
900 // If we are both methods, let the method resolution emit warnings
902 if (match is MethodBase && mc is MethodCore)
905 if ((mc.ModFlags & Modifiers.NEW) == 0)
906 Warning_KeywordNewRequired (mc.Location, defined_names [idx]);
909 foreach (object o in remove_list)
912 remove_list.Clear ();
916 // Defines the indexers, and also verifies that the IndexerNameAttribute in the
917 // class is consisten. Either it is `Item' or it is the name defined by all the
918 // indexers with the `IndexerName' attribute.
920 // Turns out that the IndexerNameAttribute is applied to each indexer,
921 // but it is never emitted, instead a DefaultName attribute is attached
924 void DefineIndexers ()
926 string class_indexer_name = null;
928 foreach (Indexer i in Indexers){
933 name = i.IndexerName;
935 if (i.InterfaceType != null)
938 if (class_indexer_name == null){
939 class_indexer_name = name;
943 if (name == class_indexer_name)
947 668, "Two indexers have different names, " +
948 " you should use the same name for all your indexers");
950 if (class_indexer_name == null)
951 class_indexer_name = "Item";
952 IndexerName = class_indexer_name;
955 static void Report1530 (Location loc)
957 Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
961 /// Populates our TypeBuilder with fields and methods
963 public override bool DefineMembers (TypeContainer parent)
965 MemberInfo [] defined_names = null;
967 if (interface_order != null){
968 foreach (Interface iface in interface_order)
969 if ((iface.ModFlags & Modifiers.NEW) == 0)
970 iface.DefineMembers (this);
972 Report1530 (iface.Location);
975 if (RootContext.WarningLevel > 1){
979 // This code throws an exception in the comparer
980 // I guess the string is not an object?
982 ptype = TypeBuilder.BaseType;
984 defined_names = (MemberInfo []) FindMembers (
985 ptype, MemberTypes.All & ~MemberTypes.Constructor,
986 BindingFlags.Public | BindingFlags.Instance |
987 BindingFlags.Static, null, null);
989 Array.Sort (defined_names, mif_compare);
993 if (constants != null)
994 DefineMembers (constants, defined_names);
997 DefineMembers (fields, defined_names);
1000 if (instance_constructors == null){
1001 if (default_constructor == null)
1002 DefineDefaultConstructor (false);
1005 if (initialized_static_fields != null &&
1006 default_static_constructor == null)
1007 DefineDefaultConstructor (true);
1010 if (this is Struct){
1012 // Structs can not have initialized instance
1015 if (initialized_static_fields != null &&
1016 default_static_constructor == null)
1017 DefineDefaultConstructor (true);
1019 if (initialized_fields != null)
1020 ReportStructInitializedInstanceError ();
1023 Pending = PendingImplementation.GetPendingImplementations (this);
1026 // Constructors are not in the defined_names array
1028 if (instance_constructors != null)
1029 DefineMembers (instance_constructors, null);
1031 if (default_static_constructor != null)
1032 default_static_constructor.Define (this);
1034 if (methods != null)
1035 DefineMembers (methods, defined_names);
1037 if (properties != null)
1038 DefineMembers (properties, defined_names);
1041 DefineMembers (events, defined_names);
1043 if (indexers != null) {
1046 IndexerName = "Item";
1048 if (operators != null)
1049 DefineMembers (operators, null);
1052 DefineMembers (enums, defined_names);
1054 if (delegates != null)
1055 DefineMembers (delegates, defined_names);
1058 if (TypeBuilder.BaseType != null)
1059 parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
1061 member_cache = new MemberCache (this);
1067 public override bool Define (TypeContainer parent)
1069 if (interface_order != null){
1070 foreach (Interface iface in interface_order)
1071 if ((iface.ModFlags & Modifiers.NEW) == 0)
1072 iface.Define (this);
1079 /// This function is based by a delegate to the FindMembers routine
1081 static bool AlwaysAccept (MemberInfo m, object filterCriteria)
1087 /// This filter is used by FindMembers, and we just keep
1088 /// a global for the filter to `AlwaysAccept'
1090 static MemberFilter accepting_filter;
1094 /// A member comparission method based on name only
1096 static IComparer mif_compare;
1098 static TypeContainer ()
1100 accepting_filter = new MemberFilter (AlwaysAccept);
1101 mif_compare = new MemberInfoCompare ();
1105 /// This method returns the members of this type just like Type.FindMembers would
1106 /// Only, we need to use this for types which are _being_ defined because MS'
1107 /// implementation can't take care of that.
1110 // FIXME: return an empty static array instead of null, that cleans up
1111 // some code and is consistent with some coding conventions I just found
1115 // Notice that in various cases we check if our field is non-null,
1116 // something that would normally mean that there was a bug elsewhere.
1118 // The problem happens while we are defining p-invoke methods, as those
1119 // will trigger a FindMembers, but this happens before things are defined
1121 // Since the whole process is a no-op, it is fine to check for null here.
1123 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1124 MemberFilter filter, object criteria)
1126 ArrayList members = new ArrayList ();
1129 if ((bf & BindingFlags.Public) != 0)
1130 modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
1132 if ((bf & BindingFlags.NonPublic) != 0)
1133 modflags |= Modifiers.PRIVATE;
1135 int static_mask = 0, static_flags = 0;
1136 switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
1137 case BindingFlags.Static:
1138 static_mask = static_flags = Modifiers.STATIC;
1141 case BindingFlags.Instance:
1142 static_mask = Modifiers.STATIC;
1147 static_mask = static_flags = 0;
1151 Timer.StartTimer (TimerType.TcFindMembers);
1154 filter = accepting_filter;
1156 if ((mt & MemberTypes.Field) != 0) {
1157 if (fields != null) {
1158 foreach (Field f in fields) {
1159 if ((f.ModFlags & modflags) == 0)
1161 if ((f.ModFlags & static_mask) != static_flags)
1164 FieldBuilder fb = f.FieldBuilder;
1165 if (fb != null && filter (fb, criteria) == true)
1170 if (constants != null) {
1171 foreach (Const con in constants) {
1172 if ((con.ModFlags & modflags) == 0)
1174 if ((con.ModFlags & static_mask) != static_flags)
1177 FieldBuilder fb = con.FieldBuilder;
1178 if (fb != null && filter (fb, criteria) == true)
1184 if ((mt & MemberTypes.Method) != 0) {
1185 if (methods != null) {
1186 foreach (Method m in methods) {
1187 if ((m.ModFlags & modflags) == 0)
1189 if ((m.ModFlags & static_mask) != static_flags)
1192 MethodBuilder mb = m.MethodBuilder;
1194 if (mb != null && filter (mb, criteria) == true)
1199 if (operators != null){
1200 foreach (Operator o in operators) {
1201 if ((o.ModFlags & modflags) == 0)
1203 if ((o.ModFlags & static_mask) != static_flags)
1206 MethodBuilder ob = o.OperatorMethodBuilder;
1207 if (ob != null && filter (ob, criteria) == true)
1212 if (properties != null){
1213 foreach (Property p in properties){
1214 if ((p.ModFlags & modflags) == 0)
1216 if ((p.ModFlags & static_mask) != static_flags)
1222 if (b != null && filter (b, criteria) == true)
1226 if (b != null && filter (b, criteria) == true)
1231 if (indexers != null){
1232 foreach (Indexer ix in indexers){
1233 if ((ix.ModFlags & modflags) == 0)
1235 if ((ix.ModFlags & static_mask) != static_flags)
1241 if (b != null && filter (b, criteria) == true)
1245 if (b != null && filter (b, criteria) == true)
1251 if ((mt & MemberTypes.Event) != 0) {
1253 foreach (Event e in events) {
1254 if ((e.ModFlags & modflags) == 0)
1257 MemberInfo eb = e.EventBuilder;
1258 if (eb != null && filter (eb, criteria) == true)
1259 members.Add (e.EventBuilder);
1263 if ((mt & MemberTypes.Property) != 0){
1264 if (properties != null)
1265 foreach (Property p in properties) {
1266 if ((p.ModFlags & modflags) == 0)
1268 if ((p.ModFlags & static_mask) != static_flags)
1271 MemberInfo pb = p.PropertyBuilder;
1272 if (pb != null && filter (pb, criteria) == true) {
1273 members.Add (p.PropertyBuilder);
1277 if (indexers != null)
1278 foreach (Indexer ix in indexers) {
1279 if ((ix.ModFlags & modflags) == 0)
1281 if ((ix.ModFlags & static_mask) != static_flags)
1284 MemberInfo ib = ix.PropertyBuilder;
1285 if (ib != null && filter (ib, criteria) == true) {
1286 members.Add (ix.PropertyBuilder);
1291 if ((mt & MemberTypes.NestedType) != 0) {
1293 foreach (TypeContainer t in types) {
1294 if ((t.ModFlags & modflags) == 0)
1297 TypeBuilder tb = t.TypeBuilder;
1298 if (tb != null && (filter (tb, criteria) == true))
1304 foreach (Enum en in enums){
1305 if ((en.ModFlags & modflags) == 0)
1308 TypeBuilder tb = en.TypeBuilder;
1309 if (tb != null && (filter (tb, criteria) == true))
1314 if (delegates != null){
1315 foreach (Delegate d in delegates){
1316 if ((d.ModFlags & modflags) == 0)
1319 TypeBuilder tb = d.TypeBuilder;
1320 if (tb != null && (filter (tb, criteria) == true))
1325 if (interfaces != null){
1326 foreach (Interface iface in interfaces){
1327 if ((iface.ModFlags & modflags) == 0)
1330 TypeBuilder tb = iface.TypeBuilder;
1331 if (tb != null && (filter (tb, criteria) == true))
1337 if ((mt & MemberTypes.Constructor) != 0){
1338 if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
1339 foreach (Constructor c in instance_constructors){
1340 ConstructorBuilder cb = c.ConstructorBuilder;
1342 if (filter (cb, criteria) == true)
1347 if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
1348 ConstructorBuilder cb =
1349 default_static_constructor.ConstructorBuilder;
1352 if (filter (cb, criteria) == true)
1358 // Lookup members in parent if requested.
1360 if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
1361 MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
1362 members.AddRange (list);
1365 Timer.StopTimer (TimerType.TcFindMembers);
1367 return new MemberList (members);
1370 public override MemberCache MemberCache {
1372 return member_cache;
1376 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
1377 MemberFilter filter, object criteria)
1379 TypeContainer tc = TypeManager.LookupTypeContainer (t);
1382 return tc.FindMembers (mt, bf, filter, criteria);
1384 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
1388 // FindMethods will look for methods not only in the type `t', but in
1389 // any interfaces implemented by the type.
1391 public static MethodInfo [] FindMethods (Type t, BindingFlags bf,
1392 MemberFilter filter, object criteria)
1398 /// Emits the values for the constants
1400 public void EmitConstants ()
1402 if (constants != null)
1403 foreach (Const con in constants)
1404 con.EmitConstant (this);
1409 /// Emits the code, this step is performed after all
1410 /// the types, enumerations, constructors
1414 if (instance_constructors != null)
1415 foreach (Constructor c in instance_constructors)
1418 if (default_static_constructor != null)
1419 default_static_constructor.Emit (this);
1421 if (methods != null)
1422 foreach (Method m in methods)
1425 if (operators != null)
1426 foreach (Operator o in operators)
1429 if (properties != null)
1430 foreach (Property p in properties)
1433 if (indexers != null){
1434 foreach (Indexer ix in indexers)
1437 CustomAttributeBuilder cb = Interface.EmitDefaultMemberAttr (
1438 this, IndexerName, ModFlags, Location);
1439 TypeBuilder.SetCustomAttribute (cb);
1443 foreach (Field f in fields)
1446 if (events != null){
1447 foreach (Event e in Events)
1451 if (Pending != null)
1452 if (Pending.VerifyPendingMethods ())
1455 Attribute.ApplyAttributes (ec, TypeBuilder, this, OptAttributes, Location);
1458 // Check for internal or private fields that were never assigned
1460 if (fields != null && RootContext.WarningLevel >= 3) {
1461 foreach (Field f in fields) {
1462 if ((f.ModFlags & Modifiers.PUBLIC) != 0)
1467 169, f.Location, "Private field " +
1468 MakeName (f.Name) + " is never used");
1473 // Only report 649 on level 4
1475 if (RootContext.WarningLevel < 4)
1478 if ((f.status & Field.Status.ASSIGNED) != 0)
1483 "Field " + MakeName (f.Name) + " is never assigned " +
1484 " to and will always have its default value");
1488 // if (types != null)
1489 // foreach (TypeContainer tc in types)
1493 public override void CloseType ()
1498 TypeBuilder.CreateType ();
1500 } catch (TypeLoadException){
1502 // This is fine, the code still created the type
1504 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
1505 // Console.WriteLine (e.Message);
1507 Console.WriteLine ("In type: " + Name);
1512 foreach (Enum en in Enums)
1515 if (interface_order != null){
1516 foreach (Interface iface in interface_order)
1521 foreach (TypeContainer tc in Types)
1525 foreach (TypeContainer tc in Types)
1526 if (!(tc is Struct))
1530 if (Delegates != null)
1531 foreach (Delegate d in Delegates)
1535 public string MakeName (string n)
1537 return "`" + Name + "." + n + "'";
1540 public void Warning_KeywordNewRequired (Location l, MemberInfo mi)
1543 108, l, "The keyword new is required on " +
1544 MakeName (mi.Name) + " because it hides `" +
1545 mi.ReflectedType.Name + "." + mi.Name + "'");
1548 public void Warning_KewywordNewNotRequired (Location l, MemberCore mc)
1551 109, l, "The member " + MakeName (mc.Name) + " does not hide an " +
1552 "inherited member, the keyword new is not required");
1555 public static int CheckMember (string name, MemberInfo mi, int ModFlags)
1561 // Performs the validation on a Method's modifiers (properties have
1562 // the same properties).
1564 public bool MethodModifiersValid (int flags, string n, Location loc)
1566 const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
1567 const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
1568 const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
1570 string name = MakeName (n);
1573 // At most one of static, virtual or override
1575 if ((flags & Modifiers.STATIC) != 0){
1576 if ((flags & vao) != 0){
1578 112, loc, "static method " + name + "can not be marked " +
1579 "as virtual, abstract or override");
1584 if (this is Struct){
1585 if ((flags & va) != 0){
1586 Modifiers.Error_InvalidModifier (loc, "virtual or abstract");
1591 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
1594 " marked as override cannot be marked as new or virtual");
1599 // If the declaration includes the abstract modifier, then the
1600 // declaration does not include static, virtual or extern
1602 if ((flags & Modifiers.ABSTRACT) != 0){
1603 if ((flags & Modifiers.EXTERN) != 0){
1605 180, loc, name + " can not be both abstract and extern");
1609 if ((flags & Modifiers.VIRTUAL) != 0){
1611 503, loc, name + " can not be both abstract and virtual");
1615 if ((ModFlags & Modifiers.ABSTRACT) == 0){
1618 " is abstract but its container class is not");
1624 if ((flags & Modifiers.PRIVATE) != 0){
1625 if ((flags & vao) != 0){
1628 " virtual or abstract members can not be private");
1633 if ((flags & Modifiers.SEALED) != 0){
1634 if ((flags & Modifiers.OVERRIDE) == 0){
1637 " cannot be sealed because it is not an override");
1645 // Access level of a type.
1648 ProtectedInternal = 1,
1654 // Check whether `flags' denotes a more restricted access than `level'
1655 // and return the new level.
1656 static AccessLevel CheckAccessLevel (AccessLevel level, int flags)
1658 AccessLevel old_level = level;
1660 if ((flags & Modifiers.INTERNAL) != 0) {
1661 if ((flags & Modifiers.PROTECTED) != 0) {
1662 if ((int) level < (int) AccessLevel.ProtectedInternal)
1663 level = AccessLevel.ProtectedInternal;
1665 if ((int) level < (int) AccessLevel.Internal)
1666 level = AccessLevel.Internal;
1668 } else if ((flags & Modifiers.PROTECTED) != 0) {
1669 if ((int) level < (int) AccessLevel.Protected)
1670 level = AccessLevel.Protected;
1671 } else if ((flags & Modifiers.PRIVATE) != 0)
1672 level = AccessLevel.Private;
1677 // Return the access level for a new member which is defined in the current
1678 // TypeContainer with access modifiers `flags'.
1679 AccessLevel GetAccessLevel (int flags)
1681 if ((flags & Modifiers.PRIVATE) != 0)
1682 return AccessLevel.Private;
1685 if (!IsTopLevel && (Parent != null))
1686 level = Parent.GetAccessLevel (flags);
1688 level = AccessLevel.Public;
1690 return CheckAccessLevel (CheckAccessLevel (level, flags), ModFlags);
1693 // Return the access level for type `t', but don't give more access than `flags'.
1694 static AccessLevel GetAccessLevel (Type t, int flags)
1696 if (((flags & Modifiers.PRIVATE) != 0) || t.IsNestedPrivate)
1697 return AccessLevel.Private;
1700 if (TypeManager.IsBuiltinType (t))
1701 return AccessLevel.Public;
1702 else if ((t.DeclaringType != null) && (t != t.DeclaringType))
1703 level = GetAccessLevel (t.DeclaringType, flags);
1705 level = CheckAccessLevel (AccessLevel.Public, flags);
1708 if (t.IsNestedPublic)
1711 if (t.IsNestedAssembly || t.IsNotPublic) {
1712 if ((int) level < (int) AccessLevel.Internal)
1713 level = AccessLevel.Internal;
1716 if (t.IsNestedFamily) {
1717 if ((int) level < (int) AccessLevel.Protected)
1718 level = AccessLevel.Protected;
1721 if (t.IsNestedFamORAssem) {
1722 if ((int) level < (int) AccessLevel.ProtectedInternal)
1723 level = AccessLevel.ProtectedInternal;
1730 // Returns true if `parent' is as accessible as the flags `flags'
1731 // given for this member.
1733 public bool AsAccessible (Type parent, int flags)
1735 while (parent.IsArray || parent.IsPointer || parent.IsByRef)
1736 parent = parent.GetElementType ();
1738 AccessLevel level = GetAccessLevel (flags);
1739 AccessLevel level2 = GetAccessLevel (parent, flags);
1741 return (int) level >= (int) level2;
1744 Hashtable builder_and_args;
1746 public bool RegisterMethod (MethodBuilder mb, InternalParameters ip, Type [] args)
1748 if (builder_and_args == null)
1749 builder_and_args = new Hashtable ();
1754 /// Performs checks for an explicit interface implementation. First it
1755 /// checks whether the `interface_type' is a base inteface implementation.
1756 /// Then it checks whether `name' exists in the interface type.
1758 public bool VerifyImplements (Type interface_type, string full, string name, Location loc)
1762 if (ifaces != null){
1763 foreach (Type t in ifaces){
1764 if (t == interface_type){
1772 Report.Error (540, "`" + full + "': containing class does not implement interface `" + interface_type.FullName + "'");
1779 public static void Error_ExplicitInterfaceNotMemberInterface (Location loc, string name)
1781 Report.Error (539, loc, "Explicit implementation: `" + name + "' is not a member of the interface");
1788 string IMemberContainer.Name {
1794 Type IMemberContainer.Type {
1800 IMemberContainer IMemberContainer.Parent {
1802 return parent_container;
1806 MemberCache IMemberContainer.MemberCache {
1808 return member_cache;
1812 bool IMemberContainer.IsInterface {
1818 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
1820 return FindMembers (mt, bf | BindingFlags.DeclaredOnly, null, null);
1824 public class Class : TypeContainer {
1826 // Modifiers allowed in a class declaration
1828 public const int AllowedModifiers =
1831 Modifiers.PROTECTED |
1832 Modifiers.INTERNAL |
1834 Modifiers.ABSTRACT |
1838 public Class (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
1839 : base (parent, name, l)
1843 if (parent.Parent == null)
1844 accmods = Modifiers.INTERNAL;
1846 accmods = Modifiers.PRIVATE;
1848 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
1849 this.attributes = attrs;
1853 // FIXME: How do we deal with the user specifying a different
1856 public override TypeAttributes TypeAttr {
1858 return base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
1863 public class Struct : TypeContainer {
1865 // Modifiers allowed in a struct declaration
1867 public const int AllowedModifiers =
1870 Modifiers.PROTECTED |
1871 Modifiers.INTERNAL |
1875 public Struct (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
1876 : base (parent, name, l)
1880 if (parent.Parent == null)
1881 accmods = Modifiers.INTERNAL;
1883 accmods = Modifiers.PRIVATE;
1885 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
1887 this.ModFlags |= Modifiers.SEALED;
1888 this.attributes = attrs;
1893 // FIXME: Allow the user to specify a different set of attributes
1894 // in some cases (Sealed for example is mandatory for a class,
1895 // but what SequentialLayout can be changed
1897 public override TypeAttributes TypeAttr {
1899 return base.TypeAttr |
1900 TypeAttributes.SequentialLayout |
1901 TypeAttributes.Sealed |
1902 TypeAttributes.BeforeFieldInit;
1907 public abstract class MethodCore : MemberBase {
1908 public readonly Parameters Parameters;
1912 // Parameters, cached for semantic analysis.
1914 protected InternalParameters parameter_info;
1915 protected Type [] parameter_types;
1917 public MethodCore (Expression type, int mod, int allowed_mod, string name,
1918 Attributes attrs, Parameters parameters, Location loc)
1919 : base (type, mod, allowed_mod, name, attrs, loc)
1921 Parameters = parameters;
1925 // Returns the System.Type array for the parameters of this method
1927 public Type [] ParameterTypes {
1929 return parameter_types;
1933 public InternalParameters ParameterInfo
1936 return parameter_info;
1940 public Block Block {
1950 protected virtual bool DoDefineParameters (TypeContainer parent)
1952 // Check if arguments were correct
1953 parameter_types = Parameters.GetParameterInfo (parent);
1954 if ((parameter_types == null) || !CheckParameters (parent, parameter_types))
1957 parameter_info = new InternalParameters (parent, Parameters);
1962 public CallingConventions GetCallingConvention (bool is_class)
1964 CallingConventions cc = 0;
1966 cc = Parameters.GetCallingConvention ();
1969 if ((ModFlags & Modifiers.STATIC) == 0)
1970 cc |= CallingConventions.HasThis;
1972 // FIXME: How is `ExplicitThis' used in C#?
1977 public void LabelParameters (EmitContext ec, Type [] parameters, MethodBase builder)
1980 // Define each type attribute (in/out/ref) and
1981 // the argument names.
1983 Parameter [] p = Parameters.FixedParameters;
1986 MethodBuilder mb = null;
1987 ConstructorBuilder cb = null;
1989 if (builder is MethodBuilder)
1990 mb = (MethodBuilder) builder;
1992 cb = (ConstructorBuilder) builder;
1995 for (i = 0; i < p.Length; i++) {
1996 ParameterBuilder pb;
1999 pb = cb.DefineParameter (
2000 i + 1, p [i].Attributes, p [i].Name);
2002 pb = mb.DefineParameter (
2003 i + 1, p [i].Attributes, p [i].Name);
2005 Attributes attr = p [i].OptAttributes;
2007 Attribute.ApplyAttributes (ec, pb, pb, attr, Location);
2011 if (Parameters.ArrayParameter != null){
2012 ParameterBuilder pb;
2013 Parameter array_param = Parameters.ArrayParameter;
2016 pb = cb.DefineParameter (
2017 i + 1, array_param.Attributes,
2020 pb = mb.DefineParameter (
2021 i + 1, array_param.Attributes,
2024 CustomAttributeBuilder a = new CustomAttributeBuilder (
2025 TypeManager.cons_param_array_attribute, new object [0]);
2027 pb.SetCustomAttribute (a);
2032 public class Method : MethodCore {
2033 public MethodBuilder MethodBuilder;
2034 public MethodData MethodData;
2037 /// Modifiers allowed in a class declaration
2039 const int AllowedModifiers =
2042 Modifiers.PROTECTED |
2043 Modifiers.INTERNAL |
2048 Modifiers.OVERRIDE |
2049 Modifiers.ABSTRACT |
2054 // return_type can be "null" for VOID values.
2056 public Method (Expression return_type, int mod, string name, Parameters parameters,
2057 Attributes attrs, Location l)
2058 : base (return_type, mod, AllowedModifiers, name, attrs, parameters, l)
2062 // Returns the `System.Type' for the ReturnType of this
2063 // function. Provides a nice cache. (used between semantic analysis
2064 // and actual code generation
2066 public Type GetReturnType (TypeContainer parent)
2071 // Whether this is an operator method.
2072 public bool IsOperator;
2074 void DuplicateEntryPoint (MethodInfo b, Location location)
2078 "Program `" + CodeGen.FileName +
2079 "' has more than one entry point defined: `" +
2080 TypeManager.CSharpSignature(b) + "'");
2083 void Report28 (MethodInfo b)
2085 if (RootContext.WarningLevel < 4)
2090 "`" + TypeManager.CSharpSignature(b) +
2091 "' has the wrong signature to be an entry point");
2094 public bool IsEntryPoint (MethodBuilder b, InternalParameters pinfo)
2096 if (b.ReturnType != TypeManager.void_type &&
2097 b.ReturnType != TypeManager.int32_type)
2100 if (pinfo.Count == 0)
2103 if (pinfo.Count > 1)
2106 Type t = pinfo.ParameterType(0);
2108 (t.GetArrayRank() == 1) &&
2109 (t.GetElementType() == TypeManager.string_type) &&
2110 (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
2117 // Checks our base implementation if any
2119 protected override bool CheckBase (TypeContainer parent)
2121 // Check whether arguments were correct.
2122 if (!DoDefineParameters (parent))
2125 MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
2129 mi_this = TypeContainer.FindMembers (
2130 parent.TypeBuilder, MemberTypes.Method,
2131 BindingFlags.NonPublic | BindingFlags.Public |
2132 BindingFlags.Static | BindingFlags.Instance |
2133 BindingFlags.DeclaredOnly,
2134 MethodSignature.method_signature_filter, ms);
2136 if (mi_this.Count > 0) {
2137 Report.Error (111, Location, "Class `" + parent.Name + "' " +
2138 "already defines a member called `" + Name + "' " +
2139 "with the same parameter types");
2145 // Verify if the parent has a type with the same name, and then
2146 // check whether we have to create a new slot for it or not.
2148 Type ptype = parent.TypeBuilder.BaseType;
2150 // ptype is only null for System.Object while compiling corlib.
2152 MemberList mi, mi_static, mi_instance;
2154 mi_static = TypeContainer.FindMembers (
2155 ptype, MemberTypes.Method,
2156 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static,
2157 MethodSignature.inheritable_method_signature_filter, ms);
2159 mi_instance = TypeContainer.FindMembers (
2160 ptype, MemberTypes.Method,
2161 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
2162 MethodSignature.inheritable_method_signature_filter,
2165 if (mi_instance.Count > 0){
2167 } else if (mi_static.Count > 0)
2172 if (mi != null && mi.Count > 0){
2173 parent_method = (MethodInfo) mi [0];
2174 string name = parent_method.DeclaringType.Name + "." +
2177 if (!CheckMethodAgainstBase (parent, flags, parent_method, name))
2180 if ((ModFlags & Modifiers.NEW) == 0) {
2181 Type parent_ret = TypeManager.TypeToCoreType (
2182 parent_method.ReturnType);
2184 if (parent_ret != MemberType) {
2186 508, parent.MakeName (Name) + ": cannot " +
2187 "change return type when overriding " +
2188 "inherited member " + name);
2193 if ((ModFlags & Modifiers.NEW) != 0)
2194 WarningNotHiding (parent);
2196 if ((ModFlags & Modifiers.OVERRIDE) != 0){
2197 Report.Error (115, Location,
2198 parent.MakeName (Name) +
2199 " no suitable methods found to override");
2202 } else if ((ModFlags & Modifiers.NEW) != 0)
2203 WarningNotHiding (parent);
2211 public override bool Define (TypeContainer parent)
2213 if (!DoDefine (parent))
2216 if (!CheckBase (parent))
2219 CallingConventions cc = GetCallingConvention (parent is Class);
2221 MethodData = new MethodData (this, null, MemberType, ParameterTypes,
2222 ParameterInfo, cc, OptAttributes,
2223 ModFlags, flags, true);
2225 if (!MethodData.Define (parent))
2228 MethodBuilder = MethodData.MethodBuilder;
2231 // This is used to track the Entry Point,
2233 if (Name == "Main" &&
2234 ((ModFlags & Modifiers.STATIC) != 0) &&
2235 (RootContext.MainClass == null ||
2236 RootContext.MainClass == parent.TypeBuilder.FullName)){
2237 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
2238 if (RootContext.EntryPoint == null) {
2239 RootContext.EntryPoint = MethodBuilder;
2240 RootContext.EntryPointLocation = Location;
2242 DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
2243 DuplicateEntryPoint (MethodBuilder, Location);
2246 Report28(MethodBuilder);
2255 public void Emit (TypeContainer parent)
2257 MethodData.Emit (parent, Block, this);
2261 public abstract class ConstructorInitializer {
2262 ArrayList argument_list;
2263 ConstructorInfo parent_constructor;
2264 Parameters parameters;
2267 public ConstructorInitializer (ArrayList argument_list, Parameters parameters,
2270 this.argument_list = argument_list;
2271 this.parameters = parameters;
2275 public ArrayList Arguments {
2277 return argument_list;
2281 public bool Resolve (EmitContext ec)
2283 Expression parent_constructor_group;
2286 ec.CurrentBlock = new Block (null, true, parameters);
2288 if (argument_list != null){
2289 foreach (Argument a in argument_list){
2290 if (!a.Resolve (ec, loc))
2295 ec.CurrentBlock = null;
2297 if (this is ConstructorBaseInitializer) {
2298 if (ec.ContainerType.BaseType == null)
2301 t = ec.ContainerType.BaseType;
2302 if (ec.ContainerType.IsValueType) {
2303 Report.Error (522, loc,
2304 "structs cannot call base class constructors");
2308 t = ec.ContainerType;
2310 parent_constructor_group = Expression.MemberLookup (
2312 MemberTypes.Constructor,
2313 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
2316 if (parent_constructor_group == null){
2317 Report.Error (1501, loc,
2318 "Can not find a constructor for this argument list");
2322 parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (ec,
2323 (MethodGroupExpr) parent_constructor_group, argument_list, loc);
2325 if (parent_constructor == null){
2326 Report.Error (1501, loc,
2327 "Can not find a constructor for this argument list");
2334 public void Emit (EmitContext ec)
2336 if (parent_constructor != null)
2337 ec.ig.Emit (OpCodes.Ldarg_0);
2338 if (argument_list != null)
2339 Invocation.EmitArguments (ec, null, argument_list);
2340 if (parent_constructor != null)
2341 ec.ig.Emit (OpCodes.Call, parent_constructor);
2345 public class ConstructorBaseInitializer : ConstructorInitializer {
2346 public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
2347 base (argument_list, pars, l)
2352 public class ConstructorThisInitializer : ConstructorInitializer {
2353 public ConstructorThisInitializer (ArrayList argument_list, Parameters pars, Location l) :
2354 base (argument_list, pars, l)
2359 public class Constructor : MethodCore {
2360 public ConstructorBuilder ConstructorBuilder;
2361 public ConstructorInitializer Initializer;
2362 new public Attributes OptAttributes;
2365 // Modifiers allowed for a constructor.
2367 const int AllowedModifiers =
2369 Modifiers.PROTECTED |
2370 Modifiers.INTERNAL |
2376 // The spec claims that static is not permitted, but
2377 // my very own code has static constructors.
2379 public Constructor (string name, Parameters args, ConstructorInitializer init, Location l)
2380 : base (null, 0, AllowedModifiers, name, null, args, l)
2386 // Returns true if this is a default constructor
2388 public bool IsDefault ()
2390 if ((ModFlags & Modifiers.STATIC) != 0)
2391 return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
2392 (Parameters.ArrayParameter == null ? true : Parameters.Empty);
2395 return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
2396 (Parameters.ArrayParameter == null ? true : Parameters.Empty) &&
2397 (Initializer is ConstructorBaseInitializer) &&
2398 (Initializer.Arguments == null);
2402 // Creates the ConstructorBuilder
2404 public override bool Define (TypeContainer parent)
2406 MethodAttributes ca = (MethodAttributes.RTSpecialName |
2407 MethodAttributes.SpecialName);
2409 // Check if arguments were correct.
2410 if (!DoDefineParameters (parent))
2413 if ((ModFlags & Modifiers.STATIC) != 0)
2414 ca |= MethodAttributes.Static;
2416 if (parent is Struct && ParameterTypes.Length == 0){
2419 "Structs can not contain explicit parameterless " +
2423 ca |= MethodAttributes.Public | MethodAttributes.HideBySig;
2426 ConstructorBuilder = parent.TypeBuilder.DefineConstructor (
2427 ca, GetCallingConvention (parent is Class), ParameterTypes);
2430 // HACK because System.Reflection.Emit is lame
2432 if (!TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes)) {
2435 "Class `" +parent.Name+ "' already contains a definition with the " +
2436 "same return value and parameter types for constructor `" + Name
2447 public void Emit (TypeContainer parent)
2449 ILGenerator ig = ConstructorBuilder.GetILGenerator ();
2450 EmitContext ec = new EmitContext (parent, Location, ig, null, ModFlags, true);
2452 if ((ModFlags & Modifiers.STATIC) == 0){
2453 if (parent is Class && Initializer == null)
2454 Initializer = new ConstructorBaseInitializer (
2455 null, Parameters.EmptyReadOnlyParameters, parent.Location);
2459 // Spec mandates that Initializers will not have
2463 if (Initializer != null && !Initializer.Resolve (ec))
2465 ec.IsStatic = false;
2468 LabelParameters (ec, ParameterTypes, ConstructorBuilder);
2471 // Classes can have base initializers and instance field initializers.
2473 if (parent is Class){
2474 if ((ModFlags & Modifiers.STATIC) == 0)
2475 parent.EmitFieldInitializers (ec);
2477 if (Initializer != null)
2478 Initializer.Emit (ec);
2480 if ((ModFlags & Modifiers.STATIC) != 0)
2481 parent.EmitFieldInitializers (ec);
2483 Attribute.ApplyAttributes (ec, ConstructorBuilder, this, OptAttributes, Location);
2485 // If this is a non-static `struct' constructor and doesn't have any
2486 // initializer, it must initialize all of the struct's fields.
2487 if ((parent is Struct) && ((ModFlags & Modifiers.STATIC) == 0) &&
2488 (Initializer == null))
2489 Block.AddThisVariable (parent, Location);
2491 ec.EmitTopBlock (Block, ParameterInfo, Location);
2495 public class MethodData {
2497 // The return type of this method
2499 public readonly Type ReturnType;
2500 public readonly Type[] ParameterTypes;
2501 public readonly InternalParameters ParameterInfo;
2502 public readonly CallingConventions CallingConventions;
2503 public readonly Attributes OptAttributes;
2504 public readonly Location Location;
2507 // Are we implementing an interface ?
2509 public bool IsImplementing = false;
2514 protected MemberBase member;
2515 protected int modifiers;
2516 protected MethodAttributes flags;
2517 protected bool is_method;
2518 protected string accessor_name;
2519 ArrayList conditionals;
2521 MethodBuilder builder = null;
2522 public MethodBuilder MethodBuilder {
2528 public MethodData (MemberBase member, string name, Type return_type,
2529 Type [] parameter_types, InternalParameters parameters,
2530 CallingConventions cc, Attributes opt_attrs,
2531 int modifiers, MethodAttributes flags, bool is_method)
2533 this.member = member;
2534 this.accessor_name = name;
2535 this.ReturnType = return_type;
2536 this.ParameterTypes = parameter_types;
2537 this.ParameterInfo = parameters;
2538 this.CallingConventions = cc;
2539 this.OptAttributes = opt_attrs;
2540 this.modifiers = modifiers;
2542 this.is_method = is_method;
2543 this.Location = member.Location;
2544 this.conditionals = new ArrayList ();
2550 Attribute dllimport_attribute = null;
2551 string obsolete = null;
2552 bool obsolete_error = false;
2554 public virtual bool ApplyAttributes (Attributes opt_attrs, bool is_method)
2556 if ((opt_attrs == null) || (opt_attrs.AttributeSections == null))
2559 foreach (AttributeSection asec in opt_attrs.AttributeSections) {
2560 if (asec.Attributes == null)
2563 foreach (Attribute a in asec.Attributes) {
2564 if (a.Name == "Conditional") {
2565 if (!ApplyConditionalAttribute (a))
2567 } else if (a.Name == "Obsolete") {
2568 if (!ApplyObsoleteAttribute (a))
2570 } else if (a.Name.IndexOf ("DllImport") != -1) {
2572 a.Type = TypeManager.dllimport_type;
2573 Attribute.Error_AttributeNotValidForElement (a, Location);
2576 if (!ApplyDllImportAttribute (a))
2586 // Applies the `DllImport' attribute to the method.
2588 protected virtual bool ApplyDllImportAttribute (Attribute a)
2590 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
2591 if ((modifiers & extern_static) != extern_static) {
2592 Report.Error (601, Location,
2593 "The DllImport attribute must be specified on a method " +
2594 "marked `static' and `extern'.");
2598 flags |= MethodAttributes.PinvokeImpl;
2599 dllimport_attribute = a;
2604 // Applies the `Obsolete' attribute to the method.
2606 protected virtual bool ApplyObsoleteAttribute (Attribute a)
2608 if (obsolete != null) {
2609 Report.Error (579, Location, "Duplicate `Obsolete' attribute");
2613 obsolete = a.Obsolete_GetObsoleteMessage (out obsolete_error);
2614 return obsolete != null;
2618 // Applies the `Conditional' attribute to the method.
2620 protected virtual bool ApplyConditionalAttribute (Attribute a)
2622 // The Conditional attribute is only valid on methods.
2624 Attribute.Error_AttributeNotValidForElement (a, Location);
2628 string condition = a.Conditional_GetConditionName ();
2630 if (condition == null)
2633 if (ReturnType != TypeManager.void_type) {
2634 Report.Error (578, Location,
2635 "Conditional not valid on `" + member.Name + "' " +
2636 "because its return type is not void");
2640 if ((modifiers & Modifiers.OVERRIDE) != 0) {
2641 Report.Error (243, Location,
2642 "Conditional not valid on `" + member.Name + "' " +
2643 "because it is an override method");
2647 if (member.IsExplicitImpl) {
2648 Report.Error (577, Location,
2649 "Conditional not valid on `" + member.Name + "' " +
2650 "because it is an explicit interface implementation");
2654 if (IsImplementing) {
2655 Report.Error (623, Location,
2656 "Conditional not valid on `" + member.Name + "' " +
2657 "because it is an interface method");
2661 conditionals.Add (condition);
2667 // Checks whether this method should be ignored due to its Conditional attributes.
2669 bool ShouldIgnore (Location loc)
2671 // When we're overriding a virtual method, we implicitly inherit the
2672 // Conditional attributes from our parent.
2673 if (member.ParentMethod != null) {
2674 TypeManager.MethodFlags flags = TypeManager.GetMethodFlags (
2675 member.ParentMethod, loc);
2677 if ((flags & TypeManager.MethodFlags.ShouldIgnore) != 0)
2681 foreach (string condition in conditionals)
2682 if (RootContext.AllDefines [condition] == null)
2689 // Returns the TypeManager.MethodFlags for this method.
2690 // This emits an error 619 / warning 618 if the method is obsolete.
2691 // In the former case, TypeManager.MethodFlags.IsObsoleteError is returned.
2693 public virtual TypeManager.MethodFlags GetMethodFlags (Location loc)
2695 TypeManager.MethodFlags flags = 0;
2697 if (obsolete != null) {
2698 if (obsolete_error) {
2699 Report.Error (619, loc, "Method `" + member.Name +
2700 "' is obsolete: `" + obsolete + "'");
2701 return TypeManager.MethodFlags.IsObsoleteError;
2703 Report.Warning (618, loc, "Method `" + member.Name +
2704 "' is obsolete: `" + obsolete + "'");
2706 flags |= TypeManager.MethodFlags.IsObsolete;
2709 if (ShouldIgnore (loc))
2710 flags |= TypeManager.MethodFlags.ShouldIgnore;
2715 public virtual bool Define (TypeContainer parent)
2717 MethodInfo implementing = null;
2718 string method_name, name, prefix;
2720 if (OptAttributes != null)
2721 if (!ApplyAttributes (OptAttributes, is_method))
2724 if (member.IsExplicitImpl)
2725 prefix = member.InterfaceType.FullName + ".";
2729 if (accessor_name != null)
2730 name = accessor_name + "_" + member.ShortName;
2732 name = member.ShortName;
2733 method_name = prefix + name;
2735 if (parent.Pending != null){
2736 if (member is Indexer)
2737 implementing = parent.Pending.IsInterfaceIndexer (
2738 member.InterfaceType, ReturnType, ParameterTypes);
2740 implementing = parent.Pending.IsInterfaceMethod (
2741 member.InterfaceType, name, ReturnType, ParameterTypes);
2743 if (member.InterfaceType != null && implementing == null){
2744 TypeContainer.Error_ExplicitInterfaceNotMemberInterface (
2751 // For implicit implementations, make sure we are public, for
2752 // explicit implementations, make sure we are private.
2754 if (implementing != null){
2756 // Setting null inside this block will trigger a more
2757 // verbose error reporting for missing interface implementations
2759 // The "candidate" function has been flagged already
2760 // but it wont get cleared
2762 if (!member.IsExplicitImpl){
2764 // We already catch different accessibility settings
2765 // so we just need to check that we are not private
2767 if ((modifiers & Modifiers.PRIVATE) != 0)
2768 implementing = null;
2771 // Static is not allowed
2773 if ((modifiers & Modifiers.STATIC) != 0)
2774 implementing = null;
2776 if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
2777 Modifiers.Error_InvalidModifier (Location, "public, virtual or abstract");
2778 implementing = null;
2784 // If implementing is still valid, set flags
2786 if (implementing != null){
2788 // When implementing interface methods, set NewSlot.
2790 if (implementing.DeclaringType.IsInterface)
2791 flags |= MethodAttributes.NewSlot;
2794 MethodAttributes.Virtual |
2795 MethodAttributes.HideBySig;
2797 // Get the method name from the explicit interface.
2798 if (member.InterfaceType != null) {
2799 name = implementing.Name;
2800 method_name = prefix + name;
2803 IsImplementing = true;
2807 // Create the MethodBuilder for the method
2809 if ((flags & MethodAttributes.PinvokeImpl) != 0) {
2810 if ((modifiers & Modifiers.STATIC) == 0) {
2811 Report.Error (601, Location,
2812 "The DllImport attribute must be specified on " +
2813 "a method marked 'static' and 'extern'.");
2817 EmitContext ec = new EmitContext (
2818 parent, Location, null, ReturnType, modifiers);
2820 builder = dllimport_attribute.DefinePInvokeMethod (
2821 ec, parent.TypeBuilder, method_name, flags,
2822 ReturnType, ParameterTypes);
2824 builder = parent.TypeBuilder.DefineMethod (
2825 method_name, flags, CallingConventions,
2826 ReturnType, ParameterTypes);
2828 if (builder == null)
2831 if (IsImplementing) {
2833 // clear the pending implemntation flag
2835 if (member is Indexer) {
2836 parent.Pending.ImplementIndexer (
2837 member.InterfaceType, builder, ReturnType,
2838 ParameterTypes, true);
2840 parent.Pending.ImplementMethod (
2841 member.InterfaceType, name, ReturnType,
2842 ParameterTypes, member.IsExplicitImpl);
2844 if (member.IsExplicitImpl)
2845 parent.TypeBuilder.DefineMethodOverride (
2846 builder, implementing);
2849 if (!TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes)) {
2850 Report.Error (111, Location,
2851 "Class `" + parent.Name +
2852 "' already contains a definition with the " +
2853 "same return value and parameter types as the " +
2854 "'get' method of property `" + member.Name + "'");
2858 TypeManager.AddMethod (builder, this);
2866 public virtual void Emit (TypeContainer parent, Block block, object kind)
2871 if ((flags & MethodAttributes.PinvokeImpl) == 0)
2872 ig = builder.GetILGenerator ();
2876 ec = new EmitContext (parent, Location, ig, ReturnType, modifiers);
2878 if (OptAttributes != null)
2879 Attribute.ApplyAttributes (ec, builder, kind, OptAttributes, Location);
2881 if (member is MethodCore)
2882 ((MethodCore) member).LabelParameters (ec, ParameterTypes, MethodBuilder);
2885 // abstract or extern methods have no bodies
2887 if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
2892 // abstract or extern methods have no bodies.
2894 if ((modifiers & Modifiers.ABSTRACT) != 0)
2896 500, Location, "Abstract method `" +
2897 TypeManager.CSharpSignature (builder) +
2898 "' can not have a body");
2900 if ((modifiers & Modifiers.EXTERN) != 0)
2902 179, Location, "External method `" +
2903 TypeManager.CSharpSignature (builder) +
2904 "' can not have a body");
2910 // Methods must have a body unless they're extern or abstract
2912 if (block == null) {
2914 501, Location, "Method `" +
2915 TypeManager.CSharpSignature (builder) +
2916 "' must declare a body since it is not marked " +
2917 "abstract or extern");
2922 // Handle destructors specially
2924 // FIXME: This code generates buggy code
2926 if (member.Name == "Finalize" && ReturnType == TypeManager.void_type)
2927 EmitDestructor (ec, block);
2929 ISymbolWriter sw = CodeGen.SymbolWriter;
2931 if ((sw != null) && !Location.IsNull (Location) &&
2932 !Location.IsNull (block.EndLocation)) {
2933 Location end = block.EndLocation;
2934 MethodToken token = MethodBuilder.GetToken ();
2935 sw.OpenMethod (new SymbolToken (token.Token));
2936 sw.SetMethodSourceRange (Location.SymbolDocument,
2941 ec.EmitTopBlock (block, ParameterInfo, Location);
2945 ec.EmitTopBlock (block, ParameterInfo, Location);
2949 void EmitDestructor (EmitContext ec, Block block)
2951 ILGenerator ig = ec.ig;
2953 Label finish = ig.DefineLabel ();
2954 bool old_in_try = ec.InTry;
2956 ig.BeginExceptionBlock ();
2958 ec.ReturnLabel = finish;
2959 ec.HasReturnLabel = true;
2960 ec.EmitTopBlock (block, null, Location);
2961 ec.InTry = old_in_try;
2963 // ig.MarkLabel (finish);
2964 bool old_in_finally = ec.InFinally;
2965 ec.InFinally = true;
2966 ig.BeginFinallyBlock ();
2968 if (ec.ContainerType.BaseType != null) {
2969 Expression member_lookup = Expression.MemberLookup (
2970 ec, ec.ContainerType.BaseType, "Finalize",
2971 MemberTypes.Method, Expression.AllBindingFlags, Location);
2973 if (member_lookup != null){
2974 MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
2976 ig.Emit (OpCodes.Ldarg_0);
2977 ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
2980 ec.InFinally = old_in_finally;
2982 ig.EndExceptionBlock ();
2983 //ig.MarkLabel (ec.ReturnLabel);
2984 ig.Emit (OpCodes.Ret);
2988 abstract public class MemberBase : MemberCore {
2989 public Expression Type;
2990 public readonly Attributes OptAttributes;
2992 protected MethodAttributes flags;
2995 // The "short" name of this property / indexer / event. This is the
2996 // name without the explicit interface.
2998 public string ShortName;
3001 // The type of this property / indexer / event
3003 public Type MemberType;
3006 // If true, this is an explicit interface implementation
3008 public bool IsExplicitImpl = false;
3011 // The name of the interface we are explicitly implementing
3013 public string ExplicitInterfaceName = null;
3016 // If true, the interface type we are explicitly implementing
3018 public Type InterfaceType = null;
3021 // The method we're overriding if this is an override method.
3023 protected MethodInfo parent_method = null;
3024 public MethodInfo ParentMethod {
3026 return parent_method;
3031 // The constructor is only exposed to our children
3033 protected MemberBase (Expression type, int mod, int allowed_mod, string name,
3034 Attributes attrs, Location loc)
3038 ModFlags = Modifiers.Check (allowed_mod, mod, Modifiers.PRIVATE, loc);
3039 OptAttributes = attrs;
3042 protected virtual bool CheckBase (TypeContainer parent)
3047 protected virtual bool CheckParameters (TypeContainer parent, Type [] parameters)
3051 foreach (Type partype in parameters){
3052 if (partype.IsPointer && !UnsafeOK (parent))
3055 if (parent.AsAccessible (partype, ModFlags))
3058 if (this is Indexer)
3059 Report.Error (55, Location,
3060 "Inconsistent accessibility: parameter type `" +
3061 TypeManager.CSharpName (partype) + "' is less " +
3062 "accessible than indexer `" + Name + "'");
3064 Report.Error (51, Location,
3065 "Inconsistent accessibility: parameter type `" +
3066 TypeManager.CSharpName (partype) + "' is less " +
3067 "accessible than method `" + Name + "'");
3074 protected virtual bool DoDefine (TypeContainer parent)
3079 if (!parent.MethodModifiersValid (ModFlags, Name, Location))
3082 flags = Modifiers.MethodAttr (ModFlags);
3084 // Lookup Type, verify validity
3085 MemberType = parent.ResolveType (Type, false, Location);
3086 if (MemberType == null)
3089 // verify accessibility
3090 if (!parent.AsAccessible (MemberType, ModFlags)) {
3091 if (this is Property)
3092 Report.Error (53, Location,
3093 "Inconsistent accessibility: property type `" +
3094 TypeManager.CSharpName (MemberType) + "' is less " +
3095 "accessible than property `" + Name + "'");
3096 else if (this is Indexer)
3097 Report.Error (54, Location,
3098 "Inconsistent accessibility: indexer return type `" +
3099 TypeManager.CSharpName (MemberType) + "' is less " +
3100 "accessible than indexer `" + Name + "'");
3101 else if (this is Method)
3102 Report.Error (50, Location,
3103 "Inconsistent accessibility: return type `" +
3104 TypeManager.CSharpName (MemberType) + "' is less " +
3105 "accessible than method `" + Name + "'");
3107 Report.Error (52, Location,
3108 "Inconsistent accessibility: field type `" +
3109 TypeManager.CSharpName (MemberType) + "' is less " +
3110 "accessible than field `" + Name + "'");
3114 if (MemberType.IsPointer && !UnsafeOK (parent))
3118 // Check for explicit interface implementation
3120 if ((ExplicitInterfaceName == null) && (Name.IndexOf (".") != -1)){
3121 int pos = Name.LastIndexOf (".");
3123 ExplicitInterfaceName = Name.Substring (0, pos);
3124 ShortName = Name.Substring (pos + 1);
3128 if (ExplicitInterfaceName != null) {
3129 InterfaceType = RootContext.LookupType (
3130 parent, ExplicitInterfaceName, false, Location);
3131 if (InterfaceType == null)
3134 // Compute the full name that we need to export.
3135 Name = InterfaceType.FullName + "." + ShortName;
3137 if (!parent.VerifyImplements (InterfaceType, ShortName, Name, Location))
3140 IsExplicitImpl = true;
3142 IsExplicitImpl = false;
3149 // Fields and Events both generate FieldBuilders, we use this to share
3150 // their common bits. This is also used to flag usage of the field
3152 abstract public class FieldBase : MemberBase {
3153 public FieldBuilder FieldBuilder;
3154 public Status status;
3157 public enum Status : byte { ASSIGNED = 1, USED = 2 }
3160 // The constructor is only exposed to our children
3162 protected FieldBase (Expression type, int mod, int allowed_mod, string name,
3163 object init, Attributes attrs, Location loc)
3164 : base (type, mod, allowed_mod, name, attrs, loc)
3170 // Whether this field has an initializer.
3172 public bool HasInitializer {
3174 return init != null;
3179 readonly Object init;
3180 Expression init_expr;
3181 bool init_expr_initialized = false;
3184 // Resolves and returns the field initializer.
3186 public Expression GetInitializerExpression (EmitContext ec)
3188 if (init_expr_initialized)
3192 if (init is Expression)
3193 e = (Expression) init;
3195 e = new ArrayCreation (Type, "", (ArrayList)init, Location);
3197 ec.IsFieldInitializer = true;
3198 e = e.DoResolve (ec);
3199 ec.IsFieldInitializer = false;
3202 init_expr_initialized = true;
3209 // The Field class is used to represents class/struct fields during parsing.
3211 public class Field : FieldBase {
3213 // Modifiers allowed in a class declaration
3215 const int AllowedModifiers =
3218 Modifiers.PROTECTED |
3219 Modifiers.INTERNAL |
3222 Modifiers.VOLATILE |
3226 public Field (Expression type, int mod, string name, Object expr_or_array_init,
3227 Attributes attrs, Location loc)
3228 : base (type, mod, AllowedModifiers, name, expr_or_array_init, attrs, loc)
3232 public override bool Define (TypeContainer parent)
3234 Type t = parent.ResolveType (Type, false, Location);
3239 if (!parent.AsAccessible (t, ModFlags)) {
3240 Report.Error (52, Location,
3241 "Inconsistent accessibility: field type `" +
3242 TypeManager.CSharpName (t) + "' is less " +
3243 "accessible than field `" + Name + "'");
3247 if (t.IsPointer && !UnsafeOK (parent))
3250 if (RootContext.WarningLevel > 1){
3251 Type ptype = parent.TypeBuilder.BaseType;
3253 // ptype is only null for System.Object while compiling corlib.
3255 TypeContainer.FindMembers (
3256 ptype, MemberTypes.Method,
3257 BindingFlags.Public |
3258 BindingFlags.Static | BindingFlags.Instance,
3259 System.Type.FilterName, Name);
3263 if ((ModFlags & Modifiers.VOLATILE) != 0){
3265 if (TypeManager.IsEnumType (t))
3266 t = TypeManager.EnumToUnderlying (t);
3268 if (!((t == TypeManager.bool_type) ||
3269 (t == TypeManager.sbyte_type) ||
3270 (t == TypeManager.byte_type) ||
3271 (t == TypeManager.short_type) ||
3272 (t == TypeManager.ushort_type) ||
3273 (t == TypeManager.int32_type) ||
3274 (t == TypeManager.uint32_type) ||
3275 (t == TypeManager.char_type) ||
3276 (t == TypeManager.float_type))){
3278 677, Location, parent.MakeName (Name) +
3279 " A volatile field can not be of type `" +
3280 TypeManager.CSharpName (t) + "'");
3286 FieldBuilder = parent.TypeBuilder.DefineField (
3287 Name, t, Modifiers.FieldAttr (ModFlags));
3289 TypeManager.RegisterFieldBase (FieldBuilder, this);
3293 public void Emit (TypeContainer tc)
3295 EmitContext ec = new EmitContext (tc, Location, null,
3296 FieldBuilder.FieldType, ModFlags);
3298 Attribute.ApplyAttributes (ec, FieldBuilder, this, OptAttributes, Location);
3303 // `set' and `get' accessors are represented with an Accessor.
3305 public class Accessor {
3307 // Null if the accessor is empty, or a Block if not
3310 public Attributes OptAttributes;
3312 public Accessor (Block b, Attributes attrs)
3315 OptAttributes = attrs;
3320 // Properties and Indexers both generate PropertyBuilders, we use this to share
3321 // their common bits.
3323 abstract public class PropertyBase : MethodCore {
3324 public Accessor Get, Set;
3325 public PropertyBuilder PropertyBuilder;
3326 public MethodBuilder GetBuilder, SetBuilder;
3327 public MethodData GetData, SetData;
3329 protected EmitContext ec;
3331 public PropertyBase (Expression type, string name, int mod_flags, int allowed_mod,
3332 Parameters parameters, Accessor get_block, Accessor set_block,
3333 Attributes attrs, Location loc)
3334 : base (type, mod_flags, allowed_mod, name, attrs, parameters, loc)
3340 protected override bool DoDefine (TypeContainer parent)
3342 if (!base.DoDefine (parent))
3345 ec = new EmitContext (parent, Location, null, MemberType, ModFlags);
3351 // Checks our base implementation if any
3353 protected override bool CheckBase (TypeContainer parent)
3355 // Check whether arguments were correct.
3356 if (!DoDefineParameters (parent))
3359 MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
3360 MemberList props_this;
3362 props_this = TypeContainer.FindMembers (
3363 parent.TypeBuilder, MemberTypes.Property,
3364 BindingFlags.NonPublic | BindingFlags.Public |
3365 BindingFlags.Static | BindingFlags.Instance |
3366 BindingFlags.DeclaredOnly,
3367 MethodSignature.method_signature_filter, ms);
3369 if (props_this.Count > 0) {
3370 Report.Error (111, Location, "Class `" + parent.Name + "' " +
3371 "already defines a member called `" + Name + "' " +
3372 "with the same parameter types");
3377 // Find properties with the same name on the base class
3380 MemberList props_static = TypeContainer.FindMembers (
3381 parent.TypeBuilder.BaseType, MemberTypes.Property,
3382 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static,
3383 MethodSignature.inheritable_property_signature_filter, ms);
3385 MemberList props_instance = TypeContainer.FindMembers (
3386 parent.TypeBuilder.BaseType, MemberTypes.Property,
3387 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
3388 MethodSignature.inheritable_property_signature_filter,
3392 // Find if we have anything
3394 if (props_static.Count > 0)
3395 props = props_static;
3396 else if (props_instance.Count > 0)
3397 props = props_instance;
3402 // If we have something on the base.
3403 if (props != null && props.Count > 0){
3404 PropertyInfo pi = (PropertyInfo) props [0];
3406 MethodInfo inherited_get = TypeManager.GetPropertyGetter (pi);
3407 MethodInfo inherited_set = TypeManager.GetPropertySetter (pi);
3409 MethodInfo reference = inherited_get == null ?
3410 inherited_set : inherited_get;
3412 if (reference != null) {
3413 string name = reference.DeclaringType.Name + "." + Name;
3415 if (!CheckMethodAgainstBase (parent, flags, reference, name))
3419 if (((ModFlags & Modifiers.NEW) == 0) && (pi.PropertyType != MemberType)) {
3420 Report.Error (508, parent.MakeName (Name) + ": cannot " +
3421 "change return type when overriding inherited " +
3422 "member `" + pi.DeclaringType + "." + pi.Name + "'");
3426 if ((ModFlags & Modifiers.NEW) != 0)
3427 WarningNotHiding (parent);
3429 if ((ModFlags & Modifiers.OVERRIDE) != 0){
3430 if (this is Indexer)
3431 Report.Error (115, Location,
3432 parent.MakeName (Name) +
3433 " no suitable indexers found to override");
3435 Report.Error (115, Location,
3436 parent.MakeName (Name) +
3437 " no suitable properties found to override");
3444 public void Emit (TypeContainer tc)
3447 // The PropertyBuilder can be null for explicit implementations, in that
3448 // case, we do not actually emit the ".property", so there is nowhere to
3449 // put the attribute
3451 if (PropertyBuilder != null)
3452 Attribute.ApplyAttributes (ec, PropertyBuilder, this, OptAttributes, Location);
3454 if (GetData != null)
3455 GetData.Emit (tc, Get.Block, Get);
3457 if (SetData != null)
3458 SetData.Emit (tc, Set.Block, Set);
3462 public class Property : PropertyBase {
3463 const int AllowedModifiers =
3466 Modifiers.PROTECTED |
3467 Modifiers.INTERNAL |
3471 Modifiers.OVERRIDE |
3472 Modifiers.ABSTRACT |
3477 public Property (Expression type, string name, int mod_flags,
3478 Accessor get_block, Accessor set_block,
3479 Attributes attrs, Location loc)
3480 : base (type, name, mod_flags, AllowedModifiers,
3481 Parameters.EmptyReadOnlyParameters,
3482 get_block, set_block, attrs, loc)
3486 public override bool Define (TypeContainer parent)
3488 if (!DoDefine (parent))
3491 if (!CheckBase (parent))
3494 flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
3497 Type [] parameters = TypeManager.NoTypes;
3499 InternalParameters ip = new InternalParameters (
3500 parent, Parameters.EmptyReadOnlyParameters);
3502 GetData = new MethodData (this, "get", MemberType,
3503 parameters, ip, CallingConventions.Standard,
3504 Get.OptAttributes, ModFlags, flags, false);
3506 if (!GetData.Define (parent))
3509 GetBuilder = GetData.MethodBuilder;
3513 Type [] parameters = new Type [1];
3514 parameters [0] = MemberType;
3516 Parameter [] parms = new Parameter [1];
3517 parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
3518 InternalParameters ip = new InternalParameters (
3519 parent, new Parameters (parms, null, Location));
3521 SetData = new MethodData (this, "set", TypeManager.void_type,
3522 parameters, ip, CallingConventions.Standard,
3523 Set.OptAttributes, ModFlags, flags, false);
3525 if (!SetData.Define (parent))
3528 SetBuilder = SetData.MethodBuilder;
3529 SetBuilder.DefineParameter (1, ParameterAttributes.None, "value");
3532 // FIXME - PropertyAttributes.HasDefault ?
3534 PropertyAttributes prop_attr =
3535 PropertyAttributes.RTSpecialName |
3536 PropertyAttributes.SpecialName;
3538 if (!IsExplicitImpl){
3539 PropertyBuilder = parent.TypeBuilder.DefineProperty (
3540 Name, prop_attr, MemberType, null);
3543 PropertyBuilder.SetGetMethod (GetBuilder);
3546 PropertyBuilder.SetSetMethod (SetBuilder);
3549 // HACK for the reasons exposed above
3551 if (!TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder)) {
3554 "Class `" + parent.Name +
3555 "' already contains a definition for the property `" +
3565 /// Gigantic workaround for lameness in SRE follows :
3566 /// This class derives from EventInfo and attempts to basically
3567 /// wrap around the EventBuilder so that FindMembers can quickly
3568 /// return this in it search for members
3570 public class MyEventBuilder : EventInfo {
3573 // We use this to "point" to our Builder which is
3574 // not really a MemberInfo
3576 EventBuilder MyBuilder;
3579 // We "catch" and wrap these methods
3581 MethodInfo raise, remove, add;
3583 EventAttributes attributes;
3584 Type declaring_type, reflected_type, event_type;
3587 public MyEventBuilder (TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
3589 MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
3591 // And now store the values in our own fields.
3593 declaring_type = type_builder;
3595 reflected_type = type_builder;
3597 attributes = event_attr;
3599 this.event_type = event_type;
3603 // Methods that you have to override. Note that you only need
3604 // to "implement" the variants that take the argument (those are
3605 // the "abstract" methods, the others (GetAddMethod()) are
3608 public override MethodInfo GetAddMethod (bool nonPublic)
3613 public override MethodInfo GetRemoveMethod (bool nonPublic)
3618 public override MethodInfo GetRaiseMethod (bool nonPublic)
3624 // These methods make "MyEventInfo" look like a Builder
3626 public void SetRaiseMethod (MethodBuilder raiseMethod)
3628 raise = raiseMethod;
3629 MyBuilder.SetRaiseMethod (raiseMethod);
3632 public void SetRemoveOnMethod (MethodBuilder removeMethod)
3634 remove = removeMethod;
3635 MyBuilder.SetRemoveOnMethod (removeMethod);
3638 public void SetAddOnMethod (MethodBuilder addMethod)
3641 MyBuilder.SetAddOnMethod (addMethod);
3644 public void SetCustomAttribute (CustomAttributeBuilder cb)
3646 MyBuilder.SetCustomAttribute (cb);
3649 public override object [] GetCustomAttributes (bool inherit)
3651 // FIXME : There's nothing which can be seemingly done here because
3652 // we have no way of getting at the custom attribute objects of the
3657 public override object [] GetCustomAttributes (Type t, bool inherit)
3659 // FIXME : Same here !
3663 public override bool IsDefined (Type t, bool b)
3668 public override EventAttributes Attributes {
3674 public override string Name {
3680 public override Type DeclaringType {
3682 return declaring_type;
3686 public override Type ReflectedType {
3688 return reflected_type;
3692 public Type EventType {
3699 public class Event : FieldBase {
3700 const int AllowedModifiers =
3703 Modifiers.PROTECTED |
3704 Modifiers.INTERNAL |
3709 Modifiers.OVERRIDE |
3713 public readonly Accessor Add;
3714 public readonly Accessor Remove;
3715 public MyEventBuilder EventBuilder;
3717 MethodBuilder AddBuilder, RemoveBuilder;
3718 MethodData AddData, RemoveData;
3720 public Event (Expression type, string name, Object init, int mod, Accessor add,
3721 Accessor remove, Attributes attrs, Location loc)
3722 : base (type, mod, AllowedModifiers, name, init, attrs, loc)
3728 public override bool Define (TypeContainer parent)
3730 EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
3732 if (!DoDefine (parent))
3735 if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
3736 Report.Error (66, Location, "'" + parent.Name + "." + Name +
3737 "' : event must be of a delegate type");
3741 Type [] parameter_types = new Type [1];
3742 parameter_types [0] = MemberType;
3744 Parameter [] parms = new Parameter [1];
3745 parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
3746 InternalParameters ip = new InternalParameters (
3747 parent, new Parameters (parms, null, Location));
3749 if (!CheckBase (parent))
3753 // Now define the accessors
3755 AddData = new MethodData (this, "add", TypeManager.void_type,
3756 parameter_types, ip, CallingConventions.Standard,
3757 (Add != null) ? Add.OptAttributes : null,
3758 ModFlags, flags, false);
3760 if (!AddData.Define (parent))
3763 AddBuilder = AddData.MethodBuilder;
3764 AddBuilder.DefineParameter (1, ParameterAttributes.None, "value");
3766 RemoveData = new MethodData (this, "remove", TypeManager.void_type,
3767 parameter_types, ip, CallingConventions.Standard,
3768 (Remove != null) ? Remove.OptAttributes : null,
3769 ModFlags, flags, false);
3771 if (!RemoveData.Define (parent))
3774 RemoveBuilder = RemoveData.MethodBuilder;
3775 RemoveBuilder.DefineParameter (1, ParameterAttributes.None, "value");
3777 if (!IsExplicitImpl){
3778 EventBuilder = new MyEventBuilder (
3779 parent.TypeBuilder, Name, e_attr, MemberType);
3781 if (Add == null && Remove == null) {
3782 FieldBuilder = parent.TypeBuilder.DefineField (
3783 Name, MemberType, FieldAttributes.FamANDAssem);
3784 TypeManager.RegisterPrivateFieldOfEvent (
3785 (EventInfo) EventBuilder, FieldBuilder);
3786 TypeManager.RegisterFieldBase (FieldBuilder, this);
3789 EventBuilder.SetAddOnMethod (AddBuilder);
3790 EventBuilder.SetRemoveOnMethod (RemoveBuilder);
3792 if (!TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder)) {
3793 Report.Error (111, Location,
3794 "Class `" + parent.Name +
3795 "' already contains a definition for the event `" +
3804 void EmitDefaultMethod (EmitContext ec, bool is_add)
3806 ILGenerator ig = ec.ig;
3807 MethodInfo method = null;
3810 method = TypeManager.delegate_combine_delegate_delegate;
3812 method = TypeManager.delegate_remove_delegate_delegate;
3814 if ((ModFlags & Modifiers.STATIC) != 0) {
3815 ig.Emit (OpCodes.Ldsfld, (FieldInfo) FieldBuilder);
3816 ig.Emit (OpCodes.Ldarg_0);
3817 ig.Emit (OpCodes.Call, method);
3818 ig.Emit (OpCodes.Castclass, MemberType);
3819 ig.Emit (OpCodes.Stsfld, (FieldInfo) FieldBuilder);
3821 ig.Emit (OpCodes.Ldarg_0);
3822 ig.Emit (OpCodes.Ldarg_0);
3823 ig.Emit (OpCodes.Ldfld, (FieldInfo) FieldBuilder);
3824 ig.Emit (OpCodes.Ldarg_1);
3825 ig.Emit (OpCodes.Call, method);
3826 ig.Emit (OpCodes.Castclass, MemberType);
3827 ig.Emit (OpCodes.Stfld, (FieldInfo) FieldBuilder);
3829 ig.Emit (OpCodes.Ret);
3832 public void Emit (TypeContainer tc)
3836 ec = new EmitContext (tc, Location, null, MemberType, ModFlags);
3837 Attribute.ApplyAttributes (ec, EventBuilder, this, OptAttributes, Location);
3840 AddData.Emit (tc, Add.Block, Add);
3842 ILGenerator ig = AddData.MethodBuilder.GetILGenerator ();
3843 ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
3844 EmitDefaultMethod (ec, true);
3848 RemoveData.Emit (tc, Remove.Block, Remove);
3850 ILGenerator ig = RemoveData.MethodBuilder.GetILGenerator ();
3851 ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
3852 EmitDefaultMethod (ec, false);
3859 // FIXME: This does not handle:
3861 // int INTERFACENAME [ args ]
3866 // int this [ args ]
3868 public class Indexer : PropertyBase {
3870 const int AllowedModifiers =
3873 Modifiers.PROTECTED |
3874 Modifiers.INTERNAL |
3878 Modifiers.OVERRIDE |
3883 public string IndexerName;
3884 public string InterfaceIndexerName;
3887 // Are we implementing an interface ?
3889 bool IsImplementing = false;
3891 public Indexer (Expression type, string int_type, int flags, Parameters parameters,
3892 Accessor get_block, Accessor set_block, Attributes attrs, Location loc)
3893 : base (type, "", flags, AllowedModifiers, parameters, get_block, set_block,
3896 ExplicitInterfaceName = int_type;
3899 public override bool Define (TypeContainer parent)
3901 PropertyAttributes prop_attr =
3902 PropertyAttributes.RTSpecialName |
3903 PropertyAttributes.SpecialName;
3905 if (!DoDefine (parent))
3908 IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
3909 if (IndexerName == null)
3910 IndexerName = "Item";
3911 else if (IsExplicitImpl)
3912 Report.Error (592, Location,
3913 "Attribute 'IndexerName' is not valid on this declaration " +
3914 "type. It is valid on `property' declarations only.");
3916 ShortName = IndexerName;
3917 if (IsExplicitImpl) {
3918 InterfaceIndexerName = TypeManager.IndexerPropertyName (InterfaceType);
3919 Name = InterfaceType.FullName + "." + IndexerName;
3921 InterfaceIndexerName = IndexerName;
3925 if (!CheckBase (parent))
3929 InternalParameters ip = new InternalParameters (parent, Parameters);
3931 GetData = new MethodData (this, "get", MemberType,
3932 ParameterTypes, ip, CallingConventions.Standard,
3933 Get.OptAttributes, ModFlags, flags, false);
3935 if (!GetData.Define (parent))
3938 GetBuilder = GetData.MethodBuilder;
3942 int top = ParameterTypes.Length;
3943 Type [] set_pars = new Type [top + 1];
3944 ParameterTypes.CopyTo (set_pars, 0);
3945 set_pars [top] = MemberType;
3947 Parameter [] fixed_parms = Parameters.FixedParameters;
3949 if (fixed_parms == null){
3950 throw new Exception ("We currently do not support only array arguments in an indexer");
3951 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
3952 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
3954 // Here is the problem: the `value' parameter has
3955 // to come *after* the array parameter in the declaration
3957 // X (object [] x, Type value)
3960 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
3961 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
3965 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
3968 fixed_parms.CopyTo (tmp, 0);
3969 tmp [fixed_parms.Length] = new Parameter (
3970 Type, "value", Parameter.Modifier.NONE, null);
3972 Parameters set_formal_params = new Parameters (tmp, null, Location);
3974 InternalParameters ip = new InternalParameters (parent, set_formal_params);
3976 SetData = new MethodData (this, "set", TypeManager.void_type,
3977 set_pars, ip, CallingConventions.Standard,
3978 Set.OptAttributes, ModFlags, flags, false);
3980 if (!SetData.Define (parent))
3983 SetBuilder = SetData.MethodBuilder;
3987 // Now name the parameters
3989 Parameter [] p = Parameters.FixedParameters;
3993 for (i = 0; i < p.Length; ++i) {
3995 GetBuilder.DefineParameter (
3996 i + 1, p [i].Attributes, p [i].Name);
3999 SetBuilder.DefineParameter (
4000 i + 1, p [i].Attributes, p [i].Name);
4004 SetBuilder.DefineParameter (
4005 i + 1, ParameterAttributes.None, "value");
4007 if (i != ParameterTypes.Length) {
4008 Parameter array_param = Parameters.ArrayParameter;
4009 SetBuilder.DefineParameter (
4010 i + 1, array_param.Attributes, array_param.Name);
4014 if (GetData != null)
4015 IsImplementing = GetData.IsImplementing;
4016 else if (SetData != null)
4017 IsImplementing = SetData.IsImplementing;
4020 // Define the PropertyBuilder if one of the following conditions are met:
4021 // a) we're not implementing an interface indexer.
4022 // b) the indexer has a different IndexerName and this is no
4023 // explicit interface implementation.
4025 if (!IsExplicitImpl) {
4026 PropertyBuilder = parent.TypeBuilder.DefineProperty (
4027 IndexerName, prop_attr, MemberType, ParameterTypes);
4029 if (GetData != null)
4030 PropertyBuilder.SetGetMethod (GetBuilder);
4032 if (SetData != null)
4033 PropertyBuilder.SetSetMethod (SetBuilder);
4035 TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
4043 public class Operator : MemberCore {
4045 const int AllowedModifiers =
4051 const int RequiredModifiers =
4055 public enum OpType : byte {
4065 // Unary and Binary operators
4088 // Implicit and Explicit
4093 public readonly OpType OperatorType;
4094 public readonly Expression ReturnType;
4095 public readonly Expression FirstArgType, SecondArgType;
4096 public readonly string FirstArgName, SecondArgName;
4097 public readonly Block Block;
4098 public Attributes OptAttributes;
4099 public MethodBuilder OperatorMethodBuilder;
4101 public string MethodName;
4102 public Method OperatorMethod;
4104 public Operator (OpType type, Expression ret_type, int flags,
4105 Expression arg1type, string arg1name,
4106 Expression arg2type, string arg2name,
4107 Block block, Attributes attrs, Location loc)
4110 OperatorType = type;
4111 ReturnType = ret_type;
4112 ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PUBLIC, loc);
4113 FirstArgType = arg1type;
4114 FirstArgName = arg1name;
4115 SecondArgType = arg2type;
4116 SecondArgName = arg2name;
4118 OptAttributes = attrs;
4121 string Prototype (TypeContainer parent)
4123 return parent.Name + ".operator " + OperatorType + " (" + FirstArgType + "," +
4124 SecondArgType + ")";
4127 public override bool Define (TypeContainer parent)
4130 MethodName = "op_" + OperatorType;
4132 if (SecondArgType != null)
4135 Parameter [] param_list = new Parameter [length];
4137 if ((ModFlags & RequiredModifiers) != RequiredModifiers){
4140 "User defined operators `" +
4141 Prototype (parent) +
4142 "' must be declared static and public");
4146 param_list[0] = new Parameter (FirstArgType, FirstArgName,
4147 Parameter.Modifier.NONE, null);
4148 if (SecondArgType != null)
4149 param_list[1] = new Parameter (SecondArgType, SecondArgName,
4150 Parameter.Modifier.NONE, null);
4152 OperatorMethod = new Method (ReturnType, ModFlags, MethodName,
4153 new Parameters (param_list, null, Location),
4154 OptAttributes, Mono.CSharp.Location.Null);
4156 OperatorMethod.IsOperator = true;
4157 OperatorMethod.Define (parent);
4159 if (OperatorMethod.MethodBuilder == null)
4162 OperatorMethodBuilder = OperatorMethod.MethodBuilder;
4164 Type [] param_types = OperatorMethod.ParameterTypes;
4165 Type declaring_type = OperatorMethodBuilder.DeclaringType;
4166 Type return_type = OperatorMethod.GetReturnType (parent);
4167 Type first_arg_type = param_types [0];
4169 // Rules for conversion operators
4171 if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
4172 if (first_arg_type == return_type && first_arg_type == declaring_type){
4175 "User-defined conversion cannot take an object of the " +
4176 "enclosing type and convert to an object of the enclosing" +
4181 if (first_arg_type != declaring_type && return_type != declaring_type){
4184 "User-defined conversion must convert to or from the " +
4189 if (first_arg_type == TypeManager.object_type ||
4190 return_type == TypeManager.object_type){
4193 "User-defined conversion cannot convert to or from " +
4198 if (first_arg_type.IsInterface || return_type.IsInterface){
4201 "User-defined conversion cannot convert to or from an " +
4206 if (first_arg_type.IsSubclassOf (return_type) ||
4207 return_type.IsSubclassOf (first_arg_type)){
4210 "User-defined conversion cannot convert between types " +
4211 "that derive from each other");
4214 } else if (SecondArgType == null) {
4215 // Checks for Unary operators
4217 if (first_arg_type != declaring_type){
4220 "The parameter of a unary operator must be the " +
4225 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
4226 if (return_type != declaring_type){
4229 "The parameter and return type for ++ and -- " +
4230 "must be the containing type");
4236 if (OperatorType == OpType.True || OperatorType == OpType.False) {
4237 if (return_type != TypeManager.bool_type){
4240 "The return type of operator True or False " +
4247 // Checks for Binary operators
4249 if (first_arg_type != declaring_type &&
4250 param_types [1] != declaring_type){
4253 "One of the parameters of a binary operator must " +
4254 "be the containing type");
4262 public void Emit (TypeContainer parent)
4264 EmitContext ec = new EmitContext (parent, Location, null, null, ModFlags);
4265 Attribute.ApplyAttributes (ec, OperatorMethodBuilder, this, OptAttributes, Location);
4268 // abstract or extern methods have no bodies
4270 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
4273 OperatorMethod.Block = Block;
4274 OperatorMethod.Emit (parent);
4279 // This is used to compare method signatures
4281 struct MethodSignature {
4283 public Type RetType;
4284 public Type [] Parameters;
4287 /// This delegate is used to extract methods which have the
4288 /// same signature as the argument
4290 public static MemberFilter method_signature_filter;
4293 /// This delegate is used to extract inheritable methods which
4294 /// have the same signature as the argument. By inheritable,
4295 /// this means that we have permissions to override the method
4296 /// from the current assembly and class
4298 public static MemberFilter inheritable_method_signature_filter;
4301 /// This delegate is used to extract inheritable methods which
4302 /// have the same signature as the argument. By inheritable,
4303 /// this means that we have permissions to override the method
4304 /// from the current assembly and class
4306 public static MemberFilter inheritable_property_signature_filter;
4308 static MethodSignature ()
4310 method_signature_filter = new MemberFilter (MemberSignatureCompare);
4311 inheritable_method_signature_filter = new MemberFilter (
4312 InheritableMemberSignatureCompare);
4313 inheritable_property_signature_filter = new MemberFilter (
4314 InheritablePropertySignatureCompare);
4317 public MethodSignature (string name, Type ret_type, Type [] parameters)
4322 if (parameters == null)
4323 Parameters = TypeManager.NoTypes;
4325 Parameters = parameters;
4328 public override int GetHashCode ()
4330 return Name.GetHashCode ();
4333 public override bool Equals (Object o)
4335 MethodSignature other = (MethodSignature) o;
4337 if (other.Name != Name)
4340 if (other.RetType != RetType)
4343 if (Parameters == null){
4344 if (other.Parameters == null)
4349 if (other.Parameters == null)
4352 int c = Parameters.Length;
4353 if (other.Parameters.Length != c)
4356 for (int i = 0; i < c; i++)
4357 if (other.Parameters [i] != Parameters [i])
4363 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
4365 MethodSignature sig = (MethodSignature) filter_criteria;
4367 if (m.Name != sig.Name)
4371 MethodInfo mi = m as MethodInfo;
4372 PropertyInfo pi = m as PropertyInfo;
4375 ReturnType = mi.ReturnType;
4376 else if (pi != null)
4377 ReturnType = pi.PropertyType;
4382 // we use sig.RetType == null to mean `do not check the
4383 // method return value.
4385 if (sig.RetType != null)
4386 if (ReturnType != sig.RetType)
4391 args = TypeManager.GetArgumentTypes (mi);
4393 args = TypeManager.GetArgumentTypes (pi);
4394 Type [] sigp = sig.Parameters;
4396 if (args.Length != sigp.Length)
4399 for (int i = args.Length; i > 0; ){
4401 if (args [i] != sigp [i])
4408 // This filter should be used when we are requesting methods that
4409 // we want to override.
4411 // This makes a number of assumptions, for example
4412 // that the methods being extracted are of a parent
4413 // class (this means we know implicitly that we are
4414 // being called to find out about members by a derived
4417 static bool InheritableMemberSignatureCompare (MemberInfo m, object filter_criteria)
4419 if (MemberSignatureCompare (m, filter_criteria)){
4420 MethodInfo mi = (MethodInfo) m;
4421 MethodAttributes prot = mi.Attributes & MethodAttributes.MemberAccessMask;
4423 // If only accessible to the current class.
4424 if (prot == MethodAttributes.Private)
4427 // If only accessible to the defining assembly or
4428 if (prot == MethodAttributes.FamANDAssem ||
4429 prot == MethodAttributes.Assembly){
4430 if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
4436 // Anything else (FamOrAssembly and Public) is fine
4443 // This filter should be used when we are requesting properties that
4444 // we want to override.
4446 // This makes a number of assumptions, for example
4447 // that the methods being extracted are of a parent
4448 // class (this means we know implicitly that we are
4449 // being called to find out about members by a derived
4452 static bool InheritablePropertySignatureCompare (MemberInfo m, object filter_criteria)
4454 if (MemberSignatureCompare (m, filter_criteria)){
4455 PropertyInfo pi = (PropertyInfo) m;
4457 MethodInfo inherited_get = TypeManager.GetPropertyGetter (pi);
4458 MethodInfo inherited_set = TypeManager.GetPropertySetter (pi);
4460 MethodInfo mi = inherited_get == null ? inherited_set : inherited_get;
4462 MethodAttributes prot = mi.Attributes & MethodAttributes.MemberAccessMask;
4464 // If only accessible to the current class.
4465 if (prot == MethodAttributes.Private)
4468 // If only accessible to the defining assembly or
4469 if (prot == MethodAttributes.FamANDAssem ||
4470 prot == MethodAttributes.Assembly){
4471 if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
4477 // Anything else (FamOrAssembly and Public) is fine