2 // class.cs: Class and Struct handlers
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 // Martin Baulig (martin@ximian.com)
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)
11 // (C) 2004 Novell, Inc
14 // 2002-10-11 Miguel de Icaza <miguel@ximian.com>
16 // * class.cs: Following the comment from 2002-09-26 to AddMethod, I
17 // have fixed a remaining problem: not every AddXXXX was adding a
18 // fully qualified name.
20 // Now everyone registers a fully qualified name in the DeclSpace as
21 // being defined instead of the partial name.
23 // Downsides: we are slower than we need to be due to the excess
24 // copies and the names being registered this way.
26 // The reason for this is that we currently depend (on the corlib
27 // bootstrap for instance) that types are fully qualified, because
28 // we dump all the types in the namespace, and we should really have
29 // types inserted into the proper namespace, so we can only store the
30 // basenames in the defined_names array.
36 using System
.Collections
;
37 using System
.Collections
.Specialized
;
38 using System
.Reflection
;
39 using System
.Reflection
.Emit
;
40 using System
.Runtime
.CompilerServices
;
41 using System
.Runtime
.InteropServices
;
42 using System
.Security
;
43 using System
.Security
.Permissions
;
46 using Mono
.CompilerServices
.SymbolWriter
;
48 namespace Mono
.CSharp
{
58 /// This is the base class for structs and classes.
60 public abstract class TypeContainer
: DeclSpace
, IMemberContainer
{
62 public class MemberCoreArrayList
: ArrayList
65 /// Defines the MemberCore objects that are in this array
67 public virtual void DefineContainerMembers ()
69 foreach (MemberCore mc
in this) {
74 public virtual void Emit ()
76 foreach (MemberCore mc
in this)
81 public class MethodArrayList
: MemberCoreArrayList
89 CachedMethods cached_method
;
90 TypeContainer container
;
92 public MethodArrayList (TypeContainer container
)
94 this.container
= container
;
98 /// Method container contains Equals method
100 public bool HasEquals
{
102 cached_method
|= CachedMethods
.Equals
;
106 return (cached_method
& CachedMethods
.Equals
) != 0;
111 /// Method container contains GetHashCode method
113 public bool HasGetHashCode
{
115 cached_method
|= CachedMethods
.GetHashCode
;
119 return (cached_method
& CachedMethods
.GetHashCode
) != 0;
123 public override void DefineContainerMembers ()
125 base.DefineContainerMembers ();
127 if ((RootContext
.WarningLevel
>= 3) && HasEquals
&& !HasGetHashCode
) {
128 Report
.Warning (659, container
.Location
, "'{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container
.GetSignatureForError ());
134 public sealed class IndexerArrayList
: MemberCoreArrayList
137 /// The indexer name for this container
139 public string IndexerName
= DefaultIndexerName
;
141 bool seen_normal_indexers
= false;
143 TypeContainer container
;
145 public IndexerArrayList (TypeContainer container
)
147 this.container
= container
;
151 /// Defines the indexers, and also verifies that the IndexerNameAttribute in the
152 /// class is consistent. Either it is `Item' or it is the name defined by all the
153 /// indexers with the `IndexerName' attribute.
155 /// Turns out that the IndexerNameAttribute is applied to each indexer,
156 /// but it is never emitted, instead a DefaultMember attribute is attached
159 public override void DefineContainerMembers()
161 base.DefineContainerMembers ();
163 string class_indexer_name
= null;
166 // If there's both an explicit and an implicit interface implementation, the
167 // explicit one actually implements the interface while the other one is just
168 // a normal indexer. See bug #37714.
171 // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
172 foreach (Indexer i
in this) {
173 if (i
.InterfaceType
!= null) {
174 if (seen_normal_indexers
)
175 throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
179 seen_normal_indexers
= true;
181 if (class_indexer_name
== null) {
182 class_indexer_name
= i
.ShortName
;
186 if (i
.ShortName
!= class_indexer_name
)
187 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");
190 if (class_indexer_name
!= null)
191 IndexerName
= class_indexer_name
;
194 public override void Emit ()
198 if (!seen_normal_indexers
)
201 CustomAttributeBuilder cb
= new CustomAttributeBuilder (TypeManager
.default_member_ctor
, new string [] { IndexerName }
);
202 container
.TypeBuilder
.SetCustomAttribute (cb
);
206 public class OperatorArrayList
: MemberCoreArrayList
208 TypeContainer container
;
210 public OperatorArrayList (TypeContainer container
)
212 this.container
= container
;
216 // Operator pair checking
221 public Type ret_type
;
222 public Type type1
, type2
;
224 public Operator
.OpType ot
;
226 public OperatorEntry (int f
, Operator o
)
230 ret_type
= o
.OperatorMethod
.ReturnType
;
231 Type
[] pt
= o
.OperatorMethod
.ParameterTypes
;
238 public override int GetHashCode ()
240 return ret_type
.GetHashCode ();
243 public override bool Equals (object o
)
245 OperatorEntry other
= (OperatorEntry
) o
;
247 if (other
.ret_type
!= ret_type
)
249 if (other
.type1
!= type1
)
251 if (other
.type2
!= type2
)
258 // Checks that some operators come in pairs:
264 // They are matched based on the return type and the argument types
266 void CheckPairedOperators ()
268 Hashtable pairs
= new Hashtable (null, null);
269 Operator true_op
= null;
270 Operator false_op
= null;
271 bool has_equality_or_inequality
= false;
273 // Register all the operators we care about.
274 foreach (Operator op
in this){
277 switch (op
.OperatorType
){
278 case Operator
.OpType
.Equality
:
280 has_equality_or_inequality
= true;
282 case Operator
.OpType
.Inequality
:
284 has_equality_or_inequality
= true;
287 case Operator
.OpType
.True
:
290 case Operator
.OpType
.False
:
294 case Operator
.OpType
.GreaterThan
:
296 case Operator
.OpType
.LessThan
:
299 case Operator
.OpType
.GreaterThanOrEqual
:
301 case Operator
.OpType
.LessThanOrEqual
:
307 OperatorEntry oe
= new OperatorEntry (reg
, op
);
309 object o
= pairs
[oe
];
313 oe
= (OperatorEntry
) o
;
318 if (true_op
!= null){
319 if (false_op
== null)
320 Report
.Error (216, true_op
.Location
, "operator true requires a matching operator false");
321 } else if (false_op
!= null)
322 Report
.Error (216, false_op
.Location
, "operator false requires a matching operator true");
325 // Look for the mistakes.
327 foreach (DictionaryEntry de
in pairs
){
328 OperatorEntry oe
= (OperatorEntry
) de
.Key
;
335 case Operator
.OpType
.Equality
:
338 case Operator
.OpType
.Inequality
:
341 case Operator
.OpType
.GreaterThan
:
344 case Operator
.OpType
.LessThan
:
347 case Operator
.OpType
.GreaterThanOrEqual
:
350 case Operator
.OpType
.LessThanOrEqual
:
354 Report
.Error (216, oe
.op
.Location
,
355 "The operator `" + oe
.op
+ "' requires a matching operator `" + s
+ "' to also be defined");
358 if (has_equality_or_inequality
&& (RootContext
.WarningLevel
> 2)) {
359 if (container
.Methods
== null || !container
.Methods
.HasEquals
)
360 Report
.Warning (660, container
.Location
, "'{0}' defines operator == or operator != but does not override Object.Equals(object o)", container
.GetSignatureForError ());
362 if (container
.Methods
== null || !container
.Methods
.HasGetHashCode
)
363 Report
.Warning (661, container
.Location
, "'{0}' defines operator == or operator != but does not override Object.GetHashCode()", container
.GetSignatureForError ());
367 public override void DefineContainerMembers ()
369 base.DefineContainerMembers ();
370 CheckPairedOperators ();
375 // Whether this is a struct, class or interface
376 public readonly Kind Kind
;
378 // Holds a list of classes and structures
381 // Holds the list of properties
382 MemberCoreArrayList properties
;
384 // Holds the list of enumerations
385 MemberCoreArrayList enums
;
387 // Holds the list of delegates
388 MemberCoreArrayList delegates
;
390 // Holds the list of constructors
391 protected MemberCoreArrayList instance_constructors
;
393 // Holds the list of fields
394 MemberCoreArrayList fields
;
396 // Holds a list of fields that have initializers
397 protected ArrayList initialized_fields
;
399 // Holds a list of static fields that have initializers
400 protected ArrayList initialized_static_fields
;
402 // Holds the list of constants
403 MemberCoreArrayList constants
;
406 MemberCoreArrayList interfaces
;
408 // Holds the methods.
409 MethodArrayList methods
;
412 protected MemberCoreArrayList events
;
414 // Holds the indexers
415 IndexerArrayList indexers
;
417 // Holds the operators
418 MemberCoreArrayList operators
;
420 // Holds the iterators
423 // Holds the parts of a partial class;
427 // Pointers to the default constructor and the default static constructor
429 protected Constructor default_constructor
;
430 protected Constructor default_static_constructor
;
433 // Whether we have at least one non-static field
435 bool have_nonstatic_fields
= false;
438 // This one is computed after we can distinguish interfaces
439 // from classes from the arraylist `type_bases'
441 string base_class_name
;
444 ArrayList type_bases
;
446 bool members_defined
;
447 bool members_defined_ok
;
449 // The interfaces we implement.
450 protected Type
[] ifaces
;
451 protected Type ptype
;
453 // The base member cache and our member cache
454 MemberCache base_cache
;
455 MemberCache member_cache
;
457 public const string DefaultIndexerName
= "Item";
461 public TypeContainer (NamespaceEntry ns
, TypeContainer parent
, MemberName name
,
462 Attributes attrs
, Kind kind
, Location l
)
463 : base (ns
, parent
, name
, attrs
, l
)
467 types
= new ArrayList ();
469 base_class_name
= null;
472 public bool AddToMemberContainer (MemberCore symbol
)
474 return AddToContainer (symbol
, String
.Concat (Name
, '.', symbol
.Name
), symbol
.Name
);
477 bool AddToTypeContainer (DeclSpace ds
)
479 return AddToContainer (ds
, ds
.Name
, ds
.Basename
);
482 public void AddConstant (Const constant
)
484 if (!AddToMemberContainer (constant
))
487 if (constants
== null)
488 constants
= new MemberCoreArrayList ();
490 constants
.Add (constant
);
493 public void AddEnum (Mono
.CSharp
.Enum e
)
495 if (!AddToTypeContainer (e
))
499 enums
= new MemberCoreArrayList ();
504 public void AddClassOrStruct (TypeContainer c
)
506 if (!AddToTypeContainer (c
))
512 public void AddDelegate (Delegate d
)
514 if (!AddToTypeContainer (d
))
517 if (delegates
== null)
518 delegates
= new MemberCoreArrayList ();
523 public void AddMethod (Method method
)
525 if (!AddToMemberContainer (method
))
529 methods
= new MethodArrayList (this);
531 if (method
.Name
.IndexOf ('.') != -1)
532 methods
.Insert (0, method
);
534 methods
.Add (method
);
537 public void AddConstructor (Constructor c
)
539 if (c
.Name
!= Basename
) {
540 Report
.Error (1520, c
.Location
, "Class, struct, or interface method must have a return type");
543 bool is_static
= (c
.ModFlags
& Modifiers
.STATIC
) != 0;
546 if (default_static_constructor
!= null) {
547 Report
.SymbolRelatedToPreviousError (default_static_constructor
);
548 Report
.Error (111, c
.Location
, "Type '{0}' already defines a member " +
549 "called '{1}' with the same parameter types", Name
, c
.Name
);
553 default_static_constructor
= c
;
556 if (default_constructor
!= null) {
557 Report
.SymbolRelatedToPreviousError (default_constructor
);
558 Report
.Error (111, c
.Location
, "Type '{0}' already defines a member " +
559 "called '{1}' with the same parameter types", Name
, c
.Name
);
562 default_constructor
= c
;
565 if (instance_constructors
== null)
566 instance_constructors
= new MemberCoreArrayList ();
568 instance_constructors
.Add (c
);
572 public void AddInterface (TypeContainer iface
)
574 if (!AddToTypeContainer (iface
))
577 if (interfaces
== null) {
578 interfaces
= new MemberCoreArrayList ();
581 interfaces
.Add (iface
);
584 public void AddField (Field field
)
586 if (!AddToMemberContainer (field
))
590 fields
= new MemberCoreArrayList ();
594 if (field
.HasInitializer
){
595 if ((field
.ModFlags
& Modifiers
.STATIC
) != 0){
596 if (initialized_static_fields
== null)
597 initialized_static_fields
= new ArrayList ();
599 initialized_static_fields
.Add (field
);
602 if (initialized_fields
== null)
603 initialized_fields
= new ArrayList ();
605 initialized_fields
.Add (field
);
609 if ((field
.ModFlags
& Modifiers
.STATIC
) == 0)
610 have_nonstatic_fields
= true;
613 public void AddProperty (Property prop
)
615 if (!AddToMemberContainer (prop
) ||
616 !AddToMemberContainer (prop
.Get
) || !AddToMemberContainer (prop
.Set
))
619 if (properties
== null)
620 properties
= new MemberCoreArrayList ();
622 if (prop
.Name
.IndexOf ('.') != -1)
623 properties
.Insert (0, prop
);
625 properties
.Add (prop
);
628 public void AddEvent (Event e
)
630 if (!AddToMemberContainer (e
))
633 if (e
is EventProperty
) {
634 if (!AddToMemberContainer (e
.Add
))
637 if (!AddToMemberContainer (e
.Remove
))
642 events
= new MemberCoreArrayList ();
648 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
650 public void AddIndexer (Indexer i
)
652 if (indexers
== null)
653 indexers
= new IndexerArrayList (this);
655 if (i
.IsExplicitImpl
)
656 indexers
.Insert (0, i
);
661 public void AddOperator (Operator op
)
663 if (!AddToMemberContainer (op
))
666 if (operators
== null)
667 operators
= new OperatorArrayList (this);
672 public void AddIterator (Iterator i
)
674 if (iterators
== null)
675 iterators
= new ArrayList ();
680 public void AddType (TypeContainer tc
)
685 public void AddPart (ClassPart part
)
688 parts
= new ArrayList ();
693 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
695 if (a
.Type
== TypeManager
.default_member_type
) {
696 if (Indexers
!= null) {
697 Report
.Error (646, a
.Location
,
698 "Cannot specify the DefaultMember attribute on" +
699 " a type containing an indexer");
704 base.ApplyAttributeBuilder (a
, cb
);
707 public override AttributeTargets AttributeTargets
{
711 return AttributeTargets
.Class
;
713 return AttributeTargets
.Struct
;
715 return AttributeTargets
.Interface
;
717 throw new NotSupportedException ();
722 public ArrayList Types
{
728 public MethodArrayList Methods
{
734 public ArrayList Constants
{
740 public ArrayList Interfaces
{
746 public ArrayList Iterators
{
754 return base_class_name
;
758 public ArrayList Bases
{
768 public ArrayList Fields
{
774 public ArrayList InstanceConstructors
{
776 return instance_constructors
;
780 public ArrayList Properties
{
786 public ArrayList Events
{
792 public ArrayList Enums
{
798 public ArrayList Indexers
{
804 public ArrayList Operators
{
810 public ArrayList Delegates
{
816 public ArrayList Parts
{
822 public virtual TypeAttributes TypeAttr
{
824 return Modifiers
.TypeAttr (ModFlags
, this);
828 public string IndexerName
{
830 return indexers
== null ? DefaultIndexerName
: indexers
.IndexerName
;
835 // Emits the instance field initializers
837 public bool EmitFieldInitializers (EmitContext ec
)
840 Expression instance_expr
;
843 fields
= initialized_static_fields
;
844 instance_expr
= null;
846 fields
= initialized_fields
;
847 instance_expr
= new This (Location
.Null
).Resolve (ec
);
853 foreach (Field f
in fields
){
854 Expression e
= f
.GetInitializerExpression (ec
);
858 Location l
= f
.Location
;
859 FieldExpr fe
= new FieldExpr (f
.FieldBuilder
, l
);
860 fe
.InstanceExpression
= instance_expr
;
861 fe
.IsFieldInitializer
= true;
863 ExpressionStatement a
= new Assign (fe
, e
, l
);
865 a
= a
.ResolveStatement (ec
);
869 a
.EmitStatement (ec
);
876 // Defines the default constructors
878 protected void DefineDefaultConstructor (bool is_static
)
882 // The default constructor is public
883 // If the class is abstract, the default constructor is protected
884 // The default static constructor is private
886 int mods
= Modifiers
.PUBLIC
;
888 mods
= Modifiers
.STATIC
| Modifiers
.PRIVATE
;
889 else if ((ModFlags
& Modifiers
.ABSTRACT
) != 0)
890 mods
= Modifiers
.PROTECTED
;
892 c
= new Constructor (this, Basename
, mods
, Parameters
.EmptyReadOnlyParameters
,
893 new ConstructorBaseInitializer (
894 null, Parameters
.EmptyReadOnlyParameters
,
900 c
.Block
= new ToplevelBlock (null, Location
);
905 /// The pending methods that need to be implemented
906 // (interfaces or abstract methods)
908 public PendingImplementation Pending
;
910 public abstract void Register ();
912 public abstract PendingImplementation
GetPendingImplementations ();
914 TypeExpr
[] GetPartialBases (out TypeExpr base_class
, out bool error
)
916 ArrayList ifaces
= new ArrayList ();
919 Location base_loc
= Location
.Null
;
921 foreach (ClassPart part
in parts
) {
922 TypeExpr new_base_class
;
923 TypeExpr
[] new_ifaces
;
925 new_ifaces
= part
.GetClassBases (out new_base_class
, out error
);
929 if ((base_class
!= null) && (new_base_class
!= null) &&
930 !base_class
.Equals (new_base_class
)) {
931 Report
.Error (263, part
.Location
,
932 "Partial declarations of `{0}' must " +
933 "not specify different base classes",
936 if (!Location
.IsNull (base_loc
))
937 Report
.LocationOfPreviousError (base_loc
);
943 if ((base_class
== null) && (new_base_class
!= null)) {
944 base_class
= new_base_class
;
945 base_loc
= part
.Location
;
948 if (new_ifaces
== null)
951 foreach (TypeExpr iface
in new_ifaces
) {
953 foreach (TypeExpr old_iface
in ifaces
) {
954 if (old_iface
.Equals (iface
)) {
967 TypeExpr
[] retval
= new TypeExpr
[ifaces
.Count
];
968 ifaces
.CopyTo (retval
, 0);
972 TypeExpr
[] GetNormalBases (out TypeExpr base_class
, out bool error
)
976 int count
= Bases
.Count
;
979 if (Kind
== Kind
.Class
){
980 TypeExpr name
= ResolveBaseTypeExpr (
981 (Expression
) Bases
[0], false, Location
);
988 if (!name
.IsInterface
) {
989 // base_class could be a class, struct, enum, delegate.
990 // This is validated in GetClassBases.
996 TypeExpr
[] ifaces
= new TypeExpr
[count
-start
];
998 for (i
= start
, j
= 0; i
< count
; i
++, j
++){
999 TypeExpr resolved
= ResolveBaseTypeExpr ((Expression
) Bases
[i
], false, Location
);
1000 if (resolved
== null) {
1005 ifaces
[j
] = resolved
;
1013 /// This function computes the Base class and also the
1014 /// list of interfaces that the class or struct @c implements.
1016 /// The return value is an array (might be null) of
1017 /// interfaces implemented (as Types).
1019 /// The @base_class argument is set to the base object or null
1020 /// if this is `System.Object'.
1022 TypeExpr
[] GetClassBases (out TypeExpr base_class
, out bool error
)
1031 ifaces
= GetPartialBases (out base_class
, out error
);
1032 else if (Bases
== null){
1036 ifaces
= GetNormalBases (out base_class
, out error
);
1041 if ((base_class
!= null) && (Kind
== Kind
.Class
)){
1042 if (base_class
is TypeParameterExpr
){
1044 689, base_class
.Location
,
1045 "Type parameter `{0}' can not be used as a " +
1046 "base class or interface", base_class
.Name
);
1051 if (IsGeneric
&& base_class
.IsAttribute
){
1053 698, base_class
.Location
,
1054 "A generic type cannot derive from `{0}' " +
1055 "because it is an attribute class",
1061 if (base_class
.Type
.IsArray
|| base_class
.Type
.IsPointer
) {
1062 Report
.Error (1521, base_class
.Location
, "Invalid base type");
1067 if (base_class
.IsSealed
){
1069 Report
.SymbolRelatedToPreviousError (base_class
.Type
);
1070 if (base_class
.Type
.IsAbstract
) {
1071 Report
.Error (709, Location
, "'{0}': Cannot derive from static class", GetSignatureForError ());
1073 Report
.Error (509, Location
, "'{0}': Cannot derive from sealed class", GetSignatureForError ());
1078 if (!base_class
.CanInheritFrom ()){
1079 Report
.Error (644, Location
,
1080 "`{0}' cannot inherit from special class `{1}'",
1081 Name
, base_class
.Name
);
1086 if (!base_class
.AsAccessible (this, ModFlags
)) {
1087 Report
.SymbolRelatedToPreviousError (base_class
.Type
);
1088 Report
.Error (60, Location
, "Inconsistent accessibility: base class '{0}' is less accessible than class '{1}'",
1089 TypeManager
.CSharpName (base_class
.Type
), GetSignatureForError ());
1093 if (base_class
!= null)
1094 base_class_name
= base_class
.Name
;
1099 int count
= ifaces
!= null ? ifaces
.Length
: 0;
1101 for (i
= 0; i
< count
; i
++) {
1102 TypeExpr iface
= (TypeExpr
) ifaces
[i
];
1104 if (!iface
.IsInterface
) {
1106 if (Kind
!= Kind
.Class
) {
1107 string what
= Kind
== Kind
.Struct
? "Struct" : "Interface";
1109 Report
.Error (527, Location
,
1110 "In {0} `{1}', type `{2}' is not "+
1111 "an interface", what
, Name
, iface
.Name
);
1113 else if (base_class
!= null)
1114 Report
.Error (1721, Location
,
1115 "In Class `{0}', `{1}' is not an interface, and a base class has already been defined",
1118 Report
.Error (1722, Location
,
1119 "In Class `{0}', `{1}' is not " +
1120 "an interface, a base class must be listed first", Name
, iface
.Name
);
1125 for (int x
= 0; x
< i
; x
++) {
1126 if (iface
.Equals (ifaces
[x
])) {
1127 Report
.Error (528, Location
,
1128 "`{0}' is already listed in " +
1129 "interface list", iface
.Name
);
1134 if ((Kind
== Kind
.Interface
) &&
1135 !iface
.AsAccessible (Parent
, ModFlags
)) {
1136 Report
.Error (61, Location
,
1137 "Inconsistent accessibility: base " +
1138 "interface `{0}' is less accessible " +
1139 "than interface `{1}'", iface
.Name
,
1151 bool CheckGenericInterfaces (Type
[] ifaces
)
1153 ArrayList already_checked
= new ArrayList ();
1155 for (int i
= 0; i
< ifaces
.Length
; i
++) {
1156 Type iface
= ifaces
[i
];
1157 foreach (Type t
in already_checked
) {
1161 Type
[] infered
= new Type
[CountTypeParameters
];
1162 if (!TypeManager
.MayBecomeEqualGenericInstances (iface
, t
, infered
, null))
1167 "`{0}' cannot implement both `{1}' and `{2}' " +
1168 "because they may unify for some type " +
1169 "parameter substitutions",
1170 TypeManager
.GetFullName (TypeBuilder
),
1175 already_checked
.Add (iface
);
1184 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1186 public override TypeBuilder
DefineType ()
1191 if (TypeBuilder
!= null)
1194 ec
= new EmitContext (this, Mono
.CSharp
.Location
.Null
, null, null, ModFlags
);
1196 TypeAttributes type_attributes
= TypeAttr
;
1200 if (TypeManager
.NamespaceClash (Name
, Location
)) {
1205 ModuleBuilder builder
= CodeGen
.Module
.Builder
;
1206 TypeBuilder
= builder
.DefineType (
1207 Name
, type_attributes
, null, null);
1209 TypeBuilder builder
;
1210 if (Parent
.TypeBuilder
!= null)
1211 builder
= Parent
.TypeBuilder
;
1213 builder
= Parent
.DefineType ();
1215 if (builder
== null) {
1220 TypeBuilder
= builder
.DefineNestedType (
1221 MemberName
.Basename
, type_attributes
,
1225 catch (ArgumentException
) {
1226 Report
.RuntimeMissingSupport (Location
, "static classes");
1230 TypeManager
.AddUserType (Name
, TypeBuilder
, this);
1232 TypeExpr current_type
= null;
1235 string[] param_names
= new string [TypeParameters
.Length
];
1236 for (int i
= 0; i
< TypeParameters
.Length
; i
++)
1237 param_names
[i
] = TypeParameters
[i
].Name
;
1239 GenericTypeParameterBuilder
[] gen_params
;
1240 gen_params
= TypeBuilder
.DefineGenericParameters (param_names
);
1242 int offset
= CountTypeParameters
- CurrentTypeParameters
.Length
;
1243 for (int i
= offset
; i
< gen_params
.Length
; i
++)
1244 CurrentTypeParameters
[i
- offset
].Define (gen_params
[i
]);
1246 foreach (TypeParameter type_param
in CurrentTypeParameters
) {
1247 if (!type_param
.Resolve (this)) {
1253 for (int i
= offset
; i
< gen_params
.Length
; i
++)
1254 CurrentTypeParameters
[i
- offset
].DefineConstraints ();
1256 current_type
= new ConstructedType (Name
, TypeParameters
, Location
);
1258 foreach (TypeParameter type_param
in TypeParameters
) {
1259 if (!type_param
.DefineType (ec
)) {
1265 if (!CheckConstraints (ec
)) {
1271 if ((Kind
== Kind
.Struct
) && TypeManager
.value_type
== null)
1272 throw new Exception ();
1274 TypeExpr
[] iface_exprs
= GetClassBases (out base_type
, out error
);
1278 if (base_type
== null) {
1279 if (Kind
== Kind
.Class
){
1280 if (RootContext
.StdLib
)
1281 base_type
= TypeManager
.system_object_expr
;
1282 else if (Name
!= "System.Object")
1283 base_type
= TypeManager
.system_object_expr
;
1284 } else if (Kind
== Kind
.Struct
){
1286 // If we are compiling our runtime,
1287 // and we are defining ValueType, then our
1288 // base is `System.Object'.
1290 if (!RootContext
.StdLib
&& Name
== "System.ValueType")
1291 base_type
= TypeManager
.system_object_expr
;
1292 else if (Kind
== Kind
.Struct
)
1293 base_type
= TypeManager
.system_valuetype_expr
;
1297 if (base_type
!= null) {
1298 base_type
= base_type
.ResolveAsTypeTerminal (ec
);
1299 if (base_type
== null) {
1304 ptype
= base_type
.Type
;
1307 if (!CheckRecursiveDefinition ()) {
1313 TypeBuilder
.SetParent (ptype
);
1316 // Structs with no fields need to have at least one byte.
1317 // The right thing would be to set the PackingSize in a DefineType
1318 // but there are no functions that allow interfaces *and* the size to
1322 if ((Kind
== Kind
.Struct
) && !have_nonstatic_fields
){
1323 TypeBuilder
.DefineField ("$PRIVATE$", TypeManager
.byte_type
,
1324 FieldAttributes
.Private
);
1327 // add interfaces that were not added at type creation
1328 if (iface_exprs
!= null) {
1329 // FIXME: I think this should be ...ExpandInterfaces (Parent.EmitContext, ...).
1330 // However, if Parent == RootContext.Tree.Types, its NamespaceEntry will be null.
1331 ifaces
= TypeManager
.ExpandInterfaces (ec
, iface_exprs
);
1332 if (ifaces
== null) {
1337 foreach (Type itype
in ifaces
)
1338 TypeBuilder
.AddInterfaceImplementation (itype
);
1340 if (!CheckGenericInterfaces (ifaces
)) {
1345 TypeManager
.RegisterBuilder (TypeBuilder
, ifaces
);
1349 foreach (TypeParameter type_param
in TypeParameters
)
1350 if (!type_param
.CheckDependencies (ec
)) {
1356 if (current_type
!= null) {
1357 current_type
= current_type
.ResolveAsTypeTerminal (ec
);
1358 if (current_type
== null) {
1363 CurrentType
= current_type
.Type
;
1367 // Finish the setup for the EmitContext
1369 ec
.ContainerType
= TypeBuilder
;
1371 if ((base_type
!= null) && base_type
.IsAttribute
) {
1372 RootContext
.RegisterAttribute (this);
1373 } else if (!(this is Iterator
))
1374 RootContext
.RegisterOrder (this);
1376 if (!DefineNestedTypes ()) {
1384 protected virtual bool CheckConstraints (EmitContext ec
)
1389 protected virtual bool DefineNestedTypes ()
1391 if (Interfaces
!= null) {
1392 foreach (TypeContainer iface
in Interfaces
)
1393 if (iface
.DefineType () == null)
1397 if (Types
!= null) {
1398 foreach (TypeContainer tc
in Types
)
1399 if (tc
.DefineType () == null)
1403 if (Delegates
!= null) {
1404 foreach (Delegate d
in Delegates
)
1405 if (d
.DefineType () == null)
1409 if (Enums
!= null) {
1410 foreach (Enum en
in Enums
)
1411 if (en
.DefineType () == null)
1415 if (Parts
!= null) {
1416 foreach (ClassPart part
in Parts
) {
1417 part
.TypeBuilder
= TypeBuilder
;
1418 part
.base_type
= base_type
;
1419 part
.ec
= new EmitContext (part
, Mono
.CSharp
.Location
.Null
, null, null, ModFlags
);
1426 protected bool CheckRecursiveDefinition ()
1429 Report
.Error (146, Location
,
1430 "Class definition is circular: `{0}'",
1431 GetSignatureForError ());
1438 Type parent
= ptype
;
1439 if (parent
!= null) {
1440 if (parent
.IsGenericInstance
)
1441 parent
= parent
.GetGenericTypeDefinition ();
1443 TypeContainer ptc
= TypeManager
.LookupTypeContainer (parent
);
1444 if ((ptc
!= null) && !ptc
.CheckRecursiveDefinition ())
1452 static void Error_KeywordNotAllowed (Location loc
)
1454 Report
.Error (1530, loc
, "Keyword new not allowed for namespace elements");
1458 /// Populates our TypeBuilder with fields and methods
1460 public override bool DefineMembers (TypeContainer container
)
1462 if (members_defined
)
1463 return members_defined_ok
;
1465 members_defined_ok
= DoDefineMembers ();
1466 members_defined
= true;
1468 return members_defined_ok
;
1471 protected virtual bool DoDefineMembers ()
1474 if ((ModFlags
& Modifiers
.NEW
) != 0)
1475 Error_KeywordNotAllowed (Location
);
1477 // HACK: missing implemenation
1478 // This is not fully functional. Better way how to handle this is to have recursive definition of containers
1479 // instead of flat as we have now.
1480 // Now we are not able to check inner attribute class because its parent had not been defined.
1482 // TODO: remove this if
1483 if (Parent
.MemberCache
!= null) {
1484 MemberInfo conflict_symbol
= Parent
.MemberCache
.FindMemberWithSameName (Basename
, false, TypeBuilder
);
1485 if (conflict_symbol
== null) {
1486 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0))
1487 Report
.Warning (109, Location
, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1489 if ((ModFlags
& Modifiers
.NEW
) == 0) {
1490 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
1491 Report
.Warning (108, Location
, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError ());
1497 DefineContainerMembers (constants
);
1498 DefineContainerMembers (fields
);
1500 if ((Kind
== Kind
.Class
) && !(this is ClassPart
)){
1501 if ((instance_constructors
== null) &&
1502 !(this is StaticClass
)) {
1503 if (default_constructor
== null)
1504 DefineDefaultConstructor (false);
1507 if (initialized_static_fields
!= null &&
1508 default_static_constructor
== null)
1509 DefineDefaultConstructor (true);
1512 if (Kind
== Kind
.Struct
){
1514 // Structs can not have initialized instance
1517 if (initialized_static_fields
!= null &&
1518 default_static_constructor
== null)
1519 DefineDefaultConstructor (true);
1521 if (initialized_fields
!= null)
1522 ReportStructInitializedInstanceError ();
1525 Pending
= GetPendingImplementations ();
1527 if (parts
!= null) {
1528 foreach (ClassPart part
in parts
) {
1529 if (!part
.DefineMembers (this))
1535 // Constructors are not in the defined_names array
1537 DefineContainerMembers (instance_constructors
);
1539 if (default_static_constructor
!= null)
1540 default_static_constructor
.Define ();
1542 DefineContainerMembers (properties
);
1543 DefineContainerMembers (events
);
1544 DefineContainerMembers (indexers
);
1545 DefineContainerMembers (methods
);
1546 DefineContainerMembers (operators
);
1547 DefineContainerMembers (enums
);
1548 DefineContainerMembers (delegates
);
1550 if (CurrentType
!= null) {
1551 GenericType
= CurrentType
;
1553 ec
.ContainerType
= GenericType
;
1558 if (!(this is ClassPart
))
1559 member_cache
= new MemberCache (this);
1562 if (parts
!= null) {
1563 foreach (ClassPart part
in parts
)
1564 part
.member_cache
= member_cache
;
1567 if (iterators
!= null) {
1568 foreach (Iterator iterator
in iterators
) {
1569 if (iterator
.DefineType () == null)
1573 foreach (Iterator iterator
in iterators
) {
1574 if (!iterator
.DefineMembers (this))
1582 void ReportStructInitializedInstanceError ()
1584 string n
= TypeBuilder
.FullName
;
1586 foreach (Field f
in initialized_fields
){
1589 "`" + n
+ "." + f
.Name
+ "': can not have " +
1590 "instance field initializers in structs");
1594 protected virtual void DefineContainerMembers (MemberCoreArrayList mcal
)
1597 mcal
.DefineContainerMembers ();
1600 public override bool Define ()
1602 if (parts
!= null) {
1603 foreach (ClassPart part
in parts
) {
1604 if (!part
.Define ())
1612 public MemberInfo
FindBaseMemberWithSameName (string name
, bool ignore_methods
)
1614 return BaseCache
.FindMemberWithSameName (name
, ignore_methods
, null);
1618 /// This function is based by a delegate to the FindMembers routine
1620 static bool AlwaysAccept (MemberInfo m
, object filterCriteria
)
1626 /// This filter is used by FindMembers, and we just keep
1627 /// a global for the filter to `AlwaysAccept'
1629 static MemberFilter accepting_filter
;
1632 static TypeContainer ()
1634 accepting_filter
= new MemberFilter (AlwaysAccept
);
1637 public MethodInfo
[] GetMethods ()
1639 ArrayList members
= new ArrayList ();
1641 DefineMembers (null);
1643 if (methods
!= null) {
1644 int len
= methods
.Count
;
1645 for (int i
= 0; i
< len
; i
++) {
1646 Method m
= (Method
) methods
[i
];
1648 members
.Add (m
.MethodBuilder
);
1652 if (operators
!= null) {
1653 int len
= operators
.Count
;
1654 for (int i
= 0; i
< len
; i
++) {
1655 Operator o
= (Operator
) operators
[i
];
1657 members
.Add (o
.OperatorMethodBuilder
);
1661 if (properties
!= null) {
1662 int len
= properties
.Count
;
1663 for (int i
= 0; i
< len
; i
++) {
1664 Property p
= (Property
) properties
[i
];
1666 if (p
.GetBuilder
!= null)
1667 members
.Add (p
.GetBuilder
);
1668 if (p
.SetBuilder
!= null)
1669 members
.Add (p
.SetBuilder
);
1673 if (indexers
!= null) {
1674 int len
= indexers
.Count
;
1675 for (int i
= 0; i
< len
; i
++) {
1676 Indexer ix
= (Indexer
) indexers
[i
];
1678 if (ix
.GetBuilder
!= null)
1679 members
.Add (ix
.GetBuilder
);
1680 if (ix
.SetBuilder
!= null)
1681 members
.Add (ix
.SetBuilder
);
1685 if (events
!= null) {
1686 int len
= events
.Count
;
1687 for (int i
= 0; i
< len
; i
++) {
1688 Event e
= (Event
) events
[i
];
1690 if (e
.AddBuilder
!= null)
1691 members
.Add (e
.AddBuilder
);
1692 if (e
.RemoveBuilder
!= null)
1693 members
.Add (e
.RemoveBuilder
);
1697 MethodInfo
[] retMethods
= new MethodInfo
[members
.Count
];
1698 members
.CopyTo (retMethods
, 0);
1702 // Indicated whether container has StructLayout attribute set Explicit
1703 public virtual bool HasExplicitLayout
{
1710 /// This method returns the members of this type just like Type.FindMembers would
1711 /// Only, we need to use this for types which are _being_ defined because MS'
1712 /// implementation can't take care of that.
1715 // FIXME: return an empty static array instead of null, that cleans up
1716 // some code and is consistent with some coding conventions I just found
1720 // Notice that in various cases we check if our field is non-null,
1721 // something that would normally mean that there was a bug elsewhere.
1723 // The problem happens while we are defining p-invoke methods, as those
1724 // will trigger a FindMembers, but this happens before things are defined
1726 // Since the whole process is a no-op, it is fine to check for null here.
1728 public override MemberList
FindMembers (MemberTypes mt
, BindingFlags bf
,
1729 MemberFilter filter
, object criteria
)
1731 ArrayList members
= null;
1734 if ((bf
& BindingFlags
.Public
) != 0)
1735 modflags
|= Modifiers
.PUBLIC
| Modifiers
.PROTECTED
|
1737 if ((bf
& BindingFlags
.NonPublic
) != 0)
1738 modflags
|= Modifiers
.PRIVATE
;
1740 int static_mask
= 0, static_flags
= 0;
1741 switch (bf
& (BindingFlags
.Static
| BindingFlags
.Instance
)) {
1742 case BindingFlags
.Static
:
1743 static_mask
= static_flags
= Modifiers
.STATIC
;
1746 case BindingFlags
.Instance
:
1747 static_mask
= Modifiers
.STATIC
;
1752 static_mask
= static_flags
= 0;
1756 Timer
.StartTimer (TimerType
.TcFindMembers
);
1759 filter
= accepting_filter
;
1761 if ((mt
& MemberTypes
.Field
) != 0) {
1762 if (fields
!= null) {
1763 int len
= fields
.Count
;
1764 for (int i
= 0; i
< len
; i
++) {
1765 Field f
= (Field
) fields
[i
];
1767 if ((f
.ModFlags
& modflags
) == 0)
1769 if ((f
.ModFlags
& static_mask
) != static_flags
)
1772 FieldBuilder fb
= f
.FieldBuilder
;
1773 if (fb
!= null && filter (fb
, criteria
) == true) {
1774 if (members
== null)
1775 members
= new ArrayList ();
1782 if (constants
!= null) {
1783 int len
= constants
.Count
;
1784 for (int i
= 0; i
< len
; i
++) {
1785 Const con
= (Const
) constants
[i
];
1787 if ((con
.ModFlags
& modflags
) == 0)
1789 if ((con
.ModFlags
& static_mask
) != static_flags
)
1792 FieldBuilder fb
= con
.FieldBuilder
;
1795 fb
= con
.FieldBuilder
;
1797 if (fb
!= null && filter (fb
, criteria
) == true) {
1798 if (members
== null)
1799 members
= new ArrayList ();
1807 if ((mt
& MemberTypes
.Method
) != 0) {
1808 if (methods
!= null) {
1809 int len
= methods
.Count
;
1810 for (int i
= 0; i
< len
; i
++) {
1811 Method m
= (Method
) methods
[i
];
1813 if ((m
.ModFlags
& modflags
) == 0)
1815 if ((m
.ModFlags
& static_mask
) != static_flags
)
1818 MethodBuilder mb
= m
.MethodBuilder
;
1820 if (mb
!= null && filter (mb
, criteria
) == true) {
1821 if (members
== null)
1822 members
= new ArrayList ();
1829 if (operators
!= null) {
1830 int len
= operators
.Count
;
1831 for (int i
= 0; i
< len
; i
++) {
1832 Operator o
= (Operator
) operators
[i
];
1834 if ((o
.ModFlags
& modflags
) == 0)
1836 if ((o
.ModFlags
& static_mask
) != static_flags
)
1839 MethodBuilder ob
= o
.OperatorMethodBuilder
;
1840 if (ob
!= null && filter (ob
, criteria
) == true) {
1841 if (members
== null)
1842 members
= new ArrayList ();
1849 if (properties
!= null) {
1850 int len
= properties
.Count
;
1851 for (int i
= 0; i
< len
; i
++) {
1852 Property p
= (Property
) properties
[i
];
1854 if ((p
.ModFlags
& modflags
) == 0)
1856 if ((p
.ModFlags
& static_mask
) != static_flags
)
1862 if (b
!= null && filter (b
, criteria
) == true) {
1863 if (members
== null)
1864 members
= new ArrayList ();
1870 if (b
!= null && filter (b
, criteria
) == true) {
1871 if (members
== null)
1872 members
= new ArrayList ();
1879 if (indexers
!= null) {
1880 int len
= indexers
.Count
;
1881 for (int i
= 0; i
< len
; i
++) {
1882 Indexer ix
= (Indexer
) indexers
[i
];
1884 if ((ix
.ModFlags
& modflags
) == 0)
1886 if ((ix
.ModFlags
& static_mask
) != static_flags
)
1892 if (b
!= null && filter (b
, criteria
) == true) {
1893 if (members
== null)
1894 members
= new ArrayList ();
1900 if (b
!= null && filter (b
, criteria
) == true) {
1901 if (members
== null)
1902 members
= new ArrayList ();
1910 if ((mt
& MemberTypes
.Event
) != 0) {
1911 if (events
!= null) {
1912 int len
= events
.Count
;
1913 for (int i
= 0; i
< len
; i
++) {
1914 Event e
= (Event
) events
[i
];
1916 if ((e
.ModFlags
& modflags
) == 0)
1918 if ((e
.ModFlags
& static_mask
) != static_flags
)
1921 MemberInfo eb
= e
.EventBuilder
;
1922 if (eb
!= null && filter (eb
, criteria
) == true) {
1923 if (members
== null)
1924 members
= new ArrayList ();
1926 members
.Add (e
.EventBuilder
);
1932 if ((mt
& MemberTypes
.Property
) != 0){
1933 if (properties
!= null) {
1934 int len
= properties
.Count
;
1935 for (int i
= 0; i
< len
; i
++) {
1936 Property p
= (Property
) properties
[i
];
1938 if ((p
.ModFlags
& modflags
) == 0)
1940 if ((p
.ModFlags
& static_mask
) != static_flags
)
1943 MemberInfo pb
= p
.PropertyBuilder
;
1944 if (pb
!= null && filter (pb
, criteria
) == true) {
1945 if (members
== null)
1946 members
= new ArrayList ();
1948 members
.Add (p
.PropertyBuilder
);
1953 if (indexers
!= null) {
1954 int len
= indexers
.Count
;
1955 for (int i
= 0; i
< len
; i
++) {
1956 Indexer ix
= (Indexer
) indexers
[i
];
1958 if ((ix
.ModFlags
& modflags
) == 0)
1960 if ((ix
.ModFlags
& static_mask
) != static_flags
)
1963 MemberInfo ib
= ix
.PropertyBuilder
;
1964 if (ib
!= null && filter (ib
, criteria
) == true) {
1965 if (members
== null)
1966 members
= new ArrayList ();
1968 members
.Add (ix
.PropertyBuilder
);
1974 if ((mt
& MemberTypes
.NestedType
) != 0) {
1975 if (types
!= null) {
1976 int len
= types
.Count
;
1977 for (int i
= 0; i
< len
; i
++) {
1978 TypeContainer t
= (TypeContainer
) types
[i
];
1980 if ((t
.ModFlags
& modflags
) == 0)
1983 TypeBuilder tb
= t
.TypeBuilder
;
1985 tb
= t
.DefineType ();
1987 if (tb
!= null && (filter (tb
, criteria
) == true)) {
1988 if (members
== null)
1989 members
= new ArrayList ();
1996 if (enums
!= null) {
1997 int len
= enums
.Count
;
1998 for (int i
= 0; i
< len
; i
++) {
1999 Enum en
= (Enum
) enums
[i
];
2001 if ((en
.ModFlags
& modflags
) == 0)
2004 TypeBuilder tb
= en
.TypeBuilder
;
2005 if (tb
!= null && (filter (tb
, criteria
) == true)) {
2006 if (members
== null)
2007 members
= new ArrayList ();
2014 if (delegates
!= null) {
2015 int len
= delegates
.Count
;
2016 for (int i
= 0; i
< len
; i
++) {
2017 Delegate d
= (Delegate
) delegates
[i
];
2019 if ((d
.ModFlags
& modflags
) == 0)
2022 TypeBuilder tb
= d
.TypeBuilder
;
2023 if (tb
!= null && (filter (tb
, criteria
) == true)) {
2024 if (members
== null)
2025 members
= new ArrayList ();
2032 if (interfaces
!= null) {
2033 int len
= interfaces
.Count
;
2034 for (int i
= 0; i
< len
; i
++) {
2035 TypeContainer iface
= (TypeContainer
) interfaces
[i
];
2037 if ((iface
.ModFlags
& modflags
) == 0)
2040 TypeBuilder tb
= iface
.TypeBuilder
;
2041 if (tb
!= null && (filter (tb
, criteria
) == true)) {
2042 if (members
== null)
2043 members
= new ArrayList ();
2051 if ((mt
& MemberTypes
.Constructor
) != 0){
2052 if (((bf
& BindingFlags
.Instance
) != 0) && (instance_constructors
!= null)){
2053 int len
= instance_constructors
.Count
;
2054 for (int i
= 0; i
< len
; i
++) {
2055 Constructor c
= (Constructor
) instance_constructors
[i
];
2057 ConstructorBuilder cb
= c
.ConstructorBuilder
;
2058 if (cb
!= null && filter (cb
, criteria
) == true) {
2059 if (members
== null)
2060 members
= new ArrayList ();
2067 if (((bf
& BindingFlags
.Static
) != 0) && (default_static_constructor
!= null)){
2068 ConstructorBuilder cb
=
2069 default_static_constructor
.ConstructorBuilder
;
2071 if (cb
!= null && filter (cb
, criteria
) == true) {
2072 if (members
== null)
2073 members
= new ArrayList ();
2081 // Lookup members in base if requested.
2083 if ((bf
& BindingFlags
.DeclaredOnly
) == 0) {
2084 if (TypeBuilder
.BaseType
!= null) {
2085 MemberList list
= FindMembers (TypeBuilder
.BaseType
, mt
, bf
, filter
, criteria
);
2086 if (list
.Count
> 0) {
2087 if (members
== null)
2088 members
= new ArrayList ();
2090 members
.AddRange (list
);
2096 Timer
.StopTimer (TimerType
.TcFindMembers
);
2098 if (members
== null)
2099 return MemberList
.Empty
;
2101 return new MemberList (members
);
2104 public override MemberCache MemberCache
{
2106 return member_cache
;
2110 public static MemberList
FindMembers (Type t
, MemberTypes mt
, BindingFlags bf
,
2111 MemberFilter filter
, object criteria
)
2113 DeclSpace ds
= TypeManager
.LookupDeclSpace (t
);
2116 return ds
.FindMembers (mt
, bf
, filter
, criteria
);
2118 return new MemberList (t
.FindMembers (mt
, bf
, filter
, criteria
));
2122 // FindMethods will look for methods not only in the type `t', but in
2123 // any interfaces implemented by the type.
2125 public static MethodInfo
[] FindMethods (Type t
, BindingFlags bf
,
2126 MemberFilter filter
, object criteria
)
2132 /// Emits the values for the constants
2134 public void EmitConstants ()
2136 if (constants
!= null)
2137 foreach (Const con
in constants
)
2142 protected virtual void VerifyMembers (EmitContext ec
)
2145 // Check for internal or private fields that were never assigned
2147 if (RootContext
.WarningLevel
>= 4) {
2148 if (fields
!= null){
2149 foreach (Field f
in fields
) {
2150 if ((f
.ModFlags
& Modifiers
.Accessibility
) != Modifiers
.PRIVATE
)
2153 if ((f
.status
& Field
.Status
.USED
) == 0){
2154 Report
.Warning (169, f
.Location
, "The private field '{0}' is never used", f
.GetSignatureForError ());
2159 // Only report 649 on level 4
2161 if (RootContext
.WarningLevel
< 4)
2164 if ((f
.status
& Field
.Status
.ASSIGNED
) != 0)
2167 Report
.Warning (649, f
.Location
, "Field '{0}' is never assigned to, and will always have its default value '{1}'", f
.GetSignatureForError (), "");
2174 /// Emits the code, this step is performed after all
2175 /// the types, enumerations, constructors
2177 public void EmitType ()
2179 if (OptAttributes
!= null)
2180 OptAttributes
.Emit (ec
, this);
2184 if (instance_constructors
!= null) {
2185 if (TypeBuilder
.IsSubclassOf (TypeManager
.attribute_type
) && RootContext
.VerifyClsCompliance
&& IsClsCompliaceRequired (this)) {
2186 bool has_compliant_args
= false;
2188 foreach (Constructor c
in instance_constructors
) {
2191 if (has_compliant_args
)
2194 has_compliant_args
= c
.HasCompliantArgs
;
2196 if (!has_compliant_args
)
2197 Report
.Error (3015, Location
, "'{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2199 foreach (Constructor c
in instance_constructors
)
2206 if (default_static_constructor
!= null)
2207 default_static_constructor
.Emit ();
2209 if (methods
!= null)
2210 foreach (Method m
in methods
)
2213 if (operators
!= null)
2214 foreach (Operator o
in operators
)
2217 if (properties
!= null)
2218 foreach (Property p
in properties
)
2221 if (indexers
!= null){
2226 foreach (Field f
in fields
)
2229 if (events
!= null){
2230 foreach (Event e
in Events
)
2234 if (delegates
!= null) {
2235 foreach (Delegate d
in Delegates
) {
2240 if (enums
!= null) {
2241 foreach (Enum e
in enums
) {
2246 if (parts
!= null) {
2247 foreach (ClassPart part
in parts
)
2251 if ((Pending
!= null) && !(this is ClassPart
))
2252 if (Pending
.VerifyPendingMethods ())
2257 if (iterators
!= null)
2258 foreach (Iterator iterator
in iterators
)
2259 iterator
.EmitType ();
2261 // if (types != null)
2262 // foreach (TypeContainer tc in types)
2266 public override void CloseType ()
2268 if ((caching_flags
& Flags
.CloseTypeCreated
) != 0)
2272 caching_flags
|= Flags
.CloseTypeCreated
;
2273 TypeBuilder
.CreateType ();
2274 } catch (TypeLoadException
){
2276 // This is fine, the code still created the type
2278 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2279 // Console.WriteLine (e.Message);
2281 Console
.WriteLine ("In type: " + Name
);
2286 foreach (Enum en
in Enums
)
2290 foreach (TypeContainer tc
in Types
)
2291 if (tc
.Kind
== Kind
.Struct
)
2294 foreach (TypeContainer tc
in Types
)
2295 if (tc
.Kind
!= Kind
.Struct
)
2299 if (Delegates
!= null)
2300 foreach (Delegate d
in Delegates
)
2303 if (Iterators
!= null)
2304 foreach (Iterator i
in Iterators
)
2312 initialized_fields
= null;
2313 initialized_static_fields
= null;
2322 default_constructor
= null;
2323 default_static_constructor
= null;
2325 OptAttributes
= null;
2328 member_cache
= null;
2331 // TODO: make it obsolete and use GetSignatureForError
2332 public string MakeName (string n
)
2334 return "`" + Name
+ "." + n
+ "'";
2338 // Performs the validation on a Method's modifiers (properties have
2339 // the same properties).
2341 public bool MethodModifiersValid (MemberCore mc
)
2343 const int vao
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
| Modifiers
.OVERRIDE
);
2344 const int va
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
);
2345 const int nv
= (Modifiers
.NEW
| Modifiers
.VIRTUAL
);
2347 int flags
= mc
.ModFlags
;
2350 // At most one of static, virtual or override
2352 if ((flags
& Modifiers
.STATIC
) != 0){
2353 if ((flags
& vao
) != 0){
2354 Report
.Error (112, mc
.Location
, "static method '{0}' can not be marked as virtual, abstract or override",
2355 GetSignatureForError ());
2360 if (Kind
== Kind
.Struct
){
2361 if ((flags
& va
) != 0){
2362 Modifiers
.Error_InvalidModifier (mc
.Location
, "virtual or abstract");
2367 if ((flags
& Modifiers
.OVERRIDE
) != 0 && (flags
& nv
) != 0){
2368 Report
.Error (113, mc
.Location
, "'{0}' marked as override cannot be marked as new or virtual", mc
.GetSignatureForError ());
2373 // If the declaration includes the abstract modifier, then the
2374 // declaration does not include static, virtual or extern
2376 if ((flags
& Modifiers
.ABSTRACT
) != 0){
2377 if ((flags
& Modifiers
.EXTERN
) != 0){
2379 180, mc
.Location
, "'{0}' can not be both abstract and extern", mc
.GetSignatureForError ());
2383 if ((flags
& Modifiers
.SEALED
) != 0) {
2384 Report
.Error (502, mc
.Location
, "'{0}' cannot be both abstract and sealed", mc
.GetSignatureForError ());
2388 if ((flags
& Modifiers
.VIRTUAL
) != 0){
2389 Report
.Error (503, mc
.Location
, "'{0}' can not be both abstract and virtual", mc
.GetSignatureForError ());
2393 if ((ModFlags
& Modifiers
.ABSTRACT
) == 0){
2394 Report
.Error (513, mc
.Location
, "'{0}' is abstract but its container class is not", mc
.GetSignatureForError ());
2399 if ((flags
& Modifiers
.PRIVATE
) != 0){
2400 if ((flags
& vao
) != 0){
2401 Report
.Error (621, mc
.Location
, "'{0}' virtual or abstract members can not be private", mc
.GetSignatureForError ());
2406 if ((flags
& Modifiers
.SEALED
) != 0){
2407 if ((flags
& Modifiers
.OVERRIDE
) == 0){
2408 Report
.Error (238, mc
.Location
, "'{0}' cannot be sealed because it is not an override", mc
.GetSignatureForError ());
2416 public bool UserDefinedStaticConstructor
{
2418 return default_static_constructor
!= null;
2422 public Constructor DefaultStaticConstructor
{
2423 get { return default_static_constructor; }
2426 protected override bool VerifyClsCompliance (DeclSpace ds
)
2428 if (!base.VerifyClsCompliance (ds
))
2434 Report
.Error (3024, Location
, "'{0}': type parameters are not CLS-compliant",
2435 GetSignatureForError ());
2439 Type base_type
= TypeBuilder
.BaseType
;
2440 if (base_type
!= null && !AttributeTester
.IsClsCompliant (base_type
)) {
2441 Report
.Error (3009, Location
, "'{0}': base type '{1}' is not CLS-compliant", GetSignatureForError (), TypeManager
.CSharpName (base_type
));
2444 if (!Parent
.IsClsCompliaceRequired (ds
)) {
2445 Report
.Error (3018, Location
, "'{0}' cannot be marked as CLS-Compliant because it is a member of non CLS-Compliant type '{1}'",
2446 GetSignatureForError (), Parent
.GetSignatureForError ());
2453 /// Checks whether container name is CLS Compliant
2455 void VerifyClsName ()
2457 Hashtable base_members
= base_cache
== null ?
2459 base_cache
.GetPublicMembers ();
2460 Hashtable this_members
= new Hashtable ();
2462 foreach (DictionaryEntry entry
in defined_names
) {
2463 MemberCore mc
= (MemberCore
)entry
.Value
;
2464 if (!mc
.IsClsCompliaceRequired (this))
2467 string name
= (string)entry
.Key
;
2468 string basename
= name
.Substring (name
.LastIndexOf ('.') + 1);
2470 string lcase
= basename
.ToLower (System
.Globalization
.CultureInfo
.InvariantCulture
);
2471 object found
= base_members
[lcase
];
2472 if (found
== null) {
2473 found
= this_members
[lcase
];
2474 if (found
== null) {
2475 this_members
.Add (lcase
, mc
);
2480 if ((mc
.ModFlags
& Modifiers
.OVERRIDE
) != 0)
2483 if (found
is MemberInfo
) {
2484 if (basename
== ((MemberInfo
)found
).Name
)
2486 Report
.SymbolRelatedToPreviousError ((MemberInfo
)found
);
2488 Report
.SymbolRelatedToPreviousError ((MemberCore
) found
);
2490 Report
.Error (3005, mc
.Location
, "Identifier '{0}' differing only in case is not CLS-compliant", mc
.GetSignatureForError ());
2496 /// Performs checks for an explicit interface implementation. First it
2497 /// checks whether the `interface_type' is a base inteface implementation.
2498 /// Then it checks whether `name' exists in the interface type.
2500 public virtual bool VerifyImplements (Type interface_type
, string full
,
2501 string name
, Location loc
)
2505 if (ifaces
!= null){
2506 foreach (Type t
in ifaces
){
2507 if (t
== interface_type
){
2515 Report
.Error (540, loc
, "`{0}': containing class does not implement interface `{1}'",
2516 full
, interface_type
.FullName
);
2523 protected override void VerifyObsoleteAttribute()
2525 CheckUsageOfObsoleteAttribute (TypeBuilder
.BaseType
);
2530 foreach (Type iface
in ifaces
) {
2531 CheckUsageOfObsoleteAttribute (iface
);
2539 string IMemberContainer
.Name
{
2545 Type IMemberContainer
.Type
{
2551 MemberCache IMemberContainer
.MemberCache
{
2553 return member_cache
;
2557 bool IMemberContainer
.IsInterface
{
2559 return Kind
== Kind
.Interface
;
2563 MemberList IMemberContainer
.GetMembers (MemberTypes mt
, BindingFlags bf
)
2565 BindingFlags new_bf
= bf
| BindingFlags
.DeclaredOnly
;
2567 if (GenericType
!= null)
2568 return TypeManager
.FindMembers (GenericType
, mt
, new_bf
,
2571 return FindMembers (mt
, new_bf
, null, null);
2575 // Generates xml doc comments (if any), and if required,
2576 // handle warning report.
2578 internal override void GenerateDocComment (DeclSpace ds
)
2580 DocUtil
.GenerateTypeDocComment (this, ds
);
2583 public override string DocCommentHeader
{
2584 get { return "T:"; }
2587 public virtual MemberCache BaseCache
{
2589 if (base_cache
!= null)
2591 if (TypeBuilder
.BaseType
!= null)
2592 base_cache
= TypeManager
.LookupMemberCache (TypeBuilder
.BaseType
);
2593 if (TypeBuilder
.IsInterface
)
2594 base_cache
= TypeManager
.LookupBaseInterfacesCache (TypeBuilder
);
2601 public class PartialContainer
: TypeContainer
{
2603 public readonly Namespace Namespace
;
2604 public readonly int OriginalModFlags
;
2605 public readonly int AllowedModifiers
;
2606 public readonly TypeAttributes DefaultTypeAttributes
;
2608 static PartialContainer
Create (NamespaceEntry ns
, TypeContainer parent
,
2609 MemberName member_name
, int mod_flags
, Kind kind
,
2612 PartialContainer pc
;
2613 string full_name
= member_name
.GetName (true);
2614 DeclSpace ds
= (DeclSpace
) RootContext
.Tree
.Decls
[full_name
];
2616 pc
= ds
as PartialContainer
;
2620 260, ds
.Location
, "Missing partial modifier " +
2621 "on declaration of type `{0}'; another " +
2622 "partial implementation of this type exists",
2623 member_name
.GetTypeName());
2625 Report
.LocationOfPreviousError (loc
);
2629 if (pc
.Kind
!= kind
) {
2631 261, loc
, "Partial declarations of `{0}' " +
2632 "must be all classes, all structs or " +
2633 "all interfaces", member_name
.GetTypeName ());
2637 if (pc
.OriginalModFlags
!= mod_flags
) {
2639 262, loc
, "Partial declarations of `{0}' " +
2640 "have conflicting accessibility modifiers",
2641 member_name
.GetTypeName ());
2646 if (pc
.CountTypeParameters
!= member_name
.CountTypeArguments
) {
2648 264, loc
, "Partial declarations of `{0}' " +
2649 "must have the same type parameter names in " +
2650 "the same order", member_name
.GetTypeName ());
2654 string[] pc_names
= pc
.MemberName
.TypeArguments
.GetDeclarations ();
2655 string[] names
= member_name
.TypeArguments
.GetDeclarations ();
2657 for (int i
= 0; i
< pc
.CountTypeParameters
; i
++) {
2658 if (pc_names
[i
] == names
[i
])
2662 264, loc
, "Partial declarations of `{0}' " +
2663 "must have the same type parameter names in " +
2664 "the same order", member_name
.GetTypeName ());
2672 pc
= new PartialContainer (ns
, parent
, member_name
, mod_flags
, kind
, loc
);
2673 RootContext
.Tree
.RecordDecl (full_name
, pc
);
2674 parent
.AddType (pc
);
2676 // This is needed to define our type parameters; we define the constraints later.
2677 pc
.SetParameterInfo (null);
2681 public static ClassPart
CreatePart (NamespaceEntry ns
, TypeContainer parent
,
2682 MemberName name
, int mod
, Attributes attrs
,
2683 Kind kind
, Location loc
)
2685 PartialContainer pc
= Create (ns
, parent
, name
, mod
, kind
, loc
);
2687 // An error occured; create a dummy container, but don't
2689 pc
= new PartialContainer (ns
, parent
, name
, mod
, kind
, loc
);
2692 ClassPart part
= new ClassPart (ns
, pc
, mod
, attrs
, kind
, loc
);
2697 protected PartialContainer (NamespaceEntry ns
, TypeContainer parent
,
2698 MemberName name
, int mod
, Kind kind
, Location l
)
2699 : base (ns
, parent
, name
, null, kind
, l
)
2701 this.Namespace
= ns
.NS
;
2705 AllowedModifiers
= Class
.AllowedModifiers
;
2706 DefaultTypeAttributes
= Class
.DefaultTypeAttributes
;
2710 AllowedModifiers
= Struct
.AllowedModifiers
;
2711 DefaultTypeAttributes
= Struct
.DefaultTypeAttributes
;
2714 case Kind
.Interface
:
2715 AllowedModifiers
= Interface
.AllowedModifiers
;
2716 DefaultTypeAttributes
= Interface
.DefaultTypeAttributes
;
2720 throw new InvalidOperationException ();
2724 if (parent
.Parent
== null)
2725 accmods
= Modifiers
.INTERNAL
;
2727 accmods
= Modifiers
.PRIVATE
;
2729 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, l
);
2730 this.OriginalModFlags
= mod
;
2733 public override void Register ()
2735 if (Kind
== Kind
.Interface
)
2736 Parent
.AddInterface (this);
2737 else if (Kind
== Kind
.Class
|| Kind
== Kind
.Struct
)
2738 Parent
.AddClassOrStruct (this);
2740 throw new InvalidOperationException ();
2743 public override PendingImplementation
GetPendingImplementations ()
2745 return PendingImplementation
.GetPendingImplementations (this);
2748 ArrayList constraints_lists
;
2750 public void UpdateConstraints (ArrayList constraints_list
)
2753 // This is called for each ClassPart in a partial generic type declaration.
2755 // If no constraints were specified for the part, just return.
2756 // Otherwise, if we're called with constraints for the first time, they become
2757 // the type's constraint. If we're called with constraints again, we just
2758 // store them somewhere so we can later check whether there are no conflicts.
2760 if (constraints_list
== null)
2763 if (constraints_lists
!= null) {
2764 constraints_lists
.Add (constraints_list
);
2768 DoUpdateConstraints (null, constraints_list
, false);
2770 constraints_lists
= new ArrayList ();
2773 protected bool DoUpdateConstraints (EmitContext ec
, ArrayList constraints_list
, bool check
)
2775 for (int i
= 0; i
< TypeParameters
.Length
; i
++) {
2776 string name
= TypeParameters
[i
].Name
;
2778 Constraints constraints
= null;
2779 if (constraints_list
!= null) {
2780 foreach (Constraints constraint
in constraints_list
) {
2781 if (constraint
.TypeParameter
== name
) {
2782 constraints
= constraint
;
2788 if (!TypeParameters
[i
].UpdateConstraints (ec
, constraints
, check
)) {
2789 Report
.Error (265, Location
, "Partial declarations of `{0}' have " +
2790 "inconsistent constraints for type parameter `{1}'.",
2791 MemberName
.GetTypeName (), name
);
2799 protected override bool CheckConstraints (EmitContext ec
)
2801 if (constraints_lists
== null)
2805 // If constraints were specified in more than one part of a
2806 // partial generic type definition, they must be identical.
2808 // Note that we must resolve them and then compute the fully
2809 // resolved types since different parts may have different
2810 // `using' aliases. See gen-129.cs for an example.
2812 foreach (ArrayList constraints_list
in constraints_lists
) {
2813 if (!DoUpdateConstraints (ec
, constraints_list
, true))
2820 public ClassPart
AddPart (NamespaceEntry ns
, int mod
, Attributes attrs
,
2823 ClassPart part
= new ClassPart (ns
, this, mod
, attrs
, Kind
, l
);
2828 public override TypeAttributes TypeAttr
{
2830 return base.TypeAttr
| DefaultTypeAttributes
;
2835 public class ClassPart
: TypeContainer
, IMemberContainer
{
2836 public readonly PartialContainer PartialContainer
;
2837 public readonly bool IsPartial
;
2839 public ClassPart (NamespaceEntry ns
, PartialContainer parent
,
2840 int mod
, Attributes attrs
, Kind kind
, Location l
)
2841 : base (ns
, parent
.Parent
, parent
.MemberName
, attrs
, kind
, l
)
2843 this.PartialContainer
= parent
;
2844 this.IsPartial
= true;
2847 if (parent
.Parent
== null)
2848 accmods
= Modifiers
.INTERNAL
;
2850 accmods
= Modifiers
.PRIVATE
;
2852 this.ModFlags
= Modifiers
.Check (
2853 parent
.AllowedModifiers
, mod
, accmods
, l
);
2856 public override void Register ()
2860 public override PendingImplementation
GetPendingImplementations ()
2862 return PartialContainer
.Pending
;
2865 public override bool VerifyImplements (Type interface_type
, string full
,
2866 string name
, Location loc
)
2868 return PartialContainer
.VerifyImplements (
2869 interface_type
, full
, name
, loc
);
2872 public override void SetParameterInfo (ArrayList constraints_list
)
2874 PartialContainer
.UpdateConstraints (constraints_list
);
2877 public override MemberCache BaseCache
{
2879 return PartialContainer
.BaseCache
;
2884 public abstract class ClassOrStruct
: TypeContainer
{
2885 bool hasExplicitLayout
= false;
2886 ListDictionary declarative_security
;
2888 public ClassOrStruct (NamespaceEntry ns
, TypeContainer parent
,
2889 MemberName name
, Attributes attrs
, Kind kind
,
2891 : base (ns
, parent
, name
, attrs
, kind
, l
)
2895 public override PendingImplementation
GetPendingImplementations ()
2897 return PendingImplementation
.GetPendingImplementations (this);
2900 public override bool HasExplicitLayout
{
2902 return hasExplicitLayout
;
2906 protected override void VerifyMembers (EmitContext ec
)
2908 base.VerifyMembers (ec
);
2910 if ((events
!= null) && (RootContext
.WarningLevel
>= 3)) {
2911 foreach (Event e
in events
){
2913 Report
.Warning (67, e
.Location
, "The event '{0}' is never used", e
.GetSignatureForError ());
2918 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
2920 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
2921 if (declarative_security
== null)
2922 declarative_security
= new ListDictionary ();
2924 a
.ExtractSecurityPermissionSet (declarative_security
);
2928 if (a
.Type
== TypeManager
.struct_layout_attribute_type
2929 && (LayoutKind
) a
.GetPositionalValue (0) == LayoutKind
.Explicit
)
2930 hasExplicitLayout
= true;
2932 base.ApplyAttributeBuilder (a
, cb
);
2935 public override void Emit()
2939 if (declarative_security
!= null) {
2940 foreach (DictionaryEntry de
in declarative_security
) {
2941 TypeBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
2946 public override void Register ()
2948 Parent
.AddClassOrStruct (this);
2953 /// Class handles static classes declaration
2955 public sealed class StaticClass
: Class
{
2956 public StaticClass (NamespaceEntry ns
, TypeContainer parent
, MemberName name
, int mod
,
2957 Attributes attrs
, Location l
)
2958 : base (ns
, parent
, name
, mod
, attrs
, l
)
2960 if (RootContext
.Version
== LanguageVersion
.ISO_1
) {
2961 Report
.FeatureIsNotStandardized (l
, "static classes");
2962 Environment
.Exit (1);
2966 protected override int AllowedModifiersProp
{
2968 return Modifiers
.NEW
| Modifiers
.PUBLIC
| Modifiers
.PROTECTED
| Modifiers
.INTERNAL
| Modifiers
.PRIVATE
|
2969 Modifiers
.STATIC
| Modifiers
.UNSAFE
;
2973 protected override void DefineContainerMembers (MemberCoreArrayList list
)
2978 foreach (MemberCore m
in list
) {
2979 if (m
is Operator
) {
2980 Report
.Error (715, m
.Location
, "'{0}': static classes cannot contain user-defined operators", m
.GetSignatureForError (this));
2984 if ((m
.ModFlags
& Modifiers
.STATIC
) != 0 || m
is Enum
|| m
is Delegate
)
2987 if (m
is Constructor
) {
2988 Report
.Error (710, m
.Location
, "'{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2992 if (m
is Destructor
) {
2993 Report
.Error (711, m
.Location
, "'{0}': Static class cannot contain destructor", GetSignatureForError ());
2996 Report
.Error (708, m
.Location
, "'{0}': cannot declare instance members in a static class", m
.GetSignatureForError (this));
2999 base.DefineContainerMembers (list
);
3002 public override TypeBuilder
DefineType()
3004 if ((ModFlags
& (Modifiers
.SEALED
| Modifiers
.STATIC
)) == (Modifiers
.SEALED
| Modifiers
.STATIC
)) {
3005 Report
.Error (441, Location
, "'{0}': a class cannot be both static and sealed", GetSignatureForError ());
3009 TypeBuilder tb
= base.DefineType ();
3013 if ((ptype
!= null) && (ptype
!= TypeManager
.object_type
)) {
3016 "Static class '{0}' cannot derive from type '{1}'. " +
3017 "Static classes must derive from object",
3018 GetSignatureForError (), ptype
);
3022 if (ifaces
!= null) {
3023 foreach (Type t
in ifaces
)
3024 Report
.SymbolRelatedToPreviousError (t
);
3027 "'{0}': static classes cannot implement interfaces",
3028 GetSignatureForError ());
3033 public override TypeAttributes TypeAttr
{
3035 return base.TypeAttr
| TypeAttributes
.Abstract
| TypeAttributes
.Sealed
;
3040 public class Class
: ClassOrStruct
{
3041 // TODO: remove this and use only AllowedModifiersProp to fix partial classes bugs
3042 public const int AllowedModifiers
=
3045 Modifiers
.PROTECTED
|
3046 Modifiers
.INTERNAL
|
3048 Modifiers
.ABSTRACT
|
3052 // Information in the case we are an attribute type
3053 AttributeUsageAttribute attribute_usage
;
3055 public Class (NamespaceEntry ns
, TypeContainer parent
, MemberName name
, int mod
,
3056 Attributes attrs
, Location l
)
3057 : base (ns
, parent
, name
, attrs
, Kind
.Class
, l
)
3059 this.ModFlags
= mod
;
3060 attribute_usage
= new AttributeUsageAttribute (AttributeTargets
.All
);
3063 virtual protected int AllowedModifiersProp
{
3065 return AllowedModifiers
;
3069 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
3071 if (a
.UsageAttribute
!= null) {
3072 if (ptype
!= TypeManager
.attribute_type
&&
3073 !ptype
.IsSubclassOf (TypeManager
.attribute_type
) &&
3074 TypeBuilder
.FullName
!= "System.Attribute") {
3075 Report
.Error (641, a
.Location
, "Attribute '{0}' is only valid on classes derived from System.Attribute", a
.Name
);
3077 attribute_usage
= a
.UsageAttribute
;
3080 base.ApplyAttributeBuilder (a
, cb
);
3083 public AttributeUsageAttribute AttributeUsage
{
3085 return attribute_usage
;
3089 public const TypeAttributes DefaultTypeAttributes
=
3090 TypeAttributes
.AutoLayout
| TypeAttributes
.Class
;
3092 public override TypeBuilder
DefineType()
3094 if ((ModFlags
& Modifiers
.ABSTRACT
) == Modifiers
.ABSTRACT
&& (ModFlags
& (Modifiers
.SEALED
| Modifiers
.STATIC
)) != 0) {
3095 Report
.Error (418, Location
, "'{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
3099 int accmods
= Parent
.Parent
== null ? Modifiers
.INTERNAL
: Modifiers
.PRIVATE
;
3100 ModFlags
= Modifiers
.Check (AllowedModifiersProp
, ModFlags
, accmods
, Location
);
3102 return base.DefineType ();
3106 // FIXME: How do we deal with the user specifying a different
3109 public override TypeAttributes TypeAttr
{
3111 return base.TypeAttr
| DefaultTypeAttributes
;
3116 public class Struct
: ClassOrStruct
{
3118 // Modifiers allowed in a struct declaration
3120 public const int AllowedModifiers
=
3123 Modifiers
.PROTECTED
|
3124 Modifiers
.INTERNAL
|
3128 public Struct (NamespaceEntry ns
, TypeContainer parent
, MemberName name
,
3129 int mod
, Attributes attrs
, Location l
)
3130 : base (ns
, parent
, name
, attrs
, Kind
.Struct
, l
)
3134 if (parent
.Parent
== null)
3135 accmods
= Modifiers
.INTERNAL
;
3137 accmods
= Modifiers
.PRIVATE
;
3139 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, l
);
3141 this.ModFlags
|= Modifiers
.SEALED
;
3144 public const TypeAttributes DefaultTypeAttributes
=
3145 TypeAttributes
.SequentialLayout
|
3146 TypeAttributes
.Sealed
|
3147 TypeAttributes
.BeforeFieldInit
;
3150 // FIXME: Allow the user to specify a different set of attributes
3151 // in some cases (Sealed for example is mandatory for a class,
3152 // but what SequentialLayout can be changed
3154 public override TypeAttributes TypeAttr
{
3156 return base.TypeAttr
| DefaultTypeAttributes
;
3164 public class Interface
: TypeContainer
, IMemberContainer
{
3166 /// Modifiers allowed in a class declaration
3168 public const int AllowedModifiers
=
3171 Modifiers
.PROTECTED
|
3172 Modifiers
.INTERNAL
|
3176 public Interface (NamespaceEntry ns
, TypeContainer parent
, MemberName name
,
3177 int mod
, Attributes attrs
, Location l
)
3178 : base (ns
, parent
, name
, attrs
, Kind
.Interface
, l
)
3182 if (parent
.Parent
== null)
3183 accmods
= Modifiers
.INTERNAL
;
3185 accmods
= Modifiers
.PRIVATE
;
3187 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, l
);
3190 public override void Register ()
3192 Parent
.AddInterface (this);
3195 public override PendingImplementation
GetPendingImplementations ()
3200 public const TypeAttributes DefaultTypeAttributes
=
3201 TypeAttributes
.AutoLayout
|
3202 TypeAttributes
.Abstract
|
3203 TypeAttributes
.Interface
;
3205 public override TypeAttributes TypeAttr
{
3207 return base.TypeAttr
| DefaultTypeAttributes
;
3212 public abstract class MethodCore
: MemberBase
{
3213 public readonly Parameters Parameters
;
3214 public readonly GenericMethod GenericMethod
;
3215 public readonly DeclSpace ds
;
3216 protected ToplevelBlock block
;
3219 // Parameters, cached for semantic analysis.
3221 protected InternalParameters parameter_info
;
3222 protected Type
[] parameter_types
;
3224 // Whether this is an operator method.
3225 public bool IsOperator
;
3228 // The method we're overriding if this is an override method.
3230 protected MethodInfo base_method
= null;
3232 static string[] attribute_targets
= new string [] { "method", "return" }
;
3234 public MethodCore (TypeContainer parent
, GenericMethod generic
,
3235 Expression type
, int mod
, int allowed_mod
, bool is_iface
,
3236 MemberName name
, Attributes attrs
, Parameters parameters
,
3238 : base (parent
, type
, mod
, allowed_mod
, Modifiers
.PRIVATE
, name
,
3241 Parameters
= parameters
;
3242 IsInterface
= is_iface
;
3243 this.GenericMethod
= generic
;
3245 if (generic
!= null)
3252 // Returns the System.Type array for the parameters of this method
3254 public Type
[] ParameterTypes
{
3256 return parameter_types
;
3260 public InternalParameters ParameterInfo
3263 return parameter_info
;
3267 public ToplevelBlock Block
{
3277 protected override bool CheckBase ()
3279 if (!base.CheckBase ())
3282 // Check whether arguments were correct.
3283 if (!DoDefineParameters ())
3286 if ((caching_flags
& Flags
.TestMethodDuplication
) != 0 && !CheckForDuplications ())
3292 // Is null for System.Object while compiling corlib and base interfaces
3293 if (Parent
.BaseCache
== null) {
3294 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0)) {
3295 Report
.Warning (109, Location
, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent
));
3300 Type base_ret_type
= null;
3301 base_method
= FindOutBaseMethod (Parent
, ref base_ret_type
);
3303 // method is override
3304 if (base_method
!= null) {
3306 if (!CheckMethodAgainstBase ())
3309 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3310 if (MemberType
!= TypeManager
.TypeToCoreType (base_ret_type
)) {
3311 Report
.SymbolRelatedToPreviousError (base_method
);
3312 Report
.Error (508, Location
, GetSignatureForError (Parent
) + ": cannot " +
3313 "change return type when overriding inherited member");
3317 if (base_method
.IsAbstract
&& !IsInterface
) {
3318 Report
.SymbolRelatedToPreviousError (base_method
);
3319 Report
.Error (533, Location
, "'{0}' hides inherited abstract member", GetSignatureForError (Parent
));
3324 if (base_method
.IsSpecialName
&& !(this is PropertyBase
)) {
3325 Report
.Error (561, Location
, "'{0}': cannot override '{1}' because it is a special compiler-generated method", GetSignatureForError (Parent
), TypeManager
.GetFullNameSignature (base_method
));
3329 if (RootContext
.WarningLevel
> 2) {
3330 if (Name
== "Equals" && parameter_types
.Length
== 1 && parameter_types
[0] == TypeManager
.object_type
)
3331 Parent
.Methods
.HasEquals
= true;
3332 else if (Name
== "GetHashCode" && parameter_types
.Length
== 0)
3333 Parent
.Methods
.HasGetHashCode
= true;
3336 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3337 ObsoleteAttribute oa
= AttributeTester
.GetMethodObsoleteAttribute (base_method
);
3339 EmitContext ec
= new EmitContext (this.Parent
, this.Parent
, Location
, null, null, ModFlags
, false);
3340 if (OptAttributes
== null || !OptAttributes
.Contains (TypeManager
.obsolete_attribute_type
, ec
)) {
3341 Report
.SymbolRelatedToPreviousError (base_method
);
3342 Report
.Warning (672, 1, Location
, "Member '{0}' overrides obsolete member. Add the Obsolete attribute to '{0}'", GetSignatureForError (Parent
));
3349 MemberInfo conflict_symbol
= Parent
.FindBaseMemberWithSameName (Name
, !(this is Property
));
3350 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3351 if (conflict_symbol
!= null) {
3352 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
3353 if (this is PropertyBase
)
3354 Report
.Error (544, Location
, "'{0}': cannot override because '{1}' is not a property", GetSignatureForError (Parent
), TypeManager
.GetFullNameSignature (conflict_symbol
));
3356 Report
.Error (505, Location
, "'{0}': cannot override because '{1}' is not a method", GetSignatureForError (Parent
), TypeManager
.GetFullNameSignature (conflict_symbol
));
3358 Report
.Error (115, Location
, "'{0}': no suitable methods found to override", GetSignatureForError (Parent
));
3362 if (conflict_symbol
== null) {
3363 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0)) {
3364 Report
.Warning (109, Location
, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent
));
3369 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3370 if (this is Method
&& conflict_symbol
is MethodBase
)
3373 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
3374 Report
.Warning (108, Location
, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent
));
3382 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3383 // that have been defined.
3385 // `name' is the user visible name for reporting errors (this is used to
3386 // provide the right name regarding method names and properties)
3388 bool CheckMethodAgainstBase ()
3392 // TODO: replace with GetSignatureForError
3393 string name
= base_method
.DeclaringType
.Name
+ "." + base_method
.Name
;
3395 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0){
3396 if (!(base_method
.IsAbstract
|| base_method
.IsVirtual
)){
3398 506, Location
, Parent
.MakeName (Name
) +
3399 ": cannot override inherited member `" +
3400 name
+ "' because it is not " +
3401 "virtual, abstract or override");
3405 // Now we check that the overriden method is not final
3407 if (base_method
.IsFinal
) {
3408 // This happens when implementing interface methods.
3409 if (base_method
.IsHideBySig
&& base_method
.IsVirtual
) {
3411 506, Location
, Parent
.MakeName (Name
) +
3412 ": cannot override inherited member `" +
3413 name
+ "' because it is not " +
3414 "virtual, abstract or override");
3416 Report
.Error (239, Location
, Parent
.MakeName (Name
) + " : cannot " +
3417 "override inherited member `" + name
+
3418 "' because it is sealed.");
3422 // Check that the permissions are not being changed
3424 MethodAttributes thisp
= flags
& MethodAttributes
.MemberAccessMask
;
3425 MethodAttributes base_classp
= base_method
.Attributes
& MethodAttributes
.MemberAccessMask
;
3427 if (!CheckAccessModifiers (thisp
, base_classp
, base_method
)) {
3428 Error_CannotChangeAccessModifiers (Parent
, base_method
, name
);
3433 if ((ModFlags
& (Modifiers
.NEW
| Modifiers
.OVERRIDE
)) == 0 && Name
!= "Finalize") {
3434 ModFlags
|= Modifiers
.NEW
;
3435 Report
.SymbolRelatedToPreviousError (base_method
);
3436 if (!IsInterface
&& (base_method
.IsVirtual
|| base_method
.IsAbstract
)) {
3437 if (RootContext
.WarningLevel
>= 2)
3438 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 (base_method
));
3440 Report
.Warning (108, Location
, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent
));
3446 protected bool CheckAccessModifiers (MethodAttributes thisp
, MethodAttributes base_classp
, MethodInfo base_method
)
3448 if ((base_classp
& MethodAttributes
.FamORAssem
) == MethodAttributes
.FamORAssem
){
3450 // when overriding protected internal, the method can be declared
3451 // protected internal only within the same assembly
3454 if ((thisp
& MethodAttributes
.FamORAssem
) == MethodAttributes
.FamORAssem
){
3455 if (Parent
.TypeBuilder
.Assembly
!= base_method
.DeclaringType
.Assembly
){
3457 // assemblies differ - report an error
3461 } else if (thisp
!= base_classp
) {
3463 // same assembly, but other attributes differ - report an error
3468 } else if ((thisp
& MethodAttributes
.Family
) != MethodAttributes
.Family
) {
3470 // if it's not "protected internal", it must be "protected"
3474 } else if (Parent
.TypeBuilder
.Assembly
== base_method
.DeclaringType
.Assembly
) {
3476 // protected within the same assembly - an error
3479 } else if ((thisp
& ~
(MethodAttributes
.Family
| MethodAttributes
.FamORAssem
)) !=
3480 (base_classp
& ~
(MethodAttributes
.Family
| MethodAttributes
.FamORAssem
))) {
3482 // protected ok, but other attributes differ - report an error
3488 return (thisp
== base_classp
);
3492 void Error_CannotChangeAccessModifiers (TypeContainer parent
, MethodInfo base_method
, string name
)
3495 // FIXME: report the old/new permissions?
3498 507, Location
, parent
.MakeName (Name
) +
3499 ": can't change the access modifiers when overriding inherited " +
3500 "member `" + name
+ "'");
3503 protected static string Error722
{
3505 return "'{0}': static types cannot be used as return types";
3510 /// For custom member duplication search in a container
3512 protected abstract bool CheckForDuplications ();
3515 /// Gets base method and its return type
3517 protected abstract MethodInfo
FindOutBaseMethod (TypeContainer container
, ref Type base_ret_type
);
3519 protected virtual bool DoDefineParameters ()
3521 EmitContext ec
= ds
.EmitContext
;
3523 throw new InternalErrorException ("DoDefineParameters invoked too early");
3525 bool old_unsafe
= ec
.InUnsafe
;
3526 ec
.InUnsafe
= InUnsafe
;
3527 // Check if arguments were correct
3528 parameter_types
= Parameters
.GetParameterInfo (ec
);
3529 ec
.InUnsafe
= old_unsafe
;
3531 if ((parameter_types
== null) ||
3532 !CheckParameters (ds
, parameter_types
))
3535 TypeParameter
[] tparam
= ds
.IsGeneric
? ds
.TypeParameters
: null;
3536 parameter_info
= new InternalParameters (parameter_types
, Parameters
, tparam
);
3538 Parameter array_param
= Parameters
.ArrayParameter
;
3539 if ((array_param
!= null) &&
3540 (!array_param
.ParameterType
.IsArray
||
3541 (array_param
.ParameterType
.GetArrayRank () != 1))) {
3542 Report
.Error (225, Location
, "params parameter has to be a single dimensional array");
3549 void error_425 (Type old
, Type t
, string name
)
3551 Report
.Error (425, Location
,
3552 "The constraints of type parameter `{0}' " +
3553 "of method `{1}' must match the constraints for " +
3554 "type parameter `{2}' of method `{3}'",
3555 TypeManager
.CSharpName (old
), Name
,
3556 TypeManager
.CSharpName (t
), name
);
3559 protected override bool CheckGenericOverride (MethodInfo method
, string name
)
3561 ParameterData pd
= Invocation
.GetParameterData (method
);
3563 for (int i
= 0; i
< ParameterTypes
.Length
; i
++) {
3564 GenericConstraints ogc
= pd
.GenericConstraints (i
);
3565 GenericConstraints gc
= ParameterInfo
.GenericConstraints (i
);
3567 if ((gc
== null) && (ogc
== null))
3570 Type ot
= pd
.ParameterType (i
);
3571 Type t
= ParameterTypes
[i
];
3573 if (!((gc
!= null) && (ogc
!= null))) {
3574 error_425 (ot
, t
, name
);
3578 if ((gc
.Attributes
!= ogc
.Attributes
) ||
3579 (gc
.HasClassConstraint
!= ogc
.HasClassConstraint
)) {
3580 error_425 (ot
, t
, name
);
3584 if (ogc
.HasClassConstraint
&&
3585 !ogc
.ClassConstraint
.Equals (gc
.ClassConstraint
)) {
3586 error_425 (ot
, t
, name
);
3590 Type
[] oct
= ogc
.InterfaceConstraints
;
3591 Type
[] ct
= gc
.InterfaceConstraints
;
3593 if (oct
.Length
!= ct
.Length
) {
3594 error_425 (ot
, t
, name
);
3598 for (int j
= 0; j
< oct
.Length
; j
++)
3599 if (!oct
[j
].Equals (ct
[j
])) {
3600 error_425 (ot
, t
, name
);
3608 public override string[] ValidAttributeTargets
{
3610 return attribute_targets
;
3614 protected override bool VerifyClsCompliance (DeclSpace ds
)
3616 if (!base.VerifyClsCompliance (ds
)) {
3617 if ((ModFlags
& Modifiers
.ABSTRACT
) != 0 && IsExposedFromAssembly (ds
) && ds
.IsClsCompliaceRequired (ds
)) {
3618 Report
.Error (3011, Location
, "'{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3623 if (Parameters
.HasArglist
) {
3624 Report
.Error (3000, Location
, "Methods with variable arguments are not CLS-compliant");
3627 if (!AttributeTester
.IsClsCompliant (MemberType
)) {
3628 if (this is PropertyBase
)
3629 Report
.Error (3003, Location
, "Type of `{0}' is not CLS-compliant",
3630 GetSignatureForError ());
3632 Report
.Error (3002, Location
, "Return type of '{0}' is not CLS-compliant",
3633 GetSignatureForError ());
3636 AttributeTester
.AreParametersCompliant (Parameters
.FixedParameters
, Location
);
3641 bool MayUnify (MethodCore first
, MethodCore second
)
3643 int a_type_params
= 0;
3644 if (first
.GenericMethod
!= null)
3645 a_type_params
= first
.GenericMethod
.CountTypeParameters
;
3647 int b_type_params
= 0;
3648 if (second
.GenericMethod
!= null)
3649 b_type_params
= second
.GenericMethod
.CountTypeParameters
;
3651 if (a_type_params
!= b_type_params
)
3654 Type
[] class_infered
, method_infered
;
3655 if (Parent
.CountTypeParameters
> 0)
3656 class_infered
= new Type
[Parent
.CountTypeParameters
];
3658 class_infered
= null;
3660 if (a_type_params
> 0)
3661 method_infered
= new Type
[a_type_params
];
3663 method_infered
= null;
3665 return TypeManager
.MayBecomeEqualGenericInstances (
3666 first
.ParameterTypes
, second
.ParameterTypes
, class_infered
, method_infered
);
3669 protected bool IsDuplicateImplementation (MethodCore method
)
3671 if ((method
== this) ||
3672 (method
.MemberName
.GetTypeName () != MemberName
.GetTypeName ()))
3675 Type
[] param_types
= method
.ParameterTypes
;
3676 if (param_types
== null)
3679 if (param_types
.Length
!= ParameterTypes
.Length
)
3683 bool may_unify
= MayUnify (this, method
);
3685 for (int i
= 0; i
< param_types
.Length
; i
++) {
3686 if (param_types
[i
] != ParameterTypes
[i
])
3690 // TODO: make operator compatible with MethodCore to avoid this
3691 if (this is Operator
&& method
is Operator
) {
3692 if (MemberType
!= method
.MemberType
)
3693 equal
= may_unify
= false;
3698 // Try to report 663: method only differs on out/ref
3700 ParameterData info
= ParameterInfo
;
3701 ParameterData other_info
= method
.ParameterInfo
;
3702 for (int i
= 0; i
< info
.Count
; i
++){
3703 if (info
.ParameterModifier (i
) != other_info
.ParameterModifier (i
)){
3704 Report
.Error (663, Location
,
3705 "Overload method only differs " +
3706 "in parameter modifier");
3711 Report
.SymbolRelatedToPreviousError (method
);
3712 Report
.Error (111, Location
, "Type '{0}' already defines a member called '{1}' with the same parameter types", Parent
.Name
, Name
);
3714 } else if (may_unify
) {
3715 Report
.Error (408, Location
,
3716 "`{0}' cannot define overload members that " +
3717 "may unify for some type parameter substitutions",
3726 // Returns a string that represents the signature for this
3727 // member which should be used in XML documentation.
3729 public override string GetDocCommentName (DeclSpace ds
)
3731 return DocUtil
.GetMethodDocCommentName (this, ds
);
3735 // Raised (and passed an XmlElement that contains the comment)
3736 // when GenerateDocComment is writing documentation expectedly.
3738 // FIXME: with a few effort, it could be done with XmlReader,
3739 // that means removal of DOM use.
3741 internal override void OnGenerateDocComment (DeclSpace ds
, XmlElement el
)
3743 DocUtil
.OnMethodGenerateDocComment (this, ds
, el
);
3747 // Represents header string for documentation comment.
3749 public override string DocCommentHeader
{
3750 get { return "M:"; }
3753 protected override void VerifyObsoleteAttribute()
3755 base.VerifyObsoleteAttribute ();
3757 if (parameter_types
== null)
3760 foreach (Type type
in parameter_types
) {
3761 CheckUsageOfObsoleteAttribute (type
);
3766 public class SourceMethod
: ISourceMethod
3768 TypeContainer container
;
3771 protected SourceMethod (TypeContainer container
, MethodBase builder
,
3772 ISourceFile file
, Location start
, Location end
)
3774 this.container
= container
;
3775 this.builder
= builder
;
3777 CodeGen
.SymbolWriter
.OpenMethod (
3778 file
, this, start
.Row
, 0, end
.Row
, 0);
3781 public string Name
{
3782 get { return builder.Name; }
3785 public int NamespaceID
{
3786 get { return container.NamespaceEntry.SymbolFileID; }
3791 if (builder
is MethodBuilder
)
3792 return ((MethodBuilder
) builder
).GetToken ().Token
;
3793 else if (builder
is ConstructorBuilder
)
3794 return ((ConstructorBuilder
) builder
).GetToken ().Token
;
3796 throw new NotSupportedException ();
3800 public void CloseMethod ()
3802 if (CodeGen
.SymbolWriter
!= null)
3803 CodeGen
.SymbolWriter
.CloseMethod ();
3806 public static SourceMethod
Create (TypeContainer parent
,
3807 MethodBase builder
, Block block
)
3809 if (CodeGen
.SymbolWriter
== null)
3814 Location start_loc
= block
.StartLocation
;
3815 if (Location
.IsNull (start_loc
))
3818 Location end_loc
= block
.EndLocation
;
3819 if (Location
.IsNull (end_loc
))
3822 ISourceFile file
= start_loc
.SourceFile
;
3826 return new SourceMethod (
3827 parent
, builder
, file
, start_loc
, end_loc
);
3831 public class Method
: MethodCore
, IIteratorContainer
, IMethodData
{
3832 public MethodBuilder MethodBuilder
;
3833 public MethodData MethodData
;
3834 ReturnParameter return_attributes
;
3835 ListDictionary declarative_security
;
3838 /// Modifiers allowed in a class declaration
3840 const int AllowedModifiers
=
3843 Modifiers
.PROTECTED
|
3844 Modifiers
.INTERNAL
|
3849 Modifiers
.OVERRIDE
|
3850 Modifiers
.ABSTRACT
|
3852 Modifiers
.METHOD_YIELDS
|
3855 const int AllowedInterfaceModifiers
=
3856 Modifiers
.NEW
| Modifiers
.UNSAFE
;
3859 // return_type can be "null" for VOID values.
3861 public Method (TypeContainer parent
, GenericMethod generic
,
3862 Expression return_type
, int mod
, bool is_iface
,
3863 MemberName name
, Parameters parameters
, Attributes attrs
,
3865 : base (parent
, generic
, return_type
, mod
,
3866 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
3867 is_iface
, name
, attrs
, parameters
, l
)
3871 public override AttributeTargets AttributeTargets
{
3873 return AttributeTargets
.Method
;
3877 public override string GetSignatureForError()
3879 if (MethodBuilder
== null) {
3880 return GetSignatureForError (Parent
);
3882 return TypeManager
.CSharpSignature (MethodBuilder
);
3886 /// Use this method when MethodBuilder is null
3888 public override string GetSignatureForError (TypeContainer tc
)
3890 // TODO: get params from somewhere
3891 if (parameter_info
== null)
3892 return base.GetSignatureForError (tc
);
3894 // TODO: move to parameters
3895 System
.Text
.StringBuilder args
= new System
.Text
.StringBuilder ();
3896 if (parameter_info
.Parameters
.FixedParameters
!= null) {
3897 for (int i
= 0; i
< parameter_info
.Parameters
.FixedParameters
.Length
; ++i
) {
3898 Parameter p
= parameter_info
.Parameters
.FixedParameters
[i
];
3899 args
.Append (p
.GetSignatureForError ());
3901 if (i
< parameter_info
.Parameters
.FixedParameters
.Length
- 1)
3906 return String
.Concat (base.GetSignatureForError (tc
), "(", args
.ToString (), ")");
3909 void DuplicateEntryPoint (MethodInfo b
, Location location
)
3913 "Program `" + CodeGen
.FileName
+
3914 "' has more than one entry point defined: `" +
3915 TypeManager
.CSharpSignature(b
) + "'");
3918 public bool IsEntryPoint (MethodBuilder b
, InternalParameters pinfo
)
3920 if (b
.ReturnType
!= TypeManager
.void_type
&&
3921 b
.ReturnType
!= TypeManager
.int32_type
)
3924 if (pinfo
.Count
== 0)
3927 if (pinfo
.Count
> 1)
3930 Type t
= pinfo
.ParameterType(0);
3932 (t
.GetArrayRank() == 1) &&
3933 (TypeManager
.GetElementType(t
) == TypeManager
.string_type
) &&
3934 (pinfo
.ParameterModifier(0) == Parameter
.Modifier
.NONE
))
3940 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
3942 if (a
.Target
== AttributeTargets
.ReturnValue
) {
3943 if (return_attributes
== null)
3944 return_attributes
= new ReturnParameter (MethodBuilder
, Location
);
3946 return_attributes
.ApplyAttributeBuilder (a
, cb
);
3950 if (a
.Type
== TypeManager
.methodimpl_attr_type
&& a
.IsInternalCall
) {
3951 MethodBuilder
.SetImplementationFlags (MethodImplAttributes
.InternalCall
| MethodImplAttributes
.Runtime
);
3954 if (a
.Type
== TypeManager
.dllimport_type
) {
3955 const int extern_static
= Modifiers
.EXTERN
| Modifiers
.STATIC
;
3956 if ((ModFlags
& extern_static
) != extern_static
) {
3957 Report
.Error (601, a
.Location
, "The DllImport attribute must be specified on a method marked `static' and `extern'");
3963 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
3964 if (declarative_security
== null)
3965 declarative_security
= new ListDictionary ();
3966 a
.ExtractSecurityPermissionSet (declarative_security
);
3970 if (a
.Type
== TypeManager
.conditional_attribute_type
) {
3971 if (IsOperator
|| IsExplicitImpl
) {
3972 Report
.Error (577, Location
, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
3976 if (ReturnType
!= TypeManager
.void_type
) {
3977 Report
.Error (578, Location
, "Conditional not valid on '{0}' because its return new ErrorData ( type is not void", GetSignatureForError ());
3981 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3982 Report
.Error (243, Location
, "Conditional not valid on '{0}' because it is an override method", GetSignatureForError ());
3987 Report
.Error (582, Location
, "Conditional not valid on interface members");
3991 if (MethodData
.IsImplementing
) {
3992 Report
.Error (629, Location
, "Conditional member '{0}' cannot implement interface member", GetSignatureForError ());
3996 for (int i
= 0; i
< parameter_info
.Count
; ++i
) {
3997 if ((parameter_info
.ParameterModifier (i
) & Parameter
.Modifier
.OUT
) != 0) {
3998 Report
.Error (685, Location
, "Conditional method '{0}' cannot have an out parameter", GetSignatureForError ());
4004 MethodBuilder
.SetCustomAttribute (cb
);
4007 protected override bool CheckForDuplications ()
4009 ArrayList ar
= Parent
.Methods
;
4011 int arLen
= ar
.Count
;
4013 for (int i
= 0; i
< arLen
; i
++) {
4014 Method m
= (Method
) ar
[i
];
4015 if (IsDuplicateImplementation (m
))
4020 ar
= Parent
.Properties
;
4022 for (int i
= 0; i
< ar
.Count
; ++i
) {
4023 PropertyBase pb
= (PropertyBase
) ar
[i
];
4024 if (pb
.AreAccessorsDuplicateImplementation (this))
4029 ar
= Parent
.Indexers
;
4031 for (int i
= 0; i
< ar
.Count
; ++i
) {
4032 PropertyBase pb
= (PropertyBase
) ar
[i
];
4033 if (pb
.AreAccessorsDuplicateImplementation (this))
4040 for (int i
= 0; i
< ar
.Count
; ++i
) {
4041 Event ev
= (Event
) ar
[i
];
4042 if (ev
.AreAccessorsDuplicateImplementation (this))
4053 public override bool Define ()
4055 if (!DoDefineBase ())
4058 MethodBuilder mb
= null;
4059 if (GenericMethod
!= null) {
4060 string mname
= MemberName
.GetMethodName ();
4061 mb
= Parent
.TypeBuilder
.DefineGenericMethod (mname
, flags
);
4062 if (!GenericMethod
.Define (mb
, ReturnType
))
4073 flags
|= MethodAttributes
.SpecialName
| MethodAttributes
.HideBySig
;
4075 MethodData
= new MethodData (this, ParameterInfo
, ModFlags
, flags
,
4076 this, mb
, GenericMethod
, base_method
);
4078 if (!MethodData
.Define (Parent
))
4082 // Setup iterator if we are one
4084 if ((ModFlags
& Modifiers
.METHOD_YIELDS
) != 0){
4085 Iterator iterator
= new Iterator (
4086 Parent
, Name
, MemberType
, ParameterTypes
,
4087 ParameterInfo
, ModFlags
, block
, Location
);
4089 if (!iterator
.DefineIterator ())
4092 block
= iterator
.Block
;
4095 MethodBuilder
= MethodData
.MethodBuilder
;
4098 // This is used to track the Entry Point,
4100 if (Name
== "Main" &&
4101 ((ModFlags
& Modifiers
.STATIC
) != 0) && RootContext
.NeedsEntryPoint
&&
4102 (RootContext
.MainClass
== null ||
4103 RootContext
.MainClass
== Parent
.TypeBuilder
.FullName
)){
4104 if (IsEntryPoint (MethodBuilder
, ParameterInfo
)) {
4105 if (RootContext
.EntryPoint
== null) {
4106 if (Parent
.IsGeneric
){
4107 Report
.Error (-201, Location
,
4108 "Entry point can not be defined in a generic class");
4111 RootContext
.EntryPoint
= MethodBuilder
;
4112 RootContext
.EntryPointLocation
= Location
;
4114 DuplicateEntryPoint (RootContext
.EntryPoint
, RootContext
.EntryPointLocation
);
4115 DuplicateEntryPoint (MethodBuilder
, Location
);
4118 if (RootContext
.WarningLevel
>= 4)
4119 Report
.Warning (28, Location
, "'{0}' has the wrong signature to be an entry point", TypeManager
.CSharpSignature(MethodBuilder
) );
4123 if (MemberType
.IsAbstract
&& MemberType
.IsSealed
) {
4124 Report
.Error (722, Location
, Error722
, TypeManager
.CSharpName (MemberType
));
4134 public override void Emit ()
4136 MethodData
.Emit (Parent
, this);
4139 if (declarative_security
!= null) {
4140 foreach (DictionaryEntry de
in declarative_security
) {
4141 MethodBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
4149 protected override MethodInfo
FindOutBaseMethod (TypeContainer container
, ref Type base_ret_type
)
4151 MethodInfo mi
= (MethodInfo
) container
.BaseCache
.FindMemberToOverride (
4152 container
.TypeBuilder
, Name
, ParameterTypes
, false);
4157 base_ret_type
= mi
.ReturnType
;
4161 public override bool MarkForDuplicationCheck ()
4163 caching_flags
|= Flags
.TestMethodDuplication
;
4167 protected override bool VerifyClsCompliance(DeclSpace ds
)
4169 if (!base.VerifyClsCompliance (ds
))
4172 if (parameter_types
.Length
> 0) {
4173 ArrayList al
= (ArrayList
)ds
.MemberCache
.Members
[Name
];
4175 ds
.MemberCache
.VerifyClsParameterConflict (al
, this, MethodBuilder
);
4182 void IIteratorContainer
.SetYields ()
4184 ModFlags
|= Modifiers
.METHOD_YIELDS
;
4187 #region IMethodData Members
4189 public CallingConventions CallingConventions
{
4191 CallingConventions cc
= Parameters
.GetCallingConvention ();
4192 if (Parameters
.HasArglist
)
4193 block
.HasVarargs
= true;
4196 if ((ModFlags
& Modifiers
.STATIC
) == 0)
4197 cc
|= CallingConventions
.HasThis
;
4199 // FIXME: How is `ExplicitThis' used in C#?
4205 public Type ReturnType
{
4211 public MemberName MethodName
{
4217 public new Location Location
{
4219 return base.Location
;
4223 public EmitContext
CreateEmitContext (TypeContainer tc
, ILGenerator ig
)
4225 return new EmitContext (
4226 tc
, ds
, Location
, ig
, ReturnType
, ModFlags
, false);
4229 public ObsoleteAttribute
GetObsoleteAttribute ()
4231 return GetObsoleteAttribute (ds
);
4235 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
4237 public bool IsExcluded (EmitContext ec
)
4239 if ((caching_flags
& Flags
.Excluded_Undetected
) == 0)
4240 return (caching_flags
& Flags
.Excluded
) != 0;
4242 caching_flags
&= ~Flags
.Excluded_Undetected
;
4244 if (base_method
== null) {
4245 if (OptAttributes
== null)
4248 Attribute
[] attrs
= OptAttributes
.SearchMulti (TypeManager
.conditional_attribute_type
, ec
);
4253 foreach (Attribute a
in attrs
) {
4254 string condition
= a
.GetConditionalAttributeValue (Parent
.EmitContext
);
4255 if (RootContext
.AllDefines
.Contains (condition
))
4259 caching_flags
|= Flags
.Excluded
;
4263 IMethodData md
= TypeManager
.GetMethod (base_method
);
4265 if (AttributeTester
.IsConditionalMethodExcluded (base_method
)) {
4266 caching_flags
|= Flags
.Excluded
;
4272 if (md
.IsExcluded (ec
)) {
4273 caching_flags
|= Flags
.Excluded
;
4279 GenericMethod IMethodData
.GenericMethod
{
4281 return GenericMethod
;
4288 public abstract class ConstructorInitializer
{
4289 ArrayList argument_list
;
4290 protected ConstructorInfo base_constructor
;
4291 Parameters parameters
;
4294 public ConstructorInitializer (ArrayList argument_list
, Parameters parameters
,
4297 this.argument_list
= argument_list
;
4298 this.parameters
= parameters
;
4302 public ArrayList Arguments
{
4304 return argument_list
;
4308 public bool Resolve (ConstructorBuilder caller_builder
, EmitContext ec
)
4310 Expression base_constructor_group
;
4313 ec
.CurrentBlock
= new ToplevelBlock (Block
.Flags
.Implicit
, parameters
, loc
);
4315 if (argument_list
!= null){
4316 foreach (Argument a
in argument_list
){
4317 if (!a
.Resolve (ec
, loc
))
4321 ec
.CurrentBlock
= null;
4323 if (this is ConstructorBaseInitializer
) {
4324 if (ec
.ContainerType
.BaseType
== null)
4327 t
= ec
.ContainerType
.BaseType
;
4328 if (ec
.ContainerType
.IsValueType
) {
4329 Report
.Error (522, loc
,
4330 "structs cannot call base class constructors");
4334 t
= ec
.ContainerType
;
4336 base_constructor_group
= Expression
.MemberLookup (
4337 ec
, t
, ".ctor", MemberTypes
.Constructor
,
4338 BindingFlags
.Public
| BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
,
4341 if (base_constructor_group
== null){
4342 base_constructor_group
= Expression
.MemberLookup (
4343 ec
, t
, ".ctor", MemberTypes
.Constructor
,
4344 BindingFlags
.NonPublic
| BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
,
4347 if (base_constructor_group
!= null)
4349 112, loc
, "`{0}.{1}' is inaccessible due to " +
4350 "its protection level", t
.FullName
, t
.Name
);
4353 1501, loc
, "Can not find a constructor for " +
4354 "this argument list");
4358 base_constructor
= (ConstructorInfo
) Invocation
.OverloadResolve (
4359 ec
, (MethodGroupExpr
) base_constructor_group
, argument_list
,
4362 if (base_constructor
== null){
4363 Report
.Error (1501, loc
,
4364 "Can not find a constructor for this argument list");
4368 if (base_constructor
== caller_builder
){
4369 Report
.Error (516, String
.Format ("Constructor `{0}' can not call itself", TypeManager
.CSharpSignature (caller_builder
)));
4376 public void Emit (EmitContext ec
)
4378 if (base_constructor
!= null){
4379 ec
.Mark (loc
, false);
4381 Invocation
.EmitCall (ec
, true, true, null, base_constructor
, argument_list
, loc
);
4383 Invocation
.EmitCall (ec
, true, false, ec
.GetThis (loc
), base_constructor
, argument_list
, loc
);
4388 /// Method search for base ctor. (We do not cache it).
4390 Constructor
GetOverloadedConstructor (TypeContainer tc
)
4392 if (tc
.InstanceConstructors
== null)
4395 foreach (Constructor c
in tc
.InstanceConstructors
) {
4396 if (Arguments
== null) {
4397 if (c
.ParameterTypes
.Length
== 0)
4405 int count
= c
.ParameterInfo
.Count
;
4407 c
.ParameterInfo
.ParameterModifier (count
- 1) == Parameter
.Modifier
.PARAMS
) {
4408 for (int i
= 0; i
< count
-1; i
++)
4409 if (c
.ParameterTypes
[i
] != ((Argument
)Arguments
[i
]).Type
) {
4414 if (c
.ParameterTypes
.Length
!= Arguments
.Count
)
4417 for (int i
= 0; i
< Arguments
.Count
; ++i
)
4418 if (c
.ParameterTypes
[i
] != ((Argument
)Arguments
[i
]).Type
) {
4433 //TODO: implement caching when it will be necessary
4434 public virtual void CheckObsoleteAttribute (TypeContainer tc
, Location loc
)
4436 Constructor ctor
= GetOverloadedConstructor (tc
);
4440 ObsoleteAttribute oa
= ctor
.GetObsoleteAttribute (tc
);
4444 AttributeTester
.Report_ObsoleteMessage (oa
, ctor
.GetSignatureForError (), loc
);
4448 public class ConstructorBaseInitializer
: ConstructorInitializer
{
4449 public ConstructorBaseInitializer (ArrayList argument_list
, Parameters pars
, Location l
) :
4450 base (argument_list
, pars
, l
)
4454 public override void CheckObsoleteAttribute(TypeContainer tc
, Location loc
) {
4455 if (base_constructor
== null)
4458 TypeContainer type_ds
= TypeManager
.LookupTypeContainer (tc
.TypeBuilder
.BaseType
);
4459 if (type_ds
== null) {
4460 ObsoleteAttribute oa
= AttributeTester
.GetMemberObsoleteAttribute (base_constructor
);
4463 AttributeTester
.Report_ObsoleteMessage (oa
, TypeManager
.CSharpSignature (base_constructor
), loc
);
4468 base.CheckObsoleteAttribute (type_ds
, loc
);
4473 public class ConstructorThisInitializer
: ConstructorInitializer
{
4474 public ConstructorThisInitializer (ArrayList argument_list
, Parameters pars
, Location l
) :
4475 base (argument_list
, pars
, l
)
4480 public class Constructor
: MethodCore
, IMethodData
{
4481 public ConstructorBuilder ConstructorBuilder
;
4482 public ConstructorInitializer Initializer
;
4483 ListDictionary declarative_security
;
4486 // Modifiers allowed for a constructor.
4488 public const int AllowedModifiers
=
4490 Modifiers
.PROTECTED
|
4491 Modifiers
.INTERNAL
|
4497 bool has_compliant_args
= false;
4499 // The spec claims that static is not permitted, but
4500 // my very own code has static constructors.
4502 public Constructor (TypeContainer ds
, string name
, int mod
, Parameters args
,
4503 ConstructorInitializer init
, Location l
)
4504 : base (ds
, null, null, mod
, AllowedModifiers
, false,
4505 new MemberName (name
), null, args
, l
)
4510 public override string GetSignatureForError()
4512 if (ConstructorBuilder
== null)
4513 return GetSignatureForError (Parent
);
4515 return TypeManager
.CSharpSignature (ConstructorBuilder
);
4518 public bool HasCompliantArgs
{
4520 return has_compliant_args
;
4524 public override AttributeTargets AttributeTargets
{
4526 return AttributeTargets
.Constructor
;
4532 // Returns true if this is a default constructor
4534 public bool IsDefault ()
4536 if ((ModFlags
& Modifiers
.STATIC
) != 0)
4537 return (Parameters
.FixedParameters
== null ? true : Parameters
.Empty
) &&
4538 (Parameters
.ArrayParameter
== null ? true : Parameters
.Empty
);
4541 return (Parameters
.FixedParameters
== null ? true : Parameters
.Empty
) &&
4542 (Parameters
.ArrayParameter
== null ? true : Parameters
.Empty
) &&
4543 (Initializer
is ConstructorBaseInitializer
) &&
4544 (Initializer
.Arguments
== null);
4547 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
4549 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
4550 if (declarative_security
== null) {
4551 declarative_security
= new ListDictionary ();
4553 a
.ExtractSecurityPermissionSet (declarative_security
);
4557 ConstructorBuilder
.SetCustomAttribute (cb
);
4560 protected override bool CheckForDuplications ()
4562 ArrayList ar
= Parent
.InstanceConstructors
;
4564 int arLen
= ar
.Count
;
4566 for (int i
= 0; i
< arLen
; i
++) {
4567 Constructor m
= (Constructor
) ar
[i
];
4568 if (IsDuplicateImplementation (m
))
4575 protected override bool CheckBase ()
4577 // Check whether arguments were correct.
4578 if (!DoDefineParameters ())
4581 // TODO: skip the rest for generated ctor
4582 if ((ModFlags
& Modifiers
.STATIC
) != 0)
4585 if (!CheckForDuplications ())
4588 if (Parent
.Kind
== Kind
.Struct
) {
4589 if (ParameterTypes
.Length
== 0) {
4590 Report
.Error (568, Location
,
4591 "Structs can not contain explicit parameterless " +
4596 if ((ModFlags
& Modifiers
.PROTECTED
) != 0) {
4597 Report
.Error (666, Location
, "Protected member in struct declaration");
4602 if ((RootContext
.WarningLevel
>= 4) && ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0 && (ModFlags
& Modifiers
.PROTECTED
) != 0)) {
4603 Report
.Warning (628, Location
, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent
));
4610 // Creates the ConstructorBuilder
4612 public override bool Define ()
4614 MethodAttributes ca
= (MethodAttributes
.RTSpecialName
|
4615 MethodAttributes
.SpecialName
);
4617 if ((ModFlags
& Modifiers
.STATIC
) != 0){
4618 ca
|= MethodAttributes
.Static
| MethodAttributes
.Private
;
4620 ca
|= MethodAttributes
.HideBySig
;
4622 if ((ModFlags
& Modifiers
.PUBLIC
) != 0)
4623 ca
|= MethodAttributes
.Public
;
4624 else if ((ModFlags
& Modifiers
.PROTECTED
) != 0){
4625 if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
4626 ca
|= MethodAttributes
.FamORAssem
;
4628 ca
|= MethodAttributes
.Family
;
4629 } else if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
4630 ca
|= MethodAttributes
.Assembly
;
4631 else if (IsDefault ())
4632 ca
|= MethodAttributes
.Public
;
4634 ca
|= MethodAttributes
.Private
;
4637 // Check if arguments were correct.
4641 ConstructorBuilder
= Parent
.TypeBuilder
.DefineConstructor (
4642 ca
, CallingConventions
,
4645 if ((ModFlags
& Modifiers
.UNSAFE
) != 0)
4646 ConstructorBuilder
.InitLocals
= false;
4648 TypeManager
.AddMethod (ConstructorBuilder
, this);
4651 // HACK because System.Reflection.Emit is lame
4653 TypeManager
.RegisterMethod (ConstructorBuilder
, ParameterInfo
, ParameterTypes
);
4661 public override void Emit ()
4663 EmitContext ec
= CreateEmitContext (null, null);
4666 // extern methods have no bodies
4668 if ((ModFlags
& Modifiers
.EXTERN
) != 0) {
4669 if ((block
!= null) && ((ModFlags
& Modifiers
.EXTERN
) != 0)) {
4671 179, Location
, "External constructor `" +
4672 TypeManager
.CSharpSignature (ConstructorBuilder
) +
4673 "' can not have a body");
4676 } else if (block
== null) {
4678 501, Location
, "Constructor `" +
4679 TypeManager
.CSharpSignature (ConstructorBuilder
) +
4680 "' must declare a body since it is not marked extern");
4684 if ((ModFlags
& Modifiers
.STATIC
) == 0){
4685 if (Parent
.Kind
== Kind
.Class
&& Initializer
== null)
4686 Initializer
= new ConstructorBaseInitializer (
4687 null, Parameters
.EmptyReadOnlyParameters
, Location
);
4691 // Spec mandates that Initializers will not have
4695 if (Initializer
!= null && !Initializer
.Resolve (ConstructorBuilder
, ec
))
4697 ec
.IsStatic
= false;
4700 Parameters
.LabelParameters (ec
, ConstructorBuilder
, Location
);
4702 SourceMethod source
= SourceMethod
.Create (
4703 Parent
, ConstructorBuilder
, block
);
4706 // Classes can have base initializers and instance field initializers.
4708 if (Parent
.Kind
== Kind
.Class
){
4709 if ((ModFlags
& Modifiers
.STATIC
) == 0){
4712 // If we use a "this (...)" constructor initializer, then
4713 // do not emit field initializers, they are initialized in the other constructor
4715 if (!(Initializer
!= null && Initializer
is ConstructorThisInitializer
))
4716 Parent
.EmitFieldInitializers (ec
);
4719 if (Initializer
!= null) {
4720 if (GetObsoleteAttribute (Parent
) == null && Parent
.GetObsoleteAttribute (Parent
.Parent
) == null)
4721 Initializer
.CheckObsoleteAttribute (Parent
, Location
);
4723 ec
.TestObsoleteMethodUsage
= false;
4724 Initializer
.Emit (ec
);
4727 if ((ModFlags
& Modifiers
.STATIC
) != 0)
4728 Parent
.EmitFieldInitializers (ec
);
4730 if (OptAttributes
!= null)
4731 OptAttributes
.Emit (ec
, this);
4733 // If this is a non-static `struct' constructor and doesn't have any
4734 // initializer, it must initialize all of the struct's fields.
4735 if ((Parent
.Kind
== Kind
.Struct
) &&
4736 ((ModFlags
& Modifiers
.STATIC
) == 0) && (Initializer
== null))
4737 Block
.AddThisVariable (Parent
, Location
);
4739 ec
.EmitTopBlock (block
, ParameterInfo
, Location
);
4742 source
.CloseMethod ();
4746 if (declarative_security
!= null) {
4747 foreach (DictionaryEntry de
in declarative_security
) {
4748 ConstructorBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
4755 // Is never override
4756 protected override MethodInfo
FindOutBaseMethod (TypeContainer container
, ref Type base_ret_type
)
4761 protected override bool VerifyClsCompliance (DeclSpace ds
)
4763 if (!base.VerifyClsCompliance (ds
) || !IsExposedFromAssembly (ds
)) {
4767 if (parameter_types
.Length
> 0) {
4768 ArrayList al
= (ArrayList
)ds
.MemberCache
.Members
[".ctor"];
4770 ds
.MemberCache
.VerifyClsParameterConflict (al
, this, ConstructorBuilder
);
4772 if (ds
.TypeBuilder
.IsSubclassOf (TypeManager
.attribute_type
)) {
4773 foreach (Type param
in parameter_types
) {
4774 if (param
.IsArray
) {
4780 has_compliant_args
= true;
4784 #region IMethodData Members
4786 public System
.Reflection
.CallingConventions CallingConventions
{
4788 CallingConventions cc
= Parameters
.GetCallingConvention ();
4790 if (Parent
.Kind
== Kind
.Class
)
4791 if ((ModFlags
& Modifiers
.STATIC
) == 0)
4792 cc
|= CallingConventions
.HasThis
;
4794 // FIXME: How is `ExplicitThis' used in C#?
4800 public new Location Location
{
4802 return base.Location
;
4806 public MemberName MethodName
{
4812 public Type ReturnType
{
4818 public EmitContext
CreateEmitContext (TypeContainer tc
, ILGenerator ig
)
4820 ILGenerator ig_
= ConstructorBuilder
.GetILGenerator ();
4821 return new EmitContext (Parent
, Location
, ig_
, null, ModFlags
, true);
4824 public ObsoleteAttribute
GetObsoleteAttribute ()
4829 public bool IsExcluded(EmitContext ec
)
4834 GenericMethod IMethodData
.GenericMethod
{
4844 /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
4846 public interface IMethodData
4848 CallingConventions CallingConventions { get; }
4849 Location Location { get; }
4850 MemberName MethodName { get; }
4851 Type
[] ParameterTypes { get; }
4852 Type ReturnType { get; }
4853 GenericMethod GenericMethod { get; }
4855 Attributes OptAttributes { get; }
4856 ToplevelBlock Block { get; }
4858 EmitContext
CreateEmitContext (TypeContainer tc
, ILGenerator ig
);
4859 ObsoleteAttribute
GetObsoleteAttribute ();
4860 string GetSignatureForError (TypeContainer tc
);
4861 bool IsExcluded (EmitContext ec
);
4862 bool IsClsCompliaceRequired (DeclSpace ds
);
4866 // Encapsulates most of the Method's state
4868 public class MethodData
{
4870 readonly IMethodData method
;
4873 // The return type of this method
4875 public readonly GenericMethod GenericMethod
;
4876 public readonly InternalParameters ParameterInfo
;
4879 // Are we implementing an interface ?
4881 public bool IsImplementing
= false;
4886 protected MemberBase member
;
4887 protected int modifiers
;
4888 protected MethodAttributes flags
;
4889 protected Type declaring_type
;
4890 protected MethodInfo parent_method
;
4894 MethodBuilder builder
= null;
4895 public MethodBuilder MethodBuilder
{
4901 public Type DeclaringType
{
4903 return declaring_type
;
4907 public MethodData (MemberBase member
, InternalParameters parameters
,
4908 int modifiers
, MethodAttributes flags
, IMethodData method
)
4910 this.member
= member
;
4911 this.ParameterInfo
= parameters
;
4912 this.modifiers
= modifiers
;
4915 this.method
= method
;
4918 public MethodData (MemberBase member
, InternalParameters parameters
,
4919 int modifiers
, MethodAttributes flags
,
4920 IMethodData method
, MethodBuilder builder
,
4921 GenericMethod generic
, MethodInfo parent_method
)
4922 : this (member
, parameters
, modifiers
, flags
, method
)
4924 this.builder
= builder
;
4925 this.GenericMethod
= generic
;
4926 this.parent_method
= parent_method
;
4929 static string RemoveArity (string name
)
4932 StringBuilder sb
= new StringBuilder ();
4933 while (start
< name
.Length
) {
4934 int pos
= name
.IndexOf ('`', start
);
4936 sb
.Append (name
.Substring (start
));
4940 sb
.Append (name
.Substring (start
, pos
-start
));
4943 while ((pos
< name
.Length
) && Char
.IsNumber (name
[pos
]))
4949 return sb
.ToString ();
4952 public bool Define (TypeContainer container
)
4954 MethodInfo implementing
= null;
4957 if (member
.IsExplicitImpl
)
4958 prefix
= member
.InterfaceType
.FullName
+ ".";
4962 string name
= method
.MethodName
.Basename
;
4963 string method_name
= prefix
+ name
;
4965 Type
[] ParameterTypes
= method
.ParameterTypes
;
4967 if (container
.Pending
!= null){
4968 if (member
is Indexer
)
4969 implementing
= container
.Pending
.IsInterfaceIndexer (
4970 member
.InterfaceType
, method
.ReturnType
, ParameterTypes
);
4972 implementing
= container
.Pending
.IsInterfaceMethod (
4973 member
.InterfaceType
, name
, method
.ReturnType
, ParameterTypes
);
4975 if (member
.InterfaceType
!= null){
4976 if (implementing
== null){
4977 Report
.Error (539, method
.Location
,
4978 "'{0}' in explicit interface declaration is not a member of interface", member
.GetSignatureForError () );
4985 // For implicit implementations, make sure we are public, for
4986 // explicit implementations, make sure we are private.
4988 if (implementing
!= null){
4990 // Setting null inside this block will trigger a more
4991 // verbose error reporting for missing interface implementations
4993 // The "candidate" function has been flagged already
4994 // but it wont get cleared
4996 if (member
.IsExplicitImpl
){
4997 if ((modifiers
& (Modifiers
.PUBLIC
| Modifiers
.ABSTRACT
| Modifiers
.VIRTUAL
)) != 0){
4998 Modifiers
.Error_InvalidModifier (method
.Location
, "public, virtual or abstract");
4999 implementing
= null;
5001 } else if ((flags
& MethodAttributes
.MemberAccessMask
) != MethodAttributes
.Public
){
5002 if (TypeManager
.IsInterfaceType (implementing
.DeclaringType
)){
5004 // If this is an interface method implementation,
5005 // check for public accessibility
5007 implementing
= null;
5008 } else if ((flags
& MethodAttributes
.MemberAccessMask
) == MethodAttributes
.Private
){
5009 // We may never be private.
5010 implementing
= null;
5011 } else if ((modifiers
& Modifiers
.OVERRIDE
) == 0){
5013 // We may be protected if we're overriding something.
5015 implementing
= null;
5020 // Static is not allowed
5022 if ((modifiers
& Modifiers
.STATIC
) != 0){
5023 implementing
= null;
5024 Modifiers
.Error_InvalidModifier (method
.Location
, "static");
5029 // If implementing is still valid, set flags
5031 if (implementing
!= null){
5033 // When implementing interface methods, set NewSlot
5034 // unless, we are overwriting a method.
5036 if (implementing
.DeclaringType
.IsInterface
){
5037 if ((modifiers
& Modifiers
.OVERRIDE
) == 0)
5038 flags
|= MethodAttributes
.NewSlot
;
5041 MethodAttributes
.Virtual
|
5042 MethodAttributes
.HideBySig
;
5044 // Set Final unless we're virtual, abstract or already overriding a method.
5045 if ((modifiers
& (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
| Modifiers
.OVERRIDE
)) == 0)
5046 flags
|= MethodAttributes
.Final
;
5048 IsImplementing
= true;
5051 EmitContext ec
= method
.CreateEmitContext (container
, null);
5053 DefineMethodBuilder (ec
, container
, method_name
, ParameterTypes
);
5055 if (builder
== null)
5058 if (container
.CurrentType
!= null)
5059 declaring_type
= container
.CurrentType
;
5061 declaring_type
= container
.TypeBuilder
;
5063 if ((modifiers
& Modifiers
.UNSAFE
) != 0)
5064 builder
.InitLocals
= false;
5066 if (IsImplementing
){
5068 // clear the pending implemntation flag
5070 if (member
is Indexer
) {
5071 container
.Pending
.ImplementIndexer (
5072 member
.InterfaceType
, builder
, method
.ReturnType
,
5073 ParameterTypes
, member
.IsExplicitImpl
);
5075 container
.Pending
.ImplementMethod (
5076 member
.InterfaceType
, name
, method
.ReturnType
,
5077 ParameterTypes
, member
.IsExplicitImpl
);
5079 if (member
.IsExplicitImpl
)
5080 container
.TypeBuilder
.DefineMethodOverride (
5081 builder
, implementing
);
5085 TypeManager
.RegisterMethod (builder
, ParameterInfo
, ParameterTypes
);
5086 TypeManager
.AddMethod (builder
, method
);
5088 if (GenericMethod
!= null) {
5089 bool is_override
= member
.IsExplicitImpl
|
5090 ((modifiers
& Modifiers
.OVERRIDE
) != 0);
5092 if (implementing
!= null)
5093 parent_method
= implementing
;
5095 if (!GenericMethod
.DefineType (ec
, builder
, parent_method
, is_override
))
5103 /// Create the MethodBuilder for the method
5105 void DefineMethodBuilder (EmitContext ec
, TypeContainer container
, string method_name
, Type
[] ParameterTypes
)
5107 const int extern_static
= Modifiers
.EXTERN
| Modifiers
.STATIC
;
5109 if ((modifiers
& extern_static
) == extern_static
) {
5111 if (method
.OptAttributes
!= null) {
5112 Attribute dllimport_attribute
= method
.OptAttributes
.Search (TypeManager
.dllimport_type
, ec
);
5113 if (dllimport_attribute
!= null) {
5114 flags
|= MethodAttributes
.PinvokeImpl
;
5115 builder
= dllimport_attribute
.DefinePInvokeMethod (
5116 ec
, container
.TypeBuilder
, method_name
, flags
,
5117 method
.ReturnType
, ParameterTypes
);
5123 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
5124 // We are more strict than Microsoft and report CS0626 like error
5125 if (method
.OptAttributes
== null ||
5126 !method
.OptAttributes
.Contains (TypeManager
.methodimpl_attr_type
, ec
)) {
5127 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
));
5132 if (builder
== null)
5133 builder
= container
.TypeBuilder
.DefineMethod (
5134 method_name
, flags
, method
.CallingConventions
,
5135 method
.ReturnType
, ParameterTypes
);
5137 builder
.SetGenericMethodSignature (
5138 flags
, method
.CallingConventions
,
5139 method
.ReturnType
, ParameterTypes
);
5145 public void Emit (TypeContainer container
, Attributable kind
)
5148 if ((flags
& MethodAttributes
.PinvokeImpl
) == 0)
5149 ec
= method
.CreateEmitContext (container
, builder
.GetILGenerator ());
5151 ec
= method
.CreateEmitContext (container
, null);
5153 if (method
.GetObsoleteAttribute () != null || container
.GetObsoleteAttribute (container
.Parent
) != null)
5154 ec
.TestObsoleteMethodUsage
= false;
5156 Location loc
= method
.Location
;
5157 Attributes OptAttributes
= method
.OptAttributes
;
5159 if (OptAttributes
!= null)
5160 OptAttributes
.Emit (ec
, kind
);
5162 if (member
is MethodCore
)
5163 ((MethodCore
) member
).Parameters
.LabelParameters (ec
, MethodBuilder
, loc
);
5165 ToplevelBlock block
= method
.Block
;
5168 // abstract or extern methods have no bodies
5170 if ((modifiers
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) != 0){
5175 // abstract or extern methods have no bodies.
5177 if ((modifiers
& Modifiers
.ABSTRACT
) != 0)
5179 500, method
.Location
, "Abstract method `" +
5180 TypeManager
.CSharpSignature (builder
) +
5181 "' can not have a body");
5183 if ((modifiers
& Modifiers
.EXTERN
) != 0)
5185 179, method
.Location
, "External method `" +
5186 TypeManager
.CSharpSignature (builder
) +
5187 "' can not have a body");
5193 // Methods must have a body unless they're extern or abstract
5195 if (block
== null) {
5197 501, method
.Location
, "Method `" +
5198 TypeManager
.CSharpSignature (builder
) +
5199 "' must declare a body since it is not marked " +
5200 "abstract or extern");
5204 SourceMethod source
= SourceMethod
.Create (
5205 container
, MethodBuilder
, method
.Block
);
5208 // Handle destructors specially
5210 // FIXME: This code generates buggy code
5212 if (member
is Destructor
)
5213 EmitDestructor (ec
, block
);
5215 ec
.EmitTopBlock (block
, ParameterInfo
, loc
);
5218 source
.CloseMethod ();
5221 void EmitDestructor (EmitContext ec
, ToplevelBlock block
)
5223 ILGenerator ig
= ec
.ig
;
5225 Label finish
= ig
.DefineLabel ();
5227 block
.SetDestructor ();
5229 ig
.BeginExceptionBlock ();
5230 ec
.ReturnLabel
= finish
;
5231 ec
.HasReturnLabel
= true;
5232 ec
.EmitTopBlock (block
, null, method
.Location
);
5234 // ig.MarkLabel (finish);
5235 ig
.BeginFinallyBlock ();
5237 if (ec
.ContainerType
.BaseType
!= null) {
5238 Expression member_lookup
= Expression
.MemberLookup (
5239 ec
, ec
.ContainerType
.BaseType
, null, ec
.ContainerType
.BaseType
,
5240 "Finalize", MemberTypes
.Method
, Expression
.AllBindingFlags
, method
.Location
);
5242 if (member_lookup
!= null){
5243 MethodGroupExpr base_destructor
= ((MethodGroupExpr
) member_lookup
);
5245 ig
.Emit (OpCodes
.Ldarg_0
);
5246 ig
.Emit (OpCodes
.Call
, (MethodInfo
) base_destructor
.Methods
[0]);
5250 ig
.EndExceptionBlock ();
5251 //ig.MarkLabel (ec.ReturnLabel);
5252 ig
.Emit (OpCodes
.Ret
);
5256 public class Destructor
: Method
{
5258 public Destructor (TypeContainer ds
, Expression return_type
, int mod
, string name
,
5259 Parameters parameters
, Attributes attrs
, Location l
)
5260 : base (ds
, null, return_type
, mod
, false, new MemberName (name
),
5261 parameters
, attrs
, l
)
5264 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
5266 if (a
.Type
== TypeManager
.conditional_attribute_type
) {
5267 Report
.Error (577, Location
, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
5271 base.ApplyAttributeBuilder (a
, cb
);
5275 abstract public class MemberBase
: MemberCore
{
5276 public Expression Type
;
5278 public MethodAttributes flags
;
5280 protected readonly int explicit_mod_flags
;
5283 // The "short" name of this property / indexer / event. This is the
5284 // name without the explicit interface.
5286 public string ShortName
;
5289 // The type of this property / indexer / event
5291 public Type MemberType
;
5294 // If true, this is an explicit interface implementation
5296 public bool IsExplicitImpl
= false;
5299 // The name of the interface we are explicitly implementing
5301 public MemberName ExplicitInterfaceName
= null;
5304 // Whether this is an interface member.
5306 public bool IsInterface
;
5309 // If true, the interface type we are explicitly implementing
5311 public Type InterfaceType
= null;
5314 // The constructor is only exposed to our children
5316 protected MemberBase (TypeContainer parent
, Expression type
, int mod
,
5317 int allowed_mod
, int def_mod
, MemberName name
,
5318 Attributes attrs
, Location loc
)
5319 : base (parent
, name
, attrs
, loc
)
5321 explicit_mod_flags
= mod
;
5323 ModFlags
= Modifiers
.Check (allowed_mod
, mod
, def_mod
, loc
);
5325 // Check for explicit interface implementation
5326 if (MemberName
.Left
!= null) {
5327 ExplicitInterfaceName
= MemberName
.Left
;
5328 ShortName
= MemberName
.Name
;
5329 IsExplicitImpl
= true;
5334 protected virtual bool CheckBase ()
5336 if ((ModFlags
& Modifiers
.PROTECTED
) != 0 && Parent
.Kind
== Kind
.Struct
) {
5337 Report
.Error (666, Location
, "Protected member in struct declaration");
5341 if ((RootContext
.WarningLevel
>= 4) &&
5342 ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0) &&
5343 ((ModFlags
& Modifiers
.PROTECTED
) != 0) &&
5344 ((ModFlags
& Modifiers
.OVERRIDE
) == 0) && (Name
!= "Finalize")) {
5345 Report
.Warning (628, Location
, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent
));
5351 protected abstract bool CheckGenericOverride (MethodInfo method
, string name
);
5353 protected virtual bool CheckParameters (DeclSpace ds
, Type
[] parameters
)
5357 foreach (Type partype
in parameters
){
5358 if (partype
== TypeManager
.void_type
) {
5360 1547, Location
, "Keyword 'void' cannot " +
5361 "be used in this context");
5365 if (partype
.IsPointer
){
5368 if (!TypeManager
.VerifyUnManaged (TypeManager
.GetElementType (partype
), Location
))
5372 if (ds
.AsAccessible (partype
, ModFlags
))
5375 if (this is Indexer
)
5376 Report
.Error (55, Location
,
5377 "Inconsistent accessibility: parameter type `" +
5378 TypeManager
.CSharpName (partype
) + "' is less " +
5379 "accessible than indexer `" + Name
+ "'");
5380 else if ((this is Method
) && ((Method
) this).IsOperator
)
5381 Report
.Error (57, Location
,
5382 "Inconsistent accessibility: parameter type `" +
5383 TypeManager
.CSharpName (partype
) + "' is less " +
5384 "accessible than operator `" + Name
+ "'");
5386 Report
.Error (51, Location
,
5387 "Inconsistent accessibility: parameter type `" +
5388 TypeManager
.CSharpName (partype
) + "' is less " +
5389 "accessible than method `" + Name
+ "'");
5396 protected virtual bool DoDefineBase ()
5398 EmitContext ec
= Parent
.EmitContext
;
5400 throw new InternalErrorException ("MemberBase.DoDefine called too early");
5403 throw new InternalErrorException ();
5406 ModFlags
= Modifiers
.PUBLIC
|
5407 Modifiers
.ABSTRACT
|
5408 Modifiers
.VIRTUAL
| (ModFlags
& Modifiers
.UNSAFE
) | (ModFlags
& Modifiers
.NEW
);
5410 flags
= MethodAttributes
.Public
|
5411 MethodAttributes
.Abstract
|
5412 MethodAttributes
.HideBySig
|
5413 MethodAttributes
.NewSlot
|
5414 MethodAttributes
.Virtual
;
5416 if (!Parent
.MethodModifiersValid (this))
5419 flags
= Modifiers
.MethodAttr (ModFlags
);
5425 protected virtual bool DoDefine (DeclSpace decl
)
5427 EmitContext ec
= decl
.EmitContext
;
5429 throw new InternalErrorException ("MemberBase.DoDefine called too early");
5431 ec
.InUnsafe
= InUnsafe
;
5433 // Lookup Type, verify validity
5434 bool old_unsafe
= ec
.InUnsafe
;
5435 ec
.InUnsafe
= InUnsafe
;
5436 TypeExpr texpr
= Type
.ResolveAsTypeTerminal (ec
);
5437 ec
.InUnsafe
= old_unsafe
;
5442 MemberType
= texpr
.Type
;
5444 if ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0){
5445 if ((ModFlags
& (Modifiers
.VIRTUAL
|Modifiers
.ABSTRACT
)) != 0){
5446 Report
.Error (549, Location
, "Virtual method can not be contained in sealed class");
5451 // verify accessibility
5452 if (!Parent
.AsAccessible (MemberType
, ModFlags
)) {
5453 Report
.SymbolRelatedToPreviousError (MemberType
);
5454 if (this is Property
)
5455 Report
.Error (53, Location
,
5456 "Inconsistent accessibility: property type `" +
5457 TypeManager
.CSharpName (MemberType
) + "' is less " +
5458 "accessible than property `" + GetSignatureForError () + "'");
5459 else if (this is Indexer
)
5460 Report
.Error (54, Location
,
5461 "Inconsistent accessibility: indexer return type `" +
5462 TypeManager
.CSharpName (MemberType
) + "' is less " +
5463 "accessible than indexer `" + Name
+ "'");
5464 else if (this is MethodCore
) {
5465 if (this is Operator
)
5466 Report
.Error (56, Location
,
5467 "Inconsistent accessibility: return type `" +
5468 TypeManager
.CSharpName (MemberType
) + "' is less " +
5469 "accessible than operator `" + Name
+ "'");
5471 Report
.Error (50, Location
,
5472 "Inconsistent accessibility: return type `" +
5473 TypeManager
.CSharpName (MemberType
) + "' is less " +
5474 "accessible than method `" + Name
+ "'");
5476 Report
.Error (52, Location
,
5477 "Inconsistent accessibility: field type `" +
5478 TypeManager
.CSharpName (MemberType
) + "' is less " +
5479 "accessible than field `" + Name
+ "'");
5484 if (MemberType
.IsPointer
&& !UnsafeOK (Parent
))
5487 if (IsExplicitImpl
) {
5488 Expression expr
= ExplicitInterfaceName
.GetTypeExpression (Location
);
5489 TypeExpr iface_texpr
= expr
.ResolveAsTypeTerminal (ec
);
5490 if (iface_texpr
== null)
5493 InterfaceType
= iface_texpr
.Type
;
5495 if (!InterfaceType
.IsInterface
) {
5496 Report
.Error (538, Location
, "'{0}' in explicit interface declaration is not an interface", TypeManager
.CSharpName (InterfaceType
));
5500 if (!Parent
.VerifyImplements (InterfaceType
, ShortName
, Name
, Location
))
5503 Modifiers
.Check (Modifiers
.AllowedExplicitImplFlags
, explicit_mod_flags
, 0, Location
);
5510 /// The name of the member can be changed during definition (see IndexerName attribute)
5512 protected virtual void UpdateMemberName ()
5514 MemberName
.Name
= ShortName
;
5517 public override string GetSignatureForError (TypeContainer tc
)
5519 return String
.Concat (tc
.Name
, '.', base.GetSignatureForError (tc
));
5522 protected bool IsTypePermitted ()
5524 if (MemberType
== TypeManager
.arg_iterator_type
|| MemberType
== TypeManager
.typed_reference_type
) {
5525 Report
.Error (610, Location
, "Field or property cannot be of type '{0}'", TypeManager
.CSharpName (MemberType
));
5531 protected override bool VerifyClsCompliance(DeclSpace ds
)
5533 if (base.VerifyClsCompliance (ds
)) {
5537 if (IsInterface
&& HasClsCompliantAttribute
&& ds
.IsClsCompliaceRequired (ds
)) {
5538 Report
.Error (3010, Location
, "'{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
5543 protected override void VerifyObsoleteAttribute()
5545 CheckUsageOfObsoleteAttribute (MemberType
);
5550 // Fields and Events both generate FieldBuilders, we use this to share
5551 // their common bits. This is also used to flag usage of the field
5553 abstract public class FieldBase
: MemberBase
{
5554 public FieldBuilder FieldBuilder
;
5555 public Status status
;
5558 public enum Status
: byte {
5561 HAS_OFFSET
= 4 // Used by FieldMember.
5564 static string[] attribute_targets
= new string [] { "field" }
;
5567 /// Symbol with same name in base class/struct
5569 public MemberInfo conflict_symbol
;
5572 // The constructor is only exposed to our children
5574 protected FieldBase (TypeContainer parent
, Expression type
, int mod
,
5575 int allowed_mod
, MemberName name
, object init
,
5576 Attributes attrs
, Location loc
)
5577 : base (parent
, type
, mod
, allowed_mod
, Modifiers
.PRIVATE
,
5583 public override AttributeTargets AttributeTargets
{
5585 return AttributeTargets
.Field
;
5589 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
5591 if (a
.Type
== TypeManager
.marshal_as_attr_type
) {
5592 UnmanagedMarshal marshal
= a
.GetMarshal (this);
5593 if (marshal
!= null) {
5594 FieldBuilder
.SetMarshal (marshal
);
5599 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
)) {
5600 a
.Error_InvalidSecurityParent ();
5604 FieldBuilder
.SetCustomAttribute (cb
);
5608 // Whether this field has an initializer.
5610 public bool HasInitializer
{
5612 return init
!= null;
5616 protected readonly Object init
;
5618 Expression init_expr
;
5619 bool init_expr_initialized
= false;
5621 protected override bool CheckGenericOverride (MethodInfo method
, string name
)
5627 // Resolves and returns the field initializer.
5629 public Expression
GetInitializerExpression (EmitContext ec
)
5631 if (init_expr_initialized
)
5635 if (init
is Expression
)
5636 e
= (Expression
) init
;
5638 e
= new ArrayCreation (Type
, "", (ArrayList
)init
, Location
);
5640 ec
.IsFieldInitializer
= true;
5641 e
= e
.DoResolve (ec
);
5642 ec
.IsFieldInitializer
= false;
5645 init_expr_initialized
= true;
5650 protected override bool CheckBase ()
5652 if (!base.CheckBase ())
5659 conflict_symbol
= Parent
.FindBaseMemberWithSameName (Name
, false);
5660 if (conflict_symbol
== null) {
5661 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0)) {
5662 Report
.Warning (109, Location
, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent
));
5667 if ((ModFlags
& (Modifiers
.NEW
| Modifiers
.OVERRIDE
)) == 0) {
5668 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
5669 Report
.Warning (108, Location
, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent
));
5675 protected override bool DoDefine (DeclSpace ds
)
5677 if (!base.DoDefine (ds
))
5680 if (MemberType
== TypeManager
.void_type
) {
5681 Report
.Error (1547, Location
,
5682 "Keyword 'void' cannot be used in this context");
5688 public override string GetSignatureForError ()
5690 if (FieldBuilder
== null) {
5691 return base.GetSignatureForError (Parent
);
5693 return TypeManager
.GetFullNameSignature (FieldBuilder
);
5696 public override string[] ValidAttributeTargets
{
5698 return attribute_targets
;
5702 protected override bool VerifyClsCompliance (DeclSpace ds
)
5704 if (!base.VerifyClsCompliance (ds
))
5707 if (FieldBuilder
== null) {
5711 if (!AttributeTester
.IsClsCompliant (FieldBuilder
.FieldType
)) {
5712 Report
.Error (3003, Location
, "Type of '{0}' is not CLS-compliant", GetSignatureForError ());
5718 public void SetAssigned ()
5720 status
|= Status
.ASSIGNED
;
5724 public abstract class FieldMember
: FieldBase
5728 protected FieldMember (TypeContainer parent
, Expression type
, int mod
,
5729 int allowed_mod
, MemberName name
, object init
, Attributes attrs
, Location loc
)
5730 : base (parent
, type
, mod
, allowed_mod
, name
, init
, attrs
, loc
)
5734 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
5736 if (a
.Type
== TypeManager
.field_offset_attribute_type
)
5738 status
|= Status
.HAS_OFFSET
;
5740 if (!Parent
.HasExplicitLayout
) {
5741 Report
.Error (636, Location
, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5745 if ((ModFlags
& Modifiers
.STATIC
) != 0 || this is Const
) {
5746 Report
.Error (637, Location
, "The FieldOffset attribute is not allowed on static or const fields");
5750 base.ApplyAttributeBuilder (a
, cb
);
5754 public override bool Define()
5756 EmitContext ec
= Parent
.EmitContext
;
5758 throw new InternalErrorException ("FieldMember.Define called too early");
5760 bool old_unsafe
= ec
.InUnsafe
;
5761 ec
.InUnsafe
= InUnsafe
;
5762 TypeExpr texpr
= Type
.ResolveAsTypeTerminal (ec
);
5763 ec
.InUnsafe
= old_unsafe
;
5767 MemberType
= texpr
.Type
;
5769 ec
.InUnsafe
= old_unsafe
;
5771 if (MemberType
== TypeManager
.void_type
) {
5772 Report
.Error (1547, Location
, "Keyword 'void' cannot be used in this context");
5779 if (!Parent
.AsAccessible (MemberType
, ModFlags
)) {
5780 Report
.Error (52, Location
,
5781 "Inconsistent accessibility: field type `" +
5782 TypeManager
.CSharpName (MemberType
) + "' is less " +
5783 "accessible than field `" + Name
+ "'");
5787 if (!IsTypePermitted ())
5790 if (MemberType
.IsPointer
&& !UnsafeOK (Parent
))
5796 public override void Emit ()
5798 if (Parent
.HasExplicitLayout
&& ((status
& Status
.HAS_OFFSET
) == 0) && (ModFlags
& Modifiers
.STATIC
) == 0) {
5799 Report
.Error (625, Location
, "'{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5806 // Represents header string for documentation comment.
5808 public override string DocCommentHeader
{
5809 get { return "F:"; }
5814 // The Field class is used to represents class/struct fields during parsing.
5816 public class Field
: FieldMember
{
5818 // Modifiers allowed in a class declaration
5820 const int AllowedModifiers
=
5823 Modifiers
.PROTECTED
|
5824 Modifiers
.INTERNAL
|
5827 Modifiers
.VOLATILE
|
5831 public Field (TypeContainer parent
, Expression type
, int mod
, string name
,
5832 Object expr_or_array_init
, Attributes attrs
, Location loc
)
5833 : base (parent
, type
, mod
, AllowedModifiers
, new MemberName (name
),
5834 expr_or_array_init
, attrs
, loc
)
5838 public override bool Define ()
5840 if (!base.Define ())
5843 if (RootContext
.WarningLevel
> 1){
5844 Type ptype
= Parent
.TypeBuilder
.BaseType
;
5846 // ptype is only null for System.Object while compiling corlib.
5848 TypeContainer
.FindMembers (
5849 ptype
, MemberTypes
.Method
,
5850 BindingFlags
.Public
|
5851 BindingFlags
.Static
| BindingFlags
.Instance
,
5852 System
.Type
.FilterName
, Name
);
5856 if ((ModFlags
& Modifiers
.VOLATILE
) != 0){
5857 if (!MemberType
.IsClass
){
5858 Type vt
= MemberType
;
5860 if (TypeManager
.IsEnumType (vt
))
5861 vt
= TypeManager
.EnumToUnderlying (MemberType
);
5863 if (!((vt
== TypeManager
.bool_type
) ||
5864 (vt
== TypeManager
.sbyte_type
) ||
5865 (vt
== TypeManager
.byte_type
) ||
5866 (vt
== TypeManager
.short_type
) ||
5867 (vt
== TypeManager
.ushort_type
) ||
5868 (vt
== TypeManager
.int32_type
) ||
5869 (vt
== TypeManager
.uint32_type
) ||
5870 (vt
== TypeManager
.char_type
) ||
5871 (vt
== TypeManager
.float_type
) ||
5872 (!vt
.IsValueType
))){
5874 677, Location
, Parent
.MakeName (Name
) +
5875 " A volatile field can not be of type `" +
5876 TypeManager
.CSharpName (vt
) + "'");
5881 if ((ModFlags
& Modifiers
.READONLY
) != 0){
5884 "A field can not be both volatile and readonly");
5889 FieldAttributes fa
= Modifiers
.FieldAttr (ModFlags
);
5891 if (Parent
.Kind
== Kind
.Struct
&&
5892 ((fa
& FieldAttributes
.Static
) == 0) &&
5893 MemberType
== Parent
.TypeBuilder
&&
5894 !TypeManager
.IsBuiltinType (MemberType
)){
5895 Report
.Error (523, Location
, "Struct member `" + Parent
.Name
+ "." + Name
+
5896 "' causes a cycle in the structure layout");
5901 FieldBuilder
= Parent
.TypeBuilder
.DefineField (
5902 Name
, MemberType
, Modifiers
.FieldAttr (ModFlags
));
5904 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
5906 catch (ArgumentException
) {
5907 Report
.Warning (-24, Location
, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
5914 public override void Emit ()
5916 if (OptAttributes
!= null) {
5917 EmitContext ec
= new EmitContext (
5918 Parent
, Location
, null, FieldBuilder
.FieldType
,
5920 OptAttributes
.Emit (ec
, this);
5928 // `set' and `get' accessors are represented with an Accessor.
5930 public class Accessor
{
5932 // Null if the accessor is empty, or a Block if not
5934 public const int AllowedModifiers
=
5936 Modifiers
.PROTECTED
|
5937 Modifiers
.INTERNAL
|
5940 public ToplevelBlock Block
;
5941 public Attributes Attributes
;
5942 public Location Location
;
5943 public int ModFlags
;
5945 public Accessor (ToplevelBlock b
, int mod
, Attributes attrs
, Location loc
)
5950 ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, 0, loc
);
5955 // Ooouh Martin, templates are missing here.
5956 // When it will be possible move here a lot of child code and template method type.
5957 public abstract class AbstractPropertyEventMethod
: MemberCore
, IMethodData
{
5958 protected MethodData method_data
;
5959 protected ToplevelBlock block
;
5960 protected ListDictionary declarative_security
;
5962 // The accessor are created event if they are not wanted.
5963 // But we need them because their names are reserved.
5964 // Field says whether accessor will be emited or not
5965 public readonly bool IsDummy
;
5967 protected readonly string prefix
;
5969 ReturnParameter return_attributes
;
5971 public AbstractPropertyEventMethod (MemberBase member
, string prefix
)
5972 : base (null, SetupName (prefix
, member
), null, member
.Location
)
5974 this.prefix
= prefix
;
5978 public AbstractPropertyEventMethod (MemberBase member
, Accessor accessor
,
5980 : base (null, SetupName (prefix
, member
),
5981 accessor
.Attributes
, accessor
.Location
)
5983 this.prefix
= prefix
;
5984 this.block
= accessor
.Block
;
5987 static MemberName
SetupName (string prefix
, MemberBase member
)
5989 MemberName name
= member
.MemberName
.Clone ();
5990 name
.Name
= prefix
+ member
.ShortName
;
5994 public void UpdateName (MemberBase member
)
5996 MemberName
.Name
= prefix
+ member
.ShortName
;
5999 #region IMethodData Members
6001 public ToplevelBlock Block
{
6011 public CallingConventions CallingConventions
{
6013 return CallingConventions
.Standard
;
6017 public bool IsExcluded (EmitContext ec
)
6022 GenericMethod IMethodData
.GenericMethod
{
6028 public MemberName MethodName
{
6034 public abstract ObsoleteAttribute
GetObsoleteAttribute ();
6035 public abstract Type
[] ParameterTypes { get; }
6036 public abstract Type ReturnType { get; }
6037 public abstract EmitContext
CreateEmitContext(TypeContainer tc
, ILGenerator ig
);
6041 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
6043 if (a
.Type
== TypeManager
.cls_compliant_attribute_type
|| a
.Type
== TypeManager
.obsolete_attribute_type
||
6044 a
.Type
== TypeManager
.conditional_attribute_type
) {
6045 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 ());
6049 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
6050 if (declarative_security
== null)
6051 declarative_security
= new ListDictionary ();
6052 a
.ExtractSecurityPermissionSet (declarative_security
);
6056 if (a
.Target
== AttributeTargets
.Method
) {
6057 method_data
.MethodBuilder
.SetCustomAttribute (cb
);
6061 if (a
.Target
== AttributeTargets
.ReturnValue
) {
6062 if (return_attributes
== null)
6063 return_attributes
= new ReturnParameter (method_data
.MethodBuilder
, Location
);
6065 return_attributes
.ApplyAttributeBuilder (a
, cb
);
6069 ApplyToExtraTarget (a
, cb
);
6072 virtual protected void ApplyToExtraTarget (Attribute a
, CustomAttributeBuilder cb
)
6074 System
.Diagnostics
.Debug
.Fail ("You forgot to define special attribute target handling");
6077 public override bool Define()
6079 throw new NotSupportedException ();
6082 public virtual void Emit (TypeContainer container
)
6084 method_data
.Emit (container
, this);
6086 if (declarative_security
!= null) {
6087 foreach (DictionaryEntry de
in declarative_security
) {
6088 method_data
.MethodBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
6095 public override bool IsClsCompliaceRequired(DeclSpace ds
)
6100 public bool IsDuplicateImplementation (MethodCore method
)
6102 if (Name
!= method
.Name
)
6105 Type
[] param_types
= method
.ParameterTypes
;
6107 if (param_types
.Length
!= ParameterTypes
.Length
)
6110 for (int i
= 0; i
< param_types
.Length
; i
++)
6111 if (param_types
[i
] != ParameterTypes
[i
])
6114 Report
.SymbolRelatedToPreviousError (method
);
6115 Report
.Error (111, Location
, "Type '{0}' already defines a member called '{1}' with " +
6116 "the same parameter types", Parent
.Name
, Name
);
6120 public new Location Location
{
6122 return base.Location
;
6127 // Represents header string for documentation comment.
6129 public override string DocCommentHeader
{
6130 get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6133 protected override void VerifyObsoleteAttribute()
6140 // Properties and Indexers both generate PropertyBuilders, we use this to share
6141 // their common bits.
6143 abstract public class PropertyBase
: MethodCore
{
6145 public class GetMethod
: PropertyMethod
6147 static string[] attribute_targets
= new string [] { "method", "return" }
;
6148 Parameters parameters
;
6150 public GetMethod (MethodCore method
):
6151 base (method
, "get_")
6155 public GetMethod (MethodCore method
, Accessor accessor
):
6156 base (method
, accessor
, "get_")
6160 public GetMethod (MethodCore method
, Parameters parameters
):
6161 base (method
, "get_")
6163 this.parameters
= parameters
;
6166 public GetMethod (MethodCore method
, Accessor accessor
, Parameters parameters
):
6167 base (method
, accessor
, "get_")
6169 this.parameters
= parameters
;
6172 protected virtual InternalParameters
GetParameterInfo (EmitContext ec
)
6174 if (parameters
== null) {
6175 Parameter
[] parms
= new Parameter
[1];
6176 parms
[0] = new Parameter (method
.Type
, "Screwed", Parameter
.Modifier
.NONE
, null);
6177 parameters
= new Parameters (parms
, null, method
.Location
);
6180 Type
[] types
= parameters
.GetParameterInfo (ec
);
6181 return new InternalParameters (types
, parameters
);
6184 public override MethodBuilder
Define(TypeContainer container
)
6186 base.Define (container
);
6188 method_data
= new MethodData (method
, GetParameterInfo (container
.EmitContext
), ModFlags
, flags
, this);
6190 if (!method_data
.Define (container
))
6193 return method_data
.MethodBuilder
;
6196 public override string GetSignatureForError (TypeContainer tc
)
6198 return String
.Concat (base.GetSignatureForError (tc
), ".get");
6201 public override Type ReturnType
{
6203 return method
.MemberType
;
6207 public override string[] ValidAttributeTargets
{
6209 return attribute_targets
;
6214 public class SetMethod
: PropertyMethod
{
6216 static string[] attribute_targets
= new string [] { "method", "param", "return" }
;
6217 ImplicitParameter param_attr
;
6219 Parameters parameters
;
6221 public SetMethod (MethodCore method
):
6222 base (method
, "set_")
6226 public SetMethod (MethodCore method
, Accessor accessor
):
6227 base (method
, accessor
, "set_")
6231 public SetMethod (MethodCore method
, Parameters parameters
):
6232 base (method
, "set_")
6234 this.parameters
= parameters
;
6237 public SetMethod (MethodCore method
, Accessor accessor
, Parameters parameters
):
6238 base (method
, accessor
, "set_")
6240 this.parameters
= parameters
;
6242 protected override void ApplyToExtraTarget(Attribute a
, CustomAttributeBuilder cb
)
6244 if (a
.Target
== AttributeTargets
.Parameter
) {
6245 if (param_attr
== null)
6246 param_attr
= new ImplicitParameter (method_data
.MethodBuilder
);
6248 param_attr
.ApplyAttributeBuilder (a
, cb
);
6252 base.ApplyAttributeBuilder (a
, cb
);
6255 protected virtual InternalParameters
GetParameterInfo (EmitContext ec
)
6258 if (parameters
== null) {
6259 Parameter
[] parms
= new Parameter
[1];
6260 parms
[0] = new Parameter (method
.Type
, "value", Parameter
.Modifier
.NONE
, null);
6261 parameters
= new Parameters (parms
, null, method
.Location
);
6264 bool old_unsafe
= ec
.InUnsafe
;
6265 ec
.InUnsafe
= InUnsafe
;
6266 Type
[] types
= parameters
.GetParameterInfo (ec
);
6267 ec
.InUnsafe
= old_unsafe
;
6269 return new InternalParameters (types
, parameters
);
6272 public override MethodBuilder
Define (TypeContainer container
)
6274 if (container
.EmitContext
== null)
6275 throw new InternalErrorException ("SetMethod.Define called too early");
6277 base.Define (container
);
6279 method_data
= new MethodData (method
, GetParameterInfo (container
.EmitContext
), ModFlags
, flags
, this);
6281 if (!method_data
.Define (container
))
6284 return method_data
.MethodBuilder
;
6287 public override string GetSignatureForError (TypeContainer tc
)
6289 return String
.Concat (base.GetSignatureForError (tc
), ".set");
6292 public override Type
[] ParameterTypes
{
6294 return new Type
[] { method.MemberType }
;
6298 public override Type ReturnType
{
6300 return TypeManager
.void_type
;
6304 public override string[] ValidAttributeTargets
{
6306 return attribute_targets
;
6311 static string[] attribute_targets
= new string [] { "property" }
;
6313 public abstract class PropertyMethod
: AbstractPropertyEventMethod
{
6314 protected readonly MethodCore method
;
6315 protected MethodAttributes flags
;
6317 public PropertyMethod (MethodCore method
, string prefix
)
6318 : base (method
, prefix
)
6320 this.method
= method
;
6321 Parent
= method
.Parent
;
6324 public PropertyMethod (MethodCore method
, Accessor accessor
, string prefix
)
6325 : base (method
, accessor
, prefix
)
6327 this.method
= method
;
6328 Parent
= method
.Parent
;
6329 this.ModFlags
= accessor
.ModFlags
;
6331 if (accessor
.ModFlags
!= 0 && RootContext
.Version
== LanguageVersion
.ISO_1
) {
6332 Report
.FeatureIsNotStandardized (Location
, "accessor modifiers");
6333 Environment
.Exit (1);
6337 public override AttributeTargets AttributeTargets
{
6339 return AttributeTargets
.Method
;
6343 public override bool IsClsCompliaceRequired(DeclSpace ds
)
6345 return method
.IsClsCompliaceRequired (ds
);
6348 public InternalParameters ParameterInfo
6351 return method_data
.ParameterInfo
;
6355 public virtual MethodBuilder
Define (TypeContainer container
)
6358 // Check for custom access modifier
6360 if (ModFlags
== 0) {
6361 ModFlags
= method
.ModFlags
;
6362 flags
= method
.flags
;
6364 CheckModifiers (container
, ModFlags
);
6365 ModFlags
|= (method
.ModFlags
& (~Modifiers
.Accessibility
));
6366 flags
= Modifiers
.MethodAttr (ModFlags
);
6367 flags
|= (method
.flags
& (~MethodAttributes
.MemberAccessMask
));
6374 public override Type
[] ParameterTypes
{
6376 return TypeManager
.NoTypes
;
6380 public override EmitContext
CreateEmitContext (TypeContainer tc
,
6383 return new EmitContext (
6384 tc
, method
.ds
, method
.Location
, ig
, ReturnType
,
6385 method
.ModFlags
, false);
6388 public override ObsoleteAttribute
GetObsoleteAttribute ()
6390 return method
.GetObsoleteAttribute (method
.ds
);
6393 public override string GetSignatureForError (TypeContainer tc
)
6395 return String
.Concat (tc
.Name
, '.', method
.Name
);
6398 void CheckModifiers (TypeContainer container
, int modflags
)
6401 int mflags
= method
.ModFlags
& Modifiers
.Accessibility
;
6403 if ((mflags
& Modifiers
.PUBLIC
) != 0) {
6404 flags
|= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
| Modifiers
.PRIVATE
;
6406 else if ((mflags
& Modifiers
.PROTECTED
) != 0) {
6407 if ((mflags
& Modifiers
.INTERNAL
) != 0)
6408 flags
|= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
;
6410 flags
|= Modifiers
.PRIVATE
;
6412 else if ((mflags
& Modifiers
.INTERNAL
) != 0)
6413 flags
|= Modifiers
.PRIVATE
;
6415 if ((mflags
== modflags
) || (modflags
& (~flags
)) != 0)
6416 Report
.Error (273, Location
, "{0}: accessibility modifier must be more restrictive than the property or indexer",
6417 GetSignatureForError (container
));
6420 public override bool MarkForDuplicationCheck ()
6422 caching_flags
|= Flags
.TestMethodDuplication
;
6427 public PropertyMethod Get
, Set
;
6428 public PropertyBuilder PropertyBuilder
;
6429 public MethodBuilder GetBuilder
, SetBuilder
;
6431 protected EmitContext ec
;
6433 public PropertyBase (TypeContainer parent
, Expression type
, int mod_flags
,
6434 int allowed_mod
, bool is_iface
, MemberName name
,
6435 Parameters parameters
, Attributes attrs
,
6437 : base (parent
, null, type
, mod_flags
, allowed_mod
, is_iface
, name
,
6438 attrs
, parameters
, loc
)
6442 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
6444 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
)) {
6445 a
.Error_InvalidSecurityParent ();
6449 PropertyBuilder
.SetCustomAttribute (cb
);
6452 public override AttributeTargets AttributeTargets
{
6454 return AttributeTargets
.Property
;
6458 public override bool Define ()
6460 if (!DoDefine (Parent
))
6463 if (!IsTypePermitted ())
6469 protected override bool DoDefine (DeclSpace ds
)
6471 if (!base.DoDefine (ds
))
6475 // Accessors modifiers check
6477 if (Get
.ModFlags
!= 0 && Set
.ModFlags
!= 0) {
6478 Report
.Error (274, Location
, "'{0}': cannot specify accessibility modifiers for both accessors of the property or indexer.",
6479 GetSignatureForError ());
6483 if ((Get
.IsDummy
|| Set
.IsDummy
)
6484 && (Get
.ModFlags
!= 0 || Set
.ModFlags
!= 0) && (ModFlags
& Modifiers
.OVERRIDE
) == 0) {
6485 Report
.Error (276, Location
,
6486 "'{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor.",
6487 GetSignatureForError ());
6491 if (MemberType
.IsAbstract
&& MemberType
.IsSealed
) {
6492 Report
.Error (722, Location
, Error722
, TypeManager
.CSharpName (MemberType
));
6496 ec
= new EmitContext (Parent
, Location
, null, MemberType
, ModFlags
);
6500 public override string GetSignatureForError()
6502 if (PropertyBuilder
== null)
6503 return GetSignatureForError (Parent
);
6505 return TypeManager
.CSharpSignature (PropertyBuilder
, false);
6508 protected override bool CheckForDuplications ()
6510 ArrayList ar
= Parent
.Indexers
;
6512 int arLen
= ar
.Count
;
6514 for (int i
= 0; i
< arLen
; i
++) {
6515 Indexer m
= (Indexer
) ar
[i
];
6516 if (IsDuplicateImplementation (m
))
6521 ar
= Parent
.Properties
;
6523 int arLen
= ar
.Count
;
6525 for (int i
= 0; i
< arLen
; i
++) {
6526 Property m
= (Property
) ar
[i
];
6527 if (IsDuplicateImplementation (m
))
6535 // TODO: rename to Resolve......
6536 protected override MethodInfo
FindOutBaseMethod (TypeContainer container
, ref Type base_ret_type
)
6538 PropertyInfo base_property
= container
.BaseCache
.FindMemberToOverride (
6539 container
.TypeBuilder
, Name
, ParameterTypes
, true) as PropertyInfo
;
6541 if (base_property
== null)
6544 base_ret_type
= base_property
.PropertyType
;
6545 MethodInfo get_accessor
= base_property
.GetGetMethod (true);
6546 MethodInfo set_accessor
= base_property
.GetSetMethod (true);
6547 MethodAttributes get_accessor_access
, set_accessor_access
;
6549 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
6550 if (Get
!= null && !Get
.IsDummy
&& get_accessor
== null) {
6551 Report
.SymbolRelatedToPreviousError (base_property
);
6552 Report
.Error (545, Location
, "'{0}': cannot override because '{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager
.GetFullNameSignature (base_property
));
6555 if (Set
!= null && !Set
.IsDummy
&& set_accessor
== null) {
6556 Report
.SymbolRelatedToPreviousError (base_property
);
6557 Report
.Error (546, Location
, "'{0}': cannot override because '{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager
.GetFullNameSignature (base_property
));
6562 // Check base class accessors access
6564 get_accessor_access
= set_accessor_access
= 0;
6565 if ((ModFlags
& Modifiers
.NEW
) == 0) {
6566 if (get_accessor
!= null) {
6567 MethodAttributes get_flags
= Modifiers
.MethodAttr (Get
.ModFlags
!= 0 ? Get
.ModFlags
: ModFlags
);
6568 get_accessor_access
= (get_accessor
.Attributes
& MethodAttributes
.MemberAccessMask
);
6570 if (!Get
.IsDummy
&& !CheckAccessModifiers (get_flags
& MethodAttributes
.MemberAccessMask
, get_accessor_access
, get_accessor
))
6571 Report
.Error (507, Location
, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
6572 GetSignatureForError (), TypeManager
.GetFullNameSignature (base_property
));
6575 if (set_accessor
!= null) {
6576 MethodAttributes set_flags
= Modifiers
.MethodAttr (Set
.ModFlags
!= 0 ? Set
.ModFlags
: ModFlags
);
6577 set_accessor_access
= (set_accessor
.Attributes
& MethodAttributes
.MemberAccessMask
);
6579 if (!Set
.IsDummy
&& !CheckAccessModifiers (set_flags
& MethodAttributes
.MemberAccessMask
, set_accessor_access
, set_accessor
))
6580 Report
.Error (507, Location
, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
6581 GetSignatureForError (container
), TypeManager
.GetFullNameSignature (base_property
));
6586 // Get the less restrictive access
6588 return get_accessor_access
> set_accessor_access
? get_accessor
: set_accessor
;
6591 public override void Emit ()
6594 // The PropertyBuilder can be null for explicit implementations, in that
6595 // case, we do not actually emit the ".property", so there is nowhere to
6596 // put the attribute
6598 if (PropertyBuilder
!= null && OptAttributes
!= null)
6599 OptAttributes
.Emit (ec
, this);
6611 /// Tests whether accessors are not in collision with some method (CS0111)
6613 public bool AreAccessorsDuplicateImplementation (MethodCore mc
)
6615 return Get
.IsDuplicateImplementation (mc
) || Set
.IsDuplicateImplementation (mc
);
6618 protected override void UpdateMemberName ()
6620 base.UpdateMemberName ();
6622 Get
.UpdateName (this);
6623 Set
.UpdateName (this);
6626 protected override bool VerifyClsCompliance (DeclSpace ds
)
6628 if (!base.VerifyClsCompliance (ds
))
6631 if ((Get
.ModFlags
!= ModFlags
&& !Get
.IsDummy
) || (Set
.ModFlags
!= ModFlags
&& !Set
.IsDummy
)) {
6632 Report
.Error (3025, Get
.ModFlags
!= ModFlags
? Get
.Location
: Set
.Location
,
6633 "CLS-compliant accessors must have the same accessibility as their property");
6638 public override string[] ValidAttributeTargets
{
6640 return attribute_targets
;
6645 // Represents header string for documentation comment.
6647 public override string DocCommentHeader
{
6648 get { return "P:"; }
6652 public class Property
: PropertyBase
, IIteratorContainer
{
6653 const int AllowedModifiers
=
6656 Modifiers
.PROTECTED
|
6657 Modifiers
.INTERNAL
|
6661 Modifiers
.OVERRIDE
|
6662 Modifiers
.ABSTRACT
|
6665 Modifiers
.METHOD_YIELDS
|
6668 const int AllowedInterfaceModifiers
=
6671 public Property (TypeContainer parent
, Expression type
, int mod_flags
,
6672 bool is_iface
, MemberName name
, Attributes attrs
,
6673 Accessor get_block
, Accessor set_block
, Location loc
)
6674 : base (parent
, type
, mod_flags
,
6675 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
6676 is_iface
, name
, Parameters
.EmptyReadOnlyParameters
, attrs
,
6679 if (get_block
== null)
6680 Get
= new GetMethod (this);
6682 Get
= new GetMethod (this, get_block
);
6684 if (set_block
== null)
6685 Set
= new SetMethod (this);
6687 Set
= new SetMethod (this, set_block
);
6690 public Property (TypeContainer ds
, Expression type
, int mod
, bool is_iface
,
6691 MemberName name
, Attributes attrs
, Parameters get_params
, Accessor get_block
,
6692 Parameters set_params
, Accessor set_block
, Location loc
)
6693 : base (ds
, type
, mod
,
6694 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
6695 is_iface
, name
, Parameters
.EmptyReadOnlyParameters
, attrs
,
6698 if (get_block
== null)
6699 Get
= new GetMethod (this, get_params
);
6701 Get
= new GetMethod (this, get_block
, get_params
);
6703 if (set_block
== null)
6704 Set
= new SetMethod (this, set_params
);
6706 Set
= new SetMethod (this, set_block
, set_params
);
6709 public override bool Define ()
6711 if (!DoDefineBase ())
6714 if (!base.Define ())
6720 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
6724 GetBuilder
= Get
.Define (Parent
);
6725 if (GetBuilder
== null)
6729 // Setup iterator if we are one
6731 if ((ModFlags
& Modifiers
.METHOD_YIELDS
) != 0){
6732 Iterator iterator
= new Iterator (
6733 Parent
, "get", MemberType
,
6734 TypeManager
.NoTypes
, Get
.ParameterInfo
,
6735 ModFlags
, Get
.Block
, Location
);
6737 if (!iterator
.DefineIterator ())
6739 Get
.Block
= iterator
.Block
;
6744 SetBuilder
= Set
.Define (Parent
);
6745 if (SetBuilder
== null)
6748 SetBuilder
.DefineParameter (1, ParameterAttributes
.None
, "value");
6751 // FIXME - PropertyAttributes.HasDefault ?
6753 PropertyAttributes prop_attr
= PropertyAttributes
.None
;
6755 prop_attr
|= PropertyAttributes
.RTSpecialName
|
6756 PropertyAttributes
.SpecialName
;
6758 PropertyBuilder
= Parent
.TypeBuilder
.DefineProperty (
6759 Name
, prop_attr
, MemberType
, null);
6762 PropertyBuilder
.SetGetMethod (GetBuilder
);
6765 PropertyBuilder
.SetSetMethod (SetBuilder
);
6767 TypeManager
.RegisterProperty (PropertyBuilder
, GetBuilder
, SetBuilder
);
6771 public void SetYields ()
6773 ModFlags
|= Modifiers
.METHOD_YIELDS
;
6778 /// Gigantic workaround for lameness in SRE follows :
6779 /// This class derives from EventInfo and attempts to basically
6780 /// wrap around the EventBuilder so that FindMembers can quickly
6781 /// return this in it search for members
6783 public class MyEventBuilder
: EventInfo
{
6786 // We use this to "point" to our Builder which is
6787 // not really a MemberInfo
6789 EventBuilder MyBuilder
;
6792 // We "catch" and wrap these methods
6794 MethodInfo raise
, remove, add;
6796 EventAttributes attributes
;
6797 Type declaring_type
, reflected_type
, event_type
;
6802 public MyEventBuilder (Event ev
, TypeBuilder type_builder
, string name
, EventAttributes event_attr
, Type event_type
)
6804 MyBuilder
= type_builder
.DefineEvent (name
, event_attr
, event_type
);
6806 // And now store the values in our own fields.
6808 declaring_type
= type_builder
;
6810 reflected_type
= type_builder
;
6812 attributes
= event_attr
;
6815 this.event_type
= event_type
;
6819 // Methods that you have to override. Note that you only need
6820 // to "implement" the variants that take the argument (those are
6821 // the "abstract" methods, the others (GetAddMethod()) are
6824 public override MethodInfo
GetAddMethod (bool nonPublic
)
6829 public override MethodInfo
GetRemoveMethod (bool nonPublic
)
6834 public override MethodInfo
GetRaiseMethod (bool nonPublic
)
6840 // These methods make "MyEventInfo" look like a Builder
6842 public void SetRaiseMethod (MethodBuilder raiseMethod
)
6844 raise
= raiseMethod
;
6845 MyBuilder
.SetRaiseMethod (raiseMethod
);
6848 public void SetRemoveOnMethod (MethodBuilder removeMethod
)
6850 remove = removeMethod
;
6851 MyBuilder
.SetRemoveOnMethod (removeMethod
);
6854 public void SetAddOnMethod (MethodBuilder addMethod
)
6857 MyBuilder
.SetAddOnMethod (addMethod
);
6860 public void SetCustomAttribute (CustomAttributeBuilder cb
)
6862 MyBuilder
.SetCustomAttribute (cb
);
6865 public override object [] GetCustomAttributes (bool inherit
)
6867 // FIXME : There's nothing which can be seemingly done here because
6868 // we have no way of getting at the custom attribute objects of the
6873 public override object [] GetCustomAttributes (Type t
, bool inherit
)
6875 // FIXME : Same here !
6879 public override bool IsDefined (Type t
, bool b
)
6884 public override EventAttributes Attributes
{
6890 public override string Name
{
6896 public override Type DeclaringType
{
6898 return declaring_type
;
6902 public override Type ReflectedType
{
6904 return reflected_type
;
6908 public Type EventType
{
6914 public void SetUsed ()
6916 if (my_event
!= null)
6917 my_event
.status
= (FieldBase
.Status
.ASSIGNED
| FieldBase
.Status
.USED
);
6922 /// For case when event is declared like property (with add and remove accessors).
6924 public class EventProperty
: Event
{
6926 static string[] attribute_targets
= new string [] { "event", "property" }
;
6928 public EventProperty (TypeContainer parent
, Expression type
, int mod_flags
,
6929 bool is_iface
, MemberName name
, Object init
,
6930 Attributes attrs
, Accessor
add, Accessor
remove,
6932 : base (parent
, type
, mod_flags
, is_iface
, name
, init
, attrs
, loc
)
6934 Add
= new AddDelegateMethod (this, add);
6935 Remove
= new RemoveDelegateMethod (this, remove);
6937 // For this event syntax we don't report error CS0067
6938 // because it is hard to do it.
6942 public override string[] ValidAttributeTargets
{
6944 return attribute_targets
;
6950 /// Event is declared like field.
6952 public class EventField
: Event
{
6954 static string[] attribute_targets
= new string [] { "event", "field", "method" }
;
6955 static string[] attribute_targets_interface
= new string[] { "event", "method" }
;
6957 public EventField (TypeContainer parent
, Expression type
, int mod_flags
,
6958 bool is_iface
, MemberName name
, Object init
,
6959 Attributes attrs
, Location loc
)
6960 : base (parent
, type
, mod_flags
, is_iface
, name
, init
, attrs
, loc
)
6962 Add
= new AddDelegateMethod (this);
6963 Remove
= new RemoveDelegateMethod (this);
6966 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
6968 if (a
.Target
== AttributeTargets
.Field
) {
6969 FieldBuilder
.SetCustomAttribute (cb
);
6973 if (a
.Target
== AttributeTargets
.Method
) {
6974 Add
.ApplyAttributeBuilder (a
, cb
);
6975 Remove
.ApplyAttributeBuilder (a
, cb
);
6979 base.ApplyAttributeBuilder (a
, cb
);
6982 public override string[] ValidAttributeTargets
{
6984 return IsInterface
? attribute_targets_interface
: attribute_targets
;
6989 public abstract class Event
: FieldBase
{
6991 protected sealed class AddDelegateMethod
: DelegateMethod
6994 public AddDelegateMethod (Event method
):
6995 base (method
, "add_")
6999 public AddDelegateMethod (Event method
, Accessor accessor
):
7000 base (method
, accessor
, "add_")
7004 protected override MethodInfo DelegateMethodInfo
{
7006 return TypeManager
.delegate_combine_delegate_delegate
;
7012 protected sealed class RemoveDelegateMethod
: DelegateMethod
7014 public RemoveDelegateMethod (Event method
):
7015 base (method
, "remove_")
7019 public RemoveDelegateMethod (Event method
, Accessor accessor
):
7020 base (method
, accessor
, "remove_")
7024 protected override MethodInfo DelegateMethodInfo
{
7026 return TypeManager
.delegate_remove_delegate_delegate
;
7032 public abstract class DelegateMethod
: AbstractPropertyEventMethod
7034 protected readonly Event method
;
7035 ImplicitParameter param_attr
;
7037 static string[] attribute_targets
= new string [] { "method", "param", "return" }
;
7039 public DelegateMethod (Event method
, string prefix
)
7040 : base (method
, prefix
)
7042 this.method
= method
;
7045 public DelegateMethod (Event method
, Accessor accessor
, string prefix
)
7046 : base (method
, accessor
, prefix
)
7048 this.method
= method
;
7051 protected override void ApplyToExtraTarget(Attribute a
, CustomAttributeBuilder cb
)
7053 if (a
.Target
== AttributeTargets
.Parameter
) {
7054 if (param_attr
== null)
7055 param_attr
= new ImplicitParameter (method_data
.MethodBuilder
);
7057 param_attr
.ApplyAttributeBuilder (a
, cb
);
7061 base.ApplyAttributeBuilder (a
, cb
);
7064 public override AttributeTargets AttributeTargets
{
7066 return AttributeTargets
.Method
;
7070 public override bool IsClsCompliaceRequired(DeclSpace ds
)
7072 return method
.IsClsCompliaceRequired (ds
);
7075 public MethodBuilder
Define (TypeContainer container
, InternalParameters ip
)
7077 method_data
= new MethodData (method
, ip
, method
.ModFlags
,
7078 method
.flags
| MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
, this);
7080 if (!method_data
.Define (container
))
7083 MethodBuilder mb
= method_data
.MethodBuilder
;
7084 mb
.DefineParameter (1, ParameterAttributes
.None
, "value");
7089 public override void Emit (TypeContainer tc
)
7091 if (block
!= null) {
7096 ILGenerator ig
= method_data
.MethodBuilder
.GetILGenerator ();
7097 FieldInfo field_info
= (FieldInfo
)method
.FieldBuilder
;
7099 method_data
.MethodBuilder
.SetImplementationFlags (MethodImplAttributes
.Synchronized
);
7100 if ((method
.ModFlags
& Modifiers
.STATIC
) != 0) {
7101 ig
.Emit (OpCodes
.Ldsfld
, field_info
);
7102 ig
.Emit (OpCodes
.Ldarg_0
);
7103 ig
.Emit (OpCodes
.Call
, DelegateMethodInfo
);
7104 ig
.Emit (OpCodes
.Castclass
, method
.MemberType
);
7105 ig
.Emit (OpCodes
.Stsfld
, field_info
);
7107 ig
.Emit (OpCodes
.Ldarg_0
);
7108 ig
.Emit (OpCodes
.Ldarg_0
);
7109 ig
.Emit (OpCodes
.Ldfld
, field_info
);
7110 ig
.Emit (OpCodes
.Ldarg_1
);
7111 ig
.Emit (OpCodes
.Call
, DelegateMethodInfo
);
7112 ig
.Emit (OpCodes
.Castclass
, method
.MemberType
);
7113 ig
.Emit (OpCodes
.Stfld
, field_info
);
7115 ig
.Emit (OpCodes
.Ret
);
7118 protected abstract MethodInfo DelegateMethodInfo { get; }
7120 public override Type
[] ParameterTypes
{
7122 return new Type
[] { method.MemberType }
;
7126 public override Type ReturnType
{
7128 return TypeManager
.void_type
;
7132 public override EmitContext
CreateEmitContext (TypeContainer tc
,
7135 return new EmitContext (
7136 tc
, method
.Parent
, Location
, ig
, ReturnType
,
7137 method
.ModFlags
, false);
7140 public override string GetSignatureForError (TypeContainer tc
)
7142 return String
.Concat (tc
.Name
, '.', method
.Name
);
7145 public override ObsoleteAttribute
GetObsoleteAttribute ()
7147 return method
.GetObsoleteAttribute (method
.Parent
);
7150 public override string[] ValidAttributeTargets
{
7152 return attribute_targets
;
7158 const int AllowedModifiers
=
7161 Modifiers
.PROTECTED
|
7162 Modifiers
.INTERNAL
|
7167 Modifiers
.OVERRIDE
|
7171 const int AllowedInterfaceModifiers
=
7174 public DelegateMethod Add
, Remove
;
7175 public MyEventBuilder EventBuilder
;
7176 public MethodBuilder AddBuilder
, RemoveBuilder
;
7178 MethodData AddData
, RemoveData
;
7180 public Event (TypeContainer parent
, Expression type
, int mod_flags
,
7181 bool is_iface
, MemberName name
, Object init
, Attributes attrs
,
7183 : base (parent
, type
, mod_flags
,
7184 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
7185 name
, init
, attrs
, loc
)
7187 IsInterface
= is_iface
;
7190 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
7192 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
)) {
7193 a
.Error_InvalidSecurityParent ();
7197 EventBuilder
.SetCustomAttribute (cb
);
7200 public bool AreAccessorsDuplicateImplementation (MethodCore mc
)
7202 return Add
.IsDuplicateImplementation (mc
) || Remove
.IsDuplicateImplementation (mc
);
7205 public override AttributeTargets AttributeTargets
{
7207 return AttributeTargets
.Event
;
7211 public override bool Define ()
7213 EventAttributes e_attr
;
7214 e_attr
= EventAttributes
.None
;
7216 if (!DoDefineBase ())
7219 if (!DoDefine (Parent
))
7222 if (init
!= null && ((ModFlags
& Modifiers
.ABSTRACT
) != 0)){
7223 Report
.Error (74, Location
, "'" + Parent
.Name
+ "." + Name
+
7224 "': abstract event can not have an initializer");
7228 if (!TypeManager
.IsDelegateType (MemberType
)) {
7229 Report
.Error (66, Location
, "'" + Parent
.Name
+ "." + Name
+
7230 "' : event must be of a delegate type");
7234 EmitContext ec
= Parent
.EmitContext
;
7236 throw new InternalErrorException ("Event.Define called too early?");
7237 bool old_unsafe
= ec
.InUnsafe
;
7238 ec
.InUnsafe
= InUnsafe
;
7240 Parameter
[] parms
= new Parameter
[1];
7241 parms
[0] = new Parameter (Type
, "value", Parameter
.Modifier
.NONE
, null);
7242 Parameters parameters
= new Parameters (parms
, null, Location
);
7243 Type
[] types
= parameters
.GetParameterInfo (ec
);
7244 InternalParameters ip
= new InternalParameters (types
, parameters
);
7246 ec
.InUnsafe
= old_unsafe
;
7252 // Now define the accessors
7255 AddBuilder
= Add
.Define (Parent
, ip
);
7256 if (AddBuilder
== null)
7259 RemoveBuilder
= Remove
.Define (Parent
, ip
);
7260 if (RemoveBuilder
== null)
7263 EventBuilder
= new MyEventBuilder (this, Parent
.TypeBuilder
, Name
, e_attr
, MemberType
);
7265 if (Add
.Block
== null && Remove
.Block
== null && !IsInterface
) {
7266 FieldBuilder
= Parent
.TypeBuilder
.DefineField (
7268 FieldAttributes
.Private
| ((ModFlags
& Modifiers
.STATIC
) != 0 ? FieldAttributes
.Static
: 0));
7269 TypeManager
.RegisterPrivateFieldOfEvent (
7270 (EventInfo
) EventBuilder
, FieldBuilder
);
7271 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
7274 EventBuilder
.SetAddOnMethod (AddBuilder
);
7275 EventBuilder
.SetRemoveOnMethod (RemoveBuilder
);
7277 TypeManager
.RegisterEvent (EventBuilder
, AddBuilder
, RemoveBuilder
);
7281 protected override bool CheckBase ()
7283 if (!base.CheckBase ())
7286 if (conflict_symbol
!= null && (ModFlags
& Modifiers
.NEW
) == 0) {
7287 if (!(conflict_symbol
is EventInfo
)) {
7288 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
7289 Report
.Error (72, Location
, "Event '{0}' can override only event", GetSignatureForError (Parent
));
7297 public override void Emit ()
7299 if (OptAttributes
!= null) {
7300 EmitContext ec
= new EmitContext (
7301 Parent
, Location
, null, MemberType
, ModFlags
);
7302 OptAttributes
.Emit (ec
, this);
7307 Remove
.Emit (Parent
);
7313 public override string GetSignatureForError ()
7315 if (EventBuilder
== null)
7316 return base.GetSignatureForError (Parent
);
7318 return TypeManager
.GetFullNameSignature (EventBuilder
);
7322 // Represents header string for documentation comment.
7324 public override string DocCommentHeader
{
7325 get { return "E:"; }
7330 public class Indexer
: PropertyBase
{
7332 class GetIndexerMethod
: GetMethod
7334 public GetIndexerMethod (MethodCore method
):
7339 public GetIndexerMethod (MethodCore method
, Accessor accessor
):
7340 base (method
, accessor
)
7344 public override Type
[] ParameterTypes
{
7346 return method
.ParameterTypes
;
7351 class SetIndexerMethod
: SetMethod
7353 readonly Parameters parameters
;
7355 public SetIndexerMethod (MethodCore method
):
7360 public SetIndexerMethod (MethodCore method
, Parameters parameters
, Accessor accessor
):
7361 base (method
, accessor
)
7363 this.parameters
= parameters
;
7366 public override Type
[] ParameterTypes
{
7368 int top
= method
.ParameterTypes
.Length
;
7369 Type
[] set_pars
= new Type
[top
+ 1];
7370 method
.ParameterTypes
.CopyTo (set_pars
, 0);
7371 set_pars
[top
] = method
.MemberType
;
7376 protected override InternalParameters
GetParameterInfo (EmitContext ec
)
7378 Parameter
[] fixed_parms
= parameters
.FixedParameters
;
7380 if (fixed_parms
== null){
7381 throw new Exception ("We currently do not support only array arguments in an indexer at: " + method
.Location
);
7382 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
7383 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
7385 // Here is the problem: the `value' parameter has
7386 // to come *after* the array parameter in the declaration
7388 // X (object [] x, Type value)
7391 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
7392 // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
7396 Parameter
[] tmp
= new Parameter
[fixed_parms
.Length
+ 1];
7398 fixed_parms
.CopyTo (tmp
, 0);
7399 tmp
[fixed_parms
.Length
] = new Parameter (
7400 method
.Type
, "value", Parameter
.Modifier
.NONE
, null);
7402 Parameters set_formal_params
= new Parameters (tmp
, null, method
.Location
);
7403 Type
[] types
= set_formal_params
.GetParameterInfo (ec
);
7405 return new InternalParameters (types
, set_formal_params
);
7409 const int AllowedModifiers
=
7412 Modifiers
.PROTECTED
|
7413 Modifiers
.INTERNAL
|
7417 Modifiers
.OVERRIDE
|
7422 const int AllowedInterfaceModifiers
=
7426 // Are we implementing an interface ?
7428 public Indexer (TypeContainer parent
, Expression type
, MemberName name
, int mod
,
7429 bool is_iface
, Parameters parameters
, Attributes attrs
,
7430 Accessor get_block
, Accessor set_block
, Location loc
)
7431 : base (parent
, type
, mod
,
7432 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
7433 is_iface
, name
, parameters
, attrs
, loc
)
7435 if (get_block
== null)
7436 Get
= new GetIndexerMethod (this);
7438 Get
= new GetIndexerMethod (this, get_block
);
7440 if (set_block
== null)
7441 Set
= new SetIndexerMethod (this);
7443 Set
= new SetIndexerMethod (this, parameters
, set_block
);
7446 public override bool Define ()
7448 PropertyAttributes prop_attr
=
7449 PropertyAttributes
.RTSpecialName
|
7450 PropertyAttributes
.SpecialName
;
7452 if (!DoDefineBase ())
7455 if (!base.Define ())
7458 if (MemberType
== TypeManager
.void_type
) {
7459 Report
.Error (620, Location
, "Indexers cannot have void type");
7463 if (OptAttributes
!= null) {
7464 Attribute indexer_attr
= OptAttributes
.Search (TypeManager
.indexer_name_type
, ec
);
7465 if (indexer_attr
!= null) {
7466 // Remove the attribute from the list because it is not emitted
7467 OptAttributes
.Attrs
.Remove (indexer_attr
);
7469 ShortName
= indexer_attr
.GetIndexerAttributeValue (ec
);
7471 if (IsExplicitImpl
) {
7472 Report
.Error (415, indexer_attr
.Location
,
7473 "The 'IndexerName' attribute is valid only on an" +
7474 "indexer that is not an explicit interface member declaration");
7478 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
7479 Report
.Error (609, indexer_attr
.Location
,
7480 "Cannot set the 'IndexerName' attribute on an indexer marked override");
7484 // if (!Tokenizer.IsValidIdentifier (ShortName)) {
7485 // Report.Error (633, indexer_attr.Location,
7486 // "The argument to the 'IndexerName' attribute must be a valid identifier");
7490 UpdateMemberName ();
7494 if (InterfaceType
!= null) {
7495 string base_IndexerName
= TypeManager
.IndexerPropertyName (InterfaceType
);
7496 if (base_IndexerName
!= Name
)
7497 ShortName
= base_IndexerName
;
7498 UpdateMemberName ();
7501 if (!Parent
.AddToMemberContainer (this) ||
7502 !Parent
.AddToMemberContainer (Get
) || !Parent
.AddToMemberContainer (Set
))
7508 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
7510 GetBuilder
= Get
.Define (Parent
);
7511 if (GetBuilder
== null)
7516 SetBuilder
= Set
.Define (Parent
);
7517 if (SetBuilder
== null)
7522 // Now name the parameters
7524 Parameter
[] p
= Parameters
.FixedParameters
;
7526 if ((p
[0].ModFlags
& Parameter
.Modifier
.ISBYREF
) != 0) {
7527 Report
.Error (631, Location
, "ref and out are not valid in this context");
7533 for (i
= 0; i
< p
.Length
; ++i
) {
7535 GetBuilder
.DefineParameter (
7536 i
+ 1, p
[i
].Attributes
, p
[i
].Name
);
7539 SetBuilder
.DefineParameter (
7540 i
+ 1, p
[i
].Attributes
, p
[i
].Name
);
7544 SetBuilder
.DefineParameter (
7545 i
+ 1, ParameterAttributes
.None
, "value");
7547 if (i
!= ParameterTypes
.Length
) {
7548 Parameter array_param
= Parameters
.ArrayParameter
;
7550 SetBuilder
.DefineParameter (
7551 i
+ 1, array_param
.Attributes
, array_param
.Name
);
7555 PropertyBuilder
= Parent
.TypeBuilder
.DefineProperty (
7556 Name
, prop_attr
, MemberType
, ParameterTypes
);
7559 PropertyBuilder
.SetGetMethod (GetBuilder
);
7562 PropertyBuilder
.SetSetMethod (SetBuilder
);
7564 TypeManager
.RegisterIndexer (PropertyBuilder
, GetBuilder
, SetBuilder
, ParameterTypes
);
7569 public override string GetSignatureForError ()
7571 if (PropertyBuilder
== null)
7572 return GetSignatureForError (Parent
);
7574 return TypeManager
.CSharpSignature (PropertyBuilder
, true);
7577 public override string GetSignatureForError(TypeContainer tc
)
7579 return String
.Concat (tc
.Name
, ".this[", Parameters
.FixedParameters
[0].TypeName
.ToString (), ']');
7582 public override bool MarkForDuplicationCheck ()
7584 caching_flags
|= Flags
.TestMethodDuplication
;
7590 public class Operator
: MethodCore
, IIteratorContainer
{
7592 const int AllowedModifiers
=
7598 public enum OpType
: byte {
7608 // Unary and Binary operators
7631 // Implicit and Explicit
7636 public readonly OpType OperatorType
;
7637 public MethodBuilder OperatorMethodBuilder
;
7639 public Method OperatorMethod
;
7641 static string[] attribute_targets
= new string [] { "method", "return" }
;
7643 public Operator (TypeContainer parent
, OpType type
, Expression ret_type
,
7644 int mod_flags
, Parameters parameters
,
7645 ToplevelBlock block
, Attributes attrs
, Location loc
)
7646 : base (parent
, null, ret_type
, mod_flags
, AllowedModifiers
, false,
7647 new MemberName ("op_" + type
), attrs
, parameters
, loc
)
7649 OperatorType
= type
;
7653 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
7655 OperatorMethod
.ApplyAttributeBuilder (a
, cb
);
7658 public override AttributeTargets AttributeTargets
{
7660 return AttributeTargets
.Method
;
7664 protected override bool CheckGenericOverride (MethodInfo method
, string name
)
7669 protected override bool CheckForDuplications()
7671 ArrayList ar
= Parent
.Operators
;
7673 int arLen
= ar
.Count
;
7675 for (int i
= 0; i
< arLen
; i
++) {
7676 Operator o
= (Operator
) ar
[i
];
7677 if (IsDuplicateImplementation (o
))
7682 ar
= Parent
.Methods
;
7684 int arLen
= ar
.Count
;
7686 for (int i
= 0; i
< arLen
; i
++) {
7687 Method m
= (Method
) ar
[i
];
7688 if (IsDuplicateImplementation (m
))
7696 public override bool Define ()
7698 const int RequiredModifiers
= Modifiers
.PUBLIC
| Modifiers
.STATIC
;
7699 if ((ModFlags
& RequiredModifiers
) != RequiredModifiers
){
7700 Report
.Error (558, Location
, "User defined operators '{0}' must be declared static and public", GetSignatureForError (Parent
));
7707 if (MemberType
== TypeManager
.void_type
) {
7708 Report
.Error (590, Location
, "User-defined operators cannot return void");
7712 OperatorMethod
= new Method (
7713 Parent
, null, Type
, ModFlags
, false, MemberName
,
7714 Parameters
, OptAttributes
, Location
);
7716 OperatorMethod
.Block
= Block
;
7717 OperatorMethod
.IsOperator
= true;
7718 OperatorMethod
.flags
|= MethodAttributes
.SpecialName
| MethodAttributes
.HideBySig
;
7719 OperatorMethod
.Define ();
7721 if (OperatorMethod
.MethodBuilder
== null)
7724 OperatorMethodBuilder
= OperatorMethod
.MethodBuilder
;
7726 parameter_types
= OperatorMethod
.ParameterTypes
;
7727 Type declaring_type
= OperatorMethod
.MethodData
.DeclaringType
;
7728 Type return_type
= OperatorMethod
.ReturnType
;
7729 Type first_arg_type
= parameter_types
[0];
7734 // Rules for conversion operators
7736 if (OperatorType
== OpType
.Implicit
|| OperatorType
== OpType
.Explicit
) {
7737 if (first_arg_type
== return_type
&& first_arg_type
== declaring_type
){
7740 "User-defined conversion cannot take an object of the " +
7741 "enclosing type and convert to an object of the enclosing" +
7746 if (first_arg_type
!= declaring_type
&& return_type
!= declaring_type
){
7749 "User-defined conversion must convert to or from the " +
7754 if (first_arg_type
== TypeManager
.object_type
||
7755 return_type
== TypeManager
.object_type
){
7758 "User-defined conversion cannot convert to or from " +
7763 if (first_arg_type
.IsInterface
|| return_type
.IsInterface
){
7766 "User-defined conversion cannot convert to or from an " +
7771 if (first_arg_type
.IsSubclassOf (return_type
)
7772 || return_type
.IsSubclassOf (first_arg_type
)){
7773 if (declaring_type
.IsSubclassOf (return_type
)) {
7774 Report
.Error (553, Location
, "'{0}' : user defined conversion to/from base class", GetSignatureForError ());
7777 Report
.Error (554, Location
, "'{0}' : user defined conversion to/from derived class", GetSignatureForError ());
7780 } else if (OperatorType
== OpType
.LeftShift
|| OperatorType
== OpType
.RightShift
) {
7781 if (first_arg_type
!= declaring_type
|| parameter_types
[1] != TypeManager
.int32_type
) {
7782 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");
7785 } else if (Parameters
.FixedParameters
.Length
== 1) {
7786 // Checks for Unary operators
7788 if (OperatorType
== OpType
.Increment
|| OperatorType
== OpType
.Decrement
) {
7789 if (return_type
!= declaring_type
&& !return_type
.IsSubclassOf (declaring_type
)) {
7790 Report
.Error (448, Location
,
7791 "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7794 if (first_arg_type
!= declaring_type
){
7796 559, Location
, "The parameter type for ++ or -- operator must be the containing type");
7801 if (first_arg_type
!= declaring_type
){
7804 "The parameter of a unary operator must be the " +
7809 if (OperatorType
== OpType
.True
|| OperatorType
== OpType
.False
) {
7810 if (return_type
!= TypeManager
.bool_type
){
7813 "The return type of operator True or False " +
7820 // Checks for Binary operators
7822 if (first_arg_type
!= declaring_type
&&
7823 parameter_types
[1] != declaring_type
){
7826 "One of the parameters of a binary operator must " +
7827 "be the containing type");
7835 public override void Emit ()
7838 // abstract or extern methods have no bodies
7840 if ((ModFlags
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) != 0)
7843 OperatorMethod
.Emit ();
7847 // Operator cannot be override
7848 protected override MethodInfo
FindOutBaseMethod (TypeContainer container
, ref Type base_ret_type
)
7853 public static string GetName (OpType ot
)
7856 case OpType
.LogicalNot
:
7858 case OpType
.OnesComplement
:
7860 case OpType
.Increment
:
7862 case OpType
.Decrement
:
7868 case OpType
.Addition
:
7870 case OpType
.Subtraction
:
7872 case OpType
.UnaryPlus
:
7874 case OpType
.UnaryNegation
:
7876 case OpType
.Multiply
:
7878 case OpType
.Division
:
7880 case OpType
.Modulus
:
7882 case OpType
.BitwiseAnd
:
7884 case OpType
.BitwiseOr
:
7886 case OpType
.ExclusiveOr
:
7888 case OpType
.LeftShift
:
7890 case OpType
.RightShift
:
7892 case OpType
.Equality
:
7894 case OpType
.Inequality
:
7896 case OpType
.GreaterThan
:
7898 case OpType
.LessThan
:
7900 case OpType
.GreaterThanOrEqual
:
7902 case OpType
.LessThanOrEqual
:
7904 case OpType
.Implicit
:
7906 case OpType
.Explicit
:
7912 public override string GetSignatureForError (TypeContainer tc
)
7914 StringBuilder sb
= new StringBuilder ();
7915 sb
.AppendFormat ("{0}.operator {1} {2}({3}", tc
.Name
, GetName (OperatorType
), Type
.Type
== null ? Type
.ToString () : TypeManager
.CSharpName (Type
.Type
),
7916 Parameters
.FixedParameters
[0].GetSignatureForError ());
7918 if (Parameters
.FixedParameters
.Length
> 1) {
7920 sb
.Append (Parameters
.FixedParameters
[1].GetSignatureForError ());
7923 return sb
.ToString ();
7926 public override string GetSignatureForError ()
7931 public override bool MarkForDuplicationCheck ()
7933 caching_flags
|= Flags
.TestMethodDuplication
;
7937 public override string ToString ()
7939 if (OperatorMethod
== null)
7942 Type return_type
= OperatorMethod
.ReturnType
;
7943 Type
[] param_types
= OperatorMethod
.ParameterTypes
;
7945 if (Parameters
.FixedParameters
.Length
== 1)
7946 return String
.Format (
7947 "{0} operator {1}({2})",
7948 TypeManager
.CSharpName (return_type
),
7949 GetName (OperatorType
),
7952 return String
.Format (
7953 "{0} operator {1}({2}, {3})",
7954 TypeManager
.CSharpName (return_type
),
7955 GetName (OperatorType
),
7956 param_types
[0], param_types
[1]);
7959 public override string[] ValidAttributeTargets
{
7961 return attribute_targets
;
7965 public void SetYields ()
7967 ModFlags
|= Modifiers
.METHOD_YIELDS
;
7972 // This is used to compare method signatures
7974 struct MethodSignature
{
7976 public Type RetType
;
7977 public Type
[] Parameters
;
7980 /// This delegate is used to extract methods which have the
7981 /// same signature as the argument
7983 public static MemberFilter method_signature_filter
= new MemberFilter (MemberSignatureCompare
);
7985 public MethodSignature (string name
, Type ret_type
, Type
[] parameters
)
7990 if (parameters
== null)
7991 Parameters
= TypeManager
.NoTypes
;
7993 Parameters
= parameters
;
7996 public override string ToString ()
7999 if (Parameters
.Length
!= 0){
8000 System
.Text
.StringBuilder sb
= new System
.Text
.StringBuilder ();
8001 for (int i
= 0; i
< Parameters
.Length
; i
++){
8002 sb
.Append (Parameters
[i
]);
8003 if (i
+1 < Parameters
.Length
)
8006 pars
= sb
.ToString ();
8009 return String
.Format ("{0} {1} ({2})", RetType
, Name
, pars
);
8012 public override int GetHashCode ()
8014 return Name
.GetHashCode ();
8017 public override bool Equals (Object o
)
8019 MethodSignature other
= (MethodSignature
) o
;
8021 if (other
.Name
!= Name
)
8024 if (other
.RetType
!= RetType
)
8027 if (Parameters
== null){
8028 if (other
.Parameters
== null)
8033 if (other
.Parameters
== null)
8036 int c
= Parameters
.Length
;
8037 if (other
.Parameters
.Length
!= c
)
8040 for (int i
= 0; i
< c
; i
++)
8041 if (other
.Parameters
[i
] != Parameters
[i
])
8047 static bool MemberSignatureCompare (MemberInfo m
, object filter_criteria
)
8049 MethodSignature sig
= (MethodSignature
) filter_criteria
;
8051 if (m
.Name
!= sig
.Name
)
8055 MethodInfo mi
= m
as MethodInfo
;
8056 PropertyInfo pi
= m
as PropertyInfo
;
8059 ReturnType
= mi
.ReturnType
;
8060 else if (pi
!= null)
8061 ReturnType
= pi
.PropertyType
;
8066 // we use sig.RetType == null to mean `do not check the
8067 // method return value.
8069 if (sig
.RetType
!= null)
8070 if (ReturnType
!= sig
.RetType
)
8075 args
= TypeManager
.GetArgumentTypes (mi
);
8077 args
= TypeManager
.GetArgumentTypes (pi
);
8078 Type
[] sigp
= sig
.Parameters
;
8080 if (args
.Length
!= sigp
.Length
)
8083 for (int i
= args
.Length
; i
> 0; ){
8085 if (args
[i
] != sigp
[i
])