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 AddHandlers stements for events
92 // The emit context for toplevel objects.
96 // Pointers to the default constructor and the default static constructor
98 Constructor default_constructor
;
99 Constructor default_static_constructor
;
102 // Whether we have seen a static constructor for this class or not
104 bool have_static_constructor
= false;
107 // Whether we have at least one non-static field
109 bool have_nonstatic_fields
= false;
112 // This one is computed after we can distinguish interfaces
113 // from classes from the arraylist `type_bases'
115 string base_class_name
;
117 ArrayList type_bases
;
119 // Attributes for this type
120 protected Attributes attributes
;
122 // Information in the case we are an attribute type
124 AttributeUsageAttribute attribute_usage
= new AttributeUsageAttribute (AttributeTargets
.All
);
126 public AttributeUsageAttribute AttributeUsage
{
128 return attribute_usage
;
132 attribute_usage
= value;
136 // The interfaces we implement.
139 // The parent member container and our member cache
140 IMemberContainer parent_container
;
141 MemberCache member_cache
;
144 // The indexer name for this class
146 public string IndexerName
;
148 public TypeContainer (TypeContainer parent
, string name
, Location l
)
149 : base (parent
, name
, l
)
152 types
= new ArrayList ();
159 base_class_name
= null;
161 //Console.WriteLine ("New class " + name + " inside " + n);
164 public AdditionResult
AddConstant (Const constant
)
167 string basename
= constant
.Name
;
169 if ((res
= IsValid (basename
)) != AdditionResult
.Success
)
172 if (constants
== null)
173 constants
= new ArrayList ();
175 constants
.Add (constant
);
176 DefineName (Name
+ "." + basename
, constant
);
178 return AdditionResult
.Success
;
181 public AdditionResult
AddEnum (Mono
.MonoBASIC
.Enum e
)
185 if ((res
= IsValid (e
.Basename
)) != AdditionResult
.Success
)
189 enums
= new ArrayList ();
192 DefineName (e
.Name
, e
);
194 return AdditionResult
.Success
;
197 public AdditionResult
AddClass (Class c
)
201 if ((res
= IsValid (c
.Basename
)) != AdditionResult
.Success
)
206 DefineName (c
.Name
, c
);
209 // FIXME: Do we really need to explicitly add an empty default static constructor?
210 // Apparently we don't
211 /* if (c.default_static_constructor == null)
213 bool isModule = c is Mono.MonoBASIC.Module;
214 Constructor dc = new Constructor ("New", Parameters.EmptyReadOnlyParameters, null, c.Location);
215 dc.ModFlags = isModule ? Modifiers.PUBLIC | Modifiers.STATIC : Modifiers.PUBLIC;
216 c.AddConstructor (dc);
219 //--------------------------------------------------------------
221 return AdditionResult
.Success
;
224 public AdditionResult
AddStruct (Struct s
)
228 if ((res
= IsValid (s
.Basename
)) != AdditionResult
.Success
)
231 DefineName (s
.Name
, s
);
234 return AdditionResult
.Success
;
237 public AdditionResult
AddDelegate (Delegate d
)
241 if ((res
= IsValid (d
.Basename
)) != AdditionResult
.Success
)
244 if (delegates
== null)
245 delegates
= new ArrayList ();
247 DefineName (d
.Name
, d
);
250 return AdditionResult
.Success
;
253 public AdditionResult
AddMethod (Method method
)
255 string basename
= method
.Name
;
256 string fullname
= Name
+ "." + basename
;
258 Object
value = defined_names
[fullname
];
260 if (value != null && (!(value is Method
)))
261 return AdditionResult
.NameExists
;
263 if (basename
== Basename
)
264 return AdditionResult
.EnclosingClash
;
267 methods
= new ArrayList ();
269 if (method
.Name
.IndexOf (".") != -1)
270 methods
.Insert (0, method
);
272 methods
.Add (method
);
275 DefineName (fullname
, method
);
277 return AdditionResult
.Success
;
280 public AdditionResult
AddConstructor (Constructor c
)
283 return AdditionResult
.NotAConstructor
;
285 bool is_static
= (c
.ModFlags
& Modifiers
.STATIC
) != 0;
288 have_static_constructor
= true;
289 if (default_static_constructor
!= null){
290 Console
.WriteLine ("I have a static constructor already");
291 Console
.WriteLine (" " + default_static_constructor
);
292 return AdditionResult
.MethodExists
;
295 default_static_constructor
= c
;
298 /*if (default_constructor != null)
299 return AdditionResult.MethodExists;*/
300 default_constructor
= c
;
303 if (instance_constructors
== null)
304 instance_constructors
= new ArrayList ();
306 instance_constructors
.Add (c
);
309 return AdditionResult
.Success
;
312 public AdditionResult
AddInterface (Interface iface
)
316 if ((res
= IsValid (iface
.Basename
)) != AdditionResult
.Success
)
319 if (interfaces
== null)
320 interfaces
= new ArrayList ();
321 interfaces
.Add (iface
);
322 DefineName (iface
.Name
, iface
);
324 return AdditionResult
.Success
;
327 public AdditionResult
AddField (Field field
)
330 string basename
= field
.Name
;
332 if ((res
= IsValid (basename
)) != AdditionResult
.Success
)
336 fields
= new ArrayList ();
340 if (field
.HasInitializer
){
341 if ((field
.ModFlags
& Modifiers
.STATIC
) != 0) {
342 if (initialized_static_fields
== null)
343 initialized_static_fields
= new ArrayList ();
345 initialized_static_fields
.Add (field
);
348 // We have not seen a static constructor,
349 // but we will provide static initialization of fields
351 have_static_constructor
= true;
353 if (initialized_fields
== null)
354 initialized_fields
= new ArrayList ();
356 initialized_fields
.Add (field
);
360 if ((field
.ModFlags
& Modifiers
.STATIC
) == 0)
361 have_nonstatic_fields
= true;
363 DefineName (Name
+ "." + basename
, field
);
364 return AdditionResult
.Success
;
367 public AdditionResult
AddProperty (Property prop
)
370 string basename
= prop
.Name
;
372 if ((res
= IsValid (basename
)) != AdditionResult
.Success
)
375 if (properties
== null)
376 properties
= new ArrayList ();
378 if (prop
.Name
.IndexOf (".") != -1)
379 properties
.Insert (0, prop
);
381 properties
.Add (prop
);
382 DefineName (Name
+ "." + basename
, prop
);
384 return AdditionResult
.Success
;
387 public AdditionResult
AddEvent (Event e
)
390 string basename
= e
.Name
;
392 if ((res
= IsValid (basename
)) != AdditionResult
.Success
)
396 events
= new ArrayList ();
399 DefineName (Name
+ "." + basename
, e
);
401 return AdditionResult
.Success
;
404 public AdditionResult
AddIndexer (Indexer i
)
406 if (indexers
== null)
407 indexers
= new ArrayList ();
409 if (i
.InterfaceType
!= null)
410 indexers
.Insert (0, i
);
414 return AdditionResult
.Success
;
417 public AdditionResult
AddEventHandler (Statement stmt
)
419 if (handlers
== null)
420 handlers
= new ArrayList ();
423 return AdditionResult
.Success
;
426 public void RegisterOrder (Interface iface
)
428 if (interface_order
== null)
429 interface_order
= new ArrayList ();
431 interface_order
.Add (iface
);
434 public ArrayList Types
{
440 public ArrayList Methods
{
446 public ArrayList Constants
{
452 public ArrayList Interfaces
{
460 return base_class_name
;
464 public ArrayList Bases
{
474 public ArrayList Fields
{
484 public ArrayList InstanceConstructors
{
486 return instance_constructors
;
490 public ArrayList Properties
{
496 public ArrayList Events
{
502 public ArrayList Enums
{
508 public ArrayList Indexers
{
514 public ArrayList Delegates
{
520 public Attributes OptAttributes
{
526 public bool HaveStaticConstructor
{
528 return have_static_constructor
;
532 public virtual TypeAttributes TypeAttr
{
534 return Modifiers
.TypeAttr (ModFlags
, this);
538 public ArrayList EventHandlers
{
545 // Emits the instance field initializers
547 public bool EmitFieldInitializers (EmitContext ec
)
550 ILGenerator ig
= ec
.ig
;
551 Expression instance_expr
;
554 fields
= initialized_static_fields
;
555 instance_expr
= null;
557 fields
= initialized_fields
;
558 instance_expr
= new This (Location
.Null
).Resolve (ec
);
564 foreach (Field f
in fields
){
565 Expression e
= f
.GetInitializerExpression (ec
);
569 Location l
= f
.Location
;
570 FieldExpr fe
= new FieldExpr (f
.FieldBuilder
, l
);
571 fe
.InstanceExpression
= instance_expr
;
572 Expression a
= new Assign (fe
, e
, l
);
578 if (a
is ExpressionStatement
)
579 ((ExpressionStatement
) a
).EmitStatement (ec
);
581 throw new Exception ("Assign.Resolve returned a non ExpressionStatement");
589 // Defines the default constructors
591 void DefineDefaultConstructor (bool is_static
)
596 c
= new Constructor ("New", Parameters
.EmptyReadOnlyParameters
,
601 mods
= Modifiers
.STATIC
;
605 c
.Initializer
= new ConstructorBaseInitializer (
606 null, Parameters
.EmptyReadOnlyParameters
,
611 c
.Block
= new Block (null);
615 public void ReportStructInitializedInstanceError ()
617 string n
= TypeBuilder
.FullName
;
619 foreach (Field f
in initialized_fields
){
622 "`" + n
+ "." + f
.Name
+ "': can not have " +
623 "instance field initializers in structs");
628 /// The pending methods that need to be implemented (interfaces or abstract methods)
630 public PendingImplementation Pending
;
633 /// This function computes the Base class and also the
634 /// list of interfaces that the class or struct @c implements.
636 /// The return value is an array (might be null) of
637 /// interfaces implemented (as Types).
639 /// The @parent argument is set to the parent object or null
640 /// if this is `System.Object'.
642 Type
[] GetClassBases (bool is_class
, out Type parent
, out bool error
)
644 ArrayList bases
= Bases
;
653 parent
= TypeManager
.value_type
;
657 if (RootContext
.StdLib
)
658 parent
= TypeManager
.object_type
;
659 else if (Name
!= "System.Object")
660 parent
= TypeManager
.object_type
;
663 // If we are compiling our runtime,
664 // and we are defining ValueType, then our
665 // parent is `System.Object'.
667 if (!RootContext
.StdLib
&& Name
== "System.ValueType")
668 parent
= TypeManager
.object_type
;
675 // Bases should be null if there are no bases at all
679 if (is_class
&& (!(this is Interface
))){
680 Expression name
= (Expression
) bases
[0];
681 name
= ResolveTypeExpr (name
, false, Location
);
688 Type first
= name
.Type
;
694 parent
= TypeManager
.object_type
;
698 if (parent
.IsSealed
)
699 Report
.Error (30299, Location
,
700 "Class " + Name
+ " cannot inherit " +
701 "'NotInheritable' class " + TypeManager
.MonoBASIC_Name (parent
));
703 if (!AsAccessible (parent
, ModFlags
))
704 Report
.Error (30389, Location
,
705 "Inconsistent accessibility: base class `" +
706 TypeManager
.MonoBASIC_Name (parent
) + "' is less " +
707 "accessible than class `" +
714 Type
[] ifaces
= new Type
[count
-start
];
716 for (i
= start
, j
= 0; i
< count
; i
++, j
++){
717 Expression name
= (Expression
) bases
[i
];
718 Expression resolved
= ResolveTypeExpr (name
, false, Location
);
719 bases
[i
] = resolved
;
720 Type t
= resolved
.Type
;
726 if (is_class
== false && !t
.IsInterface
){
727 Report
.Error (527, "In Struct `" + Name
+ "', type `"+
728 name
+"' is not an interface");
735 Report
.Error (30258, "class `"+ Name
+
736 "': a class can not inherit from a struct/enum");
738 /*Report.Error (509, "class `"+ Name +
739 "': Cannot inherit from sealed class `"+
747 Report
.Error (30121, Name
+ ": A class cannot inherit " +
748 "more than one class");
754 for (int x
= 0; x
< j
; x
++) {
755 if (t
== ifaces
[x
]) {
756 Report
.Error (528, "`" + name
+ "' is already listed in interface list");
769 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
771 public override TypeBuilder
DefineType ()
777 if (TypeBuilder
!= null)
790 ec
= new EmitContext (this, Mono
.MonoBASIC
.Location
.Null
, null, null, ModFlags
);
792 if (((ModFlags
& Modifiers
.ABSTRACT
) != 0) &&
793 ((ModFlags
& Modifiers
.SEALED
) != 0)){
794 Report
.Error (31408, Location
,
795 "Class declared as 'MustInherit' cannot be declared as 'NotInheritable'");
798 ifaces
= GetClassBases (is_class
, out parent
, out error
);
802 if (this is Interface
)
805 if (is_class
&& parent
!= null){
806 if (parent
== TypeManager
.enum_type
||
807 (parent
== TypeManager
.value_type
&& RootContext
.StdLib
) ||
808 parent
== TypeManager
.delegate_type
||
809 parent
== TypeManager
.array_type
){
811 644, Location
, "`" + Name
+ "' cannot inherit from " +
812 "special class `" + TypeManager
.MonoBASIC_Name (parent
) + "'");
817 if (!is_class
&& TypeManager
.value_type
== null)
818 throw new Exception ();
820 if (is_class
&& Parent
.Parent
== null && (!(this is Interface
)))
822 if ((ModFlags
& Modifiers
.PRIVATE
) != 0)
823 Report
.Error (31089, Location
,
824 "Only internal classes can be declared as 'Private'");
826 if ((ModFlags
& Modifiers
.PROTECTED
) != 0)
827 Report
.Error (31047, Location
,
828 "Only internal classes can be declared as 'Protected'");
831 if ((Parent
is Module
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
832 Report
.Error (30735, Location
,
833 "'Type' inside a 'Module' can not be " +
834 "declared as 'Protected'");
836 if ((Parent
is Struct
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
837 Report
.Error (30435, Location
,
838 "'Type' inside a 'Structure' can not be " +
839 "declared as 'Protected'");
841 TypeAttributes type_attributes
= TypeAttr
;
843 // if (parent_builder is ModuleBuilder) {
845 ModuleBuilder builder
= CodeGen
.ModuleBuilder
;
846 TypeBuilder
= builder
.DefineType (
847 Name
, type_attributes
, parent
, ifaces
);
850 TypeBuilder builder
= Parent
.TypeBuilder
;
851 TypeBuilder
= builder
.DefineNestedType (
852 Basename
, type_attributes
, parent
, ifaces
);
857 // structure must contain atleast one member variable
858 if(!have_nonstatic_fields
){
860 30281, Location
, "Structure `" + Name
+ "' do not " +
861 "contain any member Variable");
863 /*TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
864 FieldAttributes.Private);*/
867 // add interfaces that were not added at type creation (weird API issue)
868 if (!have_nonstatic_fields
&& (ifaces
!= null)) {
869 foreach (Type i
in ifaces
)
870 TypeBuilder
.AddInterfaceImplementation (i
);
876 // Finish the setup for the EmitContext
878 ec
.ContainerType
= TypeBuilder
;
880 TypeManager
.AddUserType (Name
, TypeBuilder
, this, ifaces
);
882 if ((parent
!= null) &&
883 (parent
== TypeManager
.attribute_type
||
884 parent
.IsSubclassOf (TypeManager
.attribute_type
))) {
885 RootContext
.RegisterAttribute (this);
887 RootContext
.RegisterOrder (this);
889 if (Interfaces
!= null) {
890 foreach (Interface iface
in Interfaces
)
895 foreach (TypeContainer tc
in Types
)
899 if (Delegates
!= null) {
900 foreach (Delegate d
in Delegates
)
905 foreach (Enum en
in Enums
)
915 /// Defines the MemberCore objects that are in the `list' Arraylist
917 /// The `defined_names' array contains a list of members defined in
920 static ArrayList remove_list
= new ArrayList ();
921 void DefineMembers (ArrayList list
, MemberInfo
[] defined_names
)
925 // if one of the overloaded method is having
926 // Shadows or Overloads modifier all other should
927 // have the same modifier
928 Hashtable members
= new Hashtable();
930 foreach (MemberCore mc
in list
)
933 if(members
[mc
.Name
] == null)
935 foreach (MemberCore m
in list
)
937 if(m
.Name
== mc
.Name
)
939 if ((m
.ModFlags
& Modifiers
.SHADOWS
) != 0)
941 modval
= Modifiers
.SHADOWS
;
944 else if((m
.ModFlags
& Modifiers
.NEW
) != 0)
946 modval
= Modifiers
.NEW
;
950 members
.Add(mc
.Name
, modval
);
953 modval
= (int)members
[mc
.Name
];
956 if(((modval
& Modifiers
.SHADOWS
) != 0) && ((mc
.ModFlags
& Modifiers
.SHADOWS
) == 0))
959 "Function '" + mc
.Name
+ "': must be declared 'Shadows' " +
960 "because another '" + mc
.Name
+ "' declared 'Shadows'");
961 else if(((modval
& Modifiers
.NEW
) != 0) && ((mc
.ModFlags
& Modifiers
.NEW
) == 0))
964 "Function '" + mc
.Name
+ "': must be declared 'Overloads' " +
965 "because another '" + mc
.Name
+ "' declared 'Overloads'");
969 remove_list
.Clear ();
971 foreach (MemberCore mc
in list
){
972 if (!mc
.Define (this)){
973 remove_list
.Add (mc
);
977 if (defined_names
== null)
980 idx
= Array
.BinarySearch (defined_names
, mc
.Name
, mif_compare
);
982 if (RootContext
.WarningLevel
>= 4){
983 if ((mc
.ModFlags
& Modifiers
.NEW
) != 0)
984 Warning_KewywordNewNotRequired (mc
.Location
, mc
);
985 if ((mc
.ModFlags
& Modifiers
.SHADOWS
) != 0)
986 Warning_KewywordShadowsNotRequired (mc
.Location
, mc
);
991 MemberInfo match
= defined_names
[idx
];
993 if (match
is PropertyInfo
&& ((mc
.ModFlags
& Modifiers
.OVERRIDE
) != 0))
997 // If we are both methods, let the method resolution emit warnings
999 if (match
is MethodBase
&& mc
is MethodCore
)
1002 if (((mc
.ModFlags
& Modifiers
.SHADOWS
) == 0) && idx
> 0)
1003 Warning_KeywordShadowsRequired (mc
.Location
, defined_names
[idx
]);
1007 foreach (object o
in remove_list
)
1010 remove_list
.Clear ();
1014 // Defines the indexers, and also verifies that the IndexerNameAttribute in the
1015 // class is consisten. Either it is `Item' or it is the name defined by all the
1016 // indexers with the `IndexerName' attribute.
1018 // Turns out that the IndexerNameAttribute is applied to each indexer,
1019 // but it is never emitted, instead a DefaultName attribute is attached
1022 void DefineIndexers ()
1024 string class_indexer_name
= null;
1026 foreach (Indexer i
in Indexers
){
1031 name
= i
.IndexerName
;
1033 if (i
.InterfaceType
!= null)
1036 if (class_indexer_name
== null){
1037 class_indexer_name
= name
;
1041 if (name
== class_indexer_name
)
1045 668, "Two indexers have different names, " +
1046 " you should use the same name for all your indexers");
1048 if (class_indexer_name
== null)
1049 class_indexer_name
= "Item";
1050 IndexerName
= class_indexer_name
;
1053 static void Error_KeywordNotAllowed (Location loc
)
1055 Report
.Error (1530, loc
, "Keyword new not allowed for namespace elements");
1059 /// Populates our TypeBuilder with fields and methods
1061 public override bool DefineMembers (TypeContainer parent
)
1063 MemberInfo
[] defined_names
= null;
1065 if (interface_order
!= null){
1066 foreach (Interface iface
in interface_order
)
1067 if ((iface
.ModFlags
& Modifiers
.NEW
) == 0)
1068 iface
.DefineMembers (this);
1070 Error_KeywordNotAllowed (iface
.Location
);
1073 if (RootContext
.WarningLevel
> 1){
1077 // This code throws an exception in the comparer
1078 // I guess the string is not an object?
1080 ptype
= TypeBuilder
.BaseType
;
1082 defined_names
= (MemberInfo
[]) FindMembers (
1083 ptype
, MemberTypes
.All
& ~MemberTypes
.Constructor
,
1084 BindingFlags
.Public
| BindingFlags
.Instance
|
1085 BindingFlags
.Static
, null, null);
1087 Array
.Sort (defined_names
, mif_compare
);
1091 if (constants
!= null)
1092 DefineMembers (constants
, defined_names
);
1095 DefineMembers (fields
, defined_names
);
1097 if (this is Class
&& (!(this is Interface
))){
1098 if (instance_constructors
== null){
1099 if (default_constructor
== null)
1100 DefineDefaultConstructor (false);
1103 if (initialized_static_fields
!= null &&
1104 default_static_constructor
== null)
1105 DefineDefaultConstructor (true);
1108 if (this is Struct
){
1110 // Structs can not have initialized instance
1113 if (initialized_static_fields
!= null &&
1114 default_static_constructor
== null)
1115 DefineDefaultConstructor (true);
1117 if (initialized_fields
!= null)
1118 ReportStructInitializedInstanceError ();
1121 if (!(this is Interface
))
1122 Pending
= PendingImplementation
.GetPendingImplementations (this);
1124 // Constructors are not in the defined_names array
1126 if (instance_constructors
!= null)
1127 DefineMembers (instance_constructors
, null);
1129 if (default_static_constructor
!= null)
1130 default_static_constructor
.Define (this);
1132 if (methods
!= null)
1133 DefineMembers (methods
, defined_names
);
1135 if (properties
!= null)
1136 DefineMembers (properties
, defined_names
);
1139 DefineMembers (events
, defined_names
);
1141 if (indexers
!= null) {
1144 IndexerName
= "Item";
1147 DefineMembers (enums
, defined_names
);
1149 if (delegates
!= null)
1150 DefineMembers (delegates
, defined_names
);
1153 if (TypeBuilder
.BaseType
!= null)
1154 parent_container
= TypeManager
.LookupMemberContainer (TypeBuilder
.BaseType
);
1156 member_cache
= new MemberCache (this);
1162 public override bool Define (TypeContainer parent
)
1164 if (interface_order
!= null){
1165 foreach (Interface iface
in interface_order
)
1166 if ((iface
.ModFlags
& Modifiers
.NEW
) == 0)
1167 iface
.Define (this);
1174 /// This function is based by a delegate to the FindMembers routine
1176 static bool AlwaysAccept (MemberInfo m
, object filterCriteria
)
1182 /// This filter is used by FindMembers, and we just keep
1183 /// a global for the filter to `AlwaysAccept'
1185 static MemberFilter accepting_filter
;
1189 /// A member comparission method based on name only
1191 static IComparer mif_compare
;
1193 static TypeContainer ()
1195 accepting_filter
= new MemberFilter (AlwaysAccept
);
1196 mif_compare
= new MemberInfoCompare ();
1200 /// This method returns the members of this type just like Type.FindMembers would
1201 /// Only, we need to use this for types which are _being_ defined because MS'
1202 /// implementation can't take care of that.
1205 // FIXME: return an empty static array instead of null, that cleans up
1206 // some code and is consistent with some coding conventions I just found
1210 // Notice that in various cases we check if our field is non-null,
1211 // something that would normally mean that there was a bug elsewhere.
1213 // The problem happens while we are defining p-invoke methods, as those
1214 // will trigger a FindMembers, but this happens before things are defined
1216 // Since the whole process is a no-op, it is fine to check for null here.
1218 public override MemberList
FindMembers (MemberTypes mt
, BindingFlags bf
,
1219 MemberFilter filter
, object criteria
)
1221 ArrayList members
= new ArrayList ();
1224 if ((bf
& BindingFlags
.Public
) != 0)
1225 modflags
|= Modifiers
.PUBLIC
| Modifiers
.PROTECTED
|
1227 if ((bf
& BindingFlags
.NonPublic
) != 0)
1228 modflags
|= Modifiers
.PRIVATE
;
1230 int static_mask
= 0, static_flags
= 0;
1231 switch (bf
& (BindingFlags
.Static
| BindingFlags
.Instance
)) {
1232 case BindingFlags
.Static
:
1233 static_mask
= static_flags
= Modifiers
.STATIC
;
1236 case BindingFlags
.Instance
:
1237 static_mask
= Modifiers
.STATIC
;
1242 static_mask
= static_flags
= 0;
1246 Timer
.StartTimer (TimerType
.TcFindMembers
);
1249 filter
= accepting_filter
;
1251 if ((mt
& MemberTypes
.Field
) != 0) {
1252 if (fields
!= null) {
1253 foreach (Field f
in fields
) {
1254 if ((f
.ModFlags
& modflags
) == 0)
1256 if ((f
.ModFlags
& static_mask
) != static_flags
)
1259 FieldBuilder fb
= f
.FieldBuilder
;
1260 if (fb
!= null && filter (fb
, criteria
) == true)
1265 if (constants
!= null) {
1266 foreach (Const con
in constants
) {
1267 if ((con
.ModFlags
& modflags
) == 0)
1269 if ((con
.ModFlags
& static_mask
) != static_flags
)
1272 FieldBuilder fb
= con
.FieldBuilder
;
1273 if (fb
!= null && filter (fb
, criteria
) == true)
1279 if ((mt
& MemberTypes
.Method
) != 0) {
1280 if (methods
!= null) {
1281 foreach (Method m
in methods
) {
1282 if ((m
.ModFlags
& modflags
) == 0)
1284 if ((m
.ModFlags
& static_mask
) != static_flags
)
1287 MethodBuilder mb
= m
.MethodBuilder
;
1289 if (mb
!= null && filter (mb
, criteria
) == true)
1294 if (properties
!= null){
1295 foreach (Property p
in properties
){
1296 if ((p
.ModFlags
& modflags
) == 0)
1298 if ((p
.ModFlags
& static_mask
) != static_flags
)
1304 if (b
!= null && filter (b
, criteria
) == true)
1308 if (b
!= null && filter (b
, criteria
) == true)
1313 if (indexers
!= null){
1314 foreach (Indexer ix
in indexers
){
1315 if ((ix
.ModFlags
& modflags
) == 0)
1317 if ((ix
.ModFlags
& static_mask
) != static_flags
)
1323 if (b
!= null && filter (b
, criteria
) == true)
1327 if (b
!= null && filter (b
, criteria
) == true)
1333 if ((mt
& MemberTypes
.Event
) != 0) {
1335 foreach (Event e
in events
) {
1336 if ((e
.ModFlags
& modflags
) == 0)
1338 if ((e
.ModFlags
& static_mask
) != static_flags
)
1341 MemberInfo eb
= e
.EventBuilder
;
1342 if (eb
!= null && filter (eb
, criteria
) == true)
1343 members
.Add (e
.EventBuilder
);
1347 if ((mt
& MemberTypes
.Property
) != 0){
1348 if (properties
!= null)
1349 foreach (Property p
in properties
) {
1350 if ((p
.ModFlags
& modflags
) == 0)
1352 if ((p
.ModFlags
& static_mask
) != static_flags
)
1355 MemberInfo pb
= p
.PropertyBuilder
;
1357 if (pb
!= null && filter (pb
, criteria
) == true)
1358 members
.Add (p
.PropertyBuilder
);
1361 if (indexers
!= null)
1362 foreach (Indexer ix
in indexers
) {
1363 if ((ix
.ModFlags
& modflags
) == 0)
1365 if ((ix
.ModFlags
& static_mask
) != static_flags
)
1368 MemberInfo ib
= ix
.PropertyBuilder
;
1369 if (ib
!= null && filter (ib
, criteria
) == true) {
1370 members
.Add (ix
.PropertyBuilder
);
1375 if ((mt
& MemberTypes
.NestedType
) != 0) {
1377 foreach (TypeContainer t
in types
) {
1378 if ((t
.ModFlags
& modflags
) == 0)
1381 TypeBuilder tb
= t
.TypeBuilder
;
1382 if (tb
!= null && (filter (tb
, criteria
) == true))
1388 foreach (Enum en
in enums
){
1389 if ((en
.ModFlags
& modflags
) == 0)
1392 TypeBuilder tb
= en
.TypeBuilder
;
1393 if (tb
!= null && (filter (tb
, criteria
) == true))
1398 if (delegates
!= null){
1399 foreach (Delegate d
in delegates
){
1400 if ((d
.ModFlags
& modflags
) == 0)
1403 TypeBuilder tb
= d
.TypeBuilder
;
1404 if (tb
!= null && (filter (tb
, criteria
) == true))
1409 if (interfaces
!= null){
1410 foreach (Interface iface
in interfaces
){
1411 if ((iface
.ModFlags
& modflags
) == 0)
1414 TypeBuilder tb
= iface
.TypeBuilder
;
1415 if (tb
!= null && (filter (tb
, criteria
) == true))
1421 if ((mt
& MemberTypes
.Constructor
) != 0){
1422 if (((bf
& BindingFlags
.Instance
) != 0) && (instance_constructors
!= null)){
1423 foreach (Constructor c
in instance_constructors
){
1424 if ((c
.ModFlags
& modflags
) == 0)
1427 ConstructorBuilder cb
= c
.ConstructorBuilder
;
1429 if (filter (cb
, criteria
) == true)
1434 if (((bf
& BindingFlags
.Static
) != 0) && (default_static_constructor
!= null) &&
1435 ((default_static_constructor
.ModFlags
& modflags
) != 0)){
1436 ConstructorBuilder cb
=
1437 default_static_constructor
.ConstructorBuilder
;
1440 if (filter (cb
, criteria
) == true)
1446 // Lookup members in parent if requested.
1448 if (((bf
& BindingFlags
.DeclaredOnly
) == 0) && (TypeBuilder
.BaseType
!= null)) {
1449 if ((mt
& ~MemberTypes
.Constructor
) != 0) {
1450 MemberList list
= FindMembers (TypeBuilder
.BaseType
, mt
& ~MemberTypes
.Constructor
, bf
, filter
, criteria
);
1451 members
.AddRange (list
);
1455 Timer
.StopTimer (TimerType
.TcFindMembers
);
1457 return new MemberList (members
);
1460 public override MemberCache MemberCache
{
1462 return member_cache
;
1466 public static MemberList
FindMembers (Type t
, MemberTypes mt
, BindingFlags bf
,
1467 MemberFilter filter
, object criteria
)
1469 TypeContainer tc
= TypeManager
.LookupTypeContainer (t
);
1472 return tc
.FindMembers (mt
, bf
, filter
, criteria
);
1474 return new MemberList (t
.FindMembers (mt
, bf
, filter
, criteria
));
1478 // FindMethods will look for methods not only in the type `t', but in
1479 // any interfaces implemented by the type.
1481 public static MethodInfo
[] FindMethods (Type t
, BindingFlags bf
,
1482 MemberFilter filter
, object criteria
)
1488 /// Emits the values for the constants
1490 public void EmitConstants ()
1492 if (constants
!= null)
1493 foreach (Const con
in constants
)
1494 con
.EmitConstant (this);
1499 /// Emits the code, this step is performed after all
1500 /// the types, enumerations, constructors
1504 if (instance_constructors
!= null)
1505 foreach (Constructor c
in instance_constructors
)
1508 if (default_static_constructor
!= null)
1509 default_static_constructor
.Emit (this);
1511 if (methods
!= null)
1512 foreach (Method m
in methods
)
1515 if (properties
!= null)
1516 foreach (Property p
in properties
)
1519 if (indexers
!= null){
1520 foreach (Indexer ix
in indexers
)
1523 /*CustomAttributeBuilder cb = Interface.EmitDefaultMemberAttr (
1524 this, IndexerName, ModFlags, Location);
1525 TypeBuilder.SetCustomAttribute (cb);*/
1529 foreach (Field f
in fields
)
1532 if (events
!= null){
1533 foreach (Event e
in Events
)
1537 if (Pending
!= null)
1538 if (Pending
.VerifyPendingMethods ())
1541 Attribute
.ApplyAttributes (ec
, TypeBuilder
, this, OptAttributes
, Location
);
1544 // Check for internal or private fields that were never assigned
1546 if (fields
!= null && RootContext
.WarningLevel
>= 3) {
1547 foreach (Field f
in fields
) {
1548 if ((f
.ModFlags
& Modifiers
.PUBLIC
) != 0)
1553 169, f
.Location
, "Private field " +
1554 MakeName (f
.Name
) + " is never used");
1559 // Only report 649 on level 4
1561 if (RootContext
.WarningLevel
< 4)
1564 if ((f
.status
& Field
.Status
.ASSIGNED
) != 0)
1569 "Field " + MakeName (f
.Name
) + " is never assigned " +
1570 " to and will always have its default value");
1574 // if (types != null)
1575 // foreach (TypeContainer tc in types)
1579 public override void CloseType ()
1584 TypeBuilder
.CreateType ();
1586 } catch (TypeLoadException
){
1588 // This is fine, the code still created the type
1590 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
1591 // Console.WriteLine (e.Message);
1593 Console
.WriteLine ("In type: " + Name
);
1598 foreach (Enum en
in Enums
)
1601 if (interface_order
!= null){
1602 foreach (Interface iface
in interface_order
)
1607 foreach (TypeContainer tc
in Types
)
1611 foreach (TypeContainer tc
in Types
)
1612 if (!(tc
is Struct
))
1616 if (Delegates
!= null)
1617 foreach (Delegate d
in Delegates
)
1621 public string MakeName (string n
)
1623 return "`" + Name
+ "." + n
+ "'";
1626 public void Warning_KeywordShadowsRequired (Location l
, MemberInfo mi
)
1629 108, l
, "The keyword 'Shadows' is required on " +
1630 MakeName (mi
.Name
) + " because it shadows `" +
1631 mi
.ReflectedType
.Name
+ "." + mi
.Name
+ "'");
1634 public void Warning_KewywordShadowsNotRequired (Location l
, MemberCore mc
)
1637 109, l
, "The member " + MakeName (mc
.Name
) + " does not hide an " +
1638 "inherited member, the keyword shadows is not required");
1641 public void Warning_KewywordNewNotRequired (Location l
, MemberCore mc
)
1644 109, l
, "The member " + MakeName (mc
.Name
) + " does not hide an " +
1645 "inherited member, the keyword new is not required");
1648 public static int CheckMember (string name
, MemberInfo mi
, int ModFlags
)
1654 // Performs the validation on a Method's modifiers (properties have
1655 // the same properties).
1657 public bool MethodModifiersValid (int flags
, string n
, Location loc
)
1659 const int vao
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
| Modifiers
.OVERRIDE
);
1660 const int va
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
);
1661 const int nv
= (Modifiers
.SHADOWS
| Modifiers
.VIRTUAL
);
1663 string name
= MakeName (n
);
1666 // At most one of static, virtual or override
1668 if ((flags
& Modifiers
.STATIC
) != 0){
1669 if ((flags
& vao
) != 0){
1671 30501, loc
, "Shared method " + name
+ " can not be " +
1672 "declared as Overridable");
1677 if (this is Struct
){
1678 if ((flags
& va
) != 0){
1679 Modifiers
.Error_InvalidModifier (loc
, "virtual or abstract");
1684 if ((flags
& Modifiers
.OVERRIDE
) != 0 && (flags
& Modifiers
.VIRTUAL
) != 0)
1688 ": Methods marked as Overrides cannot be made Overridable");
1692 if ((flags
& Modifiers
.OVERRIDE
) != 0 && (flags
& Modifiers
.SHADOWS
) != 0){
1695 ": Methods marked as Overrides cannot be marked as Shadows");
1700 // If the declaration includes the abstract modifier, then the
1701 // declaration does not include static, virtual or extern
1703 if ((flags
& Modifiers
.ABSTRACT
) != 0){
1704 if ((flags
& Modifiers
.EXTERN
) != 0){
1706 180, loc
, name
+ " can not be both abstract and extern");
1710 if ((flags
& Modifiers
.VIRTUAL
) != 0){
1712 503, loc
, name
+ " can not be both abstract and virtual");
1716 if((ModFlags
& Modifiers
.SEALED
) != 0){
1719 "Class declared as 'NotInheritable' " +
1720 "cannot have a 'MustOverride' member");
1723 else if ((ModFlags
& Modifiers
.ABSTRACT
) == 0){
1726 " is declared as 'MustOverride', hence its container " +
1727 "class should be declared as 'MustInherit'");
1733 if ((flags
& Modifiers
.PRIVATE
) != 0){
1734 if ((flags
& vao
) != 0){
1737 ": Members marked as Overridable or Overrides can not be Private");
1742 if ((flags
& Modifiers
.SEALED
) != 0){
1743 if ((flags
& Modifiers
.OVERRIDE
) == 0){
1746 ": cannot be sealed because it is not an override");
1750 if ((flags
& Modifiers
.NEW
) != 0){
1751 if ((flags
& Modifiers
.SHADOWS
) != 0){
1754 " 'Overloads' and 'Shadows' cannot be combined ");
1762 // Access level of a type.
1765 ProtectedInternal
= 1,
1771 // Check whether `flags' denotes a more restricted access than `level'
1772 // and return the new level.
1773 static AccessLevel
CheckAccessLevel (AccessLevel level
, int flags
)
1775 AccessLevel old_level
= level
;
1777 if ((flags
& Modifiers
.INTERNAL
) != 0) {
1778 if ((flags
& Modifiers
.PROTECTED
) != 0) {
1779 if ((int) level
< (int) AccessLevel
.ProtectedInternal
)
1780 level
= AccessLevel
.ProtectedInternal
;
1782 if ((int) level
< (int) AccessLevel
.Internal
)
1783 level
= AccessLevel
.Internal
;
1785 } else if ((flags
& Modifiers
.PROTECTED
) != 0) {
1786 if ((int) level
< (int) AccessLevel
.Protected
)
1787 level
= AccessLevel
.Protected
;
1788 } else if ((flags
& Modifiers
.PRIVATE
) != 0)
1789 level
= AccessLevel
.Private
;
1794 // Return the access level for a new member which is defined in the current
1795 // TypeContainer with access modifiers `flags'.
1796 AccessLevel
GetAccessLevel (int flags
)
1798 if ((flags
& Modifiers
.PRIVATE
) != 0)
1799 return AccessLevel
.Private
;
1802 if (!IsTopLevel
&& (Parent
!= null))
1803 level
= Parent
.GetAccessLevel (flags
);
1805 level
= AccessLevel
.Public
;
1807 return CheckAccessLevel (CheckAccessLevel (level
, flags
), ModFlags
);
1810 // Return the access level for type `t', but don't give more access than `flags'.
1811 static AccessLevel
GetAccessLevel (Type t
, int flags
)
1813 if (((flags
& Modifiers
.PRIVATE
) != 0) || t
.IsNestedPrivate
)
1814 return AccessLevel
.Private
;
1817 if (TypeManager
.IsBuiltinType (t
))
1818 return AccessLevel
.Public
;
1819 else if ((t
.DeclaringType
!= null) && (t
!= t
.DeclaringType
))
1820 level
= GetAccessLevel (t
.DeclaringType
, flags
);
1822 level
= CheckAccessLevel (AccessLevel
.Public
, flags
);
1825 if (t
.IsNestedPublic
)
1828 if (t
.IsNestedAssembly
|| t
.IsNotPublic
) {
1829 if ((int) level
< (int) AccessLevel
.Internal
)
1830 level
= AccessLevel
.Internal
;
1833 if (t
.IsNestedFamily
) {
1834 if ((int) level
< (int) AccessLevel
.Protected
)
1835 level
= AccessLevel
.Protected
;
1838 if (t
.IsNestedFamORAssem
) {
1839 if ((int) level
< (int) AccessLevel
.ProtectedInternal
)
1840 level
= AccessLevel
.ProtectedInternal
;
1847 // Returns true if `parent' is as accessible as the flags `flags'
1848 // given for this member.
1850 public bool AsAccessible (Type parent
, int flags
)
1852 while (parent
.IsArray
|| parent
.IsPointer
|| parent
.IsByRef
)
1853 parent
= parent
.GetElementType ();
1855 AccessLevel level
= GetAccessLevel (flags
);
1856 AccessLevel level2
= GetAccessLevel (parent
, flags
);
1858 return (int) level
>= (int) level2
;
1861 Hashtable builder_and_args
;
1863 public bool RegisterMethod (MethodBuilder mb
, InternalParameters ip
, Type
[] args
)
1865 if (builder_and_args
== null)
1866 builder_and_args
= new Hashtable ();
1871 /// Performs checks for an explicit interface implementation. First it
1872 /// checks whether the `interface_type' is a base inteface implementation.
1873 /// Then it checks whether `name' exists in the interface type.
1875 public bool VerifyImplements (Type interface_type
, string full
, string name
, Location loc
)
1879 if (ifaces
!= null){
1880 foreach (Type t
in ifaces
){
1881 if (t
== interface_type
){
1889 Report
.Error (540, "`" + full
+ "': containing class does not implement interface `" + interface_type
.FullName
+ "'");
1896 public static void Error_NotInterfaceMember (Location loc
, string member_name
, string iface_name
)
1898 Report
.Error (30401, loc
, "'" + member_name
+ "' is not a member of the interface '" + iface_name
+ "'");
1905 string IMemberContainer
.Name
{
1911 Type IMemberContainer
.Type
{
1917 IMemberContainer IMemberContainer
.Parent
{
1919 return parent_container
;
1923 MemberCache IMemberContainer
.MemberCache
{
1925 return member_cache
;
1929 bool IMemberContainer
.IsInterface
{
1931 return this is Interface
;
1935 MemberList IMemberContainer
.GetMembers (MemberTypes mt
, BindingFlags bf
)
1937 return FindMembers (mt
, bf
| BindingFlags
.DeclaredOnly
, null, null);
1942 public class Class
: TypeContainer
{
1944 // Modifiers allowed in a class declaration
1946 public const int AllowedModifiers
=
1949 Modifiers
.PROTECTED
|
1950 Modifiers
.INTERNAL
|
1952 Modifiers
.ABSTRACT
|
1955 public Class (TypeContainer parent
, string name
, int mod
, Attributes attrs
, Location l
)
1956 : base (parent
, name
, l
)
1960 if (parent
.Parent
== null)
1961 accmods
= Modifiers
.INTERNAL
;
1963 accmods
= Modifiers
.PUBLIC
;
1965 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, l
);
1966 this.attributes
= attrs
;
1970 // FIXME: How do we deal with the user specifying a different
1973 public override TypeAttributes TypeAttr
{
1975 return base.TypeAttr
| TypeAttributes
.AutoLayout
| TypeAttributes
.Class
;
1980 public class Struct
: TypeContainer
{
1982 // Modifiers allowed in a struct declaration
1984 public const int AllowedModifiers
=
1987 Modifiers
.PROTECTED
|
1988 Modifiers
.INTERNAL
|
1992 public Struct (TypeContainer parent
, string name
, int mod
, Attributes attrs
, Location l
)
1993 : base (parent
, name
, l
)
1997 if (parent
.Parent
== null)
1998 accmods
= Modifiers
.INTERNAL
;
2000 accmods
= Modifiers
.PUBLIC
;
2002 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, l
);
2004 this.ModFlags
|= Modifiers
.SEALED
;
2005 this.attributes
= attrs
;
2010 // FIXME: Allow the user to specify a different set of attributes
2011 // in some cases (Sealed for example is mandatory for a class,
2012 // but what SequentialLayout can be changed
2014 public override TypeAttributes TypeAttr
{
2016 return base.TypeAttr
|
2017 TypeAttributes
.SequentialLayout
|
2018 TypeAttributes
.Sealed
|
2019 TypeAttributes
.BeforeFieldInit
;
2024 public abstract class MethodCore
: MemberBase
{
2025 public /* readonly */ Parameters Parameters
;
2029 // Parameters, cached for semantic analysis.
2031 protected InternalParameters parameter_info
;
2032 protected Type
[] parameter_types
;
2034 // Whether this is an operator
2035 public bool IsOperator
;
2037 public MethodCore (Expression type
, int mod
, int allowed_mod
, string name
,
2038 Attributes attrs
, Parameters parameters
, Location loc
)
2039 : base (type
, mod
, allowed_mod
, name
, attrs
, loc
)
2041 Parameters
= parameters
;
2045 // Returns the System.Type array for the parameters of this method
2047 public Type
[] ParameterTypes
{
2049 return parameter_types
;
2053 public InternalParameters ParameterInfo
2056 return parameter_info
;
2060 public Block Block
{
2070 protected virtual bool DoDefineParameters (TypeContainer parent
)
2072 // Check if arguments were correct
2073 parameter_types
= Parameters
.GetParameterInfo (parent
);
2074 if ((parameter_types
== null) || !CheckParameters (parent
, parameter_types
))
2077 parameter_info
= new InternalParameters (parent
, Parameters
);
2082 public CallingConventions
GetCallingConvention (bool is_class
)
2084 CallingConventions cc
= 0;
2086 cc
= Parameters
.GetCallingConvention ();
2089 if ((ModFlags
& Modifiers
.STATIC
) == 0)
2090 cc
|= CallingConventions
.HasThis
;
2092 // FIXME: How is `ExplicitThis' used in C#?
2097 public void LabelParameters (EmitContext ec
, Type
[] parameters
, MethodBase builder
)
2099 LabelParameters (ec
, parameters
, builder
, null);
2102 public void LabelParameters (EmitContext ec
, Type
[] parameters
, MethodBase builder
, Parameters p_params
)
2105 // Define each type attribute (in/out/ref) and
2106 // the argument names.
2108 Parameter
[] p
= p_params
== null ? Parameters
.FixedParameters
: p_params
.FixedParameters
;
2111 MethodBuilder mb
= null;
2112 ConstructorBuilder cb
= null;
2114 if (builder
is MethodBuilder
)
2115 mb
= (MethodBuilder
) builder
;
2117 cb
= (ConstructorBuilder
) builder
;
2120 for (i
= 0; i
< p
.Length
; i
++) {
2121 ParameterBuilder pb
;
2124 pb
= cb
.DefineParameter (
2125 i
+ 1, p
[i
].Attributes
, p
[i
].Name
);
2127 pb
= mb
.DefineParameter (
2128 i
+ 1, p
[i
].Attributes
, p
[i
].Name
);
2130 if (p
[i
].ParameterInitializer
!= null) {
2131 if (p
[i
].ParameterInitializer
is MemberAccess
) {
2132 MemberAccess ma
= p
[i
].ParameterInitializer
as MemberAccess
;
2134 Expression const_ex
= ma
.Resolve(ec
);
2135 if (const_ex
is EnumConstant
)
2136 pb
.SetConstant (((EnumConstant
) const_ex
).Child
.GetValue());
2139 "Internal error - Non supported argument type in optional parameter");
2142 pb
.SetConstant (((Constant
) p
[i
].ParameterInitializer
).GetValue());
2145 Attributes attr
= p
[i
].OptAttributes
;
2147 Attribute
.ApplyAttributes (ec
, pb
, pb
, attr
, Location
);
2151 if (Parameters
.ArrayParameter
!= null){
2152 ParameterBuilder pb
;
2153 Parameter array_param
= Parameters
.ArrayParameter
;
2156 pb
= cb
.DefineParameter (
2157 i
+ 1, array_param
.Attributes
,
2160 pb
= mb
.DefineParameter (
2161 i
+ 1, array_param
.Attributes
,
2164 CustomAttributeBuilder a
= new CustomAttributeBuilder (
2165 TypeManager
.cons_param_array_attribute
, new object [0]);
2167 pb
.SetCustomAttribute (a
);
2172 public class Method
: MethodCore
{
2173 public MethodBuilder MethodBuilder
;
2174 public MethodData MethodData
;
2177 /// Modifiers allowed in a class declaration
2179 const int AllowedModifiers
=
2182 Modifiers
.PROTECTED
|
2183 Modifiers
.INTERNAL
|
2187 Modifiers
.NONVIRTUAL
|
2188 Modifiers
.OVERRIDE
|
2189 Modifiers
.ABSTRACT
|
2195 // return_type can be "null" for VOID values.
2197 public Method (Expression return_type
, int mod
, string name
, Parameters parameters
,
2198 Attributes attrs
, Location l
)
2199 : base (return_type
, mod
, AllowedModifiers
, name
, attrs
, parameters
, l
)
2204 public Method (Expression return_type
, int mod
, string name
, Parameters parameters
,
2205 Attributes attrs
, ArrayList impl_what
, Location l
)
2206 : base (return_type
, mod
, AllowedModifiers
, name
, attrs
, parameters
, l
)
2208 Implements
= impl_what
;
2212 // Returns the `System.Type' for the ReturnType of this
2213 // function. Provides a nice cache. (used between semantic analysis
2214 // and actual code generation
2216 public Type
GetReturnType ()
2221 void DuplicateEntryPoint (MethodInfo b
, Location location
)
2225 "Program `" + CodeGen
.FileName
+
2226 "' has more than one entry point defined: `" +
2227 TypeManager
.MonoBASIC_Signature(b
) + "'");
2230 void Report28 (MethodInfo b
)
2232 if (RootContext
.WarningLevel
< 4)
2237 "`" + TypeManager
.MonoBASIC_Signature(b
) +
2238 "' has the wrong signature to be an entry point");
2241 public bool IsEntryPoint (MethodBuilder b
, InternalParameters pinfo
)
2243 if (b
.ReturnType
!= TypeManager
.void_type
&&
2244 b
.ReturnType
!= TypeManager
.int32_type
)
2247 if (pinfo
.Count
== 0)
2250 if (pinfo
.Count
> 1)
2253 Type t
= pinfo
.ParameterType(0);
2255 (t
.GetArrayRank() == 1) &&
2256 (t
.GetElementType() == TypeManager
.string_type
) &&
2257 (pinfo
.ParameterModifier(0) == Parameter
.Modifier
.NONE
))
2264 // Checks our base implementation if any
2266 protected override bool CheckBase (TypeContainer parent
)
2268 // Check whether arguments were correct.
2269 if (!DoDefineParameters (parent
))
2272 MethodSignature ms
= new MethodSignature (Name
, null, ParameterTypes
);
2276 mi_this
= TypeContainer
.FindMembers (
2277 parent
.TypeBuilder
, MemberTypes
.Method
,
2278 BindingFlags
.NonPublic
| BindingFlags
.Public
|
2279 BindingFlags
.Static
| BindingFlags
.Instance
|
2280 BindingFlags
.DeclaredOnly
,
2281 MethodSignature
.method_signature_filter
, ms
);
2283 if (mi_this
.Count
> 0) {
2284 Report
.Error (111, Location
, "Class `" + parent
.Name
+ "' " +
2285 "already defines a member called `" + Name
+ "' " +
2286 "with the same parameter types");
2292 // Verify if the parent has a type with the same name, and then
2293 // check whether we have to create a new slot for it or not.
2295 Type ptype
= parent
.TypeBuilder
.BaseType
;
2297 // ptype is only null for System.Object while compiling corlib.
2299 MemberList mi
, mi_static
, mi_instance
;
2301 mi_static
= TypeContainer
.FindMembers (
2302 ptype
, MemberTypes
.Method
,
2303 BindingFlags
.NonPublic
| BindingFlags
.Public
| BindingFlags
.Static
,
2304 MethodSignature
.inheritable_method_signature_filter
, ms
);
2306 mi_instance
= TypeContainer
.FindMembers (
2307 ptype
, MemberTypes
.Method
,
2308 BindingFlags
.NonPublic
| BindingFlags
.Public
| BindingFlags
.Instance
,
2309 MethodSignature
.inheritable_method_signature_filter
,
2312 if (mi_instance
.Count
> 0){
2314 } else if (mi_static
.Count
> 0)
2319 if (mi
!= null && mi
.Count
> 0){
2320 parent_method
= (MethodInfo
) mi
[0];
2321 string name
= parent_method
.DeclaringType
.Name
+ "." +
2324 if (!CheckMethodAgainstBase (parent
, flags
, parent_method
, name
))
2327 if ((ModFlags
& Modifiers
.NEW
) == 0) {
2328 Type parent_ret
= TypeManager
.TypeToCoreType (
2329 parent_method
.ReturnType
);
2331 if (parent_ret
!= MemberType
) {
2333 508, parent
.MakeName (Name
) + ": cannot " +
2334 "change return type when overriding " +
2335 "inherited member " + name
);
2340 /*if ((ModFlags & Modifiers.NEW) != 0)
2341 WarningNotHiding (parent);*/
2343 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0){
2344 Report
.Error (30284, Location
,
2345 parent
.MakeName (Name
) +
2346 " : No suitable methods found to override");
2348 if ((ModFlags
& ( Modifiers
.NEW
| Modifiers
.SHADOWS
| Modifiers
.OVERRIDE
)) == 0)
2350 if ((ModFlags
& Modifiers
.NONVIRTUAL
) != 0)
2352 Report
.Error (31088, Location
,
2353 parent
.MakeName (Name
) + " : Cannot " +
2354 "be declared NotOverridable since this method is " +
2355 "not maked as Overrides");
2358 // if a member of module is not inherited from Object class
2359 // can not be declared protected
2360 if ((parent
is Module
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
2361 Report
.Error (31066, Location
,
2362 "'Sub' or 'Function' inside a 'Module' can not be declared as " +
2363 "'Protected' or 'Protected Friend'");
2366 /* else if ((ModFlags & Modifiers.NEW) != 0)
2367 WarningNotHiding (parent);
2376 public override bool Define (TypeContainer parent
)
2378 if (!DoDefine (parent
))
2381 if (!CheckBase (parent
))
2384 if ((parent
is Struct
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
2385 Report
.Error (31067, Location
,
2386 "'Sub' or 'Function' inside a 'Structure' can not be declared as " +
2387 "'Protected' or 'Protected Friend'");
2389 CallingConventions cc
= GetCallingConvention (parent
is Class
);
2391 MethodData
= new MethodData (this, null, MemberType
, ParameterTypes
,
2392 ParameterInfo
, cc
, OptAttributes
,
2393 ModFlags
, flags
, true);
2395 if (!MethodData
.Define (parent
))
2398 MethodBuilder
= MethodData
.MethodBuilder
;
2401 // This is used to track the Entry Point,
2403 if (Name
.ToUpper() == "MAIN" &&
2404 ((ModFlags
& Modifiers
.STATIC
) != 0) &&
2405 (RootContext
.MainClass
== null ||
2406 RootContext
.MainClass
== parent
.TypeBuilder
.FullName
||
2407 (RootContext
.RootNamespace
!= null &&
2408 RootContext
.RootNamespace
.Length
> 0 &&
2409 (RootContext
.RootNamespace
+ "." + RootContext
.MainClass
) == parent
.TypeBuilder
.FullName
))) {
2410 if (IsEntryPoint (MethodBuilder
, ParameterInfo
)) {
2411 if (RootContext
.EntryPoint
== null) {
2412 RootContext
.EntryPoint
= MethodBuilder
;
2413 RootContext
.EntryPointLocation
= Location
;
2415 DuplicateEntryPoint (RootContext
.EntryPoint
, RootContext
.EntryPointLocation
);
2416 DuplicateEntryPoint (MethodBuilder
, Location
);
2419 Report28(MethodBuilder
);
2428 public void Emit (TypeContainer parent
)
2430 MethodData
.Emit (parent
, Block
, this);
2434 public abstract class ConstructorInitializer
{
2435 ArrayList argument_list
;
2436 ConstructorInfo parent_constructor
;
2437 Parameters parameters
;
2439 public bool implicit_initialization
;
2441 public ConstructorInitializer (ArrayList argument_list
, Parameters parameters
,
2444 this.argument_list
= argument_list
;
2445 this.parameters
= parameters
;
2447 this.implicit_initialization
= false;
2450 public ArrayList Arguments
{
2452 return argument_list
;
2456 public ConstructorInfo ParentConstructor
2460 return parent_constructor
;
2464 public bool Resolve (EmitContext ec
)
2466 Expression parent_constructor_group
;
2469 ec
.CurrentBlock
= new Block (null, true, parameters
);
2471 if (argument_list
!= null){
2472 foreach (Argument a
in argument_list
){
2473 if (!a
.Resolve (ec
, loc
))
2478 ec
.CurrentBlock
= null;
2480 if (this is ConstructorBaseInitializer
) {
2481 if (ec
.ContainerType
.BaseType
== null)
2484 t
= ec
.ContainerType
.BaseType
;
2485 if (ec
.ContainerType
.IsValueType
){
2486 Report
.Error (522, loc
,
2487 "structs cannot call base class constructors");
2492 t
= ec
.ContainerType
;
2494 parent_constructor_group
= Expression
.MemberLookup (
2496 MemberTypes
.Constructor
,
2497 BindingFlags
.Public
| BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
,
2500 if (parent_constructor_group
== null){
2501 Report
.Error (30455, loc
, "Class '" + t
+ "' can not find a constructor for this argument list" );
2505 parent_constructor
= (ConstructorInfo
) Invocation
.OverloadResolve (ec
,
2506 (MethodGroupExpr
) parent_constructor_group
, argument_list
, loc
);
2508 if (parent_constructor
== null) {
2509 if (this.implicit_initialization
)
2510 Report
.Error (30148, loc
, "Must declare 'MyBase.New' in the constructor " +
2511 "of the class '" + ec
.TypeContainer
.Name
+ "' with appropriate arguments, since the base class '" +
2512 t
.FullName
+ "' does not contain a definition of 'New' without any parameter");
2514 Report
.Error (30455, loc
, "Class '" + t
+ "' can not find a constructor for this argument list" );
2522 public void Emit (EmitContext ec
)
2524 if (parent_constructor
!= null){
2526 Invocation
.EmitCall (ec
, true, true, null, parent_constructor
, argument_list
, loc
);
2528 Invocation
.EmitCall (ec
, true, false, ec
.This
, parent_constructor
, argument_list
, loc
);
2535 public class ConstructorBaseInitializer
: ConstructorInitializer
{
2536 public ConstructorBaseInitializer (ArrayList argument_list
, Parameters pars
, Location l
) :
2537 base (argument_list
, pars
, l
)
2542 public class ConstructorThisInitializer
: ConstructorInitializer
{
2543 public ConstructorThisInitializer (ArrayList argument_list
, Parameters pars
, Location l
) :
2544 base (argument_list
, pars
, l
)
2549 public class Constructor
: MethodCore
{
2550 public ConstructorBuilder ConstructorBuilder
;
2551 public ConstructorInitializer Initializer
;
2552 new public Attributes OptAttributes
;
2555 // Modifiers allowed for a constructor.
2557 public const int AllowedModifiers
=
2559 Modifiers
.PROTECTED
|
2560 Modifiers
.INTERNAL
|
2567 // The spec claims that static is not permitted, but
2568 // my very own code has static constructors.
2570 public Constructor (string name
, Parameters args
, ConstructorInitializer init
, Location l
)
2571 : base (null, 0, AllowedModifiers
, name
, null, args
, l
)
2576 public Constructor (string name
, int mod
, Parameters args
, ConstructorInitializer init
, Location l
)
2577 : base (null, mod
, AllowedModifiers
, name
, null, args
, l
)
2583 // Returns true if this is a default constructor
2585 public bool IsDefault ()
2587 if ((ModFlags
& Modifiers
.STATIC
) != 0)
2588 return (Parameters
.FixedParameters
== null ? true : Parameters
.Empty
) &&
2589 (Parameters
.ArrayParameter
== null ? true : Parameters
.Empty
);
2592 return (Parameters
.FixedParameters
== null ? true : Parameters
.Empty
) &&
2593 (Parameters
.ArrayParameter
== null ? true : Parameters
.Empty
) &&
2594 (Initializer
is ConstructorBaseInitializer
) &&
2595 (Initializer
.Arguments
== null);
2599 // Creates the ConstructorBuilder
2601 public override bool Define (TypeContainer parent
)
2603 MethodAttributes ca
= (MethodAttributes
.RTSpecialName
|
2604 MethodAttributes
.SpecialName
);
2606 if (parent
.EventHandlers
!= null) {
2607 ArrayList hdlrs
= parent
.EventHandlers
;
2608 foreach(Statement stmt
in hdlrs
)
2609 this.Block
.AddStatement (stmt
);
2613 // Check if arguments were correct.
2614 if (!DoDefineParameters (parent
))
2617 if ((ModFlags
& Modifiers
.STATIC
) != 0) {
2618 ca
|= MethodAttributes
.Static
;
2620 if (this.Parameters
!= Parameters
.EmptyReadOnlyParameters
)
2623 "Shared constructor can not have parameters");
2625 if ((ModFlags
& Modifiers
.Accessibility
) != 0)
2628 "Shared constructor can not be declared " +
2629 "explicitly as public, private, friend or protected");
2631 if (this.Initializer
!= null)
2634 "Keywords like MyBase, MyClass, Me are not " +
2635 "valid inside a Shared Constructor");
2638 if (parent
is Struct
&& ParameterTypes
.Length
== 0) {
2641 "Structs can not contain explicit parameterless " +
2645 ca
|= MethodAttributes
.HideBySig
;
2647 if ((ModFlags
& Modifiers
.PUBLIC
) != 0)
2648 ca
|= MethodAttributes
.Public
;
2649 else if ((ModFlags
& Modifiers
.PROTECTED
) != 0) {
2650 if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
2651 ca
|= MethodAttributes
.FamORAssem
;
2653 ca
|= MethodAttributes
.Family
;
2655 else if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
2656 ca
|= MethodAttributes
.Assembly
;
2657 else if (IsDefault ())
2658 ca
|= MethodAttributes
.Public
;
2660 ca
|= MethodAttributes
.Private
;
2663 ConstructorBuilder
= parent
.TypeBuilder
.DefineConstructor (
2664 ca
, GetCallingConvention (parent
is Class
), ParameterTypes
);
2667 // HACK because System.Reflection.Emit is lame
2669 if (!TypeManager
.RegisterMethod (ConstructorBuilder
, ParameterInfo
, ParameterTypes
)) {
2672 "Class `" +parent
.Name
+ "' already contains a definition with the " +
2673 "same return value and parameter types for constructor `" + Name
2684 public void Emit (TypeContainer parent
)
2686 ILGenerator ig
= ConstructorBuilder
.GetILGenerator ();
2687 EmitContext ec
= new EmitContext (parent
, Location
, ig
, null, ModFlags
, true);
2689 if ((ModFlags
& Modifiers
.STATIC
) == 0){
2690 if (parent
is Class
&& Initializer
== null) {
2691 Initializer
= new ConstructorBaseInitializer (
2692 null, Parameters
.EmptyReadOnlyParameters
, parent
.Location
);
2693 Initializer
.implicit_initialization
= true;
2697 // Spec mandates that Initializers will not have
2701 if (Initializer
!= null && !Initializer
.Resolve (ec
))
2703 ec
.IsStatic
= false;
2706 LabelParameters (ec
, ParameterTypes
, ConstructorBuilder
);
2709 // Classes can have base initializers and instance field initializers.
2711 if (parent
is Class
){
2712 if ((ModFlags
& Modifiers
.STATIC
) == 0)
2713 parent
.EmitFieldInitializers (ec
);
2716 if (Initializer
!= null) {
2717 if (this.ConstructorBuilder
.Equals (Initializer
.ParentConstructor
))
2720 "A constructor can not call itself" );
2722 Initializer
.Emit (ec
);
2725 if ((ModFlags
& Modifiers
.STATIC
) != 0)
2726 parent
.EmitFieldInitializers (ec
);
2728 Attribute
.ApplyAttributes (ec
, ConstructorBuilder
, this, OptAttributes
, Location
);
2730 // If this is a non-static `struct' constructor and doesn't have any
2731 // initializer, it must initialize all of the struct's fields.
2732 if ((parent
is Struct
) && ((ModFlags
& Modifiers
.STATIC
) == 0) &&
2733 (Initializer
== null))
2734 Block
.AddThisVariable (parent
, Location
);
2736 ec
.EmitTopBlock (Block
, ParameterInfo
, Location
);
2740 public class MethodData
{
2742 // The return type of this method
2744 public readonly Type ReturnType
;
2745 public readonly Type
[] ParameterTypes
;
2746 public readonly InternalParameters ParameterInfo
;
2747 public readonly CallingConventions CallingConventions
;
2748 public readonly Attributes OptAttributes
;
2749 public readonly Location Location
;
2752 // Are we implementing an interface ?
2754 public bool IsImplementing
= false;
2759 protected MemberBase member
;
2760 protected int modifiers
;
2761 protected MethodAttributes flags
;
2762 protected bool is_method
;
2763 protected string accessor_name
;
2764 ArrayList conditionals
;
2766 MethodBuilder builder
= null;
2767 public MethodBuilder MethodBuilder
{
2773 public MethodData (MemberBase member
, string name
, Type return_type
,
2774 Type
[] parameter_types
, InternalParameters parameters
,
2775 CallingConventions cc
, Attributes opt_attrs
,
2776 int modifiers
, MethodAttributes flags
, bool is_method
)
2778 this.member
= member
;
2779 this.accessor_name
= name
;
2780 this.ReturnType
= return_type
;
2781 this.ParameterTypes
= parameter_types
;
2782 this.ParameterInfo
= parameters
;
2783 this.CallingConventions
= cc
;
2784 this.OptAttributes
= opt_attrs
;
2785 this.modifiers
= modifiers
;
2787 this.is_method
= is_method
;
2788 this.Location
= member
.Location
;
2789 this.conditionals
= new ArrayList ();
2795 Attribute dllimport_attribute
= null;
2796 string obsolete
= null;
2797 bool obsolete_error
= false;
2799 public virtual bool ApplyAttributes (Attributes opt_attrs
, bool is_method
)
2801 if ((opt_attrs
== null) || (opt_attrs
.Attrs
== null))
2804 foreach (Attribute a
in opt_attrs
.Attrs
) {
2805 if (a
.Name
== "Conditional") {
2806 if (!ApplyConditionalAttribute (a
))
2808 } else if (a
.Name
== "Obsolete") {
2809 if (!ApplyObsoleteAttribute (a
))
2811 } else if (a
.Name
.IndexOf ("DllImport") != -1) {
2813 a
.Type
= TypeManager
.dllimport_type
;
2814 Attribute
.Error_AttributeNotValidForElement (a
, Location
);
2817 if (!ApplyDllImportAttribute (a
))
2826 // Applies the `DllImport' attribute to the method.
2828 protected virtual bool ApplyDllImportAttribute (Attribute a
)
2830 const int extern_static
= Modifiers
.EXTERN
| Modifiers
.STATIC
;
2831 if ((modifiers
& extern_static
) != extern_static
) {
2832 Report
.Error (601, Location
,
2833 "The DllImport attribute must be specified on a method " +
2834 "marked `static' and `extern'.");
2838 flags
|= MethodAttributes
.PinvokeImpl
;
2839 dllimport_attribute
= a
;
2844 // Applies the `Obsolete' attribute to the method.
2846 protected virtual bool ApplyObsoleteAttribute (Attribute a
)
2848 if (obsolete
!= null) {
2849 Report
.Error (579, Location
, "Duplicate `Obsolete' attribute");
2853 obsolete
= a
.Obsolete_GetObsoleteMessage (out obsolete_error
);
2854 return obsolete
!= null;
2858 // Applies the `Conditional' attribute to the method.
2860 protected virtual bool ApplyConditionalAttribute (Attribute a
)
2862 // The Conditional attribute is only valid on methods.
2864 Attribute
.Error_AttributeNotValidForElement (a
, Location
);
2868 string condition
= a
.Conditional_GetConditionName ();
2870 if (condition
== null)
2873 if (ReturnType
!= TypeManager
.void_type
) {
2874 Report
.Error (578, Location
,
2875 "Conditional not valid on `" + member
.Name
+ "' " +
2876 "because its return type is not void");
2880 if ((modifiers
& Modifiers
.OVERRIDE
) != 0) {
2881 Report
.Error (243, Location
,
2882 "Conditional not valid on `" + member
.Name
+ "' " +
2883 "because it is an override method");
2887 if (member
.IsExplicitImpl
) {
2888 Report
.Error (577, Location
,
2889 "Conditional not valid on `" + member
.Name
+ "' " +
2890 "because it is an explicit interface implementation");
2894 if (IsImplementing
) {
2895 Report
.Error (623, Location
,
2896 "Conditional not valid on `" + member
.Name
+ "' " +
2897 "because it is an interface method");
2901 conditionals
.Add (condition
);
2907 // Checks whether this method should be ignored due to its Conditional attributes.
2909 bool ShouldIgnore (Location loc
)
2911 // When we're overriding a virtual method, we implicitly inherit the
2912 // Conditional attributes from our parent.
2913 if (member
.ParentMethod
!= null) {
2914 TypeManager
.MethodFlags flags
= TypeManager
.GetMethodFlags (
2915 member
.ParentMethod
, loc
);
2917 if ((flags
& TypeManager
.MethodFlags
.ShouldIgnore
) != 0)
2921 foreach (string condition
in conditionals
)
2922 if (RootContext
.AllDefines
[condition
] == null)
2929 // Returns the TypeManager.MethodFlags for this method.
2930 // This emits an error 619 / warning 618 if the method is obsolete.
2931 // In the former case, TypeManager.MethodFlags.IsObsoleteError is returned.
2933 public virtual TypeManager
.MethodFlags
GetMethodFlags (Location loc
)
2935 TypeManager
.MethodFlags flags
= 0;
2937 if (obsolete
!= null) {
2938 if (obsolete_error
) {
2939 Report
.Error (619, loc
, "Method `" + member
.Name
+
2940 "' is obsolete: `" + obsolete
+ "'");
2941 return TypeManager
.MethodFlags
.IsObsoleteError
;
2943 Report
.Warning (618, loc
, "Method `" + member
.Name
+
2944 "' is obsolete: `" + obsolete
+ "'");
2946 flags
|= TypeManager
.MethodFlags
.IsObsolete
;
2949 if (ShouldIgnore (loc
))
2950 flags
|= TypeManager
.MethodFlags
.ShouldIgnore
;
2956 // Search all the interface bases recursively for unimplemented methods
2958 bool SearchBasesForAbstractMethods (
2959 TypeContainer parent
, Type iface_type
,
2960 string method_name
, ref ArrayList implementing_list
,
2961 ref ArrayList implementing_iface
)
2963 MethodInfo implementing
= null;
2964 bool IsImplementing
= false;
2965 Type current_iface_type
= iface_type
;
2967 if (member
is Indexer
)
2968 implementing
= parent
.Pending
.IsAbstractIndexer (
2969 current_iface_type
, ReturnType
, ParameterTypes
);
2971 implementing
= parent
.Pending
.IsAbstractMethod (
2972 current_iface_type
, method_name
, ReturnType
, ParameterTypes
);
2974 if (implementing
!= null) {
2975 if (!implementing_list
.Contains (implementing
)) {
2976 implementing_list
.Add (implementing
);
2977 implementing_iface
.Add(current_iface_type
);
2979 IsImplementing
= true;
2981 Type
[] current_iface_types
= current_iface_type
.GetInterfaces();
2982 if (current_iface_types
.Length
== 0)
2985 foreach (Type curr_iface_type
in current_iface_types
) {
2986 IsImplementing
= SearchBasesForAbstractMethods (
2987 parent
, curr_iface_type
, method_name
,
2988 ref implementing_list
, ref implementing_iface
);
2995 return IsImplementing
;
2998 public virtual bool Define (TypeContainer parent
)
3000 MethodInfo implementing
= null;
3001 ArrayList implementing_list
= null;
3002 ArrayList implementing_iface
= null;
3003 string method_name
, name
, prefix
, impl_method_name
;
3006 if (OptAttributes
!= null)
3007 if (!ApplyAttributes (OptAttributes
, is_method
))
3010 if (accessor_name
!= null)
3011 name
= accessor_name
+ "_" + member
.ShortName
;
3013 name
= member
.ShortName
;
3016 impl_method_name
= name
;
3018 if ((member
.ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3019 if (parent
.Pending
== null)
3020 implementing
= null;
3021 else if (member
is Indexer
)
3022 implementing
= parent
.Pending
.IsAbstractIndexer (
3023 (Type
) parent
.TypeBuilder
.BaseType
,
3024 ReturnType
, ParameterTypes
);
3026 implementing
= parent
.Pending
.IsAbstractMethod (
3027 (Type
) parent
.TypeBuilder
.BaseType
, name
,
3028 ReturnType
, ParameterTypes
);
3030 if (implementing
!= null)
3031 IsImplementing
= true;
3034 if (member
.Implements
!= null) {
3035 implementing_list
= new ArrayList();
3036 implementing_iface
= new ArrayList();
3038 foreach (Expression Impl
in member
.Implements
) {
3039 name
= Impl
.ToString();
3040 prefix
= name
.Substring(0, name
.LastIndexOf("."));
3041 name
= name
.Substring(name
.LastIndexOf(".") + 1);
3043 if (accessor_name
!= null)
3044 impl_method_name
= accessor_name
+ "_" + name
;
3046 impl_method_name
= name
;
3048 Type current_iface_type
= (Type
) member
.InterfaceTypes
[++pos
];
3049 IsImplementing
= SearchBasesForAbstractMethods (
3050 parent
, current_iface_type
, impl_method_name
,
3051 ref implementing_list
, ref implementing_iface
);
3053 if (IsImplementing
== false) {
3054 TypeContainer
.Error_NotInterfaceMember (
3055 Location
, name
, prefix
);
3062 // For implicit implementations, make sure we are public, for
3063 // explicit implementations, make sure we are private.
3065 //if (IsImplementing){
3067 // Setting null inside this block will trigger a more
3068 // verbose error reporting for missing interface implementations
3070 // The "candidate" function has been flagged already
3071 // but it wont get cleared
3073 /* if (!member.IsExplicitImpl){
3075 // We already catch different accessibility settings
3076 // so we just need to check that we are not private
3078 if ((modifiers & Modifiers.PRIVATE) != 0)
3079 implementing = null;
3082 // Static is not allowed
3084 if ((modifiers & Modifiers.STATIC) != 0)
3085 implementing = null;
3087 if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
3088 Modifiers.Error_InvalidModifier (Location, "public, virtual or abstract");
3089 implementing = null;
3095 // If implementing is still valid, set flags
3097 if (IsImplementing
){
3099 // When implementing interface methods, set NewSlot.
3101 if (implementing_list
!= null && implementing_list
.Count
!= 0)
3102 flags
|= MethodAttributes
.NewSlot
;
3105 MethodAttributes
.Virtual
|
3106 MethodAttributes
.HideBySig
;
3110 // Create the MethodBuilder for the method
3112 if ((flags
& MethodAttributes
.PinvokeImpl
) != 0) {
3113 if ((modifiers
& Modifiers
.STATIC
) == 0) {
3114 Report
.Error (601, Location
,
3115 "The DllImport attribute must be specified on " +
3116 "a method marked 'static' and 'extern'.");
3120 EmitContext ec
= new EmitContext (
3121 parent
, Location
, null, ReturnType
, modifiers
);
3123 builder
= dllimport_attribute
.DefinePInvokeMethod (
3124 ec
, parent
.TypeBuilder
, method_name
, flags
,
3125 ReturnType
, ParameterTypes
);
3127 builder
= parent
.TypeBuilder
.DefineMethod (
3128 method_name
, flags
, CallingConventions
,
3129 ReturnType
, ParameterTypes
);
3131 if (builder
== null)
3134 if (IsImplementing
) {
3136 // implement abstract methods from abstract classes
3138 if ((member
.ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3139 if (member
is Indexer
)
3140 parent
.Pending
.ImplementIndexer (
3141 (Type
) parent
.TypeBuilder
.BaseType
,
3142 builder
, ReturnType
,
3143 ParameterTypes
, true);
3145 parent
.Pending
.ImplementMethod (
3146 (Type
) parent
.TypeBuilder
.BaseType
,
3148 ParameterTypes
, member
.IsExplicitImpl
);
3152 // implement abstract methods of interfaces
3154 if (member
.Implements
!= null) {
3156 foreach (MethodInfo Impl
in implementing_list
) {
3157 if (member
is Indexer
)
3158 parent
.Pending
.ImplementIndexer (
3159 (Type
) implementing_iface
[pos
++],
3160 builder
, ReturnType
,
3161 ParameterTypes
, true);
3163 parent
.Pending
.ImplementMethod (
3164 (Type
) implementing_iface
[pos
++],
3165 Impl
.Name
, ReturnType
,
3166 ParameterTypes
, member
.IsExplicitImpl
);
3168 parent
.TypeBuilder
.DefineMethodOverride (
3175 if (!TypeManager
.RegisterMethod (builder
, ParameterInfo
, ParameterTypes
)) {
3176 Report
.Error (111, Location
,
3177 "Class `" + parent
.Name
+
3178 "' already contains a definition with the " +
3179 "same return value and parameter types as the " +
3180 "'get' method of property `" + member
.Name
+ "'");
3184 TypeManager
.AddMethod (builder
, this);
3191 public virtual void Emit (TypeContainer parent
, Block block
, object kind
)
3196 if ((flags
& MethodAttributes
.PinvokeImpl
) == 0)
3197 ig
= builder
.GetILGenerator ();
3201 ec
= new EmitContext (parent
, Location
, ig
, ReturnType
, modifiers
);
3203 if (OptAttributes
!= null)
3204 Attribute
.ApplyAttributes (ec
, builder
, kind
, OptAttributes
, Location
);
3206 if (member
is MethodCore
)
3207 ((MethodCore
) member
).LabelParameters (ec
, ParameterTypes
, MethodBuilder
);
3210 // abstract or extern methods have no bodies
3212 if ((modifiers
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) != 0){
3217 // abstract or extern methods have no bodies.
3219 if ((modifiers
& Modifiers
.ABSTRACT
) != 0)
3221 500, Location
, "Abstract method `" +
3222 TypeManager
.MonoBASIC_Signature (builder
) +
3223 "' can not have a body");
3225 if ((modifiers
& Modifiers
.EXTERN
) != 0)
3227 179, Location
, "External method `" +
3228 TypeManager
.MonoBASIC_Signature (builder
) +
3229 "' can not have a body");
3235 // Methods must have a body unless they're extern or abstract
3237 if (block
== null) {
3239 501, Location
, "Method `" +
3240 TypeManager
.MonoBASIC_Signature (builder
) +
3241 "' must declare a body since it is not marked " +
3242 "abstract or extern");
3247 // Handle destructors specially
3249 // FIXME: This code generates buggy code
3251 if (member
.Name
== "Finalize" && ReturnType
== TypeManager
.void_type
)
3252 EmitDestructor (ec
, block
);
3254 ISymbolWriter sw
= CodeGen
.SymbolWriter
;
3256 if ((sw
!= null) && !Location
.IsNull (Location
) &&
3257 !Location
.IsNull (block
.EndLocation
)) {
3258 Location end
= block
.EndLocation
;
3259 MethodToken token
= MethodBuilder
.GetToken ();
3260 sw
.OpenMethod (new SymbolToken (token
.Token
));
3261 // Avoid error if we don't support debugging for the platform
3263 sw
.SetMethodSourceRange (Location
.SymbolDocument
,
3267 } catch (Exception
) {
3270 ec
.EmitTopBlock (block
, member
.Name
, ParameterInfo
, Location
);
3274 ec
.EmitTopBlock (block
, member
.Name
, ParameterInfo
, Location
);
3278 void EmitDestructor (EmitContext ec
, Block block
)
3280 ILGenerator ig
= ec
.ig
;
3282 Label finish
= ig
.DefineLabel ();
3283 bool old_in_try
= ec
.InTry
;
3285 ig
.BeginExceptionBlock ();
3287 ec
.ReturnLabel
= finish
;
3288 ec
.HasReturnLabel
= true;
3289 ec
.EmitTopBlock (block
, null, Location
);
3290 ec
.InTry
= old_in_try
;
3292 // ig.MarkLabel (finish);
3293 bool old_in_finally
= ec
.InFinally
;
3294 ec
.InFinally
= true;
3295 ig
.BeginFinallyBlock ();
3297 if (ec
.ContainerType
.BaseType
!= null) {
3298 Expression member_lookup
= Expression
.MemberLookup (
3299 ec
, ec
.ContainerType
.BaseType
, ec
.ContainerType
.BaseType
, "Finalize",
3300 MemberTypes
.Method
, Expression
.AllBindingFlags
, Location
);
3302 if (member_lookup
!= null){
3303 MethodGroupExpr parent_destructor
= ((MethodGroupExpr
) member_lookup
);
3305 ig
.Emit (OpCodes
.Ldarg_0
);
3306 ig
.Emit (OpCodes
.Call
, (MethodInfo
) parent_destructor
.Methods
[0]);
3309 ec
.InFinally
= old_in_finally
;
3311 ig
.EndExceptionBlock ();
3312 //ig.MarkLabel (ec.ReturnLabel);
3313 ig
.Emit (OpCodes
.Ret
);
3317 abstract public class MemberBase
: MemberCore
{
3318 public Expression Type
;
3319 public readonly Attributes OptAttributes
;
3320 public ArrayList Implements
;
3322 protected MethodAttributes flags
;
3325 // The "short" name of this property / indexer / event. This is the
3326 // name without the explicit interface.
3328 public string ShortName
;
3331 // The type of this property / indexer / event
3333 public Type MemberType
;
3336 // If true, this is an explicit interface implementation
3338 public bool IsExplicitImpl
= false;
3341 // The name of the interface we are explicitly implementing
3343 public string ExplicitInterfaceName
= null;
3346 // If true, the interface type we are explicitly implementing
3348 public Type InterfaceType
= null;
3349 public ArrayList InterfaceTypes
= null;
3352 // The method we're overriding if this is an override method.
3354 protected MethodInfo parent_method
= null;
3355 public MethodInfo ParentMethod
{
3357 return parent_method
;
3362 // The constructor is only exposed to our children
3364 protected MemberBase (Expression type
, int mod
, int allowed_mod
, string name
,
3365 Attributes attrs
, Location loc
)
3369 ModFlags
= Modifiers
.Check (allowed_mod
, mod
, Modifiers
.PUBLIC
, loc
);
3370 OptAttributes
= attrs
;
3373 protected virtual bool CheckBase (TypeContainer parent
)
3378 protected virtual bool CheckParameters (TypeContainer parent
, Type
[] parameters
)
3382 foreach (Type partype
in parameters
){
3383 if (partype
.IsPointer
&& !UnsafeOK (parent
))
3386 if (parent
.AsAccessible (partype
, ModFlags
))
3389 if (this is Indexer
)
3390 Report
.Error (55, Location
,
3391 "Inconsistent accessibility: parameter type `" +
3392 TypeManager
.MonoBASIC_Name (partype
) + "' is less " +
3393 "accessible than indexer `" + Name
+ "'");
3395 Report
.Error (51, Location
,
3396 "Inconsistent accessibility: parameter type `" +
3397 TypeManager
.MonoBASIC_Name (partype
) + "' is less " +
3398 "accessible than method `" + Name
+ "'");
3405 protected virtual bool DoDefine (TypeContainer parent
)
3410 if (!parent
.MethodModifiersValid (ModFlags
, Name
, Location
))
3413 flags
= Modifiers
.MethodAttr (ModFlags
);
3415 // Lookup Type, verify validity
3416 MemberType
= parent
.ResolveType (Type
, false, Location
);
3417 if (MemberType
== null)
3420 // check for whether the Interface is implemented by the class
3421 if (Implements
!= null) {
3422 InterfaceTypes
= new ArrayList ();
3423 foreach (Expression Impls
in Implements
) {
3424 string iname
= Impls
.ToString();
3425 iname
= iname
.Substring(0, iname
.LastIndexOf("."));
3426 bool iface_found
= false;
3428 InterfaceType
= RootContext
.LookupType (
3429 parent
, iname
, false, Location
);
3430 if (InterfaceType
== null)
3433 InterfaceTypes
.Add (InterfaceType
);
3434 Type
[] tbases
= parent
.TypeBuilder
.GetInterfaces();
3436 if (tbases
.Length
!= 0) {
3437 ArrayList bases
= new ArrayList();
3438 TypeManager
.ExpandAllInterfaces (tbases
, ref bases
);
3440 foreach (Type tbase
in bases
) {
3441 string bname
= tbase
.Name
;
3442 if (bname
.LastIndexOf(".") != -1)
3443 bname
= bname
.Substring(bname
.LastIndexOf("."));
3445 if (bname
== iname
) {
3453 Report
.Error (31035, Location
,
3454 "Class '" + parent
.Name
+ "' doesn't implement interface '" + iname
+ "'");
3460 // verify accessibility
3461 if (!parent
.AsAccessible (MemberType
, ModFlags
)) {
3462 if (this is Property
)
3463 Report
.Error (53, Location
,
3464 "Inconsistent accessibility: property type `" +
3465 TypeManager
.MonoBASIC_Name (MemberType
) + "' is less " +
3466 "accessible than property `" + Name
+ "'");
3467 else if (this is Indexer
)
3468 Report
.Error (54, Location
,
3469 "Inconsistent accessibility: indexer return type `" +
3470 TypeManager
.MonoBASIC_Name (MemberType
) + "' is less " +
3471 "accessible than indexer `" + Name
+ "'");
3472 else if (this is Method
)
3473 Report
.Error (50, Location
,
3474 "Inconsistent accessibility: return type `" +
3475 TypeManager
.MonoBASIC_Name (MemberType
) + "' is less " +
3476 "accessible than method `" + Name
+ "'");
3478 Report
.Error (52, Location
,
3479 "Inconsistent accessibility: field type `" +
3480 TypeManager
.MonoBASIC_Name (MemberType
) + "' is less " +
3481 "accessible than field `" + Name
+ "'");
3485 if (MemberType
.IsPointer
&& !UnsafeOK (parent
))
3489 // Check for explicit interface implementation
3491 if ((ExplicitInterfaceName
== null) && (Name
.IndexOf (".") != -1)) {
3492 int pos
= Name
.LastIndexOf (".");
3494 ExplicitInterfaceName
= Name
.Substring (0, pos
);
3495 ShortName
= Name
.Substring (pos
+ 1);
3504 // Fields and Events both generate FieldBuilders, we use this to share
3505 // their common bits. This is also used to flag usage of the field
3507 abstract public class FieldBase
: MemberBase
{
3508 public FieldBuilder FieldBuilder
;
3509 public Status status
;
3512 public enum Status
: byte { ASSIGNED = 1, USED = 2 }
3515 // The constructor is only exposed to our children
3517 protected FieldBase (Expression type
, int mod
, int allowed_mod
, string name
,
3518 object init
, Attributes attrs
, Location loc
)
3519 : base (type
, mod
, allowed_mod
, name
, attrs
, loc
)
3525 // Whether this field has an initializer.
3527 public bool HasInitializer
{
3529 return init
!= null;
3534 readonly Object init
;
3535 Expression init_expr
;
3536 bool init_expr_initialized
= false;
3539 // Resolves and returns the field initializer.
3541 public Expression
GetInitializerExpression (EmitContext ec
)
3543 if (init_expr_initialized
)
3547 if (init
is Expression
)
3548 e
= (Expression
) init
;
3550 e
= new ArrayCreation (Type
, "", (ArrayList
)init
, Location
);
3552 ec
.IsFieldInitializer
= true;
3553 e
= e
.DoResolve (ec
);
3554 ec
.IsFieldInitializer
= false;
3557 init_expr_initialized
= true;
3565 // The Field class is used to represents class/struct fields during parsing.
3567 public class Field
: FieldBase
{
3569 // Modifiers allowed in a class declaration
3571 const int AllowedModifiers
=
3574 Modifiers
.PROTECTED
|
3575 Modifiers
.INTERNAL
|
3578 // Modifiers.VOLATILE |
3579 // Modifiers.UNSAFE |
3582 public Field (Expression type
, int mod
, string name
, Object expr_or_array_init
,
3583 Attributes attrs
, Location loc
)
3584 : base (type
, mod
, AllowedModifiers
, name
, expr_or_array_init
, attrs
, loc
)
3588 public override bool Define (TypeContainer parent
)
3590 Type t
= parent
.ResolveType (Type
, false, Location
);
3595 if (!parent
.AsAccessible (t
, ModFlags
)) {
3596 Report
.Error (52, Location
,
3597 "Inconsistent accessibility: field type `" +
3598 TypeManager
.MonoBASIC_Name (t
) + "' is less " +
3599 "accessible than field `" + Name
+ "'");
3603 if (t
.IsPointer
&& !UnsafeOK (parent
))
3606 Type ptype
= parent
.TypeBuilder
.BaseType
;
3608 // ptype is only null for System.Object while compiling corlib.
3610 MemberList list
= TypeContainer
.FindMembers (
3611 ptype
, MemberTypes
.Field
,
3612 BindingFlags
.Public
|
3613 BindingFlags
.Static
| BindingFlags
.Instance
,
3614 System
.Type
.FilterName
, Name
);
3616 if (RootContext
.WarningLevel
> 1){
3617 if ((list
.Count
> 0) && ((ModFlags
& Modifiers
.SHADOWS
) == 0))
3621 "Variable '" + Name
+ "' should be declared " +
3622 "Shadows since the base type '" + ptype
.Name
+
3623 "' has a variable with same name");
3625 ModFlags
|= Modifiers
.SHADOWS
;
3628 if (list
.Count
== 0)
3629 // if a member of module is not inherited from Object class
3630 // can not be declared protected
3631 if ((parent
is Module
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
3632 Report
.Error (30593, Location
,
3633 "'Variable' inside a 'Module' can not be " +
3634 "declared as 'Protected'");
3637 if ((parent
is Struct
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
3638 Report
.Error (30435, Location
,
3639 "'Variable' inside a 'Structure' can not be " +
3640 "declared as 'Protected'");
3642 if ((ModFlags
& Modifiers
.VOLATILE
) != 0){
3644 if (TypeManager
.IsEnumType (t
))
3645 t
= TypeManager
.EnumToUnderlying (t
);
3647 if (!((t
== TypeManager
.bool_type
) ||
3648 (t
== TypeManager
.sbyte_type
) ||
3649 (t
== TypeManager
.byte_type
) ||
3650 (t
== TypeManager
.short_type
) ||
3651 (t
== TypeManager
.ushort_type
) ||
3652 (t
== TypeManager
.int32_type
) ||
3653 (t
== TypeManager
.uint32_type
) ||
3654 (t
== TypeManager
.char_type
) ||
3655 (t
== TypeManager
.float_type
))){
3657 677, Location
, parent
.MakeName (Name
) +
3658 " A volatile field can not be of type `" +
3659 TypeManager
.MonoBASIC_Name (t
) + "'");
3665 FieldAttributes fa
= Modifiers
.FieldAttr (ModFlags
);
3667 if (parent
is Struct
&&
3668 ((fa
& FieldAttributes
.Static
) == 0) &&
3669 t
== parent
.TypeBuilder
&&
3670 !TypeManager
.IsBuiltinType (t
)){
3671 Report
.Error (523, Location
, "Struct member `" + parent
.Name
+ "." + Name
+
3672 "' causes a cycle in the structure layout");
3675 FieldBuilder
= parent
.TypeBuilder
.DefineField (
3676 Name
, t
, Modifiers
.FieldAttr (ModFlags
));
3678 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
3682 public void Emit (TypeContainer tc
)
3684 EmitContext ec
= new EmitContext (tc
, Location
, null,
3685 FieldBuilder
.FieldType
, ModFlags
);
3687 Attribute
.ApplyAttributes (ec
, FieldBuilder
, this, OptAttributes
, Location
);
3692 // `set' and `get' accessors are represented with an Accessor.
3694 public class Accessor
{
3696 // Null if the accessor is empty, or a Block if not
3699 public Attributes OptAttributes
;
3701 public Accessor (Block b
, Attributes attrs
)
3704 OptAttributes
= attrs
;
3709 // Properties and Indexers both generate PropertyBuilders, we use this to share
3710 // their common bits.
3712 abstract public class PropertyBase
: MethodCore
{
3713 public Accessor Get
, Set
;
3714 public PropertyBuilder PropertyBuilder
;
3715 public MethodBuilder GetBuilder
, SetBuilder
;
3716 public MethodData GetData
, SetData
;
3718 protected EmitContext ec
;
3720 public PropertyBase (Expression type
, string name
, int mod_flags
, int allowed_mod
,
3721 Parameters parameters
, Accessor get_block
, Accessor set_block
,
3722 Attributes attrs
, Location loc
)
3723 : base (type
, mod_flags
, allowed_mod
, name
, attrs
, parameters
, loc
)
3729 protected override bool DoDefine (TypeContainer parent
)
3731 if (!base.DoDefine (parent
))
3734 ec
= new EmitContext (parent
, Location
, null, MemberType
, ModFlags
);
3740 // Checks our base implementation if any
3742 protected override bool CheckBase (TypeContainer container
)
3744 base.CheckBase (container
);
3746 // Check whether arguments were correct.
3747 if (!DoDefineParameters (container
))
3753 MethodSignature ms
= new MethodSignature (Name
, null, ParameterTypes
);
3758 mi_this
= TypeContainer
.FindMembers (
3759 container
.TypeBuilder
, MemberTypes
.Property
,
3760 BindingFlags
.NonPublic
| BindingFlags
.Public
|
3761 BindingFlags
.Static
| BindingFlags
.Instance
|
3762 BindingFlags
.DeclaredOnly
,
3763 MethodSignature
.method_signature_filter
, ms
);
3765 if (mi_this
.Count
> 0) {
3766 Report
.Error (111, Location
, "Class `" + container
.Name
+ "' " +
3767 "already defines a member called `" + Name
+ "' " +
3768 "with the same parameter types");
3773 if (container
is Interface
)
3777 if ((ModFlags
& Modifiers
.READONLY
) != 0)
3778 retval
= MemberType
;
3781 MethodSignature base_ms
;
3782 if (this is Indexer
) {
3783 string name
, base_name
;
3785 report_name
= "this";
3786 name
= TypeManager
.IndexerPropertyName (container
.TypeBuilder
);
3787 ms
= new MethodSignature (name
, null, ParameterTypes
);
3788 base_name
= TypeManager
.IndexerPropertyName (container
.TypeBuilder
.BaseType
);
3789 base_ms
= new MethodSignature (base_name
, retval
, ParameterTypes
);
3792 ms
= base_ms
= new MethodSignature (Name
, retval
, ParameterTypes
);
3796 // Verify if the parent has a type with the same name, and then
3797 // check whether we have to create a new slot for it or not.
3799 Type ptype
= container
.TypeBuilder
.BaseType
;
3801 MemberInfo parent_member
= null;
3802 MemberList mi
, mi_static
, mi_instance
;
3805 // Find properties with the same name on the base class
3807 mi_static
= TypeContainer
.FindMembers (
3808 ptype
, MemberTypes
.Property
,
3809 BindingFlags
.NonPublic
| BindingFlags
.Public
| BindingFlags
.Static
,
3810 MethodSignature
.inheritable_property_signature_filter
, base_ms
);
3812 mi_instance
= TypeContainer
.FindMembers (
3813 ptype
, MemberTypes
.Property
,
3814 BindingFlags
.NonPublic
| BindingFlags
.Public
| BindingFlags
.Instance
,
3815 MethodSignature
.inheritable_property_signature_filter
,
3819 if (mi_instance
.Count
> 0)
3821 else if (mi_static
.Count
> 0)
3826 if (mi
!= null && mi
.Count
> 0)
3827 parent_member
= (PropertyInfo
) mi
[0];
3829 if (parent_member
is PropertyInfo
) {
3830 PropertyInfo parent_property
= (PropertyInfo
)parent_member
;
3832 string name
= parent_property
.DeclaringType
.Name
+ "." +
3833 parent_property
.Name
;
3835 MethodInfo
get, set, parent_method
;
3836 get = parent_property
.GetGetMethod (true);
3837 set = parent_property
.GetSetMethod (true);
3840 parent_method
= get;
3841 else if (set != null)
3842 parent_method
= set;
3844 throw new Exception ("Internal error!");
3846 if (!CheckMethodAgainstBase (container
, flags
, parent_method
, name
))
3849 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3850 Type parent_type
= TypeManager
.TypeToCoreType (
3851 parent_property
.PropertyType
);
3853 if (parent_type
!= MemberType
) {
3855 508, Location
, container
.MakeName (Name
) + ": cannot " +
3856 "change return type when overriding " +
3857 "inherited member " + name
);
3861 } else if (parent_member
== null) {
3862 /*if ((ModFlags & Modifiers.NEW) != 0)
3863 WarningNotHiding (container);
3865 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3866 if (this is Indexer
)
3867 Report
.Error (115, Location
,
3868 container
.MakeName (Name
) +
3869 " no suitable indexers found to override");
3871 Report
.Error (115, Location
,
3872 container
.MakeName (Name
) +
3873 " no suitable properties found to override");
3877 if ((ModFlags
& ( Modifiers
.NEW
| Modifiers
.SHADOWS
| Modifiers
.OVERRIDE
)) == 0) {
3878 if ((ModFlags
& Modifiers
.NONVIRTUAL
) != 0) {
3879 Report
.Error (31088, Location
,
3880 container
.MakeName (Name
) + " : Cannot " +
3881 "be declared NotOverridable since this method is " +
3882 "not maked as Overrides");
3885 // if a member of module is not inherited from Object class
3886 // can not be declared protected
3887 if ((container
is Module
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
3888 Report
.Error (31066, Location
,
3889 "'Property' inside a 'Module' can not be declared as " +
3890 "'Protected' or 'Protected Friend'");
3895 public virtual void Emit (TypeContainer tc
)
3898 // The PropertyBuilder can be null for explicit implementations, in that
3899 // case, we do not actually emit the ".property", so there is nowhere to
3900 // put the attribute
3902 if (PropertyBuilder
!= null)
3903 Attribute
.ApplyAttributes (ec
, PropertyBuilder
, this, OptAttributes
, Location
);
3905 if (GetData != null)
3906 GetData.Emit (tc, Get.Block, Get);
3908 if (SetData != null)
3909 SetData.Emit (tc, Set.Block, Set);
3914 public class Property
: PropertyBase
{
3915 const int AllowedModifiers
=
3918 Modifiers
.PROTECTED
|
3919 Modifiers
.INTERNAL
|
3923 Modifiers
.OVERRIDE
|
3924 Modifiers
.ABSTRACT
|
3928 Modifiers
.NONVIRTUAL
|
3930 Modifiers
.READONLY
|
3931 Modifiers
.WRITEONLY
|
3934 string set_parameter_name
;
3935 Parameters get_params
;
3936 Parameters set_params
;
3938 public Property (Expression type
, string name
, int mod_flags
,
3939 Accessor get_block
, Accessor set_block
,
3940 Attributes attrs
, Location loc
, string set_name
,
3941 Parameters p_get
, Parameters p_set
, ArrayList impl_what
)
3942 : base (type
, name
, mod_flags
, AllowedModifiers
,
3944 get_block
, set_block
, attrs
, loc
)
3946 set_parameter_name
= set_name
;
3949 Implements
= impl_what
;
3952 public Property (Expression type
, string name
, int mod_flags
,
3953 Accessor get_block
, Accessor set_block
,
3954 Attributes attrs
, Location loc
)
3955 : this (type
, name
, mod_flags
, get_block
, set_block
, attrs
, loc
,
3956 "Value", Parameters
.EmptyReadOnlyParameters
, Parameters
.EmptyReadOnlyParameters
, null)
3960 public override bool Define (TypeContainer parent
)
3962 Type
[] g_parameters
=null, s_parameters
=null;
3963 Parameter
[] g_parms
, s_parms
;
3964 InternalParameters g_ip
=null, s_ip
=null;
3966 if ((parent
is Struct
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
3967 Report
.Error (30435, Location
,
3968 "'Property' inside a 'Structure' can not be declared as " +
3969 "'Protected' or 'Protected Friend'");
3971 if (!DoDefine (parent
))
3974 if (!CheckBase (parent
))
3977 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
3980 if ((ModFlags
& Modifiers
.WRITEONLY
) == 0)
3983 "Property without 'Get' accessor must have a 'WriteOnly' modifier");
3986 if (get_params
== Parameters
.EmptyReadOnlyParameters
) {
3987 g_parameters
= TypeManager
.NoTypes
;
3988 g_ip
= new InternalParameters (
3989 parent
, Parameters
.EmptyReadOnlyParameters
);
3991 g_parameters
= new Type
[get_params
.FixedParameters
.Length
];
3992 for (int i
= 0; i
< get_params
.FixedParameters
.Length
; i
++) {
3993 g_parameters
[i
] = get_params
.FixedParameters
[i
].ParameterType
;
3995 g_parms
= new Parameter
[get_params
.FixedParameters
.Length
];
3996 for (int i
= 0; i
< get_params
.FixedParameters
.Length
; i
++) {
3997 Parameter tp
= get_params
.FixedParameters
[i
];
3998 g_parms
[i
] = new Parameter (tp
.TypeName
, tp
.Name
,
3999 Parameter
.Modifier
.NONE
, null);
4001 g_ip
= new InternalParameters (
4002 parent
, new Parameters (g_parms
, null, Location
));
4005 GetData
= new MethodData (this, "get", MemberType
,
4006 g_parameters
, g_ip
, CallingConventions
.Standard
,
4007 Get
.OptAttributes
, ModFlags
, flags
, false);
4009 if (!GetData
.Define (parent
))
4012 GetBuilder
= GetData
.MethodBuilder
;
4016 if ((ModFlags
& Modifiers
.READONLY
) == 0)
4019 "Property without 'Set' accessor must have a 'ReadOnly' modifier");
4024 if (set_params
== Parameters
.EmptyReadOnlyParameters
)
4026 s_parameters
= new Type
[1];
4027 s_parameters
[0] = MemberType
;
4029 s_parms
= new Parameter
[1];
4030 s_parms
[0] = new Parameter (Type
, set_parameter_name
,
4031 Parameter
.Modifier
.NONE
, null);
4033 s_parameters
= new Type
[set_params
.FixedParameters
.Length
];
4034 for (int i
= 0; i
< set_params
.FixedParameters
.Length
; i
++) {
4035 s_parameters
[i
] = set_params
.FixedParameters
[i
].ParameterType
;
4038 s_parms
= new Parameter
[set_params
.FixedParameters
.Length
];
4039 for (int i
= 0; i
< set_params
.FixedParameters
.Length
; i
++) {
4040 Parameter tp
= set_params
.FixedParameters
[i
];
4041 s_parms
[i
] = new Parameter (tp
.TypeName
, tp
.Name
,
4042 Parameter
.Modifier
.NONE
, null);
4046 s_ip
= new InternalParameters (
4047 parent
, new Parameters (s_parms
, null, Location
));
4049 SetData
= new MethodData (this, "set", TypeManager
.void_type
,
4050 s_parameters
, s_ip
, CallingConventions
.Standard
,
4051 Set
.OptAttributes
, ModFlags
, flags
, false);
4053 if (!SetData
.Define (parent
))
4056 SetBuilder
= SetData
.MethodBuilder
;
4057 SetBuilder
.DefineParameter (1, ParameterAttributes
.None
,
4058 set_parameter_name
);
4061 // FIXME - PropertyAttributes.HasDefault ?
4063 PropertyAttributes prop_attr
=
4064 PropertyAttributes
.RTSpecialName
|
4065 PropertyAttributes
.SpecialName
;
4067 if (!IsExplicitImpl
){
4068 PropertyBuilder
= parent
.TypeBuilder
.DefineProperty (
4069 Name
, prop_attr
, MemberType
, null);
4071 PropertyBuilder
.SetGetMethod (GetBuilder
);
4072 PropertyBuilder
.SetSetMethod (SetBuilder
);
4075 // HACK for the reasons exposed above
4077 if (!TypeManager
.RegisterProperty (PropertyBuilder
, GetBuilder
, SetBuilder
)) {
4080 "Class `" + parent
.Name
+
4081 "' already contains a definition for the property `" +
4089 public override void Emit (TypeContainer tc
)
4093 if (GetData
!= null)
4095 Parameters
= get_params
;
4096 GetData
.Emit (tc
, Get
.Block
, Get
);
4099 if (SetData
!= null)
4101 Parameters
= set_params
;
4102 SetData
.Emit (tc
, Set
.Block
, Set
);
4109 /// Gigantic workaround for lameness in SRE follows :
4110 /// This class derives from EventInfo and attempts to basically
4111 /// wrap around the EventBuilder so that FindMembers can quickly
4112 /// return this in it search for members
4114 public class MyEventBuilder
: EventInfo
{
4117 // We use this to "point" to our Builder which is
4118 // not really a MemberInfo
4120 EventBuilder MyBuilder
;
4123 // We "catch" and wrap these methods
4125 MethodInfo raise
, remove, add;
4127 EventAttributes attributes
;
4128 Type declaring_type
, reflected_type
, event_type
;
4131 public MyEventBuilder (TypeBuilder type_builder
, string name
, EventAttributes event_attr
, Type event_type
)
4133 MyBuilder
= type_builder
.DefineEvent (name
, event_attr
, event_type
);
4135 // And now store the values in our own fields.
4137 declaring_type
= type_builder
;
4139 reflected_type
= type_builder
;
4141 attributes
= event_attr
;
4143 this.event_type
= event_type
;
4147 // Methods that you have to override. Note that you only need
4148 // to "implement" the variants that take the argument (those are
4149 // the "abstract" methods, the others (GetAddMethod()) are
4152 public override MethodInfo
GetAddMethod (bool nonPublic
)
4157 public override MethodInfo
GetRemoveMethod (bool nonPublic
)
4162 public override MethodInfo
GetRaiseMethod (bool nonPublic
)
4168 // These methods make "MyEventInfo" look like a Builder
4170 public void SetRaiseMethod (MethodBuilder raiseMethod
)
4172 raise
= raiseMethod
;
4173 MyBuilder
.SetRaiseMethod (raiseMethod
);
4176 public void SetRemoveOnMethod (MethodBuilder removeMethod
)
4178 remove = removeMethod
;
4179 MyBuilder
.SetRemoveOnMethod (removeMethod
);
4182 public void SetAddOnMethod (MethodBuilder addMethod
)
4185 MyBuilder
.SetAddOnMethod (addMethod
);
4188 public void SetCustomAttribute (CustomAttributeBuilder cb
)
4190 MyBuilder
.SetCustomAttribute (cb
);
4193 public override object [] GetCustomAttributes (bool inherit
)
4195 // FIXME : There's nothing which can be seemingly done here because
4196 // we have no way of getting at the custom attribute objects of the
4201 public override object [] GetCustomAttributes (Type t
, bool inherit
)
4203 // FIXME : Same here !
4207 public override bool IsDefined (Type t
, bool b
)
4212 public override EventAttributes Attributes
{
4218 public override string Name
{
4224 public override Type DeclaringType
{
4226 return declaring_type
;
4230 public override Type ReflectedType
{
4232 return reflected_type
;
4236 public Type EventType
{
4243 public class Event
: FieldBase
{
4244 const int AllowedModifiers
=
4247 Modifiers
.PROTECTED
|
4248 Modifiers
.INTERNAL
|
4253 Modifiers
.OVERRIDE
|
4257 public readonly Accessor Add
;
4258 public readonly Accessor Remove
;
4259 public MyEventBuilder EventBuilder
;
4261 MethodBuilder AddBuilder
, RemoveBuilder
;
4262 MethodData AddData
, RemoveData
;
4264 public Event (Expression type
, string name
, Object init
, int mod
, Accessor
add,
4265 Accessor
remove, Attributes attrs
, Location loc
)
4266 : base (type
, mod
, AllowedModifiers
, name
, init
, attrs
, loc
)
4273 public Event (Expression type
, string name
, Object init
, int mod
, Accessor
add,
4274 Accessor
remove, Attributes attrs
, ArrayList impl_what
, Location loc
)
4275 : base (type
, mod
, AllowedModifiers
, name
, init
, attrs
, loc
)
4279 Implements
= impl_what
;
4283 public override bool Define (TypeContainer parent
)
4285 EventAttributes e_attr
= EventAttributes
.RTSpecialName
| EventAttributes
.SpecialName
;
4287 if (!DoDefine (parent
))
4290 if (!MemberType
.IsSubclassOf (TypeManager
.delegate_type
)) {
4291 Report
.Error (31044, Location
, "'" + parent
.Name
+ "." + Name
+
4292 "' : event must be of a delegate type");
4296 Type
[] parameter_types
= new Type
[1];
4297 parameter_types
[0] = MemberType
;
4299 Parameter
[] parms
= new Parameter
[1];
4300 parms
[0] = new Parameter (Type
, /* was "value" */ this.Name
, Parameter
.Modifier
.NONE
, null);
4301 InternalParameters ip
= new InternalParameters (
4302 parent
, new Parameters (parms
, null, Location
));
4304 if (!CheckBase (parent
))
4308 // Now define the accessors
4310 AddData
= new MethodData (this, "add", TypeManager
.void_type
,
4311 parameter_types
, ip
, CallingConventions
.Standard
,
4312 (Add
!= null) ? Add
.OptAttributes
: null,
4313 ModFlags
, flags
, false);
4315 if (!AddData
.Define (parent
))
4318 AddBuilder
= AddData
.MethodBuilder
;
4319 AddBuilder
.DefineParameter (1, ParameterAttributes
.None
, /* was "value" */ this.Name
);
4321 RemoveData
= new MethodData (this, "remove", TypeManager
.void_type
,
4322 parameter_types
, ip
, CallingConventions
.Standard
,
4323 (Remove
!= null) ? Remove
.OptAttributes
: null,
4324 ModFlags
, flags
, false);
4326 if (!RemoveData
.Define (parent
))
4329 RemoveBuilder
= RemoveData
.MethodBuilder
;
4330 RemoveBuilder
.DefineParameter (1, ParameterAttributes
.None
, /* was "value" */ this.Name
);
4332 if (!IsExplicitImpl
){
4333 EventBuilder
= new MyEventBuilder (
4334 parent
.TypeBuilder
, Name
, e_attr
, MemberType
);
4336 if (Add
== null && Remove
== null) {
4337 FieldBuilder
= parent
.TypeBuilder
.DefineField (
4339 FieldAttributes
.FamANDAssem
| ((ModFlags
& Modifiers
.STATIC
) != 0 ? FieldAttributes
.Static
: 0));
4340 TypeManager
.RegisterPrivateFieldOfEvent (
4341 (EventInfo
) EventBuilder
, FieldBuilder
);
4342 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
4345 EventBuilder
.SetAddOnMethod (AddBuilder
);
4346 EventBuilder
.SetRemoveOnMethod (RemoveBuilder
);
4348 if (!TypeManager
.RegisterEvent (EventBuilder
, AddBuilder
, RemoveBuilder
)) {
4349 Report
.Error (111, Location
,
4350 "Class `" + parent
.Name
+
4351 "' already contains a definition for the event `" +
4360 void EmitDefaultMethod (EmitContext ec
, bool is_add
)
4362 ILGenerator ig
= ec
.ig
;
4363 MethodInfo method
= null;
4366 method
= TypeManager
.delegate_combine_delegate_delegate
;
4368 method
= TypeManager
.delegate_remove_delegate_delegate
;
4370 if ((ModFlags
& Modifiers
.STATIC
) != 0) {
4371 ig
.Emit (OpCodes
.Ldsfld
, (FieldInfo
) FieldBuilder
);
4372 ig
.Emit (OpCodes
.Ldarg_0
);
4373 ig
.Emit (OpCodes
.Call
, method
);
4374 ig
.Emit (OpCodes
.Castclass
, MemberType
);
4375 ig
.Emit (OpCodes
.Stsfld
, (FieldInfo
) FieldBuilder
);
4377 ig
.Emit (OpCodes
.Ldarg_0
);
4378 ig
.Emit (OpCodes
.Ldarg_0
);
4379 ig
.Emit (OpCodes
.Ldfld
, (FieldInfo
) FieldBuilder
);
4380 ig
.Emit (OpCodes
.Ldarg_1
);
4381 ig
.Emit (OpCodes
.Call
, method
);
4382 ig
.Emit (OpCodes
.Castclass
, MemberType
);
4383 ig
.Emit (OpCodes
.Stfld
, (FieldInfo
) FieldBuilder
);
4385 ig
.Emit (OpCodes
.Ret
);
4388 public void Emit (TypeContainer tc
)
4392 ec
= new EmitContext (tc
, Location
, null, MemberType
, ModFlags
);
4393 Attribute
.ApplyAttributes (ec
, EventBuilder
, this, OptAttributes
, Location
);
4396 AddData
.Emit (tc
, Add
.Block
, Add
);
4398 ILGenerator ig
= AddData
.MethodBuilder
.GetILGenerator ();
4399 ec
= new EmitContext (tc
, Location
, ig
, TypeManager
.void_type
, ModFlags
);
4400 EmitDefaultMethod (ec
, true);
4404 RemoveData
.Emit (tc
, Remove
.Block
, Remove
);
4406 ILGenerator ig
= RemoveData
.MethodBuilder
.GetILGenerator ();
4407 ec
= new EmitContext (tc
, Location
, ig
, TypeManager
.void_type
, ModFlags
);
4408 EmitDefaultMethod (ec
, false);
4415 // FIXME: This does not handle:
4417 // int INTERFACENAME [ args ]
4422 // int this [ args ]
4424 public class Indexer
: PropertyBase
{
4426 const int AllowedModifiers
=
4429 Modifiers
.PROTECTED
|
4430 Modifiers
.INTERNAL
|
4434 Modifiers
.OVERRIDE
|
4439 public string IndexerName
;
4440 public string InterfaceIndexerName
;
4443 // Are we implementing an interface ?
4445 bool IsImplementing
= false;
4447 public Indexer (Expression type
, string int_type
, int flags
, Parameters parameters
,
4448 Accessor get_block
, Accessor set_block
, Attributes attrs
, Location loc
)
4449 : base (type
, "", flags
, AllowedModifiers
, parameters
, get_block
, set_block
,
4452 ExplicitInterfaceName
= int_type
;
4455 public override bool Define (TypeContainer parent
)
4457 PropertyAttributes prop_attr
=
4458 PropertyAttributes
.RTSpecialName
|
4459 PropertyAttributes
.SpecialName
;
4461 if (!DoDefine (parent
))
4464 IndexerName
= Attribute
.ScanForIndexerName (ec
, OptAttributes
);
4465 if (IndexerName
== null)
4466 IndexerName
= "Item";
4467 else if (IsExplicitImpl
)
4468 Report
.Error (592, Location
,
4469 "Attribute 'IndexerName' is not valid on this declaration " +
4470 "type. It is valid on `property' declarations only.");
4472 ShortName
= IndexerName
;
4473 if (IsExplicitImpl
) {
4474 InterfaceIndexerName
= TypeManager
.IndexerPropertyName (InterfaceType
);
4475 Name
= InterfaceType
.FullName
+ "." + IndexerName
;
4477 InterfaceIndexerName
= IndexerName
;
4481 if (!CheckBase (parent
))
4485 InternalParameters ip
= new InternalParameters (parent
, Parameters
);
4487 GetData
= new MethodData (this, "get", MemberType
,
4488 ParameterTypes
, ip
, CallingConventions
.Standard
,
4489 Get
.OptAttributes
, ModFlags
, flags
, false);
4491 if (!GetData
.Define (parent
))
4494 GetBuilder
= GetData
.MethodBuilder
;
4498 int top
= ParameterTypes
.Length
;
4499 Type
[] set_pars
= new Type
[top
+ 1];
4500 ParameterTypes
.CopyTo (set_pars
, 0);
4501 set_pars
[top
] = MemberType
;
4503 Parameter
[] fixed_parms
= Parameters
.FixedParameters
;
4505 if (fixed_parms
== null){
4506 throw new Exception ("We currently do not support only array arguments in an indexer");
4507 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4508 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4510 // Here is the problem: the `value' parameter has
4511 // to come *after* the array parameter in the declaration
4513 // X (object [] x, Type value)
4516 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4517 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4521 Parameter
[] tmp
= new Parameter
[fixed_parms
.Length
+ 1];
4524 fixed_parms
.CopyTo (tmp
, 0);
4525 tmp
[fixed_parms
.Length
] = new Parameter (
4526 Type
, /* was "value" */ this.Name
, Parameter
.Modifier
.NONE
, null);
4528 Parameters set_formal_params
= new Parameters (tmp
, null, Location
);
4530 InternalParameters ip
= new InternalParameters (parent
, set_formal_params
);
4532 SetData
= new MethodData (this, "set", TypeManager
.void_type
,
4533 set_pars
, ip
, CallingConventions
.Standard
,
4534 Set
.OptAttributes
, ModFlags
, flags
, false);
4536 if (!SetData
.Define (parent
))
4539 SetBuilder
= SetData
.MethodBuilder
;
4543 // Now name the parameters
4545 Parameter
[] p
= Parameters
.FixedParameters
;
4549 for (i
= 0; i
< p
.Length
; ++i
) {
4551 GetBuilder
.DefineParameter (
4552 i
+ 1, p
[i
].Attributes
, p
[i
].Name
);
4555 SetBuilder
.DefineParameter (
4556 i
+ 1, p
[i
].Attributes
, p
[i
].Name
);
4561 SetBuilder
.DefineParameter (
4562 i
+ 1, ParameterAttributes
.None
, /* was "value" */ this.Name
);
4564 if (i
!= ParameterTypes
.Length
) {
4565 Parameter array_param
= Parameters
.ArrayParameter
;
4566 SetBuilder
.DefineParameter (
4567 i
+ 1, array_param
.Attributes
, array_param
.Name
);
4571 if (GetData
!= null)
4572 IsImplementing
= GetData
.IsImplementing
;
4573 else if (SetData
!= null)
4574 IsImplementing
= SetData
.IsImplementing
;
4577 // Define the PropertyBuilder if one of the following conditions are met:
4578 // a) we're not implementing an interface indexer.
4579 // b) the indexer has a different IndexerName and this is no
4580 // explicit interface implementation.
4582 if (!IsExplicitImpl
) {
4583 PropertyBuilder
= parent
.TypeBuilder
.DefineProperty (
4584 IndexerName
, prop_attr
, MemberType
, ParameterTypes
);
4586 if (GetData
!= null)
4587 PropertyBuilder
.SetGetMethod (GetBuilder
);
4589 if (SetData
!= null)
4590 PropertyBuilder
.SetSetMethod (SetBuilder
);
4592 TypeManager
.RegisterIndexer (PropertyBuilder
, GetBuilder
, SetBuilder
,
4600 struct MethodSignature
{
4602 public Type RetType
;
4603 public Type
[] Parameters
;
4606 /// This delegate is used to extract methods which have the
4607 /// same signature as the argument
4609 public static MemberFilter method_signature_filter
;
4612 /// This delegate is used to extract methods which have the
4613 /// same signature as the argument except for the name
4615 public static MemberFilter method_signature_noname_filter
;
4618 /// This delegate is used to extract inheritable methods which
4619 /// have the same signature as the argument. By inheritable,
4620 /// this means that we have permissions to override the method
4621 /// from the current assembly and class
4623 public static MemberFilter inheritable_method_signature_filter
;
4626 /// This delegate is used to extract inheritable methods which
4627 /// have the same signature as the argument. By inheritable,
4628 /// this means that we have permissions to override the method
4629 /// from the current assembly and class
4631 public static MemberFilter inheritable_property_signature_filter
;
4633 static MethodSignature ()
4635 method_signature_filter
= new MemberFilter (MemberSignatureCompare
);
4636 method_signature_noname_filter
= new MemberFilter (MemberSignatureCompareNoName
);
4637 inheritable_method_signature_filter
= new MemberFilter (
4638 InheritableMemberSignatureCompare
);
4639 inheritable_property_signature_filter
= new MemberFilter (
4640 InheritablePropertySignatureCompare
);
4643 public MethodSignature (string name
, Type ret_type
, Type
[] parameters
)
4648 if (parameters
== null)
4649 Parameters
= TypeManager
.NoTypes
;
4651 Parameters
= parameters
;
4654 public override int GetHashCode ()
4656 return Name
.GetHashCode ();
4659 public override bool Equals (Object o
)
4661 MethodSignature other
= (MethodSignature
) o
;
4663 if (other
.Name
!= Name
)
4666 if (other
.RetType
!= RetType
)
4669 if (Parameters
== null){
4670 if (other
.Parameters
== null)
4675 if (other
.Parameters
== null)
4678 int c
= Parameters
.Length
;
4679 if (other
.Parameters
.Length
!= c
)
4682 for (int i
= 0; i
< c
; i
++)
4683 if (other
.Parameters
[i
] != Parameters
[i
])
4689 static bool MemberSignatureCompareNoName (MemberInfo m
, object filter_criteria
)
4691 return MemberSignatureCompare (m
, filter_criteria
, false);
4694 static bool MemberSignatureCompare (MemberInfo m
, object filter_criteria
)
4696 return MemberSignatureCompare (m
, filter_criteria
, true);
4699 static bool MemberSignatureCompare (MemberInfo m
, object filter_criteria
, bool use_name
)
4701 MethodSignature sig
= (MethodSignature
) filter_criteria
;
4703 if (use_name
&& (m
.Name
!= sig
.Name
))
4707 MethodInfo mi
= m
as MethodInfo
;
4708 PropertyInfo pi
= m
as PropertyInfo
;
4711 ReturnType
= mi
.ReturnType
;
4712 else if (pi
!= null)
4713 ReturnType
= pi
.PropertyType
;
4718 // we use sig.RetType == null to mean `do not check the
4719 // method return value.
4721 if (sig
.RetType
!= null)
4722 if (ReturnType
!= sig
.RetType
)
4727 args
= TypeManager
.GetArgumentTypes (mi
);
4729 args
= TypeManager
.GetArgumentTypes (pi
);
4731 Type
[] sigp
= sig
.Parameters
;
4733 if (args
.Length
!= sigp
.Length
)
4736 for (int i
= args
.Length
; i
> 0; ){
4738 if (args
[i
] != sigp
[i
])
4745 // This filter should be used when we are requesting methods that
4746 // we want to override.
4748 // This makes a number of assumptions, for example
4749 // that the methods being extracted are of a parent
4750 // class (this means we know implicitly that we are
4751 // being called to find out about members by a derived
4754 static bool InheritableMemberSignatureCompare (MemberInfo m
, object filter_criteria
)
4756 if (MemberSignatureCompare (m
, filter_criteria
)){
4757 MethodInfo mi
= (MethodInfo
) m
;
4758 MethodAttributes prot
= mi
.Attributes
& MethodAttributes
.MemberAccessMask
;
4760 // If only accessible to the current class.
4761 if (prot
== MethodAttributes
.Private
)
4764 // If only accessible to the defining assembly or
4765 if (prot
== MethodAttributes
.FamANDAssem
||
4766 prot
== MethodAttributes
.Assembly
){
4767 if (m
.DeclaringType
.Assembly
== CodeGen
.AssemblyBuilder
)
4773 // Anything else (FamOrAssembly and Public) is fine
4780 // This filter should be used when we are requesting properties that
4781 // we want to override.
4783 // This makes a number of assumptions, for example
4784 // that the methods being extracted are of a parent
4785 // class (this means we know implicitly that we are
4786 // being called to find out about members by a derived
4789 static bool InheritablePropertySignatureCompare (MemberInfo m
, object filter_criteria
)
4791 if (MemberSignatureCompare (m
, filter_criteria
)){
4792 PropertyInfo pi
= (PropertyInfo
) m
;
4794 MethodInfo inherited_get
= TypeManager
.GetPropertyGetter (pi
);
4795 MethodInfo inherited_set
= TypeManager
.GetPropertySetter (pi
);
4797 MethodInfo mi
= inherited_get
== null ? inherited_set
: inherited_get
;
4799 MethodAttributes prot
= mi
.Attributes
& MethodAttributes
.MemberAccessMask
;
4801 // If only accessible to the current class.
4802 if (prot
== MethodAttributes
.Private
)
4805 // If only accessible to the defining assembly or
4806 if (prot
== MethodAttributes
.FamANDAssem
||
4807 prot
== MethodAttributes
.Assembly
){
4808 if (m
.DeclaringType
.Assembly
== CodeGen
.AssemblyBuilder
)
4814 // Anything else (FamOrAssembly and Public) is fine