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
;
87 /* ArrayList indexers; */
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 // Information in the case we are an attribute type
121 AttributeUsageAttribute attribute_usage
= new AttributeUsageAttribute (AttributeTargets
.All
);
123 public AttributeUsageAttribute AttributeUsage
{
125 return attribute_usage
;
129 attribute_usage
= value;
133 // The interfaces we implement.
136 // The parent member container and our member cache
137 IMemberContainer parent_container
;
138 MemberCache member_cache
;
141 // The indexer name for this class
143 public string IndexerName
;
145 public TypeContainer (TypeContainer parent
, string name
, Attributes attrs
, Location l
)
146 : base (parent
, name
, attrs
, l
)
149 types
= new ArrayList ();
156 base_class_name
= null;
158 //Console.WriteLine ("New class " + name + " inside " + n);
161 public override AttributeTargets AttributeTargets
{
163 throw new NotSupportedException ();
167 public AdditionResult
AddConstant (Const constant
)
170 string basename
= constant
.Name
;
172 if ((res
= IsValid (basename
)) != AdditionResult
.Success
)
175 if (constants
== null)
176 constants
= new ArrayList ();
178 constants
.Add (constant
);
179 DefineName (Name
+ "." + basename
, constant
);
181 return AdditionResult
.Success
;
184 public AdditionResult
AddEnum (Mono
.MonoBASIC
.Enum e
)
188 if ((res
= IsValid (e
.Basename
)) != AdditionResult
.Success
)
192 enums
= new ArrayList ();
195 DefineName (e
.Name
, e
);
197 return AdditionResult
.Success
;
200 public AdditionResult
AddClass (Class c
)
204 if ((res
= IsValid (c
.Basename
)) != AdditionResult
.Success
)
209 DefineName (c
.Name
, c
);
212 // FIXME: Do we really need to explicitly add an empty default static constructor?
213 // Apparently we don't
214 /* if (c.default_static_constructor == null)
216 bool isModule = c is Mono.MonoBASIC.Module;
217 Constructor dc = new Constructor ("New", Parameters.EmptyReadOnlyParameters, null, c.Location);
218 dc.ModFlags = isModule ? Modifiers.PUBLIC | Modifiers.STATIC : Modifiers.PUBLIC;
219 c.AddConstructor (dc);
222 //--------------------------------------------------------------
224 return AdditionResult
.Success
;
227 public AdditionResult
AddStruct (Struct s
)
231 if ((res
= IsValid (s
.Basename
)) != AdditionResult
.Success
)
234 DefineName (s
.Name
, s
);
237 return AdditionResult
.Success
;
240 public AdditionResult
AddDelegate (Delegate d
)
244 if ((res
= IsValid (d
.Basename
)) != AdditionResult
.Success
)
247 if (delegates
== null)
248 delegates
= new ArrayList ();
250 DefineName (d
.Name
, d
);
253 return AdditionResult
.Success
;
256 public AdditionResult
AddMethod (Method method
)
258 string basename
= method
.Name
;
259 string fullname
= Name
+ "." + basename
;
261 Object
value = defined_names
[fullname
];
263 if (value != null && (!(value is Method
)))
264 return AdditionResult
.NameExists
;
266 if (basename
== Basename
)
267 return AdditionResult
.EnclosingClash
;
270 methods
= new ArrayList ();
272 if (method
.Name
.IndexOf (".") != -1)
273 methods
.Insert (0, method
);
275 methods
.Add (method
);
278 DefineName (fullname
, method
);
280 return AdditionResult
.Success
;
283 public AdditionResult
AddConstructor (Constructor c
)
286 return AdditionResult
.NotAConstructor
;
288 bool is_static
= (c
.ModFlags
& Modifiers
.STATIC
) != 0;
291 have_static_constructor
= true;
292 if (default_static_constructor
!= null){
293 Console
.WriteLine ("I have a static constructor already");
294 Console
.WriteLine (" " + default_static_constructor
);
295 return AdditionResult
.MethodExists
;
298 default_static_constructor
= c
;
301 /*if (default_constructor != null)
302 return AdditionResult.MethodExists;*/
303 default_constructor
= c
;
306 if (instance_constructors
== null)
307 instance_constructors
= new ArrayList ();
309 instance_constructors
.Add (c
);
312 return AdditionResult
.Success
;
315 public AdditionResult
AddInterface (Interface iface
)
319 if ((res
= IsValid (iface
.Basename
)) != AdditionResult
.Success
)
322 if (interfaces
== null)
323 interfaces
= new ArrayList ();
324 interfaces
.Add (iface
);
325 DefineName (iface
.Name
, iface
);
327 return AdditionResult
.Success
;
330 public AdditionResult
AddField (Field field
)
333 string basename
= field
.Name
;
335 if ((res
= IsValid (basename
)) != AdditionResult
.Success
)
339 fields
= new ArrayList ();
343 if (field
.HasInitializer
){
344 if ((field
.ModFlags
& Modifiers
.STATIC
) != 0) {
345 if (initialized_static_fields
== null)
346 initialized_static_fields
= new ArrayList ();
348 initialized_static_fields
.Add (field
);
351 // We have not seen a static constructor,
352 // but we will provide static initialization of fields
354 have_static_constructor
= true;
356 if (initialized_fields
== null)
357 initialized_fields
= new ArrayList ();
359 initialized_fields
.Add (field
);
363 if ((field
.ModFlags
& Modifiers
.STATIC
) == 0)
364 have_nonstatic_fields
= true;
366 DefineName (Name
+ "." + basename
, field
);
367 return AdditionResult
.Success
;
370 public AdditionResult
AddProperty (Property prop
)
373 string basename
= prop
.Name
;
375 if ((res
= IsValid (basename
)) != AdditionResult
.Success
)
378 if (properties
== null)
379 properties
= new ArrayList ();
381 if (prop
.Name
.IndexOf (".") != -1)
382 properties
.Insert (0, prop
);
384 properties
.Add (prop
);
385 DefineName (Name
+ "." + basename
, prop
);
387 return AdditionResult
.Success
;
390 public AdditionResult
AddEvent (Event e
)
393 string basename
= e
.Name
;
395 if ((res
= IsValid (basename
)) != AdditionResult
.Success
)
399 events
= new ArrayList ();
402 DefineName (Name
+ "." + basename
, e
);
404 return AdditionResult
.Success
;
408 public AdditionResult AddIndexer (Indexer i)
410 if (indexers == null)
411 indexers = new ArrayList ();
413 if (i.InterfaceType != null)
414 indexers.Insert (0, i);
418 return AdditionResult.Success;
422 public AdditionResult
AddEventHandler (Statement stmt
)
424 if (handlers
== null)
425 handlers
= new ArrayList ();
428 return AdditionResult
.Success
;
431 public void RegisterOrder (Interface iface
)
433 if (interface_order
== null)
434 interface_order
= new ArrayList ();
436 interface_order
.Add (iface
);
439 public ArrayList Types
{
445 public ArrayList Methods
{
451 public ArrayList Constants
{
457 public ArrayList Interfaces
{
465 return base_class_name
;
469 public ArrayList Bases
{
479 public ArrayList Fields
{
489 public ArrayList InstanceConstructors
{
491 return instance_constructors
;
495 public ArrayList Properties
{
501 public ArrayList Events
{
507 public ArrayList Enums
{
514 public ArrayList Indexers {
521 public ArrayList Delegates
{
527 public bool HaveStaticConstructor
{
529 return have_static_constructor
;
533 public virtual TypeAttributes TypeAttr
{
535 return Modifiers
.TypeAttr (ModFlags
, this);
539 public ArrayList EventHandlers
{
546 // Emits the instance field initializers
548 public bool EmitFieldInitializers (EmitContext ec
)
551 ILGenerator ig
= ec
.ig
;
552 Expression instance_expr
;
555 fields
= initialized_static_fields
;
556 instance_expr
= null;
558 fields
= initialized_fields
;
559 instance_expr
= new This (Location
.Null
).Resolve (ec
);
565 foreach (Field f
in fields
){
566 Expression e
= f
.GetInitializerExpression (ec
);
570 Location l
= f
.Location
;
571 FieldExpr fe
= new FieldExpr (f
.FieldBuilder
, l
);
572 fe
.InstanceExpression
= instance_expr
;
573 Expression a
= new Assign (fe
, e
, l
);
579 if (a
is ExpressionStatement
)
580 ((ExpressionStatement
) a
).EmitStatement (ec
);
582 throw new Exception ("Assign.Resolve returned a non ExpressionStatement");
590 // Defines the default constructors
592 void DefineDefaultConstructor (bool is_static
)
597 c
= new Constructor ("New", Parameters
.EmptyReadOnlyParameters
,
602 mods
= Modifiers
.STATIC
;
606 c
.Initializer
= new ConstructorBaseInitializer (
607 null, Parameters
.EmptyReadOnlyParameters
,
612 c
.Block
= new Block (null);
616 public void ReportStructInitializedInstanceError ()
618 string n
= TypeBuilder
.FullName
;
620 foreach (Field f
in initialized_fields
){
623 "`" + n
+ "." + f
.Name
+ "': can not have " +
624 "instance field initializers in structs");
629 /// The pending methods that need to be implemented (interfaces or abstract methods)
631 public PendingImplementation Pending
;
634 /// This function computes the Base class and also the
635 /// list of interfaces that the class or struct @c implements.
637 /// The return value is an array (might be null) of
638 /// interfaces implemented (as Types).
640 /// The @parent argument is set to the parent object or null
641 /// if this is `System.Object'.
643 Type
[] GetClassBases (bool is_class
, out Type parent
, out bool error
)
645 ArrayList bases
= Bases
;
654 parent
= TypeManager
.value_type
;
658 if (RootContext
.StdLib
)
659 parent
= TypeManager
.object_type
;
660 else if (Name
!= "System.Object")
661 parent
= TypeManager
.object_type
;
664 // If we are compiling our runtime,
665 // and we are defining ValueType, then our
666 // parent is `System.Object'.
668 if (!RootContext
.StdLib
&& Name
== "System.ValueType")
669 parent
= TypeManager
.object_type
;
676 // Bases should be null if there are no bases at all
680 if (is_class
&& (!(this is Interface
))){
681 Expression name
= (Expression
) bases
[0];
682 name
= ResolveTypeExpr (name
, false, Location
);
689 Type first
= name
.Type
;
695 parent
= TypeManager
.object_type
;
699 if (parent
.IsSealed
)
700 Report
.Error (30299, Location
,
701 "Class " + Name
+ " cannot inherit " +
702 "'NotInheritable' class " + TypeManager
.MonoBASIC_Name (parent
));
704 if (!AsAccessible (parent
, ModFlags
))
705 Report
.Error (30389, Location
,
706 "Inconsistent accessibility: base class `" +
707 TypeManager
.MonoBASIC_Name (parent
) + "' is less " +
708 "accessible than class `" +
715 Type
[] ifaces
= new Type
[count
-start
];
717 for (i
= start
, j
= 0; i
< count
; i
++, j
++){
718 Expression name
= (Expression
) bases
[i
];
719 Expression resolved
= ResolveTypeExpr (name
, false, Location
);
720 bases
[i
] = resolved
;
721 Type t
= resolved
.Type
;
727 if (is_class
== false && !t
.IsInterface
){
728 Report
.Error (527, "In Struct `" + Name
+ "', type `"+
729 name
+"' is not an interface");
736 Report
.Error (30258, "class `"+ Name
+
737 "': a class can not inherit from a struct/enum");
739 /*Report.Error (509, "class `"+ Name +
740 "': Cannot inherit from sealed class `"+
748 Report
.Error (30121, Name
+ ": A class cannot inherit " +
749 "more than one class");
755 for (int x
= 0; x
< j
; x
++) {
756 if (t
== ifaces
[x
]) {
757 Report
.Error (528, "`" + name
+ "' is already listed in interface list");
770 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
772 public override TypeBuilder
DefineType ()
778 if (TypeBuilder
!= null)
791 ec
= new EmitContext (this, Mono
.MonoBASIC
.Location
.Null
, null, null, ModFlags
);
793 if (((ModFlags
& Modifiers
.ABSTRACT
) != 0) &&
794 ((ModFlags
& Modifiers
.SEALED
) != 0)){
795 Report
.Error (31408, Location
,
796 "Class declared as 'MustInherit' cannot be declared as 'NotInheritable'");
799 ifaces
= GetClassBases (is_class
, out parent
, out error
);
803 if (this is Interface
)
806 if (is_class
&& parent
!= null){
807 if (parent
== TypeManager
.enum_type
||
808 (parent
== TypeManager
.value_type
&& RootContext
.StdLib
) ||
809 parent
== TypeManager
.delegate_type
||
810 parent
== TypeManager
.array_type
){
812 644, Location
, "`" + Name
+ "' cannot inherit from " +
813 "special class `" + TypeManager
.MonoBASIC_Name (parent
) + "'");
818 if (!is_class
&& TypeManager
.value_type
== null)
819 throw new Exception ();
821 if (is_class
&& Parent
.Parent
== null && (!(this is Interface
)))
823 if ((ModFlags
& Modifiers
.PRIVATE
) != 0)
824 Report
.Error (31089, Location
,
825 "Only internal classes can be declared as 'Private'");
827 if ((ModFlags
& Modifiers
.PROTECTED
) != 0)
828 Report
.Error (31047, Location
,
829 "Only internal classes can be declared as 'Protected'");
832 if ((Parent
is Module
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
833 Report
.Error (30735, Location
,
834 "'Type' inside a 'Module' can not be " +
835 "declared as 'Protected'");
837 if ((Parent
is Struct
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
838 Report
.Error (30435, Location
,
839 "'Type' inside a 'Structure' can not be " +
840 "declared as 'Protected'");
842 TypeAttributes type_attributes
= TypeAttr
;
844 // if (parent_builder is ModuleBuilder) {
846 ModuleBuilder builder
= CodeGen
.ModuleBuilder
;
847 TypeBuilder
= builder
.DefineType (
848 Name
, type_attributes
, parent
, ifaces
);
851 TypeBuilder builder
= Parent
.TypeBuilder
;
852 TypeBuilder
= builder
.DefineNestedType (
853 Basename
, type_attributes
, parent
, ifaces
);
858 // structure must contain atleast one member variable
859 if(!have_nonstatic_fields
){
861 30281, Location
, "Structure `" + Name
+ "' do not " +
862 "contain any member Variable");
864 /*TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
865 FieldAttributes.Private);*/
868 // add interfaces that were not added at type creation (weird API issue)
869 if (!have_nonstatic_fields
&& (ifaces
!= null)) {
870 foreach (Type i
in ifaces
)
871 TypeBuilder
.AddInterfaceImplementation (i
);
877 // Finish the setup for the EmitContext
879 ec
.ContainerType
= TypeBuilder
;
881 TypeManager
.AddUserType (Name
, TypeBuilder
, this, ifaces
);
883 if ((parent
!= null) &&
884 (parent
== TypeManager
.attribute_type
||
885 parent
.IsSubclassOf (TypeManager
.attribute_type
))) {
886 RootContext
.RegisterAttribute (this);
888 RootContext
.RegisterOrder (this);
890 if (Interfaces
!= null) {
891 foreach (Interface iface
in Interfaces
)
896 foreach (TypeContainer tc
in Types
)
900 if (Delegates
!= null) {
901 foreach (Delegate d
in Delegates
)
906 foreach (Enum en
in Enums
)
916 /// Defines the MemberCore objects that are in the `list' Arraylist
918 /// The `defined_names' array contains a list of members defined in
921 static ArrayList remove_list
= new ArrayList ();
922 void DefineMembers (ArrayList list
, MemberInfo
[] defined_names
)
926 // if one of the overloaded method is having
927 // Shadows or Overloads modifier all other should
928 // have the same modifier
929 Hashtable members
= new Hashtable();
931 foreach (MemberCore mc
in list
)
934 if(members
[mc
.Name
] == null)
936 foreach (MemberCore m
in list
)
938 if(m
.Name
== mc
.Name
)
940 if ((m
.ModFlags
& Modifiers
.SHADOWS
) != 0)
942 modval
= Modifiers
.SHADOWS
;
945 else if((m
.ModFlags
& Modifiers
.NEW
) != 0)
947 modval
= Modifiers
.NEW
;
951 members
.Add(mc
.Name
, modval
);
954 modval
= (int)members
[mc
.Name
];
957 if(((modval
& Modifiers
.SHADOWS
) != 0) && ((mc
.ModFlags
& Modifiers
.SHADOWS
) == 0))
960 "Function '" + mc
.Name
+ "': must be declared 'Shadows' " +
961 "because another '" + mc
.Name
+ "' declared 'Shadows'");
962 else if(((modval
& Modifiers
.NEW
) != 0) && ((mc
.ModFlags
& Modifiers
.NEW
) == 0))
965 "Function '" + mc
.Name
+ "': must be declared 'Overloads' " +
966 "because another '" + mc
.Name
+ "' declared 'Overloads'");
970 remove_list
.Clear ();
972 foreach (MemberCore mc
in list
){
973 if (!mc
.Define (this)){
974 remove_list
.Add (mc
);
978 if (defined_names
== null)
981 idx
= Array
.BinarySearch (defined_names
, mc
.Name
, mif_compare
);
983 if (RootContext
.WarningLevel
>= 4){
984 if ((mc
.ModFlags
& Modifiers
.NEW
) != 0)
985 Warning_KewywordNewNotRequired (mc
.Location
, mc
);
986 if ((mc
.ModFlags
& Modifiers
.SHADOWS
) != 0)
987 Warning_KewywordShadowsNotRequired (mc
.Location
, mc
);
992 MemberInfo match
= defined_names
[idx
];
994 if (match
is PropertyInfo
&& ((mc
.ModFlags
& Modifiers
.OVERRIDE
) != 0))
998 // If we are both methods, let the method resolution emit warnings
1000 if (match
is MethodBase
&& mc
is MethodCore
)
1003 if (((mc
.ModFlags
& Modifiers
.SHADOWS
) == 0) && idx
> 0)
1004 Warning_KeywordShadowsRequired (mc
.Location
, defined_names
[idx
]);
1008 foreach (object o
in remove_list
)
1011 remove_list
.Clear ();
1015 // Defines the indexers, and also verifies that the IndexerNameAttribute in the
1016 // class is consisten. Either it is `Item' or it is the name defined by all the
1017 // indexers with the `IndexerName' attribute.
1019 // Turns out that the IndexerNameAttribute is applied to each indexer,
1020 // but it is never emitted, instead a DefaultName attribute is attached
1023 void DefineIndexers ()
1025 string class_indexer_name
= null;
1028 foreach (Indexer i in Indexers){
1033 name = i.IndexerName;
1035 if (i.InterfaceType != null)
1038 if (class_indexer_name == null){
1039 class_indexer_name = name;
1043 if (name == class_indexer_name)
1047 668, "Two indexers have different names, " +
1048 " you should use the same name for all your indexers");
1052 if (class_indexer_name
== null)
1053 class_indexer_name
= "Item";
1054 IndexerName
= class_indexer_name
;
1057 static void Error_KeywordNotAllowed (Location loc
)
1059 Report
.Error (1530, loc
, "Keyword new not allowed for namespace elements");
1063 /// Populates our TypeBuilder with fields and methods
1065 public override bool DefineMembers (TypeContainer parent
)
1067 MemberInfo
[] defined_names
= null;
1069 if (interface_order
!= null){
1070 foreach (Interface iface
in interface_order
)
1071 if ((iface
.ModFlags
& Modifiers
.NEW
) == 0)
1072 iface
.DefineMembers (this);
1074 Error_KeywordNotAllowed (iface
.Location
);
1077 if (RootContext
.WarningLevel
> 1){
1081 // This code throws an exception in the comparer
1082 // I guess the string is not an object?
1084 ptype
= TypeBuilder
.BaseType
;
1086 defined_names
= (MemberInfo
[]) FindMembers (
1087 ptype
, MemberTypes
.All
& ~MemberTypes
.Constructor
,
1088 BindingFlags
.Public
| BindingFlags
.Instance
|
1089 BindingFlags
.Static
, null, null);
1091 Array
.Sort (defined_names
, mif_compare
);
1095 if (constants
!= null)
1096 DefineMembers (constants
, defined_names
);
1099 DefineMembers (fields
, defined_names
);
1101 if (this is Class
&& (!(this is Interface
))){
1102 if (instance_constructors
== null){
1103 if (default_constructor
== null)
1104 DefineDefaultConstructor (false);
1107 if (initialized_static_fields
!= null &&
1108 default_static_constructor
== null)
1109 DefineDefaultConstructor (true);
1112 if (this is Struct
){
1114 // Structs can not have initialized instance
1117 if (initialized_static_fields
!= null &&
1118 default_static_constructor
== null)
1119 DefineDefaultConstructor (true);
1121 if (initialized_fields
!= null)
1122 ReportStructInitializedInstanceError ();
1125 if (!(this is Interface
))
1126 Pending
= PendingImplementation
.GetPendingImplementations (this);
1128 // Constructors are not in the defined_names array
1130 if (instance_constructors
!= null)
1131 DefineMembers (instance_constructors
, null);
1133 if (default_static_constructor
!= null)
1134 default_static_constructor
.Define (this);
1136 if (methods
!= null)
1137 DefineMembers (methods
, defined_names
);
1139 if (properties
!= null)
1140 DefineMembers (properties
, defined_names
);
1143 DefineMembers (events
, defined_names
);
1146 if (indexers != null) {
1150 IndexerName
= "Item";
1153 DefineMembers (enums
, defined_names
);
1155 if (delegates
!= null)
1156 DefineMembers (delegates
, defined_names
);
1159 if (TypeBuilder
.BaseType
!= null)
1160 parent_container
= TypeManager
.LookupMemberContainer (TypeBuilder
.BaseType
);
1162 member_cache
= new MemberCache (this);
1168 public override bool Define (TypeContainer parent
)
1170 if (interface_order
!= null){
1171 foreach (Interface iface
in interface_order
)
1172 if ((iface
.ModFlags
& Modifiers
.NEW
) == 0)
1173 iface
.Define (this);
1180 /// This function is based by a delegate to the FindMembers routine
1182 static bool AlwaysAccept (MemberInfo m
, object filterCriteria
)
1188 /// This filter is used by FindMembers, and we just keep
1189 /// a global for the filter to `AlwaysAccept'
1191 static MemberFilter accepting_filter
;
1195 /// A member comparission method based on name only
1197 static IComparer mif_compare
;
1199 static TypeContainer ()
1201 accepting_filter
= new MemberFilter (AlwaysAccept
);
1202 mif_compare
= new MemberInfoCompare ();
1206 /// This method returns the members of this type just like Type.FindMembers would
1207 /// Only, we need to use this for types which are _being_ defined because MS'
1208 /// implementation can't take care of that.
1211 // FIXME: return an empty static array instead of null, that cleans up
1212 // some code and is consistent with some coding conventions I just found
1216 // Notice that in various cases we check if our field is non-null,
1217 // something that would normally mean that there was a bug elsewhere.
1219 // The problem happens while we are defining p-invoke methods, as those
1220 // will trigger a FindMembers, but this happens before things are defined
1222 // Since the whole process is a no-op, it is fine to check for null here.
1224 public override MemberList
FindMembers (MemberTypes mt
, BindingFlags bf
,
1225 MemberFilter filter
, object criteria
)
1227 ArrayList members
= new ArrayList ();
1230 if ((bf
& BindingFlags
.Public
) != 0)
1231 modflags
|= Modifiers
.PUBLIC
| Modifiers
.PROTECTED
|
1233 if ((bf
& BindingFlags
.NonPublic
) != 0)
1234 modflags
|= Modifiers
.PRIVATE
;
1236 int static_mask
= 0, static_flags
= 0;
1237 switch (bf
& (BindingFlags
.Static
| BindingFlags
.Instance
)) {
1238 case BindingFlags
.Static
:
1239 static_mask
= static_flags
= Modifiers
.STATIC
;
1242 case BindingFlags
.Instance
:
1243 static_mask
= Modifiers
.STATIC
;
1248 static_mask
= static_flags
= 0;
1252 Timer
.StartTimer (TimerType
.TcFindMembers
);
1255 filter
= accepting_filter
;
1257 if ((mt
& MemberTypes
.Field
) != 0) {
1258 if (fields
!= null) {
1259 foreach (Field f
in fields
) {
1260 if ((f
.ModFlags
& modflags
) == 0)
1262 if ((f
.ModFlags
& static_mask
) != static_flags
)
1265 FieldBuilder fb
= f
.FieldBuilder
;
1266 if (fb
!= null && filter (fb
, criteria
) == true)
1271 if (constants
!= null) {
1272 foreach (Const con
in constants
) {
1273 if ((con
.ModFlags
& modflags
) == 0)
1275 if ((con
.ModFlags
& static_mask
) != static_flags
)
1278 FieldBuilder fb
= con
.FieldBuilder
;
1279 if (fb
!= null && filter (fb
, criteria
) == true)
1285 if ((mt
& MemberTypes
.Method
) != 0) {
1286 if (methods
!= null) {
1287 foreach (Method m
in methods
) {
1288 if ((m
.ModFlags
& modflags
) == 0)
1290 if ((m
.ModFlags
& static_mask
) != static_flags
)
1293 MethodBuilder mb
= m
.MethodBuilder
;
1295 if (mb
!= null && filter (mb
, criteria
) == true)
1300 if (properties
!= null){
1301 foreach (Property p
in properties
){
1302 if ((p
.ModFlags
& modflags
) == 0)
1304 if ((p
.ModFlags
& static_mask
) != static_flags
)
1310 if (b
!= null && filter (b
, criteria
) == true)
1314 if (b
!= null && filter (b
, criteria
) == true)
1320 if (indexers != null){
1321 foreach (Indexer ix in indexers){
1322 if ((ix.ModFlags & modflags) == 0)
1324 if ((ix.ModFlags & static_mask) != static_flags)
1330 if (b != null && filter (b, criteria) == true)
1334 if (b != null && filter (b, criteria) == true)
1341 if ((mt
& MemberTypes
.Event
) != 0) {
1343 foreach (Event e
in events
) {
1344 if ((e
.ModFlags
& modflags
) == 0)
1346 if ((e
.ModFlags
& static_mask
) != static_flags
)
1349 MemberInfo eb
= e
.EventBuilder
;
1350 if (eb
!= null && filter (eb
, criteria
) == true)
1351 members
.Add (e
.EventBuilder
);
1355 if ((mt
& MemberTypes
.Property
) != 0){
1356 if (properties
!= null)
1357 foreach (Property p
in properties
) {
1358 if ((p
.ModFlags
& modflags
) == 0)
1360 if ((p
.ModFlags
& static_mask
) != static_flags
)
1363 MemberInfo pb
= p
.PropertyBuilder
;
1365 if (pb
!= null && filter (pb
, criteria
) == true)
1366 members
.Add (p
.PropertyBuilder
);
1370 if (indexers != null)
1371 foreach (Indexer ix in indexers) {
1372 if ((ix.ModFlags & modflags) == 0)
1374 if ((ix.ModFlags & static_mask) != static_flags)
1377 MemberInfo ib = ix.PropertyBuilder;
1378 if (ib != null && filter (ib, criteria) == true) {
1379 members.Add (ix.PropertyBuilder);
1385 if ((mt
& MemberTypes
.NestedType
) != 0) {
1387 foreach (TypeContainer t
in types
) {
1388 if ((t
.ModFlags
& modflags
) == 0)
1391 TypeBuilder tb
= t
.TypeBuilder
;
1392 if (tb
!= null && (filter (tb
, criteria
) == true))
1398 foreach (Enum en
in enums
){
1399 if ((en
.ModFlags
& modflags
) == 0)
1402 TypeBuilder tb
= en
.TypeBuilder
;
1403 if (tb
!= null && (filter (tb
, criteria
) == true))
1408 if (delegates
!= null){
1409 foreach (Delegate d
in delegates
){
1410 if ((d
.ModFlags
& modflags
) == 0)
1413 TypeBuilder tb
= d
.TypeBuilder
;
1414 if (tb
!= null && (filter (tb
, criteria
) == true))
1419 if (interfaces
!= null){
1420 foreach (Interface iface
in interfaces
){
1421 if ((iface
.ModFlags
& modflags
) == 0)
1424 TypeBuilder tb
= iface
.TypeBuilder
;
1425 if (tb
!= null && (filter (tb
, criteria
) == true))
1431 if ((mt
& MemberTypes
.Constructor
) != 0){
1432 if (((bf
& BindingFlags
.Instance
) != 0) && (instance_constructors
!= null)){
1433 foreach (Constructor c
in instance_constructors
){
1434 if ((c
.ModFlags
& modflags
) == 0)
1437 ConstructorBuilder cb
= c
.ConstructorBuilder
;
1439 if (filter (cb
, criteria
) == true)
1444 if (((bf
& BindingFlags
.Static
) != 0) && (default_static_constructor
!= null) &&
1445 ((default_static_constructor
.ModFlags
& modflags
) != 0)){
1446 ConstructorBuilder cb
=
1447 default_static_constructor
.ConstructorBuilder
;
1450 if (filter (cb
, criteria
) == true)
1456 // Lookup members in parent if requested.
1458 if (((bf
& BindingFlags
.DeclaredOnly
) == 0) && (TypeBuilder
.BaseType
!= null)) {
1459 if ((mt
& ~MemberTypes
.Constructor
) != 0) {
1460 MemberList list
= FindMembers (TypeBuilder
.BaseType
, mt
& ~MemberTypes
.Constructor
, bf
, filter
, criteria
);
1461 members
.AddRange (list
);
1465 Timer
.StopTimer (TimerType
.TcFindMembers
);
1467 return new MemberList (members
);
1470 public override MemberCache MemberCache
{
1472 return member_cache
;
1476 public static MemberList
FindMembers (Type t
, MemberTypes mt
, BindingFlags bf
,
1477 MemberFilter filter
, object criteria
)
1479 TypeContainer tc
= TypeManager
.LookupTypeContainer (t
);
1482 return tc
.FindMembers (mt
, bf
, filter
, criteria
);
1484 return new MemberList (t
.FindMembers (mt
, bf
, filter
, criteria
));
1488 // FindMethods will look for methods not only in the type `t', but in
1489 // any interfaces implemented by the type.
1491 public static MethodInfo
[] FindMethods (Type t
, BindingFlags bf
,
1492 MemberFilter filter
, object criteria
)
1498 /// Emits the values for the constants
1500 public void EmitConstants ()
1502 if (constants
!= null)
1503 foreach (Const con
in constants
)
1504 con
.EmitConstant (this);
1509 /// Emits the code, this step is performed after all
1510 /// the types, enumerations, constructors
1514 if (instance_constructors
!= null)
1515 foreach (Constructor c
in instance_constructors
)
1518 if (default_static_constructor
!= null)
1519 default_static_constructor
.Emit (this);
1521 if (methods
!= null)
1522 foreach (Method m
in methods
)
1525 if (properties
!= null)
1526 foreach (Property p
in properties
)
1530 if (indexers != null){
1531 foreach (Indexer ix in indexers)
1534 CustomAttributeBuilder cb = Interface.EmitDefaultMemberAttr (
1535 this, IndexerName, ModFlags, Location);
1536 TypeBuilder.SetCustomAttribute (cb);
1541 foreach (Field f
in fields
)
1544 if (events
!= null){
1545 foreach (Event e
in Events
)
1549 if (Pending
!= null)
1550 if (Pending
.VerifyPendingMethods ())
1553 Attribute
.ApplyAttributes (ec
, TypeBuilder
, this, OptAttributes
, Location
);
1556 // Check for internal or private fields that were never assigned
1558 if (fields
!= null && RootContext
.WarningLevel
>= 3) {
1559 foreach (Field f
in fields
) {
1560 if ((f
.ModFlags
& Modifiers
.PUBLIC
) != 0)
1565 169, f
.Location
, "Private field " +
1566 MakeName (f
.Name
) + " is never used");
1571 // Only report 649 on level 4
1573 if (RootContext
.WarningLevel
< 4)
1576 if ((f
.status
& Field
.Status
.ASSIGNED
) != 0)
1581 "Field " + MakeName (f
.Name
) + " is never assigned " +
1582 " to and will always have its default value");
1586 // if (types != null)
1587 // foreach (TypeContainer tc in types)
1591 public override void CloseType ()
1596 TypeBuilder
.CreateType ();
1598 } catch (TypeLoadException
){
1600 // This is fine, the code still created the type
1602 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
1603 // Console.WriteLine (e.Message);
1605 Console
.WriteLine ("In type: " + Name
);
1610 foreach (Enum en
in Enums
)
1613 if (interface_order
!= null){
1614 foreach (Interface iface
in interface_order
)
1619 foreach (TypeContainer tc
in Types
)
1623 foreach (TypeContainer tc
in Types
)
1624 if (!(tc
is Struct
))
1628 if (Delegates
!= null)
1629 foreach (Delegate d
in Delegates
)
1633 public string MakeName (string n
)
1635 return "`" + Name
+ "." + n
+ "'";
1638 public void Warning_KeywordShadowsRequired (Location l
, MemberInfo mi
)
1641 108, l
, "The keyword 'Shadows' is required on " +
1642 MakeName (mi
.Name
) + " because it shadows `" +
1643 mi
.ReflectedType
.Name
+ "." + mi
.Name
+ "'");
1646 public void Warning_KewywordShadowsNotRequired (Location l
, MemberCore mc
)
1649 109, l
, "The member " + MakeName (mc
.Name
) + " does not hide an " +
1650 "inherited member, the keyword shadows is not required");
1653 public void Warning_KewywordNewNotRequired (Location l
, MemberCore mc
)
1656 109, l
, "The member " + MakeName (mc
.Name
) + " does not hide an " +
1657 "inherited member, the keyword new is not required");
1660 public static int CheckMember (string name
, MemberInfo mi
, int ModFlags
)
1666 // Performs the validation on a Method's modifiers (properties have
1667 // the same properties).
1669 public bool MethodModifiersValid (int flags
, string n
, Location loc
)
1671 const int vao
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
| Modifiers
.OVERRIDE
);
1672 const int va
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
);
1673 const int nv
= (Modifiers
.SHADOWS
| Modifiers
.VIRTUAL
);
1675 string name
= MakeName (n
);
1678 // At most one of static, virtual or override
1680 if ((flags
& Modifiers
.STATIC
) != 0){
1681 if ((flags
& vao
) != 0){
1683 30501, loc
, "Shared method " + name
+ " can not be " +
1684 "declared as Overridable");
1689 if (this is Struct
){
1690 if ((flags
& va
) != 0){
1691 Modifiers
.Error_InvalidModifier (loc
, "virtual or abstract");
1696 if ((flags
& Modifiers
.OVERRIDE
) != 0 && (flags
& Modifiers
.VIRTUAL
) != 0)
1700 ": Methods marked as Overrides cannot be made Overridable");
1704 if ((flags
& Modifiers
.OVERRIDE
) != 0 && (flags
& Modifiers
.SHADOWS
) != 0){
1707 ": Methods marked as Overrides cannot be marked as Shadows");
1712 // If the declaration includes the abstract modifier, then the
1713 // declaration does not include static, virtual or extern
1715 if ((flags
& Modifiers
.ABSTRACT
) != 0){
1716 if ((flags
& Modifiers
.EXTERN
) != 0){
1718 180, loc
, name
+ " can not be both abstract and extern");
1722 if ((flags
& Modifiers
.VIRTUAL
) != 0){
1724 503, loc
, name
+ " can not be both abstract and virtual");
1728 if((ModFlags
& Modifiers
.SEALED
) != 0){
1731 "Class declared as 'NotInheritable' " +
1732 "cannot have a 'MustOverride' member");
1735 else if ((ModFlags
& Modifiers
.ABSTRACT
) == 0){
1738 " is declared as 'MustOverride', hence its container " +
1739 "class should be declared as 'MustInherit'");
1745 if ((flags
& Modifiers
.PRIVATE
) != 0){
1746 if ((flags
& vao
) != 0){
1749 ": Members marked as Overridable or Overrides can not be Private");
1754 if ((flags
& Modifiers
.SEALED
) != 0){
1755 if ((flags
& Modifiers
.OVERRIDE
) == 0){
1758 ": cannot be sealed because it is not an override");
1762 if ((flags
& Modifiers
.NEW
) != 0){
1763 if ((flags
& Modifiers
.SHADOWS
) != 0){
1766 " 'Overloads' and 'Shadows' cannot be combined ");
1774 // Access level of a type.
1777 ProtectedInternal
= 1,
1783 // Check whether `flags' denotes a more restricted access than `level'
1784 // and return the new level.
1785 static AccessLevel
CheckAccessLevel (AccessLevel level
, int flags
)
1787 AccessLevel old_level
= level
;
1789 if ((flags
& Modifiers
.INTERNAL
) != 0) {
1790 if ((flags
& Modifiers
.PROTECTED
) != 0) {
1791 if ((int) level
< (int) AccessLevel
.ProtectedInternal
)
1792 level
= AccessLevel
.ProtectedInternal
;
1794 if ((int) level
< (int) AccessLevel
.Internal
)
1795 level
= AccessLevel
.Internal
;
1797 } else if ((flags
& Modifiers
.PROTECTED
) != 0) {
1798 if ((int) level
< (int) AccessLevel
.Protected
)
1799 level
= AccessLevel
.Protected
;
1800 } else if ((flags
& Modifiers
.PRIVATE
) != 0)
1801 level
= AccessLevel
.Private
;
1806 // Return the access level for a new member which is defined in the current
1807 // TypeContainer with access modifiers `flags'.
1808 AccessLevel
GetAccessLevel (int flags
)
1810 if ((flags
& Modifiers
.PRIVATE
) != 0)
1811 return AccessLevel
.Private
;
1814 if (!IsTopLevel
&& (Parent
!= null))
1815 level
= Parent
.GetAccessLevel (flags
);
1817 level
= AccessLevel
.Public
;
1819 return CheckAccessLevel (CheckAccessLevel (level
, flags
), ModFlags
);
1822 // Return the access level for type `t', but don't give more access than `flags'.
1823 static AccessLevel
GetAccessLevel (Type t
, int flags
)
1825 if (((flags
& Modifiers
.PRIVATE
) != 0) || t
.IsNestedPrivate
)
1826 return AccessLevel
.Private
;
1829 if (TypeManager
.IsBuiltinType (t
))
1830 return AccessLevel
.Public
;
1831 else if ((t
.DeclaringType
!= null) && (t
!= t
.DeclaringType
))
1832 level
= GetAccessLevel (t
.DeclaringType
, flags
);
1834 level
= CheckAccessLevel (AccessLevel
.Public
, flags
);
1837 if (t
.IsNestedPublic
)
1840 if (t
.IsNestedAssembly
|| t
.IsNotPublic
) {
1841 if ((int) level
< (int) AccessLevel
.Internal
)
1842 level
= AccessLevel
.Internal
;
1845 if (t
.IsNestedFamily
) {
1846 if ((int) level
< (int) AccessLevel
.Protected
)
1847 level
= AccessLevel
.Protected
;
1850 if (t
.IsNestedFamORAssem
) {
1851 if ((int) level
< (int) AccessLevel
.ProtectedInternal
)
1852 level
= AccessLevel
.ProtectedInternal
;
1859 // Returns true if `parent' is as accessible as the flags `flags'
1860 // given for this member.
1862 public bool AsAccessible (Type parent
, int flags
)
1864 while (parent
.IsArray
|| parent
.IsPointer
|| parent
.IsByRef
)
1865 parent
= parent
.GetElementType ();
1867 AccessLevel level
= GetAccessLevel (flags
);
1868 AccessLevel level2
= GetAccessLevel (parent
, flags
);
1870 return (int) level
>= (int) level2
;
1873 Hashtable builder_and_args
;
1875 public bool RegisterMethod (MethodBuilder mb
, InternalParameters ip
, Type
[] args
)
1877 if (builder_and_args
== null)
1878 builder_and_args
= new Hashtable ();
1883 /// Performs checks for an explicit interface implementation. First it
1884 /// checks whether the `interface_type' is a base inteface implementation.
1885 /// Then it checks whether `name' exists in the interface type.
1887 public bool VerifyImplements (Type interface_type
, string full
, string name
, Location loc
)
1891 if (ifaces
!= null){
1892 foreach (Type t
in ifaces
){
1893 if (t
== interface_type
){
1901 Report
.Error (540, "`" + full
+ "': containing class does not implement interface `" + interface_type
.FullName
+ "'");
1908 public static void Error_NotInterfaceMember (Location loc
, string member_name
, string iface_name
)
1910 Report
.Error (30401, loc
, "'" + member_name
+ "' is not a member of the interface '" + iface_name
+ "'");
1917 string IMemberContainer
.Name
{
1923 Type IMemberContainer
.Type
{
1929 IMemberContainer IMemberContainer
.Parent
{
1931 return parent_container
;
1935 MemberCache IMemberContainer
.MemberCache
{
1937 return member_cache
;
1941 bool IMemberContainer
.IsInterface
{
1943 return this is Interface
;
1947 MemberList IMemberContainer
.GetMembers (MemberTypes mt
, BindingFlags bf
)
1949 return FindMembers (mt
, bf
| BindingFlags
.DeclaredOnly
, null, null);
1954 public class Class
: TypeContainer
{
1956 // Modifiers allowed in a class declaration
1958 public const int AllowedModifiers
=
1961 Modifiers
.PROTECTED
|
1962 Modifiers
.INTERNAL
|
1964 Modifiers
.ABSTRACT
|
1967 public Class (TypeContainer parent
, string name
, int mod
, Attributes attrs
, Location l
)
1968 : base (parent
, name
, attrs
, l
)
1972 if (parent
.Parent
== null)
1973 accmods
= Modifiers
.INTERNAL
;
1975 accmods
= Modifiers
.PUBLIC
;
1977 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, l
);
1980 public override AttributeTargets AttributeTargets
{
1982 return AttributeTargets
.Class
;
1987 // FIXME: How do we deal with the user specifying a different
1990 public override TypeAttributes TypeAttr
{
1992 return base.TypeAttr
| TypeAttributes
.AutoLayout
| TypeAttributes
.Class
;
1997 public class Struct
: TypeContainer
{
1999 // Modifiers allowed in a struct declaration
2001 public const int AllowedModifiers
=
2004 Modifiers
.PROTECTED
|
2005 Modifiers
.INTERNAL
|
2009 public Struct (TypeContainer parent
, string name
, int mod
, Attributes attrs
, Location l
)
2010 : base (parent
, name
, attrs
, l
)
2014 if (parent
.Parent
== null)
2015 accmods
= Modifiers
.INTERNAL
;
2017 accmods
= Modifiers
.PUBLIC
;
2019 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, l
);
2021 this.ModFlags
|= Modifiers
.SEALED
;
2024 public override AttributeTargets AttributeTargets
{
2026 return AttributeTargets
.Struct
;
2031 // FIXME: Allow the user to specify a different set of attributes
2032 // in some cases (Sealed for example is mandatory for a class,
2033 // but what SequentialLayout can be changed
2035 public override TypeAttributes TypeAttr
{
2037 return base.TypeAttr
|
2038 TypeAttributes
.SequentialLayout
|
2039 TypeAttributes
.Sealed
|
2040 TypeAttributes
.BeforeFieldInit
;
2045 public abstract class MethodCore
: MemberBase
{
2046 public /* readonly */ Parameters Parameters
;
2050 // Parameters, cached for semantic analysis.
2052 protected InternalParameters parameter_info
;
2053 protected Type
[] parameter_types
;
2055 // Whether this is an operator
2056 public bool IsOperator
;
2058 public MethodCore (Expression type
, int mod
, int allowed_mod
, string name
,
2059 Attributes attrs
, Parameters parameters
, Location loc
)
2060 : base (type
, mod
, allowed_mod
, name
, attrs
, loc
)
2062 Parameters
= parameters
;
2066 // Returns the System.Type array for the parameters of this method
2068 public Type
[] ParameterTypes
{
2070 return parameter_types
;
2074 public InternalParameters ParameterInfo
2077 return parameter_info
;
2081 public Block Block
{
2091 protected virtual bool DoDefineParameters (TypeContainer parent
)
2093 // Check if arguments were correct
2094 parameter_types
= Parameters
.GetParameterInfo (parent
);
2095 if ((parameter_types
== null) || !CheckParameters (parent
, parameter_types
))
2098 parameter_info
= new InternalParameters (parent
, Parameters
);
2103 public CallingConventions
GetCallingConvention (bool is_class
)
2105 CallingConventions cc
= 0;
2107 cc
= Parameters
.GetCallingConvention ();
2110 if ((ModFlags
& Modifiers
.STATIC
) == 0)
2111 cc
|= CallingConventions
.HasThis
;
2113 // FIXME: How is `ExplicitThis' used in C#?
2118 public void LabelParameters (EmitContext ec
, Type
[] parameters
, MethodBase builder
)
2120 LabelParameters (ec
, parameters
, builder
, null);
2123 public void LabelParameters (EmitContext ec
, Type
[] parameters
, MethodBase builder
, Parameters p_params
)
2126 // Define each type attribute (in/out/ref) and
2127 // the argument names.
2129 Parameter
[] p
= p_params
== null ? Parameters
.FixedParameters
: p_params
.FixedParameters
;
2132 MethodBuilder mb
= null;
2133 ConstructorBuilder cb
= null;
2135 if (builder
is MethodBuilder
)
2136 mb
= (MethodBuilder
) builder
;
2138 cb
= (ConstructorBuilder
) builder
;
2141 for (i
= 0; i
< p
.Length
; i
++) {
2142 ParameterBuilder pb
;
2145 pb
= cb
.DefineParameter (
2146 i
+ 1, p
[i
].Attributes
, p
[i
].Name
);
2148 pb
= mb
.DefineParameter (
2149 i
+ 1, p
[i
].Attributes
, p
[i
].Name
);
2151 if (p
[i
].ParameterInitializer
!= null) {
2152 if (p
[i
].ParameterInitializer
is MemberAccess
) {
2153 MemberAccess ma
= p
[i
].ParameterInitializer
as MemberAccess
;
2155 Expression const_ex
= ma
.Resolve(ec
);
2156 if (const_ex
is EnumConstant
)
2157 pb
.SetConstant (((EnumConstant
) const_ex
).Child
.GetValue());
2160 "Internal error - Non supported argument type in optional parameter");
2163 pb
.SetConstant (((Constant
) p
[i
].ParameterInitializer
).GetValue());
2166 Attributes attr
= p
[i
].OptAttributes
;
2168 Attribute
.ApplyAttributes (ec
, pb
, pb
, attr
, Location
);
2172 if (Parameters
.ArrayParameter
!= null){
2173 ParameterBuilder pb
;
2174 Parameter array_param
= Parameters
.ArrayParameter
;
2177 pb
= cb
.DefineParameter (
2178 i
+ 1, array_param
.Attributes
,
2181 pb
= mb
.DefineParameter (
2182 i
+ 1, array_param
.Attributes
,
2185 CustomAttributeBuilder a
= new CustomAttributeBuilder (
2186 TypeManager
.cons_param_array_attribute
, new object [0]);
2188 pb
.SetCustomAttribute (a
);
2193 public class Method
: MethodCore
{
2194 public MethodBuilder MethodBuilder
;
2195 public MethodData MethodData
;
2198 /// Modifiers allowed in a class declaration
2200 const int AllowedModifiers
=
2203 Modifiers
.PROTECTED
|
2204 Modifiers
.INTERNAL
|
2208 Modifiers
.NONVIRTUAL
|
2209 Modifiers
.OVERRIDE
|
2210 Modifiers
.ABSTRACT
|
2216 // return_type can be "null" for VOID values.
2218 public Method (Expression return_type
, int mod
, string name
, Parameters parameters
,
2219 Attributes attrs
, Location l
)
2220 : base (return_type
, mod
, AllowedModifiers
, name
, attrs
, parameters
, l
)
2225 public Method (Expression return_type
, int mod
, string name
, Parameters parameters
,
2226 Attributes attrs
, ArrayList impl_what
, Location l
)
2227 : base (return_type
, mod
, AllowedModifiers
, name
, attrs
, parameters
, l
)
2229 Implements
= impl_what
;
2232 public override AttributeTargets AttributeTargets
{
2234 return AttributeTargets
.Method
;
2239 // Returns the `System.Type' for the ReturnType of this
2240 // function. Provides a nice cache. (used between semantic analysis
2241 // and actual code generation
2243 public Type
GetReturnType ()
2248 void DuplicateEntryPoint (MethodInfo b
, Location location
)
2252 "Program `" + CodeGen
.FileName
+
2253 "' has more than one entry point defined: `" +
2254 TypeManager
.MonoBASIC_Signature(b
) + "'");
2257 void Report28 (MethodInfo b
)
2259 if (RootContext
.WarningLevel
< 4)
2264 "`" + TypeManager
.MonoBASIC_Signature(b
) +
2265 "' has the wrong signature to be an entry point");
2268 public bool IsEntryPoint (MethodBuilder b
, InternalParameters pinfo
)
2270 if (b
.ReturnType
!= TypeManager
.void_type
&&
2271 b
.ReturnType
!= TypeManager
.int32_type
)
2274 if (pinfo
.Count
== 0)
2277 if (pinfo
.Count
> 1)
2280 Type t
= pinfo
.ParameterType(0);
2282 (t
.GetArrayRank() == 1) &&
2283 (t
.GetElementType() == TypeManager
.string_type
) &&
2284 (pinfo
.ParameterModifier(0) == Parameter
.Modifier
.NONE
))
2291 // Checks our base implementation if any
2293 protected override bool CheckBase (TypeContainer parent
)
2295 // Check whether arguments were correct.
2296 if (!DoDefineParameters (parent
))
2299 MethodSignature ms
= new MethodSignature (Name
, null, ParameterTypes
);
2303 mi_this
= TypeContainer
.FindMembers (
2304 parent
.TypeBuilder
, MemberTypes
.Method
,
2305 BindingFlags
.NonPublic
| BindingFlags
.Public
|
2306 BindingFlags
.Static
| BindingFlags
.Instance
|
2307 BindingFlags
.DeclaredOnly
,
2308 MethodSignature
.method_signature_filter
, ms
);
2310 if (mi_this
.Count
> 0) {
2311 Report
.Error (111, Location
, "Class `" + parent
.Name
+ "' " +
2312 "already defines a member called `" + Name
+ "' " +
2313 "with the same parameter types");
2319 // Verify if the parent has a type with the same name, and then
2320 // check whether we have to create a new slot for it or not.
2322 Type ptype
= parent
.TypeBuilder
.BaseType
;
2324 // ptype is only null for System.Object while compiling corlib.
2326 MemberList mi
, mi_static
, mi_instance
;
2328 mi_static
= TypeContainer
.FindMembers (
2329 ptype
, MemberTypes
.Method
,
2330 BindingFlags
.NonPublic
| BindingFlags
.Public
| BindingFlags
.Static
,
2331 MethodSignature
.inheritable_method_signature_filter
, ms
);
2333 mi_instance
= TypeContainer
.FindMembers (
2334 ptype
, MemberTypes
.Method
,
2335 BindingFlags
.NonPublic
| BindingFlags
.Public
| BindingFlags
.Instance
,
2336 MethodSignature
.inheritable_method_signature_filter
,
2339 if (mi_instance
.Count
> 0){
2341 } else if (mi_static
.Count
> 0)
2346 if (mi
!= null && mi
.Count
> 0){
2347 parent_method
= (MethodInfo
) mi
[0];
2348 string name
= parent_method
.DeclaringType
.Name
+ "." +
2351 if (!CheckMethodAgainstBase (parent
, flags
, parent_method
, name
))
2354 if ((ModFlags
& Modifiers
.NEW
) == 0) {
2355 Type parent_ret
= TypeManager
.TypeToCoreType (
2356 parent_method
.ReturnType
);
2358 if (parent_ret
!= MemberType
) {
2360 508, parent
.MakeName (Name
) + ": cannot " +
2361 "change return type when overriding " +
2362 "inherited member " + name
);
2367 /*if ((ModFlags & Modifiers.NEW) != 0)
2368 WarningNotHiding (parent);*/
2370 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0){
2371 Report
.Error (30284, Location
,
2372 parent
.MakeName (Name
) +
2373 " : No suitable methods found to override");
2375 if ((ModFlags
& ( Modifiers
.NEW
| Modifiers
.SHADOWS
| Modifiers
.OVERRIDE
)) == 0)
2377 if ((ModFlags
& Modifiers
.NONVIRTUAL
) != 0)
2379 Report
.Error (31088, Location
,
2380 parent
.MakeName (Name
) + " : Cannot " +
2381 "be declared NotOverridable since this method is " +
2382 "not maked as Overrides");
2385 // if a member of module is not inherited from Object class
2386 // can not be declared protected
2387 if ((parent
is Module
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
2388 Report
.Error (31066, Location
,
2389 "'Sub' or 'Function' inside a 'Module' can not be declared as " +
2390 "'Protected' or 'Protected Friend'");
2393 /* else if ((ModFlags & Modifiers.NEW) != 0)
2394 WarningNotHiding (parent);
2403 public override bool Define (TypeContainer parent
)
2405 if (!DoDefine (parent
))
2408 if (!CheckBase (parent
))
2411 if ((parent
is Struct
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
2412 Report
.Error (31067, Location
,
2413 "'Sub' or 'Function' inside a 'Structure' can not be declared as " +
2414 "'Protected' or 'Protected Friend'");
2416 CallingConventions cc
= GetCallingConvention (parent
is Class
);
2418 MethodData
= new MethodData (this, null, MemberType
, ParameterTypes
,
2419 ParameterInfo
, cc
, OptAttributes
,
2420 ModFlags
, flags
, true);
2422 if (!MethodData
.Define (parent
))
2425 MethodBuilder
= MethodData
.MethodBuilder
;
2428 // This is used to track the Entry Point,
2430 if (Name
.ToUpper() == "MAIN" &&
2431 ((ModFlags
& Modifiers
.STATIC
) != 0) &&
2432 (RootContext
.MainClass
== null ||
2433 RootContext
.MainClass
== parent
.TypeBuilder
.FullName
||
2434 (RootContext
.RootNamespace
!= null &&
2435 RootContext
.RootNamespace
.Length
> 0 &&
2436 (RootContext
.RootNamespace
+ "." + RootContext
.MainClass
) == parent
.TypeBuilder
.FullName
))) {
2437 if (IsEntryPoint (MethodBuilder
, ParameterInfo
)) {
2438 if (RootContext
.EntryPoint
== null) {
2439 RootContext
.EntryPoint
= MethodBuilder
;
2440 RootContext
.EntryPointLocation
= Location
;
2442 DuplicateEntryPoint (RootContext
.EntryPoint
, RootContext
.EntryPointLocation
);
2443 DuplicateEntryPoint (MethodBuilder
, Location
);
2446 Report28(MethodBuilder
);
2455 public void Emit (TypeContainer parent
)
2457 MethodData
.Emit (parent
, Block
, this);
2461 public abstract class ConstructorInitializer
{
2462 ArrayList argument_list
;
2463 ConstructorInfo parent_constructor
;
2464 Parameters parameters
;
2466 public bool implicit_initialization
;
2468 public ConstructorInitializer (ArrayList argument_list
, Parameters parameters
,
2471 this.argument_list
= argument_list
;
2472 this.parameters
= parameters
;
2474 this.implicit_initialization
= false;
2477 public ArrayList Arguments
{
2479 return argument_list
;
2483 public ConstructorInfo ParentConstructor
2487 return parent_constructor
;
2491 public bool Resolve (EmitContext ec
)
2493 Expression parent_constructor_group
;
2496 ec
.CurrentBlock
= new Block (null, true, parameters
);
2498 if (argument_list
!= null){
2499 foreach (Argument a
in argument_list
){
2500 if (!a
.Resolve (ec
, loc
))
2505 ec
.CurrentBlock
= null;
2507 if (this is ConstructorBaseInitializer
) {
2508 if (ec
.ContainerType
.BaseType
== null)
2511 t
= ec
.ContainerType
.BaseType
;
2512 if (ec
.ContainerType
.IsValueType
){
2513 Report
.Error (522, loc
,
2514 "structs cannot call base class constructors");
2519 t
= ec
.ContainerType
;
2521 parent_constructor_group
= Expression
.MemberLookup (
2523 MemberTypes
.Constructor
,
2524 BindingFlags
.Public
| BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
,
2527 if (parent_constructor_group
== null){
2528 Report
.Error (30455, loc
, "Class '" + t
+ "' can not find a constructor for this argument list" );
2532 parent_constructor
= (ConstructorInfo
) Invocation
.OverloadResolve (ec
,
2533 (MethodGroupExpr
) parent_constructor_group
, argument_list
, loc
);
2535 if (parent_constructor
== null) {
2536 if (this.implicit_initialization
)
2537 Report
.Error (30148, loc
, "Must declare 'MyBase.New' in the constructor " +
2538 "of the class '" + ec
.TypeContainer
.Name
+ "' with appropriate arguments, since the base class '" +
2539 t
.FullName
+ "' does not contain a definition of 'New' without any parameter");
2541 Report
.Error (30455, loc
, "Class '" + t
+ "' can not find a constructor for this argument list" );
2549 public void Emit (EmitContext ec
)
2551 if (parent_constructor
!= null){
2553 Invocation
.EmitCall (ec
, true, true, null, parent_constructor
, argument_list
, loc
);
2555 Invocation
.EmitCall (ec
, true, false, ec
.This
, parent_constructor
, argument_list
, loc
);
2562 public class ConstructorBaseInitializer
: ConstructorInitializer
{
2563 public ConstructorBaseInitializer (ArrayList argument_list
, Parameters pars
, Location l
) :
2564 base (argument_list
, pars
, l
)
2569 public class ConstructorThisInitializer
: ConstructorInitializer
{
2570 public ConstructorThisInitializer (ArrayList argument_list
, Parameters pars
, Location l
) :
2571 base (argument_list
, pars
, l
)
2576 public class Constructor
: MethodCore
{
2577 public ConstructorBuilder ConstructorBuilder
;
2578 public ConstructorInitializer Initializer
;
2581 // Modifiers allowed for a constructor.
2583 public const int AllowedModifiers
=
2585 Modifiers
.PROTECTED
|
2586 Modifiers
.INTERNAL
|
2593 // The spec claims that static is not permitted, but
2594 // my very own code has static constructors.
2596 public Constructor (string name
, Parameters args
, ConstructorInitializer init
, Location l
)
2597 : base (null, 0, AllowedModifiers
, name
, null, args
, l
)
2602 public Constructor (string name
, int mod
, Parameters args
, ConstructorInitializer init
, Location l
)
2603 : base (null, mod
, AllowedModifiers
, name
, null, args
, l
)
2608 public override AttributeTargets AttributeTargets
{
2610 return AttributeTargets
.Constructor
;
2615 // Returns true if this is a default constructor
2617 public bool IsDefault ()
2619 if ((ModFlags
& Modifiers
.STATIC
) != 0)
2620 return (Parameters
.FixedParameters
== null ? true : Parameters
.Empty
) &&
2621 (Parameters
.ArrayParameter
== null ? true : Parameters
.Empty
);
2624 return (Parameters
.FixedParameters
== null ? true : Parameters
.Empty
) &&
2625 (Parameters
.ArrayParameter
== null ? true : Parameters
.Empty
) &&
2626 (Initializer
is ConstructorBaseInitializer
) &&
2627 (Initializer
.Arguments
== null);
2631 // Creates the ConstructorBuilder
2633 public override bool Define (TypeContainer parent
)
2635 MethodAttributes ca
= (MethodAttributes
.RTSpecialName
|
2636 MethodAttributes
.SpecialName
);
2638 if (parent
.EventHandlers
!= null) {
2639 ArrayList hdlrs
= parent
.EventHandlers
;
2640 foreach(Statement stmt
in hdlrs
)
2641 this.Block
.AddStatement (stmt
);
2645 // Check if arguments were correct.
2646 if (!DoDefineParameters (parent
))
2649 if ((ModFlags
& Modifiers
.STATIC
) != 0) {
2650 ca
|= MethodAttributes
.Static
;
2652 if (this.Parameters
!= Parameters
.EmptyReadOnlyParameters
)
2655 "Shared constructor can not have parameters");
2657 if ((ModFlags
& Modifiers
.Accessibility
) != 0)
2660 "Shared constructor can not be declared " +
2661 "explicitly as public, private, friend or protected");
2663 if (this.Initializer
!= null)
2666 "Keywords like MyBase, MyClass, Me are not " +
2667 "valid inside a Shared Constructor");
2670 if (parent
is Struct
&& ParameterTypes
.Length
== 0) {
2673 "Structs can not contain explicit parameterless " +
2677 ca
|= MethodAttributes
.HideBySig
;
2679 if ((ModFlags
& Modifiers
.PUBLIC
) != 0)
2680 ca
|= MethodAttributes
.Public
;
2681 else if ((ModFlags
& Modifiers
.PROTECTED
) != 0) {
2682 if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
2683 ca
|= MethodAttributes
.FamORAssem
;
2685 ca
|= MethodAttributes
.Family
;
2687 else if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
2688 ca
|= MethodAttributes
.Assembly
;
2689 else if (IsDefault ())
2690 ca
|= MethodAttributes
.Public
;
2692 ca
|= MethodAttributes
.Private
;
2695 ConstructorBuilder
= parent
.TypeBuilder
.DefineConstructor (
2696 ca
, GetCallingConvention (parent
is Class
), ParameterTypes
);
2699 // HACK because System.Reflection.Emit is lame
2701 if (!TypeManager
.RegisterMethod (ConstructorBuilder
, ParameterInfo
, ParameterTypes
)) {
2704 "Class `" +parent
.Name
+ "' already contains a definition with the " +
2705 "same return value and parameter types for constructor `" + Name
2716 public void Emit (TypeContainer parent
)
2718 ILGenerator ig
= ConstructorBuilder
.GetILGenerator ();
2719 EmitContext ec
= new EmitContext (parent
, Location
, ig
, null, ModFlags
, true);
2721 if ((ModFlags
& Modifiers
.STATIC
) == 0){
2722 if (parent
is Class
&& Initializer
== null) {
2723 Initializer
= new ConstructorBaseInitializer (
2724 null, Parameters
.EmptyReadOnlyParameters
, parent
.Location
);
2725 Initializer
.implicit_initialization
= true;
2729 // Spec mandates that Initializers will not have
2733 if (Initializer
!= null && !Initializer
.Resolve (ec
))
2735 ec
.IsStatic
= false;
2738 LabelParameters (ec
, ParameterTypes
, ConstructorBuilder
);
2741 // Classes can have base initializers and instance field initializers.
2743 if (parent
is Class
){
2744 if ((ModFlags
& Modifiers
.STATIC
) == 0)
2745 parent
.EmitFieldInitializers (ec
);
2748 if (Initializer
!= null) {
2749 if (this.ConstructorBuilder
.Equals (Initializer
.ParentConstructor
))
2752 "A constructor can not call itself" );
2754 Initializer
.Emit (ec
);
2757 if ((ModFlags
& Modifiers
.STATIC
) != 0)
2758 parent
.EmitFieldInitializers (ec
);
2760 Attribute
.ApplyAttributes (ec
, ConstructorBuilder
, this, OptAttributes
, Location
);
2762 // If this is a non-static `struct' constructor and doesn't have any
2763 // initializer, it must initialize all of the struct's fields.
2764 if ((parent
is Struct
) && ((ModFlags
& Modifiers
.STATIC
) == 0) &&
2765 (Initializer
== null))
2766 Block
.AddThisVariable (parent
, Location
);
2768 ec
.EmitTopBlock (Block
, ParameterInfo
, Location
);
2772 public class MethodData
{
2774 // The return type of this method
2776 public readonly Type ReturnType
;
2777 public readonly Type
[] ParameterTypes
;
2778 public readonly InternalParameters ParameterInfo
;
2779 public readonly CallingConventions CallingConventions
;
2780 public readonly Attributes OptAttributes
;
2781 public readonly Location Location
;
2784 // Are we implementing an interface ?
2786 public bool IsImplementing
= false;
2791 protected MemberBase member
;
2792 protected int modifiers
;
2793 protected MethodAttributes flags
;
2794 protected bool is_method
;
2795 protected string accessor_name
;
2796 ArrayList conditionals
;
2798 MethodBuilder builder
= null;
2799 public MethodBuilder MethodBuilder
{
2805 public MethodData (MemberBase member
, string name
, Type return_type
,
2806 Type
[] parameter_types
, InternalParameters parameters
,
2807 CallingConventions cc
, Attributes opt_attrs
,
2808 int modifiers
, MethodAttributes flags
, bool is_method
)
2810 this.member
= member
;
2811 this.accessor_name
= name
;
2812 this.ReturnType
= return_type
;
2813 this.ParameterTypes
= parameter_types
;
2814 this.ParameterInfo
= parameters
;
2815 this.CallingConventions
= cc
;
2816 this.OptAttributes
= opt_attrs
;
2817 this.modifiers
= modifiers
;
2819 this.is_method
= is_method
;
2820 this.Location
= member
.Location
;
2821 this.conditionals
= new ArrayList ();
2827 Attribute dllimport_attribute
= null;
2828 string obsolete
= null;
2829 bool obsolete_error
= false;
2831 public virtual bool ApplyAttributes (Attributes opt_attrs
, bool is_method
)
2833 if ((opt_attrs
== null) || (opt_attrs
.Attrs
== null))
2836 foreach (Attribute a
in opt_attrs
.Attrs
) {
2837 if (a
.Name
== "Conditional") {
2838 if (!ApplyConditionalAttribute (a
))
2840 } else if (a
.Name
== "Obsolete") {
2841 if (!ApplyObsoleteAttribute (a
))
2843 } else if (a
.Name
.IndexOf ("DllImport") != -1) {
2845 a
.Type
= TypeManager
.dllimport_type
;
2846 Attribute
.Error_AttributeNotValidForElement (a
, Location
);
2849 if (!ApplyDllImportAttribute (a
))
2858 // Applies the `DllImport' attribute to the method.
2860 protected virtual bool ApplyDllImportAttribute (Attribute a
)
2862 const int extern_static
= Modifiers
.EXTERN
| Modifiers
.STATIC
;
2863 if ((modifiers
& extern_static
) != extern_static
) {
2864 Report
.Error (601, Location
,
2865 "The DllImport attribute must be specified on a method " +
2866 "marked `static' and `extern'.");
2870 flags
|= MethodAttributes
.PinvokeImpl
;
2871 dllimport_attribute
= a
;
2876 // Applies the `Obsolete' attribute to the method.
2878 protected virtual bool ApplyObsoleteAttribute (Attribute a
)
2880 if (obsolete
!= null) {
2881 Report
.Error (579, Location
, "Duplicate `Obsolete' attribute");
2885 obsolete
= a
.Obsolete_GetObsoleteMessage (out obsolete_error
);
2886 return obsolete
!= null;
2890 // Applies the `Conditional' attribute to the method.
2892 protected virtual bool ApplyConditionalAttribute (Attribute a
)
2894 // The Conditional attribute is only valid on methods.
2896 Attribute
.Error_AttributeNotValidForElement (a
, Location
);
2900 string condition
= a
.Conditional_GetConditionName ();
2902 if (condition
== null)
2905 if (ReturnType
!= TypeManager
.void_type
) {
2906 Report
.Error (578, Location
,
2907 "Conditional not valid on `" + member
.Name
+ "' " +
2908 "because its return type is not void");
2912 if ((modifiers
& Modifiers
.OVERRIDE
) != 0) {
2913 Report
.Error (243, Location
,
2914 "Conditional not valid on `" + member
.Name
+ "' " +
2915 "because it is an override method");
2919 if (member
.IsExplicitImpl
) {
2920 Report
.Error (577, Location
,
2921 "Conditional not valid on `" + member
.Name
+ "' " +
2922 "because it is an explicit interface implementation");
2926 if (IsImplementing
) {
2927 Report
.Error (623, Location
,
2928 "Conditional not valid on `" + member
.Name
+ "' " +
2929 "because it is an interface method");
2933 conditionals
.Add (condition
);
2939 // Checks whether this method should be ignored due to its Conditional attributes.
2941 bool ShouldIgnore (Location loc
)
2943 // When we're overriding a virtual method, we implicitly inherit the
2944 // Conditional attributes from our parent.
2945 if (member
.ParentMethod
!= null) {
2946 TypeManager
.MethodFlags flags
= TypeManager
.GetMethodFlags (
2947 member
.ParentMethod
, loc
);
2949 if ((flags
& TypeManager
.MethodFlags
.ShouldIgnore
) != 0)
2953 foreach (string condition
in conditionals
)
2954 if (RootContext
.AllDefines
[condition
] == null)
2961 // Returns the TypeManager.MethodFlags for this method.
2962 // This emits an error 619 / warning 618 if the method is obsolete.
2963 // In the former case, TypeManager.MethodFlags.IsObsoleteError is returned.
2965 public virtual TypeManager
.MethodFlags
GetMethodFlags (Location loc
)
2967 TypeManager
.MethodFlags flags
= 0;
2969 if (obsolete
!= null) {
2970 if (obsolete_error
) {
2971 Report
.Error (619, loc
, "Method `" + member
.Name
+
2972 "' is obsolete: `" + obsolete
+ "'");
2973 return TypeManager
.MethodFlags
.IsObsoleteError
;
2975 Report
.Warning (618, loc
, "Method `" + member
.Name
+
2976 "' is obsolete: `" + obsolete
+ "'");
2978 flags
|= TypeManager
.MethodFlags
.IsObsolete
;
2981 if (ShouldIgnore (loc
))
2982 flags
|= TypeManager
.MethodFlags
.ShouldIgnore
;
2988 // Search all the interface bases recursively for unimplemented methods
2990 bool SearchBasesForAbstractMethods (
2991 TypeContainer parent
, Type iface_type
,
2992 string method_name
, ref ArrayList implementing_list
,
2993 ref ArrayList implementing_iface
)
2995 MethodInfo implementing
= null;
2996 bool IsImplementing
= false;
2997 Type current_iface_type
= iface_type
;
3000 if (member is Indexer)
3001 implementing = parent.Pending.IsAbstractIndexer (
3002 current_iface_type , ReturnType, ParameterTypes);
3005 implementing
= parent
.Pending
.IsAbstractMethod (
3006 current_iface_type
, method_name
, ReturnType
, ParameterTypes
);
3008 if (implementing
!= null) {
3009 if (!implementing_list
.Contains (implementing
)) {
3010 implementing_list
.Add (implementing
);
3011 implementing_iface
.Add(current_iface_type
);
3013 IsImplementing
= true;
3015 Type
[] current_iface_types
= current_iface_type
.GetInterfaces();
3016 if (current_iface_types
.Length
== 0)
3019 foreach (Type curr_iface_type
in current_iface_types
) {
3020 IsImplementing
= SearchBasesForAbstractMethods (
3021 parent
, curr_iface_type
, method_name
,
3022 ref implementing_list
, ref implementing_iface
);
3029 return IsImplementing
;
3032 public virtual bool Define (TypeContainer parent
)
3034 MethodInfo implementing
= null;
3035 ArrayList implementing_list
= null;
3036 ArrayList implementing_iface
= null;
3037 string method_name
, name
, prefix
, impl_method_name
;
3040 if (OptAttributes
!= null)
3041 if (!ApplyAttributes (OptAttributes
, is_method
))
3044 if (accessor_name
!= null)
3045 name
= accessor_name
+ "_" + member
.ShortName
;
3047 name
= member
.ShortName
;
3050 impl_method_name
= name
;
3052 if ((member
.ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3053 if (parent
.Pending
== null)
3054 implementing
= null;
3056 else if (member is Indexer)
3057 implementing = parent.Pending.IsAbstractIndexer (
3058 (Type) parent.TypeBuilder.BaseType,
3059 ReturnType, ParameterTypes);
3062 implementing
= parent
.Pending
.IsAbstractMethod (
3063 (Type
) parent
.TypeBuilder
.BaseType
, name
,
3064 ReturnType
, ParameterTypes
);
3066 if (implementing
!= null)
3067 IsImplementing
= true;
3070 if (member
.Implements
!= null) {
3071 implementing_list
= new ArrayList();
3072 implementing_iface
= new ArrayList();
3074 foreach (Expression Impl
in member
.Implements
) {
3075 name
= Impl
.ToString();
3076 prefix
= name
.Substring(0, name
.LastIndexOf("."));
3077 name
= name
.Substring(name
.LastIndexOf(".") + 1);
3079 if (accessor_name
!= null)
3080 impl_method_name
= accessor_name
+ "_" + name
;
3082 impl_method_name
= name
;
3084 Type current_iface_type
= (Type
) member
.InterfaceTypes
[++pos
];
3085 IsImplementing
= SearchBasesForAbstractMethods (
3086 parent
, current_iface_type
, impl_method_name
,
3087 ref implementing_list
, ref implementing_iface
);
3089 if (IsImplementing
== false) {
3090 TypeContainer
.Error_NotInterfaceMember (
3091 Location
, name
, prefix
);
3098 // For implicit implementations, make sure we are public, for
3099 // explicit implementations, make sure we are private.
3101 //if (IsImplementing){
3103 // Setting null inside this block will trigger a more
3104 // verbose error reporting for missing interface implementations
3106 // The "candidate" function has been flagged already
3107 // but it wont get cleared
3109 /* if (!member.IsExplicitImpl){
3111 // We already catch different accessibility settings
3112 // so we just need to check that we are not private
3114 if ((modifiers & Modifiers.PRIVATE) != 0)
3115 implementing = null;
3118 // Static is not allowed
3120 if ((modifiers & Modifiers.STATIC) != 0)
3121 implementing = null;
3123 if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
3124 Modifiers.Error_InvalidModifier (Location, "public, virtual or abstract");
3125 implementing = null;
3131 // If implementing is still valid, set flags
3133 if (IsImplementing
){
3135 // When implementing interface methods, set NewSlot.
3137 if (implementing_list
!= null && implementing_list
.Count
!= 0)
3138 flags
|= MethodAttributes
.NewSlot
;
3141 MethodAttributes
.Virtual
|
3142 MethodAttributes
.HideBySig
;
3146 // Create the MethodBuilder for the method
3148 if ((flags
& MethodAttributes
.PinvokeImpl
) != 0) {
3149 if ((modifiers
& Modifiers
.STATIC
) == 0) {
3150 Report
.Error (601, Location
,
3151 "The DllImport attribute must be specified on " +
3152 "a method marked 'static' and 'extern'.");
3156 EmitContext ec
= new EmitContext (
3157 parent
, Location
, null, ReturnType
, modifiers
);
3159 builder
= dllimport_attribute
.DefinePInvokeMethod (
3160 ec
, parent
.TypeBuilder
, method_name
, flags
,
3161 ReturnType
, ParameterTypes
);
3163 builder
= parent
.TypeBuilder
.DefineMethod (
3164 method_name
, flags
, CallingConventions
,
3165 ReturnType
, ParameterTypes
);
3167 if (builder
== null)
3170 if (IsImplementing
) {
3172 // implement abstract methods from abstract classes
3174 if ((member
.ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3176 if (member is Indexer)
3177 parent.Pending.ImplementIndexer (
3178 (Type) parent.TypeBuilder.BaseType,
3179 builder, ReturnType,
3180 ParameterTypes, true);
3183 parent
.Pending
.ImplementMethod (
3184 (Type
) parent
.TypeBuilder
.BaseType
,
3186 ParameterTypes
, member
.IsExplicitImpl
);
3190 // implement abstract methods of interfaces
3192 if (member
.Implements
!= null) {
3194 foreach (MethodInfo Impl
in implementing_list
) {
3197 if (member is Indexer)
3198 parent.Pending.ImplementIndexer (
3199 (Type) implementing_iface[pos++],
3200 builder, ReturnType,
3201 ParameterTypes, true);
3204 parent
.Pending
.ImplementMethod (
3205 (Type
) implementing_iface
[pos
++],
3206 Impl
.Name
, ReturnType
,
3207 ParameterTypes
, member
.IsExplicitImpl
);
3209 parent
.TypeBuilder
.DefineMethodOverride (
3216 if (!TypeManager
.RegisterMethod (builder
, ParameterInfo
, ParameterTypes
)) {
3217 Report
.Error (111, Location
,
3218 "Class `" + parent
.Name
+
3219 "' already contains a definition with the " +
3220 "same return value and parameter types as the " +
3221 "'get' method of property `" + member
.Name
+ "'");
3225 TypeManager
.AddMethod (builder
, this);
3232 public virtual void Emit (TypeContainer parent
, Block block
, object kind
)
3237 if ((flags
& MethodAttributes
.PinvokeImpl
) == 0)
3238 ig
= builder
.GetILGenerator ();
3242 ec
= new EmitContext (parent
, Location
, ig
, ReturnType
, modifiers
);
3244 if (OptAttributes
!= null)
3245 Attribute
.ApplyAttributes (ec
, builder
, kind
, OptAttributes
, Location
);
3247 if (member
is MethodCore
)
3248 ((MethodCore
) member
).LabelParameters (ec
, ParameterTypes
, MethodBuilder
);
3251 // abstract or extern methods have no bodies
3253 if ((modifiers
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) != 0){
3258 // abstract or extern methods have no bodies.
3260 if ((modifiers
& Modifiers
.ABSTRACT
) != 0)
3262 500, Location
, "Abstract method `" +
3263 TypeManager
.MonoBASIC_Signature (builder
) +
3264 "' can not have a body");
3266 if ((modifiers
& Modifiers
.EXTERN
) != 0)
3268 179, Location
, "External method `" +
3269 TypeManager
.MonoBASIC_Signature (builder
) +
3270 "' can not have a body");
3276 // Methods must have a body unless they're extern or abstract
3278 if (block
== null) {
3280 501, Location
, "Method `" +
3281 TypeManager
.MonoBASIC_Signature (builder
) +
3282 "' must declare a body since it is not marked " +
3283 "abstract or extern");
3288 // Handle destructors specially
3290 // FIXME: This code generates buggy code
3292 if (member
.Name
== "Finalize" && ReturnType
== TypeManager
.void_type
)
3293 EmitDestructor (ec
, block
);
3295 ISymbolWriter sw
= CodeGen
.SymbolWriter
;
3297 if ((sw
!= null) && !Location
.IsNull (Location
) &&
3298 !Location
.IsNull (block
.EndLocation
)) {
3299 Location end
= block
.EndLocation
;
3300 MethodToken token
= MethodBuilder
.GetToken ();
3301 sw
.OpenMethod (new SymbolToken (token
.Token
));
3302 // Avoid error if we don't support debugging for the platform
3304 sw
.SetMethodSourceRange (Location
.SymbolDocument
,
3308 } catch (Exception
) {
3311 ec
.EmitTopBlock (block
, member
.Name
, ParameterInfo
, Location
);
3315 ec
.EmitTopBlock (block
, member
.Name
, ParameterInfo
, Location
);
3319 void EmitDestructor (EmitContext ec
, Block block
)
3321 ILGenerator ig
= ec
.ig
;
3323 Label finish
= ig
.DefineLabel ();
3324 bool old_in_try
= ec
.InTry
;
3326 ig
.BeginExceptionBlock ();
3328 ec
.ReturnLabel
= finish
;
3329 ec
.HasReturnLabel
= true;
3330 ec
.EmitTopBlock (block
, null, Location
);
3331 ec
.InTry
= old_in_try
;
3333 // ig.MarkLabel (finish);
3334 bool old_in_finally
= ec
.InFinally
;
3335 ec
.InFinally
= true;
3336 ig
.BeginFinallyBlock ();
3338 if (ec
.ContainerType
.BaseType
!= null) {
3339 Expression member_lookup
= Expression
.MemberLookup (
3340 ec
, ec
.ContainerType
.BaseType
, ec
.ContainerType
.BaseType
, "Finalize",
3341 MemberTypes
.Method
, Expression
.AllBindingFlags
, Location
);
3343 if (member_lookup
!= null){
3344 MethodGroupExpr parent_destructor
= ((MethodGroupExpr
) member_lookup
);
3346 ig
.Emit (OpCodes
.Ldarg_0
);
3347 ig
.Emit (OpCodes
.Call
, (MethodInfo
) parent_destructor
.Methods
[0]);
3350 ec
.InFinally
= old_in_finally
;
3352 ig
.EndExceptionBlock ();
3353 //ig.MarkLabel (ec.ReturnLabel);
3354 ig
.Emit (OpCodes
.Ret
);
3358 abstract public class MemberBase
: MemberCore
{
3359 public Expression Type
;
3360 public ArrayList Implements
;
3362 protected MethodAttributes flags
;
3365 // The "short" name of this property / indexer / event. This is the
3366 // name without the explicit interface.
3368 public string ShortName
;
3371 // The type of this property / indexer / event
3373 public Type MemberType
;
3376 // If true, this is an explicit interface implementation
3378 public bool IsExplicitImpl
= false;
3381 // The name of the interface we are explicitly implementing
3383 public string ExplicitInterfaceName
= null;
3386 // If true, the interface type we are explicitly implementing
3388 public Type InterfaceType
= null;
3389 public ArrayList InterfaceTypes
= null;
3392 // The method we're overriding if this is an override method.
3394 protected MethodInfo parent_method
= null;
3395 public MethodInfo ParentMethod
{
3397 return parent_method
;
3402 // The constructor is only exposed to our children
3404 protected MemberBase (Expression type
, int mod
, int allowed_mod
, string name
,
3405 Attributes attrs
, Location loc
)
3406 : base (name
, attrs
, loc
)
3409 ModFlags
= Modifiers
.Check (allowed_mod
, mod
, Modifiers
.PUBLIC
, loc
);
3412 protected virtual bool CheckBase (TypeContainer parent
)
3417 protected virtual bool CheckParameters (TypeContainer parent
, Type
[] parameters
)
3421 foreach (Type partype
in parameters
){
3422 if (partype
.IsPointer
&& !UnsafeOK (parent
))
3425 if (parent
.AsAccessible (partype
, ModFlags
))
3429 if (this is Indexer)
3430 Report.Error (55, Location,
3431 "Inconsistent accessibility: parameter type `" +
3432 TypeManager.MonoBASIC_Name (partype) + "' is less " +
3433 "accessible than indexer `" + Name + "'");
3436 Report
.Error (51, Location
,
3437 "Inconsistent accessibility: parameter type `" +
3438 TypeManager
.MonoBASIC_Name (partype
) + "' is less " +
3439 "accessible than method `" + Name
+ "'");
3446 protected virtual bool DoDefine (TypeContainer parent
)
3451 if (!parent
.MethodModifiersValid (ModFlags
, Name
, Location
))
3454 flags
= Modifiers
.MethodAttr (ModFlags
);
3456 // Lookup Type, verify validity
3457 MemberType
= parent
.ResolveType (Type
, false, Location
);
3458 if (MemberType
== null)
3461 // check for whether the Interface is implemented by the class
3462 if (Implements
!= null) {
3463 InterfaceTypes
= new ArrayList ();
3464 foreach (Expression Impls
in Implements
) {
3465 string iname
= Impls
.ToString();
3466 iname
= iname
.Substring(0, iname
.LastIndexOf("."));
3467 bool iface_found
= false;
3469 InterfaceType
= RootContext
.LookupType (
3470 parent
, iname
, false, Location
);
3471 if (InterfaceType
== null)
3474 InterfaceTypes
.Add (InterfaceType
);
3475 Type
[] tbases
= parent
.TypeBuilder
.GetInterfaces();
3477 if (tbases
.Length
!= 0) {
3478 ArrayList bases
= new ArrayList();
3479 TypeManager
.ExpandAllInterfaces (tbases
, ref bases
);
3481 foreach (Type tbase
in bases
) {
3482 string bname
= tbase
.Name
;
3483 if (bname
.LastIndexOf(".") != -1)
3484 bname
= bname
.Substring(bname
.LastIndexOf("."));
3486 if (bname
== iname
) {
3494 Report
.Error (31035, Location
,
3495 "Class '" + parent
.Name
+ "' doesn't implement interface '" + iname
+ "'");
3501 // verify accessibility
3502 if (!parent
.AsAccessible (MemberType
, ModFlags
)) {
3503 if (this is Property
)
3504 Report
.Error (53, Location
,
3505 "Inconsistent accessibility: property type `" +
3506 TypeManager
.MonoBASIC_Name (MemberType
) + "' is less " +
3507 "accessible than property `" + Name
+ "'");
3509 else if (this is Indexer)
3510 Report.Error (54, Location,
3511 "Inconsistent accessibility: indexer return type `" +
3512 TypeManager.MonoBASIC_Name (MemberType) + "' is less " +
3513 "accessible than indexer `" + Name + "'");
3515 else if (this is Method
)
3516 Report
.Error (50, Location
,
3517 "Inconsistent accessibility: return type `" +
3518 TypeManager
.MonoBASIC_Name (MemberType
) + "' is less " +
3519 "accessible than method `" + Name
+ "'");
3521 Report
.Error (52, Location
,
3522 "Inconsistent accessibility: field type `" +
3523 TypeManager
.MonoBASIC_Name (MemberType
) + "' is less " +
3524 "accessible than field `" + Name
+ "'");
3528 if (MemberType
.IsPointer
&& !UnsafeOK (parent
))
3532 // Check for explicit interface implementation
3534 if ((ExplicitInterfaceName
== null) && (Name
.IndexOf (".") != -1)) {
3535 int pos
= Name
.LastIndexOf (".");
3537 ExplicitInterfaceName
= Name
.Substring (0, pos
);
3538 ShortName
= Name
.Substring (pos
+ 1);
3547 // Fields and Events both generate FieldBuilders, we use this to share
3548 // their common bits. This is also used to flag usage of the field
3550 abstract public class FieldBase
: MemberBase
{
3551 public FieldBuilder FieldBuilder
;
3552 public Status status
;
3555 public enum Status
: byte { ASSIGNED = 1, USED = 2 }
3558 // The constructor is only exposed to our children
3560 protected FieldBase (Expression type
, int mod
, int allowed_mod
, string name
,
3561 object init
, Attributes attrs
, Location loc
)
3562 : base (type
, mod
, allowed_mod
, name
, attrs
, loc
)
3567 public override AttributeTargets AttributeTargets
{
3569 return AttributeTargets
.Field
;
3575 // Whether this field has an initializer.
3577 public bool HasInitializer
{
3579 return init
!= null;
3584 readonly Object init
;
3585 Expression init_expr
;
3586 bool init_expr_initialized
= false;
3589 // Resolves and returns the field initializer.
3591 public Expression
GetInitializerExpression (EmitContext ec
)
3593 if (init_expr_initialized
)
3597 if (init
is Expression
)
3598 e
= (Expression
) init
;
3600 e
= new ArrayCreation (Type
, "", (ArrayList
)init
, Location
);
3602 ec
.IsFieldInitializer
= true;
3603 e
= e
.DoResolve (ec
);
3604 ec
.IsFieldInitializer
= false;
3607 init_expr_initialized
= true;
3615 // The Field class is used to represents class/struct fields during parsing.
3617 public class Field
: FieldBase
{
3619 // Modifiers allowed in a class declaration
3621 const int AllowedModifiers
=
3624 Modifiers
.PROTECTED
|
3625 Modifiers
.INTERNAL
|
3628 // Modifiers.VOLATILE |
3629 // Modifiers.UNSAFE |
3632 public Field (Expression type
, int mod
, string name
, Object expr_or_array_init
,
3633 Attributes attrs
, Location loc
)
3634 : base (type
, mod
, AllowedModifiers
, name
, expr_or_array_init
, attrs
, loc
)
3638 public override AttributeTargets AttributeTargets
{
3640 return AttributeTargets
.Field
;
3644 public override bool Define (TypeContainer parent
)
3646 Type t
= parent
.ResolveType (Type
, false, Location
);
3651 if (!parent
.AsAccessible (t
, ModFlags
)) {
3652 Report
.Error (52, Location
,
3653 "Inconsistent accessibility: field type `" +
3654 TypeManager
.MonoBASIC_Name (t
) + "' is less " +
3655 "accessible than field `" + Name
+ "'");
3659 if (t
.IsPointer
&& !UnsafeOK (parent
))
3662 Type ptype
= parent
.TypeBuilder
.BaseType
;
3664 // ptype is only null for System.Object while compiling corlib.
3666 MemberList list
= TypeContainer
.FindMembers (
3667 ptype
, MemberTypes
.Field
,
3668 BindingFlags
.Public
|
3669 BindingFlags
.Static
| BindingFlags
.Instance
,
3670 System
.Type
.FilterName
, Name
);
3672 if (RootContext
.WarningLevel
> 1){
3673 if ((list
.Count
> 0) && ((ModFlags
& Modifiers
.SHADOWS
) == 0))
3677 "Variable '" + Name
+ "' should be declared " +
3678 "Shadows since the base type '" + ptype
.Name
+
3679 "' has a variable with same name");
3681 ModFlags
|= Modifiers
.SHADOWS
;
3684 if (list
.Count
== 0)
3685 // if a member of module is not inherited from Object class
3686 // can not be declared protected
3687 if ((parent
is Module
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
3688 Report
.Error (30593, Location
,
3689 "'Variable' inside a 'Module' can not be " +
3690 "declared as 'Protected'");
3693 if ((parent
is Struct
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
3694 Report
.Error (30435, Location
,
3695 "'Variable' inside a 'Structure' can not be " +
3696 "declared as 'Protected'");
3698 if ((ModFlags
& Modifiers
.VOLATILE
) != 0){
3700 if (TypeManager
.IsEnumType (t
))
3701 t
= TypeManager
.EnumToUnderlying (t
);
3703 if (!((t
== TypeManager
.bool_type
) ||
3704 (t
== TypeManager
.sbyte_type
) ||
3705 (t
== TypeManager
.byte_type
) ||
3706 (t
== TypeManager
.short_type
) ||
3707 (t
== TypeManager
.ushort_type
) ||
3708 (t
== TypeManager
.int32_type
) ||
3709 (t
== TypeManager
.uint32_type
) ||
3710 (t
== TypeManager
.char_type
) ||
3711 (t
== TypeManager
.float_type
))){
3713 677, Location
, parent
.MakeName (Name
) +
3714 " A volatile field can not be of type `" +
3715 TypeManager
.MonoBASIC_Name (t
) + "'");
3721 FieldAttributes fa
= Modifiers
.FieldAttr (ModFlags
);
3723 if (parent
is Struct
&&
3724 ((fa
& FieldAttributes
.Static
) == 0) &&
3725 t
== parent
.TypeBuilder
&&
3726 !TypeManager
.IsBuiltinType (t
)){
3727 Report
.Error (523, Location
, "Struct member `" + parent
.Name
+ "." + Name
+
3728 "' causes a cycle in the structure layout");
3731 FieldBuilder
= parent
.TypeBuilder
.DefineField (
3732 Name
, t
, Modifiers
.FieldAttr (ModFlags
));
3734 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
3738 public void Emit (TypeContainer tc
)
3740 EmitContext ec
= new EmitContext (tc
, Location
, null,
3741 FieldBuilder
.FieldType
, ModFlags
);
3743 Attribute
.ApplyAttributes (ec
, FieldBuilder
, this, OptAttributes
, Location
);
3748 // `set' and `get' accessors are represented with an Accessor.
3750 public class Accessor
{
3752 // Null if the accessor is empty, or a Block if not
3755 public Attributes OptAttributes
;
3757 public Accessor (Block b
, Attributes attrs
)
3760 OptAttributes
= attrs
;
3764 public class Property
: MethodCore
{
3765 public Accessor Get
, Set
;
3766 public PropertyBuilder PropertyBuilder
;
3767 public MethodBuilder GetBuilder
, SetBuilder
;
3768 public MethodData GetData
, SetData
;
3770 protected EmitContext ec
;
3772 public override AttributeTargets AttributeTargets
{
3774 return AttributeTargets
.Property
;
3778 protected override bool DoDefine (TypeContainer parent
)
3780 if (!base.DoDefine (parent
))
3783 ec
= new EmitContext (parent
, Location
, null, MemberType
, ModFlags
);
3789 // Checks our base implementation if any
3791 protected override bool CheckBase (TypeContainer container
)
3793 base.CheckBase (container
);
3795 // Check whether arguments were correct.
3796 if (!DoDefineParameters (container
))
3802 MethodSignature ms
= new MethodSignature (Name
, null, ParameterTypes
);
3807 mi_this
= TypeContainer
.FindMembers (
3808 container
.TypeBuilder
, MemberTypes
.Property
,
3809 BindingFlags
.NonPublic
| BindingFlags
.Public
|
3810 BindingFlags
.Static
| BindingFlags
.Instance
|
3811 BindingFlags
.DeclaredOnly
,
3812 MethodSignature
.method_signature_filter
, ms
);
3814 if (mi_this
.Count
> 0) {
3815 Report
.Error (111, Location
, "Class `" + container
.Name
+ "' " +
3816 "already defines a member called `" + Name
+ "' " +
3817 "with the same parameter types");
3822 if (container
is Interface
)
3826 if ((ModFlags
& Modifiers
.READONLY
) != 0)
3827 retval
= MemberType
;
3830 MethodSignature base_ms
;
3833 if (this is Indexer) {
3834 string name, base_name;
3836 report_name = "this";
3837 name = TypeManager.IndexerPropertyName (container.TypeBuilder);
3838 ms = new MethodSignature (name, null, ParameterTypes);
3839 base_name = TypeManager.IndexerPropertyName (container.TypeBuilder.BaseType);
3840 base_ms = new MethodSignature (base_name, retval, ParameterTypes);
3843 ms
= base_ms
= new MethodSignature (Name
, retval
, ParameterTypes
);
3847 // Verify if the parent has a type with the same name, and then
3848 // check whether we have to create a new slot for it or not.
3850 Type ptype
= container
.TypeBuilder
.BaseType
;
3852 MemberInfo parent_member
= null;
3853 MemberList mi
, mi_static
, mi_instance
;
3856 // Find properties with the same name on the base class
3858 mi_static
= TypeContainer
.FindMembers (
3859 ptype
, MemberTypes
.Property
,
3860 BindingFlags
.NonPublic
| BindingFlags
.Public
| BindingFlags
.Static
,
3861 MethodSignature
.inheritable_property_signature_filter
, base_ms
);
3863 mi_instance
= TypeContainer
.FindMembers (
3864 ptype
, MemberTypes
.Property
,
3865 BindingFlags
.NonPublic
| BindingFlags
.Public
| BindingFlags
.Instance
,
3866 MethodSignature
.inheritable_property_signature_filter
,
3870 if (mi_instance
.Count
> 0)
3872 else if (mi_static
.Count
> 0)
3877 if (mi
!= null && mi
.Count
> 0)
3878 parent_member
= (PropertyInfo
) mi
[0];
3880 if (parent_member
is PropertyInfo
) {
3881 PropertyInfo parent_property
= (PropertyInfo
)parent_member
;
3883 string name
= parent_property
.DeclaringType
.Name
+ "." +
3884 parent_property
.Name
;
3886 MethodInfo
get, set, parent_method
;
3887 get = parent_property
.GetGetMethod (true);
3888 set = parent_property
.GetSetMethod (true);
3891 parent_method
= get;
3892 else if (set != null)
3893 parent_method
= set;
3895 throw new Exception ("Internal error!");
3897 if (!CheckMethodAgainstBase (container
, flags
, parent_method
, name
))
3900 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3901 Type parent_type
= TypeManager
.TypeToCoreType (
3902 parent_property
.PropertyType
);
3904 if (parent_type
!= MemberType
) {
3906 508, Location
, container
.MakeName (Name
) + ": cannot " +
3907 "change return type when overriding " +
3908 "inherited member " + name
);
3912 } else if (parent_member
== null) {
3913 /*if ((ModFlags & Modifiers.NEW) != 0)
3914 WarningNotHiding (container);
3916 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3919 if (this is Indexer)
3920 Report.Error (115, Location,
3921 container.MakeName (Name) +
3922 " no suitable indexers found to override");
3925 Report
.Error (115, Location
,
3926 container
.MakeName (Name
) +
3927 " no suitable properties found to override");
3931 if ((ModFlags
& ( Modifiers
.NEW
| Modifiers
.SHADOWS
| Modifiers
.OVERRIDE
)) == 0) {
3932 if ((ModFlags
& Modifiers
.NONVIRTUAL
) != 0) {
3933 Report
.Error (31088, Location
,
3934 container
.MakeName (Name
) + " : Cannot " +
3935 "be declared NotOverridable since this method is " +
3936 "not maked as Overrides");
3939 // if a member of module is not inherited from Object class
3940 // can not be declared protected
3941 if ((container
is Module
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
3942 Report
.Error (31066, Location
,
3943 "'Property' inside a 'Module' can not be declared as " +
3944 "'Protected' or 'Protected Friend'");
3950 const int AllowedModifiers
=
3953 Modifiers
.PROTECTED
|
3954 Modifiers
.INTERNAL
|
3958 Modifiers
.OVERRIDE
|
3959 Modifiers
.ABSTRACT
|
3963 Modifiers
.NONVIRTUAL
|
3965 Modifiers
.READONLY
|
3966 Modifiers
.WRITEONLY
|
3969 string set_parameter_name
;
3970 Parameters get_params
;
3971 Parameters set_params
;
3973 public Property (Expression type
, string name
, int mod_flags
,
3974 Accessor get_block
, Accessor set_block
,
3975 Attributes attrs
, Location loc
, string set_name
,
3976 Parameters p_get
, Parameters p_set
, ArrayList impl_what
)
3977 : base (type
, mod_flags
, AllowedModifiers
, name
, attrs
, p_set
, loc
)
3985 set_parameter_name
= set_name
;
3987 Implements
= impl_what
;
3990 public Property (Expression type
, string name
, int mod_flags
,
3991 Accessor get_block
, Accessor set_block
,
3992 Attributes attrs
, Location loc
)
3993 : this (type
, name
, mod_flags
, get_block
, set_block
, attrs
, loc
,
3994 "Value", Parameters
.EmptyReadOnlyParameters
, Parameters
.EmptyReadOnlyParameters
, null)
3998 public override bool Define (TypeContainer parent
)
4000 Type
[] g_parameters
=null, s_parameters
=null;
4001 Parameter
[] g_parms
, s_parms
;
4002 InternalParameters g_ip
=null, s_ip
=null;
4004 if ((parent
is Struct
) && ((ModFlags
& Modifiers
.PROTECTED
) != 0))
4005 Report
.Error (30435, Location
,
4006 "'Property' inside a 'Structure' can not be declared as " +
4007 "'Protected' or 'Protected Friend'");
4009 if (!DoDefine (parent
))
4012 if (!CheckBase (parent
))
4015 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
4018 if ((ModFlags
& Modifiers
.WRITEONLY
) == 0)
4021 "Property without 'Get' accessor must have a 'WriteOnly' modifier");
4024 if (get_params
== Parameters
.EmptyReadOnlyParameters
) {
4025 g_parameters
= TypeManager
.NoTypes
;
4026 g_ip
= new InternalParameters (
4027 parent
, Parameters
.EmptyReadOnlyParameters
);
4029 g_parameters
= new Type
[get_params
.FixedParameters
.Length
];
4030 for (int i
= 0; i
< get_params
.FixedParameters
.Length
; i
++) {
4031 g_parameters
[i
] = get_params
.FixedParameters
[i
].ParameterType
;
4033 g_parms
= new Parameter
[get_params
.FixedParameters
.Length
];
4034 for (int i
= 0; i
< get_params
.FixedParameters
.Length
; i
++) {
4035 Parameter tp
= get_params
.FixedParameters
[i
];
4036 g_parms
[i
] = new Parameter (tp
.TypeName
, tp
.Name
,
4037 Parameter
.Modifier
.NONE
, null);
4039 g_ip
= new InternalParameters (
4040 parent
, new Parameters (g_parms
, null, Location
));
4043 GetData
= new MethodData (this, "get", MemberType
,
4044 g_parameters
, g_ip
, CallingConventions
.Standard
,
4045 Get
.OptAttributes
, ModFlags
, flags
, false);
4047 if (!GetData
.Define (parent
))
4050 GetBuilder
= GetData
.MethodBuilder
;
4054 if ((ModFlags
& Modifiers
.READONLY
) == 0)
4057 "Property without 'Set' accessor must have a 'ReadOnly' modifier");
4062 if (set_params
== Parameters
.EmptyReadOnlyParameters
)
4064 s_parameters
= new Type
[1];
4065 s_parameters
[0] = MemberType
;
4067 s_parms
= new Parameter
[1];
4068 s_parms
[0] = new Parameter (Type
, set_parameter_name
,
4069 Parameter
.Modifier
.NONE
, null);
4071 s_parameters
= new Type
[set_params
.FixedParameters
.Length
];
4072 for (int i
= 0; i
< set_params
.FixedParameters
.Length
; i
++) {
4073 s_parameters
[i
] = set_params
.FixedParameters
[i
].ParameterType
;
4076 s_parms
= new Parameter
[set_params
.FixedParameters
.Length
];
4077 for (int i
= 0; i
< set_params
.FixedParameters
.Length
; i
++) {
4078 Parameter tp
= set_params
.FixedParameters
[i
];
4079 s_parms
[i
] = new Parameter (tp
.TypeName
, tp
.Name
,
4080 Parameter
.Modifier
.NONE
, null);
4084 s_ip
= new InternalParameters (
4085 parent
, new Parameters (s_parms
, null, Location
));
4087 SetData
= new MethodData (this, "set", TypeManager
.void_type
,
4088 s_parameters
, s_ip
, CallingConventions
.Standard
,
4089 Set
.OptAttributes
, ModFlags
, flags
, false);
4091 if (!SetData
.Define (parent
))
4094 SetBuilder
= SetData
.MethodBuilder
;
4095 SetBuilder
.DefineParameter (1, ParameterAttributes
.None
,
4096 set_parameter_name
);
4099 // FIXME - PropertyAttributes.HasDefault ?
4101 PropertyAttributes prop_attr
=
4102 PropertyAttributes
.RTSpecialName
|
4103 PropertyAttributes
.SpecialName
;
4105 if (!IsExplicitImpl
){
4106 PropertyBuilder
= parent
.TypeBuilder
.DefineProperty (
4107 Name
, prop_attr
, MemberType
, null);
4109 PropertyBuilder
.SetGetMethod (GetBuilder
);
4110 PropertyBuilder
.SetSetMethod (SetBuilder
);
4113 // HACK for the reasons exposed above
4115 if (!TypeManager
.RegisterProperty (PropertyBuilder
, GetBuilder
, SetBuilder
)) {
4118 "Class `" + parent
.Name
+
4119 "' already contains a definition for the property `" +
4127 public void Emit (TypeContainer tc
)
4130 // The PropertyBuilder can be null for explicit implementations, in that
4131 // case, we do not actually emit the ".property", so there is nowhere to
4132 // put the attribute
4135 if (PropertyBuilder
!= null)
4136 Attribute
.ApplyAttributes (ec
, PropertyBuilder
, this, OptAttributes
, Location
);
4138 if (GetData
!= null)
4140 Parameters
= get_params
;
4141 GetData
.Emit (tc
, Get
.Block
, Get
);
4144 if (SetData
!= null)
4146 Parameters
= set_params
;
4147 SetData
.Emit (tc
, Set
.Block
, Set
);
4154 /// Gigantic workaround for lameness in SRE follows :
4155 /// This class derives from EventInfo and attempts to basically
4156 /// wrap around the EventBuilder so that FindMembers can quickly
4157 /// return this in it search for members
4159 public class MyEventBuilder
: EventInfo
{
4162 // We use this to "point" to our Builder which is
4163 // not really a MemberInfo
4165 EventBuilder MyBuilder
;
4168 // We "catch" and wrap these methods
4170 MethodInfo raise
, remove, add;
4172 EventAttributes attributes
;
4173 Type declaring_type
, reflected_type
, event_type
;
4176 public MyEventBuilder (TypeBuilder type_builder
, string name
, EventAttributes event_attr
, Type event_type
)
4178 MyBuilder
= type_builder
.DefineEvent (name
, event_attr
, event_type
);
4180 // And now store the values in our own fields.
4182 declaring_type
= type_builder
;
4184 reflected_type
= type_builder
;
4186 attributes
= event_attr
;
4188 this.event_type
= event_type
;
4192 // Methods that you have to override. Note that you only need
4193 // to "implement" the variants that take the argument (those are
4194 // the "abstract" methods, the others (GetAddMethod()) are
4197 public override MethodInfo
GetAddMethod (bool nonPublic
)
4202 public override MethodInfo
GetRemoveMethod (bool nonPublic
)
4207 public override MethodInfo
GetRaiseMethod (bool nonPublic
)
4213 // These methods make "MyEventInfo" look like a Builder
4215 public void SetRaiseMethod (MethodBuilder raiseMethod
)
4217 raise
= raiseMethod
;
4218 MyBuilder
.SetRaiseMethod (raiseMethod
);
4221 public void SetRemoveOnMethod (MethodBuilder removeMethod
)
4223 remove = removeMethod
;
4224 MyBuilder
.SetRemoveOnMethod (removeMethod
);
4227 public void SetAddOnMethod (MethodBuilder addMethod
)
4230 MyBuilder
.SetAddOnMethod (addMethod
);
4233 public void SetCustomAttribute (CustomAttributeBuilder cb
)
4235 MyBuilder
.SetCustomAttribute (cb
);
4238 public override object [] GetCustomAttributes (bool inherit
)
4240 // FIXME : There's nothing which can be seemingly done here because
4241 // we have no way of getting at the custom attribute objects of the
4246 public override object [] GetCustomAttributes (Type t
, bool inherit
)
4248 // FIXME : Same here !
4252 public override bool IsDefined (Type t
, bool b
)
4257 public override EventAttributes Attributes
{
4263 public override string Name
{
4269 public override Type DeclaringType
{
4271 return declaring_type
;
4275 public override Type ReflectedType
{
4277 return reflected_type
;
4281 public Type EventType
{
4288 public class Event
: FieldBase
{
4289 const int AllowedModifiers
=
4292 Modifiers
.PROTECTED
|
4293 Modifiers
.INTERNAL
|
4298 Modifiers
.OVERRIDE
|
4302 public readonly Accessor Add
;
4303 public readonly Accessor Remove
;
4304 public MyEventBuilder EventBuilder
;
4306 MethodBuilder AddBuilder
, RemoveBuilder
;
4307 MethodData AddData
, RemoveData
;
4309 public Event (Expression type
, string name
, Object init
, int mod
, Accessor
add,
4310 Accessor
remove, Attributes attrs
, Location loc
)
4311 : base (type
, mod
, AllowedModifiers
, name
, init
, attrs
, loc
)
4318 public Event (Expression type
, string name
, Object init
, int mod
, Accessor
add,
4319 Accessor
remove, Attributes attrs
, ArrayList impl_what
, Location loc
)
4320 : base (type
, mod
, AllowedModifiers
, name
, init
, attrs
, loc
)
4324 Implements
= impl_what
;
4327 public override AttributeTargets AttributeTargets
{
4329 return AttributeTargets
.Event
;
4333 public override bool Define (TypeContainer parent
)
4335 EventAttributes e_attr
= EventAttributes
.RTSpecialName
| EventAttributes
.SpecialName
;
4337 if (!DoDefine (parent
))
4340 if (!MemberType
.IsSubclassOf (TypeManager
.delegate_type
)) {
4341 Report
.Error (31044, Location
, "'" + parent
.Name
+ "." + Name
+
4342 "' : event must be of a delegate type");
4346 Type
[] parameter_types
= new Type
[1];
4347 parameter_types
[0] = MemberType
;
4349 Parameter
[] parms
= new Parameter
[1];
4350 parms
[0] = new Parameter (Type
, /* was "value" */ this.Name
, Parameter
.Modifier
.NONE
, null);
4351 InternalParameters ip
= new InternalParameters (
4352 parent
, new Parameters (parms
, null, Location
));
4354 if (!CheckBase (parent
))
4358 // Now define the accessors
4360 AddData
= new MethodData (this, "add", TypeManager
.void_type
,
4361 parameter_types
, ip
, CallingConventions
.Standard
,
4362 (Add
!= null) ? Add
.OptAttributes
: null,
4363 ModFlags
, flags
, false);
4365 if (!AddData
.Define (parent
))
4368 AddBuilder
= AddData
.MethodBuilder
;
4369 AddBuilder
.DefineParameter (1, ParameterAttributes
.None
, /* was "value" */ this.Name
);
4371 RemoveData
= new MethodData (this, "remove", TypeManager
.void_type
,
4372 parameter_types
, ip
, CallingConventions
.Standard
,
4373 (Remove
!= null) ? Remove
.OptAttributes
: null,
4374 ModFlags
, flags
, false);
4376 if (!RemoveData
.Define (parent
))
4379 RemoveBuilder
= RemoveData
.MethodBuilder
;
4380 RemoveBuilder
.DefineParameter (1, ParameterAttributes
.None
, /* was "value" */ this.Name
);
4382 if (!IsExplicitImpl
){
4383 EventBuilder
= new MyEventBuilder (
4384 parent
.TypeBuilder
, Name
, e_attr
, MemberType
);
4386 if (Add
== null && Remove
== null) {
4387 FieldBuilder
= parent
.TypeBuilder
.DefineField (
4389 FieldAttributes
.FamANDAssem
| ((ModFlags
& Modifiers
.STATIC
) != 0 ? FieldAttributes
.Static
: 0));
4390 TypeManager
.RegisterPrivateFieldOfEvent (
4391 (EventInfo
) EventBuilder
, FieldBuilder
);
4392 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
4395 EventBuilder
.SetAddOnMethod (AddBuilder
);
4396 EventBuilder
.SetRemoveOnMethod (RemoveBuilder
);
4398 if (!TypeManager
.RegisterEvent (EventBuilder
, AddBuilder
, RemoveBuilder
)) {
4399 Report
.Error (111, Location
,
4400 "Class `" + parent
.Name
+
4401 "' already contains a definition for the event `" +
4410 void EmitDefaultMethod (EmitContext ec
, bool is_add
)
4412 ILGenerator ig
= ec
.ig
;
4413 MethodInfo method
= null;
4416 method
= TypeManager
.delegate_combine_delegate_delegate
;
4418 method
= TypeManager
.delegate_remove_delegate_delegate
;
4420 if ((ModFlags
& Modifiers
.STATIC
) != 0) {
4421 ig
.Emit (OpCodes
.Ldsfld
, (FieldInfo
) FieldBuilder
);
4422 ig
.Emit (OpCodes
.Ldarg_0
);
4423 ig
.Emit (OpCodes
.Call
, method
);
4424 ig
.Emit (OpCodes
.Castclass
, MemberType
);
4425 ig
.Emit (OpCodes
.Stsfld
, (FieldInfo
) FieldBuilder
);
4427 ig
.Emit (OpCodes
.Ldarg_0
);
4428 ig
.Emit (OpCodes
.Ldarg_0
);
4429 ig
.Emit (OpCodes
.Ldfld
, (FieldInfo
) FieldBuilder
);
4430 ig
.Emit (OpCodes
.Ldarg_1
);
4431 ig
.Emit (OpCodes
.Call
, method
);
4432 ig
.Emit (OpCodes
.Castclass
, MemberType
);
4433 ig
.Emit (OpCodes
.Stfld
, (FieldInfo
) FieldBuilder
);
4435 ig
.Emit (OpCodes
.Ret
);
4438 public void Emit (TypeContainer tc
)
4442 ec
= new EmitContext (tc
, Location
, null, MemberType
, ModFlags
);
4443 Attribute
.ApplyAttributes (ec
, EventBuilder
, this, OptAttributes
, Location
);
4446 AddData
.Emit (tc
, Add
.Block
, Add
);
4448 ILGenerator ig
= AddData
.MethodBuilder
.GetILGenerator ();
4449 ec
= new EmitContext (tc
, Location
, ig
, TypeManager
.void_type
, ModFlags
);
4450 EmitDefaultMethod (ec
, true);
4454 RemoveData
.Emit (tc
, Remove
.Block
, Remove
);
4456 ILGenerator ig
= RemoveData
.MethodBuilder
.GetILGenerator ();
4457 ec
= new EmitContext (tc
, Location
, ig
, TypeManager
.void_type
, ModFlags
);
4458 EmitDefaultMethod (ec
, false);
4465 // FIXME: This does not handle:
4467 // int INTERFACENAME [ args ]
4472 // int this [ args ]
4476 public class Indexer : PropertyBase {
4478 const int AllowedModifiers =
4481 Modifiers.PROTECTED |
4482 Modifiers.INTERNAL |
4486 Modifiers.OVERRIDE |
4491 public string IndexerName;
4492 public string InterfaceIndexerName;
4495 // Are we implementing an interface ?
4497 bool IsImplementing = false;
4499 public Indexer (Expression type, string int_type, int flags, Parameters parameters,
4500 Accessor get_block, Accessor set_block, Attributes attrs, Location loc)
4501 : base (type, "", flags, AllowedModifiers, parameters, get_block, set_block,
4504 ExplicitInterfaceName = int_type;
4507 public override bool Define (TypeContainer parent)
4509 PropertyAttributes prop_attr =
4510 PropertyAttributes.RTSpecialName |
4511 PropertyAttributes.SpecialName;
4513 if (!DoDefine (parent))
4516 IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
4517 if (IndexerName == null)
4518 IndexerName = "Item";
4519 else if (IsExplicitImpl)
4520 Report.Error (592, Location,
4521 "Attribute 'IndexerName' is not valid on this declaration " +
4522 "type. It is valid on `property' declarations only.");
4524 ShortName = IndexerName;
4525 if (IsExplicitImpl) {
4526 InterfaceIndexerName = TypeManager.IndexerPropertyName (InterfaceType);
4527 Name = InterfaceType.FullName + "." + IndexerName;
4529 InterfaceIndexerName = IndexerName;
4533 if (!CheckBase (parent))
4537 InternalParameters ip = new InternalParameters (parent, Parameters);
4539 GetData = new MethodData (this, "get", MemberType,
4540 ParameterTypes, ip, CallingConventions.Standard,
4541 Get.OptAttributes, ModFlags, flags, false);
4543 if (!GetData.Define (parent))
4546 GetBuilder = GetData.MethodBuilder;
4550 int top = ParameterTypes.Length;
4551 Type [] set_pars = new Type [top + 1];
4552 ParameterTypes.CopyTo (set_pars, 0);
4553 set_pars [top] = MemberType;
4555 Parameter [] fixed_parms = Parameters.FixedParameters;
4557 if (fixed_parms == null){
4558 throw new Exception ("We currently do not support only array arguments in an indexer");
4559 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4560 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4562 // Here is the problem: the `value' parameter has
4563 // to come *after* the array parameter in the declaration
4565 // X (object [] x, Type value)
4568 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4569 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
4573 Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
4576 fixed_parms.CopyTo (tmp, 0);
4577 tmp [fixed_parms.Length] = new Parameter (
4578 Type, this.Name, Parameter.Modifier.NONE, null);
4580 Parameters set_formal_params = new Parameters (tmp, null, Location);
4582 InternalParameters ip = new InternalParameters (parent, set_formal_params);
4584 SetData = new MethodData (this, "set", TypeManager.void_type,
4585 set_pars, ip, CallingConventions.Standard,
4586 Set.OptAttributes, ModFlags, flags, false);
4588 if (!SetData.Define (parent))
4591 SetBuilder = SetData.MethodBuilder;
4595 // Now name the parameters
4597 Parameter [] p = Parameters.FixedParameters;
4601 for (i = 0; i < p.Length; ++i) {
4603 GetBuilder.DefineParameter (
4604 i + 1, p [i].Attributes, p [i].Name);
4607 SetBuilder.DefineParameter (
4608 i + 1, p [i].Attributes, p [i].Name);
4613 SetBuilder.DefineParameter (
4614 i + 1, ParameterAttributes.None, this.Name);
4616 if (i != ParameterTypes.Length) {
4617 Parameter array_param = Parameters.ArrayParameter;
4618 SetBuilder.DefineParameter (
4619 i + 1, array_param.Attributes, array_param.Name);
4623 if (GetData != null)
4624 IsImplementing = GetData.IsImplementing;
4625 else if (SetData != null)
4626 IsImplementing = SetData.IsImplementing;
4629 // Define the PropertyBuilder if one of the following conditions are met:
4630 // a) we're not implementing an interface indexer.
4631 // b) the indexer has a different IndexerName and this is no
4632 // explicit interface implementation.
4634 if (!IsExplicitImpl) {
4635 PropertyBuilder = parent.TypeBuilder.DefineProperty (
4636 IndexerName, prop_attr, MemberType, ParameterTypes);
4638 if (GetData != null)
4639 PropertyBuilder.SetGetMethod (GetBuilder);
4641 if (SetData != null)
4642 PropertyBuilder.SetSetMethod (SetBuilder);
4644 TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder,
4653 struct MethodSignature
{
4655 public Type RetType
;
4656 public Type
[] Parameters
;
4659 /// This delegate is used to extract methods which have the
4660 /// same signature as the argument
4662 public static MemberFilter method_signature_filter
;
4665 /// This delegate is used to extract methods which have the
4666 /// same signature as the argument except for the name
4668 public static MemberFilter method_signature_noname_filter
;
4671 /// This delegate is used to extract inheritable methods which
4672 /// have the same signature as the argument. By inheritable,
4673 /// this means that we have permissions to override the method
4674 /// from the current assembly and class
4676 public static MemberFilter inheritable_method_signature_filter
;
4679 /// This delegate is used to extract inheritable methods which
4680 /// have the same signature as the argument. By inheritable,
4681 /// this means that we have permissions to override the method
4682 /// from the current assembly and class
4684 public static MemberFilter inheritable_property_signature_filter
;
4686 static MethodSignature ()
4688 method_signature_filter
= new MemberFilter (MemberSignatureCompare
);
4689 method_signature_noname_filter
= new MemberFilter (MemberSignatureCompareNoName
);
4690 inheritable_method_signature_filter
= new MemberFilter (
4691 InheritableMemberSignatureCompare
);
4692 inheritable_property_signature_filter
= new MemberFilter (
4693 InheritablePropertySignatureCompare
);
4696 public MethodSignature (string name
, Type ret_type
, Type
[] parameters
)
4701 if (parameters
== null)
4702 Parameters
= TypeManager
.NoTypes
;
4704 Parameters
= parameters
;
4707 public override int GetHashCode ()
4709 return Name
.GetHashCode ();
4712 public override bool Equals (Object o
)
4714 MethodSignature other
= (MethodSignature
) o
;
4716 if (other
.Name
!= Name
)
4719 if (other
.RetType
!= RetType
)
4722 if (Parameters
== null){
4723 if (other
.Parameters
== null)
4728 if (other
.Parameters
== null)
4731 int c
= Parameters
.Length
;
4732 if (other
.Parameters
.Length
!= c
)
4735 for (int i
= 0; i
< c
; i
++)
4736 if (other
.Parameters
[i
] != Parameters
[i
])
4742 static bool MemberSignatureCompareNoName (MemberInfo m
, object filter_criteria
)
4744 return MemberSignatureCompare (m
, filter_criteria
, false);
4747 static bool MemberSignatureCompare (MemberInfo m
, object filter_criteria
)
4749 return MemberSignatureCompare (m
, filter_criteria
, true);
4752 static bool MemberSignatureCompare (MemberInfo m
, object filter_criteria
, bool use_name
)
4754 MethodSignature sig
= (MethodSignature
) filter_criteria
;
4756 if (use_name
&& (m
.Name
!= sig
.Name
))
4760 MethodInfo mi
= m
as MethodInfo
;
4761 PropertyInfo pi
= m
as PropertyInfo
;
4764 ReturnType
= mi
.ReturnType
;
4765 else if (pi
!= null)
4766 ReturnType
= pi
.PropertyType
;
4771 // we use sig.RetType == null to mean `do not check the
4772 // method return value.
4774 if (sig
.RetType
!= null)
4775 if (ReturnType
!= sig
.RetType
)
4780 args
= TypeManager
.GetArgumentTypes (mi
);
4782 args
= TypeManager
.GetArgumentTypes (pi
);
4784 Type
[] sigp
= sig
.Parameters
;
4786 if (args
.Length
!= sigp
.Length
)
4789 for (int i
= args
.Length
; i
> 0; ){
4791 if (args
[i
] != sigp
[i
])
4798 // This filter should be used when we are requesting methods that
4799 // we want to override.
4801 // This makes a number of assumptions, for example
4802 // that the methods being extracted are of a parent
4803 // class (this means we know implicitly that we are
4804 // being called to find out about members by a derived
4807 static bool InheritableMemberSignatureCompare (MemberInfo m
, object filter_criteria
)
4809 if (MemberSignatureCompare (m
, filter_criteria
)){
4810 MethodInfo mi
= (MethodInfo
) m
;
4811 MethodAttributes prot
= mi
.Attributes
& MethodAttributes
.MemberAccessMask
;
4813 // If only accessible to the current class.
4814 if (prot
== MethodAttributes
.Private
)
4817 // If only accessible to the defining assembly or
4818 if (prot
== MethodAttributes
.FamANDAssem
||
4819 prot
== MethodAttributes
.Assembly
){
4820 if (m
.DeclaringType
.Assembly
== CodeGen
.AssemblyBuilder
)
4826 // Anything else (FamOrAssembly and Public) is fine
4833 // This filter should be used when we are requesting properties that
4834 // we want to override.
4836 // This makes a number of assumptions, for example
4837 // that the methods being extracted are of a parent
4838 // class (this means we know implicitly that we are
4839 // being called to find out about members by a derived
4842 static bool InheritablePropertySignatureCompare (MemberInfo m
, object filter_criteria
)
4844 if (MemberSignatureCompare (m
, filter_criteria
)){
4845 PropertyInfo pi
= (PropertyInfo
) m
;
4847 MethodInfo inherited_get
= TypeManager
.GetPropertyGetter (pi
);
4848 MethodInfo inherited_set
= TypeManager
.GetPropertySetter (pi
);
4850 MethodInfo mi
= inherited_get
== null ? inherited_set
: inherited_get
;
4852 MethodAttributes prot
= mi
.Attributes
& MethodAttributes
.MemberAccessMask
;
4854 // If only accessible to the current class.
4855 if (prot
== MethodAttributes
.Private
)
4858 // If only accessible to the defining assembly or
4859 if (prot
== MethodAttributes
.FamANDAssem
||
4860 prot
== MethodAttributes
.Assembly
){
4861 if (m
.DeclaringType
.Assembly
== CodeGen
.AssemblyBuilder
)
4867 // Anything else (FamOrAssembly and Public) is fine