2 // class.cs: Class and Struct handlers
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 // Martin Baulig (martin@gnome.org)
6 // Marek Safar (marek.safar@seznam.cz)
8 // Licensed under the terms of the GNU GPL
10 // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
13 // 2002-10-11 Miguel de Icaza <miguel@ximian.com>
15 // * class.cs: Following the comment from 2002-09-26 to AddMethod, I
16 // have fixed a remaining problem: not every AddXXXX was adding a
17 // fully qualified name.
19 // Now everyone registers a fully qualified name in the DeclSpace as
20 // being defined instead of the partial name.
22 // Downsides: we are slower than we need to be due to the excess
23 // copies and the names being registered this way.
25 // The reason for this is that we currently depend (on the corlib
26 // bootstrap for instance) that types are fully qualified, because
27 // we dump all the types in the namespace, and we should really have
28 // types inserted into the proper namespace, so we can only store the
29 // basenames in the defined_names array.
34 using System
.Collections
;
35 using System
.Collections
.Specialized
;
36 using System
.Reflection
;
37 using System
.Reflection
.Emit
;
38 using System
.Runtime
.CompilerServices
;
39 using System
.Runtime
.InteropServices
;
40 using System
.Security
;
41 using System
.Security
.Permissions
;
44 using Mono
.CompilerServices
.SymbolWriter
;
46 namespace Mono
.CSharp
{
56 /// This is the base class for structs and classes.
58 public abstract class TypeContainer
: DeclSpace
, IMemberContainer
{
60 public class MemberCoreArrayList
: ArrayList
63 /// Defines the MemberCore objects that are in this array
65 public virtual void DefineContainerMembers ()
67 foreach (MemberCore mc
in this) {
72 public virtual void Emit ()
74 foreach (MemberCore mc
in this)
79 public class MethodArrayList
: MemberCoreArrayList
87 CachedMethods cached_method
;
88 TypeContainer container
;
90 public MethodArrayList (TypeContainer container
)
92 this.container
= container
;
96 /// Method container contains Equals method
98 public bool HasEquals
{
100 cached_method
|= CachedMethods
.Equals
;
104 return (cached_method
& CachedMethods
.Equals
) != 0;
109 /// Method container contains GetHashCode method
111 public bool HasGetHashCode
{
113 cached_method
|= CachedMethods
.GetHashCode
;
117 return (cached_method
& CachedMethods
.GetHashCode
) != 0;
121 public override void DefineContainerMembers ()
123 base.DefineContainerMembers ();
125 if ((RootContext
.WarningLevel
>= 3) && HasEquals
&& !HasGetHashCode
) {
126 Report
.Warning (659, container
.Location
, "'{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container
.GetSignatureForError ());
132 public sealed class IndexerArrayList
: MemberCoreArrayList
135 /// The indexer name for this container
137 public string IndexerName
= DefaultIndexerName
;
139 bool seen_normal_indexers
= false;
141 TypeContainer container
;
143 public IndexerArrayList (TypeContainer container
)
145 this.container
= container
;
149 /// Defines the indexers, and also verifies that the IndexerNameAttribute in the
150 /// class is consistent. Either it is `Item' or it is the name defined by all the
151 /// indexers with the `IndexerName' attribute.
153 /// Turns out that the IndexerNameAttribute is applied to each indexer,
154 /// but it is never emitted, instead a DefaultMember attribute is attached
157 public override void DefineContainerMembers()
159 base.DefineContainerMembers ();
161 string class_indexer_name
= null;
164 // If there's both an explicit and an implicit interface implementation, the
165 // explicit one actually implements the interface while the other one is just
166 // a normal indexer. See bug #37714.
169 // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
170 foreach (Indexer i
in this) {
171 if (i
.InterfaceType
!= null) {
172 if (seen_normal_indexers
)
173 throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
177 seen_normal_indexers
= true;
179 if (class_indexer_name
== null) {
180 class_indexer_name
= i
.ShortName
;
184 if (i
.ShortName
!= class_indexer_name
)
185 Report
.Error (668, i
.Location
, "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
188 if (class_indexer_name
!= null)
189 IndexerName
= class_indexer_name
;
192 public override void Emit ()
196 if (!seen_normal_indexers
)
199 CustomAttributeBuilder cb
= new CustomAttributeBuilder (TypeManager
.default_member_ctor
, new string [] { IndexerName }
);
200 container
.TypeBuilder
.SetCustomAttribute (cb
);
204 public class OperatorArrayList
: MemberCoreArrayList
206 TypeContainer container
;
208 public OperatorArrayList (TypeContainer container
)
210 this.container
= container
;
214 // Operator pair checking
219 public Type ret_type
;
220 public Type type1
, type2
;
222 public Operator
.OpType ot
;
224 public OperatorEntry (int f
, Operator o
)
228 ret_type
= o
.OperatorMethod
.ReturnType
;
229 Type
[] pt
= o
.OperatorMethod
.ParameterTypes
;
236 public override int GetHashCode ()
238 return ret_type
.GetHashCode ();
241 public override bool Equals (object o
)
243 OperatorEntry other
= (OperatorEntry
) o
;
245 if (other
.ret_type
!= ret_type
)
247 if (other
.type1
!= type1
)
249 if (other
.type2
!= type2
)
256 // Checks that some operators come in pairs:
262 // They are matched based on the return type and the argument types
264 void CheckPairedOperators ()
266 Hashtable pairs
= new Hashtable (null, null);
267 Operator true_op
= null;
268 Operator false_op
= null;
269 bool has_equality_or_inequality
= false;
271 // Register all the operators we care about.
272 foreach (Operator op
in this){
275 switch (op
.OperatorType
){
276 case Operator
.OpType
.Equality
:
278 has_equality_or_inequality
= true;
280 case Operator
.OpType
.Inequality
:
282 has_equality_or_inequality
= true;
285 case Operator
.OpType
.True
:
288 case Operator
.OpType
.False
:
292 case Operator
.OpType
.GreaterThan
:
294 case Operator
.OpType
.LessThan
:
297 case Operator
.OpType
.GreaterThanOrEqual
:
299 case Operator
.OpType
.LessThanOrEqual
:
305 OperatorEntry oe
= new OperatorEntry (reg
, op
);
307 object o
= pairs
[oe
];
311 oe
= (OperatorEntry
) o
;
316 if (true_op
!= null){
317 if (false_op
== null)
318 Report
.Error (216, true_op
.Location
, "operator true requires a matching operator false");
319 } else if (false_op
!= null)
320 Report
.Error (216, false_op
.Location
, "operator false requires a matching operator true");
323 // Look for the mistakes.
325 foreach (DictionaryEntry de
in pairs
){
326 OperatorEntry oe
= (OperatorEntry
) de
.Key
;
333 case Operator
.OpType
.Equality
:
336 case Operator
.OpType
.Inequality
:
339 case Operator
.OpType
.GreaterThan
:
342 case Operator
.OpType
.LessThan
:
345 case Operator
.OpType
.GreaterThanOrEqual
:
348 case Operator
.OpType
.LessThanOrEqual
:
352 Report
.Error (216, oe
.op
.Location
,
353 "The operator `" + oe
.op
+ "' requires a matching operator `" + s
+ "' to also be defined");
356 if (has_equality_or_inequality
&& (RootContext
.WarningLevel
> 2)) {
357 if (container
.Methods
== null || !container
.Methods
.HasEquals
)
358 Report
.Warning (660, container
.Location
, "'{0}' defines operator == or operator != but does not override Object.Equals(object o)", container
.GetSignatureForError ());
360 if (container
.Methods
== null || !container
.Methods
.HasGetHashCode
)
361 Report
.Warning (661, container
.Location
, "'{0}' defines operator == or operator != but does not override Object.GetHashCode()", container
.GetSignatureForError ());
365 public override void DefineContainerMembers ()
367 base.DefineContainerMembers ();
368 CheckPairedOperators ();
373 // Whether this is a struct, class or interface
374 public readonly Kind Kind
;
376 // Holds a list of classes and structures
379 // Holds the list of properties
380 MemberCoreArrayList properties
;
382 // Holds the list of enumerations
383 MemberCoreArrayList enums
;
385 // Holds the list of delegates
386 MemberCoreArrayList delegates
;
388 // Holds the list of constructors
389 protected MemberCoreArrayList instance_constructors
;
391 // Holds the list of fields
392 MemberCoreArrayList fields
;
394 // Holds a list of fields that have initializers
395 protected ArrayList initialized_fields
;
397 // Holds a list of static fields that have initializers
398 protected ArrayList initialized_static_fields
;
400 // Holds the list of constants
401 MemberCoreArrayList constants
;
404 MemberCoreArrayList interfaces
;
406 // Holds the methods.
407 MethodArrayList methods
;
410 protected MemberCoreArrayList events
;
412 // Holds the indexers
413 IndexerArrayList indexers
;
415 // Holds the operators
416 MemberCoreArrayList operators
;
418 // Holds the iterators
421 // Holds the parts of a partial class;
424 // The emit context for toplevel objects.
427 public EmitContext EmitContext
{
432 // Pointers to the default constructor and the default static constructor
434 protected Constructor default_constructor
;
435 protected Constructor default_static_constructor
;
438 // Whether we have at least one non-static field
440 bool have_nonstatic_fields
= false;
443 // This one is computed after we can distinguish interfaces
444 // from classes from the arraylist `type_bases'
446 string base_class_name
;
447 public Type base_class_type
;
449 ArrayList type_bases
;
451 bool members_defined
;
452 bool members_defined_ok
;
454 // The interfaces we implement.
456 protected Type
[] base_inteface_types
;
458 // The parent member container and our member cache
459 IMemberContainer parent_container
;
460 MemberCache member_cache
;
462 public const string DefaultIndexerName
= "Item";
464 public TypeContainer (NamespaceEntry ns
, TypeContainer parent
, MemberName name
,
465 Attributes attrs
, Kind kind
, Location l
)
466 : base (ns
, parent
, name
, attrs
, l
)
470 types
= new ArrayList ();
472 base_class_name
= null;
475 public bool AddToMemberContainer (MemberCore symbol
, bool is_method
)
477 return AddToContainer (symbol
, is_method
, String
.Concat (Name
, '.', symbol
.Name
), symbol
.Name
);
480 bool AddToTypeContainer (DeclSpace ds
)
482 return AddToContainer (ds
, false, ds
.Name
, ds
.Basename
);
485 public void AddConstant (Const constant
)
487 if (!AddToMemberContainer (constant
, false))
490 if (constants
== null)
491 constants
= new MemberCoreArrayList ();
493 constants
.Add (constant
);
496 public void AddEnum (Mono
.CSharp
.Enum e
)
498 if (!AddToTypeContainer (e
))
502 enums
= new MemberCoreArrayList ();
507 public void AddClassOrStruct (TypeContainer c
)
509 if (!AddToTypeContainer (c
))
515 public void AddDelegate (Delegate d
)
517 if (!AddToTypeContainer (d
))
520 if (delegates
== null)
521 delegates
= new MemberCoreArrayList ();
526 public void AddMethod (Method method
)
528 if (!AddToMemberContainer (method
, true))
532 methods
= new MethodArrayList (this);
534 if (method
.Name
.IndexOf ('.') != -1)
535 methods
.Insert (0, method
);
537 methods
.Add (method
);
540 public void AddConstructor (Constructor c
)
542 if (c
.Name
!= Basename
) {
543 Report
.Error (1520, c
.Location
, "Class, struct, or interface method must have a return type");
546 bool is_static
= (c
.ModFlags
& Modifiers
.STATIC
) != 0;
549 if (default_static_constructor
!= null) {
550 Report
.SymbolRelatedToPreviousError (default_static_constructor
);
551 Report
.Error (111, c
.Location
, Error111
, Name
, c
.Name
);
555 default_static_constructor
= c
;
558 if (default_constructor
!= null) {
559 Report
.SymbolRelatedToPreviousError (default_constructor
);
560 Report
.Error (111, c
.Location
, Error111
, c
.Location
, Name
, c
.Name
);
563 default_constructor
= c
;
566 if (instance_constructors
== null)
567 instance_constructors
= new MemberCoreArrayList ();
569 instance_constructors
.Add (c
);
573 internal static string Error111
{
575 return "Type '{0}' already defines a member called '{1}' with the same parameter types";
579 public void AddInterface (TypeContainer iface
)
581 if (!AddToTypeContainer (iface
))
584 if (interfaces
== null) {
585 interfaces
= new MemberCoreArrayList ();
588 interfaces
.Add (iface
);
591 public void AddField (Field field
)
593 if (!AddToMemberContainer (field
, false))
597 fields
= new MemberCoreArrayList ();
601 if (field
.HasInitializer
){
602 if ((field
.ModFlags
& Modifiers
.STATIC
) != 0){
603 if (initialized_static_fields
== null)
604 initialized_static_fields
= new ArrayList ();
606 initialized_static_fields
.Add (field
);
608 if (initialized_fields
== null)
609 initialized_fields
= new ArrayList ();
611 initialized_fields
.Add (field
);
615 if ((field
.ModFlags
& Modifiers
.STATIC
) == 0)
616 have_nonstatic_fields
= true;
619 public void AddProperty (Property prop
)
621 if (!AddToMemberContainer (prop
, false) ||
622 !AddToMemberContainer (prop
.Get
, true) || !AddToMemberContainer (prop
.Set
, true))
625 if (properties
== null)
626 properties
= new MemberCoreArrayList ();
628 if (prop
.Name
.IndexOf ('.') != -1)
629 properties
.Insert (0, prop
);
631 properties
.Add (prop
);
634 public void AddEvent (Event e
)
636 if (!AddToMemberContainer (e
, false))
639 if (e
is EventProperty
) {
640 if (!AddToMemberContainer (e
.Add
, true))
643 if (!AddToMemberContainer (e
.Remove
, true))
648 events
= new MemberCoreArrayList ();
655 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
657 public void AddIndexer (Indexer i
)
659 if (indexers
== null)
660 indexers
= new IndexerArrayList (this);
662 if (i
.IsExplicitImpl
)
663 indexers
.Insert (0, i
);
668 public void AddOperator (Operator op
)
670 if (!AddToMemberContainer (op
, true))
673 if (operators
== null)
674 operators
= new OperatorArrayList (this);
679 public void AddIterator (Iterator i
)
681 if (iterators
== null)
682 iterators
= new ArrayList ();
687 public void AddType (TypeContainer tc
)
692 public void AddPart (ClassPart part
)
695 parts
= new ArrayList ();
700 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
702 if (a
.Type
== TypeManager
.default_member_type
) {
703 if (Indexers
!= null) {
704 Report
.Error (646, a
.Location
,
705 "Cannot specify the DefaultMember attribute on" +
706 " a type containing an indexer");
711 base.ApplyAttributeBuilder (a
, cb
);
714 public override AttributeTargets AttributeTargets
{
716 throw new NotSupportedException ();
720 public ArrayList Types
{
726 public MethodArrayList Methods
{
732 public ArrayList Constants
{
738 public ArrayList Interfaces
{
744 public ArrayList Iterators
{
752 return base_class_name
;
756 public ArrayList Bases
{
766 public ArrayList Fields
{
772 public ArrayList InstanceConstructors
{
774 return instance_constructors
;
778 public ArrayList Properties
{
784 public ArrayList Events
{
790 public ArrayList Enums
{
796 public ArrayList Indexers
{
802 public ArrayList Operators
{
808 public ArrayList Delegates
{
814 public ArrayList Parts
{
820 public virtual TypeAttributes TypeAttr
{
822 return Modifiers
.TypeAttr (ModFlags
, this);
826 public string IndexerName
{
828 return indexers
== null ? DefaultIndexerName
: indexers
.IndexerName
;
833 // Emits the instance field initializers
835 public bool EmitFieldInitializers (EmitContext ec
)
838 Expression instance_expr
;
841 fields
= initialized_static_fields
;
842 instance_expr
= null;
844 fields
= initialized_fields
;
845 instance_expr
= new This (Location
.Null
).Resolve (ec
);
851 foreach (Field f
in fields
){
852 Expression e
= f
.GetInitializerExpression (ec
);
856 Location l
= f
.Location
;
857 FieldExpr fe
= new FieldExpr (f
.FieldBuilder
, l
);
858 fe
.InstanceExpression
= instance_expr
;
859 ExpressionStatement a
= new Assign (fe
, e
, l
);
861 a
= a
.ResolveStatement (ec
);
865 a
.EmitStatement (ec
);
872 // Defines the default constructors
874 protected void DefineDefaultConstructor (bool is_static
)
878 // The default constructor is public
879 // If the class is abstract, the default constructor is protected
880 // The default static constructor is private
882 int mods
= Modifiers
.PUBLIC
;
884 mods
= Modifiers
.STATIC
| Modifiers
.PRIVATE
;
885 else if ((ModFlags
& Modifiers
.ABSTRACT
) != 0)
886 mods
= Modifiers
.PROTECTED
;
888 c
= new Constructor (this, Basename
, mods
, Parameters
.EmptyReadOnlyParameters
,
889 new ConstructorBaseInitializer (
890 null, Parameters
.EmptyReadOnlyParameters
,
896 c
.Block
= new ToplevelBlock (null, Location
);
901 /// The pending methods that need to be implemented
902 // (interfaces or abstract methods)
904 public PendingImplementation Pending
;
906 public abstract void Register ();
908 public abstract PendingImplementation
GetPendingImplementations ();
910 TypeExpr
[] GetPartialBases (out TypeExpr parent
, out bool error
)
912 ArrayList ifaces
= new ArrayList ();
915 Location parent_loc
= Location
.Null
;
917 foreach (ClassPart part
in parts
) {
919 TypeExpr
[] new_ifaces
;
921 new_ifaces
= part
.GetClassBases (out new_parent
, out error
);
925 if ((parent
!= null) && (new_parent
!= null) &&
926 !parent
.Equals (new_parent
)) {
927 Report
.Error (263, part
.Location
,
928 "Partial declarations of `{0}' must " +
929 "not specify different base classes",
932 if (!Location
.IsNull (parent_loc
))
933 Report
.LocationOfPreviousError (parent_loc
);
939 if ((parent
== null) && (new_parent
!= null)) {
941 parent_loc
= part
.Location
;
944 if (new_ifaces
== null)
947 foreach (TypeExpr iface
in new_ifaces
) {
949 foreach (TypeExpr old_iface
in ifaces
) {
950 if (old_iface
.Equals (iface
)) {
963 TypeExpr
[] retval
= new TypeExpr
[ifaces
.Count
];
964 ifaces
.CopyTo (retval
, 0);
968 TypeExpr
[] GetNormalBases (out TypeExpr parent
, out bool error
)
972 int count
= Bases
.Count
;
975 if (Kind
== Kind
.Class
){
976 TypeExpr name
= ResolveTypeExpr (
977 (Expression
) Bases
[0], false, Location
);
994 TypeExpr
[] ifaces
= new TypeExpr
[count
-start
];
996 for (i
= start
, j
= 0; i
< count
; i
++, j
++){
997 Expression name
= (Expression
) Bases
[i
];
998 TypeExpr resolved
= ResolveTypeExpr (name
, false, Location
);
999 if (resolved
== null) {
1004 ifaces
[j
] = resolved
;
1012 /// This function computes the Base class and also the
1013 /// list of interfaces that the class or struct @c implements.
1015 /// The return value is an array (might be null) of
1016 /// interfaces implemented (as Types).
1018 /// The @parent argument is set to the parent object or null
1019 /// if this is `System.Object'.
1021 TypeExpr
[] GetClassBases (out TypeExpr parent
, out bool error
)
1030 ifaces
= GetPartialBases (out parent
, out error
);
1031 else if (Bases
== null){
1035 ifaces
= GetNormalBases (out parent
, out error
);
1040 if ((parent
!= null) && (Kind
== Kind
.Class
)){
1041 if (parent
.IsSealed
){
1043 Report
.SymbolRelatedToPreviousError (parent
.Type
);
1044 if (parent
.Type
.IsAbstract
) {
1045 Report
.Error (709, Location
, "'{0}': Cannot derive from static class", GetSignatureForError ());
1047 Report
.Error (509, Location
, "'{0}': Cannot derive from sealed class", GetSignatureForError ());
1052 if (!parent
.CanInheritFrom ()){
1053 Report
.Error (644, Location
,
1054 "`{0}' cannot inherit from special class `{1}'",
1060 if (!parent
.AsAccessible (this, ModFlags
))
1061 Report
.Error (60, Location
,
1062 "Inconsistent accessibility: base class `" +
1063 parent
.Name
+ "' is less accessible than class `" +
1068 base_class_name
= parent
.Name
;
1073 int count
= ifaces
!= null ? ifaces
.Length
: 0;
1075 for (i
= 0; i
< count
; i
++) {
1076 TypeExpr iface
= (TypeExpr
) ifaces
[i
];
1078 if ((Kind
!= Kind
.Class
) && !iface
.IsInterface
){
1079 string what
= Kind
== Kind
.Struct
?
1080 "Struct" : "Interface";
1082 Report
.Error (527, Location
,
1083 "In {0} `{1}', type `{2}' is not "+
1084 "an interface", what
, Name
, iface
.Name
);
1089 if (iface
.IsClass
) {
1090 if (parent
!= null){
1091 Report
.Error (527, Location
,
1092 "In Class `{0}', `{1}' is not " +
1093 "an interface", Name
, iface
.Name
);
1099 for (int x
= 0; x
< i
; x
++) {
1100 if (iface
.Equals (ifaces
[x
])) {
1101 Report
.Error (528, Location
,
1102 "`{0}' is already listed in " +
1103 "interface list", iface
.Name
);
1109 if ((Kind
== Kind
.Interface
) &&
1110 !iface
.AsAccessible (Parent
, ModFlags
))
1111 Report
.Error (61, Location
,
1112 "Inconsistent accessibility: base " +
1113 "interface `{0}' is less accessible " +
1114 "than interface `{1}'", iface
.Name
,
1118 return TypeManager
.ExpandInterfaces (ifaces
);
1124 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1126 public override TypeBuilder
DefineType ()
1130 if (TypeBuilder
!= null)
1137 Report
.Error (146, Location
, "Class definition is circular: `{0}'", Name
);
1144 ec
= new EmitContext (this, Mono
.CSharp
.Location
.Null
, null, null, ModFlags
);
1146 ifaces
= GetClassBases (out parent
, out error
);
1150 if (parent
== null) {
1151 if (Kind
== Kind
.Class
){
1152 if (RootContext
.StdLib
)
1153 parent
= TypeManager
.system_object_expr
;
1154 else if (Name
!= "System.Object")
1155 parent
= TypeManager
.system_object_expr
;
1156 } else if (Kind
== Kind
.Struct
) {
1158 // If we are compiling our runtime,
1159 // and we are defining ValueType, then our
1160 // parent is `System.Object'.
1162 if (!RootContext
.StdLib
&& Name
== "System.ValueType")
1163 parent
= TypeManager
.system_object_expr
;
1165 parent
= TypeManager
.system_valuetype_expr
;
1169 if ((Kind
== Kind
.Struct
) && TypeManager
.value_type
== null)
1170 throw new Exception ();
1172 TypeAttributes type_attributes
= TypeAttr
;
1174 if (parent
!= null) {
1175 base_class_type
= parent
.ResolveType (ec
);
1176 if (base_class_type
== null) {
1184 if (TypeManager
.NamespaceClash (Name
, Location
)) {
1189 ModuleBuilder builder
= CodeGen
.Module
.Builder
;
1190 TypeBuilder
= builder
.DefineType (
1191 Name
, type_attributes
, base_class_type
, null);
1194 TypeBuilder builder
= Parent
.DefineType ();
1195 if (builder
== null)
1198 TypeBuilder
= builder
.DefineNestedType (
1199 Basename
, type_attributes
, base_class_type
, null);
1202 catch (ArgumentException
) {
1203 Report
.RuntimeMissingSupport (Location
, "static classes");
1208 // Structs with no fields need to have at least one byte.
1209 // The right thing would be to set the PackingSize in a DefineType
1210 // but there are no functions that allow interfaces *and* the size to
1214 if ((Kind
== Kind
.Struct
) && !have_nonstatic_fields
){
1215 TypeBuilder
.DefineField ("$PRIVATE$", TypeManager
.byte_type
,
1216 FieldAttributes
.Private
);
1219 // add interfaces that were not added at type creation
1220 if (ifaces
!= null) {
1221 base_inteface_types
= new Type
[ifaces
.Length
];
1222 for (int i
= 0; i
< ifaces
.Length
; ++i
) {
1223 Type itype
= ifaces
[i
].ResolveType (ec
);
1224 if (itype
== null) {
1228 TypeBuilder
.AddInterfaceImplementation (itype
);
1229 base_inteface_types
[i
] = itype
;
1237 // Finish the setup for the EmitContext
1239 ec
.ContainerType
= TypeBuilder
;
1241 TypeManager
.AddUserType (Name
, TypeBuilder
, this, ifaces
);
1243 if ((parent
!= null) && parent
.IsAttribute
) {
1244 RootContext
.RegisterAttribute (this);
1245 } else if (!(this is Iterator
))
1246 RootContext
.RegisterOrder (this);
1248 if (!DefineNestedTypes ()) {
1257 protected virtual bool DefineNestedTypes ()
1259 if (Interfaces
!= null) {
1260 foreach (TypeContainer iface
in Interfaces
)
1261 if (iface
.DefineType () == null)
1265 if (Types
!= null) {
1266 foreach (TypeContainer tc
in Types
)
1267 if (tc
.DefineType () == null)
1271 if (Delegates
!= null) {
1272 foreach (Delegate d
in Delegates
)
1273 if (d
.DefineType () == null)
1277 if (Enums
!= null) {
1278 foreach (Enum en
in Enums
)
1279 if (en
.DefineType () == null)
1283 if (Parts
!= null) {
1284 foreach (ClassPart part
in Parts
) {
1285 part
.TypeBuilder
= TypeBuilder
;
1286 part
.base_class_type
= base_class_type
;
1287 part
.ec
= new EmitContext (part
, Mono
.CSharp
.Location
.Null
, null, null, ModFlags
);
1294 static void Error_KeywordNotAllowed (Location loc
)
1296 Report
.Error (1530, loc
, "Keyword new not allowed for namespace elements");
1300 /// Populates our TypeBuilder with fields and methods
1302 public override bool DefineMembers (TypeContainer container
)
1304 if (members_defined
)
1305 return members_defined_ok
;
1307 members_defined_ok
= DoDefineMembers ();
1308 members_defined
= true;
1310 return members_defined_ok
;
1313 bool DoDefineMembers ()
1316 // We need to be able to use the member cache while we are checking/defining
1318 if (TypeBuilder
.BaseType
!= null)
1319 parent_container
= TypeManager
.LookupMemberContainer (TypeBuilder
.BaseType
);
1321 if (TypeBuilder
.IsInterface
)
1322 parent_container
= TypeManager
.LookupInterfaceContainer (base_inteface_types
);
1325 if ((ModFlags
& Modifiers
.NEW
) != 0)
1326 Error_KeywordNotAllowed (Location
);
1328 // HACK: missing implemenation
1329 // This is not fully functional. Better way how to handle this is to have recursive definition of containers
1330 // instead of flat as we have now.
1331 // Now we are not able to check inner attribute class because its parent had not been defined.
1333 // TODO: remove this if
1334 if (Parent
.MemberCache
!= null) {
1335 MemberInfo conflict_symbol
= Parent
.MemberCache
.FindMemberWithSameName (Basename
, false, TypeBuilder
);
1336 if (conflict_symbol
== null) {
1337 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0))
1338 Report
.Warning (109, Location
, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1340 if ((ModFlags
& Modifiers
.NEW
) == 0) {
1341 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
1342 Report
.Warning (108, Location
, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError ());
1348 DefineContainerMembers (constants
);
1349 DefineContainerMembers (fields
);
1351 if ((Kind
== Kind
.Class
) && !(this is ClassPart
) && !(this is StaticClass
)){
1352 if ((instance_constructors
== null) &&
1353 !(this is StaticClass
)) {
1354 if (default_constructor
== null)
1355 DefineDefaultConstructor (false);
1358 if (initialized_static_fields
!= null &&
1359 default_static_constructor
== null)
1360 DefineDefaultConstructor (true);
1363 if (Kind
== Kind
.Struct
){
1365 // Structs can not have initialized instance
1368 if (initialized_static_fields
!= null &&
1369 default_static_constructor
== null)
1370 DefineDefaultConstructor (true);
1372 if (initialized_fields
!= null)
1373 ReportStructInitializedInstanceError ();
1376 Pending
= GetPendingImplementations ();
1378 if (parts
!= null) {
1379 foreach (ClassPart part
in parts
) {
1380 if (!part
.DefineMembers (this))
1386 // Constructors are not in the defined_names array
1388 DefineContainerMembers (instance_constructors
);
1390 if (default_static_constructor
!= null)
1391 default_static_constructor
.Define ();
1393 DefineContainerMembers (properties
);
1394 DefineContainerMembers (events
);
1395 DefineContainerMembers (indexers
);
1396 DefineContainerMembers (methods
);
1397 DefineContainerMembers (operators
);
1398 DefineContainerMembers (enums
);
1399 DefineContainerMembers (delegates
);
1402 if (!(this is ClassPart
))
1403 member_cache
= new MemberCache (this, false);
1406 if (parts
!= null) {
1407 foreach (ClassPart part
in parts
)
1408 part
.member_cache
= member_cache
;
1411 if (iterators
!= null) {
1412 foreach (Iterator iterator
in iterators
) {
1413 if (iterator
.DefineType () == null)
1417 foreach (Iterator iterator
in iterators
) {
1418 if (!iterator
.DefineMembers (this))
1426 void ReportStructInitializedInstanceError ()
1428 string n
= TypeBuilder
.FullName
;
1430 foreach (Field f
in initialized_fields
){
1433 "`" + n
+ "." + f
.Name
+ "': can not have " +
1434 "instance field initializers in structs");
1438 protected virtual void DefineContainerMembers (MemberCoreArrayList mcal
)
1441 mcal
.DefineContainerMembers ();
1444 public override bool Define ()
1446 if (parts
!= null) {
1447 foreach (ClassPart part
in parts
) {
1448 if (!part
.Define ())
1456 public MemberInfo
FindMemberWithSameName (string name
, bool ignore_methods
)
1458 return ParentContainer
.MemberCache
.FindMemberWithSameName (name
, ignore_methods
, null);
1462 /// This function is based by a delegate to the FindMembers routine
1464 static bool AlwaysAccept (MemberInfo m
, object filterCriteria
)
1470 /// This filter is used by FindMembers, and we just keep
1471 /// a global for the filter to `AlwaysAccept'
1473 static MemberFilter accepting_filter
;
1476 static TypeContainer ()
1478 accepting_filter
= new MemberFilter (AlwaysAccept
);
1481 public MethodInfo
[] GetMethods ()
1483 ArrayList members
= new ArrayList ();
1485 DefineMembers (null);
1487 if (methods
!= null) {
1488 int len
= methods
.Count
;
1489 for (int i
= 0; i
< len
; i
++) {
1490 Method m
= (Method
) methods
[i
];
1492 members
.Add (m
.MethodBuilder
);
1496 if (operators
!= null) {
1497 int len
= operators
.Count
;
1498 for (int i
= 0; i
< len
; i
++) {
1499 Operator o
= (Operator
) operators
[i
];
1501 members
.Add (o
.OperatorMethodBuilder
);
1505 if (properties
!= null) {
1506 int len
= properties
.Count
;
1507 for (int i
= 0; i
< len
; i
++) {
1508 Property p
= (Property
) properties
[i
];
1510 if (p
.GetBuilder
!= null)
1511 members
.Add (p
.GetBuilder
);
1512 if (p
.SetBuilder
!= null)
1513 members
.Add (p
.SetBuilder
);
1517 if (indexers
!= null) {
1518 int len
= indexers
.Count
;
1519 for (int i
= 0; i
< len
; i
++) {
1520 Indexer ix
= (Indexer
) indexers
[i
];
1522 if (ix
.GetBuilder
!= null)
1523 members
.Add (ix
.GetBuilder
);
1524 if (ix
.SetBuilder
!= null)
1525 members
.Add (ix
.SetBuilder
);
1529 if (events
!= null) {
1530 int len
= events
.Count
;
1531 for (int i
= 0; i
< len
; i
++) {
1532 Event e
= (Event
) events
[i
];
1534 if (e
.AddBuilder
!= null)
1535 members
.Add (e
.AddBuilder
);
1536 if (e
.RemoveBuilder
!= null)
1537 members
.Add (e
.RemoveBuilder
);
1541 MethodInfo
[] retMethods
= new MethodInfo
[members
.Count
];
1542 members
.CopyTo (retMethods
, 0);
1546 // Indicated whether container has StructLayout attribute set Explicit
1547 public virtual bool HasExplicitLayout
{
1554 /// This method returns the members of this type just like Type.FindMembers would
1555 /// Only, we need to use this for types which are _being_ defined because MS'
1556 /// implementation can't take care of that.
1559 // FIXME: return an empty static array instead of null, that cleans up
1560 // some code and is consistent with some coding conventions I just found
1564 // Notice that in various cases we check if our field is non-null,
1565 // something that would normally mean that there was a bug elsewhere.
1567 // The problem happens while we are defining p-invoke methods, as those
1568 // will trigger a FindMembers, but this happens before things are defined
1570 // Since the whole process is a no-op, it is fine to check for null here.
1572 public override MemberList
FindMembers (MemberTypes mt
, BindingFlags bf
,
1573 MemberFilter filter
, object criteria
)
1575 ArrayList members
= null;
1578 if ((bf
& BindingFlags
.Public
) != 0)
1579 modflags
|= Modifiers
.PUBLIC
| Modifiers
.PROTECTED
|
1581 if ((bf
& BindingFlags
.NonPublic
) != 0)
1582 modflags
|= Modifiers
.PRIVATE
;
1584 int static_mask
= 0, static_flags
= 0;
1585 switch (bf
& (BindingFlags
.Static
| BindingFlags
.Instance
)) {
1586 case BindingFlags
.Static
:
1587 static_mask
= static_flags
= Modifiers
.STATIC
;
1590 case BindingFlags
.Instance
:
1591 static_mask
= Modifiers
.STATIC
;
1596 static_mask
= static_flags
= 0;
1600 Timer
.StartTimer (TimerType
.TcFindMembers
);
1603 filter
= accepting_filter
;
1605 if ((mt
& MemberTypes
.Field
) != 0) {
1606 if (fields
!= null) {
1607 int len
= fields
.Count
;
1608 for (int i
= 0; i
< len
; i
++) {
1609 Field f
= (Field
) fields
[i
];
1611 if ((f
.ModFlags
& modflags
) == 0)
1613 if ((f
.ModFlags
& static_mask
) != static_flags
)
1616 FieldBuilder fb
= f
.FieldBuilder
;
1617 if (fb
!= null && filter (fb
, criteria
) == true) {
1618 if (members
== null)
1619 members
= new ArrayList ();
1626 if (constants
!= null) {
1627 int len
= constants
.Count
;
1628 for (int i
= 0; i
< len
; i
++) {
1629 Const con
= (Const
) constants
[i
];
1631 if ((con
.ModFlags
& modflags
) == 0)
1633 if ((con
.ModFlags
& static_mask
) != static_flags
)
1636 FieldBuilder fb
= con
.FieldBuilder
;
1637 if (fb
!= null && filter (fb
, criteria
) == true) {
1638 if (members
== null)
1639 members
= new ArrayList ();
1647 if ((mt
& MemberTypes
.Method
) != 0) {
1648 if (methods
!= null) {
1649 int len
= methods
.Count
;
1650 for (int i
= 0; i
< len
; i
++) {
1651 Method m
= (Method
) methods
[i
];
1653 if ((m
.ModFlags
& modflags
) == 0)
1655 if ((m
.ModFlags
& static_mask
) != static_flags
)
1658 MethodBuilder mb
= m
.MethodBuilder
;
1660 if (mb
!= null && filter (mb
, criteria
) == true) {
1661 if (members
== null)
1662 members
= new ArrayList ();
1669 if (operators
!= null) {
1670 int len
= operators
.Count
;
1671 for (int i
= 0; i
< len
; i
++) {
1672 Operator o
= (Operator
) operators
[i
];
1674 if ((o
.ModFlags
& modflags
) == 0)
1676 if ((o
.ModFlags
& static_mask
) != static_flags
)
1679 MethodBuilder ob
= o
.OperatorMethodBuilder
;
1680 if (ob
!= null && filter (ob
, criteria
) == true) {
1681 if (members
== null)
1682 members
= new ArrayList ();
1689 if (properties
!= null) {
1690 int len
= properties
.Count
;
1691 for (int i
= 0; i
< len
; i
++) {
1692 Property p
= (Property
) properties
[i
];
1694 if ((p
.ModFlags
& modflags
) == 0)
1696 if ((p
.ModFlags
& static_mask
) != static_flags
)
1702 if (b
!= null && filter (b
, criteria
) == true) {
1703 if (members
== null)
1704 members
= new ArrayList ();
1710 if (b
!= null && filter (b
, criteria
) == true) {
1711 if (members
== null)
1712 members
= new ArrayList ();
1719 if (indexers
!= null) {
1720 int len
= indexers
.Count
;
1721 for (int i
= 0; i
< len
; i
++) {
1722 Indexer ix
= (Indexer
) indexers
[i
];
1724 if ((ix
.ModFlags
& modflags
) == 0)
1726 if ((ix
.ModFlags
& static_mask
) != static_flags
)
1732 if (b
!= null && filter (b
, criteria
) == true) {
1733 if (members
== null)
1734 members
= new ArrayList ();
1740 if (b
!= null && filter (b
, criteria
) == true) {
1741 if (members
== null)
1742 members
= new ArrayList ();
1750 if ((mt
& MemberTypes
.Event
) != 0) {
1751 if (events
!= null) {
1752 int len
= events
.Count
;
1753 for (int i
= 0; i
< len
; i
++) {
1754 Event e
= (Event
) events
[i
];
1756 if ((e
.ModFlags
& modflags
) == 0)
1758 if ((e
.ModFlags
& static_mask
) != static_flags
)
1761 MemberInfo eb
= e
.EventBuilder
;
1762 if (eb
!= null && filter (eb
, criteria
) == true) {
1763 if (members
== null)
1764 members
= new ArrayList ();
1766 members
.Add (e
.EventBuilder
);
1772 if ((mt
& MemberTypes
.Property
) != 0){
1773 if (properties
!= null) {
1774 int len
= properties
.Count
;
1775 for (int i
= 0; i
< len
; i
++) {
1776 Property p
= (Property
) properties
[i
];
1778 if ((p
.ModFlags
& modflags
) == 0)
1780 if ((p
.ModFlags
& static_mask
) != static_flags
)
1783 MemberInfo pb
= p
.PropertyBuilder
;
1784 if (pb
!= null && filter (pb
, criteria
) == true) {
1785 if (members
== null)
1786 members
= new ArrayList ();
1788 members
.Add (p
.PropertyBuilder
);
1793 if (indexers
!= null) {
1794 int len
= indexers
.Count
;
1795 for (int i
= 0; i
< len
; i
++) {
1796 Indexer ix
= (Indexer
) indexers
[i
];
1798 if ((ix
.ModFlags
& modflags
) == 0)
1800 if ((ix
.ModFlags
& static_mask
) != static_flags
)
1803 MemberInfo ib
= ix
.PropertyBuilder
;
1804 if (ib
!= null && filter (ib
, criteria
) == true) {
1805 if (members
== null)
1806 members
= new ArrayList ();
1808 members
.Add (ix
.PropertyBuilder
);
1814 if ((mt
& MemberTypes
.NestedType
) != 0) {
1815 if (types
!= null) {
1816 int len
= types
.Count
;
1817 for (int i
= 0; i
< len
; i
++) {
1818 TypeContainer t
= (TypeContainer
) types
[i
];
1820 if ((t
.ModFlags
& modflags
) == 0)
1823 TypeBuilder tb
= t
.TypeBuilder
;
1824 if (tb
!= null && (filter (tb
, criteria
) == true)) {
1825 if (members
== null)
1826 members
= new ArrayList ();
1833 if (enums
!= null) {
1834 int len
= enums
.Count
;
1835 for (int i
= 0; i
< len
; i
++) {
1836 Enum en
= (Enum
) enums
[i
];
1838 if ((en
.ModFlags
& modflags
) == 0)
1841 TypeBuilder tb
= en
.TypeBuilder
;
1842 if (tb
!= null && (filter (tb
, criteria
) == true)) {
1843 if (members
== null)
1844 members
= new ArrayList ();
1851 if (delegates
!= null) {
1852 int len
= delegates
.Count
;
1853 for (int i
= 0; i
< len
; i
++) {
1854 Delegate d
= (Delegate
) delegates
[i
];
1856 if ((d
.ModFlags
& modflags
) == 0)
1859 TypeBuilder tb
= d
.TypeBuilder
;
1860 if (tb
!= null && (filter (tb
, criteria
) == true)) {
1861 if (members
== null)
1862 members
= new ArrayList ();
1869 if (interfaces
!= null) {
1870 int len
= interfaces
.Count
;
1871 for (int i
= 0; i
< len
; i
++) {
1872 TypeContainer iface
= (TypeContainer
) interfaces
[i
];
1874 if ((iface
.ModFlags
& modflags
) == 0)
1877 TypeBuilder tb
= iface
.TypeBuilder
;
1878 if (tb
!= null && (filter (tb
, criteria
) == true)) {
1879 if (members
== null)
1880 members
= new ArrayList ();
1888 if ((mt
& MemberTypes
.Constructor
) != 0){
1889 if (((bf
& BindingFlags
.Instance
) != 0) && (instance_constructors
!= null)){
1890 int len
= instance_constructors
.Count
;
1891 for (int i
= 0; i
< len
; i
++) {
1892 Constructor c
= (Constructor
) instance_constructors
[i
];
1894 ConstructorBuilder cb
= c
.ConstructorBuilder
;
1895 if (cb
!= null && filter (cb
, criteria
) == true) {
1896 if (members
== null)
1897 members
= new ArrayList ();
1904 if (((bf
& BindingFlags
.Static
) != 0) && (default_static_constructor
!= null)){
1905 ConstructorBuilder cb
=
1906 default_static_constructor
.ConstructorBuilder
;
1908 if (cb
!= null && filter (cb
, criteria
) == true) {
1909 if (members
== null)
1910 members
= new ArrayList ();
1918 // Lookup members in parent if requested.
1920 if ((bf
& BindingFlags
.DeclaredOnly
) == 0) {
1921 if (TypeBuilder
.BaseType
!= null) {
1922 MemberList list
= FindMembers (TypeBuilder
.BaseType
, mt
, bf
, filter
, criteria
);
1923 if (list
.Count
> 0) {
1924 if (members
== null)
1925 members
= new ArrayList ();
1927 members
.AddRange (list
);
1930 if (base_inteface_types
!= null) {
1931 foreach (Type base_type
in base_inteface_types
) {
1932 MemberList list
= TypeContainer
.FindMembers (base_type
, mt
, bf
, filter
, criteria
);
1934 if (list
.Count
> 0) {
1935 if (members
== null)
1936 members
= new ArrayList ();
1937 members
.AddRange (list
);
1943 Timer
.StopTimer (TimerType
.TcFindMembers
);
1945 if (members
== null)
1946 return MemberList
.Empty
;
1948 return new MemberList (members
);
1951 public override MemberCache MemberCache
{
1953 return member_cache
;
1957 public static MemberList
FindMembers (Type t
, MemberTypes mt
, BindingFlags bf
,
1958 MemberFilter filter
, object criteria
)
1960 DeclSpace ds
= TypeManager
.LookupDeclSpace (t
);
1963 return ds
.FindMembers (mt
, bf
, filter
, criteria
);
1965 return new MemberList (t
.FindMembers (mt
, bf
, filter
, criteria
));
1970 // FindMethods will look for methods not only in the type `t', but in
1971 // any interfaces implemented by the type.
1973 public static MethodInfo
[] FindMethods (Type t
, BindingFlags bf
,
1974 MemberFilter filter
, object criteria
)
1980 /// Emits the values for the constants
1982 public void EmitConstants ()
1984 if (constants
!= null)
1985 foreach (Const con
in constants
)
1990 protected virtual void VerifyMembers (EmitContext ec
)
1993 // Check for internal or private fields that were never assigned
1995 if (RootContext
.WarningLevel
>= 3) {
1996 if (fields
!= null){
1997 foreach (Field f
in fields
) {
1998 if ((f
.ModFlags
& Modifiers
.Accessibility
) != Modifiers
.PRIVATE
)
2001 if ((f
.status
& Field
.Status
.USED
) == 0){
2002 Report
.Warning (169, f
.Location
, "The private field '{0}' is never used", f
.GetSignatureForError ());
2007 // Only report 649 on level 4
2009 if (RootContext
.WarningLevel
< 4)
2012 if ((f
.status
& Field
.Status
.ASSIGNED
) != 0)
2015 Report
.Warning (649, f
.Location
, "Field '{0}' is never assigned to, and will always have its default value '{1}'", f
.GetSignatureForError (), "");
2022 /// Emits the code, this step is performed after all
2023 /// the types, enumerations, constructors
2025 public void EmitType ()
2027 if (OptAttributes
!= null)
2028 OptAttributes
.Emit (ec
, this);
2032 if (instance_constructors
!= null) {
2033 if (TypeBuilder
.IsSubclassOf (TypeManager
.attribute_type
) && RootContext
.VerifyClsCompliance
&& IsClsCompliaceRequired (this)) {
2034 bool has_compliant_args
= false;
2036 foreach (Constructor c
in instance_constructors
) {
2039 if (has_compliant_args
)
2042 has_compliant_args
= c
.HasCompliantArgs
;
2044 if (!has_compliant_args
)
2045 Report
.Error (3015, Location
, "'{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2047 foreach (Constructor c
in instance_constructors
)
2054 if (default_static_constructor
!= null)
2055 default_static_constructor
.Emit ();
2057 if (methods
!= null)
2058 foreach (Method m
in methods
)
2061 if (operators
!= null)
2062 foreach (Operator o
in operators
)
2065 if (properties
!= null)
2066 foreach (Property p
in properties
)
2069 if (indexers
!= null){
2074 foreach (Field f
in fields
)
2077 if (events
!= null){
2078 foreach (Event e
in Events
)
2082 if (delegates
!= null) {
2083 foreach (Delegate d
in Delegates
) {
2088 if (enums
!= null) {
2089 foreach (Enum e
in enums
) {
2094 if (parts
!= null) {
2095 foreach (ClassPart part
in parts
)
2099 if ((Pending
!= null) && !(this is ClassPart
))
2100 if (Pending
.VerifyPendingMethods ())
2105 if (iterators
!= null)
2106 foreach (Iterator iterator
in iterators
)
2107 iterator
.EmitType ();
2109 // if (types != null)
2110 // foreach (TypeContainer tc in types)
2114 public override void CloseType ()
2116 if ((caching_flags
& Flags
.CloseTypeCreated
) != 0)
2120 caching_flags
|= Flags
.CloseTypeCreated
;
2121 TypeBuilder
.CreateType ();
2122 } catch (TypeLoadException
){
2124 // This is fine, the code still created the type
2126 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2127 // Console.WriteLine (e.Message);
2129 Console
.WriteLine ("In type: " + Name
);
2134 foreach (Enum en
in Enums
)
2138 foreach (TypeContainer tc
in Types
)
2139 if (tc
.Kind
== Kind
.Struct
)
2142 foreach (TypeContainer tc
in Types
)
2143 if (tc
.Kind
!= Kind
.Struct
)
2147 if (Delegates
!= null)
2148 foreach (Delegate d
in Delegates
)
2151 if (Iterators
!= null)
2152 foreach (Iterator i
in Iterators
)
2160 initialized_fields
= null;
2161 initialized_static_fields
= null;
2170 default_constructor
= null;
2171 default_static_constructor
= null;
2173 OptAttributes
= null;
2175 parent_container
= null;
2176 member_cache
= null;
2179 // TODO: make it obsolete and use GetSignatureForError
2180 public string MakeName (string n
)
2182 return "`" + Name
+ "." + n
+ "'";
2186 // Performs the validation on a Method's modifiers (properties have
2187 // the same properties).
2189 public bool MethodModifiersValid (int flags
, string n
, Location loc
)
2191 const int vao
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
| Modifiers
.OVERRIDE
);
2192 const int va
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
);
2193 const int nv
= (Modifiers
.NEW
| Modifiers
.VIRTUAL
);
2197 // At most one of static, virtual or override
2199 if ((flags
& Modifiers
.STATIC
) != 0){
2200 if ((flags
& vao
) != 0){
2202 112, loc
, "static method " + MakeName (n
) + "can not be marked " +
2203 "as virtual, abstract or override");
2208 if (Kind
== Kind
.Struct
){
2209 if ((flags
& va
) != 0){
2210 Modifiers
.Error_InvalidModifier (loc
, "virtual or abstract");
2215 if ((flags
& Modifiers
.OVERRIDE
) != 0 && (flags
& nv
) != 0){
2217 113, loc
, MakeName (n
) +
2218 " marked as override cannot be marked as new or virtual");
2223 // If the declaration includes the abstract modifier, then the
2224 // declaration does not include static, virtual or extern
2226 if ((flags
& Modifiers
.ABSTRACT
) != 0){
2227 if ((flags
& Modifiers
.EXTERN
) != 0){
2229 180, loc
, MakeName (n
) + " can not be both abstract and extern");
2233 if ((flags
& Modifiers
.VIRTUAL
) != 0){
2235 503, loc
, MakeName (n
) + " can not be both abstract and virtual");
2239 if ((ModFlags
& Modifiers
.ABSTRACT
) == 0){
2241 513, loc
, MakeName (n
) +
2242 " is abstract but its container class is not");
2248 if ((flags
& Modifiers
.PRIVATE
) != 0){
2249 if ((flags
& vao
) != 0){
2251 621, loc
, MakeName (n
) +
2252 " virtual or abstract members can not be private");
2257 if ((flags
& Modifiers
.SEALED
) != 0){
2258 if ((flags
& Modifiers
.OVERRIDE
) == 0){
2260 238, loc
, MakeName (n
) +
2261 " cannot be sealed because it is not an override");
2269 public bool UserDefinedStaticConstructor
{
2271 return default_static_constructor
!= null;
2275 protected override bool VerifyClsCompliance (DeclSpace ds
)
2277 if (!base.VerifyClsCompliance (ds
))
2282 // parent_container is null for System.Object
2283 if (parent_container
!= null && !AttributeTester
.IsClsCompliant (parent_container
.Type
)) {
2284 Report
.Error (3009, Location
, "'{0}': base type '{1}' is not CLS-compliant", GetSignatureForError (), TypeManager
.CSharpName (parent_container
.Type
));
2291 /// Checks whether container name is CLS Compliant
2293 void VerifyClsName ()
2295 Hashtable parent_members
= parent_container
== null ?
2297 parent_container
.MemberCache
.GetPublicMembers ();
2298 Hashtable this_members
= new Hashtable ();
2300 foreach (DictionaryEntry entry
in defined_names
) {
2301 MemberCore mc
= (MemberCore
)entry
.Value
;
2302 if (!mc
.IsClsCompliaceRequired (this))
2305 string name
= (string)entry
.Key
;
2306 string basename
= name
.Substring (name
.LastIndexOf ('.') + 1);
2308 string lcase
= basename
.ToLower (System
.Globalization
.CultureInfo
.InvariantCulture
);
2309 object found
= parent_members
[lcase
];
2310 if (found
== null) {
2311 found
= this_members
[lcase
];
2312 if (found
== null) {
2313 this_members
.Add (lcase
, mc
);
2318 if ((mc
.ModFlags
& Modifiers
.OVERRIDE
) != 0)
2321 if (found
is MemberInfo
) {
2322 if (basename
== ((MemberInfo
)found
).Name
)
2324 Report
.SymbolRelatedToPreviousError ((MemberInfo
)found
);
2326 Report
.SymbolRelatedToPreviousError ((MemberCore
) found
);
2328 Report
.Error (3005, mc
.Location
, "Identifier '{0}' differing only in case is not CLS-compliant", mc
.GetSignatureForError ());
2334 /// Performs checks for an explicit interface implementation. First it
2335 /// checks whether the `interface_type' is a base inteface implementation.
2336 /// Then it checks whether `name' exists in the interface type.
2338 public virtual bool VerifyImplements (Type interface_type
, string full
,
2339 string name
, Location loc
)
2343 if (ifaces
!= null){
2344 foreach (TypeExpr t
in ifaces
){
2345 if (t
.Type
== interface_type
){
2353 Report
.Error (540, "`" + full
+ "': containing class does not implement interface `" + interface_type
.FullName
+ "'");
2360 protected override void VerifyObsoleteAttribute()
2362 CheckUsageOfObsoleteAttribute (base_class_type
);
2367 foreach (TypeExpr expr
in ifaces
) {
2368 CheckUsageOfObsoleteAttribute (expr
.Type
);
2377 string IMemberContainer
.Name
{
2383 Type IMemberContainer
.Type
{
2389 MemberCache IMemberContainer
.MemberCache
{
2391 return member_cache
;
2395 bool IMemberContainer
.IsInterface
{
2397 return Kind
== Kind
.Interface
;
2401 MemberList IMemberContainer
.GetMembers (MemberTypes mt
, BindingFlags bf
)
2403 return FindMembers (mt
, bf
| BindingFlags
.DeclaredOnly
, null, null);
2406 public virtual IMemberContainer ParentContainer
{
2408 return parent_container
;
2413 public class PartialContainer
: TypeContainer
{
2415 public readonly Namespace Namespace
;
2416 public readonly int OriginalModFlags
;
2417 public readonly int AllowedModifiers
;
2418 public readonly TypeAttributes DefaultTypeAttributes
;
2420 static PartialContainer
Create (NamespaceEntry ns
, TypeContainer parent
,
2421 MemberName name
, int mod_flags
, Kind kind
,
2424 PartialContainer pc
;
2425 string full_name
= name
.GetName (true);
2426 DeclSpace ds
= (DeclSpace
) RootContext
.Tree
.Decls
[full_name
];
2428 pc
= ds
as PartialContainer
;
2432 260, ds
.Location
, "Missing partial modifier " +
2433 "on declaration of type `{0}'; another " +
2434 "partial implementation of this type exists",
2437 Report
.LocationOfPreviousError (loc
);
2441 if (pc
.Kind
!= kind
) {
2443 261, loc
, "Partial declarations of `{0}' " +
2444 "must be all classes, all structs or " +
2445 "all interfaces", name
);
2449 if (pc
.OriginalModFlags
!= mod_flags
) {
2451 262, loc
, "Partial declarations of `{0}' " +
2452 "have conflicting accessibility modifiers",
2460 pc
= new PartialContainer (ns
, parent
, name
, mod_flags
, kind
, loc
);
2461 RootContext
.Tree
.RecordDecl (full_name
, pc
);
2462 parent
.AddType (pc
);
2467 public static ClassPart
CreatePart (NamespaceEntry ns
, TypeContainer parent
,
2468 MemberName name
, int mod
, Attributes attrs
,
2469 Kind kind
, Location loc
)
2471 PartialContainer pc
= Create (ns
, parent
, name
, mod
, kind
, loc
);
2473 // An error occured; create a dummy container, but don't
2475 pc
= new PartialContainer (ns
, parent
, name
, mod
, kind
, loc
);
2478 ClassPart part
= new ClassPart (ns
, pc
, mod
, attrs
, kind
, loc
);
2483 protected PartialContainer (NamespaceEntry ns
, TypeContainer parent
,
2484 MemberName name
, int mod
, Kind kind
, Location l
)
2485 : base (ns
, parent
, name
, null, kind
, l
)
2487 this.Namespace
= ns
.NS
;
2491 AllowedModifiers
= Class
.AllowedModifiers
;
2492 DefaultTypeAttributes
= Class
.DefaultTypeAttributes
;
2496 AllowedModifiers
= Struct
.AllowedModifiers
;
2497 DefaultTypeAttributes
= Struct
.DefaultTypeAttributes
;
2500 case Kind
.Interface
:
2501 AllowedModifiers
= Interface
.AllowedModifiers
;
2502 DefaultTypeAttributes
= Interface
.DefaultTypeAttributes
;
2506 throw new InvalidOperationException ();
2510 if (parent
.Parent
== null)
2511 accmods
= Modifiers
.INTERNAL
;
2513 accmods
= Modifiers
.PRIVATE
;
2515 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, l
);
2516 this.OriginalModFlags
= mod
;
2519 public override void Register ()
2521 if (Kind
== Kind
.Interface
)
2522 Parent
.AddInterface (this);
2523 else if (Kind
== Kind
.Class
|| Kind
== Kind
.Struct
)
2524 Parent
.AddClassOrStruct (this);
2526 throw new InvalidOperationException ();
2529 public override PendingImplementation
GetPendingImplementations ()
2531 return PendingImplementation
.GetPendingImplementations (this);
2534 public ClassPart
AddPart (NamespaceEntry ns
, int mod
, Attributes attrs
,
2537 ClassPart part
= new ClassPart (ns
, this, mod
, attrs
, Kind
, l
);
2542 public override TypeAttributes TypeAttr
{
2544 return base.TypeAttr
| DefaultTypeAttributes
;
2549 public class ClassPart
: TypeContainer
, IMemberContainer
{
2550 public readonly PartialContainer PartialContainer
;
2551 public readonly bool IsPartial
;
2553 public ClassPart (NamespaceEntry ns
, PartialContainer parent
,
2554 int mod
, Attributes attrs
, Kind kind
, Location l
)
2555 : base (ns
, parent
.Parent
, parent
.MemberName
, attrs
, kind
, l
)
2557 this.PartialContainer
= parent
;
2558 this.IsPartial
= true;
2561 if (parent
.Parent
== null)
2562 accmods
= Modifiers
.INTERNAL
;
2564 accmods
= Modifiers
.PRIVATE
;
2566 this.ModFlags
= Modifiers
.Check (
2567 parent
.AllowedModifiers
, mod
, accmods
, l
);
2570 public override void Register ()
2574 public override PendingImplementation
GetPendingImplementations ()
2576 return PartialContainer
.Pending
;
2579 public override bool VerifyImplements (Type interface_type
, string full
,
2580 string name
, Location loc
)
2582 return PartialContainer
.VerifyImplements (
2583 interface_type
, full
, name
, loc
);
2586 public override IMemberContainer ParentContainer
{
2588 return PartialContainer
.ParentContainer
;
2593 public abstract class ClassOrStruct
: TypeContainer
{
2594 bool hasExplicitLayout
= false;
2595 ListDictionary declarative_security
;
2597 public ClassOrStruct (NamespaceEntry ns
, TypeContainer parent
,
2598 MemberName name
, Attributes attrs
, Kind kind
,
2600 : base (ns
, parent
, name
, attrs
, kind
, l
)
2604 public override PendingImplementation
GetPendingImplementations ()
2606 return PendingImplementation
.GetPendingImplementations (this);
2609 public override bool HasExplicitLayout
{
2611 return hasExplicitLayout
;
2615 protected override void VerifyMembers (EmitContext ec
)
2617 base.VerifyMembers (ec
);
2619 if ((events
!= null) && (RootContext
.WarningLevel
>= 3)) {
2620 foreach (Event e
in events
){
2622 Report
.Warning (67, e
.Location
, "The event '{0}' is never used", e
.GetSignatureForError ());
2627 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
2629 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
2630 if (declarative_security
== null)
2631 declarative_security
= new ListDictionary ();
2633 a
.ExtractSecurityPermissionSet (declarative_security
);
2637 if (a
.Type
== TypeManager
.struct_layout_attribute_type
2638 && (LayoutKind
) a
.GetPositionalValue (0) == LayoutKind
.Explicit
)
2639 hasExplicitLayout
= true;
2641 base.ApplyAttributeBuilder (a
, cb
);
2644 public override void Emit()
2648 if (declarative_security
!= null) {
2649 foreach (DictionaryEntry de
in declarative_security
) {
2650 TypeBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
2655 public override void Register ()
2657 Parent
.AddClassOrStruct (this);
2662 /// Class handles static classes declaration
2664 public sealed class StaticClass
: Class
{
2665 public StaticClass (NamespaceEntry ns
, TypeContainer parent
, MemberName name
, int mod
,
2666 Attributes attrs
, Location l
)
2667 : base (ns
, parent
, name
, mod
& ~Modifiers
.STATIC
, attrs
, l
)
2669 if (RootContext
.Version
== LanguageVersion
.ISO_1
) {
2670 Report
.FeatureIsNotStandardized (l
, "static classes");
2671 Environment
.Exit (1);
2675 protected override void DefineContainerMembers (MemberCoreArrayList list
)
2680 foreach (MemberCore m
in list
) {
2681 if (m
is Operator
) {
2682 Report
.Error (715, m
.Location
, "'{0}': static classes cannot contain user-defined operators", m
.GetSignatureForError (this));
2686 if ((m
.ModFlags
& Modifiers
.STATIC
) != 0)
2689 if (m
is Constructor
) {
2690 Report
.Error (710, m
.Location
, "'{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2694 if (m
is Destructor
) {
2695 Report
.Error (711, m
.Location
, "'{0}': Static class cannot contain destructor", GetSignatureForError ());
2699 Report
.Error (708, m
.Location
, "'{0}': cannot declare instance members in a static class", m
.GetSignatureForError (this));
2702 base.DefineContainerMembers (list
);
2705 public override TypeBuilder
DefineType()
2707 TypeBuilder tb
= base.DefineType ();
2711 if (base_class_type
!= TypeManager
.object_type
) {
2712 Report
.Error (713, Location
, "Static class '{0}' cannot derive from type '{1}'. Static classes must derive from object", GetSignatureForError (), TypeManager
.CSharpName (base_class_type
));
2716 if (base_inteface_types
!= null) {
2717 foreach (Type t
in base_inteface_types
)
2718 Report
.SymbolRelatedToPreviousError (t
);
2719 Report
.Error (714, Location
, "'{0}': static classes cannot implement interfaces", GetSignatureForError ());
2724 public override TypeAttributes TypeAttr
{
2726 return base.TypeAttr
| TypeAttributes
.Abstract
| TypeAttributes
.Sealed
;
2731 public class Class
: ClassOrStruct
{
2733 // Modifiers allowed in a class declaration
2735 public const int AllowedModifiers
=
2738 Modifiers
.PROTECTED
|
2739 Modifiers
.INTERNAL
|
2741 Modifiers
.ABSTRACT
|
2745 // Information in the case we are an attribute type
2746 AttributeUsageAttribute attribute_usage
;
2748 public Class (NamespaceEntry ns
, TypeContainer parent
, MemberName name
, int mod
,
2749 Attributes attrs
, Location l
)
2750 : base (ns
, parent
, name
, attrs
, Kind
.Class
, l
)
2754 if (parent
.Parent
== null)
2755 accmods
= Modifiers
.INTERNAL
;
2757 accmods
= Modifiers
.PRIVATE
;
2759 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, l
);
2760 if ((ModFlags
& (Modifiers
.ABSTRACT
| Modifiers
.SEALED
)) == (Modifiers
.ABSTRACT
| Modifiers
.SEALED
)) {
2761 Report
.Error (502, Location
, "'{0}' cannot be both abstract and sealed", GetSignatureForError ());
2764 attribute_usage
= new AttributeUsageAttribute (AttributeTargets
.All
);
2767 public override AttributeTargets AttributeTargets
{
2769 return AttributeTargets
.Class
;
2773 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
2775 if (a
.UsageAttribute
!= null) {
2776 if (base_class_type
!= TypeManager
.attribute_type
&& !base_class_type
.IsSubclassOf (TypeManager
.attribute_type
) &&
2777 TypeBuilder
.FullName
!= "System.Attribute") {
2778 Report
.Error (641, a
.Location
, "Attribute '{0}' is only valid on classes derived from System.Attribute", a
.Name
);
2780 attribute_usage
= a
.UsageAttribute
;
2783 base.ApplyAttributeBuilder (a
, cb
);
2786 public AttributeUsageAttribute AttributeUsage
{
2788 return attribute_usage
;
2792 public const TypeAttributes DefaultTypeAttributes
=
2793 TypeAttributes
.AutoLayout
| TypeAttributes
.Class
;
2796 // FIXME: How do we deal with the user specifying a different
2799 public override TypeAttributes TypeAttr
{
2801 return base.TypeAttr
| DefaultTypeAttributes
;
2806 public class Struct
: ClassOrStruct
{
2808 // Modifiers allowed in a struct declaration
2810 public const int AllowedModifiers
=
2813 Modifiers
.PROTECTED
|
2814 Modifiers
.INTERNAL
|
2818 public Struct (NamespaceEntry ns
, TypeContainer parent
, MemberName name
,
2819 int mod
, Attributes attrs
, Location l
)
2820 : base (ns
, parent
, name
, attrs
, Kind
.Struct
, l
)
2824 if (parent
.Parent
== null)
2825 accmods
= Modifiers
.INTERNAL
;
2827 accmods
= Modifiers
.PRIVATE
;
2829 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, l
);
2831 this.ModFlags
|= Modifiers
.SEALED
;
2834 public override AttributeTargets AttributeTargets
{
2836 return AttributeTargets
.Struct
;
2840 public const TypeAttributes DefaultTypeAttributes
=
2841 TypeAttributes
.SequentialLayout
|
2842 TypeAttributes
.Sealed
|
2843 TypeAttributes
.BeforeFieldInit
;
2846 // FIXME: Allow the user to specify a different set of attributes
2847 // in some cases (Sealed for example is mandatory for a class,
2848 // but what SequentialLayout can be changed
2850 public override TypeAttributes TypeAttr
{
2852 return base.TypeAttr
| DefaultTypeAttributes
;
2860 public class Interface
: TypeContainer
, IMemberContainer
{
2862 /// Modifiers allowed in a class declaration
2864 public const int AllowedModifiers
=
2867 Modifiers
.PROTECTED
|
2868 Modifiers
.INTERNAL
|
2872 public Interface (NamespaceEntry ns
, TypeContainer parent
, MemberName name
, int mod
,
2873 Attributes attrs
, Location l
)
2874 : base (ns
, parent
, name
, attrs
, Kind
.Interface
, l
)
2878 if (parent
.Parent
== null)
2879 accmods
= Modifiers
.INTERNAL
;
2881 accmods
= Modifiers
.PRIVATE
;
2883 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, l
);
2886 public override void Register ()
2888 Parent
.AddInterface (this);
2891 public override PendingImplementation
GetPendingImplementations ()
2896 public override AttributeTargets AttributeTargets
{
2898 return AttributeTargets
.Interface
;
2902 public const TypeAttributes DefaultTypeAttributes
=
2903 TypeAttributes
.AutoLayout
|
2904 TypeAttributes
.Abstract
|
2905 TypeAttributes
.Interface
;
2907 public override TypeAttributes TypeAttr
{
2909 return base.TypeAttr
| DefaultTypeAttributes
;
2914 public abstract class MethodCore
: MemberBase
{
2915 public readonly Parameters Parameters
;
2916 protected ToplevelBlock block
;
2919 // Parameters, cached for semantic analysis.
2921 protected InternalParameters parameter_info
;
2922 protected Type
[] parameter_types
;
2924 // Whether this is an operator method.
2925 public bool IsOperator
;
2928 // The method we're overriding if this is an override method.
2930 protected MethodInfo parent_method
= null;
2932 static string[] attribute_targets
= new string [] { "method", "return" }
;
2934 public MethodCore (TypeContainer parent
, Expression type
, int mod
,
2935 int allowed_mod
, bool is_interface
, MemberName name
,
2936 Attributes attrs
, Parameters parameters
, Location loc
)
2937 : base (parent
, type
, mod
, allowed_mod
, Modifiers
.PRIVATE
, name
,
2940 Parameters
= parameters
;
2941 IsInterface
= is_interface
;
2945 // Returns the System.Type array for the parameters of this method
2947 public Type
[] ParameterTypes
{
2949 return parameter_types
;
2953 public InternalParameters ParameterInfo
2956 return parameter_info
;
2960 public ToplevelBlock Block
{
2970 protected override bool CheckBase ()
2972 if (!base.CheckBase ())
2975 // Check whether arguments were correct.
2976 if (!DoDefineParameters ())
2979 if ((caching_flags
& Flags
.TestMethodDuplication
) != 0 && !CheckForDuplications ())
2985 // Is null for System.Object while compiling corlib and base interfaces
2986 if (Parent
.ParentContainer
== null) {
2987 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0)) {
2988 Report
.Warning (109, Location
, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent
));
2993 Type parent_ret_type
= null;
2994 parent_method
= FindOutParentMethod (Parent
, ref parent_ret_type
);
2996 // method is override
2997 if (parent_method
!= null) {
2999 if (!CheckMethodAgainstBase ())
3002 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3003 if (MemberType
!= TypeManager
.TypeToCoreType (parent_ret_type
)) {
3004 Report
.SymbolRelatedToPreviousError (parent_method
);
3005 Report
.Error (508, Location
, GetSignatureForError (Parent
) + ": cannot " +
3006 "change return type when overriding inherited member");
3010 if (parent_method
.IsAbstract
&& !IsInterface
) {
3011 Report
.SymbolRelatedToPreviousError (parent_method
);
3012 Report
.Error (533, Location
, "'{0}' hides inherited abstract member", GetSignatureForError (Parent
));
3017 if (parent_method
.IsSpecialName
&& !(this is PropertyBase
)) {
3018 Report
.Error (561, Location
, "'{0}': cannot override '{1}' because it is a special compiler-generated method", GetSignatureForError (Parent
), TypeManager
.GetFullNameSignature (parent_method
));
3022 if (RootContext
.WarningLevel
> 2) {
3023 if (Name
== "Equals" && parameter_types
.Length
== 1 && parameter_types
[0] == TypeManager
.object_type
)
3024 Parent
.Methods
.HasEquals
= true;
3025 else if (Name
== "GetHashCode" && parameter_types
.Length
== 0)
3026 Parent
.Methods
.HasGetHashCode
= true;
3029 ObsoleteAttribute oa
= AttributeTester
.GetMethodObsoleteAttribute (parent_method
);
3031 EmitContext ec
= new EmitContext (this.Parent
, this.Parent
, Location
, null, null, ModFlags
, false);
3032 if (OptAttributes
== null || !OptAttributes
.Contains (TypeManager
.obsolete_attribute_type
, ec
)) {
3033 Report
.SymbolRelatedToPreviousError (parent_method
);
3034 Report
.Warning (672, 1, Location
, "Member '{0}' overrides obsolete member. Add the Obsolete attribute to '{0}'", GetSignatureForError (Parent
));
3040 MemberInfo conflict_symbol
= Parent
.FindMemberWithSameName (Name
, !(this is Property
));
3041 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3042 if (conflict_symbol
!= null) {
3043 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
3044 if (this is PropertyBase
)
3045 Report
.Error (544, Location
, "'{0}': cannot override because '{1}' is not a property", GetSignatureForError (Parent
), TypeManager
.GetFullNameSignature (conflict_symbol
));
3047 Report
.Error (505, Location
, "'{0}': cannot override because '{1}' is not a method", GetSignatureForError (Parent
), TypeManager
.GetFullNameSignature (conflict_symbol
));
3049 Report
.Error (115, Location
, "'{0}': no suitable methods found to override", GetSignatureForError (Parent
));
3053 if (conflict_symbol
== null) {
3054 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0)) {
3055 Report
.Warning (109, Location
, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent
));
3060 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3061 if (this is Method
&& conflict_symbol
is MethodBase
)
3064 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
3065 Report
.Warning (108, Location
, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent
));
3073 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3074 // that have been defined.
3076 // `name' is the user visible name for reporting errors (this is used to
3077 // provide the right name regarding method names and properties)
3079 bool CheckMethodAgainstBase ()
3083 // TODO: replace with GetSignatureForError
3084 string name
= parent_method
.DeclaringType
.Name
+ "." + parent_method
.Name
;
3086 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0){
3087 if (!(parent_method
.IsAbstract
|| parent_method
.IsVirtual
)){
3089 506, Location
, Parent
.MakeName (Name
) +
3090 ": cannot override inherited member `" +
3091 name
+ "' because it is not " +
3092 "virtual, abstract or override");
3096 // Now we check that the overriden method is not final
3098 if (parent_method
.IsFinal
) {
3099 // This happens when implementing interface methods.
3100 if (parent_method
.IsHideBySig
&& parent_method
.IsVirtual
) {
3102 506, Location
, Parent
.MakeName (Name
) +
3103 ": cannot override inherited member `" +
3104 name
+ "' because it is not " +
3105 "virtual, abstract or override");
3107 Report
.Error (239, Location
, Parent
.MakeName (Name
) + " : cannot " +
3108 "override inherited member `" + name
+
3109 "' because it is sealed.");
3113 // Check that the permissions are not being changed
3115 MethodAttributes thisp
= flags
& MethodAttributes
.MemberAccessMask
;
3116 MethodAttributes parentp
= parent_method
.Attributes
& MethodAttributes
.MemberAccessMask
;
3119 // special case for "protected internal"
3122 if ((parentp
& MethodAttributes
.FamORAssem
) == MethodAttributes
.FamORAssem
){
3124 // when overriding protected internal, the method can be declared
3125 // protected internal only within the same assembly
3128 if ((thisp
& MethodAttributes
.FamORAssem
) == MethodAttributes
.FamORAssem
){
3129 if (Parent
.TypeBuilder
.Assembly
!= parent_method
.DeclaringType
.Assembly
){
3131 // assemblies differ - report an error
3134 Error_CannotChangeAccessModifiers (Parent
, parent_method
, name
);
3136 } else if (thisp
!= parentp
) {
3138 // same assembly, but other attributes differ - report an error
3141 Error_CannotChangeAccessModifiers (Parent
, parent_method
, name
);
3144 } else if ((thisp
& MethodAttributes
.Family
) != MethodAttributes
.Family
) {
3146 // if it's not "protected internal", it must be "protected"
3149 Error_CannotChangeAccessModifiers (Parent
, parent_method
, name
);
3151 } else if (Parent
.TypeBuilder
.Assembly
== parent_method
.DeclaringType
.Assembly
) {
3153 // protected within the same assembly - an error
3155 Error_CannotChangeAccessModifiers (Parent
, parent_method
, name
);
3157 } else if ((thisp
& ~
(MethodAttributes
.Family
| MethodAttributes
.FamORAssem
)) !=
3158 (parentp
& ~
(MethodAttributes
.Family
| MethodAttributes
.FamORAssem
))) {
3160 // protected ok, but other attributes differ - report an error
3162 Error_CannotChangeAccessModifiers (Parent
, parent_method
, name
);
3166 if (thisp
!= parentp
){
3167 Error_CannotChangeAccessModifiers (Parent
, parent_method
, name
);
3173 if ((ModFlags
& (Modifiers
.NEW
| Modifiers
.OVERRIDE
)) == 0 && Name
!= "Finalize") {
3174 ModFlags
|= Modifiers
.NEW
;
3175 Report
.SymbolRelatedToPreviousError (parent_method
);
3176 if (!IsInterface
&& (parent_method
.IsVirtual
|| parent_method
.IsAbstract
)) {
3177 if (RootContext
.WarningLevel
>= 2)
3178 Report
.Warning (114, Location
, "'{0}' hides inherited member '{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword", GetSignatureForError (Parent
), TypeManager
.CSharpSignature (parent_method
));
3180 Report
.Warning (108, Location
, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent
));
3186 void Error_CannotChangeAccessModifiers (TypeContainer parent
, MethodInfo parent_method
, string name
)
3189 // FIXME: report the old/new permissions?
3192 507, Location
, parent
.MakeName (Name
) +
3193 ": can't change the access modifiers when overriding inherited " +
3194 "member `" + name
+ "'");
3197 protected static string Error722
{
3199 return "'{0}': static types cannot be used as return types";
3204 /// For custom member duplication search in a container
3206 protected abstract bool CheckForDuplications ();
3209 /// Gets parent method and its return type
3211 protected abstract MethodInfo
FindOutParentMethod (TypeContainer container
, ref Type parent_ret_type
);
3213 protected virtual bool DoDefineParameters ()
3215 EmitContext ec
= Parent
.EmitContext
;
3217 throw new InternalErrorException ("DoDefineParameters invoked too early");
3219 bool old_unsafe
= ec
.InUnsafe
;
3220 ec
.InUnsafe
= InUnsafe
;
3221 // Check if arguments were correct
3222 parameter_types
= Parameters
.GetParameterInfo (ec
);
3223 ec
.InUnsafe
= old_unsafe
;
3225 if ((parameter_types
== null) ||
3226 !CheckParameters (Parent
, parameter_types
))
3229 parameter_info
= new InternalParameters (parameter_types
, Parameters
);
3231 Parameter array_param
= Parameters
.ArrayParameter
;
3232 if ((array_param
!= null) &&
3233 (!array_param
.ParameterType
.IsArray
||
3234 (array_param
.ParameterType
.GetArrayRank () != 1))) {
3235 Report
.Error (225, Location
, "params parameter has to be a single dimensional array");
3242 public override string[] ValidAttributeTargets
{
3244 return attribute_targets
;
3248 protected override bool VerifyClsCompliance (DeclSpace ds
)
3250 if (!base.VerifyClsCompliance (ds
)) {
3251 if ((ModFlags
& Modifiers
.ABSTRACT
) != 0 && IsExposedFromAssembly (ds
) && ds
.IsClsCompliaceRequired (ds
)) {
3252 Report
.Error (3011, Location
, "'{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3257 if (Parameters
.HasArglist
) {
3258 Report
.Error (3000, Location
, "Methods with variable arguments are not CLS-compliant");
3261 if (!AttributeTester
.IsClsCompliant (MemberType
)) {
3262 Report
.Error (3002, Location
, "Return type of '{0}' is not CLS-compliant", GetSignatureForError ());
3265 AttributeTester
.AreParametersCompliant (Parameters
.FixedParameters
, Location
);
3270 protected bool IsDuplicateImplementation (MethodCore method
)
3272 if ((method
== this) || (method
.Name
!= Name
))
3275 Type
[] param_types
= method
.ParameterTypes
;
3276 if (param_types
== null)
3279 if (param_types
.Length
!= ParameterTypes
.Length
)
3282 for (int i
= 0; i
< param_types
.Length
; i
++)
3283 if (param_types
[i
] != ParameterTypes
[i
])
3286 // TODO: make operator compatible with MethodCore to avoid this
3287 if (this is Operator
&& method
is Operator
) {
3288 if (MemberType
!= method
.MemberType
)
3293 // Try to report 663: method only differs on out/ref
3295 ParameterData info
= ParameterInfo
;
3296 ParameterData other_info
= method
.ParameterInfo
;
3297 for (int i
= 0; i
< info
.Count
; i
++){
3298 if (info
.ParameterModifier (i
) != other_info
.ParameterModifier (i
)){
3299 Report
.Error (663, Location
, "Overload method only differs in parameter modifier");
3304 Report
.SymbolRelatedToPreviousError (method
);
3305 Report
.Error (111, Location
, TypeContainer
.Error111
, Parent
.Name
, Name
);
3309 protected override void VerifyObsoleteAttribute()
3311 base.VerifyObsoleteAttribute ();
3313 if (parameter_types
== null)
3316 foreach (Type type
in parameter_types
) {
3317 CheckUsageOfObsoleteAttribute (type
);
3322 public class SourceMethod
: ISourceMethod
3324 TypeContainer container
;
3327 protected SourceMethod (TypeContainer container
, MethodBase builder
,
3328 ISourceFile file
, Location start
, Location end
)
3330 this.container
= container
;
3331 this.builder
= builder
;
3333 CodeGen
.SymbolWriter
.OpenMethod (
3334 file
, this, start
.Row
, 0, end
.Row
, 0);
3337 public string Name
{
3338 get { return builder.Name; }
3341 public int NamespaceID
{
3342 get { return container.NamespaceEntry.SymbolFileID; }
3347 if (builder
is MethodBuilder
)
3348 return ((MethodBuilder
) builder
).GetToken ().Token
;
3349 else if (builder
is ConstructorBuilder
)
3350 return ((ConstructorBuilder
) builder
).GetToken ().Token
;
3352 throw new NotSupportedException ();
3356 public void CloseMethod ()
3358 if (CodeGen
.SymbolWriter
!= null)
3359 CodeGen
.SymbolWriter
.CloseMethod ();
3362 public static SourceMethod
Create (TypeContainer parent
,
3363 MethodBase builder
, Block block
)
3365 if (CodeGen
.SymbolWriter
== null)
3370 Location start_loc
= block
.StartLocation
;
3371 if (Location
.IsNull (start_loc
))
3374 Location end_loc
= block
.EndLocation
;
3375 if (Location
.IsNull (end_loc
))
3378 ISourceFile file
= start_loc
.SourceFile
;
3382 return new SourceMethod (
3383 parent
, builder
, file
, start_loc
, end_loc
);
3387 public class Method
: MethodCore
, IIteratorContainer
, IMethodData
{
3388 public MethodBuilder MethodBuilder
;
3389 public MethodData MethodData
;
3390 ReturnParameter return_attributes
;
3391 ListDictionary declarative_security
;
3394 /// Modifiers allowed in a class declaration
3396 const int AllowedModifiers
=
3399 Modifiers
.PROTECTED
|
3400 Modifiers
.INTERNAL
|
3405 Modifiers
.OVERRIDE
|
3406 Modifiers
.ABSTRACT
|
3408 Modifiers
.METHOD_YIELDS
|
3411 const int AllowedInterfaceModifiers
=
3412 Modifiers
.NEW
| Modifiers
.UNSAFE
;
3415 // return_type can be "null" for VOID values.
3417 public Method (TypeContainer ds
, Expression return_type
, int mod
, bool is_iface
,
3418 MemberName name
, Parameters parameters
, Attributes attrs
,
3420 : base (ds
, return_type
, mod
,
3421 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
3422 is_iface
, name
, attrs
, parameters
, l
)
3426 public override AttributeTargets AttributeTargets
{
3428 return AttributeTargets
.Method
;
3432 public override string GetSignatureForError()
3434 if (MethodBuilder
== null) {
3435 return GetSignatureForError (Parent
);
3437 return TypeManager
.CSharpSignature (MethodBuilder
);
3441 /// Use this method when MethodBuilder is null
3443 public override string GetSignatureForError (TypeContainer tc
)
3445 // TODO: get params from somewhere
3446 if (parameter_info
== null)
3447 return base.GetSignatureForError (tc
);
3449 // TODO: move to parameters
3450 System
.Text
.StringBuilder args
= new System
.Text
.StringBuilder ();
3451 if (parameter_info
.Parameters
.FixedParameters
!= null) {
3452 for (int i
= 0; i
< parameter_info
.Parameters
.FixedParameters
.Length
; ++i
) {
3453 Parameter p
= parameter_info
.Parameters
.FixedParameters
[i
];
3454 args
.Append (p
.GetSignatureForError ());
3456 if (i
< parameter_info
.Parameters
.FixedParameters
.Length
- 1)
3461 return String
.Concat (base.GetSignatureForError (tc
), "(", args
.ToString (), ")");
3464 void DuplicateEntryPoint (MethodInfo b
, Location location
)
3468 "Program `" + CodeGen
.FileName
+
3469 "' has more than one entry point defined: `" +
3470 TypeManager
.CSharpSignature(b
) + "'");
3473 public bool IsEntryPoint (MethodBuilder b
, InternalParameters pinfo
)
3475 if (b
.ReturnType
!= TypeManager
.void_type
&&
3476 b
.ReturnType
!= TypeManager
.int32_type
)
3479 if (pinfo
.Count
== 0)
3482 if (pinfo
.Count
> 1)
3485 Type t
= pinfo
.ParameterType(0);
3487 (t
.GetArrayRank() == 1) &&
3488 (TypeManager
.GetElementType(t
) == TypeManager
.string_type
) &&
3489 (pinfo
.ParameterModifier(0) == Parameter
.Modifier
.NONE
))
3495 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
3497 if (a
.Target
== AttributeTargets
.ReturnValue
) {
3498 if (return_attributes
== null)
3499 return_attributes
= new ReturnParameter (MethodBuilder
, Location
);
3501 return_attributes
.ApplyAttributeBuilder (a
, cb
);
3505 if (a
.Type
== TypeManager
.methodimpl_attr_type
&& a
.IsInternalCall
) {
3506 MethodBuilder
.SetImplementationFlags (MethodImplAttributes
.InternalCall
| MethodImplAttributes
.Runtime
);
3509 if (a
.Type
== TypeManager
.dllimport_type
) {
3510 const int extern_static
= Modifiers
.EXTERN
| Modifiers
.STATIC
;
3511 if ((ModFlags
& extern_static
) != extern_static
) {
3512 Report
.Error (601, a
.Location
, "The DllImport attribute must be specified on a method marked `static' and `extern'");
3518 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
3519 if (declarative_security
== null)
3520 declarative_security
= new ListDictionary ();
3521 a
.ExtractSecurityPermissionSet (declarative_security
);
3525 if (a
.Type
== TypeManager
.conditional_attribute_type
) {
3526 if (IsOperator
|| IsExplicitImpl
) {
3527 Report
.Error (577, Location
, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
3531 if (ReturnType
!= TypeManager
.void_type
) {
3532 Report
.Error (578, Location
, "Conditional not valid on '{0}' because its return new ErrorData ( type is not void", GetSignatureForError ());
3536 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3537 Report
.Error (243, Location
, "Conditional not valid on '{0}' because it is an override method", GetSignatureForError ());
3542 Report
.Error (582, Location
, "Conditional not valid on interface members");
3546 if (MethodData
.IsImplementing
) {
3547 Report
.Error (629, Location
, "Conditional member '{0}' cannot implement interface member", GetSignatureForError ());
3551 for (int i
= 0; i
< parameter_info
.Count
; ++i
) {
3552 if ((parameter_info
.ParameterModifier (i
) & Parameter
.Modifier
.OUT
) != 0) {
3553 Report
.Error (685, Location
, "Conditional method '{0}' cannot have an out parameter", GetSignatureForError ());
3559 MethodBuilder
.SetCustomAttribute (cb
);
3562 protected override bool CheckForDuplications ()
3564 ArrayList ar
= Parent
.Methods
;
3566 int arLen
= ar
.Count
;
3568 for (int i
= 0; i
< arLen
; i
++) {
3569 Method m
= (Method
) ar
[i
];
3570 if (IsDuplicateImplementation (m
))
3575 ar
= Parent
.Properties
;
3577 for (int i
= 0; i
< ar
.Count
; ++i
) {
3578 PropertyBase pb
= (PropertyBase
) ar
[i
];
3579 if (pb
.AreAccessorsDuplicateImplementation (this))
3584 ar
= Parent
.Indexers
;
3586 for (int i
= 0; i
< ar
.Count
; ++i
) {
3587 PropertyBase pb
= (PropertyBase
) ar
[i
];
3588 if (pb
.AreAccessorsDuplicateImplementation (this))
3595 for (int i
= 0; i
< ar
.Count
; ++i
) {
3596 Event ev
= (Event
) ar
[i
];
3597 if (ev
.AreAccessorsDuplicateImplementation (this))
3608 public override bool Define ()
3617 flags
|= MethodAttributes
.SpecialName
| MethodAttributes
.HideBySig
;
3619 MethodData
= new MethodData (this, ParameterInfo
, ModFlags
, flags
, this);
3621 if (!MethodData
.Define (Parent
))
3625 // Setup iterator if we are one
3627 if ((ModFlags
& Modifiers
.METHOD_YIELDS
) != 0){
3628 Iterator iterator
= new Iterator (
3629 Parent
, Name
, MemberType
, ParameterTypes
,
3630 ParameterInfo
, ModFlags
, block
, Location
);
3632 if (!iterator
.DefineIterator ())
3635 block
= iterator
.Block
;
3638 MethodBuilder
= MethodData
.MethodBuilder
;
3641 // This is used to track the Entry Point,
3643 if (Name
== "Main" &&
3644 ((ModFlags
& Modifiers
.STATIC
) != 0) && RootContext
.NeedsEntryPoint
&&
3645 (RootContext
.MainClass
== null ||
3646 RootContext
.MainClass
== Parent
.TypeBuilder
.FullName
)){
3647 if (IsEntryPoint (MethodBuilder
, ParameterInfo
)) {
3648 if (RootContext
.EntryPoint
== null) {
3649 RootContext
.EntryPoint
= MethodBuilder
;
3650 RootContext
.EntryPointLocation
= Location
;
3652 DuplicateEntryPoint (RootContext
.EntryPoint
, RootContext
.EntryPointLocation
);
3653 DuplicateEntryPoint (MethodBuilder
, Location
);
3656 if (RootContext
.WarningLevel
>= 4)
3657 Report
.Warning (28, Location
, "'{0}' has the wrong signature to be an entry point", TypeManager
.CSharpSignature(MethodBuilder
));
3661 if (MemberType
.IsAbstract
&& MemberType
.IsSealed
) {
3662 Report
.Error (722, Location
, Error722
, TypeManager
.CSharpName (MemberType
));
3672 public override void Emit ()
3674 MethodData
.Emit (Parent
, this);
3677 if (declarative_security
!= null) {
3678 foreach (DictionaryEntry de
in declarative_security
) {
3679 MethodBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
3687 protected override MethodInfo
FindOutParentMethod (TypeContainer container
, ref Type parent_ret_type
)
3689 MethodInfo mi
= (MethodInfo
) container
.ParentContainer
.MemberCache
.FindMemberToOverride (
3690 container
.TypeBuilder
, Name
, ParameterTypes
, false);
3695 parent_ret_type
= mi
.ReturnType
;
3699 protected override bool VerifyClsCompliance(DeclSpace ds
)
3701 if (!base.VerifyClsCompliance (ds
))
3704 if (parameter_types
.Length
> 0) {
3705 ArrayList al
= (ArrayList
)ds
.MemberCache
.Members
[Name
];
3707 ds
.MemberCache
.VerifyClsParameterConflict (al
, this, MethodBuilder
);
3714 void IIteratorContainer
.SetYields ()
3716 ModFlags
|= Modifiers
.METHOD_YIELDS
;
3719 #region IMethodData Members
3721 public CallingConventions CallingConventions
{
3723 CallingConventions cc
= Parameters
.GetCallingConvention ();
3724 if (Parameters
.HasArglist
)
3725 block
.HasVarargs
= true;
3728 if ((ModFlags
& Modifiers
.STATIC
) == 0)
3729 cc
|= CallingConventions
.HasThis
;
3731 // FIXME: How is `ExplicitThis' used in C#?
3737 public Type ReturnType
{
3743 public MemberName MethodName
{
3749 public new Location Location
{
3751 return base.Location
;
3755 public EmitContext
CreateEmitContext (TypeContainer tc
, ILGenerator ig
)
3757 return new EmitContext (
3758 tc
, Parent
, Location
, ig
, ReturnType
, ModFlags
, false);
3761 public ObsoleteAttribute
GetObsoleteAttribute ()
3763 return GetObsoleteAttribute (Parent
);
3767 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
3769 public bool IsExcluded (EmitContext ec
)
3771 if ((caching_flags
& Flags
.Excluded_Undetected
) == 0)
3772 return (caching_flags
& Flags
.Excluded
) != 0;
3774 caching_flags
&= ~Flags
.Excluded_Undetected
;
3776 if (parent_method
== null) {
3777 if (OptAttributes
== null)
3780 Attribute
[] attrs
= OptAttributes
.SearchMulti (TypeManager
.conditional_attribute_type
, ec
);
3785 foreach (Attribute a
in attrs
) {
3786 string condition
= a
.GetConditionalAttributeValue (
3788 if (RootContext
.AllDefines
.Contains (condition
))
3792 caching_flags
|= Flags
.Excluded
;
3796 IMethodData md
= TypeManager
.GetMethod (parent_method
);
3798 if (AttributeTester
.IsConditionalMethodExcluded (parent_method
)) {
3799 caching_flags
|= Flags
.Excluded
;
3805 if (md
.IsExcluded (ec
)) {
3806 caching_flags
|= Flags
.Excluded
;
3815 public abstract class ConstructorInitializer
{
3816 ArrayList argument_list
;
3817 protected ConstructorInfo parent_constructor
;
3818 Parameters parameters
;
3821 public ConstructorInitializer (ArrayList argument_list
, Parameters parameters
,
3824 this.argument_list
= argument_list
;
3825 this.parameters
= parameters
;
3829 public ArrayList Arguments
{
3831 return argument_list
;
3835 public bool Resolve (ConstructorBuilder caller_builder
, EmitContext ec
)
3837 Expression parent_constructor_group
;
3840 ec
.CurrentBlock
= new ToplevelBlock (Block
.Flags
.Implicit
, parameters
, loc
);
3842 if (argument_list
!= null){
3843 foreach (Argument a
in argument_list
){
3844 if (!a
.Resolve (ec
, loc
))
3848 ec
.CurrentBlock
= null;
3850 if (this is ConstructorBaseInitializer
) {
3851 if (ec
.ContainerType
.BaseType
== null)
3854 t
= ec
.ContainerType
.BaseType
;
3855 if (ec
.ContainerType
.IsValueType
) {
3856 Report
.Error (522, loc
,
3857 "structs cannot call base class constructors");
3861 t
= ec
.ContainerType
;
3863 parent_constructor_group
= Expression
.MemberLookup (
3864 ec
, t
, ".ctor", MemberTypes
.Constructor
,
3865 BindingFlags
.Public
| BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
,
3868 if (parent_constructor_group
== null){
3869 parent_constructor_group
= Expression
.MemberLookup (
3870 ec
, t
, ".ctor", MemberTypes
.Constructor
,
3871 BindingFlags
.NonPublic
| BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
,
3874 if (parent_constructor_group
!= null)
3876 112, loc
, "`{0}.{1}' is inaccessible due to " +
3877 "its protection level", t
.FullName
, t
.Name
);
3880 1501, loc
, "Can not find a constructor for " +
3881 "this argument list");
3885 parent_constructor
= (ConstructorInfo
) Invocation
.OverloadResolve (
3886 ec
, (MethodGroupExpr
) parent_constructor_group
, argument_list
,
3889 if (parent_constructor
== null){
3890 Report
.Error (1501, loc
,
3891 "Can not find a constructor for this argument list");
3895 if (parent_constructor
== caller_builder
){
3896 Report
.Error (516, String
.Format ("Constructor `{0}' can not call itself", TypeManager
.CSharpSignature (caller_builder
)));
3903 public void Emit (EmitContext ec
)
3905 if (parent_constructor
!= null){
3906 ec
.Mark (loc
, false);
3908 Invocation
.EmitCall (ec
, true, true, null, parent_constructor
, argument_list
, loc
);
3910 Invocation
.EmitCall (ec
, true, false, ec
.GetThis (loc
), parent_constructor
, argument_list
, loc
);
3915 /// Method search for base ctor. (We do not cache it).
3917 Constructor
GetOverloadedConstructor (TypeContainer tc
)
3919 if (tc
.InstanceConstructors
== null)
3922 foreach (Constructor c
in tc
.InstanceConstructors
) {
3923 if (Arguments
== null) {
3924 if (c
.ParameterTypes
.Length
== 0)
3932 int count
= c
.ParameterInfo
.Count
;
3934 c
.ParameterInfo
.ParameterModifier (count
- 1) == Parameter
.Modifier
.PARAMS
) {
3935 for (int i
= 0; i
< count
-1; i
++)
3936 if (c
.ParameterTypes
[i
] != ((Argument
)Arguments
[i
]).Type
) {
3941 if (c
.ParameterTypes
.Length
!= Arguments
.Count
)
3944 for (int i
= 0; i
< Arguments
.Count
; ++i
)
3945 if (c
.ParameterTypes
[i
] != ((Argument
)Arguments
[i
]).Type
) {
3960 //TODO: implement caching when it will be necessary
3961 public virtual void CheckObsoleteAttribute (TypeContainer tc
, Location loc
)
3963 Constructor ctor
= GetOverloadedConstructor (tc
);
3967 ObsoleteAttribute oa
= ctor
.GetObsoleteAttribute (tc
);
3971 AttributeTester
.Report_ObsoleteMessage (oa
, ctor
.GetSignatureForError (), loc
);
3975 public class ConstructorBaseInitializer
: ConstructorInitializer
{
3976 public ConstructorBaseInitializer (ArrayList argument_list
, Parameters pars
, Location l
) :
3977 base (argument_list
, pars
, l
)
3981 public override void CheckObsoleteAttribute(TypeContainer tc
, Location loc
) {
3982 if (parent_constructor
== null)
3985 TypeContainer type_ds
= TypeManager
.LookupTypeContainer (tc
.base_class_type
);
3986 if (type_ds
== null) {
3987 ObsoleteAttribute oa
= AttributeTester
.GetMemberObsoleteAttribute (parent_constructor
);
3990 AttributeTester
.Report_ObsoleteMessage (oa
, TypeManager
.CSharpSignature (parent_constructor
), loc
);
3995 base.CheckObsoleteAttribute (type_ds
, loc
);
4000 public class ConstructorThisInitializer
: ConstructorInitializer
{
4001 public ConstructorThisInitializer (ArrayList argument_list
, Parameters pars
, Location l
) :
4002 base (argument_list
, pars
, l
)
4007 public class Constructor
: MethodCore
, IMethodData
{
4008 public ConstructorBuilder ConstructorBuilder
;
4009 public ConstructorInitializer Initializer
;
4010 ListDictionary declarative_security
;
4013 // Modifiers allowed for a constructor.
4015 public const int AllowedModifiers
=
4017 Modifiers
.PROTECTED
|
4018 Modifiers
.INTERNAL
|
4024 bool has_compliant_args
= false;
4026 // The spec claims that static is not permitted, but
4027 // my very own code has static constructors.
4029 public Constructor (TypeContainer ds
, string name
, int mod
, Parameters args
,
4030 ConstructorInitializer init
, Location l
)
4031 : base (ds
, null, mod
, AllowedModifiers
, false, new MemberName (name
),
4037 public override string GetSignatureForError()
4039 if (ConstructorBuilder
== null)
4040 return GetSignatureForError (Parent
);
4042 return TypeManager
.CSharpSignature (ConstructorBuilder
);
4045 public bool HasCompliantArgs
{
4047 return has_compliant_args
;
4051 public override AttributeTargets AttributeTargets
{
4053 return AttributeTargets
.Constructor
;
4059 // Returns true if this is a default constructor
4061 public bool IsDefault ()
4063 if ((ModFlags
& Modifiers
.STATIC
) != 0)
4064 return (Parameters
.FixedParameters
== null ? true : Parameters
.Empty
) &&
4065 (Parameters
.ArrayParameter
== null ? true : Parameters
.Empty
);
4068 return (Parameters
.FixedParameters
== null ? true : Parameters
.Empty
) &&
4069 (Parameters
.ArrayParameter
== null ? true : Parameters
.Empty
) &&
4070 (Initializer
is ConstructorBaseInitializer
) &&
4071 (Initializer
.Arguments
== null);
4074 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
4076 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
4077 if (declarative_security
== null) {
4078 declarative_security
= new ListDictionary ();
4080 a
.ExtractSecurityPermissionSet (declarative_security
);
4084 ConstructorBuilder
.SetCustomAttribute (cb
);
4087 protected override bool CheckForDuplications ()
4089 ArrayList ar
= Parent
.InstanceConstructors
;
4091 int arLen
= ar
.Count
;
4093 for (int i
= 0; i
< arLen
; i
++) {
4094 Constructor m
= (Constructor
) ar
[i
];
4095 if (IsDuplicateImplementation (m
))
4102 protected override bool CheckBase ()
4104 // Check whether arguments were correct.
4105 if (!DoDefineParameters ())
4108 // TODO: skip the rest for generated ctor
4109 if ((ModFlags
& Modifiers
.STATIC
) != 0)
4112 if (!CheckForDuplications ())
4115 if (Parent
.Kind
== Kind
.Struct
) {
4116 if (ParameterTypes
.Length
== 0) {
4117 Report
.Error (568, Location
,
4118 "Structs can not contain explicit parameterless " +
4123 if ((ModFlags
& Modifiers
.PROTECTED
) != 0) {
4124 Report
.Error (666, Location
, "Protected member in struct declaration");
4129 if ((RootContext
.WarningLevel
>= 4) && ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0 && (ModFlags
& Modifiers
.PROTECTED
) != 0)) {
4130 Report
.Warning (628, Location
, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent
));
4137 // Creates the ConstructorBuilder
4139 public override bool Define ()
4141 MethodAttributes ca
= (MethodAttributes
.RTSpecialName
|
4142 MethodAttributes
.SpecialName
);
4144 if ((ModFlags
& Modifiers
.STATIC
) != 0) {
4145 ca
|= MethodAttributes
.Static
| MethodAttributes
.Private
;
4147 ca
|= MethodAttributes
.HideBySig
;
4149 if ((ModFlags
& Modifiers
.PUBLIC
) != 0)
4150 ca
|= MethodAttributes
.Public
;
4151 else if ((ModFlags
& Modifiers
.PROTECTED
) != 0){
4152 if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
4153 ca
|= MethodAttributes
.FamORAssem
;
4155 ca
|= MethodAttributes
.Family
;
4156 } else if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
4157 ca
|= MethodAttributes
.Assembly
;
4158 else if (IsDefault ())
4159 ca
|= MethodAttributes
.Public
;
4161 ca
|= MethodAttributes
.Private
;
4164 // Check if arguments were correct.
4168 ConstructorBuilder
= Parent
.TypeBuilder
.DefineConstructor (
4169 ca
, CallingConventions
,
4172 if ((ModFlags
& Modifiers
.UNSAFE
) != 0)
4173 ConstructorBuilder
.InitLocals
= false;
4175 TypeManager
.AddMethod (ConstructorBuilder
, this);
4178 // HACK because System.Reflection.Emit is lame
4180 TypeManager
.RegisterMethod (ConstructorBuilder
, ParameterInfo
, ParameterTypes
);
4188 public override void Emit ()
4190 EmitContext ec
= CreateEmitContext (null, null);
4193 // extern methods have no bodies
4195 if ((ModFlags
& Modifiers
.EXTERN
) != 0) {
4196 if ((block
!= null) && ((ModFlags
& Modifiers
.EXTERN
) != 0)) {
4198 179, Location
, "External constructor `" +
4199 TypeManager
.CSharpSignature (ConstructorBuilder
) +
4200 "' can not have a body");
4203 } else if (block
== null) {
4205 501, Location
, "Constructor `" +
4206 TypeManager
.CSharpSignature (ConstructorBuilder
) +
4207 "' must declare a body since it is not marked extern");
4211 if ((ModFlags
& Modifiers
.STATIC
) == 0){
4212 if (Parent
.Kind
== Kind
.Class
&& Initializer
== null)
4213 Initializer
= new ConstructorBaseInitializer (
4214 null, Parameters
.EmptyReadOnlyParameters
, Location
);
4218 // Spec mandates that Initializers will not have
4222 if (Initializer
!= null && !Initializer
.Resolve (ConstructorBuilder
, ec
))
4224 ec
.IsStatic
= false;
4227 Parameters
.LabelParameters (ec
, ConstructorBuilder
, Location
);
4229 SourceMethod source
= SourceMethod
.Create (
4230 Parent
, ConstructorBuilder
, block
);
4233 // Classes can have base initializers and instance field initializers.
4235 if (Parent
.Kind
== Kind
.Class
){
4236 if ((ModFlags
& Modifiers
.STATIC
) == 0){
4239 // If we use a "this (...)" constructor initializer, then
4240 // do not emit field initializers, they are initialized in the other constructor
4242 if (!(Initializer
!= null && Initializer
is ConstructorThisInitializer
))
4243 Parent
.EmitFieldInitializers (ec
);
4246 if (Initializer
!= null) {
4247 if (GetObsoleteAttribute (Parent
) == null && Parent
.GetObsoleteAttribute (Parent
.Parent
) == null)
4248 Initializer
.CheckObsoleteAttribute (Parent
, Location
);
4250 ec
.TestObsoleteMethodUsage
= false;
4251 Initializer
.Emit (ec
);
4254 if ((ModFlags
& Modifiers
.STATIC
) != 0)
4255 Parent
.EmitFieldInitializers (ec
);
4257 if (OptAttributes
!= null)
4258 OptAttributes
.Emit (ec
, this);
4260 // If this is a non-static `struct' constructor and doesn't have any
4261 // initializer, it must initialize all of the struct's fields.
4262 if ((Parent
.Kind
== Kind
.Struct
) &&
4263 ((ModFlags
& Modifiers
.STATIC
) == 0) && (Initializer
== null))
4264 Block
.AddThisVariable (Parent
, Location
);
4266 ec
.EmitTopBlock (block
, ParameterInfo
, Location
);
4269 source
.CloseMethod ();
4273 if (declarative_security
!= null) {
4274 foreach (DictionaryEntry de
in declarative_security
) {
4275 ConstructorBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
4282 // Is never override
4283 protected override MethodInfo
FindOutParentMethod (TypeContainer container
, ref Type parent_ret_type
)
4288 protected override bool VerifyClsCompliance (DeclSpace ds
)
4290 if (!base.VerifyClsCompliance (ds
) || !IsExposedFromAssembly (ds
)) {
4294 if (parameter_types
.Length
> 0) {
4295 ArrayList al
= (ArrayList
)ds
.MemberCache
.Members
[".ctor"];
4297 ds
.MemberCache
.VerifyClsParameterConflict (al
, this, ConstructorBuilder
);
4299 if (ds
.TypeBuilder
.IsSubclassOf (TypeManager
.attribute_type
)) {
4300 foreach (Type param
in parameter_types
) {
4301 if (param
.IsArray
) {
4307 has_compliant_args
= true;
4311 #region IMethodData Members
4313 public System
.Reflection
.CallingConventions CallingConventions
{
4315 CallingConventions cc
= Parameters
.GetCallingConvention ();
4317 if (Parent
.Kind
== Kind
.Class
)
4318 if ((ModFlags
& Modifiers
.STATIC
) == 0)
4319 cc
|= CallingConventions
.HasThis
;
4321 // FIXME: How is `ExplicitThis' used in C#?
4327 public new Location Location
{
4329 return base.Location
;
4333 public MemberName MethodName
{
4339 public Type ReturnType
{
4345 public EmitContext
CreateEmitContext (TypeContainer tc
, ILGenerator ig
)
4347 ILGenerator ig_
= ConstructorBuilder
.GetILGenerator ();
4348 return new EmitContext (Parent
, Location
, ig_
, null, ModFlags
, true);
4351 public ObsoleteAttribute
GetObsoleteAttribute ()
4356 public bool IsExcluded(EmitContext ec
)
4365 /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
4367 public interface IMethodData
4369 CallingConventions CallingConventions { get; }
4370 Location Location { get; }
4371 MemberName MethodName { get; }
4372 Type
[] ParameterTypes { get; }
4373 Type ReturnType { get; }
4375 Attributes OptAttributes { get; }
4376 ToplevelBlock Block { get; }
4378 EmitContext
CreateEmitContext (TypeContainer tc
, ILGenerator ig
);
4379 ObsoleteAttribute
GetObsoleteAttribute ();
4380 string GetSignatureForError (TypeContainer tc
);
4381 bool IsExcluded (EmitContext ec
);
4382 bool IsClsCompliaceRequired (DeclSpace ds
);
4386 // Encapsulates most of the Method's state
4388 public class MethodData
{
4390 readonly IMethodData method
;
4393 // The return type of this method
4395 public readonly InternalParameters ParameterInfo
;
4398 // Are we implementing an interface ?
4400 public bool IsImplementing
= false;
4405 protected MemberBase member
;
4406 protected int modifiers
;
4407 protected MethodAttributes flags
;
4409 MethodBuilder builder
= null;
4410 public MethodBuilder MethodBuilder
{
4416 public MethodData (MemberBase member
, InternalParameters parameters
,
4417 int modifiers
, MethodAttributes flags
, IMethodData method
)
4419 this.member
= member
;
4420 this.ParameterInfo
= parameters
;
4421 this.modifiers
= modifiers
;
4424 this.method
= method
;
4427 public bool Define (TypeContainer container
)
4429 MethodInfo implementing
= null;
4431 string name
= method
.MethodName
.Name
;
4432 string method_name
= name
;
4434 Type
[] ParameterTypes
= method
.ParameterTypes
;
4436 if (container
.Pending
!= null){
4437 if (member
is Indexer
)
4438 implementing
= container
.Pending
.IsInterfaceIndexer (
4439 member
.InterfaceType
, method
.ReturnType
, ParameterTypes
);
4441 implementing
= container
.Pending
.IsInterfaceMethod (
4442 member
.InterfaceType
, name
, method
.ReturnType
, ParameterTypes
);
4444 if (member
.InterfaceType
!= null){
4445 if (implementing
== null){
4446 Report
.Error (539, method
.Location
,
4447 "'{0}' in explicit interface declaration is not an interface", method_name
);
4450 method_name
= member
.InterfaceType
.FullName
+ "." + name
;
4455 // For implicit implementations, make sure we are public, for
4456 // explicit implementations, make sure we are private.
4458 if (implementing
!= null){
4460 // Setting null inside this block will trigger a more
4461 // verbose error reporting for missing interface implementations
4463 // The "candidate" function has been flagged already
4464 // but it wont get cleared
4466 if (member
.IsExplicitImpl
){
4467 if ((modifiers
& (Modifiers
.PUBLIC
| Modifiers
.ABSTRACT
| Modifiers
.VIRTUAL
)) != 0){
4468 Modifiers
.Error_InvalidModifier (method
.Location
, "public, virtual or abstract");
4469 implementing
= null;
4471 } else if ((flags
& MethodAttributes
.MemberAccessMask
) != MethodAttributes
.Public
){
4472 if (TypeManager
.IsInterfaceType (implementing
.DeclaringType
)){
4474 // If this is an interface method implementation,
4475 // check for public accessibility
4477 implementing
= null;
4478 } else if ((flags
& MethodAttributes
.MemberAccessMask
) == MethodAttributes
.Private
){
4479 // We may never be private.
4480 implementing
= null;
4481 } else if ((modifiers
& Modifiers
.OVERRIDE
) == 0){
4483 // We may be protected if we're overriding something.
4485 implementing
= null;
4490 // Static is not allowed
4492 if ((modifiers
& Modifiers
.STATIC
) != 0){
4493 implementing
= null;
4494 Modifiers
.Error_InvalidModifier (method
.Location
, "static");
4499 // If implementing is still valid, set flags
4501 if (implementing
!= null){
4503 // When implementing interface methods, set NewSlot
4504 // unless, we are overwriting a method.
4506 if (implementing
.DeclaringType
.IsInterface
){
4507 if ((modifiers
& Modifiers
.OVERRIDE
) == 0)
4508 flags
|= MethodAttributes
.NewSlot
;
4511 MethodAttributes
.Virtual
|
4512 MethodAttributes
.HideBySig
;
4514 // Set Final unless we're virtual, abstract or already overriding a method.
4515 if ((modifiers
& (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
| Modifiers
.OVERRIDE
)) == 0)
4516 flags
|= MethodAttributes
.Final
;
4518 IsImplementing
= true;
4521 EmitContext ec
= method
.CreateEmitContext (container
, null);
4523 DefineMethodBuilder (ec
, container
, method_name
, ParameterTypes
);
4525 if (builder
== null)
4528 if ((modifiers
& Modifiers
.UNSAFE
) != 0)
4529 builder
.InitLocals
= false;
4531 if (IsImplementing
){
4533 // clear the pending implemntation flag
4535 if (member
is Indexer
) {
4536 container
.Pending
.ImplementIndexer (
4537 member
.InterfaceType
, builder
, method
.ReturnType
,
4538 ParameterTypes
, member
.IsExplicitImpl
);
4540 container
.Pending
.ImplementMethod (
4541 member
.InterfaceType
, name
, method
.ReturnType
,
4542 ParameterTypes
, member
.IsExplicitImpl
);
4544 if (member
.IsExplicitImpl
)
4545 container
.TypeBuilder
.DefineMethodOverride (
4546 builder
, implementing
);
4550 TypeManager
.RegisterMethod (builder
, ParameterInfo
, ParameterTypes
);
4551 TypeManager
.AddMethod (builder
, method
);
4558 /// Create the MethodBuilder for the method
4560 void DefineMethodBuilder (EmitContext ec
, TypeContainer container
, string method_name
, Type
[] ParameterTypes
)
4562 const int extern_static
= Modifiers
.EXTERN
| Modifiers
.STATIC
;
4564 if ((modifiers
& extern_static
) == extern_static
) {
4566 if (method
.OptAttributes
!= null) {
4567 Attribute dllimport_attribute
= method
.OptAttributes
.Search (TypeManager
.dllimport_type
, ec
);
4568 if (dllimport_attribute
!= null) {
4569 flags
|= MethodAttributes
.PinvokeImpl
;
4570 builder
= dllimport_attribute
.DefinePInvokeMethod (
4571 ec
, container
.TypeBuilder
, method_name
, flags
,
4572 method
.ReturnType
, ParameterTypes
);
4578 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
4579 // We are more strict than Microsoft and report CS0626 like error
4580 if (method
.OptAttributes
== null ||
4581 !method
.OptAttributes
.Contains (TypeManager
.methodimpl_attr_type
, ec
)) {
4582 Report
.Error (626, method
.Location
, "Method, operator, or accessor '{0}' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation", method
.GetSignatureForError (container
));
4587 builder
= container
.TypeBuilder
.DefineMethod (
4588 method_name
, flags
, method
.CallingConventions
,
4589 method
.ReturnType
, ParameterTypes
);
4595 public void Emit (TypeContainer container
, Attributable kind
)
4598 if ((flags
& MethodAttributes
.PinvokeImpl
) == 0)
4599 ec
= method
.CreateEmitContext (container
, builder
.GetILGenerator ());
4601 ec
= method
.CreateEmitContext (container
, null);
4603 if (method
.GetObsoleteAttribute () != null || container
.GetObsoleteAttribute (container
.Parent
) != null)
4604 ec
.TestObsoleteMethodUsage
= false;
4606 Location loc
= method
.Location
;
4607 Attributes OptAttributes
= method
.OptAttributes
;
4609 if (OptAttributes
!= null)
4610 OptAttributes
.Emit (ec
, kind
);
4612 if (member
is MethodCore
)
4613 ((MethodCore
) member
).Parameters
.LabelParameters (ec
, MethodBuilder
, loc
);
4615 SymbolWriter sw
= CodeGen
.SymbolWriter
;
4616 ToplevelBlock block
= method
.Block
;
4619 // abstract or extern methods have no bodies
4621 if ((modifiers
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) != 0){
4626 // abstract or extern methods have no bodies.
4628 if ((modifiers
& Modifiers
.ABSTRACT
) != 0)
4630 500, method
.Location
, "Abstract method `" +
4631 TypeManager
.CSharpSignature (builder
) +
4632 "' can not have a body");
4634 if ((modifiers
& Modifiers
.EXTERN
) != 0)
4636 179, method
.Location
, "External method `" +
4637 TypeManager
.CSharpSignature (builder
) +
4638 "' can not have a body");
4644 // Methods must have a body unless they're extern or abstract
4646 if (block
== null) {
4648 501, method
.Location
, "Method `" +
4649 TypeManager
.CSharpSignature (builder
) +
4650 "' must declare a body since it is not marked " +
4651 "abstract or extern");
4655 SourceMethod source
= SourceMethod
.Create (
4656 container
, MethodBuilder
, method
.Block
);
4659 // Handle destructors specially
4661 // FIXME: This code generates buggy code
4663 if (member
is Destructor
)
4664 EmitDestructor (ec
, block
);
4666 ec
.EmitTopBlock (block
, ParameterInfo
, loc
);
4669 source
.CloseMethod ();
4672 void EmitDestructor (EmitContext ec
, ToplevelBlock block
)
4674 ILGenerator ig
= ec
.ig
;
4676 Label finish
= ig
.DefineLabel ();
4678 block
.SetDestructor ();
4680 ig
.BeginExceptionBlock ();
4681 ec
.ReturnLabel
= finish
;
4682 ec
.HasReturnLabel
= true;
4683 ec
.EmitTopBlock (block
, null, method
.Location
);
4685 // ig.MarkLabel (finish);
4686 ig
.BeginFinallyBlock ();
4688 if (ec
.ContainerType
.BaseType
!= null) {
4689 Expression member_lookup
= Expression
.MemberLookup (
4690 ec
, ec
.ContainerType
.BaseType
, null, ec
.ContainerType
.BaseType
,
4691 "Finalize", MemberTypes
.Method
, Expression
.AllBindingFlags
, method
.Location
);
4693 if (member_lookup
!= null){
4694 MethodGroupExpr parent_destructor
= ((MethodGroupExpr
) member_lookup
);
4696 ig
.Emit (OpCodes
.Ldarg_0
);
4697 ig
.Emit (OpCodes
.Call
, (MethodInfo
) parent_destructor
.Methods
[0]);
4701 ig
.EndExceptionBlock ();
4702 //ig.MarkLabel (ec.ReturnLabel);
4703 ig
.Emit (OpCodes
.Ret
);
4707 public class Destructor
: Method
{
4709 public Destructor (TypeContainer ds
, Expression return_type
, int mod
,
4710 string name
, Parameters parameters
, Attributes attrs
,
4712 : base (ds
, return_type
, mod
, false, new MemberName (name
),
4713 parameters
, attrs
, l
)
4716 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
4718 if (a
.Type
== TypeManager
.conditional_attribute_type
) {
4719 Report
.Error (577, Location
, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
4723 base.ApplyAttributeBuilder (a
, cb
);
4727 abstract public class MemberBase
: MemberCore
{
4728 public Expression Type
;
4730 public MethodAttributes flags
;
4732 protected readonly int explicit_mod_flags
;
4735 // The "short" name of this property / indexer / event. This is the
4736 // name without the explicit interface.
4738 public string ShortName
;
4741 // The type of this property / indexer / event
4743 public Type MemberType
;
4746 // If true, this is an explicit interface implementation
4748 public bool IsExplicitImpl
= false;
4751 // The name of the interface we are explicitly implementing
4753 public MemberName ExplicitInterfaceName
= null;
4756 // Whether this is an interface member.
4758 public bool IsInterface
;
4761 // If true, the interface type we are explicitly implementing
4763 public Type InterfaceType
= null;
4766 // The constructor is only exposed to our children
4768 protected MemberBase (TypeContainer parent
, Expression type
, int mod
,
4769 int allowed_mod
, int def_mod
, MemberName name
,
4770 Attributes attrs
, Location loc
)
4771 : base (parent
, name
, attrs
, loc
)
4773 explicit_mod_flags
= mod
;
4775 ModFlags
= Modifiers
.Check (allowed_mod
, mod
, def_mod
, loc
);
4777 // Check for explicit interface implementation
4778 if (MemberName
.Left
!= null) {
4779 ExplicitInterfaceName
= MemberName
.Left
;
4780 ShortName
= MemberName
.Name
;
4781 IsExplicitImpl
= true;
4786 protected virtual bool CheckBase ()
4788 if ((ModFlags
& Modifiers
.PROTECTED
) != 0 && Parent
.Kind
== Kind
.Struct
) {
4789 Report
.Error (666, Location
, "Protected member in struct declaration");
4793 if ((RootContext
.WarningLevel
>= 4) &&
4794 ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0) &&
4795 ((ModFlags
& Modifiers
.PROTECTED
) != 0) &&
4796 ((ModFlags
& Modifiers
.OVERRIDE
) == 0) && (Name
!= "Finalize")) {
4797 Report
.Warning (628, Location
, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent
));
4802 protected virtual bool CheckParameters (DeclSpace ds
, Type
[] parameters
)
4806 foreach (Type partype
in parameters
){
4807 if (partype
== TypeManager
.void_type
) {
4809 1547, Location
, "Keyword 'void' cannot " +
4810 "be used in this context");
4814 if (partype
.IsPointer
){
4817 if (!TypeManager
.VerifyUnManaged (TypeManager
.GetElementType (partype
), Location
))
4821 if (ds
.AsAccessible (partype
, ModFlags
))
4824 if (this is Indexer
)
4825 Report
.Error (55, Location
,
4826 "Inconsistent accessibility: parameter type `" +
4827 TypeManager
.CSharpName (partype
) + "' is less " +
4828 "accessible than indexer `" + Name
+ "'");
4829 else if ((this is Method
) && ((Method
) this).IsOperator
)
4830 Report
.Error (57, Location
,
4831 "Inconsistent accessibility: parameter type `" +
4832 TypeManager
.CSharpName (partype
) + "' is less " +
4833 "accessible than operator `" + Name
+ "'");
4835 Report
.Error (51, Location
,
4836 "Inconsistent accessibility: parameter type `" +
4837 TypeManager
.CSharpName (partype
) + "' is less " +
4838 "accessible than method `" + Name
+ "'");
4845 protected virtual bool DoDefine ()
4847 EmitContext ec
= Parent
.EmitContext
;
4849 throw new InternalErrorException ("MemberBase.DoDefine called too early");
4852 throw new InternalErrorException ();
4855 ModFlags
= Modifiers
.PUBLIC
|
4856 Modifiers
.ABSTRACT
|
4857 Modifiers
.VIRTUAL
| (ModFlags
& Modifiers
.UNSAFE
) | (ModFlags
& Modifiers
.NEW
);
4859 flags
= MethodAttributes
.Public
|
4860 MethodAttributes
.Abstract
|
4861 MethodAttributes
.HideBySig
|
4862 MethodAttributes
.NewSlot
|
4863 MethodAttributes
.Virtual
;
4865 if (!Parent
.MethodModifiersValid (ModFlags
, Name
, Location
))
4868 flags
= Modifiers
.MethodAttr (ModFlags
);
4871 // Lookup Type, verify validity
4872 bool old_unsafe
= ec
.InUnsafe
;
4873 ec
.InUnsafe
= InUnsafe
;
4874 Type
= Type
.ResolveAsTypeTerminal (ec
, false);
4875 ec
.InUnsafe
= old_unsafe
;
4880 MemberType
= Type
.Type
;
4882 if ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0){
4883 if ((ModFlags
& (Modifiers
.VIRTUAL
|Modifiers
.ABSTRACT
)) != 0){
4884 Report
.Error (549, Location
, "Virtual method can not be contained in sealed class");
4889 // verify accessibility
4890 if (!Parent
.AsAccessible (MemberType
, ModFlags
)) {
4891 if (this is Property
)
4892 Report
.Error (53, Location
,
4893 "Inconsistent accessibility: property type `" +
4894 TypeManager
.CSharpName (MemberType
) + "' is less " +
4895 "accessible than property `" + Name
+ "'");
4896 else if (this is Indexer
)
4897 Report
.Error (54, Location
,
4898 "Inconsistent accessibility: indexer return type `" +
4899 TypeManager
.CSharpName (MemberType
) + "' is less " +
4900 "accessible than indexer `" + Name
+ "'");
4901 else if (this is Method
) {
4902 if (((Method
) this).IsOperator
)
4903 Report
.Error (56, Location
,
4904 "Inconsistent accessibility: return type `" +
4905 TypeManager
.CSharpName (MemberType
) + "' is less " +
4906 "accessible than operator `" + Name
+ "'");
4908 Report
.Error (50, Location
,
4909 "Inconsistent accessibility: return type `" +
4910 TypeManager
.CSharpName (MemberType
) + "' is less " +
4911 "accessible than method `" + Name
+ "'");
4913 Report
.Error (52, Location
,
4914 "Inconsistent accessibility: field type `" +
4915 TypeManager
.CSharpName (MemberType
) + "' is less " +
4916 "accessible than field `" + Name
+ "'");
4920 if (MemberType
.IsPointer
&& !UnsafeOK (Parent
))
4923 if (IsExplicitImpl
) {
4924 Expression expr
= ExplicitInterfaceName
.GetTypeExpression (Location
);
4925 TypeExpr texpr
= expr
.ResolveAsTypeTerminal (ec
, false);
4929 InterfaceType
= texpr
.ResolveType (ec
);
4931 if (InterfaceType
.IsClass
) {
4932 Report
.Error (538, Location
, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName
);
4937 // Compute the full name that we need to export.
4938 if (InterfaceType
.FullName
!= ExplicitInterfaceName
) {
4939 ExplicitInterfaceName
= InterfaceType
.FullName
;
4940 UpdateMemberName ();
4944 if (!Parent
.VerifyImplements (InterfaceType
, ShortName
, Name
, Location
))
4947 Modifiers
.Check (Modifiers
.AllowedExplicitImplFlags
, explicit_mod_flags
, 0, Location
);
4954 /// The name of the member can be changed during definition (see IndexerName attribute)
4956 protected virtual void UpdateMemberName ()
4958 MemberName
.Name
= ShortName
;
4961 public override string GetSignatureForError (TypeContainer tc
)
4963 return String
.Concat (tc
.Name
, '.', base.GetSignatureForError (tc
));
4966 protected bool IsTypePermitted ()
4968 if (MemberType
== TypeManager
.arg_iterator_type
|| MemberType
== TypeManager
.typed_reference_type
) {
4969 Report
.Error (610, Location
, "Field or property cannot be of type '{0}'", TypeManager
.CSharpName (MemberType
));
4975 protected override bool VerifyClsCompliance(DeclSpace ds
)
4977 if (base.VerifyClsCompliance (ds
)) {
4981 if (IsInterface
&& HasClsCompliantAttribute
&& ds
.IsClsCompliaceRequired (ds
)) {
4982 Report
.Error (3010, Location
, "'{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
4987 protected override void VerifyObsoleteAttribute()
4989 CheckUsageOfObsoleteAttribute (MemberType
);
4994 // Fields and Events both generate FieldBuilders, we use this to share
4995 // their common bits. This is also used to flag usage of the field
4997 abstract public class FieldBase
: MemberBase
{
4998 public FieldBuilder FieldBuilder
;
4999 public Status status
;
5002 public enum Status
: byte {
5007 static string[] attribute_targets
= new string [] { "field" }
;
5010 /// Symbol with same name in parent class/struct
5012 public MemberInfo conflict_symbol
;
5015 // The constructor is only exposed to our children
5017 protected FieldBase (TypeContainer parent
, Expression type
, int mod
,
5018 int allowed_mod
, MemberName name
, object init
,
5019 Attributes attrs
, Location loc
)
5020 : base (parent
, type
, mod
, allowed_mod
, Modifiers
.PRIVATE
,
5026 public override AttributeTargets AttributeTargets
{
5028 return AttributeTargets
.Field
;
5032 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
5034 if (a
.Type
== TypeManager
.marshal_as_attr_type
) {
5035 UnmanagedMarshal marshal
= a
.GetMarshal (this);
5036 if (marshal
!= null) {
5037 FieldBuilder
.SetMarshal (marshal
);
5042 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
)) {
5043 a
.Error_InvalidSecurityParent ();
5047 FieldBuilder
.SetCustomAttribute (cb
);
5051 // Whether this field has an initializer.
5053 public bool HasInitializer
{
5055 return init
!= null;
5059 protected readonly Object init
;
5062 Expression init_expr
;
5063 bool init_expr_initialized
= false;
5066 // Resolves and returns the field initializer.
5068 public Expression
GetInitializerExpression (EmitContext ec
)
5070 if (init_expr_initialized
)
5074 if (init
is Expression
)
5075 e
= (Expression
) init
;
5077 e
= new ArrayCreation (Type
, "", (ArrayList
)init
, Location
);
5079 ec
.IsFieldInitializer
= true;
5080 e
= e
.DoResolve (ec
);
5081 ec
.IsFieldInitializer
= false;
5084 init_expr_initialized
= true;
5089 protected override bool CheckBase ()
5091 if (!base.CheckBase ())
5098 conflict_symbol
= Parent
.FindMemberWithSameName (Name
, false);
5099 if (conflict_symbol
== null) {
5100 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0)) {
5101 Report
.Warning (109, Location
, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent
));
5106 if ((ModFlags
& (Modifiers
.NEW
| Modifiers
.OVERRIDE
)) == 0) {
5107 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
5108 Report
.Warning (108, Location
, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent
));
5114 protected override bool DoDefine ()
5116 if (!base.DoDefine ())
5119 if (MemberType
== TypeManager
.void_type
) {
5120 Report
.Error (1547, Location
,
5121 "Keyword 'void' cannot be used in this context");
5127 public override string GetSignatureForError ()
5129 if (FieldBuilder
== null) {
5130 return base.GetSignatureForError (Parent
);
5132 return TypeManager
.GetFullNameSignature (FieldBuilder
);
5135 public override string[] ValidAttributeTargets
{
5137 return attribute_targets
;
5141 protected override bool VerifyClsCompliance (DeclSpace ds
)
5143 if (!base.VerifyClsCompliance (ds
))
5146 if (FieldBuilder
== null) {
5150 if (!AttributeTester
.IsClsCompliant (FieldBuilder
.FieldType
)) {
5151 Report
.Error (3003, Location
, "Type of '{0}' is not CLS-compliant", GetSignatureForError ());
5157 public void SetAssigned ()
5159 status
|= Status
.ASSIGNED
;
5163 public abstract class FieldMember
: FieldBase
5165 bool has_field_offset
= false;
5167 protected FieldMember (TypeContainer parent
, Expression type
, int mod
,
5168 int allowed_mod
, MemberName name
, object init
, Attributes attrs
, Location loc
)
5169 : base (parent
, type
, mod
, allowed_mod
, name
, init
, attrs
, loc
)
5173 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
5175 if (a
.Type
== TypeManager
.field_offset_attribute_type
)
5177 has_field_offset
= true;
5179 if (!Parent
.HasExplicitLayout
) {
5180 Report
.Error (636, Location
, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5184 if ((ModFlags
& Modifiers
.STATIC
) != 0 || this is Const
) {
5185 Report
.Error (637, Location
, "The FieldOffset attribute is not allowed on static or const fields");
5189 base.ApplyAttributeBuilder (a
, cb
);
5193 public override bool Define()
5195 EmitContext ec
= Parent
.EmitContext
;
5197 throw new InternalErrorException ("FieldMember.Define called too early");
5199 bool old_unsafe
= ec
.InUnsafe
;
5200 ec
.InUnsafe
= InUnsafe
;
5201 TypeExpr texpr
= Type
.ResolveAsTypeTerminal (ec
, false);
5205 MemberType
= texpr
.ResolveType (ec
);
5206 ec
.InUnsafe
= old_unsafe
;
5211 if (!Parent
.AsAccessible (MemberType
, ModFlags
)) {
5212 Report
.Error (52, Location
,
5213 "Inconsistent accessibility: field type `" +
5214 TypeManager
.CSharpName (MemberType
) + "' is less " +
5215 "accessible than field `" + Name
+ "'");
5219 if (!IsTypePermitted ())
5222 if (MemberType
.IsPointer
&& !UnsafeOK (Parent
))
5228 public override void Emit ()
5230 if (Parent
.HasExplicitLayout
&& !has_field_offset
&& (ModFlags
& Modifiers
.STATIC
) == 0) {
5231 Report
.Error (625, Location
, "'{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5239 // The Field class is used to represents class/struct fields during parsing.
5241 public class Field
: FieldMember
{
5243 // Modifiers allowed in a class declaration
5245 const int AllowedModifiers
=
5248 Modifiers
.PROTECTED
|
5249 Modifiers
.INTERNAL
|
5252 Modifiers
.VOLATILE
|
5256 public Field (TypeContainer parent
, Expression type
, int mod
, string name
,
5257 Object expr_or_array_init
, Attributes attrs
, Location loc
)
5258 : base (parent
, type
, mod
, AllowedModifiers
, new MemberName (name
),
5259 expr_or_array_init
, attrs
, loc
)
5263 public override bool Define ()
5265 if (!base.Define ())
5268 if (RootContext
.WarningLevel
> 1){
5269 Type ptype
= Parent
.TypeBuilder
.BaseType
;
5271 // ptype is only null for System.Object while compiling corlib.
5273 TypeContainer
.FindMembers (
5274 ptype
, MemberTypes
.Method
,
5275 BindingFlags
.Public
|
5276 BindingFlags
.Static
| BindingFlags
.Instance
,
5277 System
.Type
.FilterName
, Name
);
5281 if ((ModFlags
& Modifiers
.VOLATILE
) != 0){
5282 if (!MemberType
.IsClass
){
5283 Type vt
= MemberType
;
5285 if (TypeManager
.IsEnumType (vt
))
5286 vt
= TypeManager
.EnumToUnderlying (MemberType
);
5288 if (!((vt
== TypeManager
.bool_type
) ||
5289 (vt
== TypeManager
.sbyte_type
) ||
5290 (vt
== TypeManager
.byte_type
) ||
5291 (vt
== TypeManager
.short_type
) ||
5292 (vt
== TypeManager
.ushort_type
) ||
5293 (vt
== TypeManager
.int32_type
) ||
5294 (vt
== TypeManager
.uint32_type
) ||
5295 (vt
== TypeManager
.char_type
) ||
5296 (vt
== TypeManager
.float_type
) ||
5297 (!vt
.IsValueType
))){
5299 677, Location
, Parent
.MakeName (Name
) +
5300 " A volatile field can not be of type `" +
5301 TypeManager
.CSharpName (vt
) + "'");
5306 if ((ModFlags
& Modifiers
.READONLY
) != 0){
5309 "A field can not be both volatile and readonly");
5314 FieldAttributes fa
= Modifiers
.FieldAttr (ModFlags
);
5316 if (Parent
.Kind
== Kind
.Struct
&&
5317 ((fa
& FieldAttributes
.Static
) == 0) &&
5318 MemberType
== Parent
.TypeBuilder
&&
5319 !TypeManager
.IsBuiltinType (MemberType
)){
5320 Report
.Error (523, Location
, "Struct member `" + Parent
.Name
+ "." + Name
+
5321 "' causes a cycle in the structure layout");
5326 FieldBuilder
= Parent
.TypeBuilder
.DefineField (
5327 Name
, MemberType
, Modifiers
.FieldAttr (ModFlags
));
5329 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
5331 catch (ArgumentException
) {
5332 Report
.Warning (-24, Location
, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
5339 public override void Emit ()
5341 if (OptAttributes
!= null) {
5342 EmitContext ec
= new EmitContext (
5343 Parent
, Location
, null, FieldBuilder
.FieldType
,
5345 OptAttributes
.Emit (ec
, this);
5353 // `set' and `get' accessors are represented with an Accessor.
5355 public class Accessor
{
5357 // Null if the accessor is empty, or a Block if not
5359 public const int AllowedModifiers
=
5361 Modifiers
.PROTECTED
|
5362 Modifiers
.INTERNAL
|
5365 public ToplevelBlock Block
;
5366 public Attributes Attributes
;
5367 public Location Location
;
5368 public int ModFlags
;
5370 public Accessor (ToplevelBlock b
, int mod
, Attributes attrs
, Location loc
)
5375 ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, 0, loc
);
5380 // Ooouh Martin, templates are missing here.
5381 // When it will be possible move here a lot of child code and template method type.
5382 public abstract class AbstractPropertyEventMethod
: MemberCore
, IMethodData
{
5383 protected MethodData method_data
;
5384 protected ToplevelBlock block
;
5385 protected ListDictionary declarative_security
;
5387 // The accessor are created event if they are not wanted.
5388 // But we need them because their names are reserved.
5389 // Field says whether accessor will be emited or not
5390 public readonly bool IsDummy
;
5392 protected readonly string prefix
;
5394 ReturnParameter return_attributes
;
5396 public AbstractPropertyEventMethod (MemberBase member
, string prefix
)
5397 : base (null, SetupName (prefix
, member
), null, member
.Location
)
5399 this.prefix
= prefix
;
5403 public AbstractPropertyEventMethod (MemberBase member
, Accessor accessor
,
5405 : base (null, SetupName (prefix
, member
),
5406 accessor
.Attributes
, accessor
.Location
)
5408 this.prefix
= prefix
;
5409 this.block
= accessor
.Block
;
5412 static MemberName
SetupName (string prefix
, MemberBase member
)
5414 MemberName name
= member
.MemberName
.Clone ();
5415 name
.Name
= prefix
+ member
.ShortName
;
5419 public void UpdateName (MemberBase member
)
5421 MemberName
.Name
= prefix
+ member
.ShortName
;
5424 #region IMethodData Members
5426 public ToplevelBlock Block
{
5436 public CallingConventions CallingConventions
{
5438 return CallingConventions
.Standard
;
5442 public bool IsExcluded (EmitContext ec
)
5447 public MemberName MethodName
{
5453 public abstract ObsoleteAttribute
GetObsoleteAttribute ();
5454 public abstract Type
[] ParameterTypes { get; }
5455 public abstract Type ReturnType { get; }
5456 public abstract EmitContext
CreateEmitContext(TypeContainer tc
, ILGenerator ig
);
5460 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
5462 if (a
.Type
== TypeManager
.cls_compliant_attribute_type
|| a
.Type
== TypeManager
.obsolete_attribute_type
||
5463 a
.Type
== TypeManager
.conditional_attribute_type
) {
5464 Report
.Error (1667, a
.Location
, "'{0}' is not valid on property or event accessors. It is valid on '{1}' declarations only", TypeManager
.CSharpName (a
.Type
), a
.GetValidTargets ());
5468 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
5469 if (declarative_security
== null)
5470 declarative_security
= new ListDictionary ();
5471 a
.ExtractSecurityPermissionSet (declarative_security
);
5475 if (a
.Target
== AttributeTargets
.Method
) {
5476 method_data
.MethodBuilder
.SetCustomAttribute (cb
);
5480 if (a
.Target
== AttributeTargets
.ReturnValue
) {
5481 if (return_attributes
== null)
5482 return_attributes
= new ReturnParameter (method_data
.MethodBuilder
, Location
);
5484 return_attributes
.ApplyAttributeBuilder (a
, cb
);
5488 ApplyToExtraTarget (a
, cb
);
5491 virtual protected void ApplyToExtraTarget (Attribute a
, CustomAttributeBuilder cb
)
5493 System
.Diagnostics
.Debug
.Fail ("You forgot to define special attribute target handling");
5496 public override bool Define()
5501 public virtual void Emit (TypeContainer container
)
5503 method_data
.Emit (container
, this);
5505 if (declarative_security
!= null) {
5506 foreach (DictionaryEntry de
in declarative_security
) {
5507 method_data
.MethodBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
5514 public override bool IsClsCompliaceRequired(DeclSpace ds
)
5519 public bool IsDuplicateImplementation (MethodCore method
)
5521 if (Name
!= method
.Name
)
5524 Type
[] param_types
= method
.ParameterTypes
;
5526 if (param_types
.Length
!= ParameterTypes
.Length
)
5529 for (int i
= 0; i
< param_types
.Length
; i
++)
5530 if (param_types
[i
] != ParameterTypes
[i
])
5533 Report
.SymbolRelatedToPreviousError (method
);
5534 Report
.Error (111, Location
, TypeContainer
.Error111
, method
.Parent
.GetSignatureForError (), Name
);
5538 public new Location Location
{
5540 return base.Location
;
5544 protected override void VerifyObsoleteAttribute()
5551 // Properties and Indexers both generate PropertyBuilders, we use this to share
5552 // their common bits.
5554 abstract public class PropertyBase
: MethodCore
{
5556 public class GetMethod
: PropertyMethod
5558 static string[] attribute_targets
= new string [] { "method", "return" }
;
5560 public GetMethod (MethodCore method
):
5561 base (method
, "get_")
5565 public GetMethod (MethodCore method
, Accessor accessor
):
5566 base (method
, accessor
, "get_")
5570 public override MethodBuilder
Define(TypeContainer container
)
5572 base.Define (container
);
5574 method_data
= new MethodData (method
, method
.ParameterInfo
, ModFlags
, flags
, this);
5576 if (!method_data
.Define (container
))
5579 return method_data
.MethodBuilder
;
5582 public override string GetSignatureForError (TypeContainer tc
)
5584 return String
.Concat (base.GetSignatureForError (tc
), ".get");
5587 public override Type ReturnType
{
5589 return method
.MemberType
;
5593 public override string[] ValidAttributeTargets
{
5595 return attribute_targets
;
5600 public class SetMethod
: PropertyMethod
{
5602 static string[] attribute_targets
= new string [] { "method", "param", "return" }
;
5603 ImplicitParameter param_attr
;
5605 public SetMethod (MethodCore method
):
5606 base (method
, "set_")
5610 public SetMethod (MethodCore method
, Accessor accessor
):
5611 base (method
, accessor
, "set_")
5615 protected override void ApplyToExtraTarget(Attribute a
, CustomAttributeBuilder cb
)
5617 if (a
.Target
== AttributeTargets
.Parameter
) {
5618 if (param_attr
== null)
5619 param_attr
= new ImplicitParameter (method_data
.MethodBuilder
);
5621 param_attr
.ApplyAttributeBuilder (a
, cb
);
5625 base.ApplyAttributeBuilder (a
, cb
);
5628 protected virtual InternalParameters
GetParameterInfo (EmitContext ec
)
5630 Parameter
[] parms
= new Parameter
[1];
5631 parms
[0] = new Parameter (method
.Type
, "value", Parameter
.Modifier
.NONE
, null);
5632 Parameters parameters
= new Parameters (parms
, null, method
.Location
);
5633 Type
[] types
= parameters
.GetParameterInfo (ec
);
5634 return new InternalParameters (types
, parameters
);
5637 public override MethodBuilder
Define(TypeContainer container
)
5639 if (container
.EmitContext
== null)
5640 throw new InternalErrorException ("SetMethod.Define called too early");
5642 base.Define (container
);
5644 method_data
= new MethodData (method
, GetParameterInfo (container
.EmitContext
), ModFlags
, flags
, this);
5646 if (!method_data
.Define (container
))
5649 return method_data
.MethodBuilder
;
5652 public override string GetSignatureForError (TypeContainer tc
)
5654 return String
.Concat (base.GetSignatureForError (tc
), ".set");
5657 public override Type
[] ParameterTypes
{
5659 return new Type
[] { method.MemberType }
;
5663 public override Type ReturnType
{
5665 return TypeManager
.void_type
;
5669 public override string[] ValidAttributeTargets
{
5671 return attribute_targets
;
5676 static string[] attribute_targets
= new string [] { "property" }
;
5678 public abstract class PropertyMethod
: AbstractPropertyEventMethod
5680 protected readonly MethodCore method
;
5681 protected MethodAttributes flags
;
5683 public PropertyMethod (MethodCore method
, string prefix
)
5684 : base (method
, prefix
)
5686 this.method
= method
;
5689 public PropertyMethod (MethodCore method
, Accessor accessor
,
5691 : base (method
, accessor
, prefix
)
5693 this.method
= method
;
5694 this.ModFlags
= accessor
.ModFlags
;
5696 if (accessor
.ModFlags
!= 0 && RootContext
.Version
== LanguageVersion
.ISO_1
) {
5697 Report
.FeatureIsNotStandardized (Location
, "accessor modifiers");
5698 Environment
.Exit (1);
5702 public override AttributeTargets AttributeTargets
{
5704 return AttributeTargets
.Method
;
5708 public override bool IsClsCompliaceRequired(DeclSpace ds
)
5710 return method
.IsClsCompliaceRequired (ds
);
5713 public InternalParameters ParameterInfo
5716 return method_data
.ParameterInfo
;
5720 public virtual MethodBuilder
Define (TypeContainer container
)
5723 // Check for custom access modifier
5725 if (ModFlags
== 0) {
5726 ModFlags
= method
.ModFlags
;
5727 flags
= method
.flags
;
5729 CheckModifiers (container
, ModFlags
);
5730 ModFlags
|= (method
.ModFlags
& (~Modifiers
.Accessibility
));
5731 flags
= Modifiers
.MethodAttr (ModFlags
);
5732 flags
|= (method
.flags
& (~MethodAttributes
.MemberAccessMask
));
5739 public override Type
[] ParameterTypes
{
5741 return TypeManager
.NoTypes
;
5745 public override EmitContext
CreateEmitContext (TypeContainer tc
,
5748 return new EmitContext (
5749 tc
, method
.Parent
, method
.Location
, ig
, ReturnType
,
5750 method
.ModFlags
, false);
5753 public override ObsoleteAttribute
GetObsoleteAttribute ()
5755 return method
.GetObsoleteAttribute (method
.Parent
);
5758 public override string GetSignatureForError (TypeContainer tc
)
5760 return String
.Concat (tc
.Name
, '.', method
.Name
);
5763 void CheckModifiers (TypeContainer container
, int modflags
)
5766 int mflags
= method
.ModFlags
& Modifiers
.Accessibility
;
5768 if ((mflags
& Modifiers
.PUBLIC
) != 0) {
5769 flags
|= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
| Modifiers
.PRIVATE
;
5771 else if ((mflags
& Modifiers
.PROTECTED
) != 0) {
5772 if ((mflags
& Modifiers
.INTERNAL
) != 0)
5773 flags
|= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
;
5775 flags
|= Modifiers
.PRIVATE
;
5777 else if ((mflags
& Modifiers
.INTERNAL
) != 0)
5778 flags
|= Modifiers
.PRIVATE
;
5780 if ((mflags
== modflags
) || (modflags
& (~flags
)) != 0)
5781 Report
.Error (273, Location
, "{0}: accessibility modifier must be more restrictive than the property or indexer",
5782 GetSignatureForError (container
));
5788 public PropertyMethod Get
, Set
;
5789 public PropertyBuilder PropertyBuilder
;
5790 public MethodBuilder GetBuilder
, SetBuilder
;
5792 protected EmitContext ec
;
5794 public PropertyBase (TypeContainer ds
, Expression type
, int mod_flags
,
5795 int allowed_mod
, bool is_iface
, MemberName name
,
5796 Parameters parameters
, Attributes attrs
,
5798 : base (ds
, type
, mod_flags
, allowed_mod
, is_iface
, name
,
5799 attrs
, parameters
, loc
)
5803 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
5805 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
)) {
5806 a
.Error_InvalidSecurityParent ();
5810 PropertyBuilder
.SetCustomAttribute (cb
);
5813 public override AttributeTargets AttributeTargets
{
5815 return AttributeTargets
.Property
;
5819 public override bool Define ()
5824 if (!IsTypePermitted ())
5830 protected override bool DoDefine ()
5832 if (!base.DoDefine ())
5836 // Accessors modifiers check
5838 if (Get
.ModFlags
!= 0 && Set
.ModFlags
!= 0) {
5839 Report
.Error (274, Location
, "'{0}': cannot specify accessibility modifiers for both accessors of the property or indexer.",
5840 GetSignatureForError ());
5844 if ((Get
.IsDummy
|| Set
.IsDummy
)
5845 && (Get
.ModFlags
!= 0 || Set
.ModFlags
!= 0) && (ModFlags
& Modifiers
.OVERRIDE
) == 0) {
5846 Report
.Error (276, Location
,
5847 "'{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor.",
5848 GetSignatureForError ());
5852 if (MemberType
.IsAbstract
&& MemberType
.IsSealed
) {
5853 Report
.Error (722, Location
, Error722
, TypeManager
.CSharpName (MemberType
));
5857 ec
= new EmitContext (Parent
, Location
, null, MemberType
, ModFlags
);
5861 public override string GetSignatureForError()
5863 if (PropertyBuilder
== null)
5864 return GetSignatureForError (Parent
);
5866 return TypeManager
.CSharpSignature (PropertyBuilder
, false);
5870 protected override bool CheckForDuplications ()
5872 ArrayList ar
= Parent
.Indexers
;
5874 int arLen
= ar
.Count
;
5876 for (int i
= 0; i
< arLen
; i
++) {
5877 Indexer m
= (Indexer
) ar
[i
];
5878 if (IsDuplicateImplementation (m
))
5883 ar
= Parent
.Properties
;
5885 int arLen
= ar
.Count
;
5887 for (int i
= 0; i
< arLen
; i
++) {
5888 Property m
= (Property
) ar
[i
];
5889 if (IsDuplicateImplementation (m
))
5897 // TODO: rename to Resolve......
5898 protected override MethodInfo
FindOutParentMethod (TypeContainer container
, ref Type parent_ret_type
)
5900 PropertyInfo parent_property
= container
.ParentContainer
.MemberCache
.FindMemberToOverride (
5901 container
.TypeBuilder
, Name
, ParameterTypes
, true) as PropertyInfo
;
5903 if (parent_property
== null)
5906 parent_ret_type
= parent_property
.PropertyType
;
5907 MethodInfo get_accessor
= parent_property
.GetGetMethod (true);
5908 MethodInfo set_accessor
= parent_property
.GetSetMethod (true);
5909 MethodAttributes get_accessor_access
, set_accessor_access
;
5911 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
5912 if (Get
!= null && !Get
.IsDummy
&& get_accessor
== null) {
5913 Report
.SymbolRelatedToPreviousError (parent_property
);
5914 Report
.Error (545, Location
, "'{0}': cannot override because '{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager
.GetFullNameSignature (parent_property
));
5917 if (Set
!= null && !Set
.IsDummy
&& set_accessor
== null) {
5918 Report
.SymbolRelatedToPreviousError (parent_property
);
5919 Report
.Error (546, Location
, "'{0}': cannot override because '{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager
.GetFullNameSignature (parent_property
));
5924 // Check parent accessors access
5926 get_accessor_access
= set_accessor_access
= 0;
5927 if ((ModFlags
& Modifiers
.NEW
) == 0) {
5928 if (get_accessor
!= null) {
5929 MethodAttributes get_flags
= Modifiers
.MethodAttr (Get
.ModFlags
!= 0 ? Get
.ModFlags
: ModFlags
);
5930 get_accessor_access
= (get_accessor
.Attributes
& MethodAttributes
.MemberAccessMask
);
5932 if (!Get
.IsDummy
&& (get_accessor_access
) !=
5933 (get_flags
& MethodAttributes
.MemberAccessMask
))
5934 Report
.Error (507, Location
, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
5935 GetSignatureForError (), TypeManager
.GetFullNameSignature (parent_property
));
5938 if (set_accessor
!= null) {
5939 MethodAttributes set_flags
= Modifiers
.MethodAttr (Set
.ModFlags
!= 0 ? Set
.ModFlags
: ModFlags
);
5940 set_accessor_access
= (set_accessor
.Attributes
& MethodAttributes
.MemberAccessMask
);
5942 if (!Set
.IsDummy
& (set_accessor_access
) !=
5943 (set_flags
& MethodAttributes
.MemberAccessMask
))
5944 Report
.Error (507, Location
, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
5945 GetSignatureForError (container
), TypeManager
.GetFullNameSignature (parent_property
));
5950 // Get the less restrictive access
5952 return get_accessor_access
> set_accessor_access
? get_accessor
: set_accessor
;
5955 public override void Emit ()
5958 // The PropertyBuilder can be null for explicit implementations, in that
5959 // case, we do not actually emit the ".property", so there is nowhere to
5960 // put the attribute
5962 if (PropertyBuilder
!= null && OptAttributes
!= null)
5963 OptAttributes
.Emit (ec
, this);
5975 /// Tests whether accessors are not in collision with some method (CS0111)
5977 public bool AreAccessorsDuplicateImplementation (MethodCore mc
)
5979 return Get
.IsDuplicateImplementation (mc
) || Set
.IsDuplicateImplementation (mc
);
5982 protected override void UpdateMemberName ()
5984 base.UpdateMemberName ();
5986 Get
.UpdateName (this);
5987 Set
.UpdateName (this);
5991 public override string[] ValidAttributeTargets
{
5993 return attribute_targets
;
5998 public class Property
: PropertyBase
, IIteratorContainer
{
5999 const int AllowedModifiers
=
6002 Modifiers
.PROTECTED
|
6003 Modifiers
.INTERNAL
|
6007 Modifiers
.OVERRIDE
|
6008 Modifiers
.ABSTRACT
|
6011 Modifiers
.METHOD_YIELDS
|
6014 const int AllowedInterfaceModifiers
=
6017 public Property (TypeContainer ds
, Expression type
, int mod
, bool is_iface
,
6018 MemberName name
, Attributes attrs
, Accessor get_block
,
6019 Accessor set_block
, Location loc
)
6020 : base (ds
, type
, mod
,
6021 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
6022 is_iface
, name
, Parameters
.EmptyReadOnlyParameters
, attrs
,
6025 if (get_block
== null)
6026 Get
= new GetMethod (this);
6028 Get
= new GetMethod (this, get_block
);
6030 if (set_block
== null)
6031 Set
= new SetMethod (this);
6033 Set
= new SetMethod (this, set_block
);
6036 public override bool Define ()
6038 if (!base.Define ())
6044 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
6048 GetBuilder
= Get
.Define (Parent
);
6049 if (GetBuilder
== null)
6053 // Setup iterator if we are one
6055 if ((ModFlags
& Modifiers
.METHOD_YIELDS
) != 0){
6056 Iterator iterator
= new Iterator (
6057 Parent
, "get", MemberType
,
6058 TypeManager
.NoTypes
, Get
.ParameterInfo
,
6059 ModFlags
, Get
.Block
, Location
);
6061 if (!iterator
.DefineIterator ())
6063 Get
.Block
= iterator
.Block
;
6068 SetBuilder
= Set
.Define (Parent
);
6069 if (SetBuilder
== null)
6072 SetBuilder
.DefineParameter (1, ParameterAttributes
.None
, "value");
6075 // FIXME - PropertyAttributes.HasDefault ?
6077 PropertyAttributes prop_attr
= PropertyAttributes
.None
;
6079 prop_attr
|= PropertyAttributes
.RTSpecialName
|
6080 PropertyAttributes
.SpecialName
;
6082 PropertyBuilder
= Parent
.TypeBuilder
.DefineProperty (
6083 Name
, prop_attr
, MemberType
, null);
6086 PropertyBuilder
.SetGetMethod (GetBuilder
);
6089 PropertyBuilder
.SetSetMethod (SetBuilder
);
6091 TypeManager
.RegisterProperty (PropertyBuilder
, GetBuilder
, SetBuilder
);
6095 public void SetYields ()
6097 ModFlags
|= Modifiers
.METHOD_YIELDS
;
6102 /// Gigantic workaround for lameness in SRE follows :
6103 /// This class derives from EventInfo and attempts to basically
6104 /// wrap around the EventBuilder so that FindMembers can quickly
6105 /// return this in it search for members
6107 public class MyEventBuilder
: EventInfo
{
6110 // We use this to "point" to our Builder which is
6111 // not really a MemberInfo
6113 EventBuilder MyBuilder
;
6116 // We "catch" and wrap these methods
6118 MethodInfo raise
, remove, add;
6120 EventAttributes attributes
;
6121 Type declaring_type
, reflected_type
, event_type
;
6126 public MyEventBuilder (Event ev
, TypeBuilder type_builder
, string name
, EventAttributes event_attr
, Type event_type
)
6128 MyBuilder
= type_builder
.DefineEvent (name
, event_attr
, event_type
);
6130 // And now store the values in our own fields.
6132 declaring_type
= type_builder
;
6134 reflected_type
= type_builder
;
6136 attributes
= event_attr
;
6139 this.event_type
= event_type
;
6143 // Methods that you have to override. Note that you only need
6144 // to "implement" the variants that take the argument (those are
6145 // the "abstract" methods, the others (GetAddMethod()) are
6148 public override MethodInfo
GetAddMethod (bool nonPublic
)
6153 public override MethodInfo
GetRemoveMethod (bool nonPublic
)
6158 public override MethodInfo
GetRaiseMethod (bool nonPublic
)
6164 // These methods make "MyEventInfo" look like a Builder
6166 public void SetRaiseMethod (MethodBuilder raiseMethod
)
6168 raise
= raiseMethod
;
6169 MyBuilder
.SetRaiseMethod (raiseMethod
);
6172 public void SetRemoveOnMethod (MethodBuilder removeMethod
)
6174 remove = removeMethod
;
6175 MyBuilder
.SetRemoveOnMethod (removeMethod
);
6178 public void SetAddOnMethod (MethodBuilder addMethod
)
6181 MyBuilder
.SetAddOnMethod (addMethod
);
6184 public void SetCustomAttribute (CustomAttributeBuilder cb
)
6186 MyBuilder
.SetCustomAttribute (cb
);
6189 public override object [] GetCustomAttributes (bool inherit
)
6191 // FIXME : There's nothing which can be seemingly done here because
6192 // we have no way of getting at the custom attribute objects of the
6197 public override object [] GetCustomAttributes (Type t
, bool inherit
)
6199 // FIXME : Same here !
6203 public override bool IsDefined (Type t
, bool b
)
6208 public override EventAttributes Attributes
{
6214 public override string Name
{
6220 public override Type DeclaringType
{
6222 return declaring_type
;
6226 public override Type ReflectedType
{
6228 return reflected_type
;
6232 public Type EventType
{
6238 public void SetUsed ()
6240 if (my_event
!= null)
6241 my_event
.status
= (FieldBase
.Status
.ASSIGNED
| FieldBase
.Status
.USED
);
6246 /// For case when event is declared like property (with add and remove accessors).
6248 public class EventProperty
: Event
{
6250 static string[] attribute_targets
= new string [] { "event", "property" }
;
6252 public EventProperty (TypeContainer parent
, Expression type
, int mod_flags
,
6253 bool is_iface
, MemberName name
, Object init
,
6254 Attributes attrs
, Accessor
add, Accessor
remove,
6256 : base (parent
, type
, mod_flags
, is_iface
, name
, init
, attrs
, loc
)
6258 Add
= new AddDelegateMethod (this, add);
6259 Remove
= new RemoveDelegateMethod (this, remove);
6262 public override string[] ValidAttributeTargets
{
6264 return attribute_targets
;
6270 /// Event is declared like field.
6272 public class EventField
: Event
{
6274 static string[] attribute_targets
= new string [] { "event", "field", "method" }
;
6276 public EventField (TypeContainer parent
, Expression type
, int mod_flags
,
6277 bool is_iface
, MemberName name
, Object init
,
6278 Attributes attrs
, Location loc
)
6279 : base (parent
, type
, mod_flags
, is_iface
, name
, init
, attrs
, loc
)
6281 Add
= new AddDelegateMethod (this);
6282 Remove
= new RemoveDelegateMethod (this);
6285 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
6287 if (a
.Target
== AttributeTargets
.Field
) {
6288 FieldBuilder
.SetCustomAttribute (cb
);
6292 if (a
.Target
== AttributeTargets
.Method
) {
6293 AddBuilder
.SetCustomAttribute (cb
);
6294 RemoveBuilder
.SetCustomAttribute (cb
);
6298 base.ApplyAttributeBuilder (a
, cb
);
6301 public override string[] ValidAttributeTargets
{
6303 return attribute_targets
;
6308 public abstract class Event
: FieldBase
{
6310 protected sealed class AddDelegateMethod
: DelegateMethod
6313 public AddDelegateMethod (Event method
):
6314 base (method
, "add_")
6318 public AddDelegateMethod (Event method
, Accessor accessor
):
6319 base (method
, accessor
, "add_")
6323 protected override MethodInfo DelegateMethodInfo
{
6325 return TypeManager
.delegate_combine_delegate_delegate
;
6331 protected sealed class RemoveDelegateMethod
: DelegateMethod
6333 public RemoveDelegateMethod (Event method
):
6334 base (method
, "remove_")
6338 public RemoveDelegateMethod (Event method
, Accessor accessor
):
6339 base (method
, accessor
, "remove_")
6343 protected override MethodInfo DelegateMethodInfo
{
6345 return TypeManager
.delegate_remove_delegate_delegate
;
6351 public abstract class DelegateMethod
: AbstractPropertyEventMethod
6353 protected readonly Event method
;
6354 ImplicitParameter param_attr
;
6356 static string[] attribute_targets
= new string [] { "method", "param", "return" }
;
6358 public DelegateMethod (Event method
, string prefix
)
6359 : base (method
, prefix
)
6361 this.method
= method
;
6364 public DelegateMethod (Event method
, Accessor accessor
, string prefix
)
6365 : base (method
, accessor
, prefix
)
6367 this.method
= method
;
6370 protected override void ApplyToExtraTarget(Attribute a
, CustomAttributeBuilder cb
)
6372 if (a
.Target
== AttributeTargets
.Parameter
) {
6373 if (param_attr
== null)
6374 param_attr
= new ImplicitParameter (method_data
.MethodBuilder
);
6376 param_attr
.ApplyAttributeBuilder (a
, cb
);
6380 base.ApplyAttributeBuilder (a
, cb
);
6383 public override AttributeTargets AttributeTargets
{
6385 return AttributeTargets
.Method
;
6389 public override bool IsClsCompliaceRequired(DeclSpace ds
)
6391 return method
.IsClsCompliaceRequired (ds
);
6394 public MethodBuilder
Define (TypeContainer container
, InternalParameters ip
)
6396 method_data
= new MethodData (method
, ip
, method
.ModFlags
,
6397 method
.flags
| MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
, this);
6399 if (!method_data
.Define (container
))
6402 MethodBuilder mb
= method_data
.MethodBuilder
;
6403 mb
.DefineParameter (1, ParameterAttributes
.None
, "value");
6408 public override void Emit (TypeContainer tc
)
6410 if (block
!= null) {
6415 ILGenerator ig
= method_data
.MethodBuilder
.GetILGenerator ();
6416 EmitContext ec
= CreateEmitContext (tc
, ig
);
6417 FieldInfo field_info
= (FieldInfo
)method
.FieldBuilder
;
6419 method_data
.MethodBuilder
.SetImplementationFlags (MethodImplAttributes
.Synchronized
);
6420 if ((method
.ModFlags
& Modifiers
.STATIC
) != 0) {
6421 ig
.Emit (OpCodes
.Ldsfld
, field_info
);
6422 ig
.Emit (OpCodes
.Ldarg_0
);
6423 ig
.Emit (OpCodes
.Call
, DelegateMethodInfo
);
6424 ig
.Emit (OpCodes
.Castclass
, method
.MemberType
);
6425 ig
.Emit (OpCodes
.Stsfld
, field_info
);
6427 ig
.Emit (OpCodes
.Ldarg_0
);
6428 ig
.Emit (OpCodes
.Ldarg_0
);
6429 ig
.Emit (OpCodes
.Ldfld
, field_info
);
6430 ig
.Emit (OpCodes
.Ldarg_1
);
6431 ig
.Emit (OpCodes
.Call
, DelegateMethodInfo
);
6432 ig
.Emit (OpCodes
.Castclass
, method
.MemberType
);
6433 ig
.Emit (OpCodes
.Stfld
, field_info
);
6435 ig
.Emit (OpCodes
.Ret
);
6438 protected abstract MethodInfo DelegateMethodInfo { get; }
6440 public override Type
[] ParameterTypes
{
6442 return new Type
[] { method.MemberType }
;
6446 public override Type ReturnType
{
6448 return TypeManager
.void_type
;
6452 public override EmitContext
CreateEmitContext (TypeContainer tc
,
6455 return new EmitContext (
6456 tc
, method
.Parent
, Location
, ig
, ReturnType
,
6457 method
.ModFlags
, false);
6460 public override string GetSignatureForError (TypeContainer tc
)
6462 return String
.Concat (tc
.Name
, '.', method
.Name
);
6465 public override ObsoleteAttribute
GetObsoleteAttribute ()
6467 return method
.GetObsoleteAttribute (method
.Parent
);
6470 public override string[] ValidAttributeTargets
{
6472 return attribute_targets
;
6478 const int AllowedModifiers
=
6481 Modifiers
.PROTECTED
|
6482 Modifiers
.INTERNAL
|
6487 Modifiers
.OVERRIDE
|
6491 const int AllowedInterfaceModifiers
=
6494 public DelegateMethod Add
, Remove
;
6495 public MyEventBuilder EventBuilder
;
6496 public MethodBuilder AddBuilder
, RemoveBuilder
;
6498 public Event (TypeContainer parent
, Expression type
, int mod_flags
,
6499 bool is_iface
, MemberName name
, Object init
, Attributes attrs
,
6501 : base (parent
, type
, mod_flags
,
6502 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
6503 name
, init
, attrs
, loc
)
6505 IsInterface
= is_iface
;
6508 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
6510 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
)) {
6511 a
.Error_InvalidSecurityParent ();
6515 EventBuilder
.SetCustomAttribute (cb
);
6518 public bool AreAccessorsDuplicateImplementation (MethodCore mc
)
6520 return Add
.IsDuplicateImplementation (mc
) || Remove
.IsDuplicateImplementation (mc
);
6523 public override AttributeTargets AttributeTargets
{
6525 return AttributeTargets
.Event
;
6529 public override bool Define ()
6531 EventAttributes e_attr
;
6532 e_attr
= EventAttributes
.None
;
6537 if (init
!= null && ((ModFlags
& Modifiers
.ABSTRACT
) != 0)){
6538 Report
.Error (74, Location
, "'" + Parent
.Name
+ "." + Name
+
6539 "': abstract event can not have an initializer");
6543 if (!MemberType
.IsSubclassOf (TypeManager
.delegate_type
)) {
6544 Report
.Error (66, Location
, "'" + Parent
.Name
+ "." + Name
+
6545 "' : event must be of a delegate type");
6549 EmitContext ec
= Parent
.EmitContext
;
6551 throw new InternalErrorException ("Event.Define called too early?");
6552 bool old_unsafe
= ec
.InUnsafe
;
6553 ec
.InUnsafe
= InUnsafe
;
6555 Parameter
[] parms
= new Parameter
[1];
6556 parms
[0] = new Parameter (Type
, "value", Parameter
.Modifier
.NONE
, null);
6557 Parameters parameters
= new Parameters (parms
, null, Location
);
6558 Type
[] types
= parameters
.GetParameterInfo (ec
);
6559 InternalParameters ip
= new InternalParameters (types
, parameters
);
6561 ec
.InUnsafe
= old_unsafe
;
6567 // Now define the accessors
6570 AddBuilder
= Add
.Define (Parent
, ip
);
6571 if (AddBuilder
== null)
6574 RemoveBuilder
= Remove
.Define (Parent
, ip
);
6575 if (RemoveBuilder
== null)
6578 EventBuilder
= new MyEventBuilder (this, Parent
.TypeBuilder
, Name
, e_attr
, MemberType
);
6580 if (Add
.Block
== null && Remove
.Block
== null && !IsInterface
) {
6581 FieldBuilder
= Parent
.TypeBuilder
.DefineField (
6583 FieldAttributes
.Private
| ((ModFlags
& Modifiers
.STATIC
) != 0 ? FieldAttributes
.Static
: 0));
6584 TypeManager
.RegisterPrivateFieldOfEvent (
6585 (EventInfo
) EventBuilder
, FieldBuilder
);
6586 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
6589 EventBuilder
.SetAddOnMethod (AddBuilder
);
6590 EventBuilder
.SetRemoveOnMethod (RemoveBuilder
);
6592 TypeManager
.RegisterEvent (EventBuilder
, AddBuilder
, RemoveBuilder
);
6596 protected override bool CheckBase ()
6598 if (!base.CheckBase ())
6601 if (conflict_symbol
!= null && (ModFlags
& Modifiers
.NEW
) == 0) {
6602 if (!(conflict_symbol
is EventInfo
)) {
6603 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
6604 Report
.Error (72, Location
, "Event '{0}' can override only event", GetSignatureForError (Parent
));
6612 public override void Emit ()
6614 if (OptAttributes
!= null) {
6615 EmitContext ec
= new EmitContext (
6616 Parent
, Location
, null, MemberType
, ModFlags
);
6617 OptAttributes
.Emit (ec
, this);
6622 Remove
.Emit (Parent
);
6628 public override string GetSignatureForError ()
6630 if (EventBuilder
== null)
6631 return base.GetSignatureForError (Parent
);
6633 return TypeManager
.GetFullNameSignature (EventBuilder
);
6638 public class Indexer
: PropertyBase
{
6640 class GetIndexerMethod
: GetMethod
6642 public GetIndexerMethod (MethodCore method
):
6647 public GetIndexerMethod (MethodCore method
, Accessor accessor
):
6648 base (method
, accessor
)
6652 public override Type
[] ParameterTypes
{
6654 return method
.ParameterTypes
;
6659 class SetIndexerMethod
: SetMethod
6661 readonly Parameters parameters
;
6663 public SetIndexerMethod (MethodCore method
):
6668 public SetIndexerMethod (MethodCore method
, Parameters parameters
, Accessor accessor
):
6669 base (method
, accessor
)
6671 this.parameters
= parameters
;
6674 public override Type
[] ParameterTypes
{
6676 int top
= method
.ParameterTypes
.Length
;
6677 Type
[] set_pars
= new Type
[top
+ 1];
6678 method
.ParameterTypes
.CopyTo (set_pars
, 0);
6679 set_pars
[top
] = method
.MemberType
;
6684 protected override InternalParameters
GetParameterInfo (EmitContext ec
)
6686 Parameter
[] fixed_parms
= parameters
.FixedParameters
;
6688 if (fixed_parms
== null){
6689 throw new Exception ("We currently do not support only array arguments in an indexer at: " + method
.Location
);
6690 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6691 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6693 // Here is the problem: the `value' parameter has
6694 // to come *after* the array parameter in the declaration
6696 // X (object [] x, Type value)
6699 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6700 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
6704 Parameter
[] tmp
= new Parameter
[fixed_parms
.Length
+ 1];
6706 fixed_parms
.CopyTo (tmp
, 0);
6707 tmp
[fixed_parms
.Length
] = new Parameter (
6708 method
.Type
, "value", Parameter
.Modifier
.NONE
, null);
6710 Parameters set_formal_params
= new Parameters (tmp
, null, method
.Location
);
6711 Type
[] types
= set_formal_params
.GetParameterInfo (ec
);
6713 return new InternalParameters (types
, set_formal_params
);
6718 const int AllowedModifiers
=
6721 Modifiers
.PROTECTED
|
6722 Modifiers
.INTERNAL
|
6726 Modifiers
.OVERRIDE
|
6731 const int AllowedInterfaceModifiers
=
6735 public Indexer (TypeContainer ds
, Expression type
, MemberName name
, int mod
,
6736 bool is_iface
, Parameters parameters
, Attributes attrs
,
6737 Accessor get_block
, Accessor set_block
, Location loc
)
6738 : base (ds
, type
, mod
,
6739 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
6740 is_iface
, name
, parameters
, attrs
, loc
)
6742 if (get_block
== null)
6743 Get
= new GetIndexerMethod (this);
6745 Get
= new GetIndexerMethod (this, get_block
);
6747 if (set_block
== null)
6748 Set
= new SetIndexerMethod (this);
6750 Set
= new SetIndexerMethod (this, parameters
, set_block
);
6753 public override bool Define ()
6755 PropertyAttributes prop_attr
=
6756 PropertyAttributes
.RTSpecialName
|
6757 PropertyAttributes
.SpecialName
;
6759 if (!base.Define ())
6762 if (OptAttributes
!= null) {
6763 Attribute indexer_attr
= OptAttributes
.GetIndexerNameAttribute (ec
);
6764 if (indexer_attr
!= null) {
6765 ShortName
= indexer_attr
.GetIndexerAttributeValue (ec
);
6767 if (IsExplicitImpl
) {
6768 Report
.Error (415, indexer_attr
.Location
,
6769 "The 'IndexerName' attribute is valid only on an" +
6770 "indexer that is not an explicit interface member declaration");
6774 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
6775 Report
.Error (609, indexer_attr
.Location
,
6776 "Cannot set the 'IndexerName' attribute on an indexer marked override");
6780 if (!Tokenizer
.IsValidIdentifier (ShortName
)) {
6781 Report
.Error (633, indexer_attr
.Location
,
6782 "The argument to the 'IndexerName' attribute must be a valid identifier");
6786 UpdateMemberName ();
6790 if (InterfaceType
!= null) {
6791 string parent_IndexerName
= TypeManager
.IndexerPropertyName (InterfaceType
);
6792 if (parent_IndexerName
!= Name
)
6793 ShortName
= parent_IndexerName
;
6794 UpdateMemberName ();
6797 if (!Parent
.AddToMemberContainer (this, true) ||
6798 !Parent
.AddToMemberContainer (Get
, true) || !Parent
.AddToMemberContainer (Set
, true))
6804 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
6806 GetBuilder
= Get
.Define (Parent
);
6807 if (GetBuilder
== null)
6812 SetBuilder
= Set
.Define (Parent
);
6813 if (SetBuilder
== null)
6818 // Now name the parameters
6820 Parameter
[] p
= Parameters
.FixedParameters
;
6822 if ((p
[0].ModFlags
& Parameter
.Modifier
.ISBYREF
) != 0) {
6823 Report
.Error (631, Location
, "ref and out are not valid in this context");
6829 for (i
= 0; i
< p
.Length
; ++i
) {
6831 GetBuilder
.DefineParameter (
6832 i
+ 1, p
[i
].Attributes
, p
[i
].Name
);
6835 SetBuilder
.DefineParameter (
6836 i
+ 1, p
[i
].Attributes
, p
[i
].Name
);
6840 SetBuilder
.DefineParameter (
6841 i
+ 1, ParameterAttributes
.None
, "value");
6843 if (i
!= ParameterTypes
.Length
) {
6844 Parameter array_param
= Parameters
.ArrayParameter
;
6846 SetBuilder
.DefineParameter (
6847 i
+ 1, array_param
.Attributes
, array_param
.Name
);
6851 PropertyBuilder
= Parent
.TypeBuilder
.DefineProperty (
6852 Name
, prop_attr
, MemberType
, ParameterTypes
);
6855 PropertyBuilder
.SetGetMethod (GetBuilder
);
6858 PropertyBuilder
.SetSetMethod (SetBuilder
);
6860 TypeManager
.RegisterIndexer (PropertyBuilder
, GetBuilder
, SetBuilder
, ParameterTypes
);
6865 public override string GetSignatureForError ()
6867 if (PropertyBuilder
== null)
6868 return GetSignatureForError (Parent
);
6870 return TypeManager
.CSharpSignature (PropertyBuilder
, true);
6873 public override string GetSignatureForError(TypeContainer tc
)
6875 return String
.Concat (tc
.Name
, ".this[", Parameters
.FixedParameters
[0].TypeName
.ToString (), ']');
6879 public class Operator
: MethodCore
, IIteratorContainer
{
6881 const int AllowedModifiers
=
6887 public enum OpType
: byte {
6897 // Unary and Binary operators
6920 // Implicit and Explicit
6925 public readonly OpType OperatorType
;
6926 public MethodBuilder OperatorMethodBuilder
;
6928 public Method OperatorMethod
;
6930 static string[] attribute_targets
= new string [] { "method", "return" }
;
6932 public Operator (TypeContainer parent
, OpType type
, Expression ret_type
,
6933 int mod_flags
, Parameters parameters
,
6934 ToplevelBlock block
, Attributes attrs
, Location loc
)
6935 : base (parent
, ret_type
, mod_flags
, AllowedModifiers
, false,
6936 new MemberName ("op_" + type
), attrs
, parameters
, loc
)
6938 OperatorType
= type
;
6942 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
6944 OperatorMethod
.ApplyAttributeBuilder (a
, cb
);
6947 public override AttributeTargets AttributeTargets
{
6949 return AttributeTargets
.Method
;
6953 protected override bool CheckForDuplications()
6955 ArrayList ar
= Parent
.Operators
;
6957 int arLen
= ar
.Count
;
6959 for (int i
= 0; i
< arLen
; i
++) {
6960 Operator o
= (Operator
) ar
[i
];
6961 if (IsDuplicateImplementation (o
))
6966 ar
= Parent
.Methods
;
6968 int arLen
= ar
.Count
;
6970 for (int i
= 0; i
< arLen
; i
++) {
6971 Method m
= (Method
) ar
[i
];
6972 if (IsDuplicateImplementation (m
))
6980 public override bool Define ()
6983 const int RequiredModifiers
= Modifiers
.PUBLIC
| Modifiers
.STATIC
;
6984 if ((ModFlags
& RequiredModifiers
) != RequiredModifiers
){
6985 Report
.Error (558, Location
, "User defined operators '{0}' must be declared static and public", GetSignatureForError (Parent
));
6992 OperatorMethod
= new Method (
6993 Parent
, Type
, ModFlags
, false, MemberName
,
6994 Parameters
, OptAttributes
, Location
);
6996 OperatorMethod
.Block
= Block
;
6997 OperatorMethod
.IsOperator
= true;
6998 OperatorMethod
.flags
|= MethodAttributes
.SpecialName
| MethodAttributes
.HideBySig
;
6999 OperatorMethod
.Define ();
7001 if (OperatorMethod
.MethodBuilder
== null)
7004 OperatorMethodBuilder
= OperatorMethod
.MethodBuilder
;
7006 parameter_types
= OperatorMethod
.ParameterTypes
;
7007 Type declaring_type
= OperatorMethodBuilder
.DeclaringType
;
7008 Type return_type
= OperatorMethod
.ReturnType
;
7009 Type first_arg_type
= parameter_types
[0];
7014 // Rules for conversion operators
7016 if (OperatorType
== OpType
.Implicit
|| OperatorType
== OpType
.Explicit
) {
7017 if (first_arg_type
== return_type
&& first_arg_type
== declaring_type
){
7020 "User-defined conversion cannot take an object of the " +
7021 "enclosing type and convert to an object of the enclosing" +
7026 if (first_arg_type
!= declaring_type
&& return_type
!= declaring_type
){
7029 "User-defined conversion must convert to or from the " +
7034 if (first_arg_type
== TypeManager
.object_type
||
7035 return_type
== TypeManager
.object_type
){
7038 "User-defined conversion cannot convert to or from " +
7043 if (first_arg_type
.IsInterface
|| return_type
.IsInterface
){
7046 "User-defined conversion cannot convert to or from an " +
7051 if (first_arg_type
.IsSubclassOf (return_type
)
7052 || return_type
.IsSubclassOf (first_arg_type
)){
7053 if (declaring_type
.IsSubclassOf (return_type
)) {
7054 Report
.Error (553, Location
, "'{0}' : user defined conversion to/from base class", GetSignatureForError ());
7057 Report
.Error (554, Location
, "'{0}' : user defined conversion to/from derived class", GetSignatureForError ());
7060 } else if (OperatorType
== OpType
.LeftShift
|| OperatorType
== OpType
.RightShift
) {
7061 if (first_arg_type
!= declaring_type
|| parameter_types
[1] != TypeManager
.int32_type
) {
7062 Report
.Error (564, Location
, "Overloaded shift operator must have the type of the first operand be the containing type, and the type of the second operand must be int");
7065 } else if (Parameters
.FixedParameters
.Length
== 1) {
7066 // Checks for Unary operators
7068 if (OperatorType
== OpType
.Increment
|| OperatorType
== OpType
.Decrement
) {
7069 if (return_type
!= declaring_type
&& !return_type
.IsSubclassOf (declaring_type
)) {
7070 Report
.Error (448, Location
,
7071 "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7074 if (first_arg_type
!= declaring_type
) {
7076 559, Location
, "The parameter type for ++ or -- operator must be the containing type");
7081 if (first_arg_type
!= declaring_type
){
7084 "The parameter of a unary operator must be the " +
7089 if (OperatorType
== OpType
.True
|| OperatorType
== OpType
.False
) {
7090 if (return_type
!= TypeManager
.bool_type
){
7093 "The return type of operator True or False " +
7100 // Checks for Binary operators
7102 if (first_arg_type
!= declaring_type
&&
7103 parameter_types
[1] != declaring_type
){
7106 "One of the parameters of a binary operator must " +
7107 "be the containing type");
7115 public override void Emit ()
7118 // abstract or extern methods have no bodies
7120 if ((ModFlags
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) != 0)
7123 OperatorMethod
.Emit ();
7127 // Operator cannot be override
7128 protected override MethodInfo
FindOutParentMethod (TypeContainer container
, ref Type parent_ret_type
)
7133 public static string GetName (OpType ot
)
7136 case OpType
.LogicalNot
:
7138 case OpType
.OnesComplement
:
7140 case OpType
.Increment
:
7142 case OpType
.Decrement
:
7148 case OpType
.Addition
:
7150 case OpType
.Subtraction
:
7152 case OpType
.UnaryPlus
:
7154 case OpType
.UnaryNegation
:
7156 case OpType
.Multiply
:
7158 case OpType
.Division
:
7160 case OpType
.Modulus
:
7162 case OpType
.BitwiseAnd
:
7164 case OpType
.BitwiseOr
:
7166 case OpType
.ExclusiveOr
:
7168 case OpType
.LeftShift
:
7170 case OpType
.RightShift
:
7172 case OpType
.Equality
:
7174 case OpType
.Inequality
:
7176 case OpType
.GreaterThan
:
7178 case OpType
.LessThan
:
7180 case OpType
.GreaterThanOrEqual
:
7182 case OpType
.LessThanOrEqual
:
7184 case OpType
.Implicit
:
7186 case OpType
.Explicit
:
7192 public override string GetSignatureForError (TypeContainer tc
)
7194 StringBuilder sb
= new StringBuilder ();
7195 sb
.AppendFormat ("{0}.operator {1} {2}({3}", tc
.Name
, GetName (OperatorType
), Type
.Type
== null ? Type
.ToString () : TypeManager
.CSharpName (Type
.Type
),
7196 Parameters
.FixedParameters
[0].GetSignatureForError ());
7198 if (Parameters
.FixedParameters
.Length
> 1) {
7200 sb
.Append (Parameters
.FixedParameters
[1].GetSignatureForError ());
7203 return sb
.ToString ();
7206 public override string GetSignatureForError ()
7211 public override string ToString ()
7213 if (OperatorMethod
== null)
7216 Type return_type
= OperatorMethod
.ReturnType
;
7217 Type
[] param_types
= OperatorMethod
.ParameterTypes
;
7219 if (Parameters
.FixedParameters
.Length
== 1)
7220 return String
.Format (
7221 "{0} operator {1}({2})",
7222 TypeManager
.CSharpName (return_type
),
7223 GetName (OperatorType
),
7226 return String
.Format (
7227 "{0} operator {1}({2}, {3})",
7228 TypeManager
.CSharpName (return_type
),
7229 GetName (OperatorType
),
7230 param_types
[0], param_types
[1]);
7233 public override string[] ValidAttributeTargets
{
7235 return attribute_targets
;
7239 public void SetYields ()
7241 ModFlags
|= Modifiers
.METHOD_YIELDS
;
7246 // This is used to compare method signatures
7248 struct MethodSignature
{
7250 public Type RetType
;
7251 public Type
[] Parameters
;
7254 /// This delegate is used to extract methods which have the
7255 /// same signature as the argument
7257 public static MemberFilter method_signature_filter
= new MemberFilter (MemberSignatureCompare
);
7259 public MethodSignature (string name
, Type ret_type
, Type
[] parameters
)
7264 if (parameters
== null)
7265 Parameters
= TypeManager
.NoTypes
;
7267 Parameters
= parameters
;
7270 public override string ToString ()
7273 if (Parameters
.Length
!= 0){
7274 System
.Text
.StringBuilder sb
= new System
.Text
.StringBuilder ();
7275 for (int i
= 0; i
< Parameters
.Length
; i
++){
7276 sb
.Append (Parameters
[i
]);
7277 if (i
+1 < Parameters
.Length
)
7280 pars
= sb
.ToString ();
7283 return String
.Format ("{0} {1} ({2})", RetType
, Name
, pars
);
7286 public override int GetHashCode ()
7288 return Name
.GetHashCode ();
7291 public override bool Equals (Object o
)
7293 MethodSignature other
= (MethodSignature
) o
;
7295 if (other
.Name
!= Name
)
7298 if (other
.RetType
!= RetType
)
7301 if (Parameters
== null){
7302 if (other
.Parameters
== null)
7307 if (other
.Parameters
== null)
7310 int c
= Parameters
.Length
;
7311 if (other
.Parameters
.Length
!= c
)
7314 for (int i
= 0; i
< c
; i
++)
7315 if (other
.Parameters
[i
] != Parameters
[i
])
7321 static bool MemberSignatureCompare (MemberInfo m
, object filter_criteria
)
7323 MethodSignature sig
= (MethodSignature
) filter_criteria
;
7325 if (m
.Name
!= sig
.Name
)
7329 MethodInfo mi
= m
as MethodInfo
;
7330 PropertyInfo pi
= m
as PropertyInfo
;
7333 ReturnType
= mi
.ReturnType
;
7334 else if (pi
!= null)
7335 ReturnType
= pi
.PropertyType
;
7340 // we use sig.RetType == null to mean `do not check the
7341 // method return value.
7343 if (sig
.RetType
!= null)
7344 if (ReturnType
!= sig
.RetType
)
7349 args
= TypeManager
.GetArgumentTypes (mi
);
7351 args
= TypeManager
.GetArgumentTypes (pi
);
7352 Type
[] sigp
= sig
.Parameters
;
7354 if (args
.Length
!= sigp
.Length
)
7357 for (int i
= args
.Length
; i
> 0; ){
7359 if (args
[i
] != sigp
[i
])