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 MethodArrayList
: MemberCoreArrayList
99 CachedMethods cached_method
;
100 TypeContainer container
;
102 public MethodArrayList (TypeContainer container
)
104 this.container
= container
;
108 /// Method container contains Equals method
110 public bool HasEquals
{
112 cached_method
|= CachedMethods
.Equals
;
116 return (cached_method
& CachedMethods
.Equals
) != 0;
121 /// Method container contains GetHashCode method
123 public bool HasGetHashCode
{
125 cached_method
|= CachedMethods
.GetHashCode
;
129 return (cached_method
& CachedMethods
.GetHashCode
) != 0;
133 public override void DefineContainerMembers ()
135 base.DefineContainerMembers ();
137 if (HasEquals
&& !HasGetHashCode
) {
138 Report
.Warning (659, 3, container
.Location
, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container
.GetSignatureForError ());
143 public sealed class IndexerArrayList
: MemberCoreArrayList
146 /// The indexer name for this container
148 public string IndexerName
= DefaultIndexerName
;
150 bool seen_normal_indexers
= false;
152 TypeContainer container
;
154 public IndexerArrayList (TypeContainer container
)
156 this.container
= container
;
160 /// Defines the indexers, and also verifies that the IndexerNameAttribute in the
161 /// class is consistent. Either it is `Item' or it is the name defined by all the
162 /// indexers with the `IndexerName' attribute.
164 /// Turns out that the IndexerNameAttribute is applied to each indexer,
165 /// but it is never emitted, instead a DefaultMember attribute is attached
168 public override void DefineContainerMembers()
170 base.DefineContainerMembers ();
172 string class_indexer_name
= null;
175 // If there's both an explicit and an implicit interface implementation, the
176 // explicit one actually implements the interface while the other one is just
177 // a normal indexer. See bug #37714.
180 // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
181 foreach (Indexer i
in this) {
182 if (i
.InterfaceType
!= null) {
183 if (seen_normal_indexers
)
184 throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
188 seen_normal_indexers
= true;
190 if (class_indexer_name
== null) {
191 class_indexer_name
= i
.ShortName
;
195 if (i
.ShortName
!= class_indexer_name
)
196 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");
199 if (class_indexer_name
!= null)
200 IndexerName
= class_indexer_name
;
203 public override void Emit ()
207 if (!seen_normal_indexers
)
210 CustomAttributeBuilder cb
= new CustomAttributeBuilder (TypeManager
.default_member_ctor
, new string [] { IndexerName }
);
211 container
.TypeBuilder
.SetCustomAttribute (cb
);
215 public class OperatorArrayList
: MemberCoreArrayList
217 TypeContainer container
;
219 public OperatorArrayList (TypeContainer container
)
221 this.container
= container
;
225 // Operator pair checking
230 public Type ret_type
;
231 public Type type1
, type2
;
233 public Operator
.OpType ot
;
235 public OperatorEntry (int f
, Operator o
)
239 ret_type
= o
.MemberType
;
240 Type
[] pt
= o
.ParameterTypes
;
247 public override int GetHashCode ()
249 return ret_type
.GetHashCode ();
252 public override bool Equals (object o
)
254 OperatorEntry other
= (OperatorEntry
) o
;
256 if (other
.ret_type
!= ret_type
)
258 if (other
.type1
!= type1
)
260 if (other
.type2
!= type2
)
267 // Checks that some operators come in pairs:
273 // They are matched based on the return type and the argument types
275 void CheckPairedOperators ()
277 IDictionary pairs
= new HybridDictionary ();
278 Operator true_op
= null;
279 Operator false_op
= null;
280 bool has_equality_or_inequality
= false;
282 // Register all the operators we care about.
283 foreach (Operator op
in this){
286 // Skip erroneous code.
287 if (op
.MethodBuilder
== null)
290 switch (op
.OperatorType
){
291 case Operator
.OpType
.Equality
:
293 has_equality_or_inequality
= true;
295 case Operator
.OpType
.Inequality
:
297 has_equality_or_inequality
= true;
300 case Operator
.OpType
.True
:
303 case Operator
.OpType
.False
:
307 case Operator
.OpType
.GreaterThan
:
309 case Operator
.OpType
.LessThan
:
312 case Operator
.OpType
.GreaterThanOrEqual
:
314 case Operator
.OpType
.LessThanOrEqual
:
320 OperatorEntry oe
= new OperatorEntry (reg
, op
);
322 object o
= pairs
[oe
];
326 oe
= (OperatorEntry
) o
;
331 if (true_op
!= null){
332 if (false_op
== null)
333 Report
.Error (216, true_op
.Location
, "The operator `{0}' requires a matching operator `false' to also be defined",
334 true_op
.GetSignatureForError ());
335 } else if (false_op
!= null)
336 Report
.Error (216, false_op
.Location
, "The operator `{0}' requires a matching operator `true' to also be defined",
337 false_op
.GetSignatureForError ());
340 // Look for the mistakes.
342 foreach (DictionaryEntry de
in pairs
){
343 OperatorEntry oe
= (OperatorEntry
) de
.Key
;
350 case Operator
.OpType
.Equality
:
353 case Operator
.OpType
.Inequality
:
356 case Operator
.OpType
.GreaterThan
:
359 case Operator
.OpType
.LessThan
:
362 case Operator
.OpType
.GreaterThanOrEqual
:
365 case Operator
.OpType
.LessThanOrEqual
:
369 Report
.Error (216, oe
.op
.Location
,
370 "The operator `{0}' requires a matching operator `{1}' to also be defined",
371 oe
.op
.GetSignatureForError (), s
);
374 if (has_equality_or_inequality
&& (RootContext
.WarningLevel
> 2)) {
375 if (container
.Methods
== null || !container
.Methods
.HasEquals
)
376 Report
.Warning (660, 2, container
.Location
, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container
.GetSignatureForError ());
378 if (container
.Methods
== null || !container
.Methods
.HasGetHashCode
)
379 Report
.Warning (661, 2, container
.Location
, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container
.GetSignatureForError ());
383 public override void DefineContainerMembers ()
385 base.DefineContainerMembers ();
386 CheckPairedOperators ();
391 // Whether this is a struct, class or interface
392 public readonly Kind Kind
;
394 // Holds a list of classes and structures
395 protected ArrayList types
;
397 // Holds the list of properties
398 MemberCoreArrayList properties
;
400 // Holds the list of enumerations
401 MemberCoreArrayList enums
;
403 // Holds the list of delegates
404 MemberCoreArrayList delegates
;
406 // Holds the list of constructors
407 protected MemberCoreArrayList instance_constructors
;
409 // Holds the list of fields
410 MemberCoreArrayList fields
;
412 // Holds a list of fields that have initializers
413 protected ArrayList initialized_fields
;
415 // Holds a list of static fields that have initializers
416 protected ArrayList initialized_static_fields
;
418 // Holds the list of constants
419 MemberCoreArrayList constants
;
422 MemberCoreArrayList interfaces
;
424 // Holds the methods.
425 MethodArrayList methods
;
428 protected MemberCoreArrayList events
;
430 // Holds the indexers
431 IndexerArrayList indexers
;
433 // Holds the operators
434 MemberCoreArrayList operators
;
436 // Holds the compiler generated classes
437 ArrayList compiler_generated
;
440 // Pointers to the default constructor and the default static constructor
442 protected Constructor default_constructor
;
443 protected Constructor default_static_constructor
;
446 // Points to the first non-static field added to the container.
448 // This is an arbitrary choice. We are interested in looking at _some_ non-static field,
449 // and the first one's as good as any.
451 FieldBase first_nonstatic_field
= null;
454 // This one is computed after we can distinguish interfaces
455 // from classes from the arraylist `type_bases'
458 TypeExpr
[] iface_exprs
;
461 ArrayList type_bases
;
463 bool members_resolved
;
464 bool members_resolved_ok
;
465 bool members_defined
;
466 bool members_defined_ok
;
468 // The interfaces we implement.
469 protected Type
[] ifaces
;
471 // The base member cache and our member cache
472 MemberCache base_cache
;
473 MemberCache member_cache
;
475 public const string DefaultIndexerName
= "Item";
478 GenericTypeParameterBuilder
[] gen_params
;
481 ArrayList partial_parts
;
484 /// The pending methods that need to be implemented
485 // (interfaces or abstract methods)
487 PendingImplementation pending
;
489 public TypeContainer (NamespaceEntry ns
, DeclSpace parent
, MemberName name
,
490 Attributes attrs
, Kind kind
)
491 : base (ns
, parent
, name
, attrs
)
493 if (parent
!= null && parent
.NamespaceEntry
!= ns
)
494 throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
497 this.PartialContainer
= this;
500 public bool AddMember (MemberCore symbol
)
502 return AddToContainer (symbol
, symbol
.MemberName
.MethodName
);
505 protected virtual bool AddMemberType (DeclSpace ds
)
507 return AddToContainer (ds
, ds
.Basename
);
510 public void AddConstant (Const constant
)
512 if (!AddMember (constant
))
515 if (constants
== null)
516 constants
= new MemberCoreArrayList ();
518 constants
.Add (constant
);
521 public void AddEnum (Mono
.CSharp
.Enum e
)
523 if (!AddMemberType (e
))
527 enums
= new MemberCoreArrayList ();
532 public TypeContainer
AddTypeContainer (TypeContainer tc
, bool is_interface
)
534 if (!AddMemberType (tc
))
538 if (interfaces
== null)
539 interfaces
= new MemberCoreArrayList ();
543 types
= new ArrayList (2);
549 public virtual TypeContainer
AddPartial (TypeContainer nextPart
, bool is_interface
)
551 return AddPartial (nextPart
, nextPart
.Basename
, is_interface
);
554 protected TypeContainer
AddPartial (TypeContainer nextPart
, string name
, bool is_interface
)
556 nextPart
.ModFlags
|= Modifiers
.PARTIAL
;
557 TypeContainer tc
= defined_names
[name
] as TypeContainer
;
560 return AddTypeContainer (nextPart
, is_interface
);
562 if ((tc
.ModFlags
& Modifiers
.PARTIAL
) == 0) {
563 Report
.SymbolRelatedToPreviousError (tc
);
564 Error_MissingPartialModifier (nextPart
);
568 if (tc
.Kind
!= nextPart
.Kind
) {
569 Report
.SymbolRelatedToPreviousError (tc
);
570 Report
.Error (261, nextPart
.Location
,
571 "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
572 nextPart
.GetSignatureForError ());
576 if ((tc
.ModFlags
& Modifiers
.Accessibility
) != (nextPart
.ModFlags
& Modifiers
.Accessibility
) &&
577 ((tc
.ModFlags
& Modifiers
.DEFAULT_ACCESS_MODIFER
) == 0 &&
578 (nextPart
.ModFlags
& Modifiers
.DEFAULT_ACCESS_MODIFER
) == 0)) {
579 Report
.SymbolRelatedToPreviousError (tc
);
580 Report
.Error (262, nextPart
.Location
,
581 "Partial declarations of `{0}' have conflicting accessibility modifiers",
582 nextPart
.GetSignatureForError ());
586 if (tc
.MemberName
.IsGeneric
) {
587 TypeParameter
[] tc_names
= tc
.TypeParameters
;
588 TypeParameterName
[] part_names
= nextPart
.MemberName
.TypeArguments
.GetDeclarations ();
590 for (int i
= 0; i
< tc_names
.Length
; ++i
) {
591 if (tc_names
[i
].Name
== part_names
[i
].Name
)
594 Report
.SymbolRelatedToPreviousError (part_names
[i
].Location
, "");
595 Report
.Error (264, tc
.Location
, "Partial declarations of `{0}' must have the same type parameter names in the same order",
596 tc
.GetSignatureForError ());
601 if (tc
.partial_parts
== null)
602 tc
.partial_parts
= new ArrayList (1);
604 tc
.ModFlags
|= nextPart
.ModFlags
;
605 if (nextPart
.attributes
!= null) {
606 if (tc
.attributes
== null)
607 tc
.attributes
= nextPart
.attributes
;
609 tc
.attributes
.AddAttributes (nextPart
.attributes
.Attrs
);
612 nextPart
.PartialContainer
= tc
;
613 tc
.partial_parts
.Add (nextPart
);
617 public void AddDelegate (Delegate d
)
619 if (!AddMemberType (d
))
622 if (delegates
== null)
623 delegates
= new MemberCoreArrayList ();
628 public void AddMethod (Method method
)
630 if (!AddMember (method
))
634 methods
= new MethodArrayList (this);
636 if (method
.MemberName
.Left
!= null)
637 methods
.Insert (0, method
);
639 methods
.Add (method
);
643 // Do not use this method: use AddMethod.
645 // This is only used by iterators.
647 public void AppendMethod (Method method
)
649 if (!AddMember (method
))
653 methods
= new MethodArrayList (this);
655 methods
.Add (method
);
658 public void AddConstructor (Constructor c
)
660 if (c
.Name
!= MemberName
.Name
) {
661 Report
.Error (1520, c
.Location
, "Class, struct, or interface method must have a return type");
664 bool is_static
= (c
.ModFlags
& Modifiers
.STATIC
) != 0;
667 if (default_static_constructor
!= null) {
668 Report
.SymbolRelatedToPreviousError (default_static_constructor
);
669 Report
.Error (111, c
.Location
, Error111
, c
.GetSignatureForError ());
673 default_static_constructor
= c
;
675 if (c
.Parameters
.Empty
){
676 if (default_constructor
!= null) {
677 Report
.SymbolRelatedToPreviousError (default_constructor
);
678 Report
.Error (111, c
.Location
, Error111
, c
.GetSignatureForError ());
681 default_constructor
= c
;
684 if (instance_constructors
== null)
685 instance_constructors
= new MemberCoreArrayList ();
687 instance_constructors
.Add (c
);
691 internal static string Error111
{
693 return "`{0}' is already defined. Rename this member or use different parameter types";
697 public void AddField (FieldBase field
)
699 if (!AddMember (field
))
703 fields
= new MemberCoreArrayList ();
707 if ((field
.ModFlags
& Modifiers
.STATIC
) != 0)
710 if (first_nonstatic_field
== null) {
711 first_nonstatic_field
= field
;
715 if (Kind
== Kind
.Struct
&&
716 first_nonstatic_field
.Parent
!= field
.Parent
&&
717 RootContext
.WarningLevel
>= 3) {
718 Report
.SymbolRelatedToPreviousError (first_nonstatic_field
.Parent
);
719 Report
.Warning (282, 3, field
.Location
,
720 "struct instance field `{0}' found in different declaration from instance field `{1}'",
721 field
.GetSignatureForError (), first_nonstatic_field
.GetSignatureForError ());
725 public void AddProperty (Property prop
)
727 if (!AddMember (prop
) ||
728 !AddMember (prop
.Get
) || !AddMember (prop
.Set
))
731 if (properties
== null)
732 properties
= new MemberCoreArrayList ();
734 if (prop
.MemberName
.Left
!= null)
735 properties
.Insert (0, prop
);
737 properties
.Add (prop
);
740 public void AddEvent (Event e
)
745 if (e
is EventProperty
) {
746 if (!AddMember (e
.Add
))
749 if (!AddMember (e
.Remove
))
754 events
= new MemberCoreArrayList ();
760 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
762 public void AddIndexer (Indexer i
)
764 if (indexers
== null)
765 indexers
= new IndexerArrayList (this);
767 if (i
.IsExplicitImpl
)
768 indexers
.Insert (0, i
);
773 public void AddOperator (Operator op
)
778 if (operators
== null)
779 operators
= new OperatorArrayList (this);
784 public void AddCompilerGeneratedClass (CompilerGeneratedClass c
)
786 Report
.Debug (64, "ADD COMPILER GENERATED CLASS", this, c
);
788 if (compiler_generated
== null)
789 compiler_generated
= new ArrayList ();
791 compiler_generated
.Add (c
);
794 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
796 if (a
.Type
== TypeManager
.default_member_type
) {
797 if (Indexers
!= null) {
798 Report
.Error (646, a
.Location
, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
803 base.ApplyAttributeBuilder (a
, cb
);
806 public override AttributeTargets AttributeTargets
{
808 throw new NotSupportedException ();
812 public ArrayList Types
{
818 public MethodArrayList Methods
{
824 public ArrayList Constants
{
830 public ArrayList Interfaces
{
836 public ArrayList CompilerGenerated
{
838 return compiler_generated
;
842 protected Type BaseType
{
844 return TypeBuilder
.BaseType
;
848 public ArrayList Bases
{
858 public ArrayList Fields
{
864 public ArrayList InstanceConstructors
{
866 return instance_constructors
;
870 public ArrayList Properties
{
876 public ArrayList Events
{
882 public ArrayList Enums
{
888 public ArrayList Indexers
{
894 public ArrayList Operators
{
900 public ArrayList Delegates
{
906 protected override TypeAttributes TypeAttr
{
908 return Modifiers
.TypeAttr (ModFlags
, IsTopLevel
) | base.TypeAttr
;
912 public string IndexerName
{
914 return indexers
== null ? DefaultIndexerName
: indexers
.IndexerName
;
918 public bool IsComImport
{
920 if (OptAttributes
== null)
923 return OptAttributes
.Contains (TypeManager
.comimport_attr_type
);
927 public virtual void RegisterFieldForInitialization (MemberCore field
, FieldInitializer expression
)
929 if ((field
.ModFlags
& Modifiers
.STATIC
) != 0){
930 if (initialized_static_fields
== null)
931 initialized_static_fields
= new ArrayList (4);
933 initialized_static_fields
.Add (expression
);
935 if (initialized_fields
== null)
936 initialized_fields
= new ArrayList (4);
938 initialized_fields
.Add (expression
);
943 // Emits the instance field initializers
945 public bool EmitFieldInitializers (EmitContext ec
)
950 fields
= initialized_static_fields
;
952 fields
= initialized_fields
;
958 foreach (FieldInitializer f
in fields
) {
959 f
.EmitStatement (ec
);
964 public override string DocComment
{
976 public PendingImplementation PendingImplementations
{
977 get { return pending; }
980 public override bool GetClsCompliantAttributeValue ()
982 if (PartialContainer
!= this)
983 return PartialContainer
.GetClsCompliantAttributeValue ();
985 return base.GetClsCompliantAttributeValue ();
988 public void AddBasesForPart (DeclSpace part
, ArrayList bases
)
990 // FIXME: get rid of partial_parts and store lists of bases of each part here
991 // assumed, not verified: 'part' is in 'partial_parts'
992 ((TypeContainer
) part
).Bases
= bases
;
995 TypeExpr
[] GetNormalBases (out TypeExpr base_class
)
1001 int count
= Bases
.Count
;
1002 int start
= 0, i
, j
;
1004 if (Kind
== Kind
.Class
){
1005 TypeExpr name
= ((Expression
) Bases
[0]).ResolveAsBaseTerminal (this, false);
1011 if (!name
.IsInterface
) {
1012 // base_class could be a class, struct, enum, delegate.
1013 // This is validated in GetClassBases.
1019 TypeExpr
[] ifaces
= new TypeExpr
[count
-start
];
1021 for (i
= start
, j
= 0; i
< count
; i
++, j
++){
1022 TypeExpr resolved
= ((Expression
) Bases
[i
]).ResolveAsBaseTerminal (this, false);
1023 if (resolved
== null) {
1027 ifaces
[j
] = resolved
;
1030 return ifaces
.Length
== 0 ? null : ifaces
;
1034 TypeExpr
[] GetNormalPartialBases (ref TypeExpr base_class
)
1036 ArrayList ifaces
= new ArrayList (0);
1037 if (iface_exprs
!= null)
1038 ifaces
.AddRange (iface_exprs
);
1040 foreach (TypeContainer part
in partial_parts
) {
1041 TypeExpr new_base_class
;
1042 TypeExpr
[] new_ifaces
= part
.GetClassBases (out new_base_class
);
1043 if (new_base_class
!= TypeManager
.system_object_expr
) {
1044 if (base_class
== TypeManager
.system_object_expr
)
1045 base_class
= new_base_class
;
1047 if (new_base_class
!= null && !new_base_class
.Equals (base_class
)) {
1048 Report
.SymbolRelatedToPreviousError (base_class
.Location
, "");
1049 Report
.Error (263, part
.Location
,
1050 "Partial declarations of `{0}' must not specify different base classes",
1051 part
.GetSignatureForError ());
1058 if (new_ifaces
== null)
1061 foreach (TypeExpr iface
in new_ifaces
) {
1062 if (ifaces
.Contains (iface
))
1069 if (ifaces
.Count
== 0)
1072 return (TypeExpr
[])ifaces
.ToArray (typeof (TypeExpr
));
1076 /// This function computes the Base class and also the
1077 /// list of interfaces that the class or struct @c implements.
1079 /// The return value is an array (might be null) of
1080 /// interfaces implemented (as Types).
1082 /// The @base_class argument is set to the base object or null
1083 /// if this is `System.Object'.
1085 public virtual TypeExpr
[] GetClassBases (out TypeExpr base_class
)
1087 TypeExpr
[] ifaces
= GetNormalBases (out base_class
);
1092 int count
= ifaces
.Length
;
1094 for (int i
= 0; i
< count
; i
++) {
1095 TypeExpr iface
= (TypeExpr
) ifaces
[i
];
1097 if (!iface
.IsInterface
) {
1098 if (Kind
!= Kind
.Class
) {
1099 // TODO: location of symbol related ....
1100 Error_TypeInListIsNotInterface (Location
, iface
.GetSignatureForError ());
1102 else if (base_class
!= null)
1103 Report
.Error (1721, Location
, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
1104 GetSignatureForError (), base_class
.GetSignatureForError (), iface
.GetSignatureForError ());
1106 Report
.Error (1722, Location
, "`{0}': Base class `{1}' must be specified as first",
1107 GetSignatureForError (), iface
.GetSignatureForError ());
1112 for (int x
= 0; x
< i
; x
++) {
1113 if (iface
.Equals (ifaces
[x
])) {
1114 Report
.Error (528, Location
,
1115 "`{0}' is already listed in " +
1116 "interface list", iface
.GetSignatureForError ());
1121 if ((Kind
== Kind
.Interface
) &&
1122 !iface
.AsAccessible (Parent
, ModFlags
)) {
1123 Report
.Error (61, Location
,
1124 "Inconsistent accessibility: base " +
1125 "interface `{0}' is less accessible " +
1126 "than interface `{1}'", iface
.Name
,
1134 bool CheckGenericInterfaces (Type
[] ifaces
)
1137 ArrayList already_checked
= new ArrayList ();
1139 for (int i
= 0; i
< ifaces
.Length
; i
++) {
1140 Type iface
= ifaces
[i
];
1141 foreach (Type t
in already_checked
) {
1145 Type
[] inferred
= new Type
[CountTypeParameters
];
1146 if (!TypeManager
.MayBecomeEqualGenericInstances (iface
, t
, inferred
, null))
1149 Report
.Error (695, Location
,
1150 "`{0}' cannot implement both `{1}' and `{2}' " +
1151 "because they may unify for some type parameter substitutions",
1152 TypeManager
.CSharpName (TypeBuilder
), TypeManager
.CSharpName (iface
),
1153 TypeManager
.CSharpName (t
));
1157 already_checked
.Add (iface
);
1166 protected void Error_TypeInListIsNotInterface (Location loc
, string type
)
1168 Report
.Error (527, loc
, "Type `{0}' in interface list is not an interface", type
);
1171 bool DefineTypeBuilder ()
1174 Type default_parent
= null;
1175 if (Kind
== Kind
.Struct
)
1176 default_parent
= TypeManager
.value_type
;
1177 else if (Kind
== Kind
.Enum
)
1178 default_parent
= TypeManager
.enum_type
;
1181 if (TypeManager
.NamespaceClash (Name
, Location
)) {
1185 ModuleBuilder builder
= CodeGen
.Module
.Builder
;
1186 TypeBuilder
= builder
.DefineType (
1187 Name
, TypeAttr
, default_parent
, null);
1189 TypeBuilder builder
= Parent
.TypeBuilder
;
1191 TypeBuilder
= builder
.DefineNestedType (
1192 Basename
, TypeAttr
, default_parent
, null);
1194 } catch (ArgumentException
) {
1195 Report
.RuntimeMissingSupport (Location
, "static classes");
1199 TypeManager
.AddUserType (this);
1203 string[] param_names
= new string [TypeParameters
.Length
];
1204 for (int i
= 0; i
< TypeParameters
.Length
; i
++)
1205 param_names
[i
] = TypeParameters
[i
].Name
;
1207 gen_params
= TypeBuilder
.DefineGenericParameters (param_names
);
1209 int offset
= CountTypeParameters
- CurrentTypeParameters
.Length
;
1210 for (int i
= offset
; i
< gen_params
.Length
; i
++)
1211 CurrentTypeParameters
[i
- offset
].Define (gen_params
[i
]);
1215 iface_exprs
= GetClassBases (out base_type
);
1216 if (partial_parts
!= null) {
1217 iface_exprs
= GetNormalPartialBases (ref base_type
);
1221 // GetClassBases calls ResolveBaseTypeExpr() on the various type expressions involved,
1222 // which in turn should have called DefineType()s on base types if necessary.
1224 // None of the code below should trigger DefineType()s on classes that we depend on.
1225 // Thus, we are eligible to be on the topological sort `type_container_resolve_order'.
1227 // Let's do it as soon as possible, since code below can call DefineType() on classes
1228 // that depend on us to be populated before they are.
1230 if (!(this is CompilerGeneratedClass
))
1231 RootContext
.RegisterOrder (this);
1233 if (IsGeneric
&& base_type
!= null && TypeManager
.IsAttributeType (base_type
.Type
)) {
1234 Report
.Error (698, base_type
.Location
,
1235 "A generic type cannot derive from `{0}' because it is an attribute class",
1240 if (!CheckRecursiveDefinition (this))
1243 if (base_type
!= null) {
1244 TypeBuilder
.SetParent (base_type
.Type
);
1246 ObsoleteAttribute obsolete_attr
= AttributeTester
.GetObsoleteAttribute (base_type
.Type
);
1247 if (obsolete_attr
!= null && !IsInObsoleteScope
)
1248 AttributeTester
.Report_ObsoleteMessage (obsolete_attr
, base_type
.GetSignatureForError (), Location
);
1251 // add interfaces that were not added at type creation
1252 if (iface_exprs
!= null) {
1253 ifaces
= TypeManager
.ExpandInterfaces (iface_exprs
);
1257 foreach (Type itype
in ifaces
)
1258 TypeBuilder
.AddInterfaceImplementation (itype
);
1260 foreach (TypeExpr ie
in iface_exprs
) {
1261 ObsoleteAttribute oa
= AttributeTester
.GetObsoleteAttribute (ie
.Type
);
1262 if ((oa
!= null) && !IsInObsoleteScope
)
1263 AttributeTester
.Report_ObsoleteMessage (
1264 oa
, ie
.GetSignatureForError (), Location
);
1267 if (!CheckGenericInterfaces (ifaces
))
1270 TypeManager
.RegisterBuilder (TypeBuilder
, ifaces
);
1277 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1279 public override TypeBuilder
DefineType ()
1281 if (TypeBuilder
!= null)
1287 if (!DefineTypeBuilder ()) {
1292 if (partial_parts
!= null) {
1293 foreach (TypeContainer part
in partial_parts
)
1294 part
.TypeBuilder
= TypeBuilder
;
1297 if (!(this is CompilerGeneratedClass
)) {
1298 if (!ResolveMembers ()) {
1304 if (!DefineNestedTypes ()) {
1312 public bool ResolveMembers ()
1314 if (members_resolved
)
1315 return members_resolved_ok
;
1317 members_resolved_ok
= DoResolveMembers ();
1318 members_resolved
= true;
1320 return members_resolved_ok
;
1323 protected virtual bool DoResolveMembers ()
1325 if (methods
!= null) {
1326 foreach (Method method
in methods
) {
1327 if (!method
.ResolveMembers ())
1332 if (instance_constructors
!= null) {
1333 foreach (Constructor c
in instance_constructors
) {
1334 if (!c
.ResolveMembers ())
1339 if (default_static_constructor
!= null) {
1340 if (!default_static_constructor
.ResolveMembers ())
1344 if (operators
!= null) {
1345 foreach (Operator o
in operators
) {
1346 if (!o
.ResolveMembers ())
1351 if (properties
!= null) {
1352 foreach (PropertyBase p
in properties
) {
1353 if (!p
.Get
.IsDummy
&& !p
.Get
.ResolveMembers ())
1355 if (!p
.Set
.IsDummy
&& !p
.Set
.ResolveMembers ())
1360 if (indexers
!= null) {
1361 foreach (PropertyBase p
in indexers
) {
1362 if (!p
.Get
.IsDummy
&& !p
.Get
.ResolveMembers ())
1364 if (!p
.Set
.IsDummy
&& !p
.Set
.ResolveMembers ())
1369 if (events
!= null) {
1370 foreach (Event e
in events
) {
1371 if (!e
.Add
.ResolveMembers ())
1373 if (!e
.Remove
.ResolveMembers ())
1381 Constraints
[] constraints
;
1382 public override void SetParameterInfo (ArrayList constraints_list
)
1384 if (PartialContainer
== this) {
1385 base.SetParameterInfo (constraints_list
);
1389 if (constraints_list
== null)
1392 constraints
= new Constraints
[PartialContainer
.CountCurrentTypeParameters
];
1394 TypeParameter
[] current_params
= PartialContainer
.CurrentTypeParameters
;
1395 for (int i
= 0; i
< constraints
.Length
; i
++) {
1396 foreach (Constraints constraint
in constraints_list
) {
1397 if (constraint
.TypeParameter
== current_params
[i
].Name
) {
1398 constraints
[i
] = constraint
;
1405 bool UpdateTypeParameterConstraints ()
1407 if (constraints
== null)
1410 TypeParameter
[] current_params
= PartialContainer
.CurrentTypeParameters
;
1411 for (int i
= 0; i
< current_params
.Length
; i
++) {
1412 if (!current_params
[i
].UpdateConstraints (this, constraints
[i
])) {
1413 Report
.SymbolRelatedToPreviousError (Location
, "");
1414 Report
.Error (265, PartialContainer
.Location
,
1415 "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
1416 PartialContainer
.GetSignatureForError (), current_params
[i
].Name
);
1424 public bool ResolveType ()
1426 if (!DoResolveType ())
1429 if (compiler_generated
!= null) {
1430 foreach (CompilerGeneratedClass c
in compiler_generated
)
1431 if (!c
.ResolveType ())
1438 protected virtual bool DoResolveType ()
1440 if ((base_type
!= null) &&
1441 (base_type
.ResolveAsTypeTerminal (this, false) == null)) {
1449 if (PartialContainer
!= this)
1450 throw new InternalErrorException ();
1452 TypeExpr current_type
= null;
1454 foreach (TypeParameter type_param
in CurrentTypeParameters
) {
1455 if (!type_param
.Resolve (this)) {
1461 if (partial_parts
!= null) {
1462 foreach (TypeContainer part
in partial_parts
) {
1463 if (!part
.UpdateTypeParameterConstraints ()) {
1470 foreach (TypeParameter type_param
in TypeParameters
) {
1471 if (!type_param
.DefineType (this)) {
1477 current_type
= new ConstructedType (TypeBuilder
, TypeParameters
, Location
);
1479 foreach (TypeParameter type_param
in TypeParameters
)
1480 if (!type_param
.CheckDependencies ()) {
1485 if (current_type
!= null) {
1486 current_type
= current_type
.ResolveAsTypeTerminal (this, false);
1487 if (current_type
== null) {
1492 CurrentType
= current_type
.Type
;
1498 protected virtual bool DefineNestedTypes ()
1500 if (Interfaces
!= null) {
1501 foreach (TypeContainer iface
in Interfaces
)
1502 if (iface
.DefineType () == null)
1506 if (Types
!= null) {
1507 foreach (TypeContainer tc
in Types
)
1508 if (tc
.DefineType () == null)
1512 if (Delegates
!= null) {
1513 foreach (Delegate d
in Delegates
)
1514 if (d
.DefineType () == null)
1518 if (Enums
!= null) {
1519 foreach (Enum en
in Enums
)
1520 if (en
.DefineType () == null)
1524 if (compiler_generated
!= null) {
1525 foreach (CompilerGeneratedClass c
in compiler_generated
) {
1526 if (c
.DefineType () == null)
1534 TypeContainer InTransit
;
1536 protected bool CheckRecursiveDefinition (TypeContainer tc
)
1538 if (InTransit
!= null) {
1539 Report
.SymbolRelatedToPreviousError (this);
1540 if (this is Interface
)
1542 529, tc
.Location
, "Inherited interface `{0}' causes a " +
1543 "cycle in the interface hierarchy of `{1}'",
1544 GetSignatureForError (), tc
.GetSignatureForError ());
1547 146, tc
.Location
, "Circular base class dependency " +
1548 "involving `{0}' and `{1}'",
1549 tc
.GetSignatureForError (), GetSignatureForError ());
1555 if (base_type
!= null) {
1556 Type t
= TypeManager
.DropGenericTypeArguments (base_type
.Type
);
1557 TypeContainer ptc
= TypeManager
.LookupTypeContainer (t
);
1558 if ((ptc
!= null) && !ptc
.CheckRecursiveDefinition (this))
1562 if (iface_exprs
!= null) {
1563 foreach (TypeExpr iface
in iface_exprs
) {
1564 Type itype
= TypeManager
.DropGenericTypeArguments (iface
.Type
);
1565 TypeContainer ptc
= TypeManager
.LookupTypeContainer (itype
);
1566 if ((ptc
!= null) && !ptc
.CheckRecursiveDefinition (this))
1571 if (!IsTopLevel
&& !Parent
.PartialContainer
.CheckRecursiveDefinition (this))
1578 public static void Error_KeywordNotAllowed (Location loc
)
1580 Report
.Error (1530, loc
, "Keyword `new' is not allowed on namespace elements");
1584 /// Populates our TypeBuilder with fields and methods
1586 public override bool DefineMembers ()
1588 if (members_defined
)
1589 return members_defined_ok
;
1591 if (!base.DefineMembers ())
1594 members_defined_ok
= DoDefineMembers ();
1595 members_defined
= true;
1597 return members_defined_ok
;
1600 protected virtual bool DoDefineMembers ()
1602 if (iface_exprs
!= null) {
1603 foreach (TypeExpr iface
in iface_exprs
) {
1604 ConstructedType ct
= iface
as ConstructedType
;
1605 if ((ct
!= null) && !ct
.CheckConstraints (this))
1610 if (base_type
!= null) {
1611 ConstructedType ct
= base_type
as ConstructedType
;
1612 if ((ct
!= null) && !ct
.CheckConstraints (this))
1617 MemberInfo conflict_symbol
= Parent
.PartialContainer
.FindBaseMemberWithSameName (Basename
, false);
1618 if (conflict_symbol
== null) {
1619 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0))
1620 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1622 if ((ModFlags
& Modifiers
.NEW
) == 0) {
1623 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
1624 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
1625 GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
1630 DefineContainerMembers (constants
);
1631 DefineContainerMembers (fields
);
1633 if (Kind
== Kind
.Struct
|| Kind
== Kind
.Class
) {
1634 pending
= PendingImplementation
.GetPendingImplementations (this);
1638 // Constructors are not in the defined_names array
1640 DefineContainerMembers (instance_constructors
);
1642 DefineContainerMembers (properties
);
1643 DefineContainerMembers (events
);
1644 DefineContainerMembers (indexers
);
1645 DefineContainerMembers (methods
);
1646 DefineContainerMembers (operators
);
1647 DefineContainerMembers (enums
);
1648 DefineContainerMembers (delegates
);
1650 if (CurrentType
!= null) {
1651 GenericType
= CurrentType
;
1656 member_cache
= new MemberCache (this);
1657 if (partial_parts
!= null) {
1658 foreach (TypeContainer part
in partial_parts
)
1659 part
.member_cache
= member_cache
;
1666 protected virtual void DefineContainerMembers (MemberCoreArrayList mcal
)
1669 mcal
.DefineContainerMembers ();
1672 public override bool Define ()
1674 if (compiler_generated
!= null) {
1675 foreach (CompilerGeneratedClass c
in compiler_generated
) {
1684 public MemberInfo
FindBaseMemberWithSameName (string name
, bool ignore_methods
)
1686 return BaseCache
== null ? null : BaseCache
.FindMemberWithSameName (name
, ignore_methods
, null);
1690 /// This function is based by a delegate to the FindMembers routine
1692 static bool AlwaysAccept (MemberInfo m
, object filterCriteria
)
1698 /// This filter is used by FindMembers, and we just keep
1699 /// a global for the filter to `AlwaysAccept'
1701 static MemberFilter accepting_filter
;
1704 static TypeContainer ()
1706 accepting_filter
= new MemberFilter (AlwaysAccept
);
1709 public MethodInfo
[] GetMethods ()
1711 ArrayList members
= new ArrayList ();
1715 if (methods
!= null) {
1716 int len
= methods
.Count
;
1717 for (int i
= 0; i
< len
; i
++) {
1718 Method m
= (Method
) methods
[i
];
1720 members
.Add (m
.MethodBuilder
);
1724 if (operators
!= null) {
1725 int len
= operators
.Count
;
1726 for (int i
= 0; i
< len
; i
++) {
1727 Operator o
= (Operator
) operators
[i
];
1729 members
.Add (o
.MethodBuilder
);
1733 if (properties
!= null) {
1734 int len
= properties
.Count
;
1735 for (int i
= 0; i
< len
; i
++) {
1736 Property p
= (Property
) properties
[i
];
1738 if (p
.GetBuilder
!= null)
1739 members
.Add (p
.GetBuilder
);
1740 if (p
.SetBuilder
!= null)
1741 members
.Add (p
.SetBuilder
);
1745 if (indexers
!= null) {
1746 int len
= indexers
.Count
;
1747 for (int i
= 0; i
< len
; i
++) {
1748 Indexer ix
= (Indexer
) indexers
[i
];
1750 if (ix
.GetBuilder
!= null)
1751 members
.Add (ix
.GetBuilder
);
1752 if (ix
.SetBuilder
!= null)
1753 members
.Add (ix
.SetBuilder
);
1757 if (events
!= null) {
1758 int len
= events
.Count
;
1759 for (int i
= 0; i
< len
; i
++) {
1760 Event e
= (Event
) events
[i
];
1762 if (e
.AddBuilder
!= null)
1763 members
.Add (e
.AddBuilder
);
1764 if (e
.RemoveBuilder
!= null)
1765 members
.Add (e
.RemoveBuilder
);
1769 MethodInfo
[] retMethods
= new MethodInfo
[members
.Count
];
1770 members
.CopyTo (retMethods
, 0);
1774 // Indicated whether container has StructLayout attribute set Explicit
1775 public bool HasExplicitLayout
{
1776 get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
1777 set { caching_flags |= Flags.HasExplicitLayout; }
1781 // Return the nested type with name @name. Ensures that the nested type
1782 // is defined if necessary. Do _not_ use this when you have a MemberCache handy.
1784 public Type
FindNestedType (string name
)
1786 if (PartialContainer
!= this)
1787 throw new InternalErrorException ("should not happen");
1789 ArrayList
[] lists
= { types, enums, delegates, interfaces }
;
1791 for (int j
= 0; j
< lists
.Length
; ++j
) {
1792 ArrayList list
= lists
[j
];
1796 int len
= list
.Count
;
1797 for (int i
= 0; i
< len
; ++i
) {
1798 DeclSpace ds
= (DeclSpace
) list
[i
];
1799 if (ds
.Basename
== name
) {
1800 return ds
.DefineType ();
1808 private void FindMembers_NestedTypes (int modflags
,
1809 BindingFlags bf
, MemberFilter filter
, object criteria
,
1810 ref ArrayList members
)
1812 ArrayList
[] lists
= { types, enums, delegates, interfaces }
;
1814 for (int j
= 0; j
< lists
.Length
; ++j
) {
1815 ArrayList list
= lists
[j
];
1819 int len
= list
.Count
;
1820 for (int i
= 0; i
< len
; i
++) {
1821 DeclSpace ds
= (DeclSpace
) list
[i
];
1823 if ((ds
.ModFlags
& modflags
) == 0)
1826 TypeBuilder tb
= ds
.TypeBuilder
;
1828 if (!(criteria
is string) || ds
.Basename
.Equals (criteria
))
1829 tb
= ds
.DefineType ();
1832 if (tb
!= null && (filter (tb
, criteria
) == true)) {
1833 if (members
== null)
1834 members
= new ArrayList ();
1843 /// This method returns the members of this type just like Type.FindMembers would
1844 /// Only, we need to use this for types which are _being_ defined because MS'
1845 /// implementation can't take care of that.
1848 // FIXME: return an empty static array instead of null, that cleans up
1849 // some code and is consistent with some coding conventions I just found
1853 // Notice that in various cases we check if our field is non-null,
1854 // something that would normally mean that there was a bug elsewhere.
1856 // The problem happens while we are defining p-invoke methods, as those
1857 // will trigger a FindMembers, but this happens before things are defined
1859 // Since the whole process is a no-op, it is fine to check for null here.
1861 public override MemberList
FindMembers (MemberTypes mt
, BindingFlags bf
,
1862 MemberFilter filter
, object criteria
)
1864 ArrayList members
= null;
1867 if ((bf
& BindingFlags
.Public
) != 0)
1868 modflags
|= Modifiers
.PUBLIC
| Modifiers
.PROTECTED
|
1870 if ((bf
& BindingFlags
.NonPublic
) != 0)
1871 modflags
|= Modifiers
.PRIVATE
;
1873 int static_mask
= 0, static_flags
= 0;
1874 switch (bf
& (BindingFlags
.Static
| BindingFlags
.Instance
)) {
1875 case BindingFlags
.Static
:
1876 static_mask
= static_flags
= Modifiers
.STATIC
;
1879 case BindingFlags
.Instance
:
1880 static_mask
= Modifiers
.STATIC
;
1885 static_mask
= static_flags
= 0;
1889 Timer
.StartTimer (TimerType
.TcFindMembers
);
1892 filter
= accepting_filter
;
1894 if ((mt
& MemberTypes
.Field
) != 0) {
1895 if (fields
!= null) {
1896 int len
= fields
.Count
;
1897 for (int i
= 0; i
< len
; i
++) {
1898 FieldBase f
= (FieldBase
) fields
[i
];
1900 if ((f
.ModFlags
& modflags
) == 0)
1902 if ((f
.ModFlags
& static_mask
) != static_flags
)
1905 FieldBuilder fb
= f
.FieldBuilder
;
1906 if (fb
!= null && filter (fb
, criteria
) == true) {
1907 if (members
== null)
1908 members
= new ArrayList ();
1915 if (constants
!= null) {
1916 int len
= constants
.Count
;
1917 for (int i
= 0; i
< len
; i
++) {
1918 Const con
= (Const
) constants
[i
];
1920 if ((con
.ModFlags
& modflags
) == 0)
1922 if ((con
.ModFlags
& static_mask
) != static_flags
)
1925 FieldBuilder fb
= con
.FieldBuilder
;
1928 fb
= con
.FieldBuilder
;
1930 if (fb
!= null && filter (fb
, criteria
) == true) {
1931 if (members
== null)
1932 members
= new ArrayList ();
1940 if ((mt
& MemberTypes
.Method
) != 0) {
1941 if (methods
!= null) {
1942 int len
= methods
.Count
;
1943 for (int i
= 0; i
< len
; i
++) {
1944 Method m
= (Method
) methods
[i
];
1946 if ((m
.ModFlags
& modflags
) == 0)
1948 if ((m
.ModFlags
& static_mask
) != static_flags
)
1951 MethodBuilder mb
= m
.MethodBuilder
;
1953 if (mb
!= null && filter (mb
, criteria
) == true) {
1954 if (members
== null)
1955 members
= new ArrayList ();
1962 if (operators
!= null) {
1963 int len
= operators
.Count
;
1964 for (int i
= 0; i
< len
; i
++) {
1965 Operator o
= (Operator
) operators
[i
];
1967 if ((o
.ModFlags
& modflags
) == 0)
1969 if ((o
.ModFlags
& static_mask
) != static_flags
)
1972 MethodBuilder ob
= o
.MethodBuilder
;
1973 if (ob
!= null && filter (ob
, criteria
) == true) {
1974 if (members
== null)
1975 members
= new ArrayList ();
1982 if (events
!= null) {
1983 foreach (Event e
in events
) {
1984 if ((e
.ModFlags
& modflags
) == 0)
1986 if ((e
.ModFlags
& static_mask
) != static_flags
)
1989 MethodBuilder b
= e
.AddBuilder
;
1990 if (b
!= null && filter (b
, criteria
)) {
1991 if (members
== null)
1992 members
= new ArrayList (4);
1997 b
= e
.RemoveBuilder
;
1998 if (b
!= null && filter (b
, criteria
)) {
1999 if (members
== null)
2000 members
= new ArrayList (4);
2007 if (properties
!= null) {
2008 int len
= properties
.Count
;
2009 for (int i
= 0; i
< len
; i
++) {
2010 Property p
= (Property
) properties
[i
];
2012 if ((p
.ModFlags
& modflags
) == 0)
2014 if ((p
.ModFlags
& static_mask
) != static_flags
)
2020 if (b
!= null && filter (b
, criteria
) == true) {
2021 if (members
== null)
2022 members
= new ArrayList ();
2028 if (b
!= null && filter (b
, criteria
) == true) {
2029 if (members
== null)
2030 members
= new ArrayList ();
2037 if (indexers
!= null) {
2038 int len
= indexers
.Count
;
2039 for (int i
= 0; i
< len
; i
++) {
2040 Indexer ix
= (Indexer
) indexers
[i
];
2042 if ((ix
.ModFlags
& modflags
) == 0)
2044 if ((ix
.ModFlags
& static_mask
) != static_flags
)
2050 if (b
!= null && filter (b
, criteria
) == true) {
2051 if (members
== null)
2052 members
= new ArrayList ();
2058 if (b
!= null && filter (b
, criteria
) == true) {
2059 if (members
== null)
2060 members
= new ArrayList ();
2068 if ((mt
& MemberTypes
.Event
) != 0) {
2069 if (events
!= null) {
2070 int len
= events
.Count
;
2071 for (int i
= 0; i
< len
; i
++) {
2072 Event e
= (Event
) events
[i
];
2074 if ((e
.ModFlags
& modflags
) == 0)
2076 if ((e
.ModFlags
& static_mask
) != static_flags
)
2079 MemberInfo eb
= e
.EventBuilder
;
2080 if (eb
!= null && filter (eb
, criteria
) == true) {
2081 if (members
== null)
2082 members
= new ArrayList ();
2084 members
.Add (e
.EventBuilder
);
2090 if ((mt
& MemberTypes
.Property
) != 0){
2091 if (properties
!= null) {
2092 int len
= properties
.Count
;
2093 for (int i
= 0; i
< len
; i
++) {
2094 Property p
= (Property
) properties
[i
];
2096 if ((p
.ModFlags
& modflags
) == 0)
2098 if ((p
.ModFlags
& static_mask
) != static_flags
)
2101 MemberInfo pb
= p
.PropertyBuilder
;
2102 if (pb
!= null && filter (pb
, criteria
) == true) {
2103 if (members
== null)
2104 members
= new ArrayList ();
2106 members
.Add (p
.PropertyBuilder
);
2111 if (indexers
!= null) {
2112 int len
= indexers
.Count
;
2113 for (int i
= 0; i
< len
; i
++) {
2114 Indexer ix
= (Indexer
) indexers
[i
];
2116 if ((ix
.ModFlags
& modflags
) == 0)
2118 if ((ix
.ModFlags
& static_mask
) != static_flags
)
2121 MemberInfo ib
= ix
.PropertyBuilder
;
2122 if (ib
!= null && filter (ib
, criteria
) == true) {
2123 if (members
== null)
2124 members
= new ArrayList ();
2126 members
.Add (ix
.PropertyBuilder
);
2132 if ((mt
& MemberTypes
.NestedType
) != 0)
2133 FindMembers_NestedTypes (modflags
, bf
, filter
, criteria
, ref members
);
2135 if ((mt
& MemberTypes
.Constructor
) != 0){
2136 if (((bf
& BindingFlags
.Instance
) != 0) && (instance_constructors
!= null)){
2137 int len
= instance_constructors
.Count
;
2138 for (int i
= 0; i
< len
; i
++) {
2139 Constructor c
= (Constructor
) instance_constructors
[i
];
2141 ConstructorBuilder cb
= c
.ConstructorBuilder
;
2142 if (cb
!= null && filter (cb
, criteria
) == true) {
2143 if (members
== null)
2144 members
= new ArrayList ();
2151 if (((bf
& BindingFlags
.Static
) != 0) && (default_static_constructor
!= null)){
2152 ConstructorBuilder cb
=
2153 default_static_constructor
.ConstructorBuilder
;
2155 if (cb
!= null && filter (cb
, criteria
) == true) {
2156 if (members
== null)
2157 members
= new ArrayList ();
2165 // Lookup members in base if requested.
2167 if ((bf
& BindingFlags
.DeclaredOnly
) == 0) {
2168 if (TypeBuilder
.BaseType
!= null) {
2169 MemberList list
= FindMembers (TypeBuilder
.BaseType
, mt
, bf
, filter
, criteria
);
2170 if (list
.Count
> 0) {
2171 if (members
== null)
2172 members
= new ArrayList ();
2174 members
.AddRange (list
);
2179 Timer
.StopTimer (TimerType
.TcFindMembers
);
2181 if (members
== null)
2182 return MemberList
.Empty
;
2184 return new MemberList (members
);
2187 public override MemberCache MemberCache
{
2189 return member_cache
;
2193 public static MemberList
FindMembers (Type t
, MemberTypes mt
, BindingFlags bf
,
2194 MemberFilter filter
, object criteria
)
2196 DeclSpace ds
= TypeManager
.LookupDeclSpace (t
);
2199 return ds
.FindMembers (mt
, bf
, filter
, criteria
);
2201 return new MemberList (t
.FindMembers (mt
, bf
, filter
, criteria
));
2205 /// Emits the values for the constants
2207 public void EmitConstants ()
2209 if (constants
!= null)
2210 foreach (Const con
in constants
)
2215 static void CheckMemberUsage (MemberCoreArrayList al
, string member_type
)
2220 foreach (MemberCore mc
in al
) {
2221 if ((mc
.ModFlags
& Modifiers
.Accessibility
) != Modifiers
.PRIVATE
)
2225 Report
.Warning (169, 3, mc
.Location
, "The private {0} `{1}' is never used", member_type
, mc
.GetSignatureForError ());
2230 public virtual void VerifyMembers ()
2233 // Check for internal or private fields that were never assigned
2235 if (RootContext
.WarningLevel
>= 3) {
2236 CheckMemberUsage (properties
, "property");
2237 CheckMemberUsage (methods
, "method");
2238 CheckMemberUsage (constants
, "constant");
2240 if (fields
!= null){
2241 foreach (FieldBase f
in fields
) {
2242 if ((f
.ModFlags
& Modifiers
.Accessibility
) != Modifiers
.PRIVATE
)
2246 if ((f
.caching_flags
& Flags
.IsAssigned
) == 0)
2247 Report
.Warning (169, 3, f
.Location
, "The private field `{0}' is never used", f
.GetSignatureForError ());
2250 const int error_code
= 414;
2252 const int error_code
= 169;
2254 Report
.Warning (error_code
, 3, f
.Location
, "The private field `{0}' is assigned but its value is never used",
2255 f
.GetSignatureForError ());
2261 // Only report 649 on level 4
2263 if (RootContext
.WarningLevel
< 4)
2266 if ((f
.caching_flags
& Flags
.IsAssigned
) != 0)
2269 Constant c
= New
.Constantify (f
.Type
.Type
);
2270 Report
.Warning (649, 4, f
.Location
, "Field `{0}' is never assigned to, and will always have its default value `{1}'",
2271 f
.GetSignatureForError (), c
== null ? "null" : c
.AsString ());
2277 // TODO: move to ClassOrStruct
2278 void EmitConstructors ()
2280 if (instance_constructors
== null)
2283 if (TypeBuilder
.IsSubclassOf (TypeManager
.attribute_type
) && RootContext
.VerifyClsCompliance
&& IsClsComplianceRequired ()) {
2284 bool has_compliant_args
= false;
2286 foreach (Constructor c
in instance_constructors
) {
2290 catch (Exception e
) {
2291 throw new InternalErrorException (c
, e
);
2294 if (has_compliant_args
)
2297 has_compliant_args
= c
.HasCompliantArgs
;
2299 if (!has_compliant_args
)
2300 Report
.Error (3015, Location
, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2302 foreach (Constructor c
in instance_constructors
) {
2306 catch (Exception e
) {
2307 throw new InternalErrorException (c
, e
);
2314 /// Emits the code, this step is performed after all
2315 /// the types, enumerations, constructors
2317 public virtual void EmitType ()
2319 if (OptAttributes
!= null)
2320 OptAttributes
.Emit ();
2324 int offset
= CountTypeParameters
- CurrentTypeParameters
.Length
;
2325 for (int i
= offset
; i
< gen_params
.Length
; i
++)
2326 CurrentTypeParameters
[i
- offset
].EmitAttributes ();
2331 // Structs with no fields need to have at least one byte.
2332 // The right thing would be to set the PackingSize in a DefineType
2333 // but there are no functions that allow interfaces *and* the size to
2337 if (Kind
== Kind
.Struct
&& first_nonstatic_field
== null){
2338 FieldBuilder fb
= TypeBuilder
.DefineField ("$PRIVATE$", TypeManager
.byte_type
,
2339 FieldAttributes
.Private
);
2341 if (HasExplicitLayout
){
2342 object [] ctor_args
= new object [1];
2345 CustomAttributeBuilder cba
= new CustomAttributeBuilder (
2346 TypeManager
.field_offset_attribute_ctor
, ctor_args
);
2347 fb
.SetCustomAttribute (cba
);
2353 EmitConstructors ();
2355 // Can not continue if constants are broken
2357 if (Report
.Errors
> 0)
2360 if (default_static_constructor
!= null)
2361 default_static_constructor
.Emit ();
2363 if (methods
!= null){
2364 foreach (Method m
in methods
)
2368 if (operators
!= null)
2369 foreach (Operator o
in operators
)
2372 if (properties
!= null)
2373 foreach (Property p
in properties
)
2376 if (indexers
!= null){
2381 foreach (FieldBase f
in fields
)
2384 if (events
!= null){
2385 foreach (Event e
in Events
)
2389 if (delegates
!= null) {
2390 foreach (Delegate d
in Delegates
) {
2395 if (pending
!= null)
2396 if (pending
.VerifyPendingMethods ())
2399 if (Report
.Errors
> 0)
2402 if (compiler_generated
!= null) {
2403 foreach (CompilerGeneratedClass c
in compiler_generated
) {
2404 if (!c
.DefineMembers ())
2405 throw new InternalErrorException ();
2407 foreach (CompilerGeneratedClass c
in compiler_generated
)
2412 public override void CloseType ()
2414 if ((caching_flags
& Flags
.CloseTypeCreated
) != 0)
2418 caching_flags
|= Flags
.CloseTypeCreated
;
2419 TypeBuilder
.CreateType ();
2420 } catch (TypeLoadException
){
2422 // This is fine, the code still created the type
2424 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2425 // Console.WriteLine (e.Message);
2426 } catch (Exception e
) {
2427 throw new InternalErrorException (this, e
);
2431 foreach (Enum en
in Enums
)
2435 foreach (TypeContainer tc
in Types
)
2436 if (tc
.Kind
== Kind
.Struct
)
2439 foreach (TypeContainer tc
in Types
)
2440 if (tc
.Kind
!= Kind
.Struct
)
2444 if (Delegates
!= null)
2445 foreach (Delegate d
in Delegates
)
2448 if (CompilerGenerated
!= null)
2449 foreach (CompilerGeneratedClass c
in CompilerGenerated
)
2457 initialized_fields
= null;
2458 initialized_static_fields
= null;
2465 compiler_generated
= null;
2466 default_constructor
= null;
2467 default_static_constructor
= null;
2469 OptAttributes
= null;
2472 member_cache
= null;
2476 // Performs the validation on a Method's modifiers (properties have
2477 // the same properties).
2479 public bool MethodModifiersValid (MemberCore mc
)
2481 const int vao
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
| Modifiers
.OVERRIDE
);
2482 const int va
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
);
2483 const int nv
= (Modifiers
.NEW
| Modifiers
.VIRTUAL
);
2485 int flags
= mc
.ModFlags
;
2488 // At most one of static, virtual or override
2490 if ((flags
& Modifiers
.STATIC
) != 0){
2491 if ((flags
& vao
) != 0){
2492 Report
.Error (112, mc
.Location
, "A static member `{0}' cannot be marked as override, virtual or abstract",
2493 mc
.GetSignatureForError ());
2498 if (Kind
== Kind
.Struct
){
2499 if ((flags
& va
) != 0){
2500 Modifiers
.Error_InvalidModifier (mc
.Location
, "virtual or abstract");
2505 if ((flags
& Modifiers
.OVERRIDE
) != 0 && (flags
& nv
) != 0){
2506 Report
.Error (113, mc
.Location
, "A member `{0}' marked as override cannot be marked as new or virtual",
2507 mc
.GetSignatureForError ());
2512 // If the declaration includes the abstract modifier, then the
2513 // declaration does not include static, virtual or extern
2515 if ((flags
& Modifiers
.ABSTRACT
) != 0){
2516 if ((flags
& Modifiers
.EXTERN
) != 0){
2518 180, mc
.Location
, "`{0}' cannot be both extern and abstract", mc
.GetSignatureForError ());
2522 if ((flags
& Modifiers
.SEALED
) != 0) {
2523 Report
.Error (502, mc
.Location
, "`{0}' cannot be both abstract and sealed", mc
.GetSignatureForError ());
2527 if ((flags
& Modifiers
.VIRTUAL
) != 0){
2528 Report
.Error (503, mc
.Location
, "The abstract method `{0}' cannot be marked virtual", mc
.GetSignatureForError ());
2532 if ((ModFlags
& Modifiers
.ABSTRACT
) == 0){
2533 Report
.SymbolRelatedToPreviousError (this);
2534 Report
.Error (513, mc
.Location
, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2535 mc
.GetSignatureForError (), GetSignatureForError ());
2540 if ((flags
& Modifiers
.PRIVATE
) != 0){
2541 if ((flags
& vao
) != 0){
2542 Report
.Error (621, mc
.Location
, "`{0}': virtual or abstract members cannot be private", mc
.GetSignatureForError ());
2547 if ((flags
& Modifiers
.SEALED
) != 0){
2548 if ((flags
& Modifiers
.OVERRIDE
) == 0){
2549 Report
.Error (238, mc
.Location
, "`{0}' cannot be sealed because it is not an override", mc
.GetSignatureForError ());
2557 public Constructor DefaultStaticConstructor
{
2558 get { return default_static_constructor; }
2561 protected override bool VerifyClsCompliance ()
2563 if (!base.VerifyClsCompliance ())
2568 Type base_type
= TypeBuilder
.BaseType
;
2569 if (base_type
!= null && !AttributeTester
.IsClsCompliant (base_type
)) {
2570 Report
.Error (3009, Location
, "`{0}': base type `{1}' is not CLS-compliant", GetSignatureForError (), TypeManager
.CSharpName (base_type
));
2577 /// Checks whether container name is CLS Compliant
2579 void VerifyClsName ()
2581 Hashtable base_members
= base_cache
== null ?
2583 base_cache
.GetPublicMembers ();
2584 Hashtable this_members
= new Hashtable ();
2586 foreach (DictionaryEntry entry
in defined_names
) {
2587 MemberCore mc
= (MemberCore
)entry
.Value
;
2588 if (!mc
.IsClsComplianceRequired ())
2591 string name
= (string) entry
.Key
;
2592 string basename
= name
.Substring (name
.LastIndexOf ('.') + 1);
2594 string lcase
= basename
.ToLower (System
.Globalization
.CultureInfo
.InvariantCulture
);
2595 object found
= base_members
[lcase
];
2596 if (found
== null) {
2597 found
= this_members
[lcase
];
2598 if (found
== null) {
2599 this_members
.Add (lcase
, mc
);
2604 if ((mc
.ModFlags
& Modifiers
.OVERRIDE
) != 0)
2607 if (found
is MemberInfo
) {
2608 if (basename
== ((MemberInfo
) found
).Name
)
2610 Report
.SymbolRelatedToPreviousError ((MemberInfo
) found
);
2612 Report
.SymbolRelatedToPreviousError ((MemberCore
) found
);
2615 Report
.Warning (3005, 1, mc
.Location
, "Identifier `{0}' differing only in case is not CLS-compliant", mc
.GetSignatureForError ());
2617 Report
.Error (3005, mc
.Location
, "Identifier `{0}' differing only in case is not CLS-compliant", mc
.GetSignatureForError ());
2624 /// Performs checks for an explicit interface implementation. First it
2625 /// checks whether the `interface_type' is a base inteface implementation.
2626 /// Then it checks whether `name' exists in the interface type.
2628 public virtual bool VerifyImplements (InterfaceMemberBase mb
)
2630 if (ifaces
!= null) {
2631 foreach (Type t
in ifaces
){
2632 if (t
== mb
.InterfaceType
)
2637 Report
.SymbolRelatedToPreviousError (mb
.InterfaceType
);
2638 Report
.Error (540, mb
.Location
, "`{0}': containing type does not implement interface `{1}'",
2639 mb
.GetSignatureForError (), TypeManager
.CSharpName (mb
.InterfaceType
));
2643 public override Type
LookupAnyGeneric (string typeName
)
2645 if (types
!= null) {
2646 foreach (TypeContainer tc
in types
) {
2650 int pos
= tc
.Basename
.LastIndexOf ('`');
2651 if (pos
== typeName
.Length
&& String
.Compare (typeName
, 0, tc
.Basename
, 0, pos
) == 0)
2652 return tc
.TypeBuilder
;
2656 return base.LookupAnyGeneric (typeName
);
2659 public void Mark_HasEquals ()
2661 Methods
.HasEquals
= true;
2664 public void Mark_HasGetHashCode ()
2666 Methods
.HasGetHashCode
= true;
2673 string IMemberContainer
.Name
{
2679 Type IMemberContainer
.Type
{
2685 MemberCache IMemberContainer
.MemberCache
{
2687 return member_cache
;
2691 bool IMemberContainer
.IsInterface
{
2693 return Kind
== Kind
.Interface
;
2697 MemberList IMemberContainer
.GetMembers (MemberTypes mt
, BindingFlags bf
)
2699 BindingFlags new_bf
= bf
| BindingFlags
.DeclaredOnly
;
2701 if (GenericType
!= null)
2702 return TypeManager
.FindMembers (GenericType
, mt
, new_bf
,
2705 return FindMembers (mt
, new_bf
, null, null);
2709 // Generates xml doc comments (if any), and if required,
2710 // handle warning report.
2712 internal override void GenerateDocComment (DeclSpace ds
)
2714 DocUtil
.GenerateTypeDocComment (this, ds
);
2717 public override string DocCommentHeader
{
2718 get { return "T:"; }
2721 public virtual MemberCache BaseCache
{
2723 if (base_cache
!= null)
2725 if (TypeBuilder
.BaseType
!= null)
2726 base_cache
= TypeManager
.LookupMemberCache (TypeBuilder
.BaseType
);
2727 if (TypeBuilder
.IsInterface
)
2728 base_cache
= TypeManager
.LookupBaseInterfacesCache (TypeBuilder
);
2734 public abstract class ClassOrStruct
: TypeContainer
{
2735 ListDictionary declarative_security
;
2737 public ClassOrStruct (NamespaceEntry ns
, DeclSpace parent
,
2738 MemberName name
, Attributes attrs
, Kind kind
)
2739 : base (ns
, parent
, name
, attrs
, kind
)
2743 protected override bool AddToContainer (MemberCore symbol
, string name
)
2745 if (name
== MemberName
.Name
) {
2746 if (symbol
is TypeParameter
) {
2747 Report
.Error (694, symbol
.Location
,
2748 "Type parameter `{0}' has same name as " +
2749 "containing type, or method", name
);
2753 Report
.SymbolRelatedToPreviousError (this);
2754 Report
.Error (542, symbol
.Location
, "`{0}': member names cannot be the same as their enclosing type",
2755 symbol
.GetSignatureForError ());
2759 return base.AddToContainer (symbol
, name
);
2762 public override void VerifyMembers ()
2764 base.VerifyMembers ();
2766 if ((events
!= null) && (RootContext
.WarningLevel
>= 3)) {
2767 foreach (Event e
in events
){
2768 if ((e
.ModFlags
& Modifiers
.Accessibility
) != Modifiers
.PRIVATE
)
2771 if ((e
.caching_flags
& Flags
.IsUsed
) == 0)
2772 Report
.Warning (67, 3, e
.Location
, "The event `{0}' is never used", e
.GetSignatureForError ());
2777 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
2779 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
2780 if (declarative_security
== null)
2781 declarative_security
= new ListDictionary ();
2783 a
.ExtractSecurityPermissionSet (declarative_security
);
2787 if (a
.Type
== TypeManager
.struct_layout_attribute_type
&& a
.GetLayoutKindValue () == LayoutKind
.Explicit
) {
2788 HasExplicitLayout
= true;
2791 base.ApplyAttributeBuilder (a
, cb
);
2795 /// Defines the default constructors
2797 protected void DefineDefaultConstructor (bool is_static
)
2799 // The default instance constructor is public
2800 // If the class is abstract, the default constructor is protected
2801 // The default static constructor is private
2805 mods
= Modifiers
.STATIC
| Modifiers
.PRIVATE
;
2807 mods
= ((ModFlags
& Modifiers
.ABSTRACT
) != 0) ? Modifiers
.PROTECTED
: Modifiers
.PUBLIC
;
2810 Constructor c
= new Constructor (this, MemberName
.Name
, mods
,
2811 Parameters
.EmptyReadOnlyParameters
,
2812 new GeneratedBaseInitializer (Location
),
2816 c
.Block
= new ToplevelBlock (null, Location
);
2819 void DefineFieldInitializers ()
2821 if (initialized_fields
!= null) {
2822 for (int i
= 0; i
< initialized_fields
.Count
; ++i
) {
2823 FieldInitializer fi
= (FieldInitializer
)initialized_fields
[i
];
2825 EmitContext ec
= new EmitContext (fi
.TypeContainer
, fi
.TypeContainer
,
2826 Location
, null, null, ModFlags
);
2827 ec
.IsFieldInitializer
= true;
2829 fi
.ResolveStatement (ec
);
2830 if (fi
.IsDefaultInitializer
&& RootContext
.Optimize
) {
2831 // Field is re-initialized to its default value => removed
2832 initialized_fields
.RemoveAt (i
);
2838 if (initialized_static_fields
!= null) {
2839 bool has_complex_initializer
= false;
2841 foreach (FieldInitializer fi
in initialized_static_fields
) {
2842 EmitContext ec
= new EmitContext (fi
.TypeContainer
, fi
.TypeContainer
,
2843 Location
, null, null, ModFlags
);
2845 ec
.IsFieldInitializer
= true;
2847 fi
.ResolveStatement (ec
);
2848 if (!fi
.IsComplexInitializer
)
2851 has_complex_initializer
= true;
2854 // Need special check to not optimize code like this
2855 // static int a = b = 5;
2856 // static int b = 0;
2857 if (!has_complex_initializer
&& RootContext
.Optimize
) {
2858 for (int i
= 0; i
< initialized_static_fields
.Count
; ++i
) {
2859 FieldInitializer fi
= (FieldInitializer
)initialized_static_fields
[i
];
2860 if (fi
.IsDefaultInitializer
) {
2861 initialized_static_fields
.RemoveAt (i
);
2867 if (default_static_constructor
== null && initialized_static_fields
.Count
> 0) {
2868 DefineDefaultConstructor (true);
2874 public override bool Define ()
2876 DefineFieldInitializers ();
2878 if (default_static_constructor
!= null)
2879 default_static_constructor
.Define ();
2881 return base.Define ();
2884 public override void Emit ()
2888 if (declarative_security
!= null) {
2889 foreach (DictionaryEntry de
in declarative_security
) {
2890 TypeBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
2895 public override ExtensionMethodGroupExpr
LookupExtensionMethod (Type extensionType
, string name
)
2897 return NamespaceEntry
.LookupExtensionMethod (extensionType
, true, name
);
2900 protected override TypeAttributes TypeAttr
{
2902 if (default_static_constructor
== null)
2903 return base.TypeAttr
| TypeAttributes
.BeforeFieldInit
;
2905 return base.TypeAttr
;
2911 // TODO: should be sealed
2912 public class Class
: ClassOrStruct
{
2913 const int AllowedModifiers
=
2916 Modifiers
.PROTECTED
|
2917 Modifiers
.INTERNAL
|
2919 Modifiers
.ABSTRACT
|
2924 public const TypeAttributes StaticClassAttribute
= TypeAttributes
.Abstract
| TypeAttributes
.Sealed
;
2926 public Class (NamespaceEntry ns
, DeclSpace parent
, MemberName name
, int mod
,
2928 : base (ns
, parent
, name
, attrs
, Kind
.Class
)
2930 int accmods
= Parent
.Parent
== null ? Modifiers
.INTERNAL
: Modifiers
.PRIVATE
;
2931 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, Location
);
2933 if (IsStatic
&& RootContext
.Version
== LanguageVersion
.ISO_1
) {
2934 Report
.FeatureIsNotISO1 (Location
, "static classes");
2938 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
2940 if (a
.Type
== TypeManager
.attribute_usage_type
) {
2941 if (BaseType
!= TypeManager
.attribute_type
&& !BaseType
.IsSubclassOf (TypeManager
.attribute_type
) &&
2942 TypeBuilder
.FullName
!= "System.Attribute") {
2943 Report
.Error (641, a
.Location
, "Attribute `{0}' is only valid on classes derived from System.Attribute", a
.GetSignatureForError ());
2947 if (a
.Type
== TypeManager
.conditional_attribute_type
&&
2948 !(BaseType
== TypeManager
.attribute_type
|| BaseType
.IsSubclassOf (TypeManager
.attribute_type
))) {
2949 Report
.Error (1689, a
.Location
, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2953 if (a
.Type
== TypeManager
.comimport_attr_type
&&
2954 !attributes
.Contains (TypeManager
.guid_attr_type
)) {
2955 a
.Error_MissingGuidAttribute ();
2959 if (a
.Type
== TypeManager
.extension_attribute_type
) {
2960 a
.Error_MisusedExtensionAttribute ();
2964 if (AttributeTester
.IsAttributeExcluded (a
.Type
))
2967 base.ApplyAttributeBuilder (a
, cb
);
2970 public override AttributeTargets AttributeTargets
{
2972 return AttributeTargets
.Class
;
2976 protected override void DefineContainerMembers (MemberCoreArrayList list
)
2982 base.DefineContainerMembers (list
);
2986 foreach (MemberCore m
in list
) {
2987 if (m
is Operator
) {
2988 Report
.Error (715, m
.Location
, "`{0}': Static classes cannot contain user-defined operators", m
.GetSignatureForError ());
2992 if (m
is Destructor
) {
2993 Report
.Error (711, m
.Location
, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2997 if ((m
.ModFlags
& Modifiers
.PROTECTED
) != 0) {
2998 Report
.Error (1057, m
.Location
, "`{0}': Static classes cannot contain protected members", m
.GetSignatureForError ());
3003 Report
.Error (720, m
.Location
, "`{0}': cannot declare indexers in a static class", m
.GetSignatureForError ());
3007 if ((m
.ModFlags
& Modifiers
.STATIC
) != 0 || m
is Enum
|| m
is Delegate
)
3010 if (m
is Constructor
) {
3011 Report
.Error (710, m
.Location
, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
3015 Method method
= m
as Method
;
3016 if (method
!= null && method
.Parameters
.HasExtensionMethodType
) {
3017 Report
.Error (1105, m
.Location
, "`{0}': Extension methods must be declared static", m
.GetSignatureForError ());
3021 Report
.Error (708, m
.Location
, "`{0}': cannot declare instance members in a static class", m
.GetSignatureForError ());
3024 base.DefineContainerMembers (list
);
3027 public override TypeBuilder
DefineType ()
3029 if ((ModFlags
& Modifiers
.ABSTRACT
) == Modifiers
.ABSTRACT
&& (ModFlags
& (Modifiers
.SEALED
| Modifiers
.STATIC
)) != 0) {
3030 Report
.Error (418, Location
, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
3034 if ((ModFlags
& (Modifiers
.SEALED
| Modifiers
.STATIC
)) == (Modifiers
.SEALED
| Modifiers
.STATIC
)) {
3035 Report
.Error (441, Location
, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
3039 return base.DefineType ();
3042 protected override bool DoDefineMembers ()
3044 if (InstanceConstructors
== null && !IsStatic
)
3045 DefineDefaultConstructor (false);
3047 return base.DoDefineMembers ();
3050 public override void Emit ()
3054 if ((ModFlags
& Modifiers
.METHOD_EXTENSION
) != 0)
3055 TypeBuilder
.SetCustomAttribute (TypeManager
.extension_attribute_attr
);
3058 public override TypeExpr
[] GetClassBases (out TypeExpr base_class
)
3060 TypeExpr
[] ifaces
= base.GetClassBases (out base_class
);
3062 if (base_class
== null) {
3063 if (RootContext
.StdLib
)
3064 base_class
= TypeManager
.system_object_expr
;
3065 else if (Name
!= "System.Object")
3066 base_class
= TypeManager
.system_object_expr
;
3068 if (Kind
== Kind
.Class
&& base_class
is TypeParameterExpr
){
3070 689, base_class
.Location
,
3071 "Cannot derive from `{0}' because it is a type parameter",
3072 base_class
.GetSignatureForError ());
3076 if (base_class
.Type
.IsArray
|| base_class
.Type
.IsPointer
) {
3077 Report
.Error (1521, base_class
.Location
, "Invalid base type");
3081 if (base_class
.IsSealed
){
3082 Report
.SymbolRelatedToPreviousError (base_class
.Type
);
3083 if (base_class
.Type
.IsAbstract
) {
3084 Report
.Error (709, Location
, "`{0}': Cannot derive from static class `{1}'",
3085 GetSignatureForError (), TypeManager
.CSharpName (base_class
.Type
));
3087 Report
.Error (509, Location
, "`{0}': cannot derive from sealed class `{1}'",
3088 GetSignatureForError (), TypeManager
.CSharpName (base_class
.Type
));
3093 if (!base_class
.CanInheritFrom ()){
3094 Report
.Error (644, Location
, "`{0}' cannot derive from special class `{1}'",
3095 GetSignatureForError (), base_class
.GetSignatureForError ());
3099 if (!base_class
.AsAccessible (this, ModFlags
)) {
3100 Report
.SymbolRelatedToPreviousError (base_class
.Type
);
3101 Report
.Error (60, Location
, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
3102 TypeManager
.CSharpName (base_class
.Type
), GetSignatureForError ());
3107 if (base_class
!= TypeManager
.system_object_expr
) {
3108 Report
.Error (713, Location
, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
3109 GetSignatureForError (), base_class
.GetSignatureForError ());
3113 if (ifaces
!= null) {
3114 foreach (TypeExpr t
in ifaces
)
3115 Report
.SymbolRelatedToPreviousError (t
.Type
);
3116 Report
.Error (714, Location
, "`{0}': static classes cannot implement interfaces", GetSignatureForError ());
3123 /// Search for at least one defined condition in ConditionalAttribute of attribute class
3124 /// Valid only for attribute classes.
3125 public bool IsExcluded ()
3127 if ((caching_flags
& Flags
.Excluded_Undetected
) == 0)
3128 return (caching_flags
& Flags
.Excluded
) != 0;
3130 caching_flags
&= ~Flags
.Excluded_Undetected
;
3132 if (OptAttributes
== null)
3135 Attribute
[] attrs
= OptAttributes
.SearchMulti (TypeManager
.conditional_attribute_type
);
3140 foreach (Attribute a
in attrs
) {
3141 string condition
= a
.GetConditionalAttributeValue ();
3142 if (RootContext
.AllDefines
.Contains (condition
))
3146 caching_flags
|= Flags
.Excluded
;
3152 return (ModFlags
& Modifiers
.STATIC
) != 0;
3157 // FIXME: How do we deal with the user specifying a different
3160 protected override TypeAttributes TypeAttr
{
3162 TypeAttributes ta
= base.TypeAttr
| TypeAttributes
.AutoLayout
| TypeAttributes
.Class
;
3164 ta
|= StaticClassAttribute
;
3170 public sealed class Struct
: ClassOrStruct
{
3172 // Modifiers allowed in a struct declaration
3174 const int AllowedModifiers
=
3177 Modifiers
.PROTECTED
|
3178 Modifiers
.INTERNAL
|
3182 public Struct (NamespaceEntry ns
, DeclSpace parent
, MemberName name
,
3183 int mod
, Attributes attrs
)
3184 : base (ns
, parent
, name
, attrs
, Kind
.Struct
)
3188 if (parent
.Parent
== null)
3189 accmods
= Modifiers
.INTERNAL
;
3191 accmods
= Modifiers
.PRIVATE
;
3193 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, Location
);
3195 this.ModFlags
|= Modifiers
.SEALED
;
3198 public override AttributeTargets AttributeTargets
{
3200 return AttributeTargets
.Struct
;
3204 const TypeAttributes DefaultTypeAttributes
=
3205 TypeAttributes
.SequentialLayout
|
3206 TypeAttributes
.Sealed
|
3207 TypeAttributes
.BeforeFieldInit
;
3210 public override TypeExpr
[] GetClassBases (out TypeExpr base_class
)
3212 TypeExpr
[] ifaces
= base.GetClassBases (out base_class
);
3214 // If we are compiling our runtime,
3215 // and we are defining ValueType, then our
3216 // base is `System.Object'.
3218 if (base_class
== null) {
3219 if (!RootContext
.StdLib
&& Name
== "System.ValueType")
3220 base_class
= TypeManager
.system_object_expr
;
3222 base_class
= TypeManager
.system_valuetype_expr
;
3229 // FIXME: Allow the user to specify a different set of attributes
3230 // in some cases (Sealed for example is mandatory for a class,
3231 // but what SequentialLayout can be changed
3233 protected override TypeAttributes TypeAttr
{
3235 return base.TypeAttr
| DefaultTypeAttributes
;
3239 public override void RegisterFieldForInitialization (MemberCore field
, FieldInitializer expression
)
3241 if ((field
.ModFlags
& Modifiers
.STATIC
) == 0) {
3242 Report
.Error (573, field
.Location
, "`{0}': Structs cannot have instance field initializers",
3243 field
.GetSignatureForError ());
3246 base.RegisterFieldForInitialization (field
, expression
);
3254 public sealed class Interface
: TypeContainer
, IMemberContainer
{
3257 /// Modifiers allowed in a class declaration
3259 public const int AllowedModifiers
=
3262 Modifiers
.PROTECTED
|
3263 Modifiers
.INTERNAL
|
3267 public Interface (NamespaceEntry ns
, DeclSpace parent
, MemberName name
, int mod
,
3269 : base (ns
, parent
, name
, attrs
, Kind
.Interface
)
3273 if (parent
.Parent
== null)
3274 accmods
= Modifiers
.INTERNAL
;
3276 accmods
= Modifiers
.PRIVATE
;
3278 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, name
.Location
);
3281 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
3283 if (a
.Type
== TypeManager
.comimport_attr_type
&&
3284 !attributes
.Contains (TypeManager
.guid_attr_type
)) {
3285 a
.Error_MissingGuidAttribute ();
3288 base.ApplyAttributeBuilder (a
, cb
);
3292 public override AttributeTargets AttributeTargets
{
3294 return AttributeTargets
.Interface
;
3298 const TypeAttributes DefaultTypeAttributes
=
3299 TypeAttributes
.AutoLayout
|
3300 TypeAttributes
.Abstract
|
3301 TypeAttributes
.Interface
;
3303 protected override TypeAttributes TypeAttr
{
3305 return base.TypeAttr
| DefaultTypeAttributes
;
3309 protected override bool VerifyClsCompliance ()
3311 if (!base.VerifyClsCompliance ())
3314 if (ifaces
!= null) {
3315 foreach (Type t
in ifaces
) {
3316 if (AttributeTester
.IsClsCompliant (t
))
3319 Report
.SymbolRelatedToPreviousError (t
);
3320 Report
.Warning (3027, 1, Location
, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3321 GetSignatureForError (), TypeManager
.CSharpName (t
));
3329 // It is used as a base class for all property based members
3330 // This includes properties, indexers, and events
3331 public abstract class PropertyBasedMember
: InterfaceMemberBase
3333 public PropertyBasedMember (DeclSpace parent
, GenericMethod generic
,
3334 Expression type
, int mod
, int allowed_mod
, bool is_iface
,
3335 MemberName name
, Attributes attrs
)
3336 : base (parent
, generic
, type
, mod
, allowed_mod
, is_iface
, name
, attrs
)
3340 protected override bool CheckForDuplications ()
3342 throw new NotSupportedException ();
3345 protected override bool VerifyClsCompliance ()
3347 if (!base.VerifyClsCompliance ())
3350 if (!AttributeTester
.IsClsCompliant (MemberType
)) {
3351 Report
.Error (3003, Location
, "Type of `{0}' is not CLS-compliant",
3352 GetSignatureForError ());
3360 public abstract class MethodCore
: InterfaceMemberBase
3362 public readonly Parameters Parameters
;
3363 protected ToplevelBlock block
;
3365 public MethodCore (DeclSpace parent
, GenericMethod generic
,
3366 Expression type
, int mod
, int allowed_mod
, bool is_iface
,
3367 MemberName name
, Attributes attrs
, Parameters parameters
)
3368 : base (parent
, generic
, type
, mod
, allowed_mod
, is_iface
, name
, attrs
)
3370 Parameters
= parameters
;
3374 // Returns the System.Type array for the parameters of this method
3376 public Type
[] ParameterTypes
{
3378 return Parameters
.Types
;
3382 public Parameters ParameterInfo
3389 public ToplevelBlock Block
{
3399 protected override bool CheckBase ()
3401 // Check whether arguments were correct.
3402 if (!DefineParameters (Parameters
))
3405 if (!base.CheckBase ())
3411 // TODO: create a special method for operators only to make code better
3412 protected bool IsDuplicateImplementation (MethodCore method
)
3417 Operator op2
= null;
3418 Operator op1
= null;
3420 if (!(method
.MemberName
.Equals (MemberName
)))
3422 op1
= this as Operator
;
3423 if (op1
== null || !(op1
.OperatorType
== Operator
.OpType
.Explicit
|| op1
.OperatorType
== Operator
.OpType
.Implicit
))
3426 op2
= method
as Operator
;
3427 if (op2
== null || !(op2
.OperatorType
== Operator
.OpType
.Explicit
|| op2
.OperatorType
== Operator
.OpType
.Implicit
))
3430 op1
= this as Operator
;
3431 op2
= method
as Operator
;
3434 Type
[] param_types
= method
.ParameterTypes
;
3435 // This never happen. Rewrite this as Equal
3436 if (param_types
== null && ParameterTypes
== null)
3438 if (param_types
== null || ParameterTypes
== null)
3441 if (param_types
.Length
!= ParameterTypes
.Length
)
3444 if (method
.Parameters
.HasArglist
!= Parameters
.HasArglist
)
3449 for (int i
= 0; i
< param_types
.Length
; i
++) {
3450 if (param_types
[i
] != ParameterTypes
[i
])
3454 if (IsExplicitImpl
&& (method
.InterfaceType
!= InterfaceType
))
3457 // TODO: make operator compatible with MethodCore to avoid this
3458 if (op1
!= null && op2
!= null) {
3459 if (MemberType
!= method
.MemberType
)
3465 // Try to report 663: method only differs on out/ref
3467 Parameters info
= ParameterInfo
;
3468 Parameters other_info
= method
.ParameterInfo
;
3469 for (int i
= 0; i
< info
.Count
; i
++){
3470 if (info
.ParameterModifier (i
) != other_info
.ParameterModifier (i
)){
3471 Report
.SymbolRelatedToPreviousError (method
);
3472 Report
.Error (663, Location
, "`{0}': Methods cannot differ only on their use of ref and out on a parameters",
3473 GetSignatureForError ());
3478 Report
.SymbolRelatedToPreviousError (method
);
3479 if (this is Operator
&& method
is Operator
)
3480 Report
.Error (557, Location
, "Duplicate user-defined conversion in type `{0}'", Parent
.Name
);
3482 Report
.Error (111, Location
, TypeContainer
.Error111
, GetSignatureForError ());
3491 // Returns a string that represents the signature for this
3492 // member which should be used in XML documentation.
3494 public override string GetDocCommentName (DeclSpace ds
)
3496 return DocUtil
.GetMethodDocCommentName (this, Parameters
, ds
);
3500 // Raised (and passed an XmlElement that contains the comment)
3501 // when GenerateDocComment is writing documentation expectedly.
3503 // FIXME: with a few effort, it could be done with XmlReader,
3504 // that means removal of DOM use.
3506 internal override void OnGenerateDocComment (XmlElement el
)
3508 DocUtil
.OnMethodGenerateDocComment (this, el
);
3512 // Represents header string for documentation comment.
3514 public override string DocCommentHeader
3516 get { return "M:"; }
3519 public virtual void SetYields ()
3521 ModFlags
|= Modifiers
.METHOD_YIELDS
;
3524 protected override bool VerifyClsCompliance ()
3526 if (!base.VerifyClsCompliance ())
3529 if (Parameters
.HasArglist
) {
3530 Report
.Error (3000, Location
, "Methods with variable arguments are not CLS-compliant");
3533 if (!AttributeTester
.IsClsCompliant (MemberType
)) {
3534 Report
.Error (3002, Location
, "Return type of `{0}' is not CLS-compliant",
3535 GetSignatureForError ());
3538 Parameters
.VerifyClsCompliance ();
3544 public abstract class InterfaceMemberBase
: MemberBase
{
3546 // Whether this is an interface member.
3548 public bool IsInterface
;
3551 // If true, this is an explicit interface implementation
3553 public bool IsExplicitImpl
;
3555 protected bool is_external_implementation
;
3558 // The interface type we are explicitly implementing
3560 public Type InterfaceType
;
3563 // The method we're overriding if this is an override method.
3565 protected MethodInfo base_method
;
3567 readonly int explicit_mod_flags
;
3568 public MethodAttributes flags
;
3570 public InterfaceMemberBase (DeclSpace parent
, GenericMethod generic
,
3571 Expression type
, int mod
, int allowed_mod
, bool is_iface
,
3572 MemberName name
, Attributes attrs
)
3573 : base (parent
, generic
, type
, mod
, allowed_mod
, Modifiers
.PRIVATE
,
3576 IsInterface
= is_iface
;
3577 IsExplicitImpl
= (MemberName
.Left
!= null);
3578 explicit_mod_flags
= mod
;
3581 protected override bool CheckBase ()
3583 if (!base.CheckBase ())
3586 if ((caching_flags
& Flags
.TestMethodDuplication
) != 0 && !CheckForDuplications ())
3592 // Is null for System.Object while compiling corlib and base interfaces
3593 if (Parent
.PartialContainer
.BaseCache
== null) {
3594 if ((ModFlags
& Modifiers
.NEW
) != 0) {
3595 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3600 Type base_ret_type
= null;
3601 base_method
= FindOutBaseMethod (ref base_ret_type
);
3603 // method is override
3604 if (base_method
!= null) {
3605 if (!CheckMethodAgainstBase (base_ret_type
))
3608 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3609 ObsoleteAttribute oa
= AttributeTester
.GetMethodObsoleteAttribute (base_method
);
3611 if (OptAttributes
== null || !OptAttributes
.Contains (TypeManager
.obsolete_attribute_type
)) {
3612 Report
.SymbolRelatedToPreviousError (base_method
);
3613 Report
.Warning (672, 1, Location
, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3614 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3617 if (OptAttributes
!= null && OptAttributes
.Contains (TypeManager
.obsolete_attribute_type
)) {
3618 Report
.Warning (809, 1, Location
, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3619 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3626 MemberInfo conflict_symbol
= Parent
.PartialContainer
.FindBaseMemberWithSameName (Name
, !((this is Event
) || (this is Property
)));
3627 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3628 if (conflict_symbol
!= null) {
3629 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
3631 Report
.Error (72, Location
, "`{0}': cannot override because `{1}' is not an event", GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3632 else if (this is PropertyBase
)
3633 Report
.Error (544, Location
, "`{0}': cannot override because `{1}' is not a property", GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3635 Report
.Error (505, Location
, "`{0}': cannot override because `{1}' is not a method", GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3637 Report
.Error (115, Location
, "`{0}' is marked as an override but no suitable {1} found to override",
3638 GetSignatureForError (), SimpleName
.GetMemberType (this));
3643 if (conflict_symbol
== null) {
3644 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0)) {
3645 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3650 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3651 if (this is Method
&& conflict_symbol
is MethodBase
)
3654 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
3655 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3656 GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3663 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3664 // that have been defined.
3666 // `name' is the user visible name for reporting errors (this is used to
3667 // provide the right name regarding method names and properties)
3669 bool CheckMethodAgainstBase (Type baseMethodType
)
3673 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0){
3674 if (!(base_method
.IsAbstract
|| base_method
.IsVirtual
)){
3675 Report
.Error (506, Location
,
3676 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3677 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3681 // Now we check that the overriden method is not final
3683 if (base_method
.IsFinal
) {
3684 Report
.SymbolRelatedToPreviousError (base_method
);
3685 Report
.Error (239, Location
, "`{0}': cannot override inherited member `{1}' because it is sealed",
3686 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3690 // Check that the permissions are not being changed
3692 MethodAttributes thisp
= flags
& MethodAttributes
.MemberAccessMask
;
3693 MethodAttributes base_classp
= base_method
.Attributes
& MethodAttributes
.MemberAccessMask
;
3695 if (!CheckAccessModifiers (thisp
, base_classp
, base_method
)) {
3696 Error_CannotChangeAccessModifiers (base_method
, base_classp
, null);
3700 if (!TypeManager
.IsEqual (MemberType
, TypeManager
.TypeToCoreType (baseMethodType
))) {
3701 Report
.SymbolRelatedToPreviousError (base_method
);
3702 if (this is PropertyBasedMember
) {
3703 Report
.Error (1715, Location
, "`{0}': type must be `{1}' to match overridden member `{2}'",
3704 GetSignatureForError (), TypeManager
.CSharpName (baseMethodType
), TypeManager
.CSharpSignature (base_method
));
3707 Report
.Error (508, Location
, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3708 GetSignatureForError (), TypeManager
.CSharpName (baseMethodType
), TypeManager
.CSharpSignature (base_method
));
3714 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3715 if ((ModFlags
& Modifiers
.OVERRIDE
) == 0 && Name
!= "Finalize") {
3716 ModFlags
|= Modifiers
.NEW
;
3717 Report
.SymbolRelatedToPreviousError (base_method
);
3718 if (!IsInterface
&& (base_method
.IsVirtual
|| base_method
.IsAbstract
)) {
3719 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",
3720 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3722 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3723 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3727 if (base_method
.IsAbstract
&& !IsInterface
) {
3728 Report
.SymbolRelatedToPreviousError (base_method
);
3729 Report
.Error (533, Location
, "`{0}' hides inherited abstract member `{1}'",
3730 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3738 protected bool CheckAccessModifiers (MethodAttributes thisp
, MethodAttributes base_classp
, MethodInfo base_method
)
3740 if ((base_classp
& MethodAttributes
.FamORAssem
) == MethodAttributes
.FamORAssem
){
3742 // when overriding protected internal, the method can be declared
3743 // protected internal only within the same assembly
3746 if ((thisp
& MethodAttributes
.FamORAssem
) == MethodAttributes
.FamORAssem
){
3747 if (Parent
.TypeBuilder
.Assembly
!= base_method
.DeclaringType
.Assembly
){
3749 // assemblies differ - report an error
3753 } else if (thisp
!= base_classp
) {
3755 // same assembly, but other attributes differ - report an error
3760 } else if ((thisp
& MethodAttributes
.Family
) != MethodAttributes
.Family
) {
3762 // if it's not "protected internal", it must be "protected"
3766 } else if (Parent
.TypeBuilder
.Assembly
== base_method
.DeclaringType
.Assembly
) {
3768 // protected within the same assembly - an error
3771 } else if ((thisp
& ~
(MethodAttributes
.Family
| MethodAttributes
.FamORAssem
)) !=
3772 (base_classp
& ~
(MethodAttributes
.Family
| MethodAttributes
.FamORAssem
))) {
3774 // protected ok, but other attributes differ - report an error
3780 return (thisp
== base_classp
);
3784 public bool CheckAbstractAndExtern (bool has_block
)
3786 if (Parent
.PartialContainer
.Kind
== Kind
.Interface
)
3790 if ((ModFlags
& Modifiers
.EXTERN
) != 0) {
3791 Report
.Error (179, Location
, "`{0}' cannot declare a body because it is marked extern",
3792 GetSignatureForError ());
3796 if ((ModFlags
& Modifiers
.ABSTRACT
) != 0) {
3797 Report
.Error (500, Location
, "`{0}' cannot declare a body because it is marked abstract",
3798 GetSignatureForError ());
3802 if ((ModFlags
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) == 0) {
3803 Report
.Error (501, Location
, "`{0}' must declare a body because it is not marked abstract or extern",
3804 GetSignatureForError ());
3812 protected bool DefineParameters (Parameters parameters
)
3814 IResolveContext rc
= GenericMethod
== null ? this : (IResolveContext
)ds
;
3816 if (!parameters
.Resolve (rc
))
3820 foreach (Parameter p
in parameters
.FixedParameters
) {
3821 if (p
.CheckAccessibility (this))
3824 Report
.SymbolRelatedToPreviousError (p
.ParameterType
);
3825 if (this is Indexer
)
3826 Report
.Error (55, Location
,
3827 "Inconsistent accessibility: parameter type `" +
3828 TypeManager
.CSharpName (p
.ParameterType
) + "' is less " +
3829 "accessible than indexer `" + GetSignatureForError () + "'");
3830 else if (this is Operator
)
3831 Report
.Error (57, Location
,
3832 "Inconsistent accessibility: parameter type `" +
3833 TypeManager
.CSharpName (p
.ParameterType
) + "' is less " +
3834 "accessible than operator `" + GetSignatureForError () + "'");
3836 Report
.Error (51, Location
,
3837 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3838 TypeManager
.CSharpName (p
.ParameterType
), GetSignatureForError ());
3844 protected override bool DoDefine()
3846 if (!base.DoDefine ())
3849 if (IsExplicitImpl
) {
3850 Expression expr
= MemberName
.Left
.GetTypeExpression ();
3851 TypeExpr texpr
= expr
.ResolveAsTypeTerminal (this, false);
3855 InterfaceType
= texpr
.Type
;
3857 if (!InterfaceType
.IsInterface
) {
3858 Report
.Error (538, Location
, "`{0}' in explicit interface declaration is not an interface", TypeManager
.CSharpName (InterfaceType
));
3862 if (!Parent
.PartialContainer
.VerifyImplements (this))
3869 protected virtual bool DoDefineBase ()
3872 throw new InternalErrorException ();
3875 ModFlags
= Modifiers
.PUBLIC
|
3876 Modifiers
.ABSTRACT
|
3877 Modifiers
.VIRTUAL
| (ModFlags
& Modifiers
.UNSAFE
) | (ModFlags
& Modifiers
.NEW
);
3879 flags
= MethodAttributes
.Public
|
3880 MethodAttributes
.Abstract
|
3881 MethodAttributes
.HideBySig
|
3882 MethodAttributes
.NewSlot
|
3883 MethodAttributes
.Virtual
;
3885 if (!Parent
.PartialContainer
.MethodModifiersValid (this))
3888 flags
= Modifiers
.MethodAttr (ModFlags
);
3891 if (IsExplicitImpl
) {
3892 Expression expr
= MemberName
.Left
.GetTypeExpression ();
3893 TypeExpr iface_texpr
= expr
.ResolveAsTypeTerminal (this, false);
3894 if (iface_texpr
== null)
3897 InterfaceType
= iface_texpr
.Type
;
3899 if (!InterfaceType
.IsInterface
) {
3900 Report
.Error (538, Location
, "'{0}' in explicit interface declaration is not an interface", TypeManager
.CSharpName (InterfaceType
));
3904 if (!Parent
.PartialContainer
.VerifyImplements (this))
3907 Modifiers
.Check (Modifiers
.AllowedExplicitImplFlags
, explicit_mod_flags
, 0, Location
);
3913 public override void Emit()
3915 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3916 // We are more strict than Microsoft and report CS0626 as error
3917 if ((ModFlags
& Modifiers
.EXTERN
) != 0 && !is_external_implementation
) {
3918 Report
.Error (626, Location
,
3919 "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3920 GetSignatureForError ());
3926 protected void Error_CannotChangeAccessModifiers (MemberInfo base_method
, MethodAttributes ma
, string suffix
)
3928 Report
.SymbolRelatedToPreviousError (base_method
);
3929 string base_name
= TypeManager
.GetFullNameSignature (base_method
);
3930 string this_name
= GetSignatureForError ();
3931 if (suffix
!= null) {
3932 base_name
+= suffix
;
3933 this_name
+= suffix
;
3936 Report
.Error (507, Location
, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3937 this_name
, Modifiers
.GetDescription (ma
), base_name
);
3940 protected static string Error722
{
3942 return "`{0}': static types cannot be used as return types";
3947 /// For custom member duplication search in a container
3949 protected abstract bool CheckForDuplications ();
3952 /// Gets base method and its return type
3954 protected abstract MethodInfo
FindOutBaseMethod (ref Type base_ret_type
);
3957 // The "short" name of this property / indexer / event. This is the
3958 // name without the explicit interface.
3960 public string ShortName
3962 get { return MemberName.Name; }
3963 set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
3966 protected override bool VerifyClsCompliance ()
3968 if (!base.VerifyClsCompliance ()) {
3969 if (IsInterface
&& HasClsCompliantAttribute
&& Parent
.IsClsComplianceRequired ()) {
3970 Report
.Error (3010, Location
, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
3973 if ((ModFlags
& Modifiers
.ABSTRACT
) != 0 && Parent
.TypeBuilder
.IsClass
&& IsExposedFromAssembly () && Parent
.IsClsComplianceRequired ()) {
3974 Report
.Error (3011, Location
, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3979 if (GenericMethod
!= null)
3980 GenericMethod
.VerifyClsCompliance ();
3985 public override bool IsUsed
3987 get { return IsExplicitImpl || base.IsUsed; }
3992 public abstract class MethodOrOperator
: MethodCore
, IMethodData
3994 public MethodBuilder MethodBuilder
;
3995 ReturnParameter return_attributes
;
3996 ListDictionary declarative_security
;
3997 protected MethodData MethodData
;
4000 ArrayList anonymous_methods
;
4002 static string[] attribute_targets
= new string [] { "method", "return" }
;
4004 protected MethodOrOperator (DeclSpace parent
, GenericMethod generic
, Expression type
, int mod
,
4005 int allowed_mod
, bool is_interface
, MemberName name
,
4006 Attributes attrs
, Parameters parameters
)
4007 : base (parent
, generic
, type
, mod
, allowed_mod
, is_interface
, name
,
4012 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
4014 if (a
.Target
== AttributeTargets
.ReturnValue
) {
4015 if (return_attributes
== null)
4016 return_attributes
= new ReturnParameter (MethodBuilder
, Location
);
4018 return_attributes
.ApplyAttributeBuilder (a
, cb
);
4022 if (a
.IsInternalMethodImplAttribute
) {
4023 MethodBuilder
.SetImplementationFlags (MethodImplAttributes
.InternalCall
| MethodImplAttributes
.Runtime
);
4024 is_external_implementation
= true;
4027 if (a
.Type
== TypeManager
.dllimport_type
) {
4028 const int extern_static
= Modifiers
.EXTERN
| Modifiers
.STATIC
;
4029 if ((ModFlags
& extern_static
) != extern_static
) {
4030 Report
.Error (601, a
.Location
, "The DllImport attribute must be specified on a method marked `static' and `extern'");
4032 is_external_implementation
= true;
4035 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
4036 if (declarative_security
== null)
4037 declarative_security
= new ListDictionary ();
4038 a
.ExtractSecurityPermissionSet (declarative_security
);
4042 MethodBuilder
.SetCustomAttribute (cb
);
4045 public override AttributeTargets AttributeTargets
{
4047 return AttributeTargets
.Method
;
4051 public virtual EmitContext
CreateEmitContext (DeclSpace tc
, ILGenerator ig
)
4053 return new EmitContext (
4054 this, tc
, this.ds
, Location
, ig
, MemberType
, ModFlags
, false);
4057 public void AddAnonymousMethod (AnonymousMethodExpression anonymous
)
4059 if (anonymous_methods
== null)
4060 anonymous_methods
= new ArrayList ();
4061 anonymous_methods
.Add (anonymous
);
4064 protected bool DefineGenericMethod ()
4066 if (!DoDefineBase ())
4070 if (GenericMethod
!= null) {
4071 string method_name
= MemberName
.Name
;
4073 if (IsExplicitImpl
) {
4074 method_name
= TypeManager
.CSharpName (InterfaceType
) +
4079 MethodBuilder
= Parent
.TypeBuilder
.DefineMethod (method_name
, flags
, ReturnType
, null);
4081 MethodBuilder
= Parent
.TypeBuilder
.DefineMethod (method_name
, flags
);
4084 if (!GenericMethod
.Define (MethodBuilder
, block
))
4092 public bool ResolveMembers ()
4094 if (!DefineGenericMethod ())
4097 if ((ModFlags
& Modifiers
.METHOD_YIELDS
) != 0) {
4098 iterator
= Iterator
.CreateIterator (this, Parent
, GenericMethod
, ModFlags
);
4099 if (iterator
== null)
4103 if (anonymous_methods
!= null) {
4104 foreach (AnonymousMethodExpression ame
in anonymous_methods
) {
4105 if (!ame
.CreateAnonymousHelpers ())
4113 public override bool Define ()
4118 if (!CheckAbstractAndExtern (block
!= null))
4124 MethodData
= new MethodData (
4125 this, ModFlags
, flags
, this, MethodBuilder
, GenericMethod
, base_method
);
4127 if (!MethodData
.Define (Parent
.PartialContainer
))
4130 MethodBuilder
= MethodData
.MethodBuilder
;
4132 if (!TypeManager
.IsGenericParameter (MemberType
)) {
4133 if (MemberType
.IsAbstract
&& MemberType
.IsSealed
) {
4134 Report
.Error (722, Location
, Error722
, TypeManager
.CSharpName (MemberType
));
4142 public override void Emit ()
4144 if (OptAttributes
!= null)
4145 OptAttributes
.Emit ();
4147 if (declarative_security
!= null) {
4148 foreach (DictionaryEntry de
in declarative_security
) {
4149 MethodBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
4156 protected void Error_ConditionalAttributeIsNotValid ()
4158 Report
.Error (577, Location
,
4159 "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
4160 GetSignatureForError ());
4163 public override bool MarkForDuplicationCheck ()
4165 caching_flags
|= Flags
.TestMethodDuplication
;
4169 public override string[] ValidAttributeTargets
{
4171 return attribute_targets
;
4175 #region IMethodData Members
4177 public CallingConventions CallingConventions
{
4179 CallingConventions cc
= Parameters
.CallingConvention
;
4180 if (Parameters
.HasArglist
&& block
!= null)
4181 block
.HasVarargs
= true;
4184 if ((ModFlags
& Modifiers
.STATIC
) == 0)
4185 cc
|= CallingConventions
.HasThis
;
4187 // FIXME: How is `ExplicitThis' used in C#?
4193 public Type ReturnType
{
4199 public MemberName MethodName
{
4205 public Iterator Iterator
{
4206 get { return iterator; }
4209 public new Location Location
{
4211 return base.Location
;
4215 protected override bool CheckBase ()
4217 if (!base.CheckBase ())
4220 // TODO: Destructor should derive from MethodCore
4221 if (base_method
!= null && (ModFlags
& Modifiers
.OVERRIDE
) != 0 && Name
== "Finalize" &&
4222 base_method
.DeclaringType
== TypeManager
.object_type
&& !(this is Destructor
)) {
4223 Report
.Error (249, Location
, "Do not override object.Finalize. Instead, provide a destructor");
4231 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
4233 public bool IsExcluded () {
4234 if ((caching_flags
& Flags
.Excluded_Undetected
) == 0)
4235 return (caching_flags
& Flags
.Excluded
) != 0;
4237 caching_flags
&= ~Flags
.Excluded_Undetected
;
4239 if (base_method
== null) {
4240 if (OptAttributes
== null)
4243 Attribute
[] attrs
= OptAttributes
.SearchMulti (TypeManager
.conditional_attribute_type
);
4248 foreach (Attribute a
in attrs
) {
4249 string condition
= a
.GetConditionalAttributeValue ();
4250 if (condition
== null)
4253 if (RootContext
.AllDefines
.Contains (condition
))
4257 caching_flags
|= Flags
.Excluded
;
4261 IMethodData md
= TypeManager
.GetMethod (base_method
);
4263 if (AttributeTester
.IsConditionalMethodExcluded (base_method
)) {
4264 caching_flags
|= Flags
.Excluded
;
4270 if (md
.IsExcluded ()) {
4271 caching_flags
|= Flags
.Excluded
;
4277 GenericMethod IMethodData
.GenericMethod
{
4279 return GenericMethod
;
4287 public class SourceMethod
: ISourceMethod
4292 protected SourceMethod (DeclSpace parent
, MethodBase builder
,
4293 ISourceFile file
, Location start
, Location end
)
4295 this.parent
= parent
;
4296 this.builder
= builder
;
4298 CodeGen
.SymbolWriter
.OpenMethod (file
, this, start
.Row
, start
.Column
, end
.Row
, start
.Column
);
4301 public string Name
{
4302 get { return builder.Name; }
4305 public int NamespaceID
{
4306 get { return parent.NamespaceEntry.SymbolFileID; }
4311 if (builder
is MethodBuilder
)
4312 return ((MethodBuilder
) builder
).GetToken ().Token
;
4313 else if (builder
is ConstructorBuilder
)
4314 return ((ConstructorBuilder
) builder
).GetToken ().Token
;
4316 throw new NotSupportedException ();
4320 public void CloseMethod ()
4322 if (CodeGen
.SymbolWriter
!= null)
4323 CodeGen
.SymbolWriter
.CloseMethod ();
4326 public static SourceMethod
Create (DeclSpace parent
, MethodBase builder
, Block block
)
4328 if (CodeGen
.SymbolWriter
== null)
4333 Location start_loc
= block
.StartLocation
;
4334 if (start_loc
.IsNull
)
4337 Location end_loc
= block
.EndLocation
;
4341 ISourceFile file
= start_loc
.SourceFile
;
4345 return new SourceMethod (
4346 parent
, builder
, file
, start_loc
, end_loc
);
4350 public class Method
: MethodOrOperator
, IAnonymousHost
{
4353 /// Modifiers allowed in a class declaration
4355 const int AllowedModifiers
=
4358 Modifiers
.PROTECTED
|
4359 Modifiers
.INTERNAL
|
4364 Modifiers
.OVERRIDE
|
4365 Modifiers
.ABSTRACT
|
4367 Modifiers
.METHOD_YIELDS
|
4370 const int AllowedInterfaceModifiers
=
4371 Modifiers
.NEW
| Modifiers
.UNSAFE
;
4374 // return_type can be "null" for VOID values.
4376 public Method (DeclSpace parent
, GenericMethod generic
,
4377 Expression return_type
, int mod
, bool is_iface
,
4378 MemberName name
, Parameters parameters
, Attributes attrs
)
4379 : base (parent
, generic
, return_type
, mod
,
4380 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
4381 is_iface
, name
, attrs
, parameters
)
4385 public override string GetSignatureForError()
4387 return base.GetSignatureForError () + Parameters
.GetSignatureForError ();
4390 void Error_DuplicateEntryPoint (MethodInfo b
, Location location
)
4392 Report
.Error (17, location
,
4393 "Program `{0}' has more than one entry point defined: `{1}'",
4394 CodeGen
.FileName
, TypeManager
.CSharpSignature(b
));
4397 bool IsEntryPoint ()
4399 if (ReturnType
!= TypeManager
.void_type
&&
4400 ReturnType
!= TypeManager
.int32_type
)
4403 if (Parameters
.Count
== 0)
4406 if (Parameters
.Count
> 1)
4409 Type t
= Parameters
.ParameterType (0);
4410 return t
.IsArray
&& t
.GetArrayRank () == 1 &&
4411 TypeManager
.GetElementType (t
) == TypeManager
.string_type
&&
4412 (Parameters
[0].ModFlags
& ~Parameter
.Modifier
.PARAMS
) == Parameter
.Modifier
.NONE
;
4415 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
4417 if (a
.Type
== TypeManager
.conditional_attribute_type
) {
4418 if (IsExplicitImpl
) {
4419 Error_ConditionalAttributeIsNotValid ();
4423 if (ReturnType
!= TypeManager
.void_type
) {
4424 Report
.Error (578, Location
, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
4428 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
4429 Report
.Error (243, Location
, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
4434 Report
.Error (582, Location
, "Conditional not valid on interface members");
4438 if (MethodData
.implementing
!= null) {
4439 Report
.Error (629, Location
, "Conditional member `{0}' cannot implement interface member `{1}'",
4440 GetSignatureForError (), TypeManager
.CSharpSignature (MethodData
.implementing
));
4444 for (int i
= 0; i
< Parameters
.Count
; ++i
) {
4445 if ((Parameters
.ParameterModifier (i
) & Parameter
.Modifier
.OUTMASK
) != 0) {
4446 Report
.Error (685, Location
, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
4452 if (a
.Type
== TypeManager
.extension_attribute_type
) {
4453 a
.Error_MisusedExtensionAttribute ();
4457 base.ApplyAttributeBuilder (a
, cb
);
4460 protected override bool CheckForDuplications ()
4462 ArrayList ar
= Parent
.PartialContainer
.Methods
;
4464 int arLen
= ar
.Count
;
4466 for (int i
= 0; i
< arLen
; i
++) {
4467 Method m
= (Method
) ar
[i
];
4468 if (IsDuplicateImplementation (m
))
4473 ar
= Parent
.PartialContainer
.Properties
;
4475 for (int i
= 0; i
< ar
.Count
; ++i
) {
4476 PropertyBase pb
= (PropertyBase
) ar
[i
];
4477 if (pb
.AreAccessorsDuplicateImplementation (this))
4482 ar
= Parent
.PartialContainer
.Indexers
;
4484 for (int i
= 0; i
< ar
.Count
; ++i
) {
4485 PropertyBase pb
= (PropertyBase
) ar
[i
];
4486 if (pb
.AreAccessorsDuplicateImplementation (this))
4491 ar
= Parent
.PartialContainer
.Events
;
4493 for (int i
= 0; i
< ar
.Count
; ++i
) {
4494 Event ev
= (Event
) ar
[i
];
4495 if (ev
.AreAccessorsDuplicateImplementation (this))
4506 public override bool Define ()
4508 if (!base.Define ())
4511 if (RootContext
.StdLib
&& (ReturnType
== TypeManager
.arg_iterator_type
|| ReturnType
== TypeManager
.typed_reference_type
)) {
4512 Error1599 (Location
, ReturnType
);
4516 if (ReturnType
== TypeManager
.void_type
&& ParameterTypes
.Length
== 0 &&
4517 Name
== "Finalize" && !(this is Destructor
)) {
4518 Report
.Warning (465, 1, Location
, "Introducing a 'Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
4521 if (base_method
!= null && (ModFlags
& Modifiers
.NEW
) == 0) {
4522 if (Parameters
.Count
== 1 && ParameterTypes
[0] == TypeManager
.object_type
&& Name
== "Equals")
4523 Parent
.PartialContainer
.Mark_HasEquals ();
4524 else if (Parameters
.Empty
&& Name
== "GetHashCode")
4525 Parent
.PartialContainer
.Mark_HasGetHashCode ();
4528 if ((ModFlags
& Modifiers
.STATIC
) == 0)
4531 if (Parameters
.HasExtensionMethodType
) {
4532 if (Parent
.IsStaticClass
&& !Parent
.IsGeneric
) {
4533 if (!Parent
.IsTopLevel
)
4534 Report
.Error (1109, Location
, "`{0}': Extension methods cannot be defined in a nested class",
4535 GetSignatureForError ());
4537 if (TypeManager
.extension_attribute_type
== null)
4538 Report
.Error (1110, Location
,
4539 "`{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",
4540 GetSignatureForError ());
4542 ModFlags
|= Modifiers
.METHOD_EXTENSION
;
4543 Parent
.ModFlags
|= Modifiers
.METHOD_EXTENSION
;
4544 CodeGen
.Assembly
.HasExtensionMethods
= true;
4546 Report
.Error (1106, Location
, "`{0}': Extension methods must be defined in a non-generic static class",
4547 GetSignatureForError ());
4552 // This is used to track the Entry Point,
4554 if (RootContext
.NeedsEntryPoint
&&
4556 (RootContext
.MainClass
== null ||
4557 RootContext
.MainClass
== Parent
.TypeBuilder
.FullName
)){
4558 if (IsEntryPoint ()) {
4560 if (RootContext
.EntryPoint
== null) {
4561 if (Parent
.IsGeneric
|| MemberName
.IsGeneric
) {
4562 Report
.Warning (402, 4, Location
, "`{0}': an entry point cannot be generic or in a generic type",
4563 GetSignatureForError ());
4565 IMethodData md
= TypeManager
.GetMethod (MethodBuilder
);
4566 md
.SetMemberIsUsed ();
4568 RootContext
.EntryPoint
= MethodBuilder
;
4569 RootContext
.EntryPointLocation
= Location
;
4572 Error_DuplicateEntryPoint (RootContext
.EntryPoint
, RootContext
.EntryPointLocation
);
4573 Error_DuplicateEntryPoint (MethodBuilder
, Location
);
4576 Report
.Warning (28, 4, Location
, "`{0}' has the wrong signature to be an entry point",
4577 GetSignatureForError ());
4587 public override void Emit ()
4589 Report
.Debug (64, "METHOD EMIT", this, MethodBuilder
, Location
, Block
, MethodData
);
4590 MethodData
.Emit (Parent
);
4593 if ((ModFlags
& Modifiers
.METHOD_EXTENSION
) != 0)
4594 MethodBuilder
.SetCustomAttribute (TypeManager
.extension_attribute_attr
);
4600 public static void Error1599 (Location loc
, Type t
)
4602 Report
.Error (1599, loc
, "Method or delegate cannot return type `{0}'", TypeManager
.CSharpName (t
));
4605 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
4607 MethodInfo mi
= (MethodInfo
) Parent
.PartialContainer
.BaseCache
.FindMemberToOverride (
4608 Parent
.TypeBuilder
, Name
, ParameterTypes
, GenericMethod
, false);
4613 if (mi
.IsSpecialName
)
4616 base_ret_type
= mi
.ReturnType
;
4620 protected override bool VerifyClsCompliance ()
4622 if (!base.VerifyClsCompliance ())
4625 if (ParameterInfo
.Count
> 0) {
4626 ArrayList al
= (ArrayList
)Parent
.PartialContainer
.MemberCache
.Members
[Name
];
4628 MemberCache
.VerifyClsParameterConflict (al
, this, MethodBuilder
);
4635 public abstract class ConstructorInitializer
{
4636 ArrayList argument_list
;
4637 protected ConstructorInfo base_constructor
;
4640 public ConstructorInitializer (ArrayList argument_list
, Location loc
)
4642 this.argument_list
= argument_list
;
4646 public ArrayList Arguments
{
4648 return argument_list
;
4652 public bool Resolve (ConstructorBuilder caller_builder
, Block block
, EmitContext ec
)
4654 Expression base_constructor_group
;
4658 ec
.CurrentBlock
= block
;
4660 if (argument_list
!= null){
4661 foreach (Argument a
in argument_list
){
4662 if (!a
.Resolve (ec
, loc
))
4666 ec
.CurrentBlock
= null;
4668 if (this is ConstructorBaseInitializer
) {
4669 if (ec
.ContainerType
.BaseType
== null)
4672 t
= ec
.ContainerType
.BaseType
;
4673 if (ec
.ContainerType
.IsValueType
) {
4674 Report
.Error (522, loc
,
4675 "`{0}': Struct constructors cannot call base constructors", TypeManager
.CSharpSignature (caller_builder
));
4680 // It is legal to have "this" initializers that take no arguments
4681 // in structs, they are just no-ops.
4683 // struct D { public D (int a) : this () {}
4685 if (ec
.ContainerType
.IsValueType
&& argument_list
== null)
4688 t
= ec
.ContainerType
;
4691 base_constructor_group
= Expression
.MemberLookup (
4692 ec
.ContainerType
, t
, ".ctor", MemberTypes
.Constructor
,
4693 BindingFlags
.Public
| BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
,
4696 if (base_constructor_group
== null){
4698 base_constructor_group
= Expression
.MemberLookup (
4699 t
, null, t
, ".ctor", MemberTypes
.Constructor
,
4700 BindingFlags
.NonPublic
| BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
,
4704 int errors
= Report
.Errors
;
4705 if (base_constructor_group
!= null)
4706 base_constructor
= (ConstructorInfo
)
4707 ((MethodGroupExpr
) base_constructor_group
).OverloadResolve (
4711 if (base_constructor
== null) {
4712 if (errors
== Report
.Errors
)
4713 Invocation
.Error_WrongNumArguments (loc
, TypeManager
.CSharpSignature (caller_builder
),
4714 argument_list
== null ? 0 : argument_list
.Count
);
4719 Report
.SymbolRelatedToPreviousError (base_constructor
);
4720 Expression
.ErrorIsInaccesible (loc
, TypeManager
.CSharpSignature (base_constructor
));
4721 base_constructor
= null;
4725 if (base_constructor
== caller_builder
){
4726 Report
.Error (516, loc
, "Constructor `{0}' cannot call itself", TypeManager
.CSharpSignature (caller_builder
));
4733 public virtual void Emit (EmitContext ec
)
4735 if (base_constructor
!= null){
4736 ec
.Mark (loc
, false);
4738 Invocation
.EmitCall (ec
, true, true, null, base_constructor
, argument_list
, loc
);
4740 Invocation
.EmitCall (ec
, true, false, ec
.GetThis (loc
), base_constructor
, argument_list
, loc
);
4745 public class ConstructorBaseInitializer
: ConstructorInitializer
{
4746 public ConstructorBaseInitializer (ArrayList argument_list
, Location l
) :
4747 base (argument_list
, l
)
4752 class GeneratedBaseInitializer
: ConstructorBaseInitializer
{
4753 public GeneratedBaseInitializer (Location loc
):
4759 public class ConstructorThisInitializer
: ConstructorInitializer
{
4760 public ConstructorThisInitializer (ArrayList argument_list
, Location l
) :
4761 base (argument_list
, l
)
4766 public class Constructor
: MethodCore
, IMethodData
, IAnonymousHost
{
4767 public ConstructorBuilder ConstructorBuilder
;
4768 public ConstructorInitializer Initializer
;
4769 ListDictionary declarative_security
;
4770 ArrayList anonymous_methods
;
4773 // Modifiers allowed for a constructor.
4775 public const int AllowedModifiers
=
4777 Modifiers
.PROTECTED
|
4778 Modifiers
.INTERNAL
|
4784 static string[] attribute_targets
= new string [] { "method" }
;
4786 public Iterator Iterator
{
4787 get { return null; }
4790 bool has_compliant_args
= false;
4792 // The spec claims that static is not permitted, but
4793 // my very own code has static constructors.
4795 public Constructor (DeclSpace parent
, string name
, int mod
, Parameters args
,
4796 ConstructorInitializer init
, Location loc
)
4797 : base (parent
, null, null, mod
, AllowedModifiers
, false,
4798 new MemberName (name
, loc
), null, args
)
4803 public bool HasCompliantArgs
{
4804 get { return has_compliant_args; }
4807 public override AttributeTargets AttributeTargets
{
4808 get { return AttributeTargets.Constructor; }
4813 // Returns true if this is a default constructor
4815 public bool IsDefault ()
4817 if ((ModFlags
& Modifiers
.STATIC
) != 0)
4818 return Parameters
.Empty
;
4820 return Parameters
.Empty
&&
4821 (Initializer
is ConstructorBaseInitializer
) &&
4822 (Initializer
.Arguments
== null);
4825 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
4827 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
4828 if (declarative_security
== null) {
4829 declarative_security
= new ListDictionary ();
4831 a
.ExtractSecurityPermissionSet (declarative_security
);
4835 if (a
.IsInternalMethodImplAttribute
) {
4836 ConstructorBuilder
.SetImplementationFlags (MethodImplAttributes
.InternalCall
| MethodImplAttributes
.Runtime
);
4837 is_external_implementation
= true;
4840 ConstructorBuilder
.SetCustomAttribute (cb
);
4843 public void AddAnonymousMethod (AnonymousMethodExpression anonymous
)
4845 if (anonymous_methods
== null)
4846 anonymous_methods
= new ArrayList ();
4847 anonymous_methods
.Add (anonymous
);
4850 public bool ResolveMembers ()
4852 if (anonymous_methods
!= null) {
4853 foreach (AnonymousMethodExpression ame
in anonymous_methods
) {
4854 if (!ame
.CreateAnonymousHelpers ())
4862 protected override bool CheckForDuplications ()
4864 ArrayList ar
= Parent
.PartialContainer
.InstanceConstructors
;
4866 int arLen
= ar
.Count
;
4868 for (int i
= 0; i
< arLen
; i
++) {
4869 Constructor m
= (Constructor
) ar
[i
];
4870 if (IsDuplicateImplementation (m
))
4877 protected override bool CheckBase ()
4879 if ((ModFlags
& Modifiers
.STATIC
) != 0) {
4880 if (!Parameters
.Empty
) {
4881 Report
.Error (132, Location
, "`{0}': The static constructor must be parameterless",
4882 GetSignatureForError ());
4886 // the rest can be ignored
4890 // Check whether arguments were correct.
4891 if (!DefineParameters (Parameters
))
4894 if (!CheckForDuplications ())
4897 if (Parent
.PartialContainer
.Kind
== Kind
.Struct
) {
4898 if (ParameterTypes
.Length
== 0) {
4899 Report
.Error (568, Location
,
4900 "Structs cannot contain explicit parameterless constructors");
4904 if ((ModFlags
& Modifiers
.PROTECTED
) != 0) {
4905 Report
.Error (666, Location
, "`{0}': new protected member declared in struct", GetSignatureForError ());
4910 if ((RootContext
.WarningLevel
>= 4) && ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0 && (ModFlags
& Modifiers
.PROTECTED
) != 0)) {
4911 Report
.Warning (628, 4, Location
, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
4918 // Creates the ConstructorBuilder
4920 public override bool Define ()
4922 if (ConstructorBuilder
!= null)
4925 MethodAttributes ca
= (MethodAttributes
.RTSpecialName
|
4926 MethodAttributes
.SpecialName
);
4928 if ((ModFlags
& Modifiers
.STATIC
) != 0) {
4929 ca
|= MethodAttributes
.Static
| MethodAttributes
.Private
;
4931 ca
|= MethodAttributes
.HideBySig
;
4933 if ((ModFlags
& Modifiers
.PUBLIC
) != 0)
4934 ca
|= MethodAttributes
.Public
;
4935 else if ((ModFlags
& Modifiers
.PROTECTED
) != 0){
4936 if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
4937 ca
|= MethodAttributes
.FamORAssem
;
4939 ca
|= MethodAttributes
.Family
;
4940 } else if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
4941 ca
|= MethodAttributes
.Assembly
;
4943 ca
|= MethodAttributes
.Private
;
4946 if (!CheckAbstractAndExtern (block
!= null))
4949 // Check if arguments were correct.
4953 ConstructorBuilder
= Parent
.TypeBuilder
.DefineConstructor (
4954 ca
, CallingConventions
,
4957 if ((ModFlags
& Modifiers
.UNSAFE
) != 0)
4958 ConstructorBuilder
.InitLocals
= false;
4960 if (Parent
.PartialContainer
.IsComImport
) {
4961 if (!IsDefault ()) {
4962 Report
.Error (669, Location
, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
4963 Parent
.GetSignatureForError ());
4966 ConstructorBuilder
.SetImplementationFlags (MethodImplAttributes
.InternalCall
);
4969 TypeManager
.AddMethod (ConstructorBuilder
, this);
4977 public override void Emit ()
4979 if (OptAttributes
!= null)
4980 OptAttributes
.Emit ();
4982 EmitContext ec
= CreateEmitContext (null, null);
4984 if (block
!= null) {
4985 // If this is a non-static `struct' constructor and doesn't have any
4986 // initializer, it must initialize all of the struct's fields.
4987 if ((Parent
.PartialContainer
.Kind
== Kind
.Struct
) &&
4988 ((ModFlags
& Modifiers
.STATIC
) == 0) && (Initializer
== null))
4989 block
.AddThisVariable (Parent
, Location
);
4991 if (!block
.ResolveMeta (ec
, ParameterInfo
))
4995 if ((ModFlags
& Modifiers
.STATIC
) == 0){
4996 if (Parent
.PartialContainer
.Kind
== Kind
.Class
&& Initializer
== null)
4997 Initializer
= new GeneratedBaseInitializer (Location
);
5001 // Spec mandates that Initializers will not have
5005 if ((Initializer
!= null) &&
5006 !Initializer
.Resolve (ConstructorBuilder
, block
, ec
))
5008 ec
.IsStatic
= false;
5011 Parameters
.ApplyAttributes (ConstructorBuilder
);
5013 SourceMethod source
= SourceMethod
.Create (
5014 Parent
, ConstructorBuilder
, block
);
5017 // Classes can have base initializers and instance field initializers.
5019 if (Parent
.PartialContainer
.Kind
== Kind
.Class
){
5020 if ((ModFlags
& Modifiers
.STATIC
) == 0){
5023 // If we use a "this (...)" constructor initializer, then
5024 // do not emit field initializers, they are initialized in the other constructor
5026 if (!(Initializer
!= null && Initializer
is ConstructorThisInitializer
))
5027 Parent
.PartialContainer
.EmitFieldInitializers (ec
);
5031 bool unreachable
= false;
5032 if (block
!= null) {
5033 if (!ec
.ResolveTopBlock (null, block
, ParameterInfo
, this, out unreachable
))
5035 ec
.EmitMeta (block
);
5037 if (block
.ScopeInfo
!= null) {
5038 ExpressionStatement init
= block
.ScopeInfo
.GetScopeInitializer (ec
);
5039 init
.EmitStatement (ec
);
5043 if (Initializer
!= null) {
5044 Initializer
.Emit (ec
);
5047 if ((ModFlags
& Modifiers
.STATIC
) != 0)
5048 Parent
.PartialContainer
.EmitFieldInitializers (ec
);
5051 ec
.EmitResolvedTopBlock (block
, unreachable
);
5054 source
.CloseMethod ();
5058 if (declarative_security
!= null) {
5059 foreach (DictionaryEntry de
in declarative_security
) {
5060 ConstructorBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
5067 // Is never override
5068 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
5073 public override string GetSignatureForError()
5075 return base.GetSignatureForError () + Parameters
.GetSignatureForError ();
5078 public override string[] ValidAttributeTargets
{
5080 return attribute_targets
;
5084 protected override bool VerifyClsCompliance ()
5086 if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
5090 if (ParameterInfo
.Count
> 0) {
5091 ArrayList al
= (ArrayList
)Parent
.MemberCache
.Members
[".ctor"];
5093 MemberCache
.VerifyClsParameterConflict (al
, this, ConstructorBuilder
);
5095 if (Parent
.TypeBuilder
.IsSubclassOf (TypeManager
.attribute_type
)) {
5096 foreach (Type param
in ParameterTypes
) {
5097 if (param
.IsArray
) {
5103 has_compliant_args
= true;
5107 #region IMethodData Members
5109 public System
.Reflection
.CallingConventions CallingConventions
{
5111 CallingConventions cc
= Parameters
.CallingConvention
;
5113 if (Parent
.PartialContainer
.Kind
== Kind
.Class
)
5114 if ((ModFlags
& Modifiers
.STATIC
) == 0)
5115 cc
|= CallingConventions
.HasThis
;
5117 // FIXME: How is `ExplicitThis' used in C#?
5123 public new Location Location
{
5125 return base.Location
;
5129 public MemberName MethodName
{
5135 public Type ReturnType
{
5141 public EmitContext
CreateEmitContext (DeclSpace ds
, ILGenerator ig
)
5143 ILGenerator ig_
= ConstructorBuilder
.GetILGenerator ();
5144 return new EmitContext (this, Parent
, Location
, ig_
, null, ModFlags
, true);
5147 public bool IsExcluded()
5152 GenericMethod IMethodData
.GenericMethod
{
5162 /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
5164 public interface IMethodData
5166 CallingConventions CallingConventions { get; }
5167 Location Location { get; }
5168 MemberName MethodName { get; }
5169 Type ReturnType { get; }
5170 GenericMethod GenericMethod { get; }
5171 Parameters ParameterInfo { get; }
5173 Iterator Iterator { get; }
5175 Attributes OptAttributes { get; }
5176 ToplevelBlock Block { get; set; }
5178 EmitContext
CreateEmitContext (DeclSpace ds
, ILGenerator ig
);
5179 ObsoleteAttribute
GetObsoleteAttribute ();
5180 string GetSignatureForError ();
5182 bool IsClsComplianceRequired ();
5183 void SetMemberIsUsed ();
5187 // Encapsulates most of the Method's state
5189 public class MethodData
{
5191 readonly IMethodData method
;
5193 public readonly GenericMethod GenericMethod
;
5196 // Are we implementing an interface ?
5198 public MethodInfo implementing
;
5203 protected InterfaceMemberBase member
;
5204 protected int modifiers
;
5205 protected MethodAttributes flags
;
5206 protected Type declaring_type
;
5207 protected MethodInfo parent_method
;
5209 MethodBuilder builder
= null;
5210 public MethodBuilder MethodBuilder
{
5216 public Type DeclaringType
{
5218 return declaring_type
;
5222 public MethodData (InterfaceMemberBase member
,
5223 int modifiers
, MethodAttributes flags
, IMethodData method
)
5225 this.member
= member
;
5226 this.modifiers
= modifiers
;
5229 this.method
= method
;
5232 public MethodData (InterfaceMemberBase member
,
5233 int modifiers
, MethodAttributes flags
,
5234 IMethodData method
, MethodBuilder builder
,
5235 GenericMethod generic
, MethodInfo parent_method
)
5236 : this (member
, modifiers
, flags
, method
)
5238 this.builder
= builder
;
5239 this.GenericMethod
= generic
;
5240 this.parent_method
= parent_method
;
5243 public bool Define (DeclSpace parent
)
5245 string name
= method
.MethodName
.Basename
;
5246 string method_name
= method
.MethodName
.FullName
;
5248 TypeContainer container
= parent
.PartialContainer
;
5250 PendingImplementation pending
= container
.PendingImplementations
;
5251 if (pending
!= null){
5252 if (member
is Indexer
) // TODO: test it, but it should work without this IF
5253 implementing
= pending
.IsInterfaceIndexer (
5254 member
.InterfaceType
, method
.ReturnType
, method
.ParameterInfo
);
5256 implementing
= pending
.IsInterfaceMethod (
5257 member
.InterfaceType
, name
, method
.ReturnType
, method
.ParameterInfo
);
5259 if (member
.InterfaceType
!= null){
5260 if (implementing
== null){
5261 if (member
is PropertyBase
) {
5262 Report
.Error (550, method
.Location
, "`{0}' is an accessor not found in interface member `{1}{2}'",
5263 method
.GetSignatureForError (), TypeManager
.CSharpName (member
.InterfaceType
),
5264 member
.GetSignatureForError ().Substring (member
.GetSignatureForError ().LastIndexOf ('.')));
5267 Report
.Error (539, method
.Location
,
5268 "`{0}.{1}' in explicit interface declaration is not a member of interface",
5269 TypeManager
.CSharpName (member
.InterfaceType
), member
.ShortName
);
5273 if (implementing
.IsSpecialName
&& !(method
is AbstractPropertyEventMethod
)) {
5274 Report
.SymbolRelatedToPreviousError (implementing
);
5275 Report
.Error (683, method
.Location
, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
5276 member
.GetSignatureForError (), TypeManager
.CSharpSignature (implementing
));
5280 method_name
= member
.InterfaceType
.FullName
+
5283 if (implementing
!= null) {
5284 AbstractPropertyEventMethod prop_method
= method
as AbstractPropertyEventMethod
;
5285 if (prop_method
== null) {
5286 if (implementing
.IsSpecialName
) {
5287 Report
.SymbolRelatedToPreviousError (implementing
);
5288 Report
.Error (470, method
.Location
, "Method `{0}' cannot implement interface accessor `{1}.{2}'",
5289 method
.GetSignatureForError (), TypeManager
.CSharpSignature (implementing
),
5290 implementing
.Name
.StartsWith ("get_") ? "get" : "set");
5293 } else if (implementing
.DeclaringType
.IsInterface
) {
5294 if (!implementing
.IsSpecialName
) {
5295 Report
.SymbolRelatedToPreviousError (implementing
);
5296 Report
.Error (686, method
.Location
, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
5297 method
.GetSignatureForError (), TypeManager
.CSharpSignature (implementing
), container
.GetSignatureForError ());
5300 PropertyBase
.PropertyMethod pm
= prop_method
as PropertyBase
.PropertyMethod
;
5301 if (pm
!= null && pm
.HasCustomAccessModifier
&& (pm
.ModFlags
& Modifiers
.PUBLIC
) == 0) {
5302 Report
.SymbolRelatedToPreviousError (implementing
);
5303 Report
.Error (277, method
.Location
, "Accessor `{0}' must be declared public to implement interface member `{1}'",
5304 method
.GetSignatureForError (), TypeManager
.CSharpSignature (implementing
, true));
5313 // For implicit implementations, make sure we are public, for
5314 // explicit implementations, make sure we are private.
5316 if (implementing
!= null){
5318 // Setting null inside this block will trigger a more
5319 // verbose error reporting for missing interface implementations
5321 // The "candidate" function has been flagged already
5322 // but it wont get cleared
5324 if (member
.IsExplicitImpl
){
5325 if (method
.ParameterInfo
.HasParams
&& !TypeManager
.GetParameterData (implementing
).HasParams
) {
5326 Report
.SymbolRelatedToPreviousError (implementing
);
5327 Report
.Error (466, method
.Location
, "`{0}': the explicit interface implementation cannot introduce the params modifier",
5328 method
.GetSignatureForError ());
5332 if (implementing
.DeclaringType
.IsInterface
) {
5334 // If this is an interface method implementation,
5335 // check for public accessibility
5337 if ((flags
& MethodAttributes
.MemberAccessMask
) != MethodAttributes
.Public
)
5339 implementing
= null;
5341 } else if ((flags
& MethodAttributes
.MemberAccessMask
) == MethodAttributes
.Private
){
5342 // We may never be private.
5343 implementing
= null;
5345 } else if ((modifiers
& Modifiers
.OVERRIDE
) == 0){
5347 // We may be protected if we're overriding something.
5349 implementing
= null;
5354 // Static is not allowed
5356 if ((modifiers
& Modifiers
.STATIC
) != 0){
5357 implementing
= null;
5362 // If implementing is still valid, set flags
5364 if (implementing
!= null){
5366 // When implementing interface methods, set NewSlot
5367 // unless, we are overwriting a method.
5369 if (implementing
.DeclaringType
.IsInterface
){
5370 if ((modifiers
& Modifiers
.OVERRIDE
) == 0)
5371 flags
|= MethodAttributes
.NewSlot
;
5374 MethodAttributes
.Virtual
|
5375 MethodAttributes
.HideBySig
;
5377 // Set Final unless we're virtual, abstract or already overriding a method.
5378 if ((modifiers
& (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
| Modifiers
.OVERRIDE
)) == 0)
5379 flags
|= MethodAttributes
.Final
;
5382 EmitContext ec
= method
.CreateEmitContext (container
, null);
5384 DefineMethodBuilder (container
, method_name
, method
.ParameterInfo
.Types
);
5386 if (builder
== null)
5389 if (container
.CurrentType
!= null)
5390 declaring_type
= container
.CurrentType
;
5392 declaring_type
= container
.TypeBuilder
;
5394 if ((modifiers
& Modifiers
.UNSAFE
) != 0)
5395 builder
.InitLocals
= false;
5398 if (implementing
!= null){
5400 // clear the pending implemntation flag
5402 if (member
is Indexer
) {
5403 pending
.ImplementIndexer (
5404 member
.InterfaceType
, builder
, method
.ReturnType
,
5405 method
.ParameterInfo
, member
.IsExplicitImpl
);
5407 pending
.ImplementMethod (
5408 member
.InterfaceType
, name
, method
.ReturnType
,
5409 method
.ParameterInfo
, member
.IsExplicitImpl
);
5411 if (member
.IsExplicitImpl
)
5412 container
.TypeBuilder
.DefineMethodOverride (
5413 builder
, implementing
);
5416 TypeManager
.AddMethod (builder
, method
);
5418 if (GenericMethod
!= null) {
5419 bool is_override
= member
.IsExplicitImpl
|
5420 ((modifiers
& Modifiers
.OVERRIDE
) != 0);
5422 if (implementing
!= null)
5423 parent_method
= implementing
;
5425 if (!GenericMethod
.DefineType (ec
, builder
, parent_method
, is_override
))
5434 /// Create the MethodBuilder for the method
5436 void DefineMethodBuilder (TypeContainer container
, string method_name
, Type
[] ParameterTypes
)
5438 if (builder
== null) {
5439 builder
= container
.TypeBuilder
.DefineMethod (
5440 method_name
, flags
, method
.CallingConventions
,
5441 method
.ReturnType
, ParameterTypes
);
5445 #if GMCS_SOURCE && !MS_COMPATIBLE
5446 builder
.SetGenericMethodSignature (
5447 flags
, method
.CallingConventions
,
5448 method
.ReturnType
, ParameterTypes
);
5455 public void Emit (DeclSpace parent
)
5457 ToplevelBlock block
= method
.Block
;
5461 ec
= method
.CreateEmitContext (parent
, builder
.GetILGenerator ());
5463 ec
= method
.CreateEmitContext (parent
, null);
5465 method
.ParameterInfo
.ApplyAttributes (MethodBuilder
);
5467 if (GenericMethod
!= null)
5468 GenericMethod
.EmitAttributes ();
5470 SourceMethod source
= SourceMethod
.Create (parent
, MethodBuilder
, method
.Block
);
5473 // Handle destructors specially
5475 // FIXME: This code generates buggy code
5477 if (member
is Destructor
)
5478 EmitDestructor (ec
, block
);
5480 ec
.EmitTopBlock (method
, block
);
5483 source
.CloseMethod ();
5486 void EmitDestructor (EmitContext ec
, ToplevelBlock block
)
5488 ILGenerator ig
= ec
.ig
;
5490 Label finish
= ig
.DefineLabel ();
5492 block
.SetDestructor ();
5494 ig
.BeginExceptionBlock ();
5495 ec
.ReturnLabel
= finish
;
5496 ec
.HasReturnLabel
= true;
5497 ec
.EmitTopBlock (method
, block
);
5499 // ig.MarkLabel (finish);
5500 ig
.BeginFinallyBlock ();
5502 if (ec
.ContainerType
.BaseType
!= null) {
5503 Expression member_lookup
= Expression
.MemberLookup (
5504 ec
.ContainerType
.BaseType
, null, ec
.ContainerType
.BaseType
,
5505 "Finalize", MemberTypes
.Method
, Expression
.AllBindingFlags
, method
.Location
);
5507 if (member_lookup
!= null){
5508 MethodGroupExpr base_destructor
= ((MethodGroupExpr
) member_lookup
);
5510 ig
.Emit (OpCodes
.Ldarg_0
);
5511 ig
.Emit (OpCodes
.Call
, (MethodInfo
) base_destructor
.Methods
[0]);
5515 ig
.EndExceptionBlock ();
5516 //ig.MarkLabel (ec.ReturnLabel);
5517 ig
.Emit (OpCodes
.Ret
);
5521 // TODO: Should derive from MethodCore
5522 public class Destructor
: Method
{
5524 static string[] attribute_targets
= new string [] { "method" }
;
5526 public Destructor (DeclSpace parent
, Expression return_type
, int mod
,
5527 string name
, Parameters parameters
, Attributes attrs
,
5529 : base (parent
, null, return_type
, mod
, false, new MemberName (name
, l
),
5533 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
5535 if (a
.Type
== TypeManager
.conditional_attribute_type
) {
5536 Error_ConditionalAttributeIsNotValid ();
5540 base.ApplyAttributeBuilder (a
, cb
);
5543 public override string GetSignatureForError ()
5545 return Parent
.GetSignatureForError () + ".~" + Parent
.MemberName
.Name
+ "()";
5548 public override string[] ValidAttributeTargets
{
5550 return attribute_targets
;
5555 abstract public class MemberBase
: MemberCore
{
5556 public Expression Type
;
5557 public readonly DeclSpace ds
;
5558 public readonly GenericMethod GenericMethod
;
5561 // The type of this property / indexer / event
5563 protected Type member_type
;
5564 public Type MemberType
{
5566 if (member_type
== null && Type
!= null) {
5567 IResolveContext rc
= GenericMethod
== null ? this : (IResolveContext
)ds
;
5568 Type
= Type
.ResolveAsTypeTerminal (rc
, false);
5570 member_type
= Type
.Type
;
5578 // The constructor is only exposed to our children
5580 protected MemberBase (DeclSpace parent
, GenericMethod generic
,
5581 Expression type
, int mod
, int allowed_mod
, int def_mod
,
5582 MemberName name
, Attributes attrs
)
5583 : base (parent
, name
, attrs
)
5585 this.ds
= generic
!= null ? generic
: (DeclSpace
) parent
;
5587 ModFlags
= Modifiers
.Check (allowed_mod
, mod
, def_mod
, Location
);
5588 GenericMethod
= generic
;
5589 if (GenericMethod
!= null)
5590 GenericMethod
.ModFlags
= ModFlags
;
5593 protected virtual bool CheckBase ()
5595 if ((ModFlags
& Modifiers
.PROTECTED
) != 0 && Parent
.PartialContainer
.Kind
== Kind
.Struct
) {
5596 Report
.Error (666, Location
, "`{0}': new protected member declared in struct", GetSignatureForError ());
5600 if ((RootContext
.WarningLevel
>= 4) &&
5601 ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0) &&
5602 ((ModFlags
& Modifiers
.PROTECTED
) != 0) &&
5603 ((ModFlags
& Modifiers
.OVERRIDE
) == 0) && (Name
!= "Finalize")) {
5604 Report
.Warning (628, 4, Location
, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
5609 protected virtual bool DoDefine ()
5611 if (MemberType
== null)
5614 if ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0 &&
5615 (ModFlags
& (Modifiers
.VIRTUAL
|Modifiers
.ABSTRACT
)) != 0) {
5616 Report
.Error (549, Location
, "New virtual member `{0}' is declared in a sealed class `{1}'",
5617 GetSignatureForError (), Parent
.GetSignatureForError ());
5621 // verify accessibility
5622 if (!Parent
.AsAccessible (MemberType
, ModFlags
)) {
5623 Report
.SymbolRelatedToPreviousError (MemberType
);
5624 if (this is Property
)
5625 Report
.Error (53, Location
,
5626 "Inconsistent accessibility: property type `" +
5627 TypeManager
.CSharpName (MemberType
) + "' is less " +
5628 "accessible than property `" + GetSignatureForError () + "'");
5629 else if (this is Indexer
)
5630 Report
.Error (54, Location
,
5631 "Inconsistent accessibility: indexer return type `" +
5632 TypeManager
.CSharpName (MemberType
) + "' is less " +
5633 "accessible than indexer `" + GetSignatureForError () + "'");
5634 else if (this is MethodCore
) {
5635 if (this is Operator
)
5636 Report
.Error (56, Location
,
5637 "Inconsistent accessibility: return type `" +
5638 TypeManager
.CSharpName (MemberType
) + "' is less " +
5639 "accessible than operator `" + GetSignatureForError () + "'");
5641 Report
.Error (50, Location
,
5642 "Inconsistent accessibility: return type `" +
5643 TypeManager
.CSharpName (MemberType
) + "' is less " +
5644 "accessible than method `" + GetSignatureForError () + "'");
5646 Report
.Error (52, Location
,
5647 "Inconsistent accessibility: field type `" +
5648 TypeManager
.CSharpName (MemberType
) + "' is less " +
5649 "accessible than field `" + GetSignatureForError () + "'");
5657 protected bool IsTypePermitted ()
5659 if (MemberType
== TypeManager
.arg_iterator_type
|| MemberType
== TypeManager
.typed_reference_type
) {
5660 Report
.Error (610, Location
, "Field or property cannot be of type `{0}'", TypeManager
.CSharpName (MemberType
));
5668 // Abstract class for all fields
5670 abstract public class FieldBase
: MemberBase
{
5671 public FieldBuilder FieldBuilder
;
5672 public Status status
;
5673 protected Expression initializer
;
5676 public enum Status
: byte {
5677 HAS_OFFSET
= 4 // Used by FieldMember.
5680 static readonly string[] attribute_targets
= new string [] { "field" }
;
5682 protected FieldBase (DeclSpace parent
, Expression type
, int mod
,
5683 int allowed_mod
, MemberName name
, Attributes attrs
)
5684 : base (parent
, null, type
, mod
, allowed_mod
| Modifiers
.ABSTRACT
, Modifiers
.PRIVATE
,
5687 if ((mod
& Modifiers
.ABSTRACT
) != 0)
5688 Report
.Error (681, Location
, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5691 public override AttributeTargets AttributeTargets
{
5693 return AttributeTargets
.Field
;
5697 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
5699 if (a
.Type
== TypeManager
.field_offset_attribute_type
) {
5700 status
|= Status
.HAS_OFFSET
;
5702 if (!Parent
.PartialContainer
.HasExplicitLayout
) {
5703 Report
.Error (636, Location
, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5707 if ((ModFlags
& Modifiers
.STATIC
) != 0 || this is Const
) {
5708 Report
.Error (637, Location
, "The FieldOffset attribute is not allowed on static or const fields");
5714 if (a
.Type
== TypeManager
.fixed_buffer_attr_type
) {
5715 Report
.Error (1716, Location
, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5720 if (a
.Type
== TypeManager
.marshal_as_attr_type
) {
5721 UnmanagedMarshal marshal
= a
.GetMarshal (this);
5722 if (marshal
!= null) {
5723 FieldBuilder
.SetMarshal (marshal
);
5728 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
)) {
5729 a
.Error_InvalidSecurityParent ();
5733 FieldBuilder
.SetCustomAttribute (cb
);
5736 protected override bool CheckBase ()
5738 if (!base.CheckBase ())
5741 MemberInfo conflict_symbol
= Parent
.PartialContainer
.FindBaseMemberWithSameName (Name
, false);
5742 if (conflict_symbol
== null) {
5743 if ((ModFlags
& Modifiers
.NEW
) != 0) {
5744 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5749 if ((ModFlags
& (Modifiers
.NEW
| Modifiers
.OVERRIDE
)) == 0) {
5750 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
5751 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5752 GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
5758 public override bool Define()
5760 if (MemberType
== null || Type
== null)
5763 if (TypeManager
.IsGenericParameter (MemberType
))
5766 if (MemberType
== TypeManager
.void_type
) {
5767 // TODO: wrong location
5768 Expression
.Error_VoidInvalidInTheContext (Location
);
5772 if (MemberType
.IsSealed
&& MemberType
.IsAbstract
) {
5773 Error_VariableOfStaticClass (Location
, GetSignatureForError (), MemberType
);
5780 if (!Parent
.AsAccessible (MemberType
, ModFlags
)) {
5781 Report
.Error (52, Location
,
5782 "Inconsistent accessibility: field type `" +
5783 TypeManager
.CSharpName (MemberType
) + "' is less " +
5784 "accessible than field `" + GetSignatureForError () + "'");
5788 if (!IsTypePermitted ())
5795 // Represents header string for documentation comment.
5797 public override string DocCommentHeader
{
5798 get { return "F:"; }
5801 public override void Emit ()
5803 if (OptAttributes
!= null) {
5804 OptAttributes
.Emit ();
5807 if (((status
& Status
.HAS_OFFSET
) == 0) && (ModFlags
& Modifiers
.STATIC
) == 0 && Parent
.PartialContainer
.HasExplicitLayout
) {
5808 Report
.Error (625, Location
, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5814 public static void Error_VariableOfStaticClass (Location loc
, string variableName
, Type staticClass
)
5816 Report
.SymbolRelatedToPreviousError (staticClass
);
5817 Report
.Error (723, loc
, "`{0}': cannot declare variables of static types",
5821 public Expression Initializer
{
5823 if (value != null) {
5824 this.initializer
= value;
5829 protected virtual bool IsFieldClsCompliant
{
5831 if (FieldBuilder
== null)
5834 return AttributeTester
.IsClsCompliant (FieldBuilder
.FieldType
);
5838 public override string[] ValidAttributeTargets
5841 return attribute_targets
;
5845 protected override bool VerifyClsCompliance ()
5847 if (!base.VerifyClsCompliance ())
5850 if (!IsFieldClsCompliant
) {
5851 Report
.Error (3003, Location
, "Type of `{0}' is not CLS-compliant", GetSignatureForError ());
5856 public void SetAssigned ()
5858 caching_flags
|= Flags
.IsAssigned
;
5862 interface IFixedBuffer
5864 FieldInfo Element { get; }
5865 Type ElementType { get; }
5868 public class FixedFieldExternal
: IFixedBuffer
5870 FieldInfo element_field
;
5872 public FixedFieldExternal (FieldInfo fi
)
5874 element_field
= fi
.FieldType
.GetField (FixedField
.FixedElementName
);
5877 #region IFixedField Members
5879 public FieldInfo Element
{
5881 return element_field
;
5885 public Type ElementType
{
5887 return element_field
.FieldType
;
5895 /// Fixed buffer implementation
5897 public class FixedField
: FieldBase
, IFixedBuffer
5899 public const string FixedElementName
= "FixedElementField";
5900 static int GlobalCounter
= 0;
5901 static object[] ctor_args
= new object[] { (short)LayoutKind.Sequential }
;
5902 static FieldInfo
[] fi
;
5904 TypeBuilder fixed_buffer_type
;
5905 FieldBuilder element
;
5906 Expression size_expr
;
5909 const int AllowedModifiers
=
5912 Modifiers
.PROTECTED
|
5913 Modifiers
.INTERNAL
|
5916 public FixedField (DeclSpace parent
, Expression type
, int mod
, string name
,
5917 Expression size_expr
, Attributes attrs
, Location loc
):
5918 base (parent
, type
, mod
, AllowedModifiers
, new MemberName (name
, loc
), attrs
)
5920 if (RootContext
.Version
== LanguageVersion
.ISO_1
)
5921 Report
.FeatureIsNotISO1 (loc
, "fixed size buffers");
5923 this.size_expr
= size_expr
;
5926 public override bool Define()
5929 if ((ModFlags
& (Modifiers
.PUBLIC
| Modifiers
.PROTECTED
)) != 0)
5930 Report
.Warning (-23, 1, Location
, "Only private or internal fixed sized buffers are supported by .NET 1.x");
5933 if (Parent
.PartialContainer
.Kind
!= Kind
.Struct
) {
5934 Report
.Error (1642, Location
, "`{0}': Fixed size buffer fields may only be members of structs",
5935 GetSignatureForError ());
5939 if (!base.Define ())
5942 if (!TypeManager
.IsPrimitiveType (MemberType
)) {
5943 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",
5944 GetSignatureForError ());
5948 EmitContext ec
= new EmitContext (this, Parent
, Location
, null, null, ModFlags
);
5949 Constant c
= size_expr
.ResolveAsConstant (ec
, this);
5953 IntConstant buffer_size_const
= c
.ImplicitConversionRequired (TypeManager
.int32_type
, Location
) as IntConstant
;
5954 if (buffer_size_const
== null)
5957 buffer_size
= buffer_size_const
.Value
;
5959 if (buffer_size
<= 0) {
5960 Report
.Error (1665, Location
, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5964 int type_size
= Expression
.GetTypeSize (MemberType
);
5966 if (buffer_size
> int.MaxValue
/ type_size
) {
5967 Report
.Error (1664, Location
, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5968 GetSignatureForError (), buffer_size
.ToString (), TypeManager
.CSharpName (MemberType
));
5972 buffer_size
*= type_size
;
5975 string name
= String
.Format ("<{0}>__FixedBuffer{1}", Name
, GlobalCounter
++);
5977 fixed_buffer_type
= Parent
.TypeBuilder
.DefineNestedType (name
,
5978 TypeAttributes
.NestedPublic
| TypeAttributes
.Sealed
| TypeAttributes
.BeforeFieldInit
, TypeManager
.value_type
);
5979 element
= fixed_buffer_type
.DefineField (FixedElementName
, MemberType
, FieldAttributes
.Public
);
5980 RootContext
.RegisterCompilerGeneratedType (fixed_buffer_type
);
5982 FieldBuilder
= Parent
.TypeBuilder
.DefineField (Name
, fixed_buffer_type
, Modifiers
.FieldAttr (ModFlags
));
5983 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
5988 public override void Emit()
5991 fi
= new FieldInfo
[] { TypeManager.struct_layout_attribute_type.GetField ("Size") }
;
5993 object[] fi_val
= new object[1];
5994 fi_val
[0] = buffer_size
;
5996 CustomAttributeBuilder cab
= new CustomAttributeBuilder (TypeManager
.struct_layout_attribute_ctor
,
5997 ctor_args
, fi
, fi_val
);
5998 fixed_buffer_type
.SetCustomAttribute (cab
);
6001 cab
= new CustomAttributeBuilder (TypeManager
.fixed_buffer_attr_ctor
, new object[] { MemberType, buffer_size }
);
6002 FieldBuilder
.SetCustomAttribute (cab
);
6007 protected override bool IsFieldClsCompliant
{
6013 #region IFixedField Members
6015 public FieldInfo Element
{
6021 public Type ElementType
{
6031 // The Field class is used to represents class/struct fields during parsing.
6033 public class Field
: FieldBase
{
6035 // Modifiers allowed in a class declaration
6037 const int AllowedModifiers
=
6040 Modifiers
.PROTECTED
|
6041 Modifiers
.INTERNAL
|
6044 Modifiers
.VOLATILE
|
6048 public Field (DeclSpace parent
, Expression type
, int mod
, string name
,
6049 Attributes attrs
, Location loc
)
6050 : base (parent
, type
, mod
, AllowedModifiers
, new MemberName (name
, loc
),
6055 public override bool Define ()
6057 if (!base.Define ())
6060 if (RootContext
.WarningLevel
> 1){
6061 Type ptype
= Parent
.TypeBuilder
.BaseType
;
6063 // ptype is only null for System.Object while compiling corlib.
6065 TypeContainer
.FindMembers (
6066 ptype
, MemberTypes
.Method
,
6067 BindingFlags
.Public
|
6068 BindingFlags
.Static
| BindingFlags
.Instance
,
6069 System
.Type
.FilterName
, Name
);
6073 if ((ModFlags
& Modifiers
.VOLATILE
) != 0){
6074 if (!MemberType
.IsClass
){
6075 Type vt
= MemberType
;
6077 if (TypeManager
.IsEnumType (vt
))
6078 vt
= TypeManager
.EnumToUnderlying (MemberType
);
6080 if (!((vt
== TypeManager
.bool_type
) ||
6081 (vt
== TypeManager
.sbyte_type
) ||
6082 (vt
== TypeManager
.byte_type
) ||
6083 (vt
== TypeManager
.short_type
) ||
6084 (vt
== TypeManager
.ushort_type
) ||
6085 (vt
== TypeManager
.int32_type
) ||
6086 (vt
== TypeManager
.uint32_type
) ||
6087 (vt
== TypeManager
.char_type
) ||
6088 (vt
== TypeManager
.float_type
) ||
6089 (!vt
.IsValueType
))){
6090 Report
.Error (677, Location
, "`{0}': A volatile field cannot be of the type `{1}'",
6091 GetSignatureForError (), TypeManager
.CSharpName (vt
));
6096 if ((ModFlags
& Modifiers
.READONLY
) != 0){
6097 Report
.Error (678, Location
, "`{0}': A field cannot be both volatile and readonly",
6098 GetSignatureForError ());
6103 FieldAttributes fa
= Modifiers
.FieldAttr (ModFlags
);
6105 if (Parent
.PartialContainer
.Kind
== Kind
.Struct
&&
6106 ((fa
& FieldAttributes
.Static
) == 0) &&
6107 MemberType
== Parent
.TypeBuilder
&&
6108 !TypeManager
.IsBuiltinType (MemberType
)){
6109 Report
.Error (523, Location
, "Struct member `" + Parent
.Name
+ "." + Name
+
6110 "' causes a cycle in the structure layout");
6115 FieldBuilder
= Parent
.TypeBuilder
.DefineField (
6116 Name
, MemberType
, Modifiers
.FieldAttr (ModFlags
));
6118 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
6120 catch (ArgumentException
) {
6121 Report
.Warning (-24, 1, Location
, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
6125 if (initializer
!= null)
6126 Parent
.PartialContainer
.RegisterFieldForInitialization (this,
6127 new FieldInitializer (FieldBuilder
, initializer
, Parent
));
6132 protected override bool VerifyClsCompliance ()
6134 if (!base.VerifyClsCompliance ())
6137 if ((ModFlags
& Modifiers
.VOLATILE
) != 0) {
6138 Report
.Warning (3026, 1, Location
, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
6146 // `set' and `get' accessors are represented with an Accessor.
6148 public class Accessor
: IAnonymousHost
{
6150 // Null if the accessor is empty, or a Block if not
6152 public const int AllowedModifiers
=
6154 Modifiers
.PROTECTED
|
6155 Modifiers
.INTERNAL
|
6158 public ToplevelBlock Block
;
6159 public Attributes Attributes
;
6160 public Location Location
;
6161 public int ModFlags
;
6163 public ArrayList AnonymousMethods
;
6165 public Accessor (ToplevelBlock b
, int mod
, Attributes attrs
, Location loc
)
6170 ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, 0, loc
);
6173 public void SetYields ()
6178 public void AddAnonymousMethod (AnonymousMethodExpression ame
)
6180 if (AnonymousMethods
== null)
6181 AnonymousMethods
= new ArrayList ();
6182 AnonymousMethods
.Add (ame
);
6186 // Ooouh Martin, templates are missing here.
6187 // When it will be possible move here a lot of child code and template method type.
6188 public abstract class AbstractPropertyEventMethod
: MemberCore
, IMethodData
{
6189 protected MethodData method_data
;
6190 protected ToplevelBlock block
;
6191 protected ListDictionary declarative_security
;
6193 // The accessor are created event if they are not wanted.
6194 // But we need them because their names are reserved.
6195 // Field says whether accessor will be emited or not
6196 public readonly bool IsDummy
;
6198 protected readonly string prefix
;
6200 ReturnParameter return_attributes
;
6202 public AbstractPropertyEventMethod (PropertyBasedMember member
, string prefix
)
6203 : base (member
.Parent
, SetupName (prefix
, member
, member
.Location
), null)
6205 this.prefix
= prefix
;
6209 public AbstractPropertyEventMethod (InterfaceMemberBase member
, Accessor accessor
,
6211 : base (member
.Parent
, SetupName (prefix
, member
, accessor
.Location
),
6212 accessor
.Attributes
)
6214 this.prefix
= prefix
;
6215 this.block
= accessor
.Block
;
6218 static MemberName
SetupName (string prefix
, InterfaceMemberBase member
, Location loc
)
6220 return new MemberName (member
.MemberName
.Left
, prefix
+ member
.ShortName
, loc
);
6223 public void UpdateName (InterfaceMemberBase member
)
6225 SetMemberName (SetupName (prefix
, member
, Location
));
6228 #region IMethodData Members
6230 public abstract Iterator Iterator
{
6234 public ToplevelBlock Block
{
6244 public CallingConventions CallingConventions
{
6246 return CallingConventions
.Standard
;
6250 public bool IsExcluded ()
6255 GenericMethod IMethodData
.GenericMethod
{
6261 public MemberName MethodName
{
6267 public Type
[] ParameterTypes
{
6269 return ParameterInfo
.Types
;
6273 public abstract Parameters ParameterInfo { get ; }
6274 public abstract Type ReturnType { get; }
6275 public abstract EmitContext
CreateEmitContext (DeclSpace ds
, ILGenerator ig
);
6279 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
6281 if (a
.Type
== TypeManager
.cls_compliant_attribute_type
|| a
.Type
== TypeManager
.obsolete_attribute_type
||
6282 a
.Type
== TypeManager
.conditional_attribute_type
) {
6283 Report
.Error (1667, a
.Location
,
6284 "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
6285 TypeManager
.CSharpName (a
.Type
), a
.GetValidTargets ());
6289 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
6290 if (declarative_security
== null)
6291 declarative_security
= new ListDictionary ();
6292 a
.ExtractSecurityPermissionSet (declarative_security
);
6296 if (a
.Target
== AttributeTargets
.Method
) {
6297 method_data
.MethodBuilder
.SetCustomAttribute (cb
);
6301 if (a
.Target
== AttributeTargets
.ReturnValue
) {
6302 if (return_attributes
== null)
6303 return_attributes
= new ReturnParameter (method_data
.MethodBuilder
, Location
);
6305 return_attributes
.ApplyAttributeBuilder (a
, cb
);
6309 ApplyToExtraTarget (a
, cb
);
6312 virtual protected void ApplyToExtraTarget (Attribute a
, CustomAttributeBuilder cb
)
6314 System
.Diagnostics
.Debug
.Fail ("You forgot to define special attribute target handling");
6317 // It is not supported for the accessors
6318 public sealed override bool Define()
6320 throw new NotSupportedException ();
6323 public void Emit (DeclSpace parent
)
6325 EmitMethod (parent
);
6327 if (OptAttributes
!= null)
6328 OptAttributes
.Emit ();
6330 if (declarative_security
!= null) {
6331 foreach (DictionaryEntry de
in declarative_security
) {
6332 method_data
.MethodBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
6339 protected virtual void EmitMethod (DeclSpace parent
)
6341 method_data
.Emit (parent
);
6344 public override bool IsClsComplianceRequired()
6349 public bool IsDuplicateImplementation (MethodCore method
)
6351 if (!MemberName
.Equals (method
.MemberName
))
6354 Type
[] param_types
= method
.ParameterTypes
;
6356 if (param_types
.Length
!= ParameterTypes
.Length
)
6359 for (int i
= 0; i
< param_types
.Length
; i
++)
6360 if (param_types
[i
] != ParameterTypes
[i
])
6363 Report
.SymbolRelatedToPreviousError (method
);
6364 Report
.Error (111, Location
, TypeContainer
.Error111
, method
.GetSignatureForError ());
6368 public override bool IsUsed
6378 public new Location Location
{
6380 return base.Location
;
6384 public virtual bool ResolveMembers ()
6390 // Represents header string for documentation comment.
6392 public override string DocCommentHeader
{
6393 get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6399 // Properties and Indexers both generate PropertyBuilders, we use this to share
6400 // their common bits.
6402 abstract public class PropertyBase
: PropertyBasedMember
{
6404 public class GetMethod
: PropertyMethod
6406 static string[] attribute_targets
= new string [] { "method", "return" }
;
6408 public GetMethod (PropertyBase method
):
6409 base (method
, "get_")
6413 public GetMethod (PropertyBase method
, Accessor accessor
):
6414 base (method
, accessor
, "get_")
6418 public override MethodBuilder
Define (DeclSpace parent
)
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
)
6498 base.Define (parent
);
6500 method_data
= new MethodData (method
, ModFlags
, flags
, this);
6502 if (!method_data
.Define (parent
))
6505 return method_data
.MethodBuilder
;
6508 public override Type ReturnType
{
6510 return TypeManager
.void_type
;
6514 public override string[] ValidAttributeTargets
{
6516 return attribute_targets
;
6521 static string[] attribute_targets
= new string [] { "property" }
;
6523 public abstract class PropertyMethod
: AbstractPropertyEventMethod
6525 protected readonly PropertyBase method
;
6526 protected MethodAttributes flags
;
6528 ArrayList anonymous_methods
;
6531 public PropertyMethod (PropertyBase method
, string prefix
)
6532 : base (method
, prefix
)
6534 this.method
= method
;
6537 public PropertyMethod (PropertyBase method
, Accessor accessor
,
6539 : base (method
, accessor
, prefix
)
6541 this.method
= method
;
6542 this.ModFlags
= accessor
.ModFlags
;
6543 yields
= accessor
.Yields
;
6544 anonymous_methods
= accessor
.AnonymousMethods
;
6546 if (accessor
.ModFlags
!= 0 && RootContext
.Version
== LanguageVersion
.ISO_1
) {
6547 Report
.FeatureIsNotISO1 (Location
, "access modifiers on properties");
6551 public override Iterator Iterator
{
6552 get { return iterator; }
6555 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
6557 if (a
.IsInternalMethodImplAttribute
) {
6558 method_data
.MethodBuilder
.SetImplementationFlags (MethodImplAttributes
.InternalCall
| MethodImplAttributes
.Runtime
);
6559 method
.is_external_implementation
= true;
6562 base.ApplyAttributeBuilder (a
, cb
);
6565 public override AttributeTargets AttributeTargets
{
6567 return AttributeTargets
.Method
;
6571 public override bool IsClsComplianceRequired ()
6573 return method
.IsClsComplianceRequired ();
6576 public override bool ResolveMembers ()
6579 iterator
= Iterator
.CreateIterator (this, Parent
, null, ModFlags
);
6580 if (iterator
== null)
6584 if (anonymous_methods
!= null) {
6585 foreach (AnonymousMethodExpression ame
in anonymous_methods
) {
6586 if (!ame
.CreateAnonymousHelpers ())
6594 public virtual MethodBuilder
Define (DeclSpace parent
)
6596 if (!method
.CheckAbstractAndExtern (block
!= null))
6599 TypeContainer container
= parent
.PartialContainer
;
6602 // Check for custom access modifier
6604 if (ModFlags
== 0) {
6605 ModFlags
= method
.ModFlags
;
6606 flags
= method
.flags
;
6608 if (container
.Kind
== Kind
.Interface
)
6609 Report
.Error (275, Location
, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6610 GetSignatureForError ());
6612 if ((method
.ModFlags
& Modifiers
.ABSTRACT
) != 0 && (ModFlags
& Modifiers
.PRIVATE
) != 0) {
6613 Report
.Error (442, Location
, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6616 CheckModifiers (ModFlags
);
6617 ModFlags
|= (method
.ModFlags
& (~Modifiers
.Accessibility
));
6618 ModFlags
|= Modifiers
.PROPERTY_CUSTOM
;
6619 flags
= Modifiers
.MethodAttr (ModFlags
);
6620 flags
|= (method
.flags
& (~MethodAttributes
.MemberAccessMask
));
6626 public bool HasCustomAccessModifier
6629 return (ModFlags
& Modifiers
.PROPERTY_CUSTOM
) != 0;
6633 public override EmitContext
CreateEmitContext (DeclSpace ds
, ILGenerator ig
)
6635 return new EmitContext (method
,
6636 ds
, method
.ds
, method
.Location
, ig
, ReturnType
,
6637 method
.ModFlags
, false);
6640 public override ObsoleteAttribute
GetObsoleteAttribute ()
6642 return method
.GetObsoleteAttribute ();
6645 public override string GetSignatureForError()
6647 return method
.GetSignatureForError () + '.' + prefix
.Substring (0, 3);
6650 void CheckModifiers (int modflags
)
6653 int mflags
= method
.ModFlags
& Modifiers
.Accessibility
;
6655 if ((mflags
& Modifiers
.PUBLIC
) != 0) {
6656 flags
|= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
| Modifiers
.PRIVATE
;
6658 else if ((mflags
& Modifiers
.PROTECTED
) != 0) {
6659 if ((mflags
& Modifiers
.INTERNAL
) != 0)
6660 flags
|= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
;
6662 flags
|= Modifiers
.PRIVATE
;
6664 else if ((mflags
& Modifiers
.INTERNAL
) != 0)
6665 flags
|= Modifiers
.PRIVATE
;
6667 if ((mflags
== modflags
) || (modflags
& (~flags
)) != 0) {
6668 Report
.Error (273, Location
,
6669 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6670 GetSignatureForError (), method
.GetSignatureForError ());
6674 public override bool MarkForDuplicationCheck ()
6676 caching_flags
|= Flags
.TestMethodDuplication
;
6681 public PropertyMethod Get
, Set
;
6682 public PropertyBuilder PropertyBuilder
;
6683 public MethodBuilder GetBuilder
, SetBuilder
;
6685 protected bool define_set_first
= false;
6687 public PropertyBase (DeclSpace parent
, Expression type
, int mod_flags
,
6688 int allowed_mod
, bool is_iface
, MemberName name
,
6689 Attributes attrs
, bool define_set_first
)
6690 : base (parent
, null, type
, mod_flags
, allowed_mod
, is_iface
, name
, attrs
)
6692 this.define_set_first
= define_set_first
;
6695 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
6697 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
)) {
6698 a
.Error_InvalidSecurityParent ();
6702 PropertyBuilder
.SetCustomAttribute (cb
);
6705 public override AttributeTargets AttributeTargets
{
6707 return AttributeTargets
.Property
;
6711 public override bool Define ()
6716 if (!IsTypePermitted ())
6722 protected override bool DoDefine ()
6724 if (!base.DoDefine ())
6728 // Accessors modifiers check
6730 if (Get
.ModFlags
!= 0 && Set
.ModFlags
!= 0) {
6731 Report
.Error (274, Location
, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6732 GetSignatureForError ());
6736 if ((Get
.IsDummy
|| Set
.IsDummy
)
6737 && (Get
.ModFlags
!= 0 || Set
.ModFlags
!= 0) && (ModFlags
& Modifiers
.OVERRIDE
) == 0) {
6738 Report
.Error (276, Location
,
6739 "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6740 GetSignatureForError ());
6744 if (MemberType
.IsAbstract
&& MemberType
.IsSealed
) {
6745 Report
.Error (722, Location
, Error722
, TypeManager
.CSharpName (MemberType
));
6757 GetBuilder
= Get
.Define (Parent
);
6758 return GetBuilder
!= null;
6761 bool DefineSet (bool define
)
6763 if (!define
|| Set
.IsDummy
)
6766 SetBuilder
= Set
.Define (Parent
);
6767 return SetBuilder
!= null;
6770 protected bool DefineAccessors ()
6772 return DefineSet (define_set_first
) &&
6774 DefineSet (!define_set_first
);
6777 protected abstract PropertyInfo
ResolveBaseProperty ();
6779 // TODO: rename to Resolve......
6780 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
6782 PropertyInfo base_property
= ResolveBaseProperty ();
6783 if (base_property
== null)
6786 base_ret_type
= base_property
.PropertyType
;
6787 MethodInfo get_accessor
= base_property
.GetGetMethod (true);
6788 MethodInfo set_accessor
= base_property
.GetSetMethod (true);
6789 MethodAttributes get_accessor_access
, set_accessor_access
;
6791 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
6792 if (Get
!= null && !Get
.IsDummy
&& get_accessor
== null) {
6793 Report
.SymbolRelatedToPreviousError (base_property
);
6794 Report
.Error (545, Location
, "`{0}.get': cannot override because `{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager
.GetFullNameSignature (base_property
));
6797 if (Set
!= null && !Set
.IsDummy
&& set_accessor
== null) {
6798 Report
.SymbolRelatedToPreviousError (base_property
);
6799 Report
.Error (546, Location
, "`{0}.set': cannot override because `{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager
.GetFullNameSignature (base_property
));
6804 // Check base class accessors access
6807 // TODO: rewrite to reuse Get|Set.CheckAccessModifiers and share code there
6808 get_accessor_access
= set_accessor_access
= 0;
6809 if ((ModFlags
& Modifiers
.NEW
) == 0) {
6810 if (get_accessor
!= null) {
6811 MethodAttributes get_flags
= Modifiers
.MethodAttr (Get
.ModFlags
!= 0 ? Get
.ModFlags
: ModFlags
);
6812 get_accessor_access
= (get_accessor
.Attributes
& MethodAttributes
.MemberAccessMask
);
6814 if (!Get
.IsDummy
&& !CheckAccessModifiers (get_flags
& MethodAttributes
.MemberAccessMask
, get_accessor_access
, get_accessor
))
6815 Error_CannotChangeAccessModifiers (get_accessor
, get_accessor_access
, ".get");
6818 if (set_accessor
!= null) {
6819 MethodAttributes set_flags
= Modifiers
.MethodAttr (Set
.ModFlags
!= 0 ? Set
.ModFlags
: ModFlags
);
6820 set_accessor_access
= (set_accessor
.Attributes
& MethodAttributes
.MemberAccessMask
);
6822 if (!Set
.IsDummy
&& !CheckAccessModifiers (set_flags
& MethodAttributes
.MemberAccessMask
, set_accessor_access
, set_accessor
))
6823 Error_CannotChangeAccessModifiers (set_accessor
, set_accessor_access
, ".set");
6827 // When one accessor does not exist and property hides base one
6828 // we need to propagate this upwards
6829 if (set_accessor
== null)
6830 set_accessor
= get_accessor
;
6833 // Get the less restrictive access
6835 return get_accessor_access
> set_accessor_access
? get_accessor
: set_accessor
;
6838 public override void Emit ()
6841 // The PropertyBuilder can be null for explicit implementations, in that
6842 // case, we do not actually emit the ".property", so there is nowhere to
6843 // put the attribute
6845 if (PropertyBuilder
!= null && OptAttributes
!= null)
6846 OptAttributes
.Emit ();
6858 /// Tests whether accessors are not in collision with some method (CS0111)
6860 public bool AreAccessorsDuplicateImplementation (MethodCore mc
)
6862 return Get
.IsDuplicateImplementation (mc
) || Set
.IsDuplicateImplementation (mc
);
6865 public override bool IsUsed
6871 return Get
.IsUsed
| Set
.IsUsed
;
6875 protected override void SetMemberName (MemberName new_name
)
6877 base.SetMemberName (new_name
);
6879 Get
.UpdateName (this);
6880 Set
.UpdateName (this);
6883 public override string[] ValidAttributeTargets
{
6885 return attribute_targets
;
6890 // Represents header string for documentation comment.
6892 public override string DocCommentHeader
{
6893 get { return "P:"; }
6897 public class Property
: PropertyBase
{
6898 const int AllowedModifiers
=
6901 Modifiers
.PROTECTED
|
6902 Modifiers
.INTERNAL
|
6906 Modifiers
.OVERRIDE
|
6907 Modifiers
.ABSTRACT
|
6910 Modifiers
.METHOD_YIELDS
|
6913 const int AllowedInterfaceModifiers
=
6916 public Property (DeclSpace parent
, Expression type
, int mod
, bool is_iface
,
6917 MemberName name
, Attributes attrs
, Accessor get_block
,
6918 Accessor set_block
, bool define_set_first
)
6919 : base (parent
, type
, mod
,
6920 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
6921 is_iface
, name
, attrs
, define_set_first
)
6923 if (get_block
== null)
6924 Get
= new GetMethod (this);
6926 Get
= new GetMethod (this, get_block
);
6928 if (set_block
== null)
6929 Set
= new SetMethod (this);
6931 Set
= new SetMethod (this, set_block
);
6934 public override bool Define ()
6936 if (!DoDefineBase ())
6939 if (!base.Define ())
6945 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
6947 if (!DefineAccessors ())
6950 // FIXME - PropertyAttributes.HasDefault ?
6952 PropertyBuilder
= Parent
.TypeBuilder
.DefineProperty (
6953 MemberName
.ToString (), PropertyAttributes
.None
, MemberType
, null);
6956 PropertyBuilder
.SetGetMethod (GetBuilder
);
6959 PropertyBuilder
.SetSetMethod (SetBuilder
);
6961 TypeManager
.RegisterProperty (PropertyBuilder
, this);
6965 protected override PropertyInfo
ResolveBaseProperty ()
6967 return Parent
.PartialContainer
.BaseCache
.FindMemberToOverride (
6968 Parent
.TypeBuilder
, Name
, Parameters
.EmptyReadOnlyParameters
.Types
, null, true) as PropertyInfo
;
6973 /// Gigantic workaround for lameness in SRE follows :
6974 /// This class derives from EventInfo and attempts to basically
6975 /// wrap around the EventBuilder so that FindMembers can quickly
6976 /// return this in it search for members
6978 public class MyEventBuilder
: EventInfo
{
6981 // We use this to "point" to our Builder which is
6982 // not really a MemberInfo
6984 EventBuilder MyBuilder
;
6987 // We "catch" and wrap these methods
6989 MethodInfo raise
, remove, add;
6991 EventAttributes attributes
;
6992 Type declaring_type
, reflected_type
, event_type
;
6997 public MyEventBuilder (Event ev
, TypeBuilder type_builder
, string name
, EventAttributes event_attr
, Type event_type
)
6999 MyBuilder
= type_builder
.DefineEvent (name
, event_attr
, event_type
);
7001 // And now store the values in our own fields.
7003 declaring_type
= type_builder
;
7005 reflected_type
= type_builder
;
7007 attributes
= event_attr
;
7010 this.event_type
= event_type
;
7014 // Methods that you have to override. Note that you only need
7015 // to "implement" the variants that take the argument (those are
7016 // the "abstract" methods, the others (GetAddMethod()) are
7019 public override MethodInfo
GetAddMethod (bool nonPublic
)
7024 public override MethodInfo
GetRemoveMethod (bool nonPublic
)
7029 public override MethodInfo
GetRaiseMethod (bool nonPublic
)
7035 // These methods make "MyEventInfo" look like a Builder
7037 public void SetRaiseMethod (MethodBuilder raiseMethod
)
7039 raise
= raiseMethod
;
7040 MyBuilder
.SetRaiseMethod (raiseMethod
);
7043 public void SetRemoveOnMethod (MethodBuilder removeMethod
)
7045 remove = removeMethod
;
7046 MyBuilder
.SetRemoveOnMethod (removeMethod
);
7049 public void SetAddOnMethod (MethodBuilder addMethod
)
7052 MyBuilder
.SetAddOnMethod (addMethod
);
7055 public void SetCustomAttribute (CustomAttributeBuilder cb
)
7057 MyBuilder
.SetCustomAttribute (cb
);
7060 public override object [] GetCustomAttributes (bool inherit
)
7062 // FIXME : There's nothing which can be seemingly done here because
7063 // we have no way of getting at the custom attribute objects of the
7068 public override object [] GetCustomAttributes (Type t
, bool inherit
)
7070 // FIXME : Same here !
7074 public override bool IsDefined (Type t
, bool b
)
7079 public override EventAttributes Attributes
{
7085 public override string Name
{
7091 public override Type DeclaringType
{
7093 return declaring_type
;
7097 public override Type ReflectedType
{
7099 return reflected_type
;
7103 public Type EventType
{
7109 public void SetUsed ()
7111 if (my_event
!= null) {
7112 // my_event.SetAssigned ();
7113 my_event
.SetMemberIsUsed ();
7119 /// For case when event is declared like property (with add and remove accessors).
7121 public class EventProperty
: Event
{
7122 abstract class AEventPropertyAccessor
: AEventAccessor
7124 readonly ArrayList anonymous_methods
;
7126 public AEventPropertyAccessor (Event method
, Accessor accessor
, string prefix
):
7127 base (method
, accessor
, prefix
)
7129 this.anonymous_methods
= accessor
.AnonymousMethods
;
7132 public override MethodBuilder
Define (DeclSpace ds
)
7134 method
.CheckAbstractAndExtern (block
!= null);
7135 return base.Define (ds
);
7138 public override bool ResolveMembers ()
7140 if (anonymous_methods
== null)
7143 foreach (AnonymousMethodExpression ame
in anonymous_methods
) {
7144 if (!ame
.CreateAnonymousHelpers ())
7153 sealed class AddDelegateMethod
: AEventPropertyAccessor
7155 public AddDelegateMethod (Event method
, Accessor accessor
):
7156 base (method
, accessor
, "add_")
7160 protected override MethodInfo DelegateMethodInfo
{
7162 return TypeManager
.delegate_combine_delegate_delegate
;
7167 sealed class RemoveDelegateMethod
: AEventPropertyAccessor
7169 public RemoveDelegateMethod (Event method
, Accessor accessor
):
7170 base (method
, accessor
, "remove_")
7174 protected override MethodInfo DelegateMethodInfo
{
7176 return TypeManager
.delegate_remove_delegate_delegate
;
7182 static readonly string[] attribute_targets
= new string [] { "event" }
; // "property" target was disabled for 2.0 version
7184 public EventProperty (DeclSpace parent
, Expression type
, int mod_flags
,
7185 bool is_iface
, MemberName name
,
7186 Attributes attrs
, Accessor
add, Accessor
remove)
7187 : base (parent
, type
, mod_flags
, is_iface
, name
, attrs
)
7189 Add
= new AddDelegateMethod (this, add);
7190 Remove
= new RemoveDelegateMethod (this, remove);
7193 public override bool Define()
7195 if (!base.Define ())
7204 public override string[] ValidAttributeTargets
{
7206 return attribute_targets
;
7212 /// Event is declared like field.
7214 public class EventField
: Event
{
7215 abstract class EventFieldAccessor
: AEventAccessor
7217 protected EventFieldAccessor (Event method
, string prefix
)
7218 : base (method
, prefix
)
7222 protected override void EmitMethod(DeclSpace parent
)
7224 if ((method
.ModFlags
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) != 0)
7227 MethodBuilder mb
= method_data
.MethodBuilder
;
7228 ILGenerator ig
= mb
.GetILGenerator ();
7230 // TODO: because we cannot use generics yet
7231 FieldInfo field_info
= ((EventField
)method
).FieldBuilder
;
7233 mb
.SetImplementationFlags (mb
.GetMethodImplementationFlags () | MethodImplAttributes
.Synchronized
);
7234 if ((method
.ModFlags
& Modifiers
.STATIC
) != 0) {
7235 ig
.Emit (OpCodes
.Ldsfld
, field_info
);
7236 ig
.Emit (OpCodes
.Ldarg_0
);
7237 ig
.Emit (OpCodes
.Call
, DelegateMethodInfo
);
7238 ig
.Emit (OpCodes
.Castclass
, method
.MemberType
);
7239 ig
.Emit (OpCodes
.Stsfld
, field_info
);
7241 ig
.Emit (OpCodes
.Ldarg_0
);
7242 ig
.Emit (OpCodes
.Ldarg_0
);
7243 ig
.Emit (OpCodes
.Ldfld
, field_info
);
7244 ig
.Emit (OpCodes
.Ldarg_1
);
7245 ig
.Emit (OpCodes
.Call
, DelegateMethodInfo
);
7246 ig
.Emit (OpCodes
.Castclass
, method
.MemberType
);
7247 ig
.Emit (OpCodes
.Stfld
, field_info
);
7249 ig
.Emit (OpCodes
.Ret
);
7253 sealed class AddDelegateMethod
: EventFieldAccessor
7255 public AddDelegateMethod (Event method
):
7256 base (method
, "add_")
7260 protected override MethodInfo DelegateMethodInfo
{
7262 return TypeManager
.delegate_combine_delegate_delegate
;
7267 sealed class RemoveDelegateMethod
: EventFieldAccessor
7269 public RemoveDelegateMethod (Event method
):
7270 base (method
, "remove_")
7274 protected override MethodInfo DelegateMethodInfo
{
7276 return TypeManager
.delegate_remove_delegate_delegate
;
7282 static readonly string[] attribute_targets
= new string [] { "event", "field", "method" }
;
7283 static readonly string[] attribute_targets_interface
= new string[] { "event", "method" }
;
7285 public FieldBuilder FieldBuilder
;
7286 public Expression Initializer
;
7288 public EventField (DeclSpace parent
, Expression type
, int mod_flags
,
7289 bool is_iface
, MemberName name
,
7291 : base (parent
, type
, mod_flags
, is_iface
, name
, attrs
)
7293 Add
= new AddDelegateMethod (this);
7294 Remove
= new RemoveDelegateMethod (this);
7297 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
7299 if (a
.Target
== AttributeTargets
.Field
) {
7300 FieldBuilder
.SetCustomAttribute (cb
);
7304 if (a
.Target
== AttributeTargets
.Method
) {
7305 int errors
= Report
.Errors
;
7306 Add
.ApplyAttributeBuilder (a
, cb
);
7307 if (errors
== Report
.Errors
)
7308 Remove
.ApplyAttributeBuilder (a
, cb
);
7312 base.ApplyAttributeBuilder (a
, cb
);
7315 public override bool Define()
7317 if (!base.Define ())
7323 // FIXME: We are unable to detect whether generic event is used because
7324 // we are using FieldExpr instead of EventExpr for event access in that
7325 // case. When this issue will be fixed this hack can be removed.
7326 if (TypeManager
.IsGenericType (MemberType
))
7329 FieldBuilder
= Parent
.TypeBuilder
.DefineField (
7331 FieldAttributes
.Private
| ((ModFlags
& Modifiers
.STATIC
) != 0 ? FieldAttributes
.Static
: 0));
7332 TypeManager
.RegisterEventField (EventBuilder
, this);
7334 if (Initializer
!= null) {
7335 if (((ModFlags
& Modifiers
.ABSTRACT
) != 0)) {
7336 Report
.Error (74, Location
, "`{0}': abstract event cannot have an initializer",
7337 GetSignatureForError ());
7341 Parent
.PartialContainer
.RegisterFieldForInitialization (this,
7342 new FieldInitializer (FieldBuilder
, Initializer
, Parent
));
7348 public override string[] ValidAttributeTargets
7351 return IsInterface
? attribute_targets_interface
: attribute_targets
;
7356 public abstract class Event
: PropertyBasedMember
{
7357 public abstract class AEventAccessor
: AbstractPropertyEventMethod
7359 protected readonly Event method
;
7360 ImplicitParameter param_attr
;
7362 static readonly string[] attribute_targets
= new string [] { "method", "param", "return" }
;
7364 protected AEventAccessor (Event method
, string prefix
)
7365 : base (method
, prefix
)
7367 this.method
= method
;
7370 protected AEventAccessor (Event method
, Accessor accessor
, string prefix
)
7371 : base (method
, accessor
, prefix
)
7373 this.method
= method
;
7376 public override Iterator Iterator
{
7377 get { return null; }
7380 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
7382 if (a
.IsInternalMethodImplAttribute
) {
7383 method_data
.MethodBuilder
.SetImplementationFlags (MethodImplAttributes
.InternalCall
| MethodImplAttributes
.Runtime
);
7384 method
.is_external_implementation
= true;
7387 base.ApplyAttributeBuilder (a
, cb
);
7390 protected override void ApplyToExtraTarget(Attribute a
, CustomAttributeBuilder cb
)
7392 if (a
.Target
== AttributeTargets
.Parameter
) {
7393 if (param_attr
== null)
7394 param_attr
= new ImplicitParameter (method_data
.MethodBuilder
);
7396 param_attr
.ApplyAttributeBuilder (a
, cb
);
7400 base.ApplyAttributeBuilder (a
, cb
);
7403 public override AttributeTargets AttributeTargets
{
7405 return AttributeTargets
.Method
;
7409 public override bool IsClsComplianceRequired ()
7411 return method
.IsClsComplianceRequired ();
7414 public virtual MethodBuilder
Define (DeclSpace parent
)
7416 method_data
= new MethodData (method
, method
.ModFlags
,
7417 method
.flags
| MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
, this);
7419 if (!method_data
.Define (parent
))
7422 MethodBuilder mb
= method_data
.MethodBuilder
;
7423 ParameterInfo
.ApplyAttributes (mb
);
7427 protected abstract MethodInfo DelegateMethodInfo { get; }
7429 public override Type ReturnType
{
7431 return TypeManager
.void_type
;
7435 public override EmitContext
CreateEmitContext (DeclSpace ds
, ILGenerator ig
)
7437 return new EmitContext (
7438 ds
, method
.Parent
, Location
, ig
, ReturnType
,
7439 method
.ModFlags
, false);
7442 public override ObsoleteAttribute
GetObsoleteAttribute ()
7444 return method
.GetObsoleteAttribute ();
7447 public override string[] ValidAttributeTargets
{
7449 return attribute_targets
;
7453 public override Parameters ParameterInfo
{
7455 return method
.parameters
;
7461 const int AllowedModifiers
=
7464 Modifiers
.PROTECTED
|
7465 Modifiers
.INTERNAL
|
7470 Modifiers
.OVERRIDE
|
7472 Modifiers
.ABSTRACT
|
7475 const int AllowedInterfaceModifiers
=
7478 public AEventAccessor Add
, Remove
;
7479 public MyEventBuilder EventBuilder
;
7480 public MethodBuilder AddBuilder
, RemoveBuilder
;
7482 Parameters parameters
;
7484 protected Event (DeclSpace parent
, Expression type
, int mod_flags
,
7485 bool is_iface
, MemberName name
, Attributes attrs
)
7486 : base (parent
, null, type
, mod_flags
,
7487 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
, is_iface
,
7492 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
7494 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
)) {
7495 a
.Error_InvalidSecurityParent ();
7499 EventBuilder
.SetCustomAttribute (cb
);
7502 public bool AreAccessorsDuplicateImplementation (MethodCore mc
)
7504 return Add
.IsDuplicateImplementation (mc
) || Remove
.IsDuplicateImplementation (mc
);
7507 public override AttributeTargets AttributeTargets
{
7509 return AttributeTargets
.Event
;
7513 public override bool Define ()
7515 if (!DoDefineBase ())
7521 if (!TypeManager
.IsDelegateType (MemberType
)) {
7522 Report
.Error (66, Location
, "`{0}': event must be of a delegate type", GetSignatureForError ());
7526 parameters
= new Parameters (
7527 new Parameter
[] { new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location) }
,
7528 new Type
[] { MemberType }
);
7534 // Now define the accessors
7537 AddBuilder
= Add
.Define (Parent
);
7538 if (AddBuilder
== null)
7541 RemoveBuilder
= Remove
.Define (Parent
);
7542 if (RemoveBuilder
== null)
7545 EventBuilder
= new MyEventBuilder (this, Parent
.TypeBuilder
, Name
, EventAttributes
.None
, MemberType
);
7546 EventBuilder
.SetAddOnMethod (AddBuilder
);
7547 EventBuilder
.SetRemoveOnMethod (RemoveBuilder
);
7551 public override void Emit ()
7553 if (OptAttributes
!= null) {
7554 OptAttributes
.Emit ();
7558 Remove
.Emit (Parent
);
7563 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
7565 MethodInfo mi
= (MethodInfo
) Parent
.PartialContainer
.BaseCache
.FindBaseEvent (
7566 Parent
.TypeBuilder
, Name
);
7571 ParameterData pd
= TypeManager
.GetParameterData (mi
);
7572 base_ret_type
= pd
.ParameterType (0);
7577 // Represents header string for documentation comment.
7579 public override string DocCommentHeader
{
7580 get { return "E:"; }
7585 public class Indexer
: PropertyBase
{
7587 class GetIndexerMethod
: GetMethod
7589 public GetIndexerMethod (PropertyBase method
):
7594 public GetIndexerMethod (PropertyBase method
, Accessor accessor
):
7595 base (method
, accessor
)
7599 public override Parameters ParameterInfo
{
7601 return ((Indexer
)method
).parameters
;
7606 class SetIndexerMethod
: SetMethod
7608 public SetIndexerMethod (PropertyBase method
):
7613 public SetIndexerMethod (PropertyBase method
, Accessor accessor
):
7614 base (method
, accessor
)
7618 protected override void DefineParameters ()
7620 parameters
= Parameters
.MergeGenerated (((Indexer
)method
).parameters
,
7621 new Parameter (method
.MemberType
, "value", Parameter
.Modifier
.NONE
, null, method
.Location
));
7625 const int AllowedModifiers
=
7628 Modifiers
.PROTECTED
|
7629 Modifiers
.INTERNAL
|
7633 Modifiers
.OVERRIDE
|
7638 const int AllowedInterfaceModifiers
=
7641 public readonly Parameters parameters
;
7643 public Indexer (DeclSpace parent
, Expression type
, MemberName name
, int mod
,
7644 bool is_iface
, Parameters parameters
, Attributes attrs
,
7645 Accessor get_block
, Accessor set_block
, bool define_set_first
)
7646 : base (parent
, type
, mod
,
7647 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
7648 is_iface
, name
, attrs
, define_set_first
)
7650 this.parameters
= parameters
;
7652 if (get_block
== null)
7653 Get
= new GetIndexerMethod (this);
7655 Get
= new GetIndexerMethod (this, get_block
);
7657 if (set_block
== null)
7658 Set
= new SetIndexerMethod (this);
7660 Set
= new SetIndexerMethod (this, set_block
);
7663 protected override bool CheckForDuplications ()
7665 ArrayList ar
= Parent
.PartialContainer
.Indexers
;
7667 int arLen
= ar
.Count
;
7669 for (int i
= 0; i
< arLen
; i
++) {
7670 Indexer m
= (Indexer
) ar
[i
];
7671 if (IsDuplicateImplementation (m
))
7679 bool IsDuplicateImplementation (Indexer indexer
)
7681 if (this == indexer
)
7684 if (!MemberName
.Equals (indexer
.MemberName
))
7687 Type
[] param_types
= indexer
.parameters
.Types
;
7689 // When it is not yet defined
7690 if (param_types
== null)
7693 if (param_types
.Length
!= parameters
.Count
)
7696 for (int i
= 0; i
< param_types
.Length
; i
++)
7697 if (param_types
[i
] != parameters
.Types
[i
])
7700 Report
.SymbolRelatedToPreviousError (indexer
);
7701 Report
.Error (111, Location
, TypeContainer
.Error111
, indexer
.GetSignatureForError ());
7706 public override bool Define ()
7708 if (!DoDefineBase ())
7711 if (!base.Define ())
7714 if (!DefineParameters (parameters
))
7717 if (MemberType
== TypeManager
.void_type
) {
7718 Report
.Error (620, Location
, "Indexers cannot have void type");
7722 if (OptAttributes
!= null) {
7723 Attribute indexer_attr
= OptAttributes
.Search (TypeManager
.indexer_name_type
);
7724 if (indexer_attr
!= null) {
7725 // Remove the attribute from the list because it is not emitted
7726 OptAttributes
.Attrs
.Remove (indexer_attr
);
7728 string name
= indexer_attr
.GetIndexerAttributeValue ();
7734 if (IsExplicitImpl
) {
7735 Report
.Error (415, indexer_attr
.Location
,
7736 "The `IndexerName' attribute is valid only on an " +
7737 "indexer that is not an explicit interface member declaration");
7741 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
7742 Report
.Error (609, indexer_attr
.Location
,
7743 "Cannot set the `IndexerName' attribute on an indexer marked override");
7749 if (InterfaceType
!= null) {
7750 string base_IndexerName
= TypeManager
.IndexerPropertyName (InterfaceType
);
7751 if (base_IndexerName
!= Name
)
7752 ShortName
= base_IndexerName
;
7755 if (!Parent
.PartialContainer
.AddMember (this) ||
7756 !Parent
.PartialContainer
.AddMember (Get
) || !Parent
.PartialContainer
.AddMember (Set
))
7762 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
7764 if (!DefineAccessors ())
7768 // Setup iterator if we are one
7769 if ((ModFlags
& Modifiers
.METHOD_YIELDS
) != 0){
7770 Iterator iterator
= Iterator
.CreateIterator (Get
, Parent
, null, ModFlags
);
7771 if (iterator
== null)
7777 // Now name the parameters
7779 Parameter
[] p
= parameters
.FixedParameters
;
7781 // TODO: should be done in parser and it needs to do cycle
7782 if ((p
[0].ModFlags
& Parameter
.Modifier
.ISBYREF
) != 0) {
7783 CSharpParser
.Error_ParameterModifierNotValid (Location
);
7788 PropertyBuilder
= Parent
.TypeBuilder
.DefineProperty (
7789 Name
, PropertyAttributes
.None
, MemberType
, parameters
.Types
);
7792 PropertyBuilder
.SetGetMethod (GetBuilder
);
7795 PropertyBuilder
.SetSetMethod (SetBuilder
);
7797 TypeManager
.RegisterIndexer (PropertyBuilder
, GetBuilder
, SetBuilder
, parameters
.Types
);
7802 public override string GetDocCommentName (DeclSpace ds
)
7804 return DocUtil
.GetMethodDocCommentName (this, parameters
, ds
);
7807 public override string GetSignatureForError ()
7809 StringBuilder sb
= new StringBuilder (Parent
.GetSignatureForError ());
7810 if (MemberName
.Left
!= null) {
7812 sb
.Append (MemberName
.Left
);
7815 sb
.Append (".this");
7816 sb
.Append (parameters
.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7817 return sb
.ToString ();
7820 public override bool MarkForDuplicationCheck ()
7822 caching_flags
|= Flags
.TestMethodDuplication
;
7826 protected override PropertyInfo
ResolveBaseProperty ()
7828 return Parent
.PartialContainer
.BaseCache
.FindMemberToOverride (
7829 Parent
.TypeBuilder
, Name
, parameters
.Types
, null, true) as PropertyInfo
;
7832 protected override bool VerifyClsCompliance ()
7834 if (!base.VerifyClsCompliance ())
7837 parameters
.VerifyClsCompliance ();
7842 public class Operator
: MethodOrOperator
, IAnonymousHost
{
7844 const int AllowedModifiers
=
7850 public enum OpType
: byte {
7860 // Unary and Binary operators
7883 // Implicit and Explicit
7887 // Just because of enum
7891 public readonly OpType OperatorType
;
7893 public Operator (DeclSpace parent
, OpType type
, Expression ret_type
,
7894 int mod_flags
, Parameters parameters
,
7895 ToplevelBlock block
, Attributes attrs
, Location loc
)
7896 : base (parent
, null, ret_type
, mod_flags
, AllowedModifiers
, false,
7897 new MemberName ("op_" + type
.ToString(), loc
), attrs
, parameters
)
7899 OperatorType
= type
;
7903 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
7905 if (a
.Type
== TypeManager
.conditional_attribute_type
) {
7906 Error_ConditionalAttributeIsNotValid ();
7910 base.ApplyAttributeBuilder (a
, cb
);
7913 protected override bool CheckForDuplications ()
7915 ArrayList ar
= Parent
.PartialContainer
.Operators
;
7917 int arLen
= ar
.Count
;
7919 for (int i
= 0; i
< arLen
; i
++) {
7920 Operator o
= (Operator
) ar
[i
];
7921 if (IsDuplicateImplementation (o
))
7926 ar
= Parent
.PartialContainer
.Methods
;
7928 int arLen
= ar
.Count
;
7930 for (int i
= 0; i
< arLen
; i
++) {
7931 Method m
= (Method
) ar
[i
];
7932 if (IsDuplicateImplementation (m
))
7940 public override bool Define ()
7942 const int RequiredModifiers
= Modifiers
.PUBLIC
| Modifiers
.STATIC
;
7943 if ((ModFlags
& RequiredModifiers
) != RequiredModifiers
){
7944 Report
.Error (558, Location
, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7948 // imlicit and explicit operator of same types are not allowed
7949 if (OperatorType
== OpType
.Explicit
|| OperatorType
== OpType
.Implicit
)
7950 MarkForDuplicationCheck ();
7952 if (!base.Define ())
7955 if (MemberType
== TypeManager
.void_type
) {
7956 Report
.Error (590, Location
, "User-defined operators cannot return void");
7960 Type declaring_type
= MethodData
.DeclaringType
;
7961 Type return_type
= MemberType
;
7962 Type first_arg_type
= ParameterTypes
[0];
7964 // Rules for conversion operators
7966 if (OperatorType
== OpType
.Implicit
|| OperatorType
== OpType
.Explicit
) {
7967 if (first_arg_type
== return_type
&& first_arg_type
== declaring_type
){
7968 Report
.Error (555, Location
,
7969 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7973 if ((first_arg_type
!= declaring_type
) && (return_type
!= declaring_type
) &&
7974 !TypeManager
.IsNullableTypeOf (first_arg_type
, declaring_type
) &&
7975 !TypeManager
.IsNullableTypeOf (return_type
, declaring_type
)) {
7978 "User-defined conversion must convert to or from the " +
7983 if (first_arg_type
.IsInterface
|| return_type
.IsInterface
){
7984 Report
.Error (552, Location
, "User-defined conversion `{0}' cannot convert to or from an interface type",
7985 GetSignatureForError ());
7989 if (first_arg_type
.IsSubclassOf (return_type
) || return_type
.IsSubclassOf (first_arg_type
)) {
7990 if (declaring_type
.IsSubclassOf (return_type
) || declaring_type
.IsSubclassOf (first_arg_type
)) {
7991 Report
.Error (553, Location
, "User-defined conversion `{0}' cannot convert to or from base class",
7992 GetSignatureForError ());
7995 Report
.Error (554, Location
, "User-defined conversion `{0}' cannot convert to or from derived class",
7996 GetSignatureForError ());
7999 } else if (OperatorType
== OpType
.LeftShift
|| OperatorType
== OpType
.RightShift
) {
8000 if (first_arg_type
!= declaring_type
|| ParameterTypes
[1] != TypeManager
.int32_type
) {
8001 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");
8004 } else if (Parameters
.Count
== 1) {
8005 // Checks for Unary operators
8007 if (OperatorType
== OpType
.Increment
|| OperatorType
== OpType
.Decrement
) {
8008 if (return_type
!= declaring_type
&& !TypeManager
.IsSubclassOf (return_type
, declaring_type
)) {
8009 Report
.Error (448, Location
,
8010 "The return type for ++ or -- operator must be the containing type or derived from the containing type");
8013 if (first_arg_type
!= declaring_type
) {
8015 559, Location
, "The parameter type for ++ or -- operator must be the containing type");
8020 if (first_arg_type
!= declaring_type
){
8023 "The parameter of a unary operator must be the " +
8028 if (OperatorType
== OpType
.True
|| OperatorType
== OpType
.False
) {
8029 if (return_type
!= TypeManager
.bool_type
){
8032 "The return type of operator True or False " +
8039 // Checks for Binary operators
8041 if (first_arg_type
!= declaring_type
&&
8042 ParameterTypes
[1] != declaring_type
){
8045 "One of the parameters of a binary operator must " +
8046 "be the containing type");
8054 protected override bool DoDefine ()
8056 if (!base.DoDefine ())
8059 flags
|= MethodAttributes
.SpecialName
| MethodAttributes
.HideBySig
;
8063 public override void Emit ()
8067 Parameters
.ApplyAttributes (MethodBuilder
);
8070 // abstract or extern methods have no bodies
8072 if ((ModFlags
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) != 0)
8076 if ((flags
& MethodAttributes
.PinvokeImpl
) == 0)
8077 ec
= CreateEmitContext (Parent
, MethodBuilder
.GetILGenerator ());
8079 ec
= CreateEmitContext (Parent
, null);
8081 SourceMethod source
= SourceMethod
.Create (Parent
, MethodBuilder
, Block
);
8082 ec
.EmitTopBlock (this, Block
);
8085 source
.CloseMethod ();
8090 // Operator cannot be override
8091 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
8096 public static string GetName (OpType ot
)
8099 case OpType
.LogicalNot
:
8101 case OpType
.OnesComplement
:
8103 case OpType
.Increment
:
8105 case OpType
.Decrement
:
8111 case OpType
.Addition
:
8113 case OpType
.Subtraction
:
8115 case OpType
.UnaryPlus
:
8117 case OpType
.UnaryNegation
:
8119 case OpType
.Multiply
:
8121 case OpType
.Division
:
8123 case OpType
.Modulus
:
8125 case OpType
.BitwiseAnd
:
8127 case OpType
.BitwiseOr
:
8129 case OpType
.ExclusiveOr
:
8131 case OpType
.LeftShift
:
8133 case OpType
.RightShift
:
8135 case OpType
.Equality
:
8137 case OpType
.Inequality
:
8139 case OpType
.GreaterThan
:
8141 case OpType
.LessThan
:
8143 case OpType
.GreaterThanOrEqual
:
8145 case OpType
.LessThanOrEqual
:
8147 case OpType
.Implicit
:
8149 case OpType
.Explicit
:
8155 public static OpType
GetOperatorType (string name
)
8157 if (name
.StartsWith ("op_")){
8158 for (int i
= 0; i
< Unary
.oper_names
.Length
; ++i
) {
8159 if (Unary
.oper_names
[i
] == name
)
8163 for (int i
= 0; i
< Binary
.oper_names
.Length
; ++i
) {
8164 if (Binary
.oper_names
[i
] == name
)
8171 public override string GetSignatureForError ()
8173 StringBuilder sb
= new StringBuilder ();
8174 if (OperatorType
== OpType
.Implicit
|| OperatorType
== OpType
.Explicit
) {
8175 sb
.AppendFormat ("{0}.{1} operator {2}", Parent
.GetSignatureForError (), GetName (OperatorType
), Type
.Type
== null ? Type
.ToString () : TypeManager
.CSharpName (Type
.Type
));
8178 sb
.AppendFormat ("{0}.operator {1}", Parent
.GetSignatureForError (), GetName (OperatorType
));
8181 sb
.Append (Parameters
.GetSignatureForError ());
8182 return sb
.ToString ();
8187 // This is used to compare method signatures
8189 struct MethodSignature
{
8191 public Type RetType
;
8192 public Type
[] Parameters
;
8195 /// This delegate is used to extract methods which have the
8196 /// same signature as the argument
8198 public static MemberFilter method_signature_filter
= new MemberFilter (MemberSignatureCompare
);
8200 public MethodSignature (string name
, Type ret_type
, Type
[] parameters
)
8205 if (parameters
== null)
8206 Parameters
= Type
.EmptyTypes
;
8208 Parameters
= parameters
;
8211 public override string ToString ()
8214 if (Parameters
.Length
!= 0){
8215 System
.Text
.StringBuilder sb
= new System
.Text
.StringBuilder ();
8216 for (int i
= 0; i
< Parameters
.Length
; i
++){
8217 sb
.Append (Parameters
[i
]);
8218 if (i
+1 < Parameters
.Length
)
8221 pars
= sb
.ToString ();
8224 return String
.Format ("{0} {1} ({2})", RetType
, Name
, pars
);
8227 public override int GetHashCode ()
8229 return Name
.GetHashCode ();
8232 public override bool Equals (Object o
)
8234 MethodSignature other
= (MethodSignature
) o
;
8236 if (other
.Name
!= Name
)
8239 if (other
.RetType
!= RetType
)
8242 if (Parameters
== null){
8243 if (other
.Parameters
== null)
8248 if (other
.Parameters
== null)
8251 int c
= Parameters
.Length
;
8252 if (other
.Parameters
.Length
!= c
)
8255 for (int i
= 0; i
< c
; i
++)
8256 if (other
.Parameters
[i
] != Parameters
[i
])
8262 static bool MemberSignatureCompare (MemberInfo m
, object filter_criteria
)
8264 MethodSignature sig
= (MethodSignature
) filter_criteria
;
8266 if (m
.Name
!= sig
.Name
)
8270 MethodInfo mi
= m
as MethodInfo
;
8271 PropertyInfo pi
= m
as PropertyInfo
;
8274 ReturnType
= mi
.ReturnType
;
8275 else if (pi
!= null)
8276 ReturnType
= pi
.PropertyType
;
8281 // we use sig.RetType == null to mean `do not check the
8282 // method return value.
8284 if (sig
.RetType
!= null)
8285 if (ReturnType
!= sig
.RetType
)
8290 args
= TypeManager
.GetParameterData (mi
).Types
;
8292 args
= TypeManager
.GetArgumentTypes (pi
);
8293 Type
[] sigp
= sig
.Parameters
;
8295 if (args
.Length
!= sigp
.Length
)
8298 for (int i
= args
.Length
; i
> 0; ){
8300 if (args
[i
] != sigp
[i
])