3 // class.cs: Class and Struct handlers
5 // Authors: Miguel de Icaza (miguel@gnu.org)
6 // Martin Baulig (martin@gnome.org)
7 // Anirban Bhattacharjee (banirban@novell.com)
9 // Licensed under the terms of the GNU GPL
11 // (C) 2001, 2002 Ximian, Inc (http://www.ximian.com)
14 // 2002-10-11 Miguel de Icaza <miguel@ximian.com>
16 // * class.cs: Following the comment from 2002-09-26 to AddMethod, I
17 // have fixed a remaining problem: not every AddXXXX was adding a
18 // fully qualified name.
20 // Now everyone registers a fully qualified name in the DeclSpace as
21 // being defined instead of the partial name.
23 // Downsides: we are slower than we need to be due to the excess
24 // copies and the names being registered this way.
26 // The reason for this is that we currently depend (on the corlib
27 // bootstrap for instance) that types are fully qualified, because
28 // we dump all the types in the namespace, and we should really have
29 // types inserted into the proper namespace, so we can only store the
30 // basenames in the defined_names array.
35 using System.Collections;
36 using System.Reflection;
37 using System.Reflection.Emit;
38 using System.Runtime.CompilerServices;
39 using System.Diagnostics.SymbolStore;
41 namespace Mono.MonoBASIC {
44 /// This is the base class for structs and classes.
46 public class TypeContainer : DeclSpace, IMemberContainer {
47 // Holds a list of classes and structures
50 // Holds the list of properties
53 // Holds the list of enumerations
56 // Holds the list of delegates
59 // Holds the list of constructors
60 ArrayList instance_constructors;
62 // Holds the list of fields
65 // Holds a list of fields that have initializers
66 ArrayList initialized_fields;
68 // Holds a list of static fields that have initializers
69 ArrayList initialized_static_fields;
71 // Holds the list of constants
77 // Holds order in which interfaces must be closed
78 ArrayList interface_order;
89 // Holds the operators
92 // Holds AddHandlers stements for events
95 // The emit context for toplevel objects.
99 // Pointers to the default constructor and the default static constructor
101 Constructor default_constructor;
102 Constructor default_static_constructor;
105 // Whether we have seen a static constructor for this class or not
107 bool have_static_constructor = false;
110 // Whether we have at least one non-static field
112 bool have_nonstatic_fields = false;
115 // This one is computed after we can distinguish interfaces
116 // from classes from the arraylist `type_bases'
118 string base_class_name;
120 ArrayList type_bases;
122 // Attributes for this type
123 protected Attributes attributes;
125 // Information in the case we are an attribute type
127 public AttributeTargets Targets = AttributeTargets.All;
128 public bool AllowMultiple = false;
129 public bool Inherited;
131 // The interfaces we implement.
134 // The parent member container and our member cache
135 IMemberContainer parent_container;
136 MemberCache member_cache;
139 // The indexer name for this class
141 public string IndexerName;
143 public TypeContainer (TypeContainer parent, string name, Location l)
144 : base (parent, name, l)
147 types = new ArrayList ();
154 base_class_name = null;
156 //Console.WriteLine ("New class " + name + " inside " + n);
159 public AdditionResult AddConstant (Const constant)
162 string basename = constant.Name;
164 if ((res = IsValid (basename)) != AdditionResult.Success)
167 if (constants == null)
168 constants = new ArrayList ();
170 constants.Add (constant);
171 DefineName (Name + "." + basename, constant);
173 return AdditionResult.Success;
176 public AdditionResult AddEnum (Mono.MonoBASIC.Enum e)
180 if ((res = IsValid (e.Basename)) != AdditionResult.Success)
184 enums = new ArrayList ();
187 DefineName (e.Name, e);
189 return AdditionResult.Success;
192 public AdditionResult AddClass (Class c)
196 if ((res = IsValid (c.Basename)) != AdditionResult.Success)
201 DefineName (c.Name, c);
204 // FIXME: Do we really need to explicitly add an empty default static constructor?
205 // Apparently we don't
206 /* if (c.default_static_constructor == null)
208 bool isModule = c is Mono.MonoBASIC.Module;
209 Constructor dc = new Constructor ("New", Parameters.EmptyReadOnlyParameters, null, c.Location);
210 dc.ModFlags = isModule ? Modifiers.PUBLIC | Modifiers.STATIC : Modifiers.PUBLIC;
211 c.AddConstructor (dc);
214 //--------------------------------------------------------------
216 return AdditionResult.Success;
219 public AdditionResult AddStruct (Struct s)
223 if ((res = IsValid (s.Basename)) != AdditionResult.Success)
226 DefineName (s.Name, s);
229 return AdditionResult.Success;
232 public AdditionResult AddDelegate (Delegate d)
236 if ((res = IsValid (d.Basename)) != AdditionResult.Success)
239 if (delegates == null)
240 delegates = new ArrayList ();
242 DefineName (d.Name, d);
245 return AdditionResult.Success;
248 public AdditionResult AddMethod (Method method)
250 string basename = method.Name;
251 string fullname = Name + "." + basename;
253 Object value = defined_names [fullname];
255 if (value != null && (!(value is Method)))
256 return AdditionResult.NameExists;
258 if (basename == Basename)
259 return AdditionResult.EnclosingClash;
262 methods = new ArrayList ();
264 if (method.Name.IndexOf (".") != -1)
265 methods.Insert (0, method);
267 methods.Add (method);
270 DefineName (fullname, method);
272 return AdditionResult.Success;
275 public AdditionResult AddConstructor (Constructor c)
278 return AdditionResult.NotAConstructor;
280 bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
283 have_static_constructor = true;
284 if (default_static_constructor != null){
285 Console.WriteLine ("I have a static constructor already");
286 Console.WriteLine (" " + default_static_constructor);
287 return AdditionResult.MethodExists;
290 default_static_constructor = c;
293 /*if (default_constructor != null)
294 return AdditionResult.MethodExists;*/
295 default_constructor = c;
298 if (instance_constructors == null)
299 instance_constructors = new ArrayList ();
301 instance_constructors.Add (c);
304 return AdditionResult.Success;
307 public AdditionResult AddInterface (Interface iface)
311 if ((res = IsValid (iface.Basename)) != AdditionResult.Success)
314 if (interfaces == null)
315 interfaces = new ArrayList ();
316 interfaces.Add (iface);
317 DefineName (iface.Name, iface);
319 return AdditionResult.Success;
322 public AdditionResult AddField (Field field)
325 string basename = field.Name;
327 if ((res = IsValid (basename)) != AdditionResult.Success)
331 fields = new ArrayList ();
335 if (field.HasInitializer){
336 if ((field.ModFlags & Modifiers.STATIC) != 0) {
337 if (initialized_static_fields == null)
338 initialized_static_fields = new ArrayList ();
340 initialized_static_fields.Add (field);
343 // We have not seen a static constructor,
344 // but we will provide static initialization of fields
346 have_static_constructor = true;
348 if (initialized_fields == null)
349 initialized_fields = new ArrayList ();
351 initialized_fields.Add (field);
355 if ((field.ModFlags & Modifiers.STATIC) == 0)
356 have_nonstatic_fields = true;
358 DefineName (Name + "." + basename, field);
359 return AdditionResult.Success;
362 public AdditionResult AddProperty (Property prop)
365 string basename = prop.Name;
367 if ((res = IsValid (basename)) != AdditionResult.Success)
370 if (properties == null)
371 properties = new ArrayList ();
373 if (prop.Name.IndexOf (".") != -1)
374 properties.Insert (0, prop);
376 properties.Add (prop);
377 DefineName (Name + "." + basename, prop);
379 return AdditionResult.Success;
382 public AdditionResult AddEvent (Event e)
385 string basename = e.Name;
387 if ((res = IsValid (basename)) != AdditionResult.Success)
391 events = new ArrayList ();
394 DefineName (Name + "." + basename, e);
396 return AdditionResult.Success;
399 public AdditionResult AddIndexer (Indexer i)
401 if (indexers == null)
402 indexers = new ArrayList ();
404 if (i.InterfaceType != null)
405 indexers.Insert (0, i);
409 return AdditionResult.Success;
412 public AdditionResult AddOperator (Operator op)
414 if (operators == null)
415 operators = new ArrayList ();
419 return AdditionResult.Success;
422 public AdditionResult AddEventHandler (Statement stmt)
424 if (handlers == null)
425 handlers = new ArrayList ();
428 return AdditionResult.Success;
431 public void RegisterOrder (Interface iface)
433 if (interface_order == null)
434 interface_order = new ArrayList ();
436 interface_order.Add (iface);
439 public ArrayList Types {
445 public ArrayList Methods {
451 public ArrayList Constants {
457 public ArrayList Interfaces {
465 return base_class_name;
469 public ArrayList Bases {
479 public ArrayList Fields {
489 public ArrayList InstanceConstructors {
491 return instance_constructors;
495 public ArrayList Properties {
501 public ArrayList Events {
507 public ArrayList Enums {
513 public ArrayList Indexers {
519 public ArrayList Operators {
525 public ArrayList Delegates {
531 public Attributes OptAttributes {
537 public bool HaveStaticConstructor {
539 return have_static_constructor;
543 public virtual TypeAttributes TypeAttr {
545 return Modifiers.TypeAttr (ModFlags, this);
549 public ArrayList EventHandlers {
556 // Emits the instance field initializers
558 public bool EmitFieldInitializers (EmitContext ec)
561 ILGenerator ig = ec.ig;
562 Expression instance_expr;
565 fields = initialized_static_fields;
566 instance_expr = null;
568 fields = initialized_fields;
569 instance_expr = new This (Location.Null).Resolve (ec);
575 foreach (Field f in fields){
576 Expression e = f.GetInitializerExpression (ec);
580 Location l = f.Location;
581 FieldExpr fe = new FieldExpr (f.FieldBuilder, l);
582 fe.InstanceExpression = instance_expr;
583 Expression a = new Assign (fe, e, l);
589 if (a is ExpressionStatement)
590 ((ExpressionStatement) a).EmitStatement (ec);
592 throw new Exception ("Assign.Resolve returned a non ExpressionStatement");
600 // Defines the default constructors
602 void DefineDefaultConstructor (bool is_static)
607 c = new Constructor ("New", Parameters.EmptyReadOnlyParameters,
612 mods = Modifiers.STATIC;
616 c.Initializer = new ConstructorBaseInitializer (
617 null, Parameters.EmptyReadOnlyParameters,
622 c.Block = new Block (null);
626 public void ReportStructInitializedInstanceError ()
628 string n = TypeBuilder.FullName;
630 foreach (Field f in initialized_fields){
633 "`" + n + "." + f.Name + "': can not have " +
634 "instance field initializers in structs");
639 /// The pending methods that need to be implemented (interfaces or abstract methods)
641 public PendingImplementation Pending;
644 /// This function computes the Base class and also the
645 /// list of interfaces that the class or struct @c implements.
647 /// The return value is an array (might be null) of
648 /// interfaces implemented (as Types).
650 /// The @parent argument is set to the parent object or null
651 /// if this is `System.Object'.
653 Type [] GetClassBases (bool is_class, out Type parent, out bool error)
655 ArrayList bases = Bases;
664 parent = TypeManager.value_type;
668 if (RootContext.StdLib)
669 parent = TypeManager.object_type;
670 else if (Name != "System.Object")
671 parent = TypeManager.object_type;
674 // If we are compiling our runtime,
675 // and we are defining ValueType, then our
676 // parent is `System.Object'.
678 if (!RootContext.StdLib && Name == "System.ValueType")
679 parent = TypeManager.object_type;
686 // Bases should be null if there are no bases at all
690 if (is_class && (!(this is Interface))){
691 Expression name = (Expression) bases [0];
692 name = ResolveTypeExpr (name, false, Location);
699 Type first = name.Type;
705 parent = TypeManager.object_type;
709 if (parent.IsSealed )
710 Report.Error (30299, Location,
711 "Class " + Name + " cannot inherit " +
712 "'NotInheritable' class " + TypeManager.MonoBASIC_Name (parent));
714 if (!AsAccessible (parent, ModFlags))
715 Report.Error (30389, Location,
716 "Inconsistent accessibility: base class `" +
717 TypeManager.MonoBASIC_Name (parent) + "' is less " +
718 "accessible than class `" +
725 Type [] ifaces = new Type [count-start];
727 for (i = start, j = 0; i < count; i++, j++){
728 Expression name = (Expression) bases [i];
729 Expression resolved = ResolveTypeExpr (name, false, Location);
730 bases [i] = resolved;
731 Type t = resolved.Type;
737 if (is_class == false && !t.IsInterface){
738 Report.Error (527, "In Struct `" + Name + "', type `"+
739 name +"' is not an interface");
746 Report.Error (30258, "class `"+ Name +
747 "': a class can not inherit from a struct/enum");
749 /*Report.Error (509, "class `"+ Name +
750 "': Cannot inherit from sealed class `"+
758 Report.Error (30121, Name + ": A class cannot inherit " +
759 "more than one class");
765 for (int x = 0; x < j; x++) {
766 if (t == ifaces [x]) {
767 Report.Error (528, "`" + name + "' is already listed in interface list");
780 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
782 public override TypeBuilder DefineType ()
788 if (TypeBuilder != null)
801 ec = new EmitContext (this, Mono.MonoBASIC.Location.Null, null, null, ModFlags);
803 if (((ModFlags & Modifiers.ABSTRACT ) != 0) &&
804 ((ModFlags & Modifiers.SEALED) != 0)){
805 Report.Error (31408, Location,
806 "Class declared as 'MustInherit' cannot be declared as 'NotInheritable'");
809 ifaces = GetClassBases (is_class, out parent, out error);
813 if (this is Interface)
816 if (is_class && parent != null){
817 if (parent == TypeManager.enum_type ||
818 (parent == TypeManager.value_type && RootContext.StdLib) ||
819 parent == TypeManager.delegate_type ||
820 parent == TypeManager.array_type){
822 644, Location, "`" + Name + "' cannot inherit from " +
823 "special class `" + TypeManager.MonoBASIC_Name (parent) + "'");
828 if (!is_class && TypeManager.value_type == null)
829 throw new Exception ();
831 if (is_class && Parent.Parent == null && (!(this is Interface)))
\r
833 if ((ModFlags & Modifiers.PRIVATE) != 0)
834 Report.Error (31089, Location,
835 "Only internal classes can be declared as 'Private'");
837 if ((ModFlags & Modifiers.PROTECTED) != 0)
838 Report.Error (31047, Location,
839 "Only internal classes can be declared as 'Protected'");
842 if ((Parent is Module) && ((ModFlags & Modifiers.PROTECTED) != 0))
843 Report.Error (30735, Location,
844 "'Type' inside a 'Module' can not be " +
845 "declared as 'Protected'");
847 if ((Parent is Struct) && ((ModFlags & Modifiers.PROTECTED) != 0))
848 Report.Error (30435, Location,
849 "'Type' inside a 'Structure' can not be " +
850 "declared as 'Protected'");
852 TypeAttributes type_attributes = TypeAttr;
854 // if (parent_builder is ModuleBuilder) {
856 ModuleBuilder builder = CodeGen.ModuleBuilder;
857 TypeBuilder = builder.DefineType (
858 Name, type_attributes, parent, ifaces);
861 TypeBuilder builder = Parent.TypeBuilder;
862 TypeBuilder = builder.DefineNestedType (
863 Basename, type_attributes, parent, ifaces);
868 // structure must contain atleast one member variable
869 if(!have_nonstatic_fields){
871 30281, Location, "Structure `" + Name + "' do not " +
872 "contain any member Variable");
874 /*TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
875 FieldAttributes.Private);*/
878 // add interfaces that were not added at type creation (weird API issue)
879 if (!have_nonstatic_fields && (ifaces != null)) {
880 foreach (Type i in ifaces)
881 TypeBuilder.AddInterfaceImplementation (i);
887 // Finish the setup for the EmitContext
889 ec.ContainerType = TypeBuilder;
891 TypeManager.AddUserType (Name, TypeBuilder, this, ifaces);
893 if ((parent != null) &&
894 (parent == TypeManager.attribute_type ||
895 parent.IsSubclassOf (TypeManager.attribute_type))) {
896 RootContext.RegisterAttribute (this);
897 TypeManager.RegisterAttrType (TypeBuilder, this);
899 RootContext.RegisterOrder (this);
901 if (Interfaces != null) {
902 foreach (Interface iface in Interfaces)
907 foreach (TypeContainer tc in Types)
911 if (Delegates != null) {
912 foreach (Delegate d in Delegates)
917 foreach (Enum en in Enums)
927 /// Defines the MemberCore objects that are in the `list' Arraylist
929 /// The `defined_names' array contains a list of members defined in
932 static ArrayList remove_list = new ArrayList ();
933 void DefineMembers (ArrayList list, MemberInfo [] defined_names)
937 // if one of the overloaded method is having
938 // Shadows or Overloads modifier all other should
939 // have the same modifier
940 Hashtable members = new Hashtable();
942 foreach (MemberCore mc in list)
\r
945 if(members[mc.Name] == null)
947 foreach (MemberCore m in list)
949 if(m.Name == mc.Name)
951 if ((m.ModFlags & Modifiers.SHADOWS) != 0)
953 modval = Modifiers.SHADOWS;
956 else if((m.ModFlags & Modifiers.NEW) != 0)
958 modval = Modifiers.NEW;
962 members.Add(mc.Name, modval);
965 modval = (int)members[mc.Name];
968 if(((modval & Modifiers.SHADOWS) != 0) && ((mc.ModFlags & Modifiers.SHADOWS) == 0))
971 "Function '" + mc.Name + "': must be declared 'Shadows' " +
972 "because another '" + mc.Name + "' declared 'Shadows'");
973 else if(((modval & Modifiers.NEW) != 0) && ((mc.ModFlags & Modifiers.NEW) == 0))
976 "Function '" + mc.Name + "': must be declared 'Overloads' " +
977 "because another '" + mc.Name + "' declared 'Overloads'");
981 remove_list.Clear ();
983 foreach (MemberCore mc in list){
984 if (!mc.Define (this)){
985 remove_list.Add (mc);
989 if (defined_names == null)
992 idx = Array.BinarySearch (defined_names, mc.Name, mif_compare);
994 if (RootContext.WarningLevel >= 4){
995 if ((mc.ModFlags & Modifiers.NEW) != 0)
996 Warning_KewywordNewNotRequired (mc.Location, mc);
997 if ((mc.ModFlags & Modifiers.SHADOWS) != 0)
998 Warning_KewywordShadowsNotRequired (mc.Location, mc);
1003 MemberInfo match = defined_names [idx];
1005 if (match is PropertyInfo && ((mc.ModFlags & Modifiers.OVERRIDE) != 0))
1009 // If we are both methods, let the method resolution emit warnings
1011 if (match is MethodBase && mc is MethodCore)
1014 if (((mc.ModFlags & Modifiers.SHADOWS) == 0) && idx > 0)
1015 Warning_KeywordShadowsRequired (mc.Location, defined_names [idx]);
1019 foreach (object o in remove_list)
1022 remove_list.Clear ();
1026 // Defines the indexers, and also verifies that the IndexerNameAttribute in the
1027 // class is consisten. Either it is `Item' or it is the name defined by all the
1028 // indexers with the `IndexerName' attribute.
1030 // Turns out that the IndexerNameAttribute is applied to each indexer,
1031 // but it is never emitted, instead a DefaultName attribute is attached
1034 void DefineIndexers ()
1036 string class_indexer_name = null;
1038 foreach (Indexer i in Indexers){
1043 name = i.IndexerName;
1045 if (i.InterfaceType != null)
1048 if (class_indexer_name == null){
1049 class_indexer_name = name;
1053 if (name == class_indexer_name)
1057 668, "Two indexers have different names, " +
1058 " you should use the same name for all your indexers");
1060 if (class_indexer_name == null)
1061 class_indexer_name = "Item";
1062 IndexerName = class_indexer_name;
1065 static void Error_KeywordNotAllowed (Location loc)
1067 Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
1071 /// Populates our TypeBuilder with fields and methods
1073 public override bool DefineMembers (TypeContainer parent)
1075 MemberInfo [] defined_names = null;
1077 if (interface_order != null){
1078 foreach (Interface iface in interface_order)
1079 if ((iface.ModFlags & Modifiers.NEW) == 0)
1080 iface.DefineMembers (this);
1082 Error_KeywordNotAllowed (iface.Location);
1085 if (RootContext.WarningLevel > 1){
1089 // This code throws an exception in the comparer
1090 // I guess the string is not an object?
1092 ptype = TypeBuilder.BaseType;
1094 defined_names = (MemberInfo []) FindMembers (
1095 ptype, MemberTypes.All & ~MemberTypes.Constructor,
1096 BindingFlags.Public | BindingFlags.Instance |
1097 BindingFlags.Static, null, null);
1099 Array.Sort (defined_names, mif_compare);
1103 if (constants != null)
1104 DefineMembers (constants, defined_names);
1107 DefineMembers (fields, defined_names);
1109 if (this is Class && (!(this is Interface))){
1110 if (instance_constructors == null){
1111 if (default_constructor == null)
\r
1112 DefineDefaultConstructor (false);
1115 if (initialized_static_fields != null &&
1116 default_static_constructor == null)
1117 DefineDefaultConstructor (true);
1120 if (this is Struct){
1122 // Structs can not have initialized instance
1125 if (initialized_static_fields != null &&
1126 default_static_constructor == null)
1127 DefineDefaultConstructor (true);
1129 if (initialized_fields != null)
1130 ReportStructInitializedInstanceError ();
1133 if (!(this is Interface))
1134 Pending = PendingImplementation.GetPendingImplementations (this);
1136 // Constructors are not in the defined_names array
1138 if (instance_constructors != null)
\r
1139 DefineMembers (instance_constructors, null);
1141 if (default_static_constructor != null)
1142 default_static_constructor.Define (this);
1144 if (methods != null)
1145 DefineMembers (methods, defined_names);
1147 if (properties != null)
1148 DefineMembers (properties, defined_names);
1151 DefineMembers (events, defined_names);
1153 if (indexers != null) {
1156 IndexerName = "Item";
1158 if (operators != null){
1159 DefineMembers (operators, null);
1161 CheckPairedOperators ();
1165 DefineMembers (enums, defined_names);
1167 if (delegates != null)
1168 DefineMembers (delegates, defined_names);
1171 if (TypeBuilder.BaseType != null)
1172 parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
1174 member_cache = new MemberCache (this);
1180 public override bool Define (TypeContainer parent)
1182 if (interface_order != null){
1183 foreach (Interface iface in interface_order)
1184 if ((iface.ModFlags & Modifiers.NEW) == 0)
1185 iface.Define (this);
1192 /// This function is based by a delegate to the FindMembers routine
1194 static bool AlwaysAccept (MemberInfo m, object filterCriteria)
1200 /// This filter is used by FindMembers, and we just keep
1201 /// a global for the filter to `AlwaysAccept'
1203 static MemberFilter accepting_filter;
1207 /// A member comparission method based on name only
1209 static IComparer mif_compare;
1211 static TypeContainer ()
1213 accepting_filter = new MemberFilter (AlwaysAccept);
1214 mif_compare = new MemberInfoCompare ();
1218 /// This method returns the members of this type just like Type.FindMembers would
1219 /// Only, we need to use this for types which are _being_ defined because MS'
1220 /// implementation can't take care of that.
1223 // FIXME: return an empty static array instead of null, that cleans up
1224 // some code and is consistent with some coding conventions I just found
1228 // Notice that in various cases we check if our field is non-null,
1229 // something that would normally mean that there was a bug elsewhere.
1231 // The problem happens while we are defining p-invoke methods, as those
1232 // will trigger a FindMembers, but this happens before things are defined
1234 // Since the whole process is a no-op, it is fine to check for null here.
1236 public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
1237 MemberFilter filter, object criteria)
1239 ArrayList members = new ArrayList ();
1242 if ((bf & BindingFlags.Public) != 0)
1243 modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
1245 if ((bf & BindingFlags.NonPublic) != 0)
1246 modflags |= Modifiers.PRIVATE;
1248 int static_mask = 0, static_flags = 0;
1249 switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
1250 case BindingFlags.Static:
1251 static_mask = static_flags = Modifiers.STATIC;
1254 case BindingFlags.Instance:
1255 static_mask = Modifiers.STATIC;
1260 static_mask = static_flags = 0;
1264 Timer.StartTimer (TimerType.TcFindMembers);
1267 filter = accepting_filter;
1269 if ((mt & MemberTypes.Field) != 0) {
1270 if (fields != null) {
1271 foreach (Field f in fields) {
1272 if ((f.ModFlags & modflags) == 0)
1274 if ((f.ModFlags & static_mask) != static_flags)
1277 FieldBuilder fb = f.FieldBuilder;
1278 if (fb != null && filter (fb, criteria) == true)
1283 if (constants != null) {
1284 foreach (Const con in constants) {
1285 if ((con.ModFlags & modflags) == 0)
1287 if ((con.ModFlags & static_mask) != static_flags)
1290 FieldBuilder fb = con.FieldBuilder;
1291 if (fb != null && filter (fb, criteria) == true)
1297 if ((mt & MemberTypes.Method) != 0) {
1298 if (methods != null) {
1299 foreach (Method m in methods) {
1300 if ((m.ModFlags & modflags) == 0)
1302 if ((m.ModFlags & static_mask) != static_flags)
1305 MethodBuilder mb = m.MethodBuilder;
1307 if (mb != null && filter (mb, criteria) == true)
1312 if (operators != null){
1313 foreach (Operator o in operators) {
1314 if ((o.ModFlags & modflags) == 0)
1316 if ((o.ModFlags & static_mask) != static_flags)
1319 MethodBuilder ob = o.OperatorMethodBuilder;
1320 if (ob != null && filter (ob, criteria) == true)
1325 if (properties != null){
1326 foreach (Property p in properties){
1327 if ((p.ModFlags & modflags) == 0)
1329 if ((p.ModFlags & static_mask) != static_flags)
1335 if (b != null && filter (b, criteria) == true)
1339 if (b != null && filter (b, criteria) == true)
1344 if (indexers != null){
1345 foreach (Indexer ix in indexers){
1346 if ((ix.ModFlags & modflags) == 0)
1348 if ((ix.ModFlags & static_mask) != static_flags)
1354 if (b != null && filter (b, criteria) == true)
1358 if (b != null && filter (b, criteria) == true)
1364 if ((mt & MemberTypes.Event) != 0) {
1366 foreach (Event e in events) {
1367 if ((e.ModFlags & modflags) == 0)
1369 if ((e.ModFlags & static_mask) != static_flags)
1372 MemberInfo eb = e.EventBuilder;
1373 if (eb != null && filter (eb, criteria) == true)
1374 members.Add (e.EventBuilder);
1378 if ((mt & MemberTypes.Property) != 0){
1379 if (properties != null)
1380 foreach (Property p in properties) {
1381 if ((p.ModFlags & modflags) == 0)
1383 if ((p.ModFlags & static_mask) != static_flags)
1386 MemberInfo pb = p.PropertyBuilder;
1388 if (pb != null && filter (pb, criteria) == true)
1389 members.Add (p.PropertyBuilder);
1392 if (indexers != null)
1393 foreach (Indexer ix in indexers) {
1394 if ((ix.ModFlags & modflags) == 0)
1396 if ((ix.ModFlags & static_mask) != static_flags)
1399 MemberInfo ib = ix.PropertyBuilder;
1400 if (ib != null && filter (ib, criteria) == true) {
1401 members.Add (ix.PropertyBuilder);
1406 if ((mt & MemberTypes.NestedType) != 0) {
1408 foreach (TypeContainer t in types) {
1409 if ((t.ModFlags & modflags) == 0)
1412 TypeBuilder tb = t.TypeBuilder;
1413 if (tb != null && (filter (tb, criteria) == true))
1419 foreach (Enum en in enums){
1420 if ((en.ModFlags & modflags) == 0)
1423 TypeBuilder tb = en.TypeBuilder;
1424 if (tb != null && (filter (tb, criteria) == true))
1429 if (delegates != null){
1430 foreach (Delegate d in delegates){
1431 if ((d.ModFlags & modflags) == 0)
1434 TypeBuilder tb = d.TypeBuilder;
1435 if (tb != null && (filter (tb, criteria) == true))
1440 if (interfaces != null){
1441 foreach (Interface iface in interfaces){
1442 if ((iface.ModFlags & modflags) == 0)
1445 TypeBuilder tb = iface.TypeBuilder;
1446 if (tb != null && (filter (tb, criteria) == true))
1452 if ((mt & MemberTypes.Constructor) != 0){
1453 if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
1454 foreach (Constructor c in instance_constructors){
1455 if ((c.ModFlags & modflags) == 0)
1458 ConstructorBuilder cb = c.ConstructorBuilder;
1460 if (filter (cb, criteria) == true)
1465 if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null) &&
1466 ((default_static_constructor.ModFlags & modflags) != 0)){
1467 ConstructorBuilder cb =
1468 default_static_constructor.ConstructorBuilder;
1471 if (filter (cb, criteria) == true)
1477 // Lookup members in parent if requested.
1479 if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
1480 if ((mt & ~MemberTypes.Constructor) != 0) {
1481 MemberList list = FindMembers (TypeBuilder.BaseType, mt & ~MemberTypes.Constructor, bf, filter, criteria);
1482 members.AddRange (list);
1486 Timer.StopTimer (TimerType.TcFindMembers);
1488 return new MemberList (members);
1491 public override MemberCache MemberCache {
1493 return member_cache;
1497 public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
1498 MemberFilter filter, object criteria)
1500 TypeContainer tc = TypeManager.LookupTypeContainer (t);
1503 return tc.FindMembers (mt, bf, filter, criteria);
1505 return new MemberList (t.FindMembers (mt, bf, filter, criteria));
1509 // FindMethods will look for methods not only in the type `t', but in
1510 // any interfaces implemented by the type.
1512 public static MethodInfo [] FindMethods (Type t, BindingFlags bf,
1513 MemberFilter filter, object criteria)
1519 /// Emits the values for the constants
1521 public void EmitConstants ()
1523 if (constants != null)
1524 foreach (Const con in constants)
1525 con.EmitConstant (this);
1530 /// Emits the code, this step is performed after all
1531 /// the types, enumerations, constructors
1535 if (instance_constructors != null)
1536 foreach (Constructor c in instance_constructors)
1539 if (default_static_constructor != null)
1540 default_static_constructor.Emit (this);
1542 if (methods != null)
1543 foreach (Method m in methods)
1546 if (operators != null)
1547 foreach (Operator o in operators)
1550 if (properties != null)
1551 foreach (Property p in properties)
1554 if (indexers != null){
1555 foreach (Indexer ix in indexers)
1558 /*CustomAttributeBuilder cb = Interface.EmitDefaultMemberAttr (
1559 this, IndexerName, ModFlags, Location);
1560 TypeBuilder.SetCustomAttribute (cb);*/
1564 foreach (Field f in fields)
1567 if (events != null){
1568 foreach (Event e in Events)
1572 if (Pending != null)
1573 if (Pending.VerifyPendingMethods ())
1576 Attribute.ApplyAttributes (ec, TypeBuilder, this, OptAttributes, Location);
1579 // Check for internal or private fields that were never assigned
1581 if (fields != null && RootContext.WarningLevel >= 3) {
1582 foreach (Field f in fields) {
1583 if ((f.ModFlags & Modifiers.PUBLIC) != 0)
1588 169, f.Location, "Private field " +
1589 MakeName (f.Name) + " is never used");
1594 // Only report 649 on level 4
1596 if (RootContext.WarningLevel < 4)
1599 if ((f.status & Field.Status.ASSIGNED) != 0)
1604 "Field " + MakeName (f.Name) + " is never assigned " +
1605 " to and will always have its default value");
1609 // if (types != null)
1610 // foreach (TypeContainer tc in types)
1614 public override void CloseType ()
1619 TypeBuilder.CreateType ();
1621 } catch (TypeLoadException){
1623 // This is fine, the code still created the type
1625 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
1626 // Console.WriteLine (e.Message);
1628 Console.WriteLine ("In type: " + Name);
1633 foreach (Enum en in Enums)
1636 if (interface_order != null){
1637 foreach (Interface iface in interface_order)
1642 foreach (TypeContainer tc in Types)
1646 foreach (TypeContainer tc in Types)
1647 if (!(tc is Struct))
1651 if (Delegates != null)
1652 foreach (Delegate d in Delegates)
1656 public string MakeName (string n)
1658 return "`" + Name + "." + n + "'";
1661 public void Warning_KeywordShadowsRequired (Location l, MemberInfo mi)
1664 108, l, "The keyword 'Shadows' is required on " +
1665 MakeName (mi.Name) + " because it shadows `" +
1666 mi.ReflectedType.Name + "." + mi.Name + "'");
1669 public void Warning_KewywordShadowsNotRequired (Location l, MemberCore mc)
1672 109, l, "The member " + MakeName (mc.Name) + " does not hide an " +
1673 "inherited member, the keyword shadows is not required");
1676 public void Warning_KewywordNewNotRequired (Location l, MemberCore mc)
1679 109, l, "The member " + MakeName (mc.Name) + " does not hide an " +
1680 "inherited member, the keyword new is not required");
1683 public static int CheckMember (string name, MemberInfo mi, int ModFlags)
1689 // Performs the validation on a Method's modifiers (properties have
1690 // the same properties).
1692 public bool MethodModifiersValid (int flags, string n, Location loc)
1694 const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
1695 const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
1696 const int nv = (Modifiers.SHADOWS | Modifiers.VIRTUAL);
1698 string name = MakeName (n);
1701 // At most one of static, virtual or override
1703 if ((flags & Modifiers.STATIC) != 0){
1704 if ((flags & vao) != 0){
1706 30501, loc, "Shared method " + name + " can not be " +
1707 "declared as Overridable");
1712 if (this is Struct){
1713 if ((flags & va) != 0){
1714 Modifiers.Error_InvalidModifier (loc, "virtual or abstract");
1719 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & Modifiers.VIRTUAL) != 0)
\r
1723 ": Methods marked as Overrides cannot be made Overridable");
1727 if ((flags & Modifiers.OVERRIDE) != 0 && (flags & Modifiers.SHADOWS) != 0){
1730 ": Methods marked as Overrides cannot be marked as Shadows");
1735 // If the declaration includes the abstract modifier, then the
1736 // declaration does not include static, virtual or extern
1738 if ((flags & Modifiers.ABSTRACT) != 0){
1739 if ((flags & Modifiers.EXTERN) != 0){
1741 180, loc, name + " can not be both abstract and extern");
1745 if ((flags & Modifiers.VIRTUAL) != 0){
1747 503, loc, name + " can not be both abstract and virtual");
1751 if((ModFlags & Modifiers.SEALED) != 0){
1754 "Class declared as 'NotInheritable' " +
1755 "cannot have a 'MustOverride' member");
1758 else if ((ModFlags & Modifiers.ABSTRACT) == 0){
1761 " is declared as 'MustOverride', hence its container " +
1762 "class should be declared as 'MustInherit'");
1768 if ((flags & Modifiers.PRIVATE) != 0){
1769 if ((flags & vao) != 0){
1772 ": Members marked as Overridable or Overrides can not be Private");
1777 if ((flags & Modifiers.SEALED) != 0){
1778 if ((flags & Modifiers.OVERRIDE) == 0){
1781 ": cannot be sealed because it is not an override");
1785 if ((flags & Modifiers.NEW) != 0){
1786 if ((flags & Modifiers.SHADOWS) != 0){
1789 " 'Overloads' and 'Shadows' cannot be combined ");
1797 // Access level of a type.
1800 ProtectedInternal = 1,
1806 // Check whether `flags' denotes a more restricted access than `level'
1807 // and return the new level.
1808 static AccessLevel CheckAccessLevel (AccessLevel level, int flags)
1810 AccessLevel old_level = level;
1812 if ((flags & Modifiers.INTERNAL) != 0) {
1813 if ((flags & Modifiers.PROTECTED) != 0) {
1814 if ((int) level < (int) AccessLevel.ProtectedInternal)
1815 level = AccessLevel.ProtectedInternal;
1817 if ((int) level < (int) AccessLevel.Internal)
1818 level = AccessLevel.Internal;
1820 } else if ((flags & Modifiers.PROTECTED) != 0) {
1821 if ((int) level < (int) AccessLevel.Protected)
1822 level = AccessLevel.Protected;
1823 } else if ((flags & Modifiers.PRIVATE) != 0)
1824 level = AccessLevel.Private;
1829 // Return the access level for a new member which is defined in the current
1830 // TypeContainer with access modifiers `flags'.
1831 AccessLevel GetAccessLevel (int flags)
1833 if ((flags & Modifiers.PRIVATE) != 0)
1834 return AccessLevel.Private;
1837 if (!IsTopLevel && (Parent != null))
1838 level = Parent.GetAccessLevel (flags);
1840 level = AccessLevel.Public;
1842 return CheckAccessLevel (CheckAccessLevel (level, flags), ModFlags);
1845 // Return the access level for type `t', but don't give more access than `flags'.
1846 static AccessLevel GetAccessLevel (Type t, int flags)
1848 if (((flags & Modifiers.PRIVATE) != 0) || t.IsNestedPrivate)
1849 return AccessLevel.Private;
1852 if (TypeManager.IsBuiltinType (t))
1853 return AccessLevel.Public;
1854 else if ((t.DeclaringType != null) && (t != t.DeclaringType))
1855 level = GetAccessLevel (t.DeclaringType, flags);
1857 level = CheckAccessLevel (AccessLevel.Public, flags);
1860 if (t.IsNestedPublic)
1863 if (t.IsNestedAssembly || t.IsNotPublic) {
1864 if ((int) level < (int) AccessLevel.Internal)
1865 level = AccessLevel.Internal;
1868 if (t.IsNestedFamily) {
1869 if ((int) level < (int) AccessLevel.Protected)
1870 level = AccessLevel.Protected;
1873 if (t.IsNestedFamORAssem) {
1874 if ((int) level < (int) AccessLevel.ProtectedInternal)
1875 level = AccessLevel.ProtectedInternal;
1882 // Returns true if `parent' is as accessible as the flags `flags'
1883 // given for this member.
1885 public bool AsAccessible (Type parent, int flags)
1887 while (parent.IsArray || parent.IsPointer || parent.IsByRef)
1888 parent = parent.GetElementType ();
1890 AccessLevel level = GetAccessLevel (flags);
1891 AccessLevel level2 = GetAccessLevel (parent, flags);
1893 return (int) level >= (int) level2;
1896 Hashtable builder_and_args;
1898 public bool RegisterMethod (MethodBuilder mb, InternalParameters ip, Type [] args)
1900 if (builder_and_args == null)
1901 builder_and_args = new Hashtable ();
1906 /// Performs checks for an explicit interface implementation. First it
1907 /// checks whether the `interface_type' is a base inteface implementation.
1908 /// Then it checks whether `name' exists in the interface type.
1910 public bool VerifyImplements (Type interface_type, string full, string name, Location loc)
1914 if (ifaces != null){
1915 foreach (Type t in ifaces){
1916 if (t == interface_type){
1924 Report.Error (540, "`" + full + "': containing class does not implement interface `" + interface_type.FullName + "'");
1931 public static void Error_NotInterfaceMember (Location loc, string member_name, string iface_name)
1933 Report.Error (30401, loc, "'" + member_name + "' is not a member of the interface '" + iface_name + "'");
1940 string IMemberContainer.Name {
1946 Type IMemberContainer.Type {
1952 IMemberContainer IMemberContainer.Parent {
1954 return parent_container;
1958 MemberCache IMemberContainer.MemberCache {
1960 return member_cache;
1964 bool IMemberContainer.IsInterface {
1966 return this is Interface;
1970 MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
1972 return FindMembers (mt, bf | BindingFlags.DeclaredOnly, null, null);
1976 // Operator pair checking
1979 class OperatorEntry {
1981 public Type ret_type;
1982 public Type type1, type2;
1984 public Operator.OpType ot;
1986 public OperatorEntry (int f, Operator o)
1990 ret_type = o.OperatorMethod.GetReturnType ();
1991 Type [] pt = o.OperatorMethod.ParameterTypes;
1995 ot = o.OperatorType;
1998 public override int GetHashCode ()
2000 return ret_type.GetHashCode ();
2003 public override bool Equals (object o)
2005 OperatorEntry other = (OperatorEntry) o;
2007 if (other.ret_type != ret_type)
2009 if (other.type1 != type1)
2011 if (other.type2 != type2)
2018 // Checks that some operators come in pairs:
2023 // They are matched based on the return type and the argument types
2025 void CheckPairedOperators ()
2027 Hashtable pairs = new Hashtable (null, null);
2029 // Register all the operators we care about.
2030 foreach (Operator op in operators){
2033 switch (op.OperatorType){
2034 case Operator.OpType.Equality:
2036 case Operator.OpType.Inequality:
2039 case Operator.OpType.GreaterThan:
2041 case Operator.OpType.LessThan:
2044 case Operator.OpType.GreaterThanOrEqual:
2046 case Operator.OpType.LessThanOrEqual:
2052 OperatorEntry oe = new OperatorEntry (reg, op);
2054 object o = pairs [oe];
2058 oe = (OperatorEntry) o;
2064 // Look for the mistakes.
2066 foreach (DictionaryEntry de in pairs){
2067 OperatorEntry oe = (OperatorEntry) de.Key;
2074 case Operator.OpType.Equality:
2077 case Operator.OpType.Inequality:
2080 case Operator.OpType.GreaterThan:
2083 case Operator.OpType.LessThan:
2086 case Operator.OpType.GreaterThanOrEqual:
2089 case Operator.OpType.LessThanOrEqual:
2093 Report.Error (216, oe.op.Location,
2094 "The operator `" + oe.op + "' requires a matching operator `" + s + "' to also be defined");
2101 public class Class : TypeContainer {
2103 // Modifiers allowed in a class declaration
2105 public const int AllowedModifiers =
2108 Modifiers.PROTECTED |
2109 Modifiers.INTERNAL |
2111 Modifiers.ABSTRACT |
2114 public Class (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
2115 : base (parent, name, l)
2119 if (parent.Parent == null)
2120 accmods = Modifiers.INTERNAL;
2122 accmods = Modifiers.PUBLIC;
2124 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2125 this.attributes = attrs;
2129 // FIXME: How do we deal with the user specifying a different
2132 public override TypeAttributes TypeAttr {
2134 return base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class;
2139 public class Struct : TypeContainer {
2141 // Modifiers allowed in a struct declaration
2143 public const int AllowedModifiers =
2146 Modifiers.PROTECTED |
2147 Modifiers.INTERNAL |
2151 public Struct (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
2152 : base (parent, name, l)
2156 if (parent.Parent == null)
2157 accmods = Modifiers.INTERNAL;
2159 accmods = Modifiers.PUBLIC;
2161 this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
2163 this.ModFlags |= Modifiers.SEALED;
2164 this.attributes = attrs;
2169 // FIXME: Allow the user to specify a different set of attributes
2170 // in some cases (Sealed for example is mandatory for a class,
2171 // but what SequentialLayout can be changed
2173 public override TypeAttributes TypeAttr {
2175 return base.TypeAttr |
2176 TypeAttributes.SequentialLayout |
2177 TypeAttributes.Sealed |
2178 TypeAttributes.BeforeFieldInit;
2183 public abstract class MethodCore : MemberBase {
2184 public /* readonly */ Parameters Parameters;
2188 // Parameters, cached for semantic analysis.
2190 protected InternalParameters parameter_info;
2191 protected Type [] parameter_types;
2193 // Whether this is an operator
2194 public bool IsOperator;
2196 public MethodCore (Expression type, int mod, int allowed_mod, string name,
2197 Attributes attrs, Parameters parameters, Location loc)
2198 : base (type, mod, allowed_mod, name, attrs, loc)
2200 Parameters = parameters;
2204 // Returns the System.Type array for the parameters of this method
2206 public Type [] ParameterTypes {
2208 return parameter_types;
2212 public InternalParameters ParameterInfo
2215 return parameter_info;
2219 public Block Block {
2229 protected virtual bool DoDefineParameters (TypeContainer parent)
2231 // Check if arguments were correct
2232 parameter_types = Parameters.GetParameterInfo (parent);
2233 if ((parameter_types == null) || !CheckParameters (parent, parameter_types))
2236 parameter_info = new InternalParameters (parent, Parameters);
2241 public CallingConventions GetCallingConvention (bool is_class)
2243 CallingConventions cc = 0;
2245 cc = Parameters.GetCallingConvention ();
2248 if ((ModFlags & Modifiers.STATIC) == 0)
2249 cc |= CallingConventions.HasThis;
2251 // FIXME: How is `ExplicitThis' used in C#?
2256 public void LabelParameters (EmitContext ec, Type [] parameters, MethodBase builder)
2258 LabelParameters (ec, parameters, builder, null);
2261 public void LabelParameters (EmitContext ec, Type [] parameters, MethodBase builder, Parameters p_params)
2264 // Define each type attribute (in/out/ref) and
2265 // the argument names.
2267 Parameter [] p = p_params == null ? Parameters.FixedParameters : p_params.FixedParameters;
2270 MethodBuilder mb = null;
2271 ConstructorBuilder cb = null;
2273 if (builder is MethodBuilder)
2274 mb = (MethodBuilder) builder;
2276 cb = (ConstructorBuilder) builder;
2279 for (i = 0; i < p.Length; i++) {
2280 ParameterBuilder pb;
2283 pb = cb.DefineParameter (
2284 i + 1, p [i].Attributes, p [i].Name);
2286 pb = mb.DefineParameter (
2287 i + 1, p [i].Attributes, p [i].Name);
2289 if (p [i].ParameterInitializer != null)
2290 pb.SetConstant (((Constant) p [i].ParameterInitializer).GetValue());
2292 Attributes attr = p [i].OptAttributes;
2294 Attribute.ApplyAttributes (ec, pb, pb, attr, Location);
2298 if (Parameters.ArrayParameter != null){
2299 ParameterBuilder pb;
2300 Parameter array_param = Parameters.ArrayParameter;
2303 pb = cb.DefineParameter (
2304 i + 1, array_param.Attributes,
2307 pb = mb.DefineParameter (
2308 i + 1, array_param.Attributes,
2311 CustomAttributeBuilder a = new CustomAttributeBuilder (
2312 TypeManager.cons_param_array_attribute, new object [0]);
2314 pb.SetCustomAttribute (a);
2319 public class Method : MethodCore {
2320 public MethodBuilder MethodBuilder;
2321 public MethodData MethodData;
2324 /// Modifiers allowed in a class declaration
2326 const int AllowedModifiers =
2329 Modifiers.PROTECTED |
2330 Modifiers.INTERNAL |
2334 Modifiers.NONVIRTUAL |
2335 Modifiers.OVERRIDE |
2336 Modifiers.ABSTRACT |
2342 // return_type can be "null" for VOID values.
2344 public Method (Expression return_type, int mod, string name, Parameters parameters,
2345 Attributes attrs, Location l)
2346 : base (return_type, mod, AllowedModifiers, name, attrs, parameters, l)
2351 public Method (Expression return_type, int mod, string name, Parameters parameters,
2352 Attributes attrs, ArrayList impl_what, Location l)
2353 : base (return_type, mod, AllowedModifiers, name, attrs, parameters, l)
2355 Implements = impl_what;
2359 // Returns the `System.Type' for the ReturnType of this
2360 // function. Provides a nice cache. (used between semantic analysis
2361 // and actual code generation
2363 public Type GetReturnType ()
2368 void DuplicateEntryPoint (MethodInfo b, Location location)
2372 "Program `" + CodeGen.FileName +
2373 "' has more than one entry point defined: `" +
2374 TypeManager.MonoBASIC_Signature(b) + "'");
2377 void Report28 (MethodInfo b)
2379 if (RootContext.WarningLevel < 4)
2384 "`" + TypeManager.MonoBASIC_Signature(b) +
2385 "' has the wrong signature to be an entry point");
2388 public bool IsEntryPoint (MethodBuilder b, InternalParameters pinfo)
2390 if (b.ReturnType != TypeManager.void_type &&
2391 b.ReturnType != TypeManager.int32_type)
2394 if (pinfo.Count == 0)
2397 if (pinfo.Count > 1)
2400 Type t = pinfo.ParameterType(0);
2402 (t.GetArrayRank() == 1) &&
2403 (t.GetElementType() == TypeManager.string_type) &&
2404 (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
2411 // Checks our base implementation if any
2413 protected override bool CheckBase (TypeContainer parent)
2415 // Check whether arguments were correct.
2416 if (!DoDefineParameters (parent))
2419 MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
2423 mi_this = TypeContainer.FindMembers (
2424 parent.TypeBuilder, MemberTypes.Method,
2425 BindingFlags.NonPublic | BindingFlags.Public |
2426 BindingFlags.Static | BindingFlags.Instance |
2427 BindingFlags.DeclaredOnly,
2428 MethodSignature.method_signature_filter, ms);
2430 if (mi_this.Count > 0) {
2431 Report.Error (111, Location, "Class `" + parent.Name + "' " +
2432 "already defines a member called `" + Name + "' " +
2433 "with the same parameter types");
2439 // Verify if the parent has a type with the same name, and then
2440 // check whether we have to create a new slot for it or not.
2442 Type ptype = parent.TypeBuilder.BaseType;
2444 // ptype is only null for System.Object while compiling corlib.
2446 MemberList mi, mi_static, mi_instance;
2448 mi_static = TypeContainer.FindMembers (
2449 ptype, MemberTypes.Method,
2450 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static,
2451 MethodSignature.inheritable_method_signature_filter, ms);
2453 mi_instance = TypeContainer.FindMembers (
2454 ptype, MemberTypes.Method,
2455 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
2456 MethodSignature.inheritable_method_signature_filter,
2459 if (mi_instance.Count > 0){
2461 } else if (mi_static.Count > 0)
2466 if (mi != null && mi.Count > 0){
2467 parent_method = (MethodInfo) mi [0];
2468 string name = parent_method.DeclaringType.Name + "." +
2471 if (!CheckMethodAgainstBase (parent, flags, parent_method, name))
2474 if ((ModFlags & Modifiers.NEW) == 0) {
2475 Type parent_ret = TypeManager.TypeToCoreType (
2476 parent_method.ReturnType);
2478 if (parent_ret != MemberType) {
2480 508, parent.MakeName (Name) + ": cannot " +
2481 "change return type when overriding " +
2482 "inherited member " + name);
2487 /*if ((ModFlags & Modifiers.NEW) != 0)
2488 WarningNotHiding (parent);*/
2490 if ((ModFlags & Modifiers.OVERRIDE) != 0){
2491 Report.Error (30284, Location,
2492 parent.MakeName (Name) +
2493 " : No suitable methods found to override");
2495 if ((ModFlags & ( Modifiers.NEW | Modifiers.SHADOWS | Modifiers.OVERRIDE )) == 0)
\r
2497 if ((ModFlags & Modifiers.NONVIRTUAL) != 0)
\r
2499 Report.Error (31088, Location,
2500 parent.MakeName (Name) + " : Cannot " +
2501 "be declared NotOverridable since this method is " +
2502 "not maked as Overrides");
2505 // if a member of module is not inherited from Object class
2506 // can not be declared protected
2507 if ((parent is Module) && ((ModFlags & Modifiers.PROTECTED) != 0))
2508 Report.Error (31066, Location,
2509 "'Sub' or 'Function' inside a 'Module' can not be declared as " +
2510 "'Protected' or 'Protected Friend'");
2513 /* else if ((ModFlags & Modifiers.NEW) != 0)
2514 WarningNotHiding (parent);
2523 public override bool Define (TypeContainer parent)
2525 if (!DoDefine (parent))
2528 if (!CheckBase (parent))
2531 if ((parent is Struct) && ((ModFlags & Modifiers.PROTECTED) != 0))
2532 Report.Error (31067, Location,
2533 "'Sub' or 'Function' inside a 'Structure' can not be declared as " +
2534 "'Protected' or 'Protected Friend'");
2536 CallingConventions cc = GetCallingConvention (parent is Class);
2538 MethodData = new MethodData (this, null, MemberType, ParameterTypes,
2539 ParameterInfo, cc, OptAttributes,
2540 ModFlags, flags, true);
2542 if (!MethodData.Define (parent))
2545 MethodBuilder = MethodData.MethodBuilder;
2548 // This is used to track the Entry Point,
2550 if (Name.ToUpper() == "MAIN" &&
2551 ((ModFlags & Modifiers.STATIC) != 0) &&
2552 (RootContext.MainClass == null ||
2553 RootContext.MainClass == parent.TypeBuilder.FullName ||
2554 (RootContext.RootNamespace != null &&
2555 RootContext.RootNamespace.Length > 0 &&
2556 (RootContext.RootNamespace + "." + RootContext.MainClass) == parent.TypeBuilder.FullName))) {
2557 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
2558 if (RootContext.EntryPoint == null) {
2559 RootContext.EntryPoint = MethodBuilder;
2560 RootContext.EntryPointLocation = Location;
2562 DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
2563 DuplicateEntryPoint (MethodBuilder, Location);
2566 Report28(MethodBuilder);
2575 public void Emit (TypeContainer parent)
2577 MethodData.Emit (parent, Block, this);
2581 public abstract class ConstructorInitializer {
2582 ArrayList argument_list;
2583 ConstructorInfo parent_constructor;
2584 Parameters parameters;
2586 public bool implicit_initialization;
2588 public ConstructorInitializer (ArrayList argument_list, Parameters parameters,
2591 this.argument_list = argument_list;
2592 this.parameters = parameters;
2594 this.implicit_initialization = false;
2597 public ArrayList Arguments {
2599 return argument_list;
2603 public ConstructorInfo ParentConstructor
2607 return parent_constructor;
2611 public bool Resolve (EmitContext ec)
2613 Expression parent_constructor_group;
2616 ec.CurrentBlock = new Block (null, true, parameters);
2618 if (argument_list != null){
2619 foreach (Argument a in argument_list){
2620 if (!a.Resolve (ec, loc))
2625 ec.CurrentBlock = null;
2627 if (this is ConstructorBaseInitializer) {
2628 if (ec.ContainerType.BaseType == null)
2631 t = ec.ContainerType.BaseType;
2632 if (ec.ContainerType.IsValueType){
2633 Report.Error (522, loc,
2634 "structs cannot call base class constructors");
2639 t = ec.ContainerType;
2641 parent_constructor_group = Expression.MemberLookup (
2643 MemberTypes.Constructor,
2644 BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
2647 if (parent_constructor_group == null){
2648 Report.Error (30455, loc, "Class '" + t + "' can not find a constructor for this argument list" );
2652 parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (ec,
2653 (MethodGroupExpr) parent_constructor_group, argument_list, loc);
2655 if (parent_constructor == null) {
2656 if (this.implicit_initialization)
2657 Report.Error (30148, loc, "Must declare 'MyBase.New' in the constructor " +
\r
2658 "of the class '" + ec.TypeContainer.Name + "' with appropriate arguments, since the base class '" +
\r
2659 t.FullName + "' does not contain a definition of 'New' without any parameter");
2661 Report.Error (30455, loc, "Class '" + t + "' can not find a constructor for this argument list" );
2669 public void Emit (EmitContext ec)
2671 if (parent_constructor != null){
2673 Invocation.EmitCall (ec, true, true, null, parent_constructor, argument_list, loc);
2675 Invocation.EmitCall (ec, true, false, ec.This, parent_constructor, argument_list, loc);
2682 public class ConstructorBaseInitializer : ConstructorInitializer {
2683 public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
2684 base (argument_list, pars, l)
2689 public class ConstructorThisInitializer : ConstructorInitializer {
2690 public ConstructorThisInitializer (ArrayList argument_list, Parameters pars, Location l) :
2691 base (argument_list, pars, l)
2696 public class Constructor : MethodCore {
2697 public ConstructorBuilder ConstructorBuilder;
2698 public ConstructorInitializer Initializer;
2699 new public Attributes OptAttributes;
2702 // Modifiers allowed for a constructor.
2704 public const int AllowedModifiers =
2706 Modifiers.PROTECTED |
2707 Modifiers.INTERNAL |
2714 // The spec claims that static is not permitted, but
2715 // my very own code has static constructors.
2717 public Constructor (string name, Parameters args, ConstructorInitializer init, Location l)
2718 : base (null, 0, AllowedModifiers, name, null, args, l)
2723 public Constructor (string name, int mod, Parameters args, ConstructorInitializer init, Location l)
2724 : base (null, mod, AllowedModifiers, name, null, args, l)
2730 // Returns true if this is a default constructor
2732 public bool IsDefault ()
2734 if ((ModFlags & Modifiers.STATIC) != 0)
2735 return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
2736 (Parameters.ArrayParameter == null ? true : Parameters.Empty);
2739 return (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
2740 (Parameters.ArrayParameter == null ? true : Parameters.Empty) &&
2741 (Initializer is ConstructorBaseInitializer) &&
2742 (Initializer.Arguments == null);
2746 // Creates the ConstructorBuilder
2748 public override bool Define (TypeContainer parent)
2750 MethodAttributes ca = (MethodAttributes.RTSpecialName |
2751 MethodAttributes.SpecialName);
2753 if (parent.EventHandlers != null) {
2754 ArrayList hdlrs = parent.EventHandlers;
2755 foreach(Statement stmt in hdlrs)
2756 this.Block.AddStatement (stmt);
2760 // Check if arguments were correct.
2761 if (!DoDefineParameters (parent))
2764 if ((ModFlags & Modifiers.STATIC) != 0) {
2765 ca |= MethodAttributes.Static;
2767 if (this.Parameters != Parameters.EmptyReadOnlyParameters)
2770 "Shared constructor can not have parameters");
2772 if ((ModFlags & Modifiers.Accessibility) != 0)
2775 "Shared constructor can not be declared " +
2776 "explicitly as public, private, friend or protected");
2778 if (this.Initializer != null)
2781 "Keywords like MyBase, MyClass, Me are not " +
2782 "valid inside a Shared Constructor");
2785 if (parent is Struct && ParameterTypes.Length == 0) {
2788 "Structs can not contain explicit parameterless " +
2792 ca |= MethodAttributes.HideBySig;
2794 if ((ModFlags & Modifiers.PUBLIC) != 0)
2795 ca |= MethodAttributes.Public;
2796 else if ((ModFlags & Modifiers.PROTECTED) != 0) {
2797 if ((ModFlags & Modifiers.INTERNAL) != 0)
2798 ca |= MethodAttributes.FamORAssem;
2800 ca |= MethodAttributes.Family;
2802 else if ((ModFlags & Modifiers.INTERNAL) != 0)
2803 ca |= MethodAttributes.Assembly;
2804 else if (IsDefault ())
2805 ca |= MethodAttributes.Public;
2807 ca |= MethodAttributes.Private;
2810 ConstructorBuilder = parent.TypeBuilder.DefineConstructor (
2811 ca, GetCallingConvention (parent is Class), ParameterTypes);
2814 // HACK because System.Reflection.Emit is lame
2816 if (!TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes)) {
2819 "Class `" +parent.Name+ "' already contains a definition with the " +
2820 "same return value and parameter types for constructor `" + Name
2831 public void Emit (TypeContainer parent)
2833 ILGenerator ig = ConstructorBuilder.GetILGenerator ();
2834 EmitContext ec = new EmitContext (parent, Location, ig, null, ModFlags, true);
2836 if ((ModFlags & Modifiers.STATIC) == 0){
2837 if (parent is Class && Initializer == null) {
2838 Initializer = new ConstructorBaseInitializer (
2839 null, Parameters.EmptyReadOnlyParameters, parent.Location);
2840 Initializer.implicit_initialization = true;
2844 // Spec mandates that Initializers will not have
2848 if (Initializer != null && !Initializer.Resolve (ec))
2850 ec.IsStatic = false;
2853 LabelParameters (ec, ParameterTypes, ConstructorBuilder);
2856 // Classes can have base initializers and instance field initializers.
2858 if (parent is Class){
2859 if ((ModFlags & Modifiers.STATIC) == 0)
2860 parent.EmitFieldInitializers (ec);
2863 if (Initializer != null) {
2864 if (this.ConstructorBuilder.Equals (Initializer.ParentConstructor))
2867 "A constructor can not call itself" );
2869 Initializer.Emit (ec);
2872 if ((ModFlags & Modifiers.STATIC) != 0)
2873 parent.EmitFieldInitializers (ec);
2875 Attribute.ApplyAttributes (ec, ConstructorBuilder, this, OptAttributes, Location);
2877 // If this is a non-static `struct' constructor and doesn't have any
2878 // initializer, it must initialize all of the struct's fields.
2879 if ((parent is Struct) && ((ModFlags & Modifiers.STATIC) == 0) &&
2880 (Initializer == null))
2881 Block.AddThisVariable (parent, Location);
2883 ec.EmitTopBlock (Block, ParameterInfo, Location);
2887 public class MethodData {
2889 // The return type of this method
2891 public readonly Type ReturnType;
2892 public readonly Type[] ParameterTypes;
2893 public readonly InternalParameters ParameterInfo;
2894 public readonly CallingConventions CallingConventions;
2895 public readonly Attributes OptAttributes;
2896 public readonly Location Location;
2899 // Are we implementing an interface ?
2901 public bool IsImplementing = false;
2906 protected MemberBase member;
2907 protected int modifiers;
2908 protected MethodAttributes flags;
2909 protected bool is_method;
2910 protected string accessor_name;
2911 ArrayList conditionals;
2913 MethodBuilder builder = null;
2914 public MethodBuilder MethodBuilder {
2920 public MethodData (MemberBase member, string name, Type return_type,
2921 Type [] parameter_types, InternalParameters parameters,
2922 CallingConventions cc, Attributes opt_attrs,
2923 int modifiers, MethodAttributes flags, bool is_method)
2925 this.member = member;
2926 this.accessor_name = name;
2927 this.ReturnType = return_type;
2928 this.ParameterTypes = parameter_types;
2929 this.ParameterInfo = parameters;
2930 this.CallingConventions = cc;
2931 this.OptAttributes = opt_attrs;
2932 this.modifiers = modifiers;
2934 this.is_method = is_method;
2935 this.Location = member.Location;
2936 this.conditionals = new ArrayList ();
2942 Attribute dllimport_attribute = null;
2943 string obsolete = null;
2944 bool obsolete_error = false;
2946 public virtual bool ApplyAttributes (Attributes opt_attrs, bool is_method)
2948 if ((opt_attrs == null) || (opt_attrs.AttributeSections == null))
2951 foreach (AttributeSection asec in opt_attrs.AttributeSections) {
2952 if (asec.Attributes == null)
2955 foreach (Attribute a in asec.Attributes) {
2956 if (a.Name == "Conditional") {
2957 if (!ApplyConditionalAttribute (a))
2959 } else if (a.Name == "Obsolete") {
2960 if (!ApplyObsoleteAttribute (a))
2962 } else if (a.Name.IndexOf ("DllImport") != -1) {
2964 a.Type = TypeManager.dllimport_type;
2965 Attribute.Error_AttributeNotValidForElement (a, Location);
2968 if (!ApplyDllImportAttribute (a))
2978 // Applies the `DllImport' attribute to the method.
2980 protected virtual bool ApplyDllImportAttribute (Attribute a)
2982 const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
2983 if ((modifiers & extern_static) != extern_static) {
2984 Report.Error (601, Location,
2985 "The DllImport attribute must be specified on a method " +
2986 "marked `static' and `extern'.");
2990 flags |= MethodAttributes.PinvokeImpl;
2991 dllimport_attribute = a;
2996 // Applies the `Obsolete' attribute to the method.
2998 protected virtual bool ApplyObsoleteAttribute (Attribute a)
3000 if (obsolete != null) {
3001 Report.Error (579, Location, "Duplicate `Obsolete' attribute");
3005 obsolete = a.Obsolete_GetObsoleteMessage (out obsolete_error);
3006 return obsolete != null;
3010 // Applies the `Conditional' attribute to the method.
3012 protected virtual bool ApplyConditionalAttribute (Attribute a)
3014 // The Conditional attribute is only valid on methods.
3016 Attribute.Error_AttributeNotValidForElement (a, Location);
3020 string condition = a.Conditional_GetConditionName ();
3022 if (condition == null)
3025 if (ReturnType != TypeManager.void_type) {
3026 Report.Error (578, Location,
3027 "Conditional not valid on `" + member.Name + "' " +
3028 "because its return type is not void");
3032 if ((modifiers & Modifiers.OVERRIDE) != 0) {
3033 Report.Error (243, Location,
3034 "Conditional not valid on `" + member.Name + "' " +
3035 "because it is an override method");
3039 if (member.IsExplicitImpl) {
3040 Report.Error (577, Location,
3041 "Conditional not valid on `" + member.Name + "' " +
3042 "because it is an explicit interface implementation");
3046 if (IsImplementing) {
3047 Report.Error (623, Location,
3048 "Conditional not valid on `" + member.Name + "' " +
3049 "because it is an interface method");
3053 conditionals.Add (condition);
3059 // Checks whether this method should be ignored due to its Conditional attributes.
3061 bool ShouldIgnore (Location loc)
3063 // When we're overriding a virtual method, we implicitly inherit the
3064 // Conditional attributes from our parent.
3065 if (member.ParentMethod != null) {
3066 TypeManager.MethodFlags flags = TypeManager.GetMethodFlags (
3067 member.ParentMethod, loc);
3069 if ((flags & TypeManager.MethodFlags.ShouldIgnore) != 0)
3073 foreach (string condition in conditionals)
3074 if (RootContext.AllDefines [condition] == null)
3081 // Returns the TypeManager.MethodFlags for this method.
3082 // This emits an error 619 / warning 618 if the method is obsolete.
3083 // In the former case, TypeManager.MethodFlags.IsObsoleteError is returned.
3085 public virtual TypeManager.MethodFlags GetMethodFlags (Location loc)
3087 TypeManager.MethodFlags flags = 0;
3089 if (obsolete != null) {
3090 if (obsolete_error) {
3091 Report.Error (619, loc, "Method `" + member.Name +
3092 "' is obsolete: `" + obsolete + "'");
3093 return TypeManager.MethodFlags.IsObsoleteError;
3095 Report.Warning (618, loc, "Method `" + member.Name +
3096 "' is obsolete: `" + obsolete + "'");
3098 flags |= TypeManager.MethodFlags.IsObsolete;
3101 if (ShouldIgnore (loc))
3102 flags |= TypeManager.MethodFlags.ShouldIgnore;
3108 // Search all the interface bases recursively for unimplemented methods
3110 bool SearchBasesForAbstractMethods (
3111 TypeContainer parent, Type iface_type,
3112 string method_name, ref ArrayList implementing_list,
3113 ref ArrayList implementing_iface)
3115 MethodInfo implementing = null;
3116 bool IsImplementing = false;
3117 Type current_iface_type = iface_type;
3119 if (member is Indexer)
3120 implementing = parent.Pending.IsAbstractIndexer (
3121 current_iface_type , ReturnType, ParameterTypes);
3123 implementing = parent.Pending.IsAbstractMethod (
3124 current_iface_type, method_name, ReturnType, ParameterTypes);
3126 if (implementing != null) {
3127 if (!implementing_list.Contains (implementing)) {
3128 implementing_list.Add (implementing);
3129 implementing_iface.Add(current_iface_type);
3131 IsImplementing = true;
3133 Type[] current_iface_types = current_iface_type.GetInterfaces();
3134 if (current_iface_types.Length == 0)
3137 foreach (Type curr_iface_type in current_iface_types) {
3138 IsImplementing = SearchBasesForAbstractMethods (
3139 parent, curr_iface_type, method_name,
3140 ref implementing_list, ref implementing_iface);
3147 return IsImplementing;
3150 public virtual bool Define (TypeContainer parent)
3152 MethodInfo implementing = null;
3153 ArrayList implementing_list = null;
3154 ArrayList implementing_iface = null;
3155 string method_name, name, prefix, impl_method_name;
3158 if (OptAttributes != null)
3159 if (!ApplyAttributes (OptAttributes, is_method))
3162 if (accessor_name != null)
3163 name = accessor_name + "_" + member.ShortName;
3165 name = member.ShortName;
3168 impl_method_name = name;
3170 if ((member.ModFlags & Modifiers.OVERRIDE) != 0) {
3171 if (parent.Pending == null)
3172 implementing = null;
3173 else if (member is Indexer)
3174 implementing = parent.Pending.IsAbstractIndexer (
3175 (Type) parent.TypeBuilder.BaseType,
3176 ReturnType, ParameterTypes);
3178 implementing = parent.Pending.IsAbstractMethod (
3179 (Type) parent.TypeBuilder.BaseType, name,
3180 ReturnType, ParameterTypes);
3182 if (implementing != null)
\r
3183 IsImplementing = true;
3186 if (member.Implements != null) {
3187 implementing_list = new ArrayList();
3188 implementing_iface = new ArrayList();
3190 foreach (Expression Impl in member.Implements) {
3191 name = Impl.ToString();
3192 prefix = name.Substring(0, name.LastIndexOf("."));
3193 name = name.Substring(name.LastIndexOf(".") + 1);
3195 if (accessor_name != null)
3196 impl_method_name = accessor_name + "_" + name;
3198 impl_method_name = name;
3200 Type current_iface_type = (Type) member.InterfaceTypes[++pos];
3201 IsImplementing = SearchBasesForAbstractMethods (
3202 parent, current_iface_type, impl_method_name,
3203 ref implementing_list, ref implementing_iface);
3205 if (IsImplementing == false) {
3206 TypeContainer.Error_NotInterfaceMember (
3207 Location, name, prefix);
3214 // For implicit implementations, make sure we are public, for
3215 // explicit implementations, make sure we are private.
3217 //if (IsImplementing){
3219 // Setting null inside this block will trigger a more
3220 // verbose error reporting for missing interface implementations
3222 // The "candidate" function has been flagged already
3223 // but it wont get cleared
3225 /* if (!member.IsExplicitImpl){
3227 // We already catch different accessibility settings
3228 // so we just need to check that we are not private
3230 if ((modifiers & Modifiers.PRIVATE) != 0)
3231 implementing = null;
3234 // Static is not allowed
3236 if ((modifiers & Modifiers.STATIC) != 0)
3237 implementing = null;
3239 if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
3240 Modifiers.Error_InvalidModifier (Location, "public, virtual or abstract");
3241 implementing = null;
3247 // If implementing is still valid, set flags
3249 if (IsImplementing){
3251 // When implementing interface methods, set NewSlot.
3253 if (implementing_list != null && implementing_list.Count != 0)
3254 flags |= MethodAttributes.NewSlot;
3257 MethodAttributes.Virtual |
3258 MethodAttributes.HideBySig;
3262 // Create the MethodBuilder for the method
3264 if ((flags & MethodAttributes.PinvokeImpl) != 0) {
3265 if ((modifiers & Modifiers.STATIC) == 0) {
3266 Report.Error (601, Location,
3267 "The DllImport attribute must be specified on " +
3268 "a method marked 'static' and 'extern'.");
3272 EmitContext ec = new EmitContext (
3273 parent, Location, null, ReturnType, modifiers);
3275 builder = dllimport_attribute.DefinePInvokeMethod (
3276 ec, parent.TypeBuilder, method_name, flags,
3277 ReturnType, ParameterTypes);
3279 builder = parent.TypeBuilder.DefineMethod (
3280 method_name, flags, CallingConventions,
3281 ReturnType, ParameterTypes);
3283 if (builder == null)
3286 if (IsImplementing) {
3288 // implement abstract methods from abstract classes
3290 if ((member.ModFlags & Modifiers.OVERRIDE) != 0) {
3291 if (member is Indexer)
3292 parent.Pending.ImplementIndexer (
3293 (Type) parent.TypeBuilder.BaseType,
3294 builder, ReturnType,
3295 ParameterTypes, true);
3297 parent.Pending.ImplementMethod (
3298 (Type) parent.TypeBuilder.BaseType,
3300 ParameterTypes, member.IsExplicitImpl);
3304 // implement abstract methods of interfaces
3306 if (member.Implements != null) {
3308 foreach (MethodInfo Impl in implementing_list) {
3309 if (member is Indexer)
3310 parent.Pending.ImplementIndexer (
3311 (Type) implementing_iface[pos++],
3312 builder, ReturnType,
3313 ParameterTypes, true);
3315 parent.Pending.ImplementMethod (
3316 (Type) implementing_iface[pos++],
3317 Impl.Name, ReturnType,
3318 ParameterTypes, member.IsExplicitImpl);
3320 parent.TypeBuilder.DefineMethodOverride (
3327 if (!TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes)) {
3328 Report.Error (111, Location,
3329 "Class `" + parent.Name +
3330 "' already contains a definition with the " +
3331 "same return value and parameter types as the " +
3332 "'get' method of property `" + member.Name + "'");
3336 TypeManager.AddMethod (builder, this);
3343 public virtual void Emit (TypeContainer parent, Block block, object kind)
3348 if ((flags & MethodAttributes.PinvokeImpl) == 0)
3349 ig = builder.GetILGenerator ();
3353 ec = new EmitContext (parent, Location, ig, ReturnType, modifiers);
3355 if (OptAttributes != null)
3356 Attribute.ApplyAttributes (ec, builder, kind, OptAttributes, Location);
3358 if (member is MethodCore)
3359 ((MethodCore) member).LabelParameters (ec, ParameterTypes, MethodBuilder);
3362 // abstract or extern methods have no bodies
3364 if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
3369 // abstract or extern methods have no bodies.
3371 if ((modifiers & Modifiers.ABSTRACT) != 0)
3373 500, Location, "Abstract method `" +
3374 TypeManager.MonoBASIC_Signature (builder) +
3375 "' can not have a body");
3377 if ((modifiers & Modifiers.EXTERN) != 0)
3379 179, Location, "External method `" +
3380 TypeManager.MonoBASIC_Signature (builder) +
3381 "' can not have a body");
3387 // Methods must have a body unless they're extern or abstract
3389 if (block == null) {
3391 501, Location, "Method `" +
3392 TypeManager.MonoBASIC_Signature (builder) +
3393 "' must declare a body since it is not marked " +
3394 "abstract or extern");
3399 // Handle destructors specially
3401 // FIXME: This code generates buggy code
3403 if (member.Name == "Finalize" && ReturnType == TypeManager.void_type)
3404 EmitDestructor (ec, block);
3406 ISymbolWriter sw = CodeGen.SymbolWriter;
3408 if ((sw != null) && !Location.IsNull (Location) &&
3409 !Location.IsNull (block.EndLocation)) {
3410 Location end = block.EndLocation;
3411 MethodToken token = MethodBuilder.GetToken ();
3412 sw.OpenMethod (new SymbolToken (token.Token));
3413 // Avoid error if we don't support debugging for the platform
3415 sw.SetMethodSourceRange (Location.SymbolDocument,
3419 } catch (Exception) {
3422 ec.EmitTopBlock (block, member.Name, ParameterInfo, Location);
3426 ec.EmitTopBlock (block, member.Name, ParameterInfo, Location);
3430 void EmitDestructor (EmitContext ec, Block block)
3432 ILGenerator ig = ec.ig;
3434 Label finish = ig.DefineLabel ();
3435 bool old_in_try = ec.InTry;
3437 ig.BeginExceptionBlock ();
3439 ec.ReturnLabel = finish;
3440 ec.HasReturnLabel = true;
3441 ec.EmitTopBlock (block, null, Location);
3442 ec.InTry = old_in_try;
3444 // ig.MarkLabel (finish);
3445 bool old_in_finally = ec.InFinally;
3446 ec.InFinally = true;
3447 ig.BeginFinallyBlock ();
3449 if (ec.ContainerType.BaseType != null) {
3450 Expression member_lookup = Expression.MemberLookup (
3451 ec, ec.ContainerType.BaseType, ec.ContainerType.BaseType, "Finalize",
3452 MemberTypes.Method, Expression.AllBindingFlags, Location);
3454 if (member_lookup != null){
3455 MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
3457 ig.Emit (OpCodes.Ldarg_0);
3458 ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
3461 ec.InFinally = old_in_finally;
3463 ig.EndExceptionBlock ();
3464 //ig.MarkLabel (ec.ReturnLabel);
3465 ig.Emit (OpCodes.Ret);
3469 abstract public class MemberBase : MemberCore {
3470 public Expression Type;
3471 public readonly Attributes OptAttributes;
3472 public ArrayList Implements;
3474 protected MethodAttributes flags;
3477 // The "short" name of this property / indexer / event. This is the
3478 // name without the explicit interface.
3480 public string ShortName;
3483 // The type of this property / indexer / event
3485 public Type MemberType;
3488 // If true, this is an explicit interface implementation
3490 public bool IsExplicitImpl = false;
3493 // The name of the interface we are explicitly implementing
3495 public string ExplicitInterfaceName = null;
3498 // If true, the interface type we are explicitly implementing
3500 public Type InterfaceType = null;
3501 public ArrayList InterfaceTypes = null;
3504 // The method we're overriding if this is an override method.
3506 protected MethodInfo parent_method = null;
3507 public MethodInfo ParentMethod {
3509 return parent_method;
3514 // The constructor is only exposed to our children
3516 protected MemberBase (Expression type, int mod, int allowed_mod, string name,
3517 Attributes attrs, Location loc)
3521 ModFlags = Modifiers.Check (allowed_mod, mod, Modifiers.PUBLIC, loc);
3522 OptAttributes = attrs;
3525 protected virtual bool CheckBase (TypeContainer parent)
3530 protected virtual bool CheckParameters (TypeContainer parent, Type [] parameters)
3534 foreach (Type partype in parameters){
3535 if (partype.IsPointer && !UnsafeOK (parent))
3538 if (parent.AsAccessible (partype, ModFlags))
3541 if (this is Indexer)
3542 Report.Error (55, Location,
3543 "Inconsistent accessibility: parameter type `" +
3544 TypeManager.MonoBASIC_Name (partype) + "' is less " +
3545 "accessible than indexer `" + Name + "'");
3547 Report.Error (51, Location,
3548 "Inconsistent accessibility: parameter type `" +
3549 TypeManager.MonoBASIC_Name (partype) + "' is less " +
3550 "accessible than method `" + Name + "'");
3557 protected virtual bool DoDefine (TypeContainer parent)
3562 if (!parent.MethodModifiersValid (ModFlags, Name, Location))
3565 flags = Modifiers.MethodAttr (ModFlags);
3567 // Lookup Type, verify validity
3568 MemberType = parent.ResolveType (Type, false, Location);
3569 if (MemberType == null)
3572 // check for whether the Interface is implemented by the class
3573 if (Implements != null) {
3574 InterfaceTypes = new ArrayList ();
3575 foreach (Expression Impls in Implements) {
3576 string iname = Impls.ToString();
3577 iname = iname.Substring(0, iname.LastIndexOf("."));
3578 bool iface_found = false;
3580 InterfaceType = RootContext.LookupType (
3581 parent, iname, false, Location);
3582 if (InterfaceType == null)
3585 InterfaceTypes.Add (InterfaceType);
3586 Type[] tbases = parent.TypeBuilder.GetInterfaces();
3588 if (tbases.Length != 0) {
3589 ArrayList bases = new ArrayList();
3590 TypeManager.ExpandAllInterfaces (tbases, ref bases);
3592 foreach (Type tbase in bases) {
3593 string bname = tbase.Name;
3594 if (bname.LastIndexOf(".") != -1)
3595 bname = bname.Substring(bname.LastIndexOf("."));
3597 if (bname == iname) {
3605 Report.Error (31035, Location,
3606 "Class '" + parent.Name + "' doesn't implement interface '" + iname + "'");
3612 // verify accessibility
3613 if (!parent.AsAccessible (MemberType, ModFlags)) {
3614 if (this is Property)
3615 Report.Error (53, Location,
3616 "Inconsistent accessibility: property type `" +
3617 TypeManager.MonoBASIC_Name (MemberType) + "' is less " +
3618 "accessible than property `" + Name + "'");
3619 else if (this is Indexer)
3620 Report.Error (54, Location,
3621 "Inconsistent accessibility: indexer return type `" +
3622 TypeManager.MonoBASIC_Name (MemberType) + "' is less " +
3623 "accessible than indexer `" + Name + "'");
3624 else if (this is Method)
3625 Report.Error (50, Location,
3626 "Inconsistent accessibility: return type `" +
3627 TypeManager.MonoBASIC_Name (MemberType) + "' is less " +
3628 "accessible than method `" + Name + "'");
3630 Report.Error (52, Location,
3631 "Inconsistent accessibility: field type `" +
3632 TypeManager.MonoBASIC_Name (MemberType) + "' is less " +
3633 "accessible than field `" + Name + "'");
3637 if (MemberType.IsPointer && !UnsafeOK (parent))
3641 // Check for explicit interface implementation
3643 if ((ExplicitInterfaceName == null) && (Name.IndexOf (".") != -1)) {
3644 int pos = Name.LastIndexOf (".");
3646 ExplicitInterfaceName = Name.Substring (0, pos);
3647 ShortName = Name.Substring (pos + 1);
3656 // Fields and Events both generate FieldBuilders, we use this to share
3657 // their common bits. This is also used to flag usage of the field
3659 abstract public class FieldBase : MemberBase {
3660 public FieldBuilder FieldBuilder;
3661 public Status status;
3664 public enum Status : byte { ASSIGNED = 1, USED = 2 }
3667 // The constructor is only exposed to our children
3669 protected FieldBase (Expression type, int mod, int allowed_mod, string name,
3670 object init, Attributes attrs, Location loc)
3671 : base (type, mod, allowed_mod, name, attrs, loc)
3677 // Whether this field has an initializer.
3679 public bool HasInitializer {
3681 return init != null;
3686 readonly Object init;
3687 Expression init_expr;
3688 bool init_expr_initialized = false;
3691 // Resolves and returns the field initializer.
3693 public Expression GetInitializerExpression (EmitContext ec)
3695 if (init_expr_initialized)
3699 if (init is Expression)
3700 e = (Expression) init;
3702 e = new ArrayCreation (Type, "", (ArrayList)init, Location);
3704 ec.IsFieldInitializer = true;
3705 e = e.DoResolve (ec);
3706 ec.IsFieldInitializer = false;
3709 init_expr_initialized = true;
3717 // The Field class is used to represents class/struct fields during parsing.
3719 public class Field : FieldBase {
3721 // Modifiers allowed in a class declaration
3723 const int AllowedModifiers =
3726 Modifiers.PROTECTED |
3727 Modifiers.INTERNAL |
3730 // Modifiers.VOLATILE |
3731 // Modifiers.UNSAFE |
3734 public Field (Expression type, int mod, string name, Object expr_or_array_init,
3735 Attributes attrs, Location loc)
3736 : base (type, mod, AllowedModifiers, name, expr_or_array_init, attrs, loc)
3740 public override bool Define (TypeContainer parent)
3742 Type t = parent.ResolveType (Type, false, Location);
3747 if (!parent.AsAccessible (t, ModFlags)) {
3748 Report.Error (52, Location,
3749 "Inconsistent accessibility: field type `" +
3750 TypeManager.MonoBASIC_Name (t) + "' is less " +
3751 "accessible than field `" + Name + "'");
3755 if (t.IsPointer && !UnsafeOK (parent))
3758 Type ptype = parent.TypeBuilder.BaseType;
3760 // ptype is only null for System.Object while compiling corlib.
3762 MemberList list = TypeContainer.FindMembers (
3763 ptype, MemberTypes.Field,
3764 BindingFlags.Public |
3765 BindingFlags.Static | BindingFlags.Instance,
3766 System.Type.FilterName, Name);
3768 if (RootContext.WarningLevel > 1){
3769 if ((list.Count > 0) && ((ModFlags & Modifiers.SHADOWS) == 0))
\r
3773 "Variable '" + Name + "' should be declared " +
3774 "Shadows since the base type '" + ptype.Name +
3775 "' has a variable with same name");
3777 ModFlags |= Modifiers.SHADOWS;
3780 if (list.Count == 0)
3781 // if a member of module is not inherited from Object class
3782 // can not be declared protected
3783 if ((parent is Module) && ((ModFlags & Modifiers.PROTECTED) != 0))
3784 Report.Error (30593, Location,
3785 "'Variable' inside a 'Module' can not be " +
3786 "declared as 'Protected'");
3789 if ((parent is Struct) && ((ModFlags & Modifiers.PROTECTED) != 0))
3790 Report.Error (30435, Location,
3791 "'Variable' inside a 'Structure' can not be " +
3792 "declared as 'Protected'");
3794 if ((ModFlags & Modifiers.VOLATILE) != 0){
3796 if (TypeManager.IsEnumType (t))
3797 t = TypeManager.EnumToUnderlying (t);
3799 if (!((t == TypeManager.bool_type) ||
3800 (t == TypeManager.sbyte_type) ||
3801 (t == TypeManager.byte_type) ||
3802 (t == TypeManager.short_type) ||
3803 (t == TypeManager.ushort_type) ||
3804 (t == TypeManager.int32_type) ||
3805 (t == TypeManager.uint32_type) ||
3806 (t == TypeManager.char_type) ||
3807 (t == TypeManager.float_type))){
3809 677, Location, parent.MakeName (Name) +
3810 " A volatile field can not be of type `" +
3811 TypeManager.MonoBASIC_Name (t) + "'");
3817 FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
3819 if (parent is Struct &&
3820 ((fa & FieldAttributes.Static) == 0) &&
3821 t == parent.TypeBuilder &&
3822 !TypeManager.IsBuiltinType (t)){
3823 Report.Error (523, Location, "Struct member `" + parent.Name + "." + Name +
3824 "' causes a cycle in the structure layout");
3827 FieldBuilder = parent.TypeBuilder.DefineField (
3828 Name, t, Modifiers.FieldAttr (ModFlags));
3830 TypeManager.RegisterFieldBase (FieldBuilder, this);
3834 public void Emit (TypeContainer tc)
3836 EmitContext ec = new EmitContext (tc, Location, null,
3837 FieldBuilder.FieldType, ModFlags);
3839 Attribute.ApplyAttributes (ec, FieldBuilder, this, OptAttributes, Location);
3844 // `set' and `get' accessors are represented with an Accessor.
3846 public class Accessor {
3848 // Null if the accessor is empty, or a Block if not
3851 public Attributes OptAttributes;
3853 public Accessor (Block b, Attributes attrs)
3856 OptAttributes = attrs;
3861 // Properties and Indexers both generate PropertyBuilders, we use this to share
3862 // their common bits.
3864 abstract public class PropertyBase : MethodCore {
3865 public Accessor Get, Set;
3866 public PropertyBuilder PropertyBuilder;
3867 public MethodBuilder GetBuilder, SetBuilder;
3868 public MethodData GetData, SetData;
3870 protected EmitContext ec;
3872 public PropertyBase (Expression type, string name, int mod_flags, int allowed_mod,
3873 Parameters parameters, Accessor get_block, Accessor set_block,
3874 Attributes attrs, Location loc)
3875 : base (type, mod_flags, allowed_mod, name, attrs, parameters, loc)
3881 protected override bool DoDefine (TypeContainer parent)
3883 if (!base.DoDefine (parent))
3886 ec = new EmitContext (parent, Location, null, MemberType, ModFlags);
3892 // Checks our base implementation if any
3894 protected override bool CheckBase (TypeContainer container)
3896 base.CheckBase (container);
3898 // Check whether arguments were correct.
3899 if (!DoDefineParameters (container))
3905 MethodSignature ms = new MethodSignature (Name, null, ParameterTypes);
3910 mi_this = TypeContainer.FindMembers (
3911 container.TypeBuilder, MemberTypes.Property,
3912 BindingFlags.NonPublic | BindingFlags.Public |
3913 BindingFlags.Static | BindingFlags.Instance |
3914 BindingFlags.DeclaredOnly,
3915 MethodSignature.method_signature_filter, ms);
3917 if (mi_this.Count > 0) {
3918 Report.Error (111, Location, "Class `" + container.Name + "' " +
3919 "already defines a member called `" + Name + "' " +
3920 "with the same parameter types");
3925 if (container is Interface)
3929 if ((ModFlags & Modifiers.READONLY) != 0)
3930 retval = MemberType;
3933 MethodSignature base_ms;
3934 if (this is Indexer) {
3935 string name, base_name;
3937 report_name = "this";
3938 name = TypeManager.IndexerPropertyName (container.TypeBuilder);
3939 ms = new MethodSignature (name, null, ParameterTypes);
3940 base_name = TypeManager.IndexerPropertyName (container.TypeBuilder.BaseType);
3941 base_ms = new MethodSignature (base_name, retval, ParameterTypes);
3944 ms = base_ms = new MethodSignature (Name, retval, ParameterTypes);
3948 // Verify if the parent has a type with the same name, and then
3949 // check whether we have to create a new slot for it or not.
3951 Type ptype = container.TypeBuilder.BaseType;
3953 MemberInfo parent_member = null;
3954 MemberList mi, mi_static, mi_instance;
3957 // Find properties with the same name on the base class
3959 mi_static = TypeContainer.FindMembers (
3960 ptype, MemberTypes.Property,
3961 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static,
3962 MethodSignature.inheritable_property_signature_filter, base_ms);
3964 mi_instance = TypeContainer.FindMembers (
3965 ptype, MemberTypes.Property,
3966 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance,
3967 MethodSignature.inheritable_property_signature_filter,
3971 if (mi_instance.Count > 0)
3973 else if (mi_static.Count > 0)
3978 if (mi != null && mi.Count > 0)
\r
3979 parent_member = (PropertyInfo) mi [0];
3981 if (parent_member is PropertyInfo) {
3982 PropertyInfo parent_property = (PropertyInfo)parent_member;
3984 string name = parent_property.DeclaringType.Name + "." +
3985 parent_property.Name;
3987 MethodInfo get, set, parent_method;
3988 get = parent_property.GetGetMethod (true);
3989 set = parent_property.GetSetMethod (true);
3992 parent_method = get;
3993 else if (set != null)
3994 parent_method = set;
3996 throw new Exception ("Internal error!");
3998 if (!CheckMethodAgainstBase (container, flags, parent_method, name))
4001 if ((ModFlags & Modifiers.NEW) == 0) {
4002 Type parent_type = TypeManager.TypeToCoreType (
4003 parent_property.PropertyType);
4005 if (parent_type != MemberType) {
4007 508, Location, container.MakeName (Name) + ": cannot " +
4008 "change return type when overriding " +
4009 "inherited member " + name);
4013 } else if (parent_member == null) {
4014 /*if ((ModFlags & Modifiers.NEW) != 0)
4015 WarningNotHiding (container);
4017 if ((ModFlags & Modifiers.OVERRIDE) != 0) {
4018 if (this is Indexer)
4019 Report.Error (115, Location,
4020 container.MakeName (Name) +
4021 " no suitable indexers found to override");
4023 Report.Error (115, Location,
4024 container.MakeName (Name) +
4025 " no suitable properties found to override");
4029 if ((ModFlags & ( Modifiers.NEW | Modifiers.SHADOWS | Modifiers.OVERRIDE )) == 0) {
4030 if ((ModFlags & Modifiers.NONVIRTUAL) != 0) {
4031 Report.Error (31088, Location,
4032 container.MakeName (Name) + " : Cannot " +
4033 "be declared NotOverridable since this method is " +
4034 "not maked as Overrides");
4037 // if a member of module is not inherited from Object class
4038 // can not be declared protected
4039 if ((container is Module) && ((ModFlags & Modifiers.PROTECTED) != 0))
4040 Report.Error (31066, Location,
4041 "'Property' inside a 'Module' can not be declared as " +
4042 "'Protected' or 'Protected Friend'");
4047 public virtual void Emit (TypeContainer tc)
4050 // The PropertyBuilder can be null for explicit implementations, in that
4051 // case, we do not actually emit the ".property", so there is nowhere to
4052 // put the attribute
4054 if (PropertyBuilder != null)
4055 Attribute.ApplyAttributes (ec, PropertyBuilder, this, OptAttributes, Location);
4057 if (GetData != null)
4058 GetData.Emit (tc, Get.Block, Get);
4060 if (SetData != null)
4061 SetData.Emit (tc, Set.Block, Set);
4066 public class Property : PropertyBase {
4067 const int AllowedModifiers =
4070 Modifiers.PROTECTED |
4071 Modifiers.INTERNAL |
4075 Modifiers.OVERRIDE |
4076 Modifiers.ABSTRACT |
4080 Modifiers.NONVIRTUAL |
4082 Modifiers.READONLY |
4083 Modifiers.WRITEONLY |
4086 string set_parameter_name;
4087 Parameters get_params;
4088 Parameters set_params;
4090 public Property (Expression type, string name, int mod_flags,
4091 Accessor get_block, Accessor set_block,
4092 Attributes attrs, Location loc, string set_name,
4093 Parameters p_get, Parameters p_set, ArrayList impl_what)
4094 : base (type, name, mod_flags, AllowedModifiers,
4096 get_block, set_block, attrs, loc)
4098 set_parameter_name = set_name;
4101 Implements = impl_what;
4104 public Property (Expression type, string name, int mod_flags,
4105 Accessor get_block, Accessor set_block,
4106 Attributes attrs, Location loc)
4107 : this (type, name, mod_flags, get_block, set_block, attrs, loc,
4108 "Value", Parameters.EmptyReadOnlyParameters, Parameters.EmptyReadOnlyParameters, null)
4112 public override bool Define (TypeContainer parent)
4114 Type [] g_parameters=null, s_parameters=null;
4115 Parameter [] g_parms, s_parms;
4116 InternalParameters g_ip=null, s_ip=null;
4118 if ((parent is Struct) && ((ModFlags & Modifiers.PROTECTED) != 0))
4119 Report.Error (30435, Location,
4120 "'Property' inside a 'Structure' can not be declared as " +
4121 "'Protected' or 'Protected Friend'");
4123 if (!DoDefine (parent))
4126 if (!CheckBase (parent))
4129 flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
4132 if ((ModFlags & Modifiers.WRITEONLY) == 0)
4135 "Property without 'Get' accessor must have a 'WriteOnly' modifier");
4138 if (get_params == Parameters.EmptyReadOnlyParameters) {
4139 g_parameters = TypeManager.NoTypes;
4140 g_ip = new InternalParameters (
4141 parent, Parameters.EmptyReadOnlyParameters);
4143 g_parameters = new Type [get_params.FixedParameters.Length];
4144 for (int i = 0; i < get_params.FixedParameters.Length; i ++) {
4145 g_parameters[i] = get_params.FixedParameters[i].ParameterType;
4147 g_parms = new Parameter [get_params.FixedParameters.Length];
4148 for (int i = 0; i < get_params.FixedParameters.Length; i ++) {
4149 Parameter tp = get_params.FixedParameters[i];
4150 g_parms[i] = new Parameter (tp.TypeName, tp.Name,
4151 Parameter.Modifier.NONE, null);
4153 g_ip = new InternalParameters (
4154 parent, new Parameters (g_parms, null, Location));
4157 GetData = new MethodData (this, "get", MemberType,
4158 g_parameters, g_ip, CallingConventions.Standard,
4159 Get.OptAttributes, ModFlags, flags, false);
4161 if (!GetData.Define (parent))
4164 GetBuilder = GetData.MethodBuilder;
4168 if ((ModFlags & Modifiers.READONLY) == 0)
4171 "Property without 'Set' accessor must have a 'ReadOnly' modifier");
4176 if (set_params == Parameters.EmptyReadOnlyParameters)
4178 s_parameters = new Type [1];
4179 s_parameters [0] = MemberType;
4181 s_parms = new Parameter [1];
4182 s_parms [0] = new Parameter (Type, set_parameter_name,
4183 Parameter.Modifier.NONE, null);
4185 s_parameters = new Type [set_params.FixedParameters.Length];
4186 for (int i = 0; i < set_params.FixedParameters.Length; i ++) {
4187 s_parameters[i] = set_params.FixedParameters[i].ParameterType;
4190 s_parms = new Parameter [set_params.FixedParameters.Length];
4191 for (int i = 0; i < set_params.FixedParameters.Length; i ++) {
4192 Parameter tp = set_params.FixedParameters[i];
4193 s_parms[i] = new Parameter (tp.TypeName, tp.Name,
4194 Parameter.Modifier.NONE, null);
4198 s_ip = new InternalParameters (
4199 parent, new Parameters (s_parms, null, Location));
4201 SetData = new MethodData (this, "set", TypeManager.void_type,
4202 s_parameters, s_ip, CallingConventions.Standard,
4203 Set.OptAttributes, ModFlags, flags, false);
4205 if (!SetData.Define (parent))
4208 SetBuilder = SetData.MethodBuilder;
4209 SetBuilder.DefineParameter (1, ParameterAttributes.None,
4210 set_parameter_name);
4213 // FIXME - PropertyAttributes.HasDefault ?
4215 PropertyAttributes prop_attr =
4216 PropertyAttributes.RTSpecialName |
4217 PropertyAttributes.SpecialName;
4219 if (!IsExplicitImpl){
4220 PropertyBuilder = parent.TypeBuilder.DefineProperty (
4221 Name, prop_attr, MemberType, null);
4223 PropertyBuilder.SetGetMethod (GetBuilder);
4224 PropertyBuilder.SetSetMethod (SetBuilder);
4227 // HACK for the reasons exposed above
4229 if (!TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder)) {
4232 "Class `" + parent.Name +
4233 "' already contains a definition for the property `" +
4241 public override void Emit (TypeContainer tc)
4245 if (GetData != null)
4247 Parameters = get_params;
4248 GetData.Emit (tc, Get.Block, Get);
4251 if (SetData != null)
4253 Parameters = set_params;
4254 SetData.Emit (tc, Set.Block, Set);
4261 /// Gigantic workaround for lameness in SRE follows :
4262 /// This class derives from EventInfo and attempts to basically
4263 /// wrap around the EventBuilder so that FindMembers can quickly
4264 /// return this in it search for members
4266 public class MyEventBuilder : EventInfo {
4269 // We use this to "point" to our Builder which is
4270 // not really a MemberInfo
4272 EventBuilder MyBuilder;
4275 // We "catch" and wrap these methods
4277 MethodInfo raise, remove, add;
4279 EventAttributes attributes;
4280 Type declaring_type, reflected_type, event_type;
4283 public MyEventBuilder (TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
4285 MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
4287 // And now store the values in our own fields.
4289 declaring_type = type_builder;
4291 reflected_type = type_builder;
4293 attributes = event_attr;
4295 this.event_type = event_type;
4299 // Methods that you have to override. Note that you only need
4300 // to "implement" the variants that take the argument (those are
4301 // the "abstract" methods, the others (GetAddMethod()) are
4304 public override MethodInfo GetAddMethod (bool nonPublic)
4309 public override MethodInfo GetRemoveMethod (bool nonPublic)
4314 public override MethodInfo GetRaiseMethod (bool nonPublic)
4320 // These methods make "MyEventInfo" look like a Builder
4322 public void SetRaiseMethod (MethodBuilder raiseMethod)
4324 raise = raiseMethod;
4325 MyBuilder.SetRaiseMethod (raiseMethod);
4328 public void SetRemoveOnMethod (MethodBuilder removeMethod)
4330 remove = removeMethod;
4331 MyBuilder.SetRemoveOnMethod (removeMethod);
4334 public void SetAddOnMethod (MethodBuilder addMethod)
4337 MyBuilder.SetAddOnMethod (addMethod);
4340 public void SetCustomAttribute (CustomAttributeBuilder cb)
4342 MyBuilder.SetCustomAttribute (cb);
4345 public override object [] GetCustomAttributes (bool inherit)
4347 // FIXME : There's nothing which can be seemingly done here because
4348 // we have no way of getting at the custom attribute objects of the
4353 public override object [] GetCustomAttributes (Type t, bool inherit)
4355 // FIXME : Same here !
4359 public override bool IsDefined (Type t, bool b)
4364 public override EventAttributes Attributes {
4370 public override string Name {
4376 public override Type DeclaringType {
4378 return declaring_type;
4382 public override Type ReflectedType {
4384 return reflected_type;
4388 public Type EventType {
4395 public class Event : FieldBase {
4396 const int AllowedModifiers =
4399 Modifiers.PROTECTED |
4400 Modifiers.INTERNAL |
4405 Modifiers.OVERRIDE |
4409 public readonly Accessor Add;
4410 public readonly Accessor Remove;
4411 public MyEventBuilder EventBuilder;
4413 MethodBuilder AddBuilder, RemoveBuilder;
4414 MethodData AddData, RemoveData;
4416 public Event (Expression type, string name, Object init, int mod, Accessor add,
4417 Accessor remove, Attributes attrs, Location loc)
4418 : base (type, mod, AllowedModifiers, name, init, attrs, loc)
4425 public Event (Expression type, string name, Object init, int mod, Accessor add,
4426 Accessor remove, Attributes attrs, ArrayList impl_what, Location loc)
4427 : base (type, mod, AllowedModifiers, name, init, attrs, loc)
4431 Implements = impl_what;
4435 public override bool Define (TypeContainer parent)
4437 EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
4439 if (!DoDefine (parent))
4442 if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) {
4443 Report.Error (31044, Location, "'" + parent.Name + "." + Name +
4444 "' : event must be of a delegate type");
4448 Type [] parameter_types = new Type [1];
4449 parameter_types [0] = MemberType;
4451 Parameter [] parms = new Parameter [1];
4452 parms [0] = new Parameter (Type, /* was "value" */ this.Name, Parameter.Modifier.NONE, null);
4453 InternalParameters ip = new InternalParameters (
4454 parent, new Parameters (parms, null, Location));
4456 if (!CheckBase (parent))
4460 // Now define the accessors
4462 AddData = new MethodData (this, "add", TypeManager.void_type,
4463 parameter_types, ip, CallingConventions.Standard,
4464 (Add != null) ? Add.OptAttributes : null,
4465 ModFlags, flags, false);
4467 if (!AddData.Define (parent))
4470 AddBuilder = AddData.MethodBuilder;
4471 AddBuilder.DefineParameter (1, ParameterAttributes.None, /* was "value" */ this.Name);
4473 RemoveData = new MethodData (this, "remove", TypeManager.void_type,
4474 parameter_types, ip, CallingConventions.Standard,
4475 (Remove != null) ? Remove.OptAttributes : null,
4476 ModFlags, flags, false);
4478 if (!RemoveData.Define (parent))
4481 RemoveBuilder = RemoveData.MethodBuilder;
4482 RemoveBuilder.DefineParameter (1, ParameterAttributes.None, /* was "value" */ this.Name);
4484 if (!IsExplicitImpl){
4485 EventBuilder = new MyEventBuilder (
4486 parent.TypeBuilder, Name, e_attr, MemberType);
4488 if (Add == null && Remove == null) {
4489 FieldBuilder = parent.TypeBuilder.DefineField (
4491 FieldAttributes.FamANDAssem | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
4492 TypeManager.RegisterPrivateFieldOfEvent (
4493 (EventInfo) EventBuilder, FieldBuilder);
4494 TypeManager.RegisterFieldBase (FieldBuilder, this);
4497 EventBuilder.SetAddOnMethod (AddBuilder);
4498 EventBuilder.SetRemoveOnMethod (RemoveBuilder);
4500 if (!TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder)) {
4501 Report.Error (111, Location,
4502 "Class `" + parent.Name +
4503 "' already contains a definition for the event `" +
4512 void EmitDefaultMethod (EmitContext ec, bool is_add)
4514 ILGenerator ig = ec.ig;
4515 MethodInfo method = null;
4518 method = TypeManager.delegate_combine_delegate_delegate;
4520 method = TypeManager.delegate_remove_delegate_delegate;
4522 if ((ModFlags & Modifiers.STATIC) != 0) {
4523 ig.Emit (OpCodes.Ldsfld, (FieldInfo) FieldBuilder);
4524 ig.Emit (OpCodes.Ldarg_0);
4525 ig.Emit (OpCodes.Call, method);
4526 ig.Emit (OpCodes.Castclass, MemberType);
4527 ig.Emit (OpCodes.Stsfld, (FieldInfo) FieldBuilder);
4529 ig.Emit (OpCodes.Ldarg_0);
4530 ig.Emit (OpCodes.Ldarg_0);
4531 ig.Emit (OpCodes.Ldfld, (FieldInfo) FieldBuilder);
4532 ig.Emit (OpCodes.Ldarg_1);
4533 ig.Emit (OpCodes.Call, method);
4534 ig.Emit (OpCodes.Castclass, MemberType);
4535 ig.Emit (OpCodes.Stfld, (FieldInfo) FieldBuilder);
4537 ig.Emit (OpCodes.Ret);
4540 public void Emit (TypeContainer tc)
4544 ec = new EmitContext (tc, Location, null, MemberType, ModFlags);
4545 Attribute.ApplyAttributes (ec, EventBuilder, this, OptAttributes, Location);
4548 AddData.Emit (tc, Add.Block, Add);
4550 ILGenerator ig = AddData.MethodBuilder.GetILGenerator ();
4551 ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
4552 EmitDefaultMethod (ec, true);
4556 RemoveData.Emit (tc, Remove.Block, Remove);
4558 ILGenerator ig = RemoveData.MethodBuilder.GetILGenerator ();
4559 ec = new EmitContext (tc, Location, ig, TypeManager.void_type, ModFlags);
4560 EmitDefaultMethod (ec, false);
4567 // FIXME: This does not handle:
4569 // int INTERFACENAME [ args ]
4574 // int this [ args ]
4576 public class Indexer : PropertyBase {
4578 const int AllowedModifiers =
4581 Modifiers.PROTECTED |
4582 Modifiers.INTERNAL |
4586 Modifiers.OVERRIDE |
4591 public string IndexerName;
4592 public string InterfaceIndexerName;
4595 // Are we implementing an interface ?
4597 bool IsImplementing = false;
4599 public Indexer (Expression type, string int_type, int flags, Parameters parameters,
4600 Accessor get_block, Accessor set_block, Attributes attrs, Location loc)
4601 : base (type, "", flags, AllowedModifiers, parameters, get_block, set_block,
4604 ExplicitInterfaceName = int_type;
4607 public override bool Define (TypeContainer parent)
4609 PropertyAttributes prop_attr =
4610 PropertyAttributes.RTSpecialName |
4611 PropertyAttributes.SpecialName;
4613 if (!DoDefine (parent))
4616 IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
4617 if (IndexerName == null)
4618 IndexerName = "Item";
4619 else if (IsExplicitImpl)
4620 Report.Error (592, Location,
4621 "Attribute 'IndexerName' is not valid on this declaration " +
4622 "type. It is valid on `property' declarations only.");
4624 ShortName = IndexerName;
4625 if (IsExplicitImpl) {
4626 InterfaceIndexerName = TypeManager.IndexerPropertyName (InterfaceType);
4627 Name = InterfaceType.FullName + "." + IndexerName;
4629 InterfaceIndexerName = IndexerName;
4633 if (!CheckBase (parent))
4637 InternalParameters ip = new InternalParameters (parent, Parameters);
4639 GetData = new MethodData (this, "get", MemberType,
4640 ParameterTypes, ip, CallingConventions.Standard,
4641 Get.OptAttributes, ModFlags, flags, false);
4643 if (!GetData.Define (parent))
4646 GetBuilder = GetData.MethodBuilder;
4650 int top = ParameterTypes.Length;
4651 Type [] set_pars = new Type [top + 1];
4652 ParameterTypes.CopyTo (set_pars, 0);
4653 set_pars [top] = MemberType;
4655 Parameter [] fixed_parms = Parameters.FixedParameters;
4657 if (fixed_parms == null){
4658 throw new Exception ("We currently do not support only array arguments in an indexer");
4659 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4660 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4662 // Here is the problem: the `value' parameter has
4663 // to come *after* the array parameter in the declaration
4665 // X (object [] x, Type value)
4668 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4669 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4673 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
4676 fixed_parms.CopyTo (tmp, 0);
4677 tmp [fixed_parms.Length] = new Parameter (
4678 Type, /* was "value" */ this.Name, Parameter.Modifier.NONE, null);
4680 Parameters set_formal_params = new Parameters (tmp, null, Location);
4682 InternalParameters ip = new InternalParameters (parent, set_formal_params);
4684 SetData = new MethodData (this, "set", TypeManager.void_type,
4685 set_pars, ip, CallingConventions.Standard,
4686 Set.OptAttributes, ModFlags, flags, false);
4688 if (!SetData.Define (parent))
4691 SetBuilder = SetData.MethodBuilder;
4695 // Now name the parameters
4697 Parameter [] p = Parameters.FixedParameters;
4701 for (i = 0; i < p.Length; ++i) {
4703 GetBuilder.DefineParameter (
4704 i + 1, p [i].Attributes, p [i].Name);
4707 SetBuilder.DefineParameter (
4708 i + 1, p [i].Attributes, p [i].Name);
4713 SetBuilder.DefineParameter (
4714 i + 1, ParameterAttributes.None, /* was "value" */ this.Name);
4716 if (i != ParameterTypes.Length) {
4717 Parameter array_param = Parameters.ArrayParameter;
4718 SetBuilder.DefineParameter (
4719 i + 1, array_param.Attributes, array_param.Name);
4723 if (GetData != null)
4724 IsImplementing = GetData.IsImplementing;
4725 else if (SetData != null)
4726 IsImplementing = SetData.IsImplementing;
4729 // Define the PropertyBuilder if one of the following conditions are met:
4730 // a) we're not implementing an interface indexer.
4731 // b) the indexer has a different IndexerName and this is no
4732 // explicit interface implementation.
4734 if (!IsExplicitImpl) {
4735 PropertyBuilder = parent.TypeBuilder.DefineProperty (
4736 IndexerName, prop_attr, MemberType, ParameterTypes);
4738 if (GetData != null)
4739 PropertyBuilder.SetGetMethod (GetBuilder);
4741 if (SetData != null)
4742 PropertyBuilder.SetSetMethod (SetBuilder);
4744 TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
4752 public class Operator : MemberCore {
4754 const int AllowedModifiers =
4760 const int RequiredModifiers =
4764 public enum OpType : byte {
4774 // Unary and Binary operators
4797 // Implicit and Explicit
4802 public readonly OpType OperatorType;
4803 public readonly Expression ReturnType;
4804 public readonly Expression FirstArgType, SecondArgType;
4805 public readonly string FirstArgName, SecondArgName;
4806 public readonly Block Block;
4807 public Attributes OptAttributes;
4808 public MethodBuilder OperatorMethodBuilder;
4810 public string MethodName;
4811 public Method OperatorMethod;
4813 public Operator (OpType type, Expression ret_type, int flags,
4814 Expression arg1type, string arg1name,
4815 Expression arg2type, string arg2name,
4816 Block block, Attributes attrs, Location loc)
4819 OperatorType = type;
4820 ReturnType = ret_type;
4821 ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PUBLIC, loc);
4822 FirstArgType = arg1type;
4823 FirstArgName = arg1name;
4824 SecondArgType = arg2type;
4825 SecondArgName = arg2name;
4827 OptAttributes = attrs;
4830 string Prototype (TypeContainer parent)
4832 return parent.Name + ".operator " + OperatorType + " (" + FirstArgType + "," +
4833 SecondArgType + ")";
4836 public override bool Define (TypeContainer parent)
4839 MethodName = "op_" + OperatorType;
4841 if (SecondArgType != null)
4844 Parameter [] param_list = new Parameter [length];
4846 if ((ModFlags & RequiredModifiers) != RequiredModifiers){
4849 "User defined operators `" +
4850 Prototype (parent) +
4851 "' must be declared static and public");
4855 param_list[0] = new Parameter (FirstArgType, FirstArgName,
4856 Parameter.Modifier.NONE, null);
4857 if (SecondArgType != null)
4858 param_list[1] = new Parameter (SecondArgType, SecondArgName,
4859 Parameter.Modifier.NONE, null);
4861 OperatorMethod = new Method (ReturnType, ModFlags, MethodName,
4862 new Parameters (param_list, null, Location),
4863 OptAttributes, Mono.MonoBASIC.Location.Null);
4865 OperatorMethod.IsOperator = true;
4866 OperatorMethod.Define (parent);
4868 if (OperatorMethod.MethodBuilder == null)
4871 OperatorMethodBuilder = OperatorMethod.MethodBuilder;
4873 Type [] param_types = OperatorMethod.ParameterTypes;
4874 Type declaring_type = OperatorMethodBuilder.DeclaringType;
4875 Type return_type = OperatorMethod.GetReturnType ();
4876 Type first_arg_type = param_types [0];
4878 // Rules for conversion operators
4880 if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
4881 if (first_arg_type == return_type && first_arg_type == declaring_type){
4884 "User-defined conversion cannot take an object of the " +
4885 "enclosing type and convert to an object of the enclosing" +
4890 if (first_arg_type != declaring_type && return_type != declaring_type){
4893 "User-defined conversion must convert to or from the " +
4898 if (first_arg_type == TypeManager.object_type ||
4899 return_type == TypeManager.object_type){
4902 "User-defined conversion cannot convert to or from " +
4907 if (first_arg_type.IsInterface || return_type.IsInterface){
4910 "User-defined conversion cannot convert to or from an " +
4915 if (first_arg_type.IsSubclassOf (return_type) ||
4916 return_type.IsSubclassOf (first_arg_type)){
4919 "User-defined conversion cannot convert between types " +
4920 "that derive from each other");
4923 } else if (SecondArgType == null) {
4924 // Checks for Unary operators
4926 if (first_arg_type != declaring_type){
4929 "The parameter of a unary operator must be the " +
4934 if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
4935 if (return_type != declaring_type){
4938 "The parameter and return type for ++ and -- " +
4939 "must be the containing type");
4945 if (OperatorType == OpType.True || OperatorType == OpType.False) {
4946 if (return_type != TypeManager.bool_type){
4949 "The return type of operator True or False " +
4956 // Checks for Binary operators
4958 if (first_arg_type != declaring_type &&
4959 param_types [1] != declaring_type){
4962 "One of the parameters of a binary operator must " +
4963 "be the containing type");
4971 public void Emit (TypeContainer parent)
4973 EmitContext ec = new EmitContext (parent, Location, null, null, ModFlags);
4974 Attribute.ApplyAttributes (ec, OperatorMethodBuilder, this, OptAttributes, Location);
4977 // abstract or extern methods have no bodies
4979 if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
4982 OperatorMethod.Block = Block;
4983 OperatorMethod.Emit (parent);
4986 public static string GetName (OpType ot)
4989 case OpType.LogicalNot:
4991 case OpType.OnesComplement:
4993 case OpType.Increment:
4995 case OpType.Decrement:
5001 case OpType.Addition:
5003 case OpType.Subtraction:
5005 case OpType.UnaryPlus:
5007 case OpType.UnaryNegation:
5009 case OpType.Multiply:
5011 case OpType.Division:
5013 case OpType.Modulus:
5015 case OpType.BitwiseAnd:
5017 case OpType.BitwiseOr:
5019 case OpType.ExclusiveOr:
5021 case OpType.LeftShift:
5023 case OpType.RightShift:
5025 case OpType.Equality:
5027 case OpType.Inequality:
5029 case OpType.GreaterThan:
5031 case OpType.LessThan:
5033 case OpType.GreaterThanOrEqual:
5035 case OpType.LessThanOrEqual:
5037 case OpType.Implicit:
5039 case OpType.Explicit:
5045 public override string ToString ()
5047 Type return_type = OperatorMethod.GetReturnType();
5048 Type [] param_types = OperatorMethod.ParameterTypes;
5050 if (SecondArgType == null)
5051 return String.Format (
5052 "{0} operator {1}({2})",
5053 TypeManager.MonoBASIC_Name (return_type),
5054 GetName (OperatorType),
5057 return String.Format (
5058 "{0} operator {1}({2}, {3})",
5059 TypeManager.MonoBASIC_Name (return_type),
5060 GetName (OperatorType),
5061 param_types [0], param_types [1]);
5066 // This is used to compare method signatures
5068 struct MethodSignature {
5070 public Type RetType;
5071 public Type [] Parameters;
5074 /// This delegate is used to extract methods which have the
5075 /// same signature as the argument
5077 public static MemberFilter method_signature_filter;
5080 /// This delegate is used to extract methods which have the
5081 /// same signature as the argument except for the name
5083 public static MemberFilter method_signature_noname_filter;
5086 /// This delegate is used to extract inheritable methods which
5087 /// have the same signature as the argument. By inheritable,
5088 /// this means that we have permissions to override the method
5089 /// from the current assembly and class
5091 public static MemberFilter inheritable_method_signature_filter;
5094 /// This delegate is used to extract inheritable methods which
5095 /// have the same signature as the argument. By inheritable,
5096 /// this means that we have permissions to override the method
5097 /// from the current assembly and class
5099 public static MemberFilter inheritable_property_signature_filter;
5101 static MethodSignature ()
5103 method_signature_filter = new MemberFilter (MemberSignatureCompare);
5104 method_signature_noname_filter = new MemberFilter (MemberSignatureCompareNoName);
5105 inheritable_method_signature_filter = new MemberFilter (
5106 InheritableMemberSignatureCompare);
5107 inheritable_property_signature_filter = new MemberFilter (
5108 InheritablePropertySignatureCompare);
5111 public MethodSignature (string name, Type ret_type, Type [] parameters)
5116 if (parameters == null)
5117 Parameters = TypeManager.NoTypes;
5119 Parameters = parameters;
5122 public override int GetHashCode ()
5124 return Name.GetHashCode ();
5127 public override bool Equals (Object o)
5129 MethodSignature other = (MethodSignature) o;
5131 if (other.Name != Name)
5134 if (other.RetType != RetType)
5137 if (Parameters == null){
5138 if (other.Parameters == null)
5143 if (other.Parameters == null)
5146 int c = Parameters.Length;
5147 if (other.Parameters.Length != c)
5150 for (int i = 0; i < c; i++)
5151 if (other.Parameters [i] != Parameters [i])
5157 static bool MemberSignatureCompareNoName (MemberInfo m, object filter_criteria)
5159 return MemberSignatureCompare (m, filter_criteria, false);
5162 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
5164 return MemberSignatureCompare (m, filter_criteria, true);
5167 static bool MemberSignatureCompare (MemberInfo m, object filter_criteria, bool use_name)
5169 MethodSignature sig = (MethodSignature) filter_criteria;
5171 if (use_name && (m.Name != sig.Name))
5175 MethodInfo mi = m as MethodInfo;
5176 PropertyInfo pi = m as PropertyInfo;
5179 ReturnType = mi.ReturnType;
5180 else if (pi != null)
5181 ReturnType = pi.PropertyType;
5186 // we use sig.RetType == null to mean `do not check the
5187 // method return value.
5189 if (sig.RetType != null)
5190 if (ReturnType != sig.RetType)
5195 args = TypeManager.GetArgumentTypes (mi);
5197 args = TypeManager.GetArgumentTypes (pi);
5199 Type [] sigp = sig.Parameters;
5201 if (args.Length != sigp.Length)
5204 for (int i = args.Length; i > 0; ){
5206 if (args [i] != sigp [i])
5213 // This filter should be used when we are requesting methods that
5214 // we want to override.
5216 // This makes a number of assumptions, for example
5217 // that the methods being extracted are of a parent
5218 // class (this means we know implicitly that we are
5219 // being called to find out about members by a derived
5222 static bool InheritableMemberSignatureCompare (MemberInfo m, object filter_criteria)
5224 if (MemberSignatureCompare (m, filter_criteria)){
5225 MethodInfo mi = (MethodInfo) m;
5226 MethodAttributes prot = mi.Attributes & MethodAttributes.MemberAccessMask;
5228 // If only accessible to the current class.
5229 if (prot == MethodAttributes.Private)
5232 // If only accessible to the defining assembly or
5233 if (prot == MethodAttributes.FamANDAssem ||
5234 prot == MethodAttributes.Assembly){
5235 if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
5241 // Anything else (FamOrAssembly and Public) is fine
5248 // This filter should be used when we are requesting properties that
5249 // we want to override.
5251 // This makes a number of assumptions, for example
5252 // that the methods being extracted are of a parent
5253 // class (this means we know implicitly that we are
5254 // being called to find out about members by a derived
5257 static bool InheritablePropertySignatureCompare (MemberInfo m, object filter_criteria)
5259 if (MemberSignatureCompare (m, filter_criteria)){
5260 PropertyInfo pi = (PropertyInfo) m;
5262 MethodInfo inherited_get = TypeManager.GetPropertyGetter (pi);
5263 MethodInfo inherited_set = TypeManager.GetPropertySetter (pi);
5265 MethodInfo mi = inherited_get == null ? inherited_set : inherited_get;
5267 MethodAttributes prot = mi.Attributes & MethodAttributes.MemberAccessMask;
5269 // If only accessible to the current class.
5270 if (prot == MethodAttributes.Private)
5273 // If only accessible to the defining assembly or
5274 if (prot == MethodAttributes.FamANDAssem ||
5275 prot == MethodAttributes.Assembly){
5276 if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
5282 // Anything else (FamOrAssembly and Public) is fine