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.
35 using System
.Collections
;
36 using System
.Collections
.Specialized
;
37 using System
.Reflection
;
38 using System
.Reflection
.Emit
;
39 using System
.Runtime
.CompilerServices
;
40 using System
.Runtime
.InteropServices
;
41 using System
.Security
;
42 using System
.Security
.Permissions
;
45 #if BOOTSTRAP_WITH_OLDLIB
46 using XmlElement
= System
.Object
;
51 using Mono
.CompilerServices
.SymbolWriter
;
53 namespace Mono
.CSharp
{
64 /// This is the base class for structs and classes.
66 public abstract class TypeContainer
: DeclSpace
, IMemberContainer
{
68 public class MemberCoreArrayList
: ArrayList
71 /// Defines the MemberCore objects that are in this array
73 public virtual void DefineContainerMembers ()
75 foreach (MemberCore mc
in this) {
78 } catch (Exception e
) {
79 throw new InternalErrorException (mc
, e
);
84 public virtual void Emit ()
86 foreach (MemberCore mc
in this)
91 public class OperatorArrayList
: MemberCoreArrayList
93 TypeContainer container
;
95 public OperatorArrayList (TypeContainer container
)
97 this.container
= container
;
101 // Operator pair checking
106 public Type ret_type
;
107 public Type type1
, type2
;
109 public Operator
.OpType ot
;
111 public OperatorEntry (int f
, Operator o
)
115 ret_type
= o
.MemberType
;
116 Type
[] pt
= o
.ParameterTypes
;
123 public override int GetHashCode ()
125 return ret_type
.GetHashCode ();
128 public override bool Equals (object o
)
130 OperatorEntry other
= (OperatorEntry
) o
;
132 if (other
.ret_type
!= ret_type
)
134 if (other
.type1
!= type1
)
136 if (other
.type2
!= type2
)
143 // Checks that some operators come in pairs:
149 // They are matched based on the return type and the argument types
151 void CheckPairedOperators ()
153 IDictionary pairs
= new HybridDictionary ();
154 Operator true_op
= null;
155 Operator false_op
= null;
156 bool has_equality_or_inequality
= false;
158 // Register all the operators we care about.
159 foreach (Operator op
in this){
162 // Skip erroneous code.
163 if (op
.MethodBuilder
== null)
166 switch (op
.OperatorType
){
167 case Operator
.OpType
.Equality
:
169 has_equality_or_inequality
= true;
171 case Operator
.OpType
.Inequality
:
173 has_equality_or_inequality
= true;
176 case Operator
.OpType
.True
:
179 case Operator
.OpType
.False
:
183 case Operator
.OpType
.GreaterThan
:
185 case Operator
.OpType
.LessThan
:
188 case Operator
.OpType
.GreaterThanOrEqual
:
190 case Operator
.OpType
.LessThanOrEqual
:
196 OperatorEntry oe
= new OperatorEntry (reg
, op
);
198 object o
= pairs
[oe
];
202 oe
= (OperatorEntry
) o
;
207 if (true_op
!= null){
208 if (false_op
== null)
209 Report
.Error (216, true_op
.Location
, "The operator `{0}' requires a matching operator `false' to also be defined",
210 true_op
.GetSignatureForError ());
211 } else if (false_op
!= null)
212 Report
.Error (216, false_op
.Location
, "The operator `{0}' requires a matching operator `true' to also be defined",
213 false_op
.GetSignatureForError ());
216 // Look for the mistakes.
218 foreach (DictionaryEntry de
in pairs
){
219 OperatorEntry oe
= (OperatorEntry
) de
.Key
;
226 case Operator
.OpType
.Equality
:
229 case Operator
.OpType
.Inequality
:
232 case Operator
.OpType
.GreaterThan
:
235 case Operator
.OpType
.LessThan
:
238 case Operator
.OpType
.GreaterThanOrEqual
:
241 case Operator
.OpType
.LessThanOrEqual
:
245 Report
.Error (216, oe
.op
.Location
,
246 "The operator `{0}' requires a matching operator `{1}' to also be defined",
247 oe
.op
.GetSignatureForError (), s
);
250 if (has_equality_or_inequality
&& (RootContext
.WarningLevel
> 2)) {
251 if (container
.Methods
== null || !container
.HasEquals
)
252 Report
.Warning (660, 2, container
.Location
, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container
.GetSignatureForError ());
254 if (container
.Methods
== null || !container
.HasGetHashCode
)
255 Report
.Warning (661, 2, container
.Location
, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container
.GetSignatureForError ());
259 public override void DefineContainerMembers ()
261 base.DefineContainerMembers ();
262 CheckPairedOperators ();
273 // Whether this is a struct, class or interface
274 public readonly Kind Kind
;
276 // Holds a list of classes and structures
277 protected ArrayList types
;
279 MemberCoreArrayList ordered_explicit_member_list
;
280 MemberCoreArrayList ordered_member_list
;
282 // Holds the list of properties
283 MemberCoreArrayList properties
;
285 // Holds the list of delegates
286 MemberCoreArrayList delegates
;
288 // Holds the list of constructors
289 protected MemberCoreArrayList instance_constructors
;
291 // Holds the list of fields
292 MemberCoreArrayList fields
;
294 // Holds a list of fields that have initializers
295 protected ArrayList initialized_fields
;
297 // Holds a list of static fields that have initializers
298 protected ArrayList initialized_static_fields
;
300 // Holds the list of constants
301 MemberCoreArrayList constants
;
303 // Holds the methods.
304 MemberCoreArrayList methods
;
307 protected MemberCoreArrayList events
;
309 // Holds the indexers
312 // Holds the operators
313 MemberCoreArrayList operators
;
315 // Holds the compiler generated classes
316 ArrayList compiler_generated
;
319 // Pointers to the default constructor and the default static constructor
321 protected Constructor default_constructor
;
322 protected Constructor default_static_constructor
;
325 // Points to the first non-static field added to the container.
327 // This is an arbitrary choice. We are interested in looking at _some_ non-static field,
328 // and the first one's as good as any.
330 FieldBase first_nonstatic_field
= null;
333 // This one is computed after we can distinguish interfaces
334 // from classes from the arraylist `type_bases'
337 TypeExpr
[] iface_exprs
;
340 ArrayList type_bases
;
342 bool members_resolved
;
343 bool members_resolved_ok
;
344 bool members_defined
;
345 bool members_defined_ok
;
347 // The interfaces we implement.
348 protected Type
[] ifaces
;
350 // The base member cache and our member cache
351 MemberCache base_cache
;
352 MemberCache member_cache
;
354 public const string DefaultIndexerName
= "Item";
356 private bool seen_normal_indexers
= false;
357 private string indexer_name
= DefaultIndexerName
;
359 private CachedMethods cached_method
;
362 GenericTypeParameterBuilder
[] gen_params
;
365 ArrayList partial_parts
;
368 /// The pending methods that need to be implemented
369 // (interfaces or abstract methods)
371 PendingImplementation pending
;
373 public TypeContainer (NamespaceEntry ns
, DeclSpace parent
, MemberName name
,
374 Attributes attrs
, Kind kind
)
375 : base (ns
, parent
, name
, attrs
)
377 if (parent
!= null && parent
.NamespaceEntry
!= ns
)
378 throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
381 this.PartialContainer
= this;
384 public bool AddMember (MemberCore symbol
)
386 return AddToContainer (symbol
, symbol
.MemberName
.MethodName
);
389 protected virtual bool AddMemberType (DeclSpace ds
)
391 return AddToContainer (ds
, ds
.Basename
);
394 public void AddConstant (Const constant
)
396 if (!AddMember (constant
))
399 if (constants
== null)
400 constants
= new MemberCoreArrayList ();
402 constants
.Add (constant
);
405 public TypeContainer
AddTypeContainer (TypeContainer tc
)
407 if (!AddMemberType (tc
))
411 types
= new MemberCoreArrayList ();
417 public virtual TypeContainer
AddPartial (TypeContainer next_part
)
419 return AddPartial (next_part
, next_part
.Basename
);
422 protected TypeContainer
AddPartial (TypeContainer next_part
, string name
)
424 next_part
.ModFlags
|= Modifiers
.PARTIAL
;
425 TypeContainer tc
= defined_names
[name
] as TypeContainer
;
428 return AddTypeContainer (next_part
);
430 if ((tc
.ModFlags
& Modifiers
.PARTIAL
) == 0) {
431 Report
.SymbolRelatedToPreviousError (tc
);
432 Error_MissingPartialModifier (next_part
);
436 if (tc
.Kind
!= next_part
.Kind
) {
437 Report
.SymbolRelatedToPreviousError (tc
);
438 Report
.Error (261, next_part
.Location
,
439 "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
440 next_part
.GetSignatureForError ());
444 if ((tc
.ModFlags
& Modifiers
.Accessibility
) != (next_part
.ModFlags
& Modifiers
.Accessibility
) &&
445 ((tc
.ModFlags
& Modifiers
.DEFAULT_ACCESS_MODIFER
) == 0 &&
446 (next_part
.ModFlags
& Modifiers
.DEFAULT_ACCESS_MODIFER
) == 0)) {
447 Report
.SymbolRelatedToPreviousError (tc
);
448 Report
.Error (262, next_part
.Location
,
449 "Partial declarations of `{0}' have conflicting accessibility modifiers",
450 next_part
.GetSignatureForError ());
454 if (tc
.MemberName
.IsGeneric
) {
455 TypeParameter
[] tc_names
= tc
.TypeParameters
;
456 TypeParameterName
[] part_names
= next_part
.MemberName
.TypeArguments
.GetDeclarations ();
458 for (int i
= 0; i
< tc_names
.Length
; ++i
) {
459 if (tc_names
[i
].Name
== part_names
[i
].Name
)
462 Report
.SymbolRelatedToPreviousError (part_names
[i
].Location
, "");
463 Report
.Error (264, tc
.Location
, "Partial declarations of `{0}' must have the same type parameter names in the same order",
464 tc
.GetSignatureForError ());
469 if (tc
.partial_parts
== null)
470 tc
.partial_parts
= new ArrayList (1);
472 tc
.ModFlags
|= next_part
.ModFlags
;
473 if (next_part
.attributes
!= null) {
474 if (tc
.attributes
== null)
475 tc
.attributes
= next_part
.attributes
;
477 tc
.attributes
.AddAttributes (next_part
.attributes
.Attrs
);
480 next_part
.PartialContainer
= tc
;
481 tc
.partial_parts
.Add (next_part
);
485 public void AddDelegate (Delegate d
)
487 if (!AddMemberType (d
))
490 if (delegates
== null)
491 delegates
= new MemberCoreArrayList ();
496 private void AddMemberToList (MemberCore mc
, ArrayList alist
, bool isexplicit
)
498 if (ordered_explicit_member_list
== null) {
499 ordered_explicit_member_list
= new MemberCoreArrayList ();
500 ordered_member_list
= new MemberCoreArrayList ();
504 ordered_explicit_member_list
.Add (mc
);
505 alist
.Insert (0, mc
);
508 ordered_member_list
.Add (mc
);
514 public void AddMethod (Method method
)
516 if (!AddMember (method
))
520 methods
= new MemberCoreArrayList ();
522 if (method
.MemberName
.Left
!= null)
523 AddMemberToList (method
, methods
, true);
525 AddMemberToList (method
, methods
, false);
529 // Do not use this method: use AddMethod.
531 // This is only used by iterators.
533 public void AppendMethod (Method method
)
535 if (!AddMember (method
))
539 methods
= new MemberCoreArrayList ();
541 AddMemberToList (method
, methods
, false);
544 public void AddConstructor (Constructor c
)
546 if (c
.Name
!= MemberName
.Name
) {
547 Report
.Error (1520, c
.Location
, "Class, struct, or interface method must have a return type");
550 bool is_static
= (c
.ModFlags
& Modifiers
.STATIC
) != 0;
553 if (default_static_constructor
!= null) {
554 Report
.SymbolRelatedToPreviousError (default_static_constructor
);
555 Report
.Error (111, c
.Location
, Error111
, c
.GetSignatureForError ());
559 default_static_constructor
= c
;
561 if (c
.Parameters
.Empty
){
562 if (default_constructor
!= null) {
563 Report
.SymbolRelatedToPreviousError (default_constructor
);
564 Report
.Error (111, c
.Location
, Error111
, c
.GetSignatureForError ());
567 default_constructor
= c
;
570 if (instance_constructors
== null)
571 instance_constructors
= new MemberCoreArrayList ();
573 instance_constructors
.Add (c
);
577 internal static string Error111
{
579 return "`{0}' is already defined. Rename this member or use different parameter types";
583 public void AddField (FieldBase field
)
585 if (!AddMember (field
))
589 fields
= new MemberCoreArrayList ();
593 if ((field
.ModFlags
& Modifiers
.STATIC
) != 0)
596 if (first_nonstatic_field
== null) {
597 first_nonstatic_field
= field
;
601 if (Kind
== Kind
.Struct
&&
602 first_nonstatic_field
.Parent
!= field
.Parent
&&
603 RootContext
.WarningLevel
>= 3) {
604 Report
.SymbolRelatedToPreviousError (first_nonstatic_field
.Parent
);
605 Report
.Warning (282, 3, field
.Location
,
606 "struct instance field `{0}' found in different declaration from instance field `{1}'",
607 field
.GetSignatureForError (), first_nonstatic_field
.GetSignatureForError ());
611 public void AddProperty (Property prop
)
613 if (!AddMember (prop
) ||
614 !AddMember (prop
.Get
) || !AddMember (prop
.Set
))
617 if (properties
== null)
618 properties
= new MemberCoreArrayList ();
620 if (prop
.MemberName
.Left
!= null)
621 AddMemberToList (prop
, properties
, true);
623 AddMemberToList (prop
, properties
, false);
626 public void AddEvent (Event e
)
631 if (e
is EventProperty
) {
632 if (!AddMember (e
.Add
))
635 if (!AddMember (e
.Remove
))
640 events
= new MemberCoreArrayList ();
646 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
648 public void AddIndexer (Indexer i
)
650 if (indexers
== null)
651 indexers
= new ArrayList ();
653 if (i
.IsExplicitImpl
)
654 AddMemberToList (i
, indexers
, true);
656 AddMemberToList (i
, indexers
, false);
659 public void AddOperator (Operator op
)
664 if (operators
== null)
665 operators
= new OperatorArrayList (this);
670 public void AddCompilerGeneratedClass (CompilerGeneratedClass c
)
672 Report
.Debug (64, "ADD COMPILER GENERATED CLASS", this, c
);
674 if (compiler_generated
== null)
675 compiler_generated
= new ArrayList ();
677 compiler_generated
.Add (c
);
680 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
682 if (a
.Type
== TypeManager
.default_member_type
) {
683 if (Indexers
!= null) {
684 Report
.Error (646, a
.Location
, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
689 base.ApplyAttributeBuilder (a
, cb
);
692 public override AttributeTargets AttributeTargets
{
694 throw new NotSupportedException ();
698 public ArrayList Types
{
704 public MemberCoreArrayList Methods
{
710 public ArrayList Constants
{
716 public ArrayList CompilerGenerated
{
718 return compiler_generated
;
722 protected Type BaseType
{
724 return TypeBuilder
.BaseType
;
728 public ArrayList Bases
{
738 public ArrayList Fields
{
744 public ArrayList InstanceConstructors
{
746 return instance_constructors
;
750 public ArrayList Properties
{
756 public ArrayList Events
{
762 public ArrayList Indexers
{
768 public ArrayList Operators
{
774 public ArrayList Delegates
{
780 protected override TypeAttributes TypeAttr
{
782 return Modifiers
.TypeAttr (ModFlags
, IsTopLevel
) | base.TypeAttr
;
786 public string IndexerName
{
788 return indexers
== null ? DefaultIndexerName
: indexer_name
;
792 public bool IsComImport
{
794 if (OptAttributes
== null)
797 return OptAttributes
.Contains (TypeManager
.comimport_attr_type
);
801 public virtual void RegisterFieldForInitialization (MemberCore field
, FieldInitializer expression
)
803 if ((field
.ModFlags
& Modifiers
.STATIC
) != 0){
804 if (initialized_static_fields
== null)
805 initialized_static_fields
= new ArrayList (4);
807 initialized_static_fields
.Add (expression
);
809 if (initialized_fields
== null)
810 initialized_fields
= new ArrayList (4);
812 initialized_fields
.Add (expression
);
817 // Emits the instance field initializers
819 public bool EmitFieldInitializers (EmitContext ec
)
824 fields
= initialized_static_fields
;
826 fields
= initialized_fields
;
832 foreach (FieldInitializer f
in fields
) {
833 f
.EmitStatement (ec
);
838 public override string DocComment
{
850 public PendingImplementation PendingImplementations
{
851 get { return pending; }
854 public override bool GetClsCompliantAttributeValue ()
856 if (PartialContainer
!= this)
857 return PartialContainer
.GetClsCompliantAttributeValue ();
859 return base.GetClsCompliantAttributeValue ();
862 public void AddBasesForPart (DeclSpace part
, ArrayList bases
)
864 // FIXME: get rid of partial_parts and store lists of bases of each part here
865 // assumed, not verified: 'part' is in 'partial_parts'
866 ((TypeContainer
) part
).Bases
= bases
;
869 TypeExpr
[] GetNormalBases (out TypeExpr base_class
)
875 int count
= Bases
.Count
;
878 if (Kind
== Kind
.Class
){
879 TypeExpr name
= ((Expression
) Bases
[0]).ResolveAsBaseTerminal (this, false);
885 if (!name
.IsInterface
) {
886 // base_class could be a class, struct, enum, delegate.
887 // This is validated in GetClassBases.
893 TypeExpr
[] ifaces
= new TypeExpr
[count
-start
];
895 for (i
= start
, j
= 0; i
< count
; i
++, j
++){
896 TypeExpr resolved
= ((Expression
) Bases
[i
]).ResolveAsBaseTerminal (this, false);
897 if (resolved
== null) {
901 ifaces
[j
] = resolved
;
904 return ifaces
.Length
== 0 ? null : ifaces
;
908 TypeExpr
[] GetNormalPartialBases (ref TypeExpr base_class
)
910 ArrayList ifaces
= new ArrayList (0);
911 if (iface_exprs
!= null)
912 ifaces
.AddRange (iface_exprs
);
914 foreach (TypeContainer part
in partial_parts
) {
915 TypeExpr new_base_class
;
916 TypeExpr
[] new_ifaces
= part
.GetClassBases (out new_base_class
);
917 if (new_base_class
!= TypeManager
.system_object_expr
) {
918 if (base_class
== TypeManager
.system_object_expr
)
919 base_class
= new_base_class
;
921 if (new_base_class
!= null && !new_base_class
.Equals (base_class
)) {
922 Report
.SymbolRelatedToPreviousError (base_class
.Location
, "");
923 Report
.Error (263, part
.Location
,
924 "Partial declarations of `{0}' must not specify different base classes",
925 part
.GetSignatureForError ());
932 if (new_ifaces
== null)
935 foreach (TypeExpr iface
in new_ifaces
) {
936 if (ifaces
.Contains (iface
))
943 if (ifaces
.Count
== 0)
946 return (TypeExpr
[])ifaces
.ToArray (typeof (TypeExpr
));
950 /// This function computes the Base class and also the
951 /// list of interfaces that the class or struct @c implements.
953 /// The return value is an array (might be null) of
954 /// interfaces implemented (as Types).
956 /// The @base_class argument is set to the base object or null
957 /// if this is `System.Object'.
959 public virtual TypeExpr
[] GetClassBases (out TypeExpr base_class
)
961 TypeExpr
[] ifaces
= GetNormalBases (out base_class
);
966 int count
= ifaces
.Length
;
968 for (int i
= 0; i
< count
; i
++) {
969 TypeExpr iface
= (TypeExpr
) ifaces
[i
];
971 if (!iface
.IsInterface
) {
972 if (Kind
!= Kind
.Class
) {
973 // TODO: location of symbol related ....
974 Error_TypeInListIsNotInterface (Location
, iface
.GetSignatureForError ());
976 else if (base_class
!= null)
977 Report
.Error (1721, Location
, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
978 GetSignatureForError (), base_class
.GetSignatureForError (), iface
.GetSignatureForError ());
980 Report
.Error (1722, Location
, "`{0}': Base class `{1}' must be specified as first",
981 GetSignatureForError (), iface
.GetSignatureForError ());
986 for (int x
= 0; x
< i
; x
++) {
987 if (iface
.Equals (ifaces
[x
])) {
988 Report
.Error (528, Location
,
989 "`{0}' is already listed in " +
990 "interface list", iface
.GetSignatureForError ());
995 if ((Kind
== Kind
.Interface
) &&
996 !iface
.AsAccessible (Parent
, ModFlags
)) {
997 Report
.Error (61, Location
,
998 "Inconsistent accessibility: base " +
999 "interface `{0}' is less accessible " +
1000 "than interface `{1}'", iface
.Name
,
1008 bool CheckGenericInterfaces (Type
[] ifaces
)
1011 ArrayList already_checked
= new ArrayList ();
1013 for (int i
= 0; i
< ifaces
.Length
; i
++) {
1014 Type iface
= ifaces
[i
];
1015 foreach (Type t
in already_checked
) {
1019 Type
[] inferred
= new Type
[CountTypeParameters
];
1020 if (!TypeManager
.MayBecomeEqualGenericInstances (iface
, t
, inferred
, null))
1023 Report
.Error (695, Location
,
1024 "`{0}' cannot implement both `{1}' and `{2}' " +
1025 "because they may unify for some type parameter substitutions",
1026 TypeManager
.CSharpName (TypeBuilder
), TypeManager
.CSharpName (iface
),
1027 TypeManager
.CSharpName (t
));
1031 already_checked
.Add (iface
);
1040 protected void Error_TypeInListIsNotInterface (Location loc
, string type
)
1042 Report
.Error (527, loc
, "Type `{0}' in interface list is not an interface", type
);
1045 bool CreateTypeBuilder ()
1048 Type default_parent
= null;
1049 if (Kind
== Kind
.Struct
)
1050 default_parent
= TypeManager
.value_type
;
1051 else if (Kind
== Kind
.Enum
)
1052 default_parent
= TypeManager
.enum_type
;
1055 if (TypeManager
.NamespaceClash (Name
, Location
)) {
1059 ModuleBuilder builder
= CodeGen
.Module
.Builder
;
1060 TypeBuilder
= builder
.DefineType (
1061 Name
, TypeAttr
, default_parent
, null);
1063 TypeBuilder builder
= Parent
.TypeBuilder
;
1065 TypeBuilder
= builder
.DefineNestedType (
1066 Basename
, TypeAttr
, default_parent
, null);
1068 } catch (ArgumentException
) {
1069 Report
.RuntimeMissingSupport (Location
, "static classes");
1073 TypeManager
.AddUserType (this);
1077 string[] param_names
= new string [TypeParameters
.Length
];
1078 for (int i
= 0; i
< TypeParameters
.Length
; i
++)
1079 param_names
[i
] = TypeParameters
[i
].Name
;
1081 gen_params
= TypeBuilder
.DefineGenericParameters (param_names
);
1083 int offset
= CountTypeParameters
- CurrentTypeParameters
.Length
;
1084 for (int i
= offset
; i
< gen_params
.Length
; i
++)
1085 CurrentTypeParameters
[i
- offset
].Define (gen_params
[i
]);
1092 bool DefineBaseTypes ()
1094 iface_exprs
= GetClassBases (out base_type
);
1095 if (partial_parts
!= null) {
1096 iface_exprs
= GetNormalPartialBases (ref base_type
);
1100 // GetClassBases calls ResolveBaseTypeExpr() on the various type expressions involved,
1101 // which in turn should have called DefineType()s on base types if necessary.
1103 // None of the code below should trigger DefineType()s on classes that we depend on.
1104 // Thus, we are eligible to be on the topological sort `type_container_resolve_order'.
1106 // Let's do it as soon as possible, since code below can call DefineType() on classes
1107 // that depend on us to be populated before they are.
1109 if (!(this is CompilerGeneratedClass
))
1110 RootContext
.RegisterOrder (this);
1112 if (IsGeneric
&& base_type
!= null && TypeManager
.IsAttributeType (base_type
.Type
)) {
1113 Report
.Error (698, base_type
.Location
,
1114 "A generic type cannot derive from `{0}' because it is an attribute class",
1119 if (!CheckRecursiveDefinition (this))
1122 if (base_type
!= null) {
1123 TypeBuilder
.SetParent (base_type
.Type
);
1125 ObsoleteAttribute obsolete_attr
= AttributeTester
.GetObsoleteAttribute (base_type
.Type
);
1126 if (obsolete_attr
!= null && !IsInObsoleteScope
)
1127 AttributeTester
.Report_ObsoleteMessage (obsolete_attr
, base_type
.GetSignatureForError (), Location
);
1130 // add interfaces that were not added at type creation
1131 if (iface_exprs
!= null) {
1132 ifaces
= TypeManager
.ExpandInterfaces (iface_exprs
);
1136 foreach (Type itype
in ifaces
)
1137 TypeBuilder
.AddInterfaceImplementation (itype
);
1139 foreach (TypeExpr ie
in iface_exprs
) {
1140 ObsoleteAttribute oa
= AttributeTester
.GetObsoleteAttribute (ie
.Type
);
1141 if ((oa
!= null) && !IsInObsoleteScope
)
1142 AttributeTester
.Report_ObsoleteMessage (
1143 oa
, ie
.GetSignatureForError (), Location
);
1146 if (!CheckGenericInterfaces (ifaces
))
1149 TypeManager
.RegisterBuilder (TypeBuilder
, ifaces
);
1156 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1158 public TypeBuilder
CreateType ()
1160 if (TypeBuilder
!= null)
1166 if (!CreateTypeBuilder ()) {
1171 if (partial_parts
!= null) {
1172 foreach (TypeContainer part
in partial_parts
)
1173 part
.TypeBuilder
= TypeBuilder
;
1176 if (Types
!= null) {
1177 foreach (TypeContainer tc
in Types
) {
1178 if (tc
.CreateType () == null) {
1190 public override TypeBuilder
DefineType ()
1197 type_defined
= true;
1199 if (CreateType () == null) {
1204 if (!DefineBaseTypes ()) {
1209 if (!(this is CompilerGeneratedClass
)) {
1210 if (!ResolveMembers ()) {
1216 if (!DefineNestedTypes ()) {
1224 public bool ResolveMembers ()
1226 if (members_resolved
)
1227 return members_resolved_ok
;
1229 members_resolved_ok
= DoResolveMembers ();
1230 members_resolved
= true;
1232 return members_resolved_ok
;
1235 protected virtual bool DoResolveMembers ()
1237 if (methods
!= null) {
1238 foreach (Method method
in methods
) {
1239 if (!method
.ResolveMembers ())
1244 if (instance_constructors
!= null) {
1245 foreach (Constructor c
in instance_constructors
) {
1246 if (!c
.ResolveMembers ())
1251 if (default_static_constructor
!= null) {
1252 if (!default_static_constructor
.ResolveMembers ())
1256 if (operators
!= null) {
1257 foreach (Operator o
in operators
) {
1258 if (!o
.ResolveMembers ())
1263 if (properties
!= null) {
1264 foreach (PropertyBase p
in properties
) {
1265 if (!p
.Get
.IsDummy
&& !p
.Get
.ResolveMembers ())
1267 if (!p
.Set
.IsDummy
&& !p
.Set
.ResolveMembers ())
1272 if (indexers
!= null) {
1273 foreach (PropertyBase p
in indexers
) {
1274 if (!p
.Get
.IsDummy
&& !p
.Get
.ResolveMembers ())
1276 if (!p
.Set
.IsDummy
&& !p
.Set
.ResolveMembers ())
1281 if (events
!= null) {
1282 foreach (Event e
in events
) {
1283 if (!e
.Add
.ResolveMembers ())
1285 if (!e
.Remove
.ResolveMembers ())
1290 if (compiler_generated
!= null) {
1291 foreach (CompilerGeneratedClass c
in compiler_generated
) {
1292 if (c
.DefineType () == null)
1300 Constraints
[] constraints
;
1301 public override void SetParameterInfo (ArrayList constraints_list
)
1303 if (PartialContainer
== this) {
1304 base.SetParameterInfo (constraints_list
);
1308 if (constraints_list
== null)
1311 constraints
= new Constraints
[PartialContainer
.CountCurrentTypeParameters
];
1313 TypeParameter
[] current_params
= PartialContainer
.CurrentTypeParameters
;
1314 for (int i
= 0; i
< constraints
.Length
; i
++) {
1315 foreach (Constraints constraint
in constraints_list
) {
1316 if (constraint
.TypeParameter
== current_params
[i
].Name
) {
1317 constraints
[i
] = constraint
;
1324 bool UpdateTypeParameterConstraints ()
1326 if (constraints
== null)
1329 TypeParameter
[] current_params
= PartialContainer
.CurrentTypeParameters
;
1330 for (int i
= 0; i
< current_params
.Length
; i
++) {
1331 if (!current_params
[i
].UpdateConstraints (this, constraints
[i
])) {
1332 Report
.SymbolRelatedToPreviousError (Location
, "");
1333 Report
.Error (265, PartialContainer
.Location
,
1334 "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
1335 PartialContainer
.GetSignatureForError (), current_params
[i
].Name
);
1343 public bool ResolveType ()
1345 if (!DoResolveType ())
1348 if (compiler_generated
!= null) {
1349 foreach (CompilerGeneratedClass c
in compiler_generated
)
1350 if (!c
.ResolveType ())
1357 protected virtual bool DoResolveType ()
1359 if ((base_type
!= null) &&
1360 (base_type
.ResolveAsTypeTerminal (this, false) == null)) {
1368 if (PartialContainer
!= this)
1369 throw new InternalErrorException ();
1371 TypeExpr current_type
= null;
1373 foreach (TypeParameter type_param
in CurrentTypeParameters
) {
1374 if (!type_param
.Resolve (this)) {
1380 if (partial_parts
!= null) {
1381 foreach (TypeContainer part
in partial_parts
) {
1382 if (!part
.UpdateTypeParameterConstraints ()) {
1389 foreach (TypeParameter type_param
in TypeParameters
) {
1390 if (!type_param
.DefineType (this)) {
1396 current_type
= new ConstructedType (TypeBuilder
, TypeParameters
, Location
);
1398 foreach (TypeParameter type_param
in TypeParameters
)
1399 if (!type_param
.CheckDependencies ()) {
1404 if (current_type
!= null) {
1405 current_type
= current_type
.ResolveAsTypeTerminal (this, false);
1406 if (current_type
== null) {
1411 CurrentType
= current_type
.Type
;
1417 protected virtual bool DefineNestedTypes ()
1419 if (Types
!= null) {
1420 foreach (TypeContainer tc
in Types
)
1421 if (tc
.DefineType () == null)
1425 if (Delegates
!= null) {
1426 foreach (Delegate d
in Delegates
)
1427 if (d
.DefineType () == null)
1434 TypeContainer InTransit
;
1436 protected bool CheckRecursiveDefinition (TypeContainer tc
)
1438 if (InTransit
!= null) {
1439 Report
.SymbolRelatedToPreviousError (this);
1440 if (this is Interface
)
1442 529, tc
.Location
, "Inherited interface `{0}' causes a " +
1443 "cycle in the interface hierarchy of `{1}'",
1444 GetSignatureForError (), tc
.GetSignatureForError ());
1447 146, tc
.Location
, "Circular base class dependency " +
1448 "involving `{0}' and `{1}'",
1449 tc
.GetSignatureForError (), GetSignatureForError ());
1455 if (base_type
!= null) {
1456 Type t
= TypeManager
.DropGenericTypeArguments (base_type
.Type
);
1457 TypeContainer ptc
= TypeManager
.LookupTypeContainer (t
);
1458 if ((ptc
!= null) && !ptc
.CheckRecursiveDefinition (this))
1462 if (iface_exprs
!= null) {
1463 foreach (TypeExpr iface
in iface_exprs
) {
1464 Type itype
= TypeManager
.DropGenericTypeArguments (iface
.Type
);
1465 TypeContainer ptc
= TypeManager
.LookupTypeContainer (itype
);
1466 if ((ptc
!= null) && !ptc
.CheckRecursiveDefinition (this))
1471 if (!IsTopLevel
&& !Parent
.PartialContainer
.CheckRecursiveDefinition (this))
1478 public static void Error_KeywordNotAllowed (Location loc
)
1480 Report
.Error (1530, loc
, "Keyword `new' is not allowed on namespace elements");
1484 /// Populates our TypeBuilder with fields and methods
1486 public override bool DefineMembers ()
1488 if (members_defined
)
1489 return members_defined_ok
;
1491 if (!base.DefineMembers ())
1494 members_defined_ok
= DoDefineMembers ();
1495 members_defined
= true;
1497 return members_defined_ok
;
1500 protected virtual bool DoDefineMembers ()
1502 if (iface_exprs
!= null) {
1503 foreach (TypeExpr iface
in iface_exprs
) {
1504 ConstructedType ct
= iface
as ConstructedType
;
1505 if ((ct
!= null) && !ct
.CheckConstraints (this))
1510 if (base_type
!= null) {
1511 ConstructedType ct
= base_type
as ConstructedType
;
1512 if ((ct
!= null) && !ct
.CheckConstraints (this))
1517 MemberInfo conflict_symbol
= Parent
.PartialContainer
.FindBaseMemberWithSameName (Basename
, false);
1518 if (conflict_symbol
== null) {
1519 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0))
1520 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1522 if ((ModFlags
& Modifiers
.NEW
) == 0) {
1523 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
1524 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
1525 GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
1530 DefineContainerMembers (constants
);
1531 DefineContainerMembers (fields
);
1533 if (Kind
== Kind
.Struct
|| Kind
== Kind
.Class
) {
1534 pending
= PendingImplementation
.GetPendingImplementations (this);
1538 // Constructors are not in the defined_names array
1540 DefineContainerMembers (instance_constructors
);
1542 DefineContainerMembers (events
);
1543 DefineContainerMembers (ordered_explicit_member_list
);
1544 DefineContainerMembers (ordered_member_list
);
1546 DefineContainerMembers (operators
);
1547 DefineContainerMembers (delegates
);
1549 ComputeIndexerName();
1550 CheckEqualsAndGetHashCode();
1552 if (CurrentType
!= null) {
1553 GenericType
= CurrentType
;
1557 member_cache
= new MemberCache (this);
1558 if (partial_parts
!= null) {
1559 foreach (TypeContainer part
in partial_parts
)
1560 part
.member_cache
= member_cache
;
1567 protected virtual void DefineContainerMembers (MemberCoreArrayList mcal
)
1570 mcal
.DefineContainerMembers ();
1573 protected virtual void ComputeIndexerName ()
1575 if (indexers
== null)
1578 string class_indexer_name
= null;
1581 // If there's both an explicit and an implicit interface implementation, the
1582 // explicit one actually implements the interface while the other one is just
1583 // a normal indexer. See bug #37714.
1586 // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
1587 foreach (Indexer i
in indexers
) {
1588 if (i
.InterfaceType
!= null) {
1589 if (seen_normal_indexers
)
1590 throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
1594 seen_normal_indexers
= true;
1596 if (class_indexer_name
== null) {
1597 class_indexer_name
= i
.ShortName
;
1601 if (i
.ShortName
!= class_indexer_name
)
1602 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");
1605 if (class_indexer_name
!= null)
1606 indexer_name
= class_indexer_name
;
1609 protected virtual void EmitIndexerName ()
1611 if (!seen_normal_indexers
)
1614 CustomAttributeBuilder cb
= new CustomAttributeBuilder (TypeManager
.default_member_ctor
, new string [] { IndexerName }
);
1615 TypeBuilder
.SetCustomAttribute (cb
);
1618 protected virtual void CheckEqualsAndGetHashCode ()
1620 if (methods
== null)
1623 if (HasEquals
&& !HasGetHashCode
) {
1624 Report
.Warning (659, 3, this.Location
, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", this.GetSignatureForError ());
1628 public override bool Define ()
1630 if (compiler_generated
!= null) {
1631 foreach (CompilerGeneratedClass c
in compiler_generated
) {
1640 public MemberInfo
FindBaseMemberWithSameName (string name
, bool ignore_methods
)
1642 return BaseCache
== null ? null : BaseCache
.FindMemberWithSameName (name
, ignore_methods
, null);
1646 /// This function is based by a delegate to the FindMembers routine
1648 static bool AlwaysAccept (MemberInfo m
, object filterCriteria
)
1654 /// This filter is used by FindMembers, and we just keep
1655 /// a global for the filter to `AlwaysAccept'
1657 static MemberFilter accepting_filter
;
1660 static TypeContainer ()
1662 accepting_filter
= new MemberFilter (AlwaysAccept
);
1665 public MethodInfo
[] GetMethods ()
1667 ArrayList members
= new ArrayList ();
1671 if (methods
!= null) {
1672 int len
= methods
.Count
;
1673 for (int i
= 0; i
< len
; i
++) {
1674 Method m
= (Method
) methods
[i
];
1676 members
.Add (m
.MethodBuilder
);
1680 if (operators
!= null) {
1681 int len
= operators
.Count
;
1682 for (int i
= 0; i
< len
; i
++) {
1683 Operator o
= (Operator
) operators
[i
];
1685 members
.Add (o
.MethodBuilder
);
1689 if (properties
!= null) {
1690 int len
= properties
.Count
;
1691 for (int i
= 0; i
< len
; i
++) {
1692 Property p
= (Property
) properties
[i
];
1694 if (p
.GetBuilder
!= null)
1695 members
.Add (p
.GetBuilder
);
1696 if (p
.SetBuilder
!= null)
1697 members
.Add (p
.SetBuilder
);
1701 if (indexers
!= null) {
1702 int len
= indexers
.Count
;
1703 for (int i
= 0; i
< len
; i
++) {
1704 Indexer ix
= (Indexer
) indexers
[i
];
1706 if (ix
.GetBuilder
!= null)
1707 members
.Add (ix
.GetBuilder
);
1708 if (ix
.SetBuilder
!= null)
1709 members
.Add (ix
.SetBuilder
);
1713 if (events
!= null) {
1714 int len
= events
.Count
;
1715 for (int i
= 0; i
< len
; i
++) {
1716 Event e
= (Event
) events
[i
];
1718 if (e
.AddBuilder
!= null)
1719 members
.Add (e
.AddBuilder
);
1720 if (e
.RemoveBuilder
!= null)
1721 members
.Add (e
.RemoveBuilder
);
1725 MethodInfo
[] retMethods
= new MethodInfo
[members
.Count
];
1726 members
.CopyTo (retMethods
, 0);
1730 // Indicated whether container has StructLayout attribute set Explicit
1731 public bool HasExplicitLayout
{
1732 get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
1733 set { caching_flags |= Flags.HasExplicitLayout; }
1737 // Return the nested type with name @name. Ensures that the nested type
1738 // is defined if necessary. Do _not_ use this when you have a MemberCache handy.
1740 public Type
FindNestedType (string name
)
1742 if (PartialContainer
!= this)
1743 throw new InternalErrorException ("should not happen");
1745 ArrayList
[] lists
= { types, delegates }
;
1747 for (int j
= 0; j
< lists
.Length
; ++j
) {
1748 ArrayList list
= lists
[j
];
1752 int len
= list
.Count
;
1753 for (int i
= 0; i
< len
; ++i
) {
1754 DeclSpace ds
= (DeclSpace
) list
[i
];
1755 if (ds
.Basename
== name
) {
1756 return ds
.DefineType ();
1764 private void FindMembers_NestedTypes (int modflags
,
1765 BindingFlags bf
, MemberFilter filter
, object criteria
,
1766 ref ArrayList members
)
1768 ArrayList
[] lists
= { types, delegates }
;
1770 for (int j
= 0; j
< lists
.Length
; ++j
) {
1771 ArrayList list
= lists
[j
];
1775 int len
= list
.Count
;
1776 for (int i
= 0; i
< len
; i
++) {
1777 DeclSpace ds
= (DeclSpace
) list
[i
];
1779 if ((ds
.ModFlags
& modflags
) == 0)
1782 TypeBuilder tb
= ds
.TypeBuilder
;
1784 if (!(criteria
is string) || ds
.Basename
.Equals (criteria
))
1785 tb
= ds
.DefineType ();
1788 if (tb
!= null && (filter (tb
, criteria
) == true)) {
1789 if (members
== null)
1790 members
= new ArrayList ();
1799 /// This method returns the members of this type just like Type.FindMembers would
1800 /// Only, we need to use this for types which are _being_ defined because MS'
1801 /// implementation can't take care of that.
1804 // FIXME: return an empty static array instead of null, that cleans up
1805 // some code and is consistent with some coding conventions I just found
1809 // Notice that in various cases we check if our field is non-null,
1810 // something that would normally mean that there was a bug elsewhere.
1812 // The problem happens while we are defining p-invoke methods, as those
1813 // will trigger a FindMembers, but this happens before things are defined
1815 // Since the whole process is a no-op, it is fine to check for null here.
1817 public override MemberList
FindMembers (MemberTypes mt
, BindingFlags bf
,
1818 MemberFilter filter
, object criteria
)
1820 ArrayList members
= null;
1823 if ((bf
& BindingFlags
.Public
) != 0)
1824 modflags
|= Modifiers
.PUBLIC
| Modifiers
.PROTECTED
|
1826 if ((bf
& BindingFlags
.NonPublic
) != 0)
1827 modflags
|= Modifiers
.PRIVATE
;
1829 int static_mask
= 0, static_flags
= 0;
1830 switch (bf
& (BindingFlags
.Static
| BindingFlags
.Instance
)) {
1831 case BindingFlags
.Static
:
1832 static_mask
= static_flags
= Modifiers
.STATIC
;
1835 case BindingFlags
.Instance
:
1836 static_mask
= Modifiers
.STATIC
;
1841 static_mask
= static_flags
= 0;
1845 Timer
.StartTimer (TimerType
.TcFindMembers
);
1848 filter
= accepting_filter
;
1850 if ((mt
& MemberTypes
.Field
) != 0) {
1851 if (fields
!= null) {
1852 int len
= fields
.Count
;
1853 for (int i
= 0; i
< len
; i
++) {
1854 FieldBase f
= (FieldBase
) fields
[i
];
1856 if ((f
.ModFlags
& modflags
) == 0)
1858 if ((f
.ModFlags
& static_mask
) != static_flags
)
1861 FieldBuilder fb
= f
.FieldBuilder
;
1862 if (fb
!= null && filter (fb
, criteria
) == true) {
1863 if (members
== null)
1864 members
= new ArrayList ();
1871 if (constants
!= null) {
1872 int len
= constants
.Count
;
1873 for (int i
= 0; i
< len
; i
++) {
1874 Const con
= (Const
) constants
[i
];
1876 if ((con
.ModFlags
& modflags
) == 0)
1878 if ((con
.ModFlags
& static_mask
) != static_flags
)
1881 FieldBuilder fb
= con
.FieldBuilder
;
1884 fb
= con
.FieldBuilder
;
1886 if (fb
!= null && filter (fb
, criteria
) == true) {
1887 if (members
== null)
1888 members
= new ArrayList ();
1896 if ((mt
& MemberTypes
.Method
) != 0) {
1897 if (methods
!= null) {
1898 int len
= methods
.Count
;
1899 for (int i
= 0; i
< len
; i
++) {
1900 Method m
= (Method
) methods
[i
];
1902 if ((m
.ModFlags
& modflags
) == 0)
1904 if ((m
.ModFlags
& static_mask
) != static_flags
)
1907 MethodBuilder mb
= m
.MethodBuilder
;
1909 if (mb
!= null && filter (mb
, criteria
) == true) {
1910 if (members
== null)
1911 members
= new ArrayList ();
1918 if (operators
!= null) {
1919 int len
= operators
.Count
;
1920 for (int i
= 0; i
< len
; i
++) {
1921 Operator o
= (Operator
) operators
[i
];
1923 if ((o
.ModFlags
& modflags
) == 0)
1925 if ((o
.ModFlags
& static_mask
) != static_flags
)
1928 MethodBuilder ob
= o
.MethodBuilder
;
1929 if (ob
!= null && filter (ob
, criteria
) == true) {
1930 if (members
== null)
1931 members
= new ArrayList ();
1938 if (events
!= null) {
1939 foreach (Event e
in events
) {
1940 if ((e
.ModFlags
& modflags
) == 0)
1942 if ((e
.ModFlags
& static_mask
) != static_flags
)
1945 MethodBuilder b
= e
.AddBuilder
;
1946 if (b
!= null && filter (b
, criteria
)) {
1947 if (members
== null)
1948 members
= new ArrayList (4);
1953 b
= e
.RemoveBuilder
;
1954 if (b
!= null && filter (b
, criteria
)) {
1955 if (members
== null)
1956 members
= new ArrayList (4);
1963 if (properties
!= null) {
1964 int len
= properties
.Count
;
1965 for (int i
= 0; i
< len
; i
++) {
1966 Property p
= (Property
) properties
[i
];
1968 if ((p
.ModFlags
& modflags
) == 0)
1970 if ((p
.ModFlags
& static_mask
) != static_flags
)
1976 if (b
!= null && filter (b
, criteria
) == true) {
1977 if (members
== null)
1978 members
= new ArrayList ();
1984 if (b
!= null && filter (b
, criteria
) == true) {
1985 if (members
== null)
1986 members
= new ArrayList ();
1993 if (indexers
!= null) {
1994 int len
= indexers
.Count
;
1995 for (int i
= 0; i
< len
; i
++) {
1996 Indexer ix
= (Indexer
) indexers
[i
];
1998 if ((ix
.ModFlags
& modflags
) == 0)
2000 if ((ix
.ModFlags
& static_mask
) != static_flags
)
2006 if (b
!= null && filter (b
, criteria
) == true) {
2007 if (members
== null)
2008 members
= new ArrayList ();
2014 if (b
!= null && filter (b
, criteria
) == true) {
2015 if (members
== null)
2016 members
= new ArrayList ();
2024 if ((mt
& MemberTypes
.Event
) != 0) {
2025 if (events
!= null) {
2026 int len
= events
.Count
;
2027 for (int i
= 0; i
< len
; i
++) {
2028 Event e
= (Event
) events
[i
];
2030 if ((e
.ModFlags
& modflags
) == 0)
2032 if ((e
.ModFlags
& static_mask
) != static_flags
)
2035 MemberInfo eb
= e
.EventBuilder
;
2036 if (eb
!= null && filter (eb
, criteria
) == true) {
2037 if (members
== null)
2038 members
= new ArrayList ();
2040 members
.Add (e
.EventBuilder
);
2046 if ((mt
& MemberTypes
.Property
) != 0){
2047 if (properties
!= null) {
2048 int len
= properties
.Count
;
2049 for (int i
= 0; i
< len
; i
++) {
2050 Property p
= (Property
) properties
[i
];
2052 if ((p
.ModFlags
& modflags
) == 0)
2054 if ((p
.ModFlags
& static_mask
) != static_flags
)
2057 MemberInfo pb
= p
.PropertyBuilder
;
2058 if (pb
!= null && filter (pb
, criteria
) == true) {
2059 if (members
== null)
2060 members
= new ArrayList ();
2062 members
.Add (p
.PropertyBuilder
);
2067 if (indexers
!= null) {
2068 int len
= indexers
.Count
;
2069 for (int i
= 0; i
< len
; i
++) {
2070 Indexer ix
= (Indexer
) indexers
[i
];
2072 if ((ix
.ModFlags
& modflags
) == 0)
2074 if ((ix
.ModFlags
& static_mask
) != static_flags
)
2077 MemberInfo ib
= ix
.PropertyBuilder
;
2078 if (ib
!= null && filter (ib
, criteria
) == true) {
2079 if (members
== null)
2080 members
= new ArrayList ();
2082 members
.Add (ix
.PropertyBuilder
);
2088 if ((mt
& MemberTypes
.NestedType
) != 0)
2089 FindMembers_NestedTypes (modflags
, bf
, filter
, criteria
, ref members
);
2091 if ((mt
& MemberTypes
.Constructor
) != 0){
2092 if (((bf
& BindingFlags
.Instance
) != 0) && (instance_constructors
!= null)){
2093 int len
= instance_constructors
.Count
;
2094 for (int i
= 0; i
< len
; i
++) {
2095 Constructor c
= (Constructor
) instance_constructors
[i
];
2097 ConstructorBuilder cb
= c
.ConstructorBuilder
;
2098 if (cb
!= null && filter (cb
, criteria
) == true) {
2099 if (members
== null)
2100 members
= new ArrayList ();
2107 if (((bf
& BindingFlags
.Static
) != 0) && (default_static_constructor
!= null)){
2108 ConstructorBuilder cb
=
2109 default_static_constructor
.ConstructorBuilder
;
2111 if (cb
!= null && filter (cb
, criteria
) == true) {
2112 if (members
== null)
2113 members
= new ArrayList ();
2121 // Lookup members in base if requested.
2123 if ((bf
& BindingFlags
.DeclaredOnly
) == 0) {
2124 if (TypeBuilder
.BaseType
!= null) {
2125 MemberList list
= FindMembers (TypeBuilder
.BaseType
, mt
, bf
, filter
, criteria
);
2126 if (list
.Count
> 0) {
2127 if (members
== null)
2128 members
= new ArrayList ();
2130 members
.AddRange (list
);
2135 Timer
.StopTimer (TimerType
.TcFindMembers
);
2137 if (members
== null)
2138 return MemberList
.Empty
;
2140 return new MemberList (members
);
2143 public override MemberCache MemberCache
{
2145 return member_cache
;
2149 public static MemberList
FindMembers (Type t
, MemberTypes mt
, BindingFlags bf
,
2150 MemberFilter filter
, object criteria
)
2152 DeclSpace ds
= TypeManager
.LookupDeclSpace (t
);
2155 return ds
.FindMembers (mt
, bf
, filter
, criteria
);
2157 return new MemberList (t
.FindMembers (mt
, bf
, filter
, criteria
));
2161 /// Emits the values for the constants
2163 public void EmitConstants ()
2165 if (constants
!= null)
2166 foreach (Const con
in constants
)
2171 static void CheckMemberUsage (MemberCoreArrayList al
, string member_type
)
2176 foreach (MemberCore mc
in al
) {
2177 if ((mc
.ModFlags
& Modifiers
.Accessibility
) != Modifiers
.PRIVATE
)
2181 Report
.Warning (169, 3, mc
.Location
, "The private {0} `{1}' is never used", member_type
, mc
.GetSignatureForError ());
2186 public virtual void VerifyMembers ()
2189 // Check for internal or private fields that were never assigned
2191 if (RootContext
.WarningLevel
>= 3) {
2192 CheckMemberUsage (properties
, "property");
2193 CheckMemberUsage (methods
, "method");
2194 CheckMemberUsage (constants
, "constant");
2196 if (fields
!= null){
2197 foreach (FieldBase f
in fields
) {
2198 if ((f
.ModFlags
& Modifiers
.Accessibility
) != Modifiers
.PRIVATE
)
2202 if ((f
.caching_flags
& Flags
.IsAssigned
) == 0)
2203 Report
.Warning (169, 3, f
.Location
, "The private field `{0}' is never used", f
.GetSignatureForError ());
2206 const int error_code
= 414;
2208 const int error_code
= 169;
2210 Report
.Warning (error_code
, 3, f
.Location
, "The private field `{0}' is assigned but its value is never used",
2211 f
.GetSignatureForError ());
2217 // Only report 649 on level 4
2219 if (RootContext
.WarningLevel
< 4)
2222 if ((f
.caching_flags
& Flags
.IsAssigned
) != 0)
2225 Constant c
= New
.Constantify (f
.Type
.Type
);
2226 Report
.Warning (649, 4, f
.Location
, "Field `{0}' is never assigned to, and will always have its default value `{1}'",
2227 f
.GetSignatureForError (), c
== null ? "null" : c
.AsString ());
2233 // TODO: move to ClassOrStruct
2234 void EmitConstructors ()
2236 if (instance_constructors
== null)
2239 if (TypeBuilder
.IsSubclassOf (TypeManager
.attribute_type
) && RootContext
.VerifyClsCompliance
&& IsClsComplianceRequired ()) {
2240 bool has_compliant_args
= false;
2242 foreach (Constructor c
in instance_constructors
) {
2246 catch (Exception e
) {
2247 throw new InternalErrorException (c
, e
);
2250 if (has_compliant_args
)
2253 has_compliant_args
= c
.HasCompliantArgs
;
2255 if (!has_compliant_args
)
2256 Report
.Error (3015, Location
, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2258 foreach (Constructor c
in instance_constructors
) {
2262 catch (Exception e
) {
2263 throw new InternalErrorException (c
, e
);
2270 /// Emits the code, this step is performed after all
2271 /// the types, enumerations, constructors
2273 public virtual void EmitType ()
2275 if (OptAttributes
!= null)
2276 OptAttributes
.Emit ();
2280 int offset
= CountTypeParameters
- CurrentTypeParameters
.Length
;
2281 for (int i
= offset
; i
< gen_params
.Length
; i
++)
2282 CurrentTypeParameters
[i
- offset
].EmitAttributes ();
2287 // Structs with no fields need to have at least one byte.
2288 // The right thing would be to set the PackingSize in a DefineType
2289 // but there are no functions that allow interfaces *and* the size to
2293 if (Kind
== Kind
.Struct
&& first_nonstatic_field
== null){
2294 FieldBuilder fb
= TypeBuilder
.DefineField ("$PRIVATE$", TypeManager
.byte_type
,
2295 FieldAttributes
.Private
);
2297 if (HasExplicitLayout
){
2298 object [] ctor_args
= new object [1];
2301 CustomAttributeBuilder cba
= new CustomAttributeBuilder (
2302 TypeManager
.field_offset_attribute_ctor
, ctor_args
);
2303 fb
.SetCustomAttribute (cba
);
2309 EmitConstructors ();
2311 // Can not continue if constants are broken
2313 if (Report
.Errors
> 0)
2316 if (default_static_constructor
!= null)
2317 default_static_constructor
.Emit ();
2319 if (methods
!= null){
2320 for (int i
= 0; i
< methods
.Count
; ++i
)
2321 ((Method
)methods
[i
]).Emit ();
2324 if (operators
!= null)
2325 foreach (Operator o
in operators
)
2328 if (properties
!= null)
2329 foreach (Property p
in properties
)
2332 if (indexers
!= null) {
2333 foreach (Indexer indx
in indexers
)
2339 foreach (FieldBase f
in fields
)
2342 if (events
!= null){
2343 foreach (Event e
in Events
)
2347 if (delegates
!= null) {
2348 foreach (Delegate d
in Delegates
) {
2353 if (pending
!= null)
2354 if (pending
.VerifyPendingMethods ())
2357 if (Report
.Errors
> 0)
2360 if (compiler_generated
!= null) {
2361 foreach (CompilerGeneratedClass c
in compiler_generated
) {
2362 if (!c
.DefineMembers ())
2363 throw new InternalErrorException ();
2365 foreach (CompilerGeneratedClass c
in compiler_generated
)
2370 public override void CloseType ()
2372 if ((caching_flags
& Flags
.CloseTypeCreated
) != 0)
2376 caching_flags
|= Flags
.CloseTypeCreated
;
2377 TypeBuilder
.CreateType ();
2378 } catch (TypeLoadException
){
2380 // This is fine, the code still created the type
2382 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2383 // Console.WriteLine (e.Message);
2384 } catch (Exception e
) {
2385 throw new InternalErrorException (this, e
);
2389 foreach (TypeContainer tc
in Types
)
2390 if (tc
.Kind
== Kind
.Struct
)
2393 foreach (TypeContainer tc
in Types
)
2394 if (tc
.Kind
!= Kind
.Struct
)
2398 if (Delegates
!= null)
2399 foreach (Delegate d
in Delegates
)
2402 if (CompilerGenerated
!= null)
2403 foreach (CompilerGeneratedClass c
in CompilerGenerated
)
2410 initialized_fields
= null;
2411 initialized_static_fields
= null;
2413 ordered_explicit_member_list
= null;
2414 ordered_member_list
= null;
2419 compiler_generated
= null;
2420 default_constructor
= null;
2421 default_static_constructor
= null;
2423 OptAttributes
= null;
2426 member_cache
= null;
2430 // Performs the validation on a Method's modifiers (properties have
2431 // the same properties).
2433 public bool MethodModifiersValid (MemberCore mc
)
2435 const int vao
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
| Modifiers
.OVERRIDE
);
2436 const int va
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
);
2437 const int nv
= (Modifiers
.NEW
| Modifiers
.VIRTUAL
);
2439 int flags
= mc
.ModFlags
;
2442 // At most one of static, virtual or override
2444 if ((flags
& Modifiers
.STATIC
) != 0){
2445 if ((flags
& vao
) != 0){
2446 Report
.Error (112, mc
.Location
, "A static member `{0}' cannot be marked as override, virtual or abstract",
2447 mc
.GetSignatureForError ());
2452 if (Kind
== Kind
.Struct
){
2453 if ((flags
& va
) != 0){
2454 Modifiers
.Error_InvalidModifier (mc
.Location
, "virtual or abstract");
2459 if ((flags
& Modifiers
.OVERRIDE
) != 0 && (flags
& nv
) != 0){
2460 Report
.Error (113, mc
.Location
, "A member `{0}' marked as override cannot be marked as new or virtual",
2461 mc
.GetSignatureForError ());
2466 // If the declaration includes the abstract modifier, then the
2467 // declaration does not include static, virtual or extern
2469 if ((flags
& Modifiers
.ABSTRACT
) != 0){
2470 if ((flags
& Modifiers
.EXTERN
) != 0){
2472 180, mc
.Location
, "`{0}' cannot be both extern and abstract", mc
.GetSignatureForError ());
2476 if ((flags
& Modifiers
.SEALED
) != 0) {
2477 Report
.Error (502, mc
.Location
, "`{0}' cannot be both abstract and sealed", mc
.GetSignatureForError ());
2481 if ((flags
& Modifiers
.VIRTUAL
) != 0){
2482 Report
.Error (503, mc
.Location
, "The abstract method `{0}' cannot be marked virtual", mc
.GetSignatureForError ());
2486 if ((ModFlags
& Modifiers
.ABSTRACT
) == 0){
2487 Report
.SymbolRelatedToPreviousError (this);
2488 Report
.Error (513, mc
.Location
, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2489 mc
.GetSignatureForError (), GetSignatureForError ());
2494 if ((flags
& Modifiers
.PRIVATE
) != 0){
2495 if ((flags
& vao
) != 0){
2496 Report
.Error (621, mc
.Location
, "`{0}': virtual or abstract members cannot be private", mc
.GetSignatureForError ());
2501 if ((flags
& Modifiers
.SEALED
) != 0){
2502 if ((flags
& Modifiers
.OVERRIDE
) == 0){
2503 Report
.Error (238, mc
.Location
, "`{0}' cannot be sealed because it is not an override", mc
.GetSignatureForError ());
2511 public Constructor DefaultStaticConstructor
{
2512 get { return default_static_constructor; }
2515 protected override bool VerifyClsCompliance ()
2517 if (!base.VerifyClsCompliance ())
2522 Type base_type
= TypeBuilder
.BaseType
;
2523 if (base_type
!= null && !AttributeTester
.IsClsCompliant (base_type
)) {
2524 Report
.Error (3009, Location
, "`{0}': base type `{1}' is not CLS-compliant", GetSignatureForError (), TypeManager
.CSharpName (base_type
));
2531 /// Checks whether container name is CLS Compliant
2533 void VerifyClsName ()
2535 Hashtable base_members
= base_cache
== null ?
2537 base_cache
.GetPublicMembers ();
2538 Hashtable this_members
= new Hashtable ();
2540 foreach (DictionaryEntry entry
in defined_names
) {
2541 MemberCore mc
= (MemberCore
)entry
.Value
;
2542 if (!mc
.IsClsComplianceRequired ())
2545 string name
= (string) entry
.Key
;
2546 string basename
= name
.Substring (name
.LastIndexOf ('.') + 1);
2548 string lcase
= basename
.ToLower (System
.Globalization
.CultureInfo
.InvariantCulture
);
2549 object found
= base_members
[lcase
];
2550 if (found
== null) {
2551 found
= this_members
[lcase
];
2552 if (found
== null) {
2553 this_members
.Add (lcase
, mc
);
2558 if ((mc
.ModFlags
& Modifiers
.OVERRIDE
) != 0)
2561 if (found
is MemberInfo
) {
2562 if (basename
== ((MemberInfo
) found
).Name
)
2564 Report
.SymbolRelatedToPreviousError ((MemberInfo
) found
);
2566 Report
.SymbolRelatedToPreviousError ((MemberCore
) found
);
2569 Report
.Warning (3005, 1, mc
.Location
, "Identifier `{0}' differing only in case is not CLS-compliant", mc
.GetSignatureForError ());
2571 Report
.Error (3005, mc
.Location
, "Identifier `{0}' differing only in case is not CLS-compliant", mc
.GetSignatureForError ());
2578 /// Performs checks for an explicit interface implementation. First it
2579 /// checks whether the `interface_type' is a base inteface implementation.
2580 /// Then it checks whether `name' exists in the interface type.
2582 public virtual bool VerifyImplements (InterfaceMemberBase mb
)
2584 if (ifaces
!= null) {
2585 foreach (Type t
in ifaces
){
2586 if (t
== mb
.InterfaceType
)
2591 Report
.SymbolRelatedToPreviousError (mb
.InterfaceType
);
2592 Report
.Error (540, mb
.Location
, "`{0}': containing type does not implement interface `{1}'",
2593 mb
.GetSignatureForError (), TypeManager
.CSharpName (mb
.InterfaceType
));
2597 public override Type
LookupAnyGeneric (string typeName
)
2599 if (types
!= null) {
2600 foreach (TypeContainer tc
in types
) {
2604 int pos
= tc
.Basename
.LastIndexOf ('`');
2605 if (pos
== typeName
.Length
&& String
.Compare (typeName
, 0, tc
.Basename
, 0, pos
) == 0)
2606 return tc
.TypeBuilder
;
2610 return base.LookupAnyGeneric (typeName
);
2613 public void Mark_HasEquals ()
2615 cached_method
|= CachedMethods
.Equals
;
2618 public void Mark_HasGetHashCode ()
2620 cached_method
|= CachedMethods
.GetHashCode
;
2624 /// Method container contains Equals method
2626 public bool HasEquals
{
2628 return (cached_method
& CachedMethods
.Equals
) != 0;
2633 /// Method container contains GetHashCode method
2635 public bool HasGetHashCode
{
2637 return (cached_method
& CachedMethods
.GetHashCode
) != 0;
2645 string IMemberContainer
.Name
{
2651 Type IMemberContainer
.Type
{
2657 MemberCache IMemberContainer
.MemberCache
{
2659 return member_cache
;
2663 bool IMemberContainer
.IsInterface
{
2665 return Kind
== Kind
.Interface
;
2669 MemberList IMemberContainer
.GetMembers (MemberTypes mt
, BindingFlags bf
)
2671 BindingFlags new_bf
= bf
| BindingFlags
.DeclaredOnly
;
2673 if (GenericType
!= null)
2674 return TypeManager
.FindMembers (GenericType
, mt
, new_bf
,
2677 return FindMembers (mt
, new_bf
, null, null);
2681 // Generates xml doc comments (if any), and if required,
2682 // handle warning report.
2684 internal override void GenerateDocComment (DeclSpace ds
)
2686 DocUtil
.GenerateTypeDocComment (this, ds
);
2689 public override string DocCommentHeader
{
2690 get { return "T:"; }
2693 public virtual MemberCache BaseCache
{
2695 if (base_cache
!= null)
2697 if (TypeBuilder
.BaseType
!= null)
2698 base_cache
= TypeManager
.LookupMemberCache (TypeBuilder
.BaseType
);
2699 if (TypeBuilder
.IsInterface
)
2700 base_cache
= TypeManager
.LookupBaseInterfacesCache (TypeBuilder
);
2705 private IDictionary anonymous_types
;
2706 public IDictionary AnonymousTypes
{
2708 if (anonymous_types
== null)
2709 anonymous_types
= new HybridDictionary();
2710 return anonymous_types
;
2715 public abstract class ClassOrStruct
: TypeContainer
{
2716 ListDictionary declarative_security
;
2718 public ClassOrStruct (NamespaceEntry ns
, DeclSpace parent
,
2719 MemberName name
, Attributes attrs
, Kind kind
)
2720 : base (ns
, parent
, name
, attrs
, kind
)
2724 protected override bool AddToContainer (MemberCore symbol
, string name
)
2726 if (name
== MemberName
.Name
) {
2727 if (symbol
is TypeParameter
) {
2728 Report
.Error (694, symbol
.Location
,
2729 "Type parameter `{0}' has same name as " +
2730 "containing type, or method", name
);
2734 Report
.SymbolRelatedToPreviousError (this);
2735 Report
.Error (542, symbol
.Location
, "`{0}': member names cannot be the same as their enclosing type",
2736 symbol
.GetSignatureForError ());
2740 return base.AddToContainer (symbol
, name
);
2743 public override void VerifyMembers ()
2745 base.VerifyMembers ();
2747 if ((events
!= null) && (RootContext
.WarningLevel
>= 3)) {
2748 foreach (Event e
in events
){
2749 if ((e
.ModFlags
& Modifiers
.Accessibility
) != Modifiers
.PRIVATE
)
2752 if ((e
.caching_flags
& Flags
.IsUsed
) == 0)
2753 Report
.Warning (67, 3, e
.Location
, "The event `{0}' is never used", e
.GetSignatureForError ());
2758 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
2760 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
2761 if (declarative_security
== null)
2762 declarative_security
= new ListDictionary ();
2764 a
.ExtractSecurityPermissionSet (declarative_security
);
2768 if (a
.Type
== TypeManager
.struct_layout_attribute_type
&& a
.GetLayoutKindValue () == LayoutKind
.Explicit
) {
2769 HasExplicitLayout
= true;
2772 base.ApplyAttributeBuilder (a
, cb
);
2776 /// Defines the default constructors
2778 protected void DefineDefaultConstructor (bool is_static
)
2780 // The default instance constructor is public
2781 // If the class is abstract, the default constructor is protected
2782 // The default static constructor is private
2786 mods
= Modifiers
.STATIC
| Modifiers
.PRIVATE
;
2788 mods
= ((ModFlags
& Modifiers
.ABSTRACT
) != 0) ? Modifiers
.PROTECTED
: Modifiers
.PUBLIC
;
2791 Constructor c
= new Constructor (this, MemberName
.Name
, mods
,
2792 Parameters
.EmptyReadOnlyParameters
,
2793 new GeneratedBaseInitializer (Location
),
2797 c
.Block
= new ToplevelBlock (null, Location
);
2800 void DefineFieldInitializers ()
2802 if (initialized_fields
!= null) {
2803 for (int i
= 0; i
< initialized_fields
.Count
; ++i
) {
2804 FieldInitializer fi
= (FieldInitializer
)initialized_fields
[i
];
2806 EmitContext ec
= new EmitContext (fi
.TypeContainer
, fi
.TypeContainer
,
2807 Location
, null, null, ModFlags
);
2808 ec
.IsFieldInitializer
= true;
2810 fi
.ResolveStatement (ec
);
2811 if (fi
.IsDefaultInitializer
&& RootContext
.Optimize
) {
2812 // Field is re-initialized to its default value => removed
2813 initialized_fields
.RemoveAt (i
);
2819 if (initialized_static_fields
!= null) {
2820 bool has_complex_initializer
= false;
2822 foreach (FieldInitializer fi
in initialized_static_fields
) {
2823 EmitContext ec
= new EmitContext (fi
.TypeContainer
, fi
.TypeContainer
,
2824 Location
, null, null, ModFlags
);
2826 ec
.IsFieldInitializer
= true;
2828 fi
.ResolveStatement (ec
);
2829 if (!fi
.IsComplexInitializer
)
2832 has_complex_initializer
= true;
2835 // Need special check to not optimize code like this
2836 // static int a = b = 5;
2837 // static int b = 0;
2838 if (!has_complex_initializer
&& RootContext
.Optimize
) {
2839 for (int i
= 0; i
< initialized_static_fields
.Count
; ++i
) {
2840 FieldInitializer fi
= (FieldInitializer
)initialized_static_fields
[i
];
2841 if (fi
.IsDefaultInitializer
) {
2842 initialized_static_fields
.RemoveAt (i
);
2848 if (default_static_constructor
== null && initialized_static_fields
.Count
> 0) {
2849 DefineDefaultConstructor (true);
2855 public override bool Define ()
2857 DefineFieldInitializers ();
2859 if (default_static_constructor
!= null)
2860 default_static_constructor
.Define ();
2862 return base.Define ();
2865 public override void Emit ()
2869 if (declarative_security
!= null) {
2870 foreach (DictionaryEntry de
in declarative_security
) {
2871 TypeBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
2876 public override ExtensionMethodGroupExpr
LookupExtensionMethod (Type extensionType
, string name
)
2878 return NamespaceEntry
.LookupExtensionMethod (extensionType
, this, name
);
2881 protected override TypeAttributes TypeAttr
{
2883 if (default_static_constructor
== null)
2884 return base.TypeAttr
| TypeAttributes
.BeforeFieldInit
;
2886 return base.TypeAttr
;
2892 // TODO: should be sealed
2893 public class Class
: ClassOrStruct
{
2894 const int AllowedModifiers
=
2897 Modifiers
.PROTECTED
|
2898 Modifiers
.INTERNAL
|
2900 Modifiers
.ABSTRACT
|
2905 public const TypeAttributes StaticClassAttribute
= TypeAttributes
.Abstract
| TypeAttributes
.Sealed
;
2907 public Class (NamespaceEntry ns
, DeclSpace parent
, MemberName name
, int mod
,
2909 : base (ns
, parent
, name
, attrs
, Kind
.Class
)
2911 int accmods
= Parent
.Parent
== null ? Modifiers
.INTERNAL
: Modifiers
.PRIVATE
;
2912 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, Location
);
2914 if (IsStatic
&& RootContext
.Version
== LanguageVersion
.ISO_1
) {
2915 Report
.FeatureIsNotISO1 (Location
, "static classes");
2919 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
2921 if (a
.Type
== TypeManager
.attribute_usage_type
) {
2922 if (BaseType
!= TypeManager
.attribute_type
&& !BaseType
.IsSubclassOf (TypeManager
.attribute_type
) &&
2923 TypeBuilder
.FullName
!= "System.Attribute") {
2924 Report
.Error (641, a
.Location
, "Attribute `{0}' is only valid on classes derived from System.Attribute", a
.GetSignatureForError ());
2928 if (a
.Type
== TypeManager
.conditional_attribute_type
&&
2929 !(BaseType
== TypeManager
.attribute_type
|| BaseType
.IsSubclassOf (TypeManager
.attribute_type
))) {
2930 Report
.Error (1689, a
.Location
, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2934 if (a
.Type
== TypeManager
.comimport_attr_type
&&
2935 !attributes
.Contains (TypeManager
.guid_attr_type
)) {
2936 a
.Error_MissingGuidAttribute ();
2940 if (a
.Type
== TypeManager
.extension_attribute_type
) {
2941 a
.Error_MisusedExtensionAttribute ();
2945 if (AttributeTester
.IsAttributeExcluded (a
.Type
))
2948 base.ApplyAttributeBuilder (a
, cb
);
2951 public override AttributeTargets AttributeTargets
{
2953 return AttributeTargets
.Class
;
2957 protected override void DefineContainerMembers (MemberCoreArrayList list
)
2963 base.DefineContainerMembers (list
);
2967 foreach (MemberCore m
in list
) {
2968 if (m
is Operator
) {
2969 Report
.Error (715, m
.Location
, "`{0}': Static classes cannot contain user-defined operators", m
.GetSignatureForError ());
2973 if (m
is Destructor
) {
2974 Report
.Error (711, m
.Location
, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2978 if ((m
.ModFlags
& Modifiers
.PROTECTED
) != 0) {
2979 Report
.Error (1057, m
.Location
, "`{0}': Static classes cannot contain protected members", m
.GetSignatureForError ());
2984 Report
.Error (720, m
.Location
, "`{0}': cannot declare indexers in a static class", m
.GetSignatureForError ());
2988 if ((m
.ModFlags
& Modifiers
.STATIC
) != 0 || m
is Enum
|| m
is Delegate
)
2991 if (m
is Constructor
) {
2992 Report
.Error (710, m
.Location
, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2996 Method method
= m
as Method
;
2997 if (method
!= null && method
.Parameters
.HasExtensionMethodType
) {
2998 Report
.Error (1105, m
.Location
, "`{0}': Extension methods must be declared static", m
.GetSignatureForError ());
3002 Report
.Error (708, m
.Location
, "`{0}': cannot declare instance members in a static class", m
.GetSignatureForError ());
3005 base.DefineContainerMembers (list
);
3008 public override TypeBuilder
DefineType ()
3010 if ((ModFlags
& Modifiers
.ABSTRACT
) == Modifiers
.ABSTRACT
&& (ModFlags
& (Modifiers
.SEALED
| Modifiers
.STATIC
)) != 0) {
3011 Report
.Error (418, Location
, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
3015 if ((ModFlags
& (Modifiers
.SEALED
| Modifiers
.STATIC
)) == (Modifiers
.SEALED
| Modifiers
.STATIC
)) {
3016 Report
.Error (441, Location
, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
3020 return base.DefineType ();
3023 protected override bool DoDefineMembers ()
3025 if (InstanceConstructors
== null && !IsStatic
)
3026 DefineDefaultConstructor (false);
3028 return base.DoDefineMembers ();
3031 public override void Emit ()
3035 if ((ModFlags
& Modifiers
.METHOD_EXTENSION
) != 0)
3036 TypeBuilder
.SetCustomAttribute (TypeManager
.extension_attribute_attr
);
3039 public override TypeExpr
[] GetClassBases (out TypeExpr base_class
)
3041 TypeExpr
[] ifaces
= base.GetClassBases (out base_class
);
3043 if (base_class
== null) {
3044 if (RootContext
.StdLib
)
3045 base_class
= TypeManager
.system_object_expr
;
3046 else if (Name
!= "System.Object")
3047 base_class
= TypeManager
.system_object_expr
;
3049 if (Kind
== Kind
.Class
&& base_class
is TypeParameterExpr
){
3051 689, base_class
.Location
,
3052 "Cannot derive from `{0}' because it is a type parameter",
3053 base_class
.GetSignatureForError ());
3057 if (base_class
.Type
.IsArray
|| base_class
.Type
.IsPointer
) {
3058 Report
.Error (1521, base_class
.Location
, "Invalid base type");
3062 if (base_class
.IsSealed
){
3063 Report
.SymbolRelatedToPreviousError (base_class
.Type
);
3064 if (base_class
.Type
.IsAbstract
) {
3065 Report
.Error (709, Location
, "`{0}': Cannot derive from static class `{1}'",
3066 GetSignatureForError (), TypeManager
.CSharpName (base_class
.Type
));
3068 Report
.Error (509, Location
, "`{0}': cannot derive from sealed class `{1}'",
3069 GetSignatureForError (), TypeManager
.CSharpName (base_class
.Type
));
3074 if (!base_class
.CanInheritFrom ()){
3075 Report
.Error (644, Location
, "`{0}' cannot derive from special class `{1}'",
3076 GetSignatureForError (), base_class
.GetSignatureForError ());
3080 if (!base_class
.AsAccessible (this, ModFlags
)) {
3081 Report
.SymbolRelatedToPreviousError (base_class
.Type
);
3082 Report
.Error (60, Location
, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
3083 TypeManager
.CSharpName (base_class
.Type
), GetSignatureForError ());
3088 if (base_class
!= TypeManager
.system_object_expr
) {
3089 Report
.Error (713, Location
, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
3090 GetSignatureForError (), base_class
.GetSignatureForError ());
3094 if (ifaces
!= null) {
3095 foreach (TypeExpr t
in ifaces
)
3096 Report
.SymbolRelatedToPreviousError (t
.Type
);
3097 Report
.Error (714, Location
, "`{0}': static classes cannot implement interfaces", GetSignatureForError ());
3104 /// Search for at least one defined condition in ConditionalAttribute of attribute class
3105 /// Valid only for attribute classes.
3106 public bool IsExcluded ()
3108 if ((caching_flags
& Flags
.Excluded_Undetected
) == 0)
3109 return (caching_flags
& Flags
.Excluded
) != 0;
3111 caching_flags
&= ~Flags
.Excluded_Undetected
;
3113 if (OptAttributes
== null)
3116 Attribute
[] attrs
= OptAttributes
.SearchMulti (TypeManager
.conditional_attribute_type
);
3121 foreach (Attribute a
in attrs
) {
3122 string condition
= a
.GetConditionalAttributeValue ();
3123 if (RootContext
.AllDefines
.Contains (condition
))
3127 caching_flags
|= Flags
.Excluded
;
3133 return (ModFlags
& Modifiers
.STATIC
) != 0;
3138 // FIXME: How do we deal with the user specifying a different
3141 protected override TypeAttributes TypeAttr
{
3143 TypeAttributes ta
= base.TypeAttr
| TypeAttributes
.AutoLayout
| TypeAttributes
.Class
;
3145 ta
|= StaticClassAttribute
;
3151 public sealed class Struct
: ClassOrStruct
{
3153 // Modifiers allowed in a struct declaration
3155 const int AllowedModifiers
=
3158 Modifiers
.PROTECTED
|
3159 Modifiers
.INTERNAL
|
3163 public Struct (NamespaceEntry ns
, DeclSpace parent
, MemberName name
,
3164 int mod
, Attributes attrs
)
3165 : base (ns
, parent
, name
, attrs
, Kind
.Struct
)
3169 if (parent
.Parent
== null)
3170 accmods
= Modifiers
.INTERNAL
;
3172 accmods
= Modifiers
.PRIVATE
;
3174 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, Location
);
3176 this.ModFlags
|= Modifiers
.SEALED
;
3179 public override AttributeTargets AttributeTargets
{
3181 return AttributeTargets
.Struct
;
3185 const TypeAttributes DefaultTypeAttributes
=
3186 TypeAttributes
.SequentialLayout
|
3187 TypeAttributes
.Sealed
|
3188 TypeAttributes
.BeforeFieldInit
;
3191 public override TypeExpr
[] GetClassBases (out TypeExpr base_class
)
3193 TypeExpr
[] ifaces
= base.GetClassBases (out base_class
);
3195 // If we are compiling our runtime,
3196 // and we are defining ValueType, then our
3197 // base is `System.Object'.
3199 if (base_class
== null) {
3200 if (!RootContext
.StdLib
&& Name
== "System.ValueType")
3201 base_class
= TypeManager
.system_object_expr
;
3203 base_class
= TypeManager
.system_valuetype_expr
;
3210 // FIXME: Allow the user to specify a different set of attributes
3211 // in some cases (Sealed for example is mandatory for a class,
3212 // but what SequentialLayout can be changed
3214 protected override TypeAttributes TypeAttr
{
3216 return base.TypeAttr
| DefaultTypeAttributes
;
3220 public override void RegisterFieldForInitialization (MemberCore field
, FieldInitializer expression
)
3222 if ((field
.ModFlags
& Modifiers
.STATIC
) == 0) {
3223 Report
.Error (573, field
.Location
, "`{0}': Structs cannot have instance field initializers",
3224 field
.GetSignatureForError ());
3227 base.RegisterFieldForInitialization (field
, expression
);
3235 public sealed class Interface
: TypeContainer
, IMemberContainer
{
3238 /// Modifiers allowed in a class declaration
3240 public const int AllowedModifiers
=
3243 Modifiers
.PROTECTED
|
3244 Modifiers
.INTERNAL
|
3248 public Interface (NamespaceEntry ns
, DeclSpace parent
, MemberName name
, int mod
,
3250 : base (ns
, parent
, name
, attrs
, Kind
.Interface
)
3254 if (parent
.Parent
== null)
3255 accmods
= Modifiers
.INTERNAL
;
3257 accmods
= Modifiers
.PRIVATE
;
3259 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, name
.Location
);
3262 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
3264 if (a
.Type
== TypeManager
.comimport_attr_type
&&
3265 !attributes
.Contains (TypeManager
.guid_attr_type
)) {
3266 a
.Error_MissingGuidAttribute ();
3269 base.ApplyAttributeBuilder (a
, cb
);
3273 public override AttributeTargets AttributeTargets
{
3275 return AttributeTargets
.Interface
;
3279 const TypeAttributes DefaultTypeAttributes
=
3280 TypeAttributes
.AutoLayout
|
3281 TypeAttributes
.Abstract
|
3282 TypeAttributes
.Interface
;
3284 protected override TypeAttributes TypeAttr
{
3286 return base.TypeAttr
| DefaultTypeAttributes
;
3290 protected override bool VerifyClsCompliance ()
3292 if (!base.VerifyClsCompliance ())
3295 if (ifaces
!= null) {
3296 foreach (Type t
in ifaces
) {
3297 if (AttributeTester
.IsClsCompliant (t
))
3300 Report
.SymbolRelatedToPreviousError (t
);
3301 Report
.Warning (3027, 1, Location
, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3302 GetSignatureForError (), TypeManager
.CSharpName (t
));
3310 // It is used as a base class for all property based members
3311 // This includes properties, indexers, and events
3312 public abstract class PropertyBasedMember
: InterfaceMemberBase
3314 public PropertyBasedMember (DeclSpace parent
, GenericMethod generic
,
3315 Expression type
, int mod
, int allowed_mod
, bool is_iface
,
3316 MemberName name
, Attributes attrs
)
3317 : base (parent
, generic
, type
, mod
, allowed_mod
, is_iface
, name
, attrs
)
3321 protected override bool CheckForDuplications ()
3323 throw new NotSupportedException ();
3326 protected override bool VerifyClsCompliance ()
3328 if (!base.VerifyClsCompliance ())
3331 if (!AttributeTester
.IsClsCompliant (MemberType
)) {
3332 Report
.Error (3003, Location
, "Type of `{0}' is not CLS-compliant",
3333 GetSignatureForError ());
3341 public abstract class MethodCore
: InterfaceMemberBase
3343 public readonly Parameters Parameters
;
3344 protected ToplevelBlock block
;
3346 public MethodCore (DeclSpace parent
, GenericMethod generic
,
3347 Expression type
, int mod
, int allowed_mod
, bool is_iface
,
3348 MemberName name
, Attributes attrs
, Parameters parameters
)
3349 : base (parent
, generic
, type
, mod
, allowed_mod
, is_iface
, name
, attrs
)
3351 Parameters
= parameters
;
3355 // Returns the System.Type array for the parameters of this method
3357 public Type
[] ParameterTypes
{
3359 return Parameters
.Types
;
3363 public Parameters ParameterInfo
3370 public ToplevelBlock Block
{
3380 protected override bool CheckBase ()
3382 // Check whether arguments were correct.
3383 if (!DefineParameters (Parameters
))
3386 if (!base.CheckBase ())
3392 // TODO: create a special method for operators only to make code better
3393 protected bool IsDuplicateImplementation (MethodCore method
)
3398 Operator op2
= null;
3399 Operator op1
= null;
3401 if (!(method
.MemberName
.Equals (MemberName
)))
3403 op1
= this as Operator
;
3404 if (op1
== null || !(op1
.OperatorType
== Operator
.OpType
.Explicit
|| op1
.OperatorType
== Operator
.OpType
.Implicit
))
3407 op2
= method
as Operator
;
3408 if (op2
== null || !(op2
.OperatorType
== Operator
.OpType
.Explicit
|| op2
.OperatorType
== Operator
.OpType
.Implicit
))
3411 op1
= this as Operator
;
3412 op2
= method
as Operator
;
3415 Type
[] param_types
= method
.ParameterTypes
;
3416 // This never happen. Rewrite this as Equal
3417 if (param_types
== null && ParameterTypes
== null)
3419 if (param_types
== null || ParameterTypes
== null)
3422 if (param_types
.Length
!= ParameterTypes
.Length
)
3425 if (method
.Parameters
.HasArglist
!= Parameters
.HasArglist
)
3430 for (int i
= 0; i
< param_types
.Length
; i
++) {
3431 if (param_types
[i
] != ParameterTypes
[i
])
3435 if (IsExplicitImpl
&& (method
.InterfaceType
!= InterfaceType
))
3438 // TODO: make operator compatible with MethodCore to avoid this
3439 if (op1
!= null && op2
!= null) {
3440 if (MemberType
!= method
.MemberType
)
3446 // Try to report 663: method only differs on out/ref
3448 Parameters info
= ParameterInfo
;
3449 Parameters other_info
= method
.ParameterInfo
;
3450 for (int i
= 0; i
< info
.Count
; i
++){
3451 if (info
.ParameterModifier (i
) != other_info
.ParameterModifier (i
)){
3452 Report
.SymbolRelatedToPreviousError (method
);
3453 Report
.Error (663, Location
, "`{0}': Methods cannot differ only on their use of ref and out on a parameters",
3454 GetSignatureForError ());
3459 Report
.SymbolRelatedToPreviousError (method
);
3460 if (this is Operator
&& method
is Operator
)
3461 Report
.Error (557, Location
, "Duplicate user-defined conversion in type `{0}'", Parent
.Name
);
3463 Report
.Error (111, Location
, TypeContainer
.Error111
, GetSignatureForError ());
3472 // Returns a string that represents the signature for this
3473 // member which should be used in XML documentation.
3475 public override string GetDocCommentName (DeclSpace ds
)
3477 return DocUtil
.GetMethodDocCommentName (this, Parameters
, ds
);
3481 // Raised (and passed an XmlElement that contains the comment)
3482 // when GenerateDocComment is writing documentation expectedly.
3484 // FIXME: with a few effort, it could be done with XmlReader,
3485 // that means removal of DOM use.
3487 internal override void OnGenerateDocComment (XmlElement el
)
3489 DocUtil
.OnMethodGenerateDocComment (this, el
);
3493 // Represents header string for documentation comment.
3495 public override string DocCommentHeader
3497 get { return "M:"; }
3500 public virtual void SetYields ()
3502 ModFlags
|= Modifiers
.METHOD_YIELDS
;
3505 protected override bool VerifyClsCompliance ()
3507 if (!base.VerifyClsCompliance ())
3510 if (Parameters
.HasArglist
) {
3511 Report
.Error (3000, Location
, "Methods with variable arguments are not CLS-compliant");
3514 if (!AttributeTester
.IsClsCompliant (MemberType
)) {
3515 Report
.Error (3002, Location
, "Return type of `{0}' is not CLS-compliant",
3516 GetSignatureForError ());
3519 Parameters
.VerifyClsCompliance ();
3525 public abstract class InterfaceMemberBase
: MemberBase
{
3527 // Whether this is an interface member.
3529 public bool IsInterface
;
3532 // If true, this is an explicit interface implementation
3534 public bool IsExplicitImpl
;
3536 protected bool is_external_implementation
;
3539 // The interface type we are explicitly implementing
3541 public Type InterfaceType
;
3544 // The method we're overriding if this is an override method.
3546 protected MethodInfo base_method
;
3548 readonly int explicit_mod_flags
;
3549 public MethodAttributes flags
;
3551 public InterfaceMemberBase (DeclSpace parent
, GenericMethod generic
,
3552 Expression type
, int mod
, int allowed_mod
, bool is_iface
,
3553 MemberName name
, Attributes attrs
)
3554 : base (parent
, generic
, type
, mod
, allowed_mod
, Modifiers
.PRIVATE
,
3557 IsInterface
= is_iface
;
3558 IsExplicitImpl
= (MemberName
.Left
!= null);
3559 explicit_mod_flags
= mod
;
3562 protected override bool CheckBase ()
3564 if (!base.CheckBase ())
3567 if ((caching_flags
& Flags
.TestMethodDuplication
) != 0 && !CheckForDuplications ())
3573 // Is null for System.Object while compiling corlib and base interfaces
3574 if (Parent
.PartialContainer
.BaseCache
== null) {
3575 if ((ModFlags
& Modifiers
.NEW
) != 0) {
3576 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3581 Type base_ret_type
= null;
3582 base_method
= FindOutBaseMethod (ref base_ret_type
);
3584 // method is override
3585 if (base_method
!= null) {
3586 if (!CheckMethodAgainstBase (base_ret_type
))
3589 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3590 ObsoleteAttribute oa
= AttributeTester
.GetMethodObsoleteAttribute (base_method
);
3592 if (OptAttributes
== null || !OptAttributes
.Contains (TypeManager
.obsolete_attribute_type
)) {
3593 Report
.SymbolRelatedToPreviousError (base_method
);
3594 Report
.Warning (672, 1, Location
, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3595 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3598 if (OptAttributes
!= null && OptAttributes
.Contains (TypeManager
.obsolete_attribute_type
)) {
3599 Report
.Warning (809, 1, Location
, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3600 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3607 MemberInfo conflict_symbol
= Parent
.PartialContainer
.FindBaseMemberWithSameName (Name
, !((this is Event
) || (this is Property
)));
3608 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3609 if (conflict_symbol
!= null) {
3610 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
3612 Report
.Error (72, Location
, "`{0}': cannot override because `{1}' is not an event", GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3613 else if (this is PropertyBase
)
3614 Report
.Error (544, Location
, "`{0}': cannot override because `{1}' is not a property", GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3616 Report
.Error (505, Location
, "`{0}': cannot override because `{1}' is not a method", GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3618 Report
.Error (115, Location
, "`{0}' is marked as an override but no suitable {1} found to override",
3619 GetSignatureForError (), SimpleName
.GetMemberType (this));
3624 if (conflict_symbol
== null) {
3625 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0)) {
3626 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3631 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3632 if (this is Method
&& conflict_symbol
is MethodBase
)
3635 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
3636 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3637 GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3644 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3645 // that have been defined.
3647 // `name' is the user visible name for reporting errors (this is used to
3648 // provide the right name regarding method names and properties)
3650 bool CheckMethodAgainstBase (Type base_method_type
)
3654 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0){
3655 if (!(base_method
.IsAbstract
|| base_method
.IsVirtual
)){
3656 Report
.Error (506, Location
,
3657 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3658 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3662 // Now we check that the overriden method is not final
3664 if (base_method
.IsFinal
) {
3665 Report
.SymbolRelatedToPreviousError (base_method
);
3666 Report
.Error (239, Location
, "`{0}': cannot override inherited member `{1}' because it is sealed",
3667 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3671 // Check that the permissions are not being changed
3673 MethodAttributes thisp
= flags
& MethodAttributes
.MemberAccessMask
;
3674 MethodAttributes base_classp
= base_method
.Attributes
& MethodAttributes
.MemberAccessMask
;
3676 if (!CheckAccessModifiers (thisp
, base_classp
, base_method
)) {
3677 Error_CannotChangeAccessModifiers (base_method
, base_classp
, null);
3681 if (!TypeManager
.IsEqual (MemberType
, TypeManager
.TypeToCoreType (base_method_type
))) {
3682 Report
.SymbolRelatedToPreviousError (base_method
);
3683 if (this is PropertyBasedMember
) {
3684 Report
.Error (1715, Location
, "`{0}': type must be `{1}' to match overridden member `{2}'",
3685 GetSignatureForError (), TypeManager
.CSharpName (base_method_type
), TypeManager
.CSharpSignature (base_method
));
3688 Report
.Error (508, Location
, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3689 GetSignatureForError (), TypeManager
.CSharpName (base_method_type
), TypeManager
.CSharpSignature (base_method
));
3695 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3696 if ((ModFlags
& Modifiers
.OVERRIDE
) == 0 && Name
!= "Finalize") {
3697 ModFlags
|= Modifiers
.NEW
;
3698 Report
.SymbolRelatedToPreviousError (base_method
);
3699 if (!IsInterface
&& (base_method
.IsVirtual
|| base_method
.IsAbstract
)) {
3700 Report
.Warning (114, 2, Location
, "`{0}' hides inherited member `{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword",
3701 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3703 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3704 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3708 if (base_method
.IsAbstract
&& !IsInterface
) {
3709 Report
.SymbolRelatedToPreviousError (base_method
);
3710 Report
.Error (533, Location
, "`{0}' hides inherited abstract member `{1}'",
3711 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3719 protected bool CheckAccessModifiers (MethodAttributes thisp
, MethodAttributes base_classp
, MethodInfo base_method
)
3721 if ((base_classp
& MethodAttributes
.FamORAssem
) == MethodAttributes
.FamORAssem
){
3723 // when overriding protected internal, the method can be declared
3724 // protected internal only within the same assembly
3727 if ((thisp
& MethodAttributes
.FamORAssem
) == MethodAttributes
.FamORAssem
){
3728 if (Parent
.TypeBuilder
.Assembly
!= base_method
.DeclaringType
.Assembly
){
3730 // assemblies differ - report an error
3734 } else if (thisp
!= base_classp
) {
3736 // same assembly, but other attributes differ - report an error
3741 } else if ((thisp
& MethodAttributes
.Family
) != MethodAttributes
.Family
) {
3743 // if it's not "protected internal", it must be "protected"
3747 } else if (Parent
.TypeBuilder
.Assembly
== base_method
.DeclaringType
.Assembly
) {
3749 // protected within the same assembly - an error
3752 } else if ((thisp
& ~
(MethodAttributes
.Family
| MethodAttributes
.FamORAssem
)) !=
3753 (base_classp
& ~
(MethodAttributes
.Family
| MethodAttributes
.FamORAssem
))) {
3755 // protected ok, but other attributes differ - report an error
3761 return (thisp
== base_classp
);
3765 public bool CheckAbstractAndExtern (bool has_block
)
3767 if (Parent
.PartialContainer
.Kind
== Kind
.Interface
)
3771 if ((ModFlags
& Modifiers
.EXTERN
) != 0) {
3772 Report
.Error (179, Location
, "`{0}' cannot declare a body because it is marked extern",
3773 GetSignatureForError ());
3777 if ((ModFlags
& Modifiers
.ABSTRACT
) != 0) {
3778 Report
.Error (500, Location
, "`{0}' cannot declare a body because it is marked abstract",
3779 GetSignatureForError ());
3783 if ((ModFlags
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) == 0) {
3784 Report
.Error (501, Location
, "`{0}' must declare a body because it is not marked abstract or extern",
3785 GetSignatureForError ());
3793 protected bool DefineParameters (Parameters parameters
)
3795 IResolveContext rc
= GenericMethod
== null ? this : (IResolveContext
)ds
;
3797 if (!parameters
.Resolve (rc
))
3801 foreach (Parameter p
in parameters
.FixedParameters
) {
3802 if (p
.CheckAccessibility (this))
3805 Report
.SymbolRelatedToPreviousError (p
.ParameterType
);
3806 if (this is Indexer
)
3807 Report
.Error (55, Location
,
3808 "Inconsistent accessibility: parameter type `" +
3809 TypeManager
.CSharpName (p
.ParameterType
) + "' is less " +
3810 "accessible than indexer `" + GetSignatureForError () + "'");
3811 else if (this is Operator
)
3812 Report
.Error (57, Location
,
3813 "Inconsistent accessibility: parameter type `" +
3814 TypeManager
.CSharpName (p
.ParameterType
) + "' is less " +
3815 "accessible than operator `" + GetSignatureForError () + "'");
3817 Report
.Error (51, Location
,
3818 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3819 TypeManager
.CSharpName (p
.ParameterType
), GetSignatureForError ());
3825 protected override bool DoDefine()
3827 if (!base.DoDefine ())
3830 if (IsExplicitImpl
) {
3831 Expression expr
= MemberName
.Left
.GetTypeExpression ();
3832 TypeExpr texpr
= expr
.ResolveAsTypeTerminal (this, false);
3836 InterfaceType
= texpr
.Type
;
3838 if (!InterfaceType
.IsInterface
) {
3839 Report
.Error (538, Location
, "`{0}' in explicit interface declaration is not an interface", TypeManager
.CSharpName (InterfaceType
));
3843 if (!Parent
.PartialContainer
.VerifyImplements (this))
3850 protected virtual bool DoDefineBase ()
3853 throw new InternalErrorException ();
3856 ModFlags
= Modifiers
.PUBLIC
|
3857 Modifiers
.ABSTRACT
|
3858 Modifiers
.VIRTUAL
| (ModFlags
& Modifiers
.UNSAFE
) | (ModFlags
& Modifiers
.NEW
);
3860 flags
= MethodAttributes
.Public
|
3861 MethodAttributes
.Abstract
|
3862 MethodAttributes
.HideBySig
|
3863 MethodAttributes
.NewSlot
|
3864 MethodAttributes
.Virtual
;
3866 if (!Parent
.PartialContainer
.MethodModifiersValid (this))
3869 flags
= Modifiers
.MethodAttr (ModFlags
);
3872 if (IsExplicitImpl
) {
3873 Expression expr
= MemberName
.Left
.GetTypeExpression ();
3874 TypeExpr iface_texpr
= expr
.ResolveAsTypeTerminal (this, false);
3875 if (iface_texpr
== null)
3878 InterfaceType
= iface_texpr
.Type
;
3880 if (!InterfaceType
.IsInterface
) {
3881 Report
.Error (538, Location
, "'{0}' in explicit interface declaration is not an interface", TypeManager
.CSharpName (InterfaceType
));
3885 if (!Parent
.PartialContainer
.VerifyImplements (this))
3888 Modifiers
.Check (Modifiers
.AllowedExplicitImplFlags
, explicit_mod_flags
, 0, Location
);
3894 public override void Emit()
3896 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3897 // We are more strict than Microsoft and report CS0626 as error
3898 if ((ModFlags
& Modifiers
.EXTERN
) != 0 && !is_external_implementation
) {
3899 Report
.Error (626, Location
,
3900 "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3901 GetSignatureForError ());
3907 protected void Error_CannotChangeAccessModifiers (MemberInfo base_method
, MethodAttributes ma
, string suffix
)
3909 Report
.SymbolRelatedToPreviousError (base_method
);
3910 string base_name
= TypeManager
.GetFullNameSignature (base_method
);
3911 string this_name
= GetSignatureForError ();
3912 if (suffix
!= null) {
3913 base_name
+= suffix
;
3914 this_name
+= suffix
;
3917 Report
.Error (507, Location
, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3918 this_name
, Modifiers
.GetDescription (ma
), base_name
);
3921 protected static string Error722
{
3923 return "`{0}': static types cannot be used as return types";
3928 /// For custom member duplication search in a container
3930 protected abstract bool CheckForDuplications ();
3933 /// Gets base method and its return type
3935 protected abstract MethodInfo
FindOutBaseMethod (ref Type base_ret_type
);
3938 // The "short" name of this property / indexer / event. This is the
3939 // name without the explicit interface.
3941 public string ShortName
3943 get { return MemberName.Name; }
3944 set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
3947 protected override bool VerifyClsCompliance ()
3949 if (!base.VerifyClsCompliance ()) {
3950 if (IsInterface
&& HasClsCompliantAttribute
&& Parent
.IsClsComplianceRequired ()) {
3951 Report
.Error (3010, Location
, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
3954 if ((ModFlags
& Modifiers
.ABSTRACT
) != 0 && Parent
.TypeBuilder
.IsClass
&& IsExposedFromAssembly () && Parent
.IsClsComplianceRequired ()) {
3955 Report
.Error (3011, Location
, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3960 if (GenericMethod
!= null)
3961 GenericMethod
.VerifyClsCompliance ();
3966 public override bool IsUsed
3968 get { return IsExplicitImpl || base.IsUsed; }
3973 public abstract class MethodOrOperator
: MethodCore
, IMethodData
3975 public MethodBuilder MethodBuilder
;
3976 ReturnParameter return_attributes
;
3977 ListDictionary declarative_security
;
3978 protected MethodData MethodData
;
3981 ArrayList anonymous_methods
;
3983 static string[] attribute_targets
= new string [] { "method", "return" }
;
3985 protected MethodOrOperator (DeclSpace parent
, GenericMethod generic
, Expression type
, int mod
,
3986 int allowed_mod
, bool is_interface
, MemberName name
,
3987 Attributes attrs
, Parameters parameters
)
3988 : base (parent
, generic
, type
, mod
, allowed_mod
, is_interface
, name
,
3993 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
3995 if (a
.Target
== AttributeTargets
.ReturnValue
) {
3996 if (return_attributes
== null)
3997 return_attributes
= new ReturnParameter (MethodBuilder
, Location
);
3999 return_attributes
.ApplyAttributeBuilder (a
, cb
);
4003 if (a
.IsInternalMethodImplAttribute
) {
4004 is_external_implementation
= true;
4007 if (a
.Type
== TypeManager
.dllimport_type
) {
4008 const int extern_static
= Modifiers
.EXTERN
| Modifiers
.STATIC
;
4009 if ((ModFlags
& extern_static
) != extern_static
) {
4010 Report
.Error (601, a
.Location
, "The DllImport attribute must be specified on a method marked `static' and `extern'");
4012 is_external_implementation
= true;
4015 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
4016 if (declarative_security
== null)
4017 declarative_security
= new ListDictionary ();
4018 a
.ExtractSecurityPermissionSet (declarative_security
);
4022 MethodBuilder
.SetCustomAttribute (cb
);
4025 public override AttributeTargets AttributeTargets
{
4027 return AttributeTargets
.Method
;
4031 public virtual EmitContext
CreateEmitContext (DeclSpace tc
, ILGenerator ig
)
4033 return new EmitContext (
4034 this, tc
, this.ds
, Location
, ig
, MemberType
, ModFlags
, false);
4037 public void AddAnonymousMethod (AnonymousMethodExpression anonymous
)
4039 if (anonymous_methods
== null)
4040 anonymous_methods
= new ArrayList ();
4041 anonymous_methods
.Add (anonymous
);
4044 protected bool DefineGenericMethod ()
4046 if (!DoDefineBase ())
4050 if (GenericMethod
!= null) {
4051 string method_name
= MemberName
.Name
;
4053 if (IsExplicitImpl
) {
4054 method_name
= TypeManager
.CSharpName (InterfaceType
) +
4059 MethodBuilder
= Parent
.TypeBuilder
.DefineMethod (method_name
, flags
, ReturnType
, null);
4061 MethodBuilder
= Parent
.TypeBuilder
.DefineMethod (method_name
, flags
);
4064 if (!GenericMethod
.Define (MethodBuilder
, block
))
4072 public bool ResolveMembers ()
4074 if (!DefineGenericMethod ())
4077 if ((ModFlags
& Modifiers
.METHOD_YIELDS
) != 0) {
4078 iterator
= Iterator
.CreateIterator (this, Parent
, GenericMethod
, ModFlags
);
4079 if (iterator
== null)
4083 if (anonymous_methods
!= null) {
4084 foreach (AnonymousMethodExpression ame
in anonymous_methods
) {
4085 if (!ame
.CreateAnonymousHelpers ())
4093 public override bool Define ()
4098 if (!CheckAbstractAndExtern (block
!= null))
4104 MethodData
= new MethodData (
4105 this, ModFlags
, flags
, this, MethodBuilder
, GenericMethod
, base_method
);
4107 if (!MethodData
.Define (Parent
.PartialContainer
))
4110 MethodBuilder
= MethodData
.MethodBuilder
;
4112 if (!TypeManager
.IsGenericParameter (MemberType
)) {
4113 if (MemberType
.IsAbstract
&& MemberType
.IsSealed
) {
4114 Report
.Error (722, Location
, Error722
, TypeManager
.CSharpName (MemberType
));
4122 public override void Emit ()
4125 if ((ModFlags
& Modifiers
.COMPILER_GENERATED
) != 0)
4126 MethodBuilder
.SetCustomAttribute (TypeManager
.compiler_generated_attr
);
4128 if (OptAttributes
!= null)
4129 OptAttributes
.Emit ();
4131 if (declarative_security
!= null) {
4132 foreach (DictionaryEntry de
in declarative_security
) {
4133 MethodBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
4140 protected void Error_ConditionalAttributeIsNotValid ()
4142 Report
.Error (577, Location
,
4143 "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
4144 GetSignatureForError ());
4147 public override bool MarkForDuplicationCheck ()
4149 caching_flags
|= Flags
.TestMethodDuplication
;
4153 public override string[] ValidAttributeTargets
{
4155 return attribute_targets
;
4159 #region IMethodData Members
4161 public CallingConventions CallingConventions
{
4163 CallingConventions cc
= Parameters
.CallingConvention
;
4164 if (Parameters
.HasArglist
&& block
!= null)
4165 block
.HasVarargs
= true;
4168 if ((ModFlags
& Modifiers
.STATIC
) == 0)
4169 cc
|= CallingConventions
.HasThis
;
4171 // FIXME: How is `ExplicitThis' used in C#?
4177 public Type ReturnType
{
4183 public MemberName MethodName
{
4189 public Iterator Iterator
{
4190 get { return iterator; }
4193 public new Location Location
{
4195 return base.Location
;
4199 protected override bool CheckBase ()
4201 if (!base.CheckBase ())
4204 // TODO: Destructor should derive from MethodCore
4205 if (base_method
!= null && (ModFlags
& Modifiers
.OVERRIDE
) != 0 && Name
== "Finalize" &&
4206 base_method
.DeclaringType
== TypeManager
.object_type
&& !(this is Destructor
)) {
4207 Report
.Error (249, Location
, "Do not override object.Finalize. Instead, provide a destructor");
4215 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
4217 public bool IsExcluded () {
4218 if ((caching_flags
& Flags
.Excluded_Undetected
) == 0)
4219 return (caching_flags
& Flags
.Excluded
) != 0;
4221 caching_flags
&= ~Flags
.Excluded_Undetected
;
4223 if (base_method
== null) {
4224 if (OptAttributes
== null)
4227 Attribute
[] attrs
= OptAttributes
.SearchMulti (TypeManager
.conditional_attribute_type
);
4232 foreach (Attribute a
in attrs
) {
4233 string condition
= a
.GetConditionalAttributeValue ();
4234 if (condition
== null)
4237 if (RootContext
.AllDefines
.Contains (condition
))
4241 caching_flags
|= Flags
.Excluded
;
4245 IMethodData md
= TypeManager
.GetMethod (base_method
);
4247 if (AttributeTester
.IsConditionalMethodExcluded (base_method
)) {
4248 caching_flags
|= Flags
.Excluded
;
4254 if (md
.IsExcluded ()) {
4255 caching_flags
|= Flags
.Excluded
;
4261 GenericMethod IMethodData
.GenericMethod
{
4263 return GenericMethod
;
4271 public class SourceMethod
: ISourceMethod
4276 protected SourceMethod (DeclSpace parent
, MethodBase builder
,
4277 ISourceFile file
, Location start
, Location end
)
4279 this.parent
= parent
;
4280 this.builder
= builder
;
4282 CodeGen
.SymbolWriter
.OpenMethod (file
, this, start
.Row
, start
.Column
, end
.Row
, start
.Column
);
4285 public string Name
{
4286 get { return builder.Name; }
4289 public int NamespaceID
{
4290 get { return parent.NamespaceEntry.SymbolFileID; }
4295 if (builder
is MethodBuilder
)
4296 return ((MethodBuilder
) builder
).GetToken ().Token
;
4297 else if (builder
is ConstructorBuilder
)
4298 return ((ConstructorBuilder
) builder
).GetToken ().Token
;
4300 throw new NotSupportedException ();
4304 public void CloseMethod ()
4306 if (CodeGen
.SymbolWriter
!= null)
4307 CodeGen
.SymbolWriter
.CloseMethod ();
4310 public static SourceMethod
Create (DeclSpace parent
, MethodBase builder
, Block block
)
4312 if (CodeGen
.SymbolWriter
== null)
4317 Location start_loc
= block
.StartLocation
;
4318 if (start_loc
.IsNull
)
4321 Location end_loc
= block
.EndLocation
;
4325 ISourceFile file
= start_loc
.SourceFile
;
4329 return new SourceMethod (
4330 parent
, builder
, file
, start_loc
, end_loc
);
4334 public class Method
: MethodOrOperator
, IAnonymousHost
{
4337 /// Modifiers allowed in a class declaration
4339 const int AllowedModifiers
=
4342 Modifiers
.PROTECTED
|
4343 Modifiers
.INTERNAL
|
4348 Modifiers
.OVERRIDE
|
4349 Modifiers
.ABSTRACT
|
4351 Modifiers
.METHOD_YIELDS
|
4354 const int AllowedInterfaceModifiers
=
4355 Modifiers
.NEW
| Modifiers
.UNSAFE
;
4358 // return_type can be "null" for VOID values.
4360 public Method (DeclSpace parent
, GenericMethod generic
,
4361 Expression return_type
, int mod
, bool is_iface
,
4362 MemberName name
, Parameters parameters
, Attributes attrs
)
4363 : base (parent
, generic
, return_type
, mod
,
4364 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
4365 is_iface
, name
, attrs
, parameters
)
4369 public override string GetSignatureForError()
4371 return base.GetSignatureForError () + Parameters
.GetSignatureForError ();
4374 void Error_DuplicateEntryPoint (MethodInfo b
, Location location
)
4376 Report
.Error (17, location
,
4377 "Program `{0}' has more than one entry point defined: `{1}'",
4378 CodeGen
.FileName
, TypeManager
.CSharpSignature(b
));
4381 bool IsEntryPoint ()
4383 if (ReturnType
!= TypeManager
.void_type
&&
4384 ReturnType
!= TypeManager
.int32_type
)
4387 if (Parameters
.Count
== 0)
4390 if (Parameters
.Count
> 1)
4393 Type t
= Parameters
.ParameterType (0);
4394 return t
.IsArray
&& t
.GetArrayRank () == 1 &&
4395 TypeManager
.GetElementType (t
) == TypeManager
.string_type
&&
4396 (Parameters
[0].ModFlags
& ~Parameter
.Modifier
.PARAMS
) == Parameter
.Modifier
.NONE
;
4399 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
4401 if (a
.Type
== TypeManager
.conditional_attribute_type
) {
4402 if (IsExplicitImpl
) {
4403 Error_ConditionalAttributeIsNotValid ();
4407 if (ReturnType
!= TypeManager
.void_type
) {
4408 Report
.Error (578, Location
, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
4412 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
4413 Report
.Error (243, Location
, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
4418 Report
.Error (582, Location
, "Conditional not valid on interface members");
4422 if (MethodData
.implementing
!= null) {
4423 Report
.SymbolRelatedToPreviousError (MethodData
.implementing
.DeclaringType
);
4424 Report
.Error (629, Location
, "Conditional member `{0}' cannot implement interface member `{1}'",
4425 GetSignatureForError (), TypeManager
.CSharpSignature (MethodData
.implementing
));
4429 for (int i
= 0; i
< Parameters
.Count
; ++i
) {
4430 if ((Parameters
.ParameterModifier (i
) & Parameter
.Modifier
.OUTMASK
) != 0) {
4431 Report
.Error (685, Location
, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
4437 if (a
.Type
== TypeManager
.extension_attribute_type
) {
4438 a
.Error_MisusedExtensionAttribute ();
4442 base.ApplyAttributeBuilder (a
, cb
);
4445 protected override bool CheckForDuplications ()
4447 ArrayList ar
= Parent
.PartialContainer
.Methods
;
4449 int arLen
= ar
.Count
;
4451 for (int i
= 0; i
< arLen
; i
++) {
4452 Method m
= (Method
) ar
[i
];
4453 if (IsDuplicateImplementation (m
))
4458 ar
= Parent
.PartialContainer
.Properties
;
4460 for (int i
= 0; i
< ar
.Count
; ++i
) {
4461 PropertyBase pb
= (PropertyBase
) ar
[i
];
4462 if (pb
.AreAccessorsDuplicateImplementation (this))
4467 ar
= Parent
.PartialContainer
.Indexers
;
4469 for (int i
= 0; i
< ar
.Count
; ++i
) {
4470 PropertyBase pb
= (PropertyBase
) ar
[i
];
4471 if (pb
.AreAccessorsDuplicateImplementation (this))
4476 ar
= Parent
.PartialContainer
.Events
;
4478 for (int i
= 0; i
< ar
.Count
; ++i
) {
4479 Event ev
= (Event
) ar
[i
];
4480 if (ev
.AreAccessorsDuplicateImplementation (this))
4491 public override bool Define ()
4493 if (!base.Define ())
4496 if (RootContext
.StdLib
&& (ReturnType
== TypeManager
.arg_iterator_type
|| ReturnType
== TypeManager
.typed_reference_type
)) {
4497 Error1599 (Location
, ReturnType
);
4501 if (ReturnType
== TypeManager
.void_type
&& ParameterTypes
.Length
== 0 &&
4502 Name
== "Finalize" && !(this is Destructor
)) {
4503 Report
.Warning (465, 1, Location
, "Introducing a 'Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
4506 if (base_method
!= null && (ModFlags
& Modifiers
.NEW
) == 0) {
4507 if (Parameters
.Count
== 1 && ParameterTypes
[0] == TypeManager
.object_type
&& Name
== "Equals")
4508 Parent
.PartialContainer
.Mark_HasEquals ();
4509 else if (Parameters
.Empty
&& Name
== "GetHashCode")
4510 Parent
.PartialContainer
.Mark_HasGetHashCode ();
4513 if ((ModFlags
& Modifiers
.STATIC
) == 0)
4516 if (Parameters
.HasExtensionMethodType
) {
4517 if (Parent
.IsStaticClass
&& !Parent
.IsGeneric
) {
4518 if (!Parent
.IsTopLevel
)
4519 Report
.Error (1109, Location
, "`{0}': Extension methods cannot be defined in a nested class",
4520 GetSignatureForError ());
4522 if (TypeManager
.extension_attribute_type
== null)
4523 Report
.Error (1110, Location
,
4524 "`{0}': Extension methods cannot be declared without a reference to System.Core.dll assembly. Add the assembly reference or remove `this' modifer from the first parameter",
4525 GetSignatureForError ());
4527 ModFlags
|= Modifiers
.METHOD_EXTENSION
;
4528 Parent
.ModFlags
|= Modifiers
.METHOD_EXTENSION
;
4529 CodeGen
.Assembly
.HasExtensionMethods
= true;
4531 Report
.Error (1106, Location
, "`{0}': Extension methods must be defined in a non-generic static class",
4532 GetSignatureForError ());
4537 // This is used to track the Entry Point,
4539 if (RootContext
.NeedsEntryPoint
&&
4541 (RootContext
.MainClass
== null ||
4542 RootContext
.MainClass
== Parent
.TypeBuilder
.FullName
)){
4543 if (IsEntryPoint ()) {
4545 if (RootContext
.EntryPoint
== null) {
4546 if (Parent
.IsGeneric
|| MemberName
.IsGeneric
) {
4547 Report
.Warning (402, 4, Location
, "`{0}': an entry point cannot be generic or in a generic type",
4548 GetSignatureForError ());
4550 IMethodData md
= TypeManager
.GetMethod (MethodBuilder
);
4551 md
.SetMemberIsUsed ();
4553 RootContext
.EntryPoint
= MethodBuilder
;
4554 RootContext
.EntryPointLocation
= Location
;
4557 Error_DuplicateEntryPoint (RootContext
.EntryPoint
, RootContext
.EntryPointLocation
);
4558 Error_DuplicateEntryPoint (MethodBuilder
, Location
);
4561 Report
.Warning (28, 4, Location
, "`{0}' has the wrong signature to be an entry point",
4562 GetSignatureForError ());
4572 public override void Emit ()
4574 Report
.Debug (64, "METHOD EMIT", this, MethodBuilder
, Location
, Block
, MethodData
);
4575 MethodData
.Emit (Parent
);
4578 if ((ModFlags
& Modifiers
.METHOD_EXTENSION
) != 0)
4579 MethodBuilder
.SetCustomAttribute (TypeManager
.extension_attribute_attr
);
4585 public static void Error1599 (Location loc
, Type t
)
4587 Report
.Error (1599, loc
, "Method or delegate cannot return type `{0}'", TypeManager
.CSharpName (t
));
4590 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
4592 MethodInfo mi
= (MethodInfo
) Parent
.PartialContainer
.BaseCache
.FindMemberToOverride (
4593 Parent
.TypeBuilder
, Name
, ParameterTypes
, GenericMethod
, false);
4598 if (mi
.IsSpecialName
)
4601 base_ret_type
= mi
.ReturnType
;
4605 protected override bool VerifyClsCompliance ()
4607 if (!base.VerifyClsCompliance ())
4610 if (ParameterInfo
.Count
> 0) {
4611 ArrayList al
= (ArrayList
)Parent
.PartialContainer
.MemberCache
.Members
[Name
];
4613 MemberCache
.VerifyClsParameterConflict (al
, this, MethodBuilder
);
4620 public abstract class ConstructorInitializer
{
4621 ArrayList argument_list
;
4622 protected ConstructorInfo base_constructor
;
4625 public ConstructorInitializer (ArrayList argument_list
, Location loc
)
4627 this.argument_list
= argument_list
;
4631 public ArrayList Arguments
{
4633 return argument_list
;
4637 public bool Resolve (ConstructorBuilder caller_builder
, Block block
, EmitContext ec
)
4639 Expression base_constructor_group
;
4643 ec
.CurrentBlock
= block
;
4645 if (argument_list
!= null){
4646 foreach (Argument a
in argument_list
){
4647 if (!a
.Resolve (ec
, loc
))
4651 ec
.CurrentBlock
= null;
4653 if (this is ConstructorBaseInitializer
) {
4654 if (ec
.ContainerType
.BaseType
== null)
4657 t
= ec
.ContainerType
.BaseType
;
4658 if (ec
.ContainerType
.IsValueType
) {
4659 Report
.Error (522, loc
,
4660 "`{0}': Struct constructors cannot call base constructors", TypeManager
.CSharpSignature (caller_builder
));
4665 // It is legal to have "this" initializers that take no arguments
4666 // in structs, they are just no-ops.
4668 // struct D { public D (int a) : this () {}
4670 if (ec
.ContainerType
.IsValueType
&& argument_list
== null)
4673 t
= ec
.ContainerType
;
4676 base_constructor_group
= Expression
.MemberLookup (
4677 ec
.ContainerType
, t
, ".ctor", MemberTypes
.Constructor
,
4678 BindingFlags
.Public
| BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
,
4681 if (base_constructor_group
== null){
4683 base_constructor_group
= Expression
.MemberLookup (
4684 t
, null, t
, ".ctor", MemberTypes
.Constructor
,
4685 BindingFlags
.NonPublic
| BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
,
4689 int errors
= Report
.Errors
;
4690 if (base_constructor_group
!= null)
4691 base_constructor
= (ConstructorInfo
)
4692 ((MethodGroupExpr
) base_constructor_group
).OverloadResolve (
4696 if (base_constructor
== null) {
4697 if (errors
== Report
.Errors
)
4698 Invocation
.Error_WrongNumArguments (loc
, TypeManager
.CSharpSignature (caller_builder
),
4699 argument_list
== null ? 0 : argument_list
.Count
);
4704 Report
.SymbolRelatedToPreviousError (base_constructor
);
4705 Expression
.ErrorIsInaccesible (loc
, TypeManager
.CSharpSignature (base_constructor
));
4706 base_constructor
= null;
4710 if (base_constructor
== caller_builder
){
4711 Report
.Error (516, loc
, "Constructor `{0}' cannot call itself", TypeManager
.CSharpSignature (caller_builder
));
4718 public virtual void Emit (EmitContext ec
)
4720 if (base_constructor
!= null){
4721 ec
.Mark (loc
, false);
4723 Invocation
.EmitCall (ec
, true, true, null, base_constructor
, argument_list
, loc
);
4725 Invocation
.EmitCall (ec
, true, false, ec
.GetThis (loc
), base_constructor
, argument_list
, loc
);
4730 public class ConstructorBaseInitializer
: ConstructorInitializer
{
4731 public ConstructorBaseInitializer (ArrayList argument_list
, Location l
) :
4732 base (argument_list
, l
)
4737 class GeneratedBaseInitializer
: ConstructorBaseInitializer
{
4738 public GeneratedBaseInitializer (Location loc
):
4744 public class ConstructorThisInitializer
: ConstructorInitializer
{
4745 public ConstructorThisInitializer (ArrayList argument_list
, Location l
) :
4746 base (argument_list
, l
)
4751 public class Constructor
: MethodCore
, IMethodData
, IAnonymousHost
{
4752 public ConstructorBuilder ConstructorBuilder
;
4753 public ConstructorInitializer Initializer
;
4754 ListDictionary declarative_security
;
4755 ArrayList anonymous_methods
;
4758 // Modifiers allowed for a constructor.
4760 public const int AllowedModifiers
=
4762 Modifiers
.PROTECTED
|
4763 Modifiers
.INTERNAL
|
4769 static string[] attribute_targets
= new string [] { "method" }
;
4771 public Iterator Iterator
{
4772 get { return null; }
4775 bool has_compliant_args
= false;
4777 // The spec claims that static is not permitted, but
4778 // my very own code has static constructors.
4780 public Constructor (DeclSpace parent
, string name
, int mod
, Parameters args
,
4781 ConstructorInitializer init
, Location loc
)
4782 : base (parent
, null, null, mod
, AllowedModifiers
, false,
4783 new MemberName (name
, loc
), null, args
)
4788 public bool HasCompliantArgs
{
4789 get { return has_compliant_args; }
4792 public override AttributeTargets AttributeTargets
{
4793 get { return AttributeTargets.Constructor; }
4798 // Returns true if this is a default constructor
4800 public bool IsDefault ()
4802 if ((ModFlags
& Modifiers
.STATIC
) != 0)
4803 return Parameters
.Empty
;
4805 return Parameters
.Empty
&&
4806 (Initializer
is ConstructorBaseInitializer
) &&
4807 (Initializer
.Arguments
== null);
4810 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
4812 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
4813 if (declarative_security
== null) {
4814 declarative_security
= new ListDictionary ();
4816 a
.ExtractSecurityPermissionSet (declarative_security
);
4820 if (a
.IsInternalMethodImplAttribute
) {
4821 is_external_implementation
= true;
4824 ConstructorBuilder
.SetCustomAttribute (cb
);
4827 public void AddAnonymousMethod (AnonymousMethodExpression anonymous
)
4829 if (anonymous_methods
== null)
4830 anonymous_methods
= new ArrayList ();
4831 anonymous_methods
.Add (anonymous
);
4834 public bool ResolveMembers ()
4836 if (anonymous_methods
!= null) {
4837 foreach (AnonymousMethodExpression ame
in anonymous_methods
) {
4838 if (!ame
.CreateAnonymousHelpers ())
4846 protected override bool CheckForDuplications ()
4848 ArrayList ar
= Parent
.PartialContainer
.InstanceConstructors
;
4850 int arLen
= ar
.Count
;
4852 for (int i
= 0; i
< arLen
; i
++) {
4853 Constructor m
= (Constructor
) ar
[i
];
4854 if (IsDuplicateImplementation (m
))
4861 protected override bool CheckBase ()
4863 if ((ModFlags
& Modifiers
.STATIC
) != 0) {
4864 if (!Parameters
.Empty
) {
4865 Report
.Error (132, Location
, "`{0}': The static constructor must be parameterless",
4866 GetSignatureForError ());
4870 // the rest can be ignored
4874 // Check whether arguments were correct.
4875 if (!DefineParameters (Parameters
))
4878 if (!CheckForDuplications ())
4881 if (Parent
.PartialContainer
.Kind
== Kind
.Struct
) {
4882 if (ParameterTypes
.Length
== 0) {
4883 Report
.Error (568, Location
,
4884 "Structs cannot contain explicit parameterless constructors");
4888 if ((ModFlags
& Modifiers
.PROTECTED
) != 0) {
4889 Report
.Error (666, Location
, "`{0}': new protected member declared in struct", GetSignatureForError ());
4894 if ((RootContext
.WarningLevel
>= 4) && ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0 && (ModFlags
& Modifiers
.PROTECTED
) != 0)) {
4895 Report
.Warning (628, 4, Location
, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
4902 // Creates the ConstructorBuilder
4904 public override bool Define ()
4906 if (ConstructorBuilder
!= null)
4909 MethodAttributes ca
= (MethodAttributes
.RTSpecialName
|
4910 MethodAttributes
.SpecialName
);
4912 if ((ModFlags
& Modifiers
.STATIC
) != 0) {
4913 ca
|= MethodAttributes
.Static
| MethodAttributes
.Private
;
4915 ca
|= MethodAttributes
.HideBySig
;
4917 if ((ModFlags
& Modifiers
.PUBLIC
) != 0)
4918 ca
|= MethodAttributes
.Public
;
4919 else if ((ModFlags
& Modifiers
.PROTECTED
) != 0){
4920 if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
4921 ca
|= MethodAttributes
.FamORAssem
;
4923 ca
|= MethodAttributes
.Family
;
4924 } else if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
4925 ca
|= MethodAttributes
.Assembly
;
4927 ca
|= MethodAttributes
.Private
;
4930 if (!CheckAbstractAndExtern (block
!= null))
4933 // Check if arguments were correct.
4937 ConstructorBuilder
= Parent
.TypeBuilder
.DefineConstructor (
4938 ca
, CallingConventions
,
4941 if ((ModFlags
& Modifiers
.UNSAFE
) != 0)
4942 ConstructorBuilder
.InitLocals
= false;
4944 if (Parent
.PartialContainer
.IsComImport
) {
4945 if (!IsDefault ()) {
4946 Report
.Error (669, Location
, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
4947 Parent
.GetSignatureForError ());
4950 ConstructorBuilder
.SetImplementationFlags (MethodImplAttributes
.InternalCall
);
4953 TypeManager
.AddMethod (ConstructorBuilder
, this);
4961 public override void Emit ()
4963 if (OptAttributes
!= null)
4964 OptAttributes
.Emit ();
4966 EmitContext ec
= CreateEmitContext (null, null);
4968 if (block
!= null) {
4969 // If this is a non-static `struct' constructor and doesn't have any
4970 // initializer, it must initialize all of the struct's fields.
4971 if ((Parent
.PartialContainer
.Kind
== Kind
.Struct
) &&
4972 ((ModFlags
& Modifiers
.STATIC
) == 0) && (Initializer
== null))
4973 block
.AddThisVariable (Parent
, Location
);
4975 if (!block
.ResolveMeta (ec
, ParameterInfo
))
4979 if ((ModFlags
& Modifiers
.STATIC
) == 0){
4980 if (Parent
.PartialContainer
.Kind
== Kind
.Class
&& Initializer
== null)
4981 Initializer
= new GeneratedBaseInitializer (Location
);
4985 // Spec mandates that Initializers will not have
4989 if ((Initializer
!= null) &&
4990 !Initializer
.Resolve (ConstructorBuilder
, block
, ec
))
4992 ec
.IsStatic
= false;
4995 Parameters
.ApplyAttributes (ConstructorBuilder
);
4997 SourceMethod source
= SourceMethod
.Create (
4998 Parent
, ConstructorBuilder
, block
);
5001 // Classes can have base initializers and instance field initializers.
5003 if (Parent
.PartialContainer
.Kind
== Kind
.Class
){
5004 if ((ModFlags
& Modifiers
.STATIC
) == 0){
5007 // If we use a "this (...)" constructor initializer, then
5008 // do not emit field initializers, they are initialized in the other constructor
5010 if (!(Initializer
!= null && Initializer
is ConstructorThisInitializer
))
5011 Parent
.PartialContainer
.EmitFieldInitializers (ec
);
5015 bool unreachable
= false;
5016 if (block
!= null) {
5017 if (!ec
.ResolveTopBlock (null, block
, ParameterInfo
, this, out unreachable
))
5019 ec
.EmitMeta (block
);
5021 if (block
.ScopeInfo
!= null) {
5022 ExpressionStatement init
= block
.ScopeInfo
.GetScopeInitializer (ec
);
5023 init
.EmitStatement (ec
);
5027 if (Initializer
!= null) {
5028 Initializer
.Emit (ec
);
5031 if ((ModFlags
& Modifiers
.STATIC
) != 0)
5032 Parent
.PartialContainer
.EmitFieldInitializers (ec
);
5035 ec
.EmitResolvedTopBlock (block
, unreachable
);
5038 source
.CloseMethod ();
5042 if (declarative_security
!= null) {
5043 foreach (DictionaryEntry de
in declarative_security
) {
5044 ConstructorBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
5051 // Is never override
5052 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
5057 public override string GetSignatureForError()
5059 return base.GetSignatureForError () + Parameters
.GetSignatureForError ();
5062 public override string[] ValidAttributeTargets
{
5064 return attribute_targets
;
5068 protected override bool VerifyClsCompliance ()
5070 if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
5074 if (ParameterInfo
.Count
> 0) {
5075 ArrayList al
= (ArrayList
)Parent
.MemberCache
.Members
[".ctor"];
5077 MemberCache
.VerifyClsParameterConflict (al
, this, ConstructorBuilder
);
5079 if (Parent
.TypeBuilder
.IsSubclassOf (TypeManager
.attribute_type
)) {
5080 foreach (Type param
in ParameterTypes
) {
5081 if (param
.IsArray
) {
5087 has_compliant_args
= true;
5091 #region IMethodData Members
5093 public System
.Reflection
.CallingConventions CallingConventions
{
5095 CallingConventions cc
= Parameters
.CallingConvention
;
5097 if (Parent
.PartialContainer
.Kind
== Kind
.Class
)
5098 if ((ModFlags
& Modifiers
.STATIC
) == 0)
5099 cc
|= CallingConventions
.HasThis
;
5101 // FIXME: How is `ExplicitThis' used in C#?
5107 public new Location Location
{
5109 return base.Location
;
5113 public MemberName MethodName
{
5119 public Type ReturnType
{
5125 public EmitContext
CreateEmitContext (DeclSpace ds
, ILGenerator ig
)
5127 ILGenerator ig_
= ConstructorBuilder
.GetILGenerator ();
5128 return new EmitContext (this, Parent
, Location
, ig_
, null, ModFlags
, true);
5131 public bool IsExcluded()
5136 GenericMethod IMethodData
.GenericMethod
{
5146 /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
5148 public interface IMethodData
5150 CallingConventions CallingConventions { get; }
5151 Location Location { get; }
5152 MemberName MethodName { get; }
5153 Type ReturnType { get; }
5154 GenericMethod GenericMethod { get; }
5155 Parameters ParameterInfo { get; }
5157 Iterator Iterator { get; }
5159 Attributes OptAttributes { get; }
5160 ToplevelBlock Block { get; set; }
5162 EmitContext
CreateEmitContext (DeclSpace ds
, ILGenerator ig
);
5163 ObsoleteAttribute
GetObsoleteAttribute ();
5164 string GetSignatureForError ();
5166 bool IsClsComplianceRequired ();
5167 void SetMemberIsUsed ();
5171 // Encapsulates most of the Method's state
5173 public class MethodData
{
5175 readonly IMethodData method
;
5177 public readonly GenericMethod GenericMethod
;
5180 // Are we implementing an interface ?
5182 public MethodInfo implementing
;
5187 protected InterfaceMemberBase member
;
5188 protected int modifiers
;
5189 protected MethodAttributes flags
;
5190 protected Type declaring_type
;
5191 protected MethodInfo parent_method
;
5193 MethodBuilder builder
= null;
5194 public MethodBuilder MethodBuilder
{
5200 public Type DeclaringType
{
5202 return declaring_type
;
5206 public MethodData (InterfaceMemberBase member
,
5207 int modifiers
, MethodAttributes flags
, IMethodData method
)
5209 this.member
= member
;
5210 this.modifiers
= modifiers
;
5213 this.method
= method
;
5216 public MethodData (InterfaceMemberBase member
,
5217 int modifiers
, MethodAttributes flags
,
5218 IMethodData method
, MethodBuilder builder
,
5219 GenericMethod generic
, MethodInfo parent_method
)
5220 : this (member
, modifiers
, flags
, method
)
5222 this.builder
= builder
;
5223 this.GenericMethod
= generic
;
5224 this.parent_method
= parent_method
;
5227 public bool Define (DeclSpace parent
)
5229 string name
= method
.MethodName
.Basename
;
5230 string method_name
= method
.MethodName
.FullName
;
5232 TypeContainer container
= parent
.PartialContainer
;
5234 PendingImplementation pending
= container
.PendingImplementations
;
5235 if (pending
!= null){
5236 if (member
is Indexer
) // TODO: test it, but it should work without this IF
5237 implementing
= pending
.IsInterfaceIndexer (
5238 member
.InterfaceType
, method
.ReturnType
, method
.ParameterInfo
);
5240 implementing
= pending
.IsInterfaceMethod (
5241 member
.InterfaceType
, name
, method
.ReturnType
, method
.ParameterInfo
);
5243 if (member
.InterfaceType
!= null){
5244 if (implementing
== null){
5245 if (member
is PropertyBase
) {
5246 Report
.Error (550, method
.Location
, "`{0}' is an accessor not found in interface member `{1}{2}'",
5247 method
.GetSignatureForError (), TypeManager
.CSharpName (member
.InterfaceType
),
5248 member
.GetSignatureForError ().Substring (member
.GetSignatureForError ().LastIndexOf ('.')));
5251 Report
.Error (539, method
.Location
,
5252 "`{0}.{1}' in explicit interface declaration is not a member of interface",
5253 TypeManager
.CSharpName (member
.InterfaceType
), member
.ShortName
);
5257 if (implementing
.IsSpecialName
&& !(method
is AbstractPropertyEventMethod
)) {
5258 Report
.SymbolRelatedToPreviousError (implementing
);
5259 Report
.Error (683, method
.Location
, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
5260 member
.GetSignatureForError (), TypeManager
.CSharpSignature (implementing
));
5264 method_name
= member
.InterfaceType
.FullName
+
5267 if (implementing
!= null) {
5268 AbstractPropertyEventMethod prop_method
= method
as AbstractPropertyEventMethod
;
5269 if (prop_method
== null) {
5270 if (implementing
.IsSpecialName
) {
5271 Report
.SymbolRelatedToPreviousError (implementing
);
5272 Report
.Error (470, method
.Location
, "Method `{0}' cannot implement interface accessor `{1}.{2}'",
5273 method
.GetSignatureForError (), TypeManager
.CSharpSignature (implementing
),
5274 implementing
.Name
.StartsWith ("get_") ? "get" : "set");
5277 } else if (implementing
.DeclaringType
.IsInterface
) {
5278 if (!implementing
.IsSpecialName
) {
5279 Report
.SymbolRelatedToPreviousError (implementing
);
5280 Report
.Error (686, method
.Location
, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
5281 method
.GetSignatureForError (), TypeManager
.CSharpSignature (implementing
), container
.GetSignatureForError ());
5284 PropertyBase
.PropertyMethod pm
= prop_method
as PropertyBase
.PropertyMethod
;
5285 if (pm
!= null && pm
.HasCustomAccessModifier
&& (pm
.ModFlags
& Modifiers
.PUBLIC
) == 0) {
5286 Report
.SymbolRelatedToPreviousError (implementing
);
5287 Report
.Error (277, method
.Location
, "Accessor `{0}' must be declared public to implement interface member `{1}'",
5288 method
.GetSignatureForError (), TypeManager
.CSharpSignature (implementing
, true));
5297 // For implicit implementations, make sure we are public, for
5298 // explicit implementations, make sure we are private.
5300 if (implementing
!= null){
5302 // Setting null inside this block will trigger a more
5303 // verbose error reporting for missing interface implementations
5305 // The "candidate" function has been flagged already
5306 // but it wont get cleared
5308 if (member
.IsExplicitImpl
){
5309 if (method
.ParameterInfo
.HasParams
&& !TypeManager
.GetParameterData (implementing
).HasParams
) {
5310 Report
.SymbolRelatedToPreviousError (implementing
);
5311 Report
.Error (466, method
.Location
, "`{0}': the explicit interface implementation cannot introduce the params modifier",
5312 method
.GetSignatureForError ());
5316 if (implementing
.DeclaringType
.IsInterface
) {
5318 // If this is an interface method implementation,
5319 // check for public accessibility
5321 if ((flags
& MethodAttributes
.MemberAccessMask
) != MethodAttributes
.Public
)
5323 implementing
= null;
5325 } else if ((flags
& MethodAttributes
.MemberAccessMask
) == MethodAttributes
.Private
){
5326 // We may never be private.
5327 implementing
= null;
5329 } else if ((modifiers
& Modifiers
.OVERRIDE
) == 0){
5331 // We may be protected if we're overriding something.
5333 implementing
= null;
5338 // Static is not allowed
5340 if ((modifiers
& Modifiers
.STATIC
) != 0){
5341 implementing
= null;
5346 // If implementing is still valid, set flags
5348 if (implementing
!= null){
5350 // When implementing interface methods, set NewSlot
5351 // unless, we are overwriting a method.
5353 if (implementing
.DeclaringType
.IsInterface
){
5354 if ((modifiers
& Modifiers
.OVERRIDE
) == 0)
5355 flags
|= MethodAttributes
.NewSlot
;
5358 MethodAttributes
.Virtual
|
5359 MethodAttributes
.HideBySig
;
5361 // Set Final unless we're virtual, abstract or already overriding a method.
5362 if ((modifiers
& (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
| Modifiers
.OVERRIDE
)) == 0)
5363 flags
|= MethodAttributes
.Final
;
5366 EmitContext ec
= method
.CreateEmitContext (container
, null);
5368 DefineMethodBuilder (container
, method_name
, method
.ParameterInfo
.Types
);
5370 if (builder
== null)
5373 if (container
.CurrentType
!= null)
5374 declaring_type
= container
.CurrentType
;
5376 declaring_type
= container
.TypeBuilder
;
5378 if ((modifiers
& Modifiers
.UNSAFE
) != 0)
5379 builder
.InitLocals
= false;
5382 if (implementing
!= null){
5384 // clear the pending implemntation flag
5386 if (member
is Indexer
) {
5387 pending
.ImplementIndexer (
5388 member
.InterfaceType
, builder
, method
.ReturnType
,
5389 method
.ParameterInfo
, member
.IsExplicitImpl
);
5391 pending
.ImplementMethod (
5392 member
.InterfaceType
, name
, method
.ReturnType
,
5393 method
.ParameterInfo
, member
.IsExplicitImpl
);
5395 if (member
.IsExplicitImpl
)
5396 container
.TypeBuilder
.DefineMethodOverride (
5397 builder
, implementing
);
5400 TypeManager
.AddMethod (builder
, method
);
5402 if (GenericMethod
!= null) {
5403 bool is_override
= member
.IsExplicitImpl
|
5404 ((modifiers
& Modifiers
.OVERRIDE
) != 0);
5406 if (implementing
!= null)
5407 parent_method
= implementing
;
5409 if (!GenericMethod
.DefineType (ec
, builder
, parent_method
, is_override
))
5418 /// Create the MethodBuilder for the method
5420 void DefineMethodBuilder (TypeContainer container
, string method_name
, Type
[] ParameterTypes
)
5422 if (builder
== null) {
5423 builder
= container
.TypeBuilder
.DefineMethod (
5424 method_name
, flags
, method
.CallingConventions
,
5425 method
.ReturnType
, ParameterTypes
);
5429 #if GMCS_SOURCE && !MS_COMPATIBLE
5430 builder
.SetGenericMethodSignature (
5431 flags
, method
.CallingConventions
,
5432 method
.ReturnType
, ParameterTypes
);
5439 public void Emit (DeclSpace parent
)
5441 ToplevelBlock block
= method
.Block
;
5445 ec
= method
.CreateEmitContext (parent
, builder
.GetILGenerator ());
5447 ec
= method
.CreateEmitContext (parent
, null);
5449 method
.ParameterInfo
.ApplyAttributes (MethodBuilder
);
5451 if (GenericMethod
!= null)
5452 GenericMethod
.EmitAttributes ();
5454 SourceMethod source
= SourceMethod
.Create (parent
, MethodBuilder
, method
.Block
);
5457 // Handle destructors specially
5459 // FIXME: This code generates buggy code
5461 if (member
is Destructor
)
5462 EmitDestructor (ec
, block
);
5464 ec
.EmitTopBlock (method
, block
);
5467 source
.CloseMethod ();
5470 void EmitDestructor (EmitContext ec
, ToplevelBlock block
)
5472 ILGenerator ig
= ec
.ig
;
5474 Label finish
= ig
.DefineLabel ();
5476 block
.SetDestructor ();
5478 ig
.BeginExceptionBlock ();
5479 ec
.ReturnLabel
= finish
;
5480 ec
.HasReturnLabel
= true;
5481 ec
.EmitTopBlock (method
, block
);
5483 // ig.MarkLabel (finish);
5484 ig
.BeginFinallyBlock ();
5486 if (ec
.ContainerType
.BaseType
!= null) {
5487 Expression member_lookup
= Expression
.MemberLookup (
5488 ec
.ContainerType
.BaseType
, null, ec
.ContainerType
.BaseType
,
5489 "Finalize", MemberTypes
.Method
, Expression
.AllBindingFlags
, method
.Location
);
5491 if (member_lookup
!= null){
5492 MethodGroupExpr base_destructor
= ((MethodGroupExpr
) member_lookup
);
5494 ig
.Emit (OpCodes
.Ldarg_0
);
5495 ig
.Emit (OpCodes
.Call
, (MethodInfo
) base_destructor
.Methods
[0]);
5499 ig
.EndExceptionBlock ();
5500 //ig.MarkLabel (ec.ReturnLabel);
5501 ig
.Emit (OpCodes
.Ret
);
5505 // TODO: Should derive from MethodCore
5506 public class Destructor
: Method
{
5508 static string[] attribute_targets
= new string [] { "method" }
;
5510 public Destructor (DeclSpace parent
, Expression return_type
, int mod
,
5511 string name
, Parameters parameters
, Attributes attrs
,
5513 : base (parent
, null, return_type
, mod
, false, new MemberName (name
, l
),
5517 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
5519 if (a
.Type
== TypeManager
.conditional_attribute_type
) {
5520 Error_ConditionalAttributeIsNotValid ();
5524 base.ApplyAttributeBuilder (a
, cb
);
5527 public override string GetSignatureForError ()
5529 return Parent
.GetSignatureForError () + ".~" + Parent
.MemberName
.Name
+ "()";
5532 public override string[] ValidAttributeTargets
{
5534 return attribute_targets
;
5539 abstract public class MemberBase
: MemberCore
{
5540 public Expression Type
;
5541 public readonly DeclSpace ds
;
5542 public readonly GenericMethod GenericMethod
;
5545 // The type of this property / indexer / event
5547 protected Type member_type
;
5548 public Type MemberType
{
5550 if (member_type
== null && Type
!= null) {
5551 IResolveContext rc
= GenericMethod
== null ? this : (IResolveContext
)ds
;
5552 Type
= Type
.ResolveAsTypeTerminal (rc
, false);
5554 member_type
= Type
.Type
;
5562 // The constructor is only exposed to our children
5564 protected MemberBase (DeclSpace parent
, GenericMethod generic
,
5565 Expression type
, int mod
, int allowed_mod
, int def_mod
,
5566 MemberName name
, Attributes attrs
)
5567 : base (parent
, name
, attrs
)
5569 this.ds
= generic
!= null ? generic
: (DeclSpace
) parent
;
5571 ModFlags
= Modifiers
.Check (allowed_mod
, mod
, def_mod
, Location
);
5572 GenericMethod
= generic
;
5573 if (GenericMethod
!= null)
5574 GenericMethod
.ModFlags
= ModFlags
;
5577 protected virtual bool CheckBase ()
5579 if ((ModFlags
& Modifiers
.PROTECTED
) != 0 && Parent
.PartialContainer
.Kind
== Kind
.Struct
) {
5580 Report
.Error (666, Location
, "`{0}': new protected member declared in struct", GetSignatureForError ());
5584 if ((RootContext
.WarningLevel
>= 4) &&
5585 ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0) &&
5586 ((ModFlags
& Modifiers
.PROTECTED
) != 0) &&
5587 ((ModFlags
& Modifiers
.OVERRIDE
) == 0) && (Name
!= "Finalize")) {
5588 Report
.Warning (628, 4, Location
, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
5593 protected virtual bool DoDefine ()
5595 if (MemberType
== null)
5598 if ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0 &&
5599 (ModFlags
& (Modifiers
.VIRTUAL
|Modifiers
.ABSTRACT
)) != 0) {
5600 Report
.Error (549, Location
, "New virtual member `{0}' is declared in a sealed class `{1}'",
5601 GetSignatureForError (), Parent
.GetSignatureForError ());
5605 // verify accessibility
5606 if (!Parent
.AsAccessible (MemberType
, ModFlags
)) {
5607 Report
.SymbolRelatedToPreviousError (MemberType
);
5608 if (this is Property
)
5609 Report
.Error (53, Location
,
5610 "Inconsistent accessibility: property type `" +
5611 TypeManager
.CSharpName (MemberType
) + "' is less " +
5612 "accessible than property `" + GetSignatureForError () + "'");
5613 else if (this is Indexer
)
5614 Report
.Error (54, Location
,
5615 "Inconsistent accessibility: indexer return type `" +
5616 TypeManager
.CSharpName (MemberType
) + "' is less " +
5617 "accessible than indexer `" + GetSignatureForError () + "'");
5618 else if (this is MethodCore
) {
5619 if (this is Operator
)
5620 Report
.Error (56, Location
,
5621 "Inconsistent accessibility: return type `" +
5622 TypeManager
.CSharpName (MemberType
) + "' is less " +
5623 "accessible than operator `" + GetSignatureForError () + "'");
5625 Report
.Error (50, Location
,
5626 "Inconsistent accessibility: return type `" +
5627 TypeManager
.CSharpName (MemberType
) + "' is less " +
5628 "accessible than method `" + GetSignatureForError () + "'");
5630 Report
.Error (52, Location
,
5631 "Inconsistent accessibility: field type `" +
5632 TypeManager
.CSharpName (MemberType
) + "' is less " +
5633 "accessible than field `" + GetSignatureForError () + "'");
5641 protected bool IsTypePermitted ()
5643 if (MemberType
== TypeManager
.arg_iterator_type
|| MemberType
== TypeManager
.typed_reference_type
) {
5644 Report
.Error (610, Location
, "Field or property cannot be of type `{0}'", TypeManager
.CSharpName (MemberType
));
5652 // Abstract class for all fields
5654 abstract public class FieldBase
: MemberBase
{
5655 public FieldBuilder FieldBuilder
;
5656 public Status status
;
5657 protected Expression initializer
;
5660 public enum Status
: byte {
5661 HAS_OFFSET
= 4 // Used by FieldMember.
5664 static readonly string[] attribute_targets
= new string [] { "field" }
;
5666 protected FieldBase (DeclSpace parent
, Expression type
, int mod
,
5667 int allowed_mod
, MemberName name
, Attributes attrs
)
5668 : base (parent
, null, type
, mod
, allowed_mod
| Modifiers
.ABSTRACT
, Modifiers
.PRIVATE
,
5671 if ((mod
& Modifiers
.ABSTRACT
) != 0)
5672 Report
.Error (681, Location
, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5675 public override AttributeTargets AttributeTargets
{
5677 return AttributeTargets
.Field
;
5681 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
5683 if (a
.Type
== TypeManager
.field_offset_attribute_type
) {
5684 status
|= Status
.HAS_OFFSET
;
5686 if (!Parent
.PartialContainer
.HasExplicitLayout
) {
5687 Report
.Error (636, Location
, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5691 if ((ModFlags
& Modifiers
.STATIC
) != 0 || this is Const
) {
5692 Report
.Error (637, Location
, "The FieldOffset attribute is not allowed on static or const fields");
5698 if (a
.Type
== TypeManager
.fixed_buffer_attr_type
) {
5699 Report
.Error (1716, Location
, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5704 if (a
.Type
== TypeManager
.marshal_as_attr_type
) {
5705 UnmanagedMarshal marshal
= a
.GetMarshal (this);
5706 if (marshal
!= null) {
5707 FieldBuilder
.SetMarshal (marshal
);
5712 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
)) {
5713 a
.Error_InvalidSecurityParent ();
5717 FieldBuilder
.SetCustomAttribute (cb
);
5720 protected override bool CheckBase ()
5722 if (!base.CheckBase ())
5725 MemberInfo conflict_symbol
= Parent
.PartialContainer
.FindBaseMemberWithSameName (Name
, false);
5726 if (conflict_symbol
== null) {
5727 if ((ModFlags
& Modifiers
.NEW
) != 0) {
5728 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5733 if ((ModFlags
& (Modifiers
.NEW
| Modifiers
.OVERRIDE
)) == 0) {
5734 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
5735 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5736 GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
5742 public override bool Define()
5744 if (MemberType
== null || Type
== null)
5747 if (TypeManager
.IsGenericParameter (MemberType
))
5750 if (MemberType
== TypeManager
.void_type
) {
5751 // TODO: wrong location
5752 Expression
.Error_VoidInvalidInTheContext (Location
);
5756 if (MemberType
.IsSealed
&& MemberType
.IsAbstract
) {
5757 Error_VariableOfStaticClass (Location
, GetSignatureForError (), MemberType
);
5764 if (!Parent
.AsAccessible (MemberType
, ModFlags
)) {
5765 Report
.Error (52, Location
,
5766 "Inconsistent accessibility: field type `" +
5767 TypeManager
.CSharpName (MemberType
) + "' is less " +
5768 "accessible than field `" + GetSignatureForError () + "'");
5772 if (!IsTypePermitted ())
5779 // Represents header string for documentation comment.
5781 public override string DocCommentHeader
{
5782 get { return "F:"; }
5785 public override void Emit ()
5788 if ((ModFlags
& Modifiers
.COMPILER_GENERATED
) != 0) {
5789 FieldBuilder
.SetCustomAttribute (TypeManager
.compiler_generated_attr
);
5793 if (OptAttributes
!= null) {
5794 OptAttributes
.Emit ();
5797 if (((status
& Status
.HAS_OFFSET
) == 0) && (ModFlags
& Modifiers
.STATIC
) == 0 && Parent
.PartialContainer
.HasExplicitLayout
) {
5798 Report
.Error (625, Location
, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5804 public static void Error_VariableOfStaticClass (Location loc
, string variable_name
, Type static_class
)
5806 Report
.SymbolRelatedToPreviousError (static_class
);
5807 Report
.Error (723, loc
, "`{0}': cannot declare variables of static types",
5811 public Expression Initializer
{
5813 if (value != null) {
5814 this.initializer
= value;
5819 protected virtual bool IsFieldClsCompliant
{
5821 if (FieldBuilder
== null)
5824 return AttributeTester
.IsClsCompliant (FieldBuilder
.FieldType
);
5828 public override string[] ValidAttributeTargets
5831 return attribute_targets
;
5835 protected override bool VerifyClsCompliance ()
5837 if (!base.VerifyClsCompliance ())
5840 if (!IsFieldClsCompliant
) {
5841 Report
.Error (3003, Location
, "Type of `{0}' is not CLS-compliant", GetSignatureForError ());
5846 public void SetAssigned ()
5848 caching_flags
|= Flags
.IsAssigned
;
5852 interface IFixedBuffer
5854 FieldInfo Element { get; }
5855 Type ElementType { get; }
5858 public class FixedFieldExternal
: IFixedBuffer
5860 FieldInfo element_field
;
5862 public FixedFieldExternal (FieldInfo fi
)
5864 element_field
= fi
.FieldType
.GetField (FixedField
.FixedElementName
);
5867 #region IFixedField Members
5869 public FieldInfo Element
{
5871 return element_field
;
5875 public Type ElementType
{
5877 return element_field
.FieldType
;
5885 /// Fixed buffer implementation
5887 public class FixedField
: FieldBase
, IFixedBuffer
5889 public const string FixedElementName
= "FixedElementField";
5890 static int GlobalCounter
= 0;
5891 static object[] ctor_args
= new object[] { (short)LayoutKind.Sequential }
;
5892 static FieldInfo
[] fi
;
5894 TypeBuilder fixed_buffer_type
;
5895 FieldBuilder element
;
5896 Expression size_expr
;
5899 const int AllowedModifiers
=
5902 Modifiers
.PROTECTED
|
5903 Modifiers
.INTERNAL
|
5906 public FixedField (DeclSpace parent
, Expression type
, int mod
, string name
,
5907 Expression size_expr
, Attributes attrs
, Location loc
):
5908 base (parent
, type
, mod
, AllowedModifiers
, new MemberName (name
, loc
), attrs
)
5910 if (RootContext
.Version
== LanguageVersion
.ISO_1
)
5911 Report
.FeatureIsNotISO1 (loc
, "fixed size buffers");
5913 this.size_expr
= size_expr
;
5916 public override bool Define()
5919 if ((ModFlags
& (Modifiers
.PUBLIC
| Modifiers
.PROTECTED
)) != 0)
5920 Report
.Warning (-23, 1, Location
, "Only private or internal fixed sized buffers are supported by .NET 1.x");
5923 if (Parent
.PartialContainer
.Kind
!= Kind
.Struct
) {
5924 Report
.Error (1642, Location
, "`{0}': Fixed size buffer fields may only be members of structs",
5925 GetSignatureForError ());
5929 if (!base.Define ())
5932 if (!TypeManager
.IsPrimitiveType (MemberType
)) {
5933 Report
.Error (1663, Location
, "`{0}': Fixed size buffers type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double",
5934 GetSignatureForError ());
5938 EmitContext ec
= new EmitContext (this, Parent
, Location
, null, null, ModFlags
);
5939 Constant c
= size_expr
.ResolveAsConstant (ec
, this);
5943 IntConstant buffer_size_const
= c
.ImplicitConversionRequired (TypeManager
.int32_type
, Location
) as IntConstant
;
5944 if (buffer_size_const
== null)
5947 buffer_size
= buffer_size_const
.Value
;
5949 if (buffer_size
<= 0) {
5950 Report
.Error (1665, Location
, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5954 int type_size
= Expression
.GetTypeSize (MemberType
);
5956 if (buffer_size
> int.MaxValue
/ type_size
) {
5957 Report
.Error (1664, Location
, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5958 GetSignatureForError (), buffer_size
.ToString (), TypeManager
.CSharpName (MemberType
));
5962 buffer_size
*= type_size
;
5965 string name
= String
.Format ("<{0}>__FixedBuffer{1}", Name
, GlobalCounter
++);
5967 fixed_buffer_type
= Parent
.TypeBuilder
.DefineNestedType (name
,
5968 TypeAttributes
.NestedPublic
| TypeAttributes
.Sealed
| TypeAttributes
.BeforeFieldInit
, TypeManager
.value_type
);
5969 element
= fixed_buffer_type
.DefineField (FixedElementName
, MemberType
, FieldAttributes
.Public
);
5970 RootContext
.RegisterCompilerGeneratedType (fixed_buffer_type
);
5972 FieldBuilder
= Parent
.TypeBuilder
.DefineField (Name
, fixed_buffer_type
, Modifiers
.FieldAttr (ModFlags
));
5973 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
5978 public override void Emit()
5981 fi
= new FieldInfo
[] { TypeManager.struct_layout_attribute_type.GetField ("Size") }
;
5983 object[] fi_val
= new object[1];
5984 fi_val
[0] = buffer_size
;
5986 CustomAttributeBuilder cab
= new CustomAttributeBuilder (TypeManager
.struct_layout_attribute_ctor
,
5987 ctor_args
, fi
, fi_val
);
5988 fixed_buffer_type
.SetCustomAttribute (cab
);
5991 cab
= new CustomAttributeBuilder (TypeManager
.fixed_buffer_attr_ctor
, new object[] { MemberType, buffer_size }
);
5992 FieldBuilder
.SetCustomAttribute (cab
);
5997 protected override bool IsFieldClsCompliant
{
6003 #region IFixedField Members
6005 public FieldInfo Element
{
6011 public Type ElementType
{
6021 // The Field class is used to represents class/struct fields during parsing.
6023 public class Field
: FieldBase
{
6025 // Modifiers allowed in a class declaration
6027 const int AllowedModifiers
=
6030 Modifiers
.PROTECTED
|
6031 Modifiers
.INTERNAL
|
6034 Modifiers
.VOLATILE
|
6038 public Field (DeclSpace parent
, Expression type
, int mod
, string name
,
6039 Attributes attrs
, Location loc
)
6040 : base (parent
, type
, mod
, AllowedModifiers
, new MemberName (name
, loc
),
6045 public override bool Define ()
6047 if (!base.Define ())
6050 if (RootContext
.WarningLevel
> 1){
6051 Type ptype
= Parent
.TypeBuilder
.BaseType
;
6053 // ptype is only null for System.Object while compiling corlib.
6055 TypeContainer
.FindMembers (
6056 ptype
, MemberTypes
.Method
,
6057 BindingFlags
.Public
|
6058 BindingFlags
.Static
| BindingFlags
.Instance
,
6059 System
.Type
.FilterName
, Name
);
6063 if ((ModFlags
& Modifiers
.VOLATILE
) != 0){
6064 if (!MemberType
.IsClass
){
6065 Type vt
= MemberType
;
6067 if (TypeManager
.IsEnumType (vt
))
6068 vt
= TypeManager
.EnumToUnderlying (MemberType
);
6070 if (!((vt
== TypeManager
.bool_type
) ||
6071 (vt
== TypeManager
.sbyte_type
) ||
6072 (vt
== TypeManager
.byte_type
) ||
6073 (vt
== TypeManager
.short_type
) ||
6074 (vt
== TypeManager
.ushort_type
) ||
6075 (vt
== TypeManager
.int32_type
) ||
6076 (vt
== TypeManager
.uint32_type
) ||
6077 (vt
== TypeManager
.char_type
) ||
6078 (vt
== TypeManager
.float_type
) ||
6079 (!vt
.IsValueType
))){
6080 Report
.Error (677, Location
, "`{0}': A volatile field cannot be of the type `{1}'",
6081 GetSignatureForError (), TypeManager
.CSharpName (vt
));
6086 if ((ModFlags
& Modifiers
.READONLY
) != 0){
6087 Report
.Error (678, Location
, "`{0}': A field cannot be both volatile and readonly",
6088 GetSignatureForError ());
6093 FieldAttributes fa
= Modifiers
.FieldAttr (ModFlags
);
6095 if (Parent
.PartialContainer
.Kind
== Kind
.Struct
&&
6096 ((fa
& FieldAttributes
.Static
) == 0) &&
6097 MemberType
== Parent
.TypeBuilder
&&
6098 !TypeManager
.IsBuiltinType (MemberType
)){
6099 Report
.Error (523, Location
, "Struct member `" + Parent
.Name
+ "." + Name
+
6100 "' causes a cycle in the structure layout");
6105 FieldBuilder
= Parent
.TypeBuilder
.DefineField (
6106 Name
, MemberType
, Modifiers
.FieldAttr (ModFlags
));
6108 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
6110 catch (ArgumentException
) {
6111 Report
.Warning (-24, 1, Location
, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
6115 if (initializer
!= null)
6116 Parent
.PartialContainer
.RegisterFieldForInitialization (this,
6117 new FieldInitializer (FieldBuilder
, initializer
, Parent
));
6122 protected override bool VerifyClsCompliance ()
6124 if (!base.VerifyClsCompliance ())
6127 if ((ModFlags
& Modifiers
.VOLATILE
) != 0) {
6128 Report
.Warning (3026, 1, Location
, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
6136 // `set' and `get' accessors are represented with an Accessor.
6138 public class Accessor
: IAnonymousHost
{
6140 // Null if the accessor is empty, or a Block if not
6142 public const int AllowedModifiers
=
6144 Modifiers
.PROTECTED
|
6145 Modifiers
.INTERNAL
|
6148 public ToplevelBlock Block
;
6149 public Attributes Attributes
;
6150 public Location Location
;
6151 public int ModFlags
;
6153 public ArrayList AnonymousMethods
;
6155 public Accessor (ToplevelBlock b
, int mod
, Attributes attrs
, Location loc
)
6160 ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, 0, loc
);
6163 public void SetYields ()
6168 public void AddAnonymousMethod (AnonymousMethodExpression ame
)
6170 if (AnonymousMethods
== null)
6171 AnonymousMethods
= new ArrayList ();
6172 AnonymousMethods
.Add (ame
);
6176 // Ooouh Martin, templates are missing here.
6177 // When it will be possible move here a lot of child code and template method type.
6178 public abstract class AbstractPropertyEventMethod
: MemberCore
, IMethodData
{
6179 protected MethodData method_data
;
6180 protected ToplevelBlock block
;
6181 protected ListDictionary declarative_security
;
6183 // The accessor are created event if they are not wanted.
6184 // But we need them because their names are reserved.
6185 // Field says whether accessor will be emited or not
6186 public readonly bool IsDummy
;
6188 protected readonly string prefix
;
6190 ReturnParameter return_attributes
;
6192 public AbstractPropertyEventMethod (PropertyBasedMember member
, string prefix
)
6193 : base (member
.Parent
, SetupName (prefix
, member
, member
.Location
), null)
6195 this.prefix
= prefix
;
6199 public AbstractPropertyEventMethod (InterfaceMemberBase member
, Accessor accessor
,
6201 : base (member
.Parent
, SetupName (prefix
, member
, accessor
.Location
),
6202 accessor
.Attributes
)
6204 this.prefix
= prefix
;
6205 this.block
= accessor
.Block
;
6208 static MemberName
SetupName (string prefix
, InterfaceMemberBase member
, Location loc
)
6210 return new MemberName (member
.MemberName
.Left
, prefix
+ member
.ShortName
, loc
);
6213 public void UpdateName (InterfaceMemberBase member
)
6215 SetMemberName (SetupName (prefix
, member
, Location
));
6218 #region IMethodData Members
6220 public abstract Iterator Iterator
{
6224 public ToplevelBlock Block
{
6234 public CallingConventions CallingConventions
{
6236 return CallingConventions
.Standard
;
6240 public bool IsExcluded ()
6245 GenericMethod IMethodData
.GenericMethod
{
6251 public MemberName MethodName
{
6257 public Type
[] ParameterTypes
{
6259 return ParameterInfo
.Types
;
6263 public abstract Parameters ParameterInfo { get ; }
6264 public abstract Type ReturnType { get; }
6265 public abstract EmitContext
CreateEmitContext (DeclSpace ds
, ILGenerator ig
);
6269 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
6271 if (a
.Type
== TypeManager
.cls_compliant_attribute_type
|| a
.Type
== TypeManager
.obsolete_attribute_type
||
6272 a
.Type
== TypeManager
.conditional_attribute_type
) {
6273 Report
.Error (1667, a
.Location
,
6274 "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
6275 TypeManager
.CSharpName (a
.Type
), a
.GetValidTargets ());
6279 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
6280 if (declarative_security
== null)
6281 declarative_security
= new ListDictionary ();
6282 a
.ExtractSecurityPermissionSet (declarative_security
);
6286 if (a
.Target
== AttributeTargets
.Method
) {
6287 method_data
.MethodBuilder
.SetCustomAttribute (cb
);
6291 if (a
.Target
== AttributeTargets
.ReturnValue
) {
6292 if (return_attributes
== null)
6293 return_attributes
= new ReturnParameter (method_data
.MethodBuilder
, Location
);
6295 return_attributes
.ApplyAttributeBuilder (a
, cb
);
6299 ApplyToExtraTarget (a
, cb
);
6302 virtual protected void ApplyToExtraTarget (Attribute a
, CustomAttributeBuilder cb
)
6304 System
.Diagnostics
.Debug
.Fail ("You forgot to define special attribute target handling");
6307 // It is not supported for the accessors
6308 public sealed override bool Define()
6310 throw new NotSupportedException ();
6313 public void Emit (DeclSpace parent
)
6315 EmitMethod (parent
);
6318 if ((ModFlags
& Modifiers
.COMPILER_GENERATED
) != 0)
6319 method_data
.MethodBuilder
.SetCustomAttribute (TypeManager
.compiler_generated_attr
);
6321 if (OptAttributes
!= null)
6322 OptAttributes
.Emit ();
6324 if (declarative_security
!= null) {
6325 foreach (DictionaryEntry de
in declarative_security
) {
6326 method_data
.MethodBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
6333 protected virtual void EmitMethod (DeclSpace parent
)
6335 method_data
.Emit (parent
);
6338 public override bool IsClsComplianceRequired()
6343 public bool IsDuplicateImplementation (MethodCore method
)
6345 if (!MemberName
.Equals (method
.MemberName
))
6348 Type
[] param_types
= method
.ParameterTypes
;
6350 if (param_types
== null || param_types
.Length
!= ParameterTypes
.Length
)
6353 for (int i
= 0; i
< param_types
.Length
; i
++)
6354 if (param_types
[i
] != ParameterTypes
[i
])
6357 Report
.SymbolRelatedToPreviousError (method
);
6358 Report
.Error (111, Location
, TypeContainer
.Error111
, method
.GetSignatureForError ());
6362 public override bool IsUsed
6372 public new Location Location
{
6374 return base.Location
;
6378 public virtual bool ResolveMembers ()
6384 // Represents header string for documentation comment.
6386 public override string DocCommentHeader
{
6387 get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6393 // Properties and Indexers both generate PropertyBuilders, we use this to share
6394 // their common bits.
6396 abstract public class PropertyBase
: PropertyBasedMember
{
6398 public class GetMethod
: PropertyMethod
6400 static string[] attribute_targets
= new string [] { "method", "return" }
;
6402 public GetMethod (PropertyBase method
):
6403 base (method
, "get_")
6407 public GetMethod (PropertyBase method
, Accessor accessor
):
6408 base (method
, accessor
, "get_")
6412 public override MethodBuilder
Define (DeclSpace parent
)
6414 if (!CheckForDuplications ())
6420 base.Define (parent
);
6422 method_data
= new MethodData (method
, ModFlags
, flags
, this);
6424 if (!method_data
.Define (parent
))
6427 return method_data
.MethodBuilder
;
6430 public override Type ReturnType
{
6432 return method
.MemberType
;
6436 public override Parameters ParameterInfo
{
6438 return Parameters
.EmptyReadOnlyParameters
;
6442 public override string[] ValidAttributeTargets
{
6444 return attribute_targets
;
6449 public class SetMethod
: PropertyMethod
{
6451 static string[] attribute_targets
= new string [] { "method", "param", "return" }
;
6452 ImplicitParameter param_attr
;
6453 protected Parameters parameters
;
6455 public SetMethod (PropertyBase method
):
6456 base (method
, "set_")
6460 public SetMethod (PropertyBase method
, Accessor accessor
):
6461 base (method
, accessor
, "set_")
6465 protected override void ApplyToExtraTarget(Attribute a
, CustomAttributeBuilder cb
)
6467 if (a
.Target
== AttributeTargets
.Parameter
) {
6468 if (param_attr
== null)
6469 param_attr
= new ImplicitParameter (method_data
.MethodBuilder
);
6471 param_attr
.ApplyAttributeBuilder (a
, cb
);
6475 base.ApplyAttributeBuilder (a
, cb
);
6478 public override Parameters ParameterInfo
{
6480 if (parameters
== null)
6481 DefineParameters ();
6486 protected virtual void DefineParameters ()
6488 parameters
= new Parameters (
6489 new Parameter
[] { new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location) }
,
6490 new Type
[] { method.MemberType }
);
6493 public override MethodBuilder
Define (DeclSpace parent
)
6495 if (!CheckForDuplications ())
6501 base.Define (parent
);
6503 method_data
= new MethodData (method
, ModFlags
, flags
, this);
6505 if (!method_data
.Define (parent
))
6508 return method_data
.MethodBuilder
;
6511 public override Type ReturnType
{
6513 return TypeManager
.void_type
;
6517 public override string[] ValidAttributeTargets
{
6519 return attribute_targets
;
6524 static string[] attribute_targets
= new string [] { "property" }
;
6526 public abstract class PropertyMethod
: AbstractPropertyEventMethod
6528 protected readonly PropertyBase method
;
6529 protected MethodAttributes flags
;
6531 ArrayList anonymous_methods
;
6534 public PropertyMethod (PropertyBase method
, string prefix
)
6535 : base (method
, prefix
)
6537 this.method
= method
;
6540 public PropertyMethod (PropertyBase method
, Accessor accessor
,
6542 : base (method
, accessor
, prefix
)
6544 this.method
= method
;
6545 this.ModFlags
= accessor
.ModFlags
;
6546 yields
= accessor
.Yields
;
6547 anonymous_methods
= accessor
.AnonymousMethods
;
6549 if (accessor
.ModFlags
!= 0 && RootContext
.Version
== LanguageVersion
.ISO_1
) {
6550 Report
.FeatureIsNotISO1 (Location
, "access modifiers on properties");
6554 public override Iterator Iterator
{
6555 get { return iterator; }
6558 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
6560 if (a
.IsInternalMethodImplAttribute
) {
6561 method
.is_external_implementation
= true;
6564 base.ApplyAttributeBuilder (a
, cb
);
6567 public override AttributeTargets AttributeTargets
{
6569 return AttributeTargets
.Method
;
6573 public override bool IsClsComplianceRequired ()
6575 return method
.IsClsComplianceRequired ();
6578 public override bool ResolveMembers ()
6581 iterator
= Iterator
.CreateIterator (this, Parent
, null, ModFlags
);
6582 if (iterator
== null)
6586 if (anonymous_methods
!= null) {
6587 foreach (AnonymousMethodExpression ame
in anonymous_methods
) {
6588 if (!ame
.CreateAnonymousHelpers ())
6596 public virtual MethodBuilder
Define (DeclSpace parent
)
6598 if (!method
.CheckAbstractAndExtern (block
!= null))
6601 TypeContainer container
= parent
.PartialContainer
;
6604 // Check for custom access modifier
6606 if ((ModFlags
& Modifiers
.Accessibility
) == 0) {
6607 ModFlags
|= method
.ModFlags
;
6608 flags
= method
.flags
;
6610 if (container
.Kind
== Kind
.Interface
)
6611 Report
.Error (275, Location
, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6612 GetSignatureForError ());
6614 if ((method
.ModFlags
& Modifiers
.ABSTRACT
) != 0 && (ModFlags
& Modifiers
.PRIVATE
) != 0) {
6615 Report
.Error (442, Location
, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6618 CheckModifiers (ModFlags
);
6619 ModFlags
|= (method
.ModFlags
& (~Modifiers
.Accessibility
));
6620 ModFlags
|= Modifiers
.PROPERTY_CUSTOM
;
6621 flags
= Modifiers
.MethodAttr (ModFlags
);
6622 flags
|= (method
.flags
& (~MethodAttributes
.MemberAccessMask
));
6628 public bool HasCustomAccessModifier
6631 return (ModFlags
& Modifiers
.PROPERTY_CUSTOM
) != 0;
6635 public override EmitContext
CreateEmitContext (DeclSpace ds
, ILGenerator ig
)
6637 return new EmitContext (method
,
6638 ds
, method
.ds
, method
.Location
, ig
, ReturnType
,
6639 method
.ModFlags
, false);
6642 public override ObsoleteAttribute
GetObsoleteAttribute ()
6644 return method
.GetObsoleteAttribute ();
6647 public override string GetSignatureForError()
6649 return method
.GetSignatureForError () + '.' + prefix
.Substring (0, 3);
6652 void CheckModifiers (int modflags
)
6654 modflags
&= Modifiers
.Accessibility
;
6656 int mflags
= method
.ModFlags
& Modifiers
.Accessibility
;
6658 if ((mflags
& Modifiers
.PUBLIC
) != 0) {
6659 flags
|= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
| Modifiers
.PRIVATE
;
6661 else if ((mflags
& Modifiers
.PROTECTED
) != 0) {
6662 if ((mflags
& Modifiers
.INTERNAL
) != 0)
6663 flags
|= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
;
6665 flags
|= Modifiers
.PRIVATE
;
6667 else if ((mflags
& Modifiers
.INTERNAL
) != 0)
6668 flags
|= Modifiers
.PRIVATE
;
6670 if ((mflags
== modflags
) || (modflags
& (~flags
)) != 0) {
6671 Report
.Error (273, Location
,
6672 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6673 GetSignatureForError (), method
.GetSignatureForError ());
6677 public override bool MarkForDuplicationCheck ()
6679 caching_flags
|= Flags
.TestMethodDuplication
;
6683 protected bool CheckForDuplications ()
6685 if ((caching_flags
& Flags
.TestMethodDuplication
) == 0)
6688 ArrayList ar
= Parent
.PartialContainer
.Methods
;
6690 int arLen
= ar
.Count
;
6692 for (int i
= 0; i
< arLen
; i
++) {
6693 Method m
= (Method
) ar
[i
];
6694 if (IsDuplicateImplementation (m
))
6703 public PropertyMethod Get
, Set
;
6704 public PropertyBuilder PropertyBuilder
;
6705 public MethodBuilder GetBuilder
, SetBuilder
;
6707 protected bool define_set_first
= false;
6709 public PropertyBase (DeclSpace parent
, Expression type
, int mod_flags
,
6710 int allowed_mod
, bool is_iface
, MemberName name
,
6711 Attributes attrs
, bool define_set_first
)
6712 : base (parent
, null, type
, mod_flags
, allowed_mod
, is_iface
, name
, attrs
)
6714 this.define_set_first
= define_set_first
;
6717 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
6719 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
)) {
6720 a
.Error_InvalidSecurityParent ();
6724 PropertyBuilder
.SetCustomAttribute (cb
);
6727 public override AttributeTargets AttributeTargets
{
6729 return AttributeTargets
.Property
;
6733 public override bool Define ()
6738 if (!IsTypePermitted ())
6744 protected override bool DoDefine ()
6746 if (!base.DoDefine ())
6750 // Accessors modifiers check
6752 if ((Get
.ModFlags
& Modifiers
.Accessibility
) != 0 &&
6753 (Set
.ModFlags
& Modifiers
.Accessibility
) != 0) {
6754 Report
.Error (274, Location
, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6755 GetSignatureForError ());
6759 if ((Get
.IsDummy
|| Set
.IsDummy
)
6760 && (Get
.ModFlags
!= 0 || Set
.ModFlags
!= 0) && (ModFlags
& Modifiers
.OVERRIDE
) == 0) {
6761 Report
.Error (276, Location
,
6762 "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6763 GetSignatureForError ());
6767 if (MemberType
.IsAbstract
&& MemberType
.IsSealed
) {
6768 Report
.Error (722, Location
, Error722
, TypeManager
.CSharpName (MemberType
));
6777 GetBuilder
= Get
.Define (Parent
);
6778 return (Get
.IsDummy
) ? true : GetBuilder
!= null;
6781 bool DefineSet (bool define
)
6786 SetBuilder
= Set
.Define (Parent
);
6787 return (Set
.IsDummy
) ? true : SetBuilder
!= null;
6790 protected bool DefineAccessors ()
6792 return DefineSet (define_set_first
) &&
6794 DefineSet (!define_set_first
);
6797 protected abstract PropertyInfo
ResolveBaseProperty ();
6799 // TODO: rename to Resolve......
6800 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
6802 PropertyInfo base_property
= ResolveBaseProperty ();
6803 if (base_property
== null)
6806 base_ret_type
= base_property
.PropertyType
;
6807 MethodInfo get_accessor
= base_property
.GetGetMethod (true);
6808 MethodInfo set_accessor
= base_property
.GetSetMethod (true);
6809 MethodAttributes get_accessor_access
, set_accessor_access
;
6811 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
6812 if (Get
!= null && !Get
.IsDummy
&& get_accessor
== null) {
6813 Report
.SymbolRelatedToPreviousError (base_property
);
6814 Report
.Error (545, Location
, "`{0}.get': cannot override because `{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager
.GetFullNameSignature (base_property
));
6817 if (Set
!= null && !Set
.IsDummy
&& set_accessor
== null) {
6818 Report
.SymbolRelatedToPreviousError (base_property
);
6819 Report
.Error (546, Location
, "`{0}.set': cannot override because `{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager
.GetFullNameSignature (base_property
));
6824 // Check base class accessors access
6827 // TODO: rewrite to reuse Get|Set.CheckAccessModifiers and share code there
6828 get_accessor_access
= set_accessor_access
= 0;
6829 if ((ModFlags
& Modifiers
.NEW
) == 0) {
6830 if (get_accessor
!= null) {
6831 MethodAttributes get_flags
= Modifiers
.MethodAttr (Get
.ModFlags
!= 0 ? Get
.ModFlags
: ModFlags
);
6832 get_accessor_access
= (get_accessor
.Attributes
& MethodAttributes
.MemberAccessMask
);
6834 if (!Get
.IsDummy
&& !CheckAccessModifiers (get_flags
& MethodAttributes
.MemberAccessMask
, get_accessor_access
, get_accessor
))
6835 Error_CannotChangeAccessModifiers (get_accessor
, get_accessor_access
, ".get");
6838 if (set_accessor
!= null) {
6839 MethodAttributes set_flags
= Modifiers
.MethodAttr (Set
.ModFlags
!= 0 ? Set
.ModFlags
: ModFlags
);
6840 set_accessor_access
= (set_accessor
.Attributes
& MethodAttributes
.MemberAccessMask
);
6842 if (!Set
.IsDummy
&& !CheckAccessModifiers (set_flags
& MethodAttributes
.MemberAccessMask
, set_accessor_access
, set_accessor
))
6843 Error_CannotChangeAccessModifiers (set_accessor
, set_accessor_access
, ".set");
6847 // When one accessor does not exist and property hides base one
6848 // we need to propagate this upwards
6849 if (set_accessor
== null)
6850 set_accessor
= get_accessor
;
6853 // Get the less restrictive access
6855 return get_accessor_access
> set_accessor_access
? get_accessor
: set_accessor
;
6858 public override void Emit ()
6861 // The PropertyBuilder can be null for explicit implementations, in that
6862 // case, we do not actually emit the ".property", so there is nowhere to
6863 // put the attribute
6865 if (PropertyBuilder
!= null && OptAttributes
!= null)
6866 OptAttributes
.Emit ();
6878 /// Tests whether accessors are not in collision with some method (CS0111)
6880 public bool AreAccessorsDuplicateImplementation (MethodCore mc
)
6882 return Get
.IsDuplicateImplementation (mc
) || Set
.IsDuplicateImplementation (mc
);
6885 public override bool IsUsed
6891 return Get
.IsUsed
| Set
.IsUsed
;
6895 protected override void SetMemberName (MemberName new_name
)
6897 base.SetMemberName (new_name
);
6899 Get
.UpdateName (this);
6900 Set
.UpdateName (this);
6903 public override string[] ValidAttributeTargets
{
6905 return attribute_targets
;
6910 // Represents header string for documentation comment.
6912 public override string DocCommentHeader
{
6913 get { return "P:"; }
6917 public class Property
: PropertyBase
{
6918 const int AllowedModifiers
=
6921 Modifiers
.PROTECTED
|
6922 Modifiers
.INTERNAL
|
6926 Modifiers
.OVERRIDE
|
6927 Modifiers
.ABSTRACT
|
6930 Modifiers
.METHOD_YIELDS
|
6933 const int AllowedInterfaceModifiers
=
6936 void CreateAutomaticProperty (Block block
, Accessor get_block
, Accessor set_block
)
6939 Field field
= new Field (
6941 Modifiers
.COMPILER_GENERATED
| Modifiers
.PRIVATE
| (ModFlags
& Modifiers
.STATIC
),
6942 CompilerGeneratedClass
.MakeName ("CompilerGeneratedField"),
6944 ((TypeContainer
)Parent
).AddField (field
);
6947 get_block
.Block
= new ToplevelBlock (block
, null, Location
);
6948 Return r
= new Return (new SimpleName(field
.Name
, Location
), Location
);
6949 get_block
.Block
.AddStatement (r
);
6950 get_block
.ModFlags
|= Modifiers
.COMPILER_GENERATED
;
6953 Parameters parameters
= new Parameters (new Parameter (Type
, "value", Parameter
.Modifier
.NONE
, null, Location
));
6954 set_block
.Block
= new ToplevelBlock (block
, parameters
, Location
);
6955 Assign a
= new Assign (new SimpleName(field
.Name
, Location
), new SimpleName ("value", Location
));
6956 set_block
.Block
.AddStatement (new StatementExpression(a
));
6957 set_block
.ModFlags
|= Modifiers
.COMPILER_GENERATED
;
6960 public Property (DeclSpace parent
, Expression type
, int mod
, bool is_iface
,
6961 MemberName name
, Attributes attrs
, Accessor get_block
,
6962 Accessor set_block
, bool define_set_first
)
6963 : this (parent
, type
, mod
, is_iface
, name
, attrs
, get_block
, set_block
,
6964 define_set_first
, null)
6968 public Property (DeclSpace parent
, Expression type
, int mod
, bool is_iface
,
6969 MemberName name
, Attributes attrs
, Accessor get_block
,
6970 Accessor set_block
, bool define_set_first
, Block current_block
)
6971 : base (parent
, type
, mod
,
6972 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
6973 is_iface
, name
, attrs
, define_set_first
)
6975 if (RootContext
.Version
>= LanguageVersion
.LINQ
&&
6977 (mod
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) == 0 &&
6978 get_block
!= null && get_block
.Block
== null &&
6979 set_block
!= null && set_block
.Block
== null)
6980 CreateAutomaticProperty (current_block
, get_block
, set_block
);
6982 if (get_block
== null)
6983 Get
= new GetMethod (this);
6985 Get
= new GetMethod (this, get_block
);
6987 if (set_block
== null)
6988 Set
= new SetMethod (this);
6990 Set
= new SetMethod (this, set_block
);
6993 public override bool Define ()
6995 if (!DoDefineBase ())
6998 if (!base.Define ())
7004 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
7006 if (!DefineAccessors ())
7009 // FIXME - PropertyAttributes.HasDefault ?
7011 PropertyBuilder
= Parent
.TypeBuilder
.DefineProperty (
7012 MemberName
.ToString (), PropertyAttributes
.None
, MemberType
, null);
7015 PropertyBuilder
.SetGetMethod (GetBuilder
);
7018 PropertyBuilder
.SetSetMethod (SetBuilder
);
7020 TypeManager
.RegisterProperty (PropertyBuilder
, this);
7024 protected override PropertyInfo
ResolveBaseProperty ()
7026 return Parent
.PartialContainer
.BaseCache
.FindMemberToOverride (
7027 Parent
.TypeBuilder
, Name
, Parameters
.EmptyReadOnlyParameters
.Types
, null, true) as PropertyInfo
;
7032 /// Gigantic workaround for lameness in SRE follows :
7033 /// This class derives from EventInfo and attempts to basically
7034 /// wrap around the EventBuilder so that FindMembers can quickly
7035 /// return this in it search for members
7037 public class MyEventBuilder
: EventInfo
{
7040 // We use this to "point" to our Builder which is
7041 // not really a MemberInfo
7043 EventBuilder MyBuilder
;
7046 // We "catch" and wrap these methods
7048 MethodInfo raise
, remove, add;
7050 EventAttributes attributes
;
7051 Type declaring_type
, reflected_type
, event_type
;
7056 public MyEventBuilder (Event ev
, TypeBuilder type_builder
, string name
, EventAttributes event_attr
, Type event_type
)
7058 MyBuilder
= type_builder
.DefineEvent (name
, event_attr
, event_type
);
7060 // And now store the values in our own fields.
7062 declaring_type
= type_builder
;
7064 reflected_type
= type_builder
;
7066 attributes
= event_attr
;
7069 this.event_type
= event_type
;
7073 // Methods that you have to override. Note that you only need
7074 // to "implement" the variants that take the argument (those are
7075 // the "abstract" methods, the others (GetAddMethod()) are
7078 public override MethodInfo
GetAddMethod (bool nonPublic
)
7083 public override MethodInfo
GetRemoveMethod (bool nonPublic
)
7088 public override MethodInfo
GetRaiseMethod (bool nonPublic
)
7094 // These methods make "MyEventInfo" look like a Builder
7096 public void SetRaiseMethod (MethodBuilder raiseMethod
)
7098 raise
= raiseMethod
;
7099 MyBuilder
.SetRaiseMethod (raiseMethod
);
7102 public void SetRemoveOnMethod (MethodBuilder removeMethod
)
7104 remove = removeMethod
;
7105 MyBuilder
.SetRemoveOnMethod (removeMethod
);
7108 public void SetAddOnMethod (MethodBuilder addMethod
)
7111 MyBuilder
.SetAddOnMethod (addMethod
);
7114 public void SetCustomAttribute (CustomAttributeBuilder cb
)
7116 MyBuilder
.SetCustomAttribute (cb
);
7119 public override object [] GetCustomAttributes (bool inherit
)
7121 // FIXME : There's nothing which can be seemingly done here because
7122 // we have no way of getting at the custom attribute objects of the
7127 public override object [] GetCustomAttributes (Type t
, bool inherit
)
7129 // FIXME : Same here !
7133 public override bool IsDefined (Type t
, bool b
)
7138 public override EventAttributes Attributes
{
7144 public override string Name
{
7150 public override Type DeclaringType
{
7152 return declaring_type
;
7156 public override Type ReflectedType
{
7158 return reflected_type
;
7162 public Type EventType
{
7168 public void SetUsed ()
7170 if (my_event
!= null) {
7171 // my_event.SetAssigned ();
7172 my_event
.SetMemberIsUsed ();
7178 /// For case when event is declared like property (with add and remove accessors).
7180 public class EventProperty
: Event
{
7181 abstract class AEventPropertyAccessor
: AEventAccessor
7183 readonly ArrayList anonymous_methods
;
7185 public AEventPropertyAccessor (Event method
, Accessor accessor
, string prefix
):
7186 base (method
, accessor
, prefix
)
7188 this.anonymous_methods
= accessor
.AnonymousMethods
;
7191 public override MethodBuilder
Define (DeclSpace ds
)
7193 method
.CheckAbstractAndExtern (block
!= null);
7194 return base.Define (ds
);
7197 public override bool ResolveMembers ()
7199 if (anonymous_methods
== null)
7202 foreach (AnonymousMethodExpression ame
in anonymous_methods
) {
7203 if (!ame
.CreateAnonymousHelpers ())
7212 sealed class AddDelegateMethod
: AEventPropertyAccessor
7214 public AddDelegateMethod (Event method
, Accessor accessor
):
7215 base (method
, accessor
, "add_")
7219 protected override MethodInfo DelegateMethodInfo
{
7221 return TypeManager
.delegate_combine_delegate_delegate
;
7226 sealed class RemoveDelegateMethod
: AEventPropertyAccessor
7228 public RemoveDelegateMethod (Event method
, Accessor accessor
):
7229 base (method
, accessor
, "remove_")
7233 protected override MethodInfo DelegateMethodInfo
{
7235 return TypeManager
.delegate_remove_delegate_delegate
;
7241 static readonly string[] attribute_targets
= new string [] { "event" }
; // "property" target was disabled for 2.0 version
7243 public EventProperty (DeclSpace parent
, Expression type
, int mod_flags
,
7244 bool is_iface
, MemberName name
,
7245 Attributes attrs
, Accessor
add, Accessor
remove)
7246 : base (parent
, type
, mod_flags
, is_iface
, name
, attrs
)
7248 Add
= new AddDelegateMethod (this, add);
7249 Remove
= new RemoveDelegateMethod (this, remove);
7252 public override bool Define()
7254 if (!base.Define ())
7263 public override string[] ValidAttributeTargets
{
7265 return attribute_targets
;
7271 /// Event is declared like field.
7273 public class EventField
: Event
{
7274 abstract class EventFieldAccessor
: AEventAccessor
7276 protected EventFieldAccessor (Event method
, string prefix
)
7277 : base (method
, prefix
)
7281 protected override void EmitMethod(DeclSpace parent
)
7283 if ((method
.ModFlags
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) != 0)
7286 MethodBuilder mb
= method_data
.MethodBuilder
;
7287 ILGenerator ig
= mb
.GetILGenerator ();
7289 // TODO: because we cannot use generics yet
7290 FieldInfo field_info
= ((EventField
)method
).FieldBuilder
;
7292 mb
.SetImplementationFlags (mb
.GetMethodImplementationFlags () | MethodImplAttributes
.Synchronized
);
7293 if ((method
.ModFlags
& Modifiers
.STATIC
) != 0) {
7294 ig
.Emit (OpCodes
.Ldsfld
, field_info
);
7295 ig
.Emit (OpCodes
.Ldarg_0
);
7296 ig
.Emit (OpCodes
.Call
, DelegateMethodInfo
);
7297 ig
.Emit (OpCodes
.Castclass
, method
.MemberType
);
7298 ig
.Emit (OpCodes
.Stsfld
, field_info
);
7300 ig
.Emit (OpCodes
.Ldarg_0
);
7301 ig
.Emit (OpCodes
.Ldarg_0
);
7302 ig
.Emit (OpCodes
.Ldfld
, field_info
);
7303 ig
.Emit (OpCodes
.Ldarg_1
);
7304 ig
.Emit (OpCodes
.Call
, DelegateMethodInfo
);
7305 ig
.Emit (OpCodes
.Castclass
, method
.MemberType
);
7306 ig
.Emit (OpCodes
.Stfld
, field_info
);
7308 ig
.Emit (OpCodes
.Ret
);
7312 sealed class AddDelegateMethod
: EventFieldAccessor
7314 public AddDelegateMethod (Event method
):
7315 base (method
, "add_")
7319 protected override MethodInfo DelegateMethodInfo
{
7321 return TypeManager
.delegate_combine_delegate_delegate
;
7326 sealed class RemoveDelegateMethod
: EventFieldAccessor
7328 public RemoveDelegateMethod (Event method
):
7329 base (method
, "remove_")
7333 protected override MethodInfo DelegateMethodInfo
{
7335 return TypeManager
.delegate_remove_delegate_delegate
;
7341 static readonly string[] attribute_targets
= new string [] { "event", "field", "method" }
;
7342 static readonly string[] attribute_targets_interface
= new string[] { "event", "method" }
;
7344 public FieldBuilder FieldBuilder
;
7345 public Expression Initializer
;
7347 public EventField (DeclSpace parent
, Expression type
, int mod_flags
,
7348 bool is_iface
, MemberName name
,
7350 : base (parent
, type
, mod_flags
, is_iface
, name
, attrs
)
7352 Add
= new AddDelegateMethod (this);
7353 Remove
= new RemoveDelegateMethod (this);
7356 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
7358 if (a
.Target
== AttributeTargets
.Field
) {
7359 FieldBuilder
.SetCustomAttribute (cb
);
7363 if (a
.Target
== AttributeTargets
.Method
) {
7364 int errors
= Report
.Errors
;
7365 Add
.ApplyAttributeBuilder (a
, cb
);
7366 if (errors
== Report
.Errors
)
7367 Remove
.ApplyAttributeBuilder (a
, cb
);
7371 base.ApplyAttributeBuilder (a
, cb
);
7374 public override bool Define()
7376 if (!base.Define ())
7382 // FIXME: We are unable to detect whether generic event is used because
7383 // we are using FieldExpr instead of EventExpr for event access in that
7384 // case. When this issue will be fixed this hack can be removed.
7385 if (TypeManager
.IsGenericType (MemberType
))
7388 FieldBuilder
= Parent
.TypeBuilder
.DefineField (
7390 FieldAttributes
.Private
| ((ModFlags
& Modifiers
.STATIC
) != 0 ? FieldAttributes
.Static
: 0));
7391 TypeManager
.RegisterEventField (EventBuilder
, this);
7393 if (Initializer
!= null) {
7394 if (((ModFlags
& Modifiers
.ABSTRACT
) != 0)) {
7395 Report
.Error (74, Location
, "`{0}': abstract event cannot have an initializer",
7396 GetSignatureForError ());
7400 Parent
.PartialContainer
.RegisterFieldForInitialization (this,
7401 new FieldInitializer (FieldBuilder
, Initializer
, Parent
));
7407 public override string[] ValidAttributeTargets
7410 return IsInterface
? attribute_targets_interface
: attribute_targets
;
7415 public abstract class Event
: PropertyBasedMember
{
7416 public abstract class AEventAccessor
: AbstractPropertyEventMethod
7418 protected readonly Event method
;
7419 ImplicitParameter param_attr
;
7421 static readonly string[] attribute_targets
= new string [] { "method", "param", "return" }
;
7423 protected AEventAccessor (Event method
, string prefix
)
7424 : base (method
, prefix
)
7426 this.method
= method
;
7429 protected AEventAccessor (Event method
, Accessor accessor
, string prefix
)
7430 : base (method
, accessor
, prefix
)
7432 this.method
= method
;
7435 public override Iterator Iterator
{
7436 get { return null; }
7439 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
7441 if (a
.IsInternalMethodImplAttribute
) {
7442 method
.is_external_implementation
= true;
7445 base.ApplyAttributeBuilder (a
, cb
);
7448 protected override void ApplyToExtraTarget(Attribute a
, CustomAttributeBuilder cb
)
7450 if (a
.Target
== AttributeTargets
.Parameter
) {
7451 if (param_attr
== null)
7452 param_attr
= new ImplicitParameter (method_data
.MethodBuilder
);
7454 param_attr
.ApplyAttributeBuilder (a
, cb
);
7458 base.ApplyAttributeBuilder (a
, cb
);
7461 public override AttributeTargets AttributeTargets
{
7463 return AttributeTargets
.Method
;
7467 public override bool IsClsComplianceRequired ()
7469 return method
.IsClsComplianceRequired ();
7472 public virtual MethodBuilder
Define (DeclSpace parent
)
7474 method_data
= new MethodData (method
, method
.ModFlags
,
7475 method
.flags
| MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
, this);
7477 if (!method_data
.Define (parent
))
7480 MethodBuilder mb
= method_data
.MethodBuilder
;
7481 ParameterInfo
.ApplyAttributes (mb
);
7485 protected abstract MethodInfo DelegateMethodInfo { get; }
7487 public override Type ReturnType
{
7489 return TypeManager
.void_type
;
7493 public override EmitContext
CreateEmitContext (DeclSpace ds
, ILGenerator ig
)
7495 return new EmitContext (
7496 ds
, method
.Parent
, Location
, ig
, ReturnType
,
7497 method
.ModFlags
, false);
7500 public override ObsoleteAttribute
GetObsoleteAttribute ()
7502 return method
.GetObsoleteAttribute ();
7505 public override string[] ValidAttributeTargets
{
7507 return attribute_targets
;
7511 public override Parameters ParameterInfo
{
7513 return method
.parameters
;
7519 const int AllowedModifiers
=
7522 Modifiers
.PROTECTED
|
7523 Modifiers
.INTERNAL
|
7528 Modifiers
.OVERRIDE
|
7530 Modifiers
.ABSTRACT
|
7533 const int AllowedInterfaceModifiers
=
7536 public AEventAccessor Add
, Remove
;
7537 public MyEventBuilder EventBuilder
;
7538 public MethodBuilder AddBuilder
, RemoveBuilder
;
7540 Parameters parameters
;
7542 protected Event (DeclSpace parent
, Expression type
, int mod_flags
,
7543 bool is_iface
, MemberName name
, Attributes attrs
)
7544 : base (parent
, null, type
, mod_flags
,
7545 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
, is_iface
,
7550 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
7552 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
)) {
7553 a
.Error_InvalidSecurityParent ();
7557 EventBuilder
.SetCustomAttribute (cb
);
7560 public bool AreAccessorsDuplicateImplementation (MethodCore mc
)
7562 return Add
.IsDuplicateImplementation (mc
) || Remove
.IsDuplicateImplementation (mc
);
7565 public override AttributeTargets AttributeTargets
{
7567 return AttributeTargets
.Event
;
7571 public override bool Define ()
7573 if (!DoDefineBase ())
7579 if (!TypeManager
.IsDelegateType (MemberType
)) {
7580 Report
.Error (66, Location
, "`{0}': event must be of a delegate type", GetSignatureForError ());
7584 parameters
= new Parameters (
7585 new Parameter
[] { new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location) }
,
7586 new Type
[] { MemberType }
);
7592 // Now define the accessors
7595 AddBuilder
= Add
.Define (Parent
);
7596 if (AddBuilder
== null)
7599 RemoveBuilder
= Remove
.Define (Parent
);
7600 if (RemoveBuilder
== null)
7603 EventBuilder
= new MyEventBuilder (this, Parent
.TypeBuilder
, Name
, EventAttributes
.None
, MemberType
);
7604 EventBuilder
.SetAddOnMethod (AddBuilder
);
7605 EventBuilder
.SetRemoveOnMethod (RemoveBuilder
);
7609 public override void Emit ()
7611 if (OptAttributes
!= null) {
7612 OptAttributes
.Emit ();
7616 Remove
.Emit (Parent
);
7621 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
7623 MethodInfo mi
= (MethodInfo
) Parent
.PartialContainer
.BaseCache
.FindBaseEvent (
7624 Parent
.TypeBuilder
, Name
);
7629 ParameterData pd
= TypeManager
.GetParameterData (mi
);
7630 base_ret_type
= pd
.ParameterType (0);
7635 // Represents header string for documentation comment.
7637 public override string DocCommentHeader
{
7638 get { return "E:"; }
7643 public class Indexer
: PropertyBase
{
7645 class GetIndexerMethod
: GetMethod
7647 public GetIndexerMethod (PropertyBase method
):
7652 public GetIndexerMethod (PropertyBase method
, Accessor accessor
):
7653 base (method
, accessor
)
7657 public override Parameters ParameterInfo
{
7659 return ((Indexer
)method
).parameters
;
7664 class SetIndexerMethod
: SetMethod
7666 public SetIndexerMethod (PropertyBase method
):
7671 public SetIndexerMethod (PropertyBase method
, Accessor accessor
):
7672 base (method
, accessor
)
7676 protected override void DefineParameters ()
7678 parameters
= Parameters
.MergeGenerated (((Indexer
)method
).parameters
,
7679 new Parameter (method
.MemberType
, "value", Parameter
.Modifier
.NONE
, null, method
.Location
));
7683 const int AllowedModifiers
=
7686 Modifiers
.PROTECTED
|
7687 Modifiers
.INTERNAL
|
7691 Modifiers
.OVERRIDE
|
7696 const int AllowedInterfaceModifiers
=
7699 public readonly Parameters parameters
;
7701 public Indexer (DeclSpace parent
, Expression type
, MemberName name
, int mod
,
7702 bool is_iface
, Parameters parameters
, Attributes attrs
,
7703 Accessor get_block
, Accessor set_block
, bool define_set_first
)
7704 : base (parent
, type
, mod
,
7705 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
7706 is_iface
, name
, attrs
, define_set_first
)
7708 this.parameters
= parameters
;
7710 if (get_block
== null)
7711 Get
= new GetIndexerMethod (this);
7713 Get
= new GetIndexerMethod (this, get_block
);
7715 if (set_block
== null)
7716 Set
= new SetIndexerMethod (this);
7718 Set
= new SetIndexerMethod (this, set_block
);
7721 protected override bool CheckForDuplications ()
7723 ArrayList ar
= Parent
.PartialContainer
.Indexers
;
7725 int arLen
= ar
.Count
;
7727 for (int i
= 0; i
< arLen
; i
++) {
7728 Indexer m
= (Indexer
) ar
[i
];
7729 if (IsDuplicateImplementation (m
))
7737 bool IsDuplicateImplementation (Indexer indexer
)
7739 if (this == indexer
)
7742 if (!MemberName
.Equals (indexer
.MemberName
))
7745 Type
[] param_types
= indexer
.parameters
.Types
;
7747 // When it is not yet defined
7748 if (param_types
== null)
7751 if (param_types
.Length
!= parameters
.Count
)
7754 for (int i
= 0; i
< param_types
.Length
; i
++)
7755 if (param_types
[i
] != parameters
.Types
[i
])
7758 Report
.SymbolRelatedToPreviousError (indexer
);
7759 Report
.Error (111, Location
, TypeContainer
.Error111
, indexer
.GetSignatureForError ());
7764 public override bool Define ()
7766 if (!DoDefineBase ())
7769 if (!base.Define ())
7772 if (!DefineParameters (parameters
))
7775 if (MemberType
== TypeManager
.void_type
) {
7776 Report
.Error (620, Location
, "Indexers cannot have void type");
7780 if (OptAttributes
!= null) {
7781 Attribute indexer_attr
= OptAttributes
.Search (TypeManager
.indexer_name_type
);
7782 if (indexer_attr
!= null) {
7783 // Remove the attribute from the list because it is not emitted
7784 OptAttributes
.Attrs
.Remove (indexer_attr
);
7786 string name
= indexer_attr
.GetIndexerAttributeValue ();
7792 if (IsExplicitImpl
) {
7793 Report
.Error (415, indexer_attr
.Location
,
7794 "The `IndexerName' attribute is valid only on an " +
7795 "indexer that is not an explicit interface member declaration");
7799 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
7800 Report
.Error (609, indexer_attr
.Location
,
7801 "Cannot set the `IndexerName' attribute on an indexer marked override");
7807 if (InterfaceType
!= null) {
7808 string base_IndexerName
= TypeManager
.IndexerPropertyName (InterfaceType
);
7809 if (base_IndexerName
!= Name
)
7810 ShortName
= base_IndexerName
;
7813 if (!Parent
.PartialContainer
.AddMember (this) ||
7814 !Parent
.PartialContainer
.AddMember (Get
) || !Parent
.PartialContainer
.AddMember (Set
))
7820 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
7822 if (!DefineAccessors ())
7826 // Setup iterator if we are one
7827 if ((ModFlags
& Modifiers
.METHOD_YIELDS
) != 0){
7828 Iterator iterator
= Iterator
.CreateIterator (Get
, Parent
, null, ModFlags
);
7829 if (iterator
== null)
7835 // Now name the parameters
7837 Parameter
[] p
= parameters
.FixedParameters
;
7839 // TODO: should be done in parser and it needs to do cycle
7840 if ((p
[0].ModFlags
& Parameter
.Modifier
.ISBYREF
) != 0) {
7841 CSharpParser
.Error_ParameterModifierNotValid (Location
);
7846 PropertyBuilder
= Parent
.TypeBuilder
.DefineProperty (
7847 Name
, PropertyAttributes
.None
, MemberType
, parameters
.Types
);
7850 PropertyBuilder
.SetGetMethod (GetBuilder
);
7853 PropertyBuilder
.SetSetMethod (SetBuilder
);
7855 TypeManager
.RegisterIndexer (PropertyBuilder
, GetBuilder
, SetBuilder
, parameters
.Types
);
7860 public override string GetDocCommentName (DeclSpace ds
)
7862 return DocUtil
.GetMethodDocCommentName (this, parameters
, ds
);
7865 public override string GetSignatureForError ()
7867 StringBuilder sb
= new StringBuilder (Parent
.GetSignatureForError ());
7868 if (MemberName
.Left
!= null) {
7870 sb
.Append (MemberName
.Left
);
7873 sb
.Append (".this");
7874 sb
.Append (parameters
.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7875 return sb
.ToString ();
7878 public override bool MarkForDuplicationCheck ()
7880 caching_flags
|= Flags
.TestMethodDuplication
;
7884 protected override PropertyInfo
ResolveBaseProperty ()
7886 return Parent
.PartialContainer
.BaseCache
.FindMemberToOverride (
7887 Parent
.TypeBuilder
, Name
, parameters
.Types
, null, true) as PropertyInfo
;
7890 protected override bool VerifyClsCompliance ()
7892 if (!base.VerifyClsCompliance ())
7895 parameters
.VerifyClsCompliance ();
7900 public class Operator
: MethodOrOperator
, IAnonymousHost
{
7902 const int AllowedModifiers
=
7908 public enum OpType
: byte {
7918 // Unary and Binary operators
7941 // Implicit and Explicit
7945 // Just because of enum
7949 public readonly OpType OperatorType
;
7951 public Operator (DeclSpace parent
, OpType type
, Expression ret_type
,
7952 int mod_flags
, Parameters parameters
,
7953 ToplevelBlock block
, Attributes attrs
, Location loc
)
7954 : base (parent
, null, ret_type
, mod_flags
, AllowedModifiers
, false,
7955 new MemberName ("op_" + type
.ToString(), loc
), attrs
, parameters
)
7957 OperatorType
= type
;
7961 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
7963 if (a
.Type
== TypeManager
.conditional_attribute_type
) {
7964 Error_ConditionalAttributeIsNotValid ();
7968 base.ApplyAttributeBuilder (a
, cb
);
7971 protected override bool CheckForDuplications ()
7973 ArrayList ar
= Parent
.PartialContainer
.Operators
;
7975 int arLen
= ar
.Count
;
7977 for (int i
= 0; i
< arLen
; i
++) {
7978 Operator o
= (Operator
) ar
[i
];
7979 if (IsDuplicateImplementation (o
))
7984 ar
= Parent
.PartialContainer
.Methods
;
7986 int arLen
= ar
.Count
;
7988 for (int i
= 0; i
< arLen
; i
++) {
7989 Method m
= (Method
) ar
[i
];
7990 if (IsDuplicateImplementation (m
))
7998 public override bool Define ()
8000 const int RequiredModifiers
= Modifiers
.PUBLIC
| Modifiers
.STATIC
;
8001 if ((ModFlags
& RequiredModifiers
) != RequiredModifiers
){
8002 Report
.Error (558, Location
, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
8006 // imlicit and explicit operator of same types are not allowed
8007 if (OperatorType
== OpType
.Explicit
|| OperatorType
== OpType
.Implicit
)
8008 MarkForDuplicationCheck ();
8010 if (!base.Define ())
8013 if (MemberType
== TypeManager
.void_type
) {
8014 Report
.Error (590, Location
, "User-defined operators cannot return void");
8018 Type declaring_type
= MethodData
.DeclaringType
;
8019 Type return_type
= MemberType
;
8020 Type first_arg_type
= ParameterTypes
[0];
8022 // Rules for conversion operators
8024 if (OperatorType
== OpType
.Implicit
|| OperatorType
== OpType
.Explicit
) {
8025 if (first_arg_type
== return_type
&& first_arg_type
== declaring_type
){
8026 Report
.Error (555, Location
,
8027 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
8031 if ((first_arg_type
!= declaring_type
) && (return_type
!= declaring_type
) &&
8032 !TypeManager
.IsNullableTypeOf (first_arg_type
, declaring_type
) &&
8033 !TypeManager
.IsNullableTypeOf (return_type
, declaring_type
)) {
8036 "User-defined conversion must convert to or from the " +
8041 if (first_arg_type
.IsInterface
|| return_type
.IsInterface
){
8042 Report
.Error (552, Location
, "User-defined conversion `{0}' cannot convert to or from an interface type",
8043 GetSignatureForError ());
8047 if (first_arg_type
.IsSubclassOf (return_type
) || return_type
.IsSubclassOf (first_arg_type
)) {
8048 if (declaring_type
.IsSubclassOf (return_type
) || declaring_type
.IsSubclassOf (first_arg_type
)) {
8049 Report
.Error (553, Location
, "User-defined conversion `{0}' cannot convert to or from base class",
8050 GetSignatureForError ());
8053 Report
.Error (554, Location
, "User-defined conversion `{0}' cannot convert to or from derived class",
8054 GetSignatureForError ());
8057 } else if (OperatorType
== OpType
.LeftShift
|| OperatorType
== OpType
.RightShift
) {
8058 if (first_arg_type
!= declaring_type
|| ParameterTypes
[1] != TypeManager
.int32_type
) {
8059 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");
8062 } else if (Parameters
.Count
== 1) {
8063 // Checks for Unary operators
8065 if (OperatorType
== OpType
.Increment
|| OperatorType
== OpType
.Decrement
) {
8066 if (return_type
!= declaring_type
&& !TypeManager
.IsSubclassOf (return_type
, declaring_type
)) {
8067 Report
.Error (448, Location
,
8068 "The return type for ++ or -- operator must be the containing type or derived from the containing type");
8071 if (first_arg_type
!= declaring_type
) {
8073 559, Location
, "The parameter type for ++ or -- operator must be the containing type");
8078 if (first_arg_type
!= declaring_type
){
8081 "The parameter of a unary operator must be the " +
8086 if (OperatorType
== OpType
.True
|| OperatorType
== OpType
.False
) {
8087 if (return_type
!= TypeManager
.bool_type
){
8090 "The return type of operator True or False " +
8097 // Checks for Binary operators
8099 if (first_arg_type
!= declaring_type
&&
8100 ParameterTypes
[1] != declaring_type
){
8103 "One of the parameters of a binary operator must " +
8104 "be the containing type");
8112 protected override bool DoDefine ()
8114 if (!base.DoDefine ())
8117 flags
|= MethodAttributes
.SpecialName
| MethodAttributes
.HideBySig
;
8121 public override void Emit ()
8125 Parameters
.ApplyAttributes (MethodBuilder
);
8128 // abstract or extern methods have no bodies
8130 if ((ModFlags
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) != 0)
8134 if ((flags
& MethodAttributes
.PinvokeImpl
) == 0)
8135 ec
= CreateEmitContext (Parent
, MethodBuilder
.GetILGenerator ());
8137 ec
= CreateEmitContext (Parent
, null);
8139 SourceMethod source
= SourceMethod
.Create (Parent
, MethodBuilder
, Block
);
8140 ec
.EmitTopBlock (this, Block
);
8143 source
.CloseMethod ();
8148 // Operator cannot be override
8149 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
8154 public static string GetName (OpType ot
)
8157 case OpType
.LogicalNot
:
8159 case OpType
.OnesComplement
:
8161 case OpType
.Increment
:
8163 case OpType
.Decrement
:
8169 case OpType
.Addition
:
8171 case OpType
.Subtraction
:
8173 case OpType
.UnaryPlus
:
8175 case OpType
.UnaryNegation
:
8177 case OpType
.Multiply
:
8179 case OpType
.Division
:
8181 case OpType
.Modulus
:
8183 case OpType
.BitwiseAnd
:
8185 case OpType
.BitwiseOr
:
8187 case OpType
.ExclusiveOr
:
8189 case OpType
.LeftShift
:
8191 case OpType
.RightShift
:
8193 case OpType
.Equality
:
8195 case OpType
.Inequality
:
8197 case OpType
.GreaterThan
:
8199 case OpType
.LessThan
:
8201 case OpType
.GreaterThanOrEqual
:
8203 case OpType
.LessThanOrEqual
:
8205 case OpType
.Implicit
:
8207 case OpType
.Explicit
:
8213 public static OpType
GetOperatorType (string name
)
8215 if (name
.StartsWith ("op_")){
8216 for (int i
= 0; i
< Unary
.oper_names
.Length
; ++i
) {
8217 if (Unary
.oper_names
[i
] == name
)
8221 for (int i
= 0; i
< Binary
.oper_names
.Length
; ++i
) {
8222 if (Binary
.oper_names
[i
] == name
)
8229 public override string GetSignatureForError ()
8231 StringBuilder sb
= new StringBuilder ();
8232 if (OperatorType
== OpType
.Implicit
|| OperatorType
== OpType
.Explicit
) {
8233 sb
.AppendFormat ("{0}.{1} operator {2}", Parent
.GetSignatureForError (), GetName (OperatorType
), Type
.Type
== null ? Type
.ToString () : TypeManager
.CSharpName (Type
.Type
));
8236 sb
.AppendFormat ("{0}.operator {1}", Parent
.GetSignatureForError (), GetName (OperatorType
));
8239 sb
.Append (Parameters
.GetSignatureForError ());
8240 return sb
.ToString ();
8245 // This is used to compare method signatures
8247 struct MethodSignature
{
8249 public Type RetType
;
8250 public Type
[] Parameters
;
8253 /// This delegate is used to extract methods which have the
8254 /// same signature as the argument
8256 public static MemberFilter method_signature_filter
= new MemberFilter (MemberSignatureCompare
);
8258 public MethodSignature (string name
, Type ret_type
, Type
[] parameters
)
8263 if (parameters
== null)
8264 Parameters
= Type
.EmptyTypes
;
8266 Parameters
= parameters
;
8269 public override string ToString ()
8272 if (Parameters
.Length
!= 0){
8273 System
.Text
.StringBuilder sb
= new System
.Text
.StringBuilder ();
8274 for (int i
= 0; i
< Parameters
.Length
; i
++){
8275 sb
.Append (Parameters
[i
]);
8276 if (i
+1 < Parameters
.Length
)
8279 pars
= sb
.ToString ();
8282 return String
.Format ("{0} {1} ({2})", RetType
, Name
, pars
);
8285 public override int GetHashCode ()
8287 return Name
.GetHashCode ();
8290 public override bool Equals (Object o
)
8292 MethodSignature other
= (MethodSignature
) o
;
8294 if (other
.Name
!= Name
)
8297 if (other
.RetType
!= RetType
)
8300 if (Parameters
== null){
8301 if (other
.Parameters
== null)
8306 if (other
.Parameters
== null)
8309 int c
= Parameters
.Length
;
8310 if (other
.Parameters
.Length
!= c
)
8313 for (int i
= 0; i
< c
; i
++)
8314 if (other
.Parameters
[i
] != Parameters
[i
])
8320 static bool MemberSignatureCompare (MemberInfo m
, object filter_criteria
)
8322 MethodSignature sig
= (MethodSignature
) filter_criteria
;
8324 if (m
.Name
!= sig
.Name
)
8328 MethodInfo mi
= m
as MethodInfo
;
8329 PropertyInfo pi
= m
as PropertyInfo
;
8332 ReturnType
= mi
.ReturnType
;
8333 else if (pi
!= null)
8334 ReturnType
= pi
.PropertyType
;
8339 // we use sig.RetType == null to mean `do not check the
8340 // method return value.
8342 if (sig
.RetType
!= null)
8343 if (ReturnType
!= sig
.RetType
)
8348 args
= TypeManager
.GetParameterData (mi
).Types
;
8350 args
= TypeManager
.GetArgumentTypes (pi
);
8351 Type
[] sigp
= sig
.Parameters
;
8353 if (args
.Length
!= sigp
.Length
)
8356 for (int i
= args
.Length
; i
> 0; ){
8358 if (args
[i
] != sigp
[i
])