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
;
46 using Mono
.CompilerServices
.SymbolWriter
;
48 namespace Mono
.CSharp
{
58 /// This is the base class for structs and classes.
60 public abstract class TypeContainer
: DeclSpace
, IMemberContainer
{
62 public class MemberCoreArrayList
: ArrayList
65 /// Defines the MemberCore objects that are in this array
67 public virtual void DefineContainerMembers ()
69 foreach (MemberCore mc
in this) {
74 throw new InternalErrorException (mc
.Location
, mc
.GetSignatureForError (), e
);
79 public virtual void Emit ()
81 foreach (MemberCore mc
in this)
86 public class MethodArrayList
: MemberCoreArrayList
94 CachedMethods cached_method
;
95 TypeContainer container
;
97 public MethodArrayList (TypeContainer container
)
99 this.container
= container
;
103 /// Method container contains Equals method
105 public bool HasEquals
{
107 cached_method
|= CachedMethods
.Equals
;
111 return (cached_method
& CachedMethods
.Equals
) != 0;
116 /// Method container contains GetHashCode method
118 public bool HasGetHashCode
{
120 cached_method
|= CachedMethods
.GetHashCode
;
124 return (cached_method
& CachedMethods
.GetHashCode
) != 0;
128 public override void DefineContainerMembers ()
130 base.DefineContainerMembers ();
132 if (HasEquals
&& !HasGetHashCode
) {
133 Report
.Warning (659, 3, container
.Location
, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container
.GetSignatureForError ());
139 public sealed class IndexerArrayList
: MemberCoreArrayList
142 /// The indexer name for this container
144 public string IndexerName
= DefaultIndexerName
;
146 bool seen_normal_indexers
= false;
148 TypeContainer container
;
150 public IndexerArrayList (TypeContainer container
)
152 this.container
= container
;
156 /// Defines the indexers, and also verifies that the IndexerNameAttribute in the
157 /// class is consistent. Either it is `Item' or it is the name defined by all the
158 /// indexers with the `IndexerName' attribute.
160 /// Turns out that the IndexerNameAttribute is applied to each indexer,
161 /// but it is never emitted, instead a DefaultMember attribute is attached
164 public override void DefineContainerMembers()
166 base.DefineContainerMembers ();
168 string class_indexer_name
= null;
171 // If there's both an explicit and an implicit interface implementation, the
172 // explicit one actually implements the interface while the other one is just
173 // a normal indexer. See bug #37714.
176 // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
177 foreach (Indexer i
in this) {
178 if (i
.InterfaceType
!= null) {
179 if (seen_normal_indexers
)
180 throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
184 seen_normal_indexers
= true;
186 if (class_indexer_name
== null) {
187 class_indexer_name
= i
.ShortName
;
191 if (i
.ShortName
!= class_indexer_name
)
192 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");
195 if (class_indexer_name
!= null)
196 IndexerName
= class_indexer_name
;
199 public override void Emit ()
203 if (!seen_normal_indexers
)
206 CustomAttributeBuilder cb
= new CustomAttributeBuilder (TypeManager
.default_member_ctor
, new string [] { IndexerName }
);
207 container
.TypeBuilder
.SetCustomAttribute (cb
);
211 public class OperatorArrayList
: MemberCoreArrayList
213 TypeContainer container
;
215 public OperatorArrayList (TypeContainer container
)
217 this.container
= container
;
221 // Operator pair checking
226 public Type ret_type
;
227 public Type type1
, type2
;
229 public Operator
.OpType ot
;
231 public OperatorEntry (int f
, Operator o
)
235 ret_type
= o
.MemberType
;
236 Type
[] pt
= o
.ParameterTypes
;
243 public override int GetHashCode ()
245 return ret_type
.GetHashCode ();
248 public override bool Equals (object o
)
250 OperatorEntry other
= (OperatorEntry
) o
;
252 if (other
.ret_type
!= ret_type
)
254 if (other
.type1
!= type1
)
256 if (other
.type2
!= type2
)
263 // Checks that some operators come in pairs:
269 // They are matched based on the return type and the argument types
271 void CheckPairedOperators ()
273 IDictionary pairs
= new HybridDictionary ();
274 Operator true_op
= null;
275 Operator false_op
= null;
276 bool has_equality_or_inequality
= false;
278 // Register all the operators we care about.
279 foreach (Operator op
in this){
282 // Skip erroneous code.
283 if (op
.MethodBuilder
== null)
286 switch (op
.OperatorType
){
287 case Operator
.OpType
.Equality
:
289 has_equality_or_inequality
= true;
291 case Operator
.OpType
.Inequality
:
293 has_equality_or_inequality
= true;
296 case Operator
.OpType
.True
:
299 case Operator
.OpType
.False
:
303 case Operator
.OpType
.GreaterThan
:
305 case Operator
.OpType
.LessThan
:
308 case Operator
.OpType
.GreaterThanOrEqual
:
310 case Operator
.OpType
.LessThanOrEqual
:
316 OperatorEntry oe
= new OperatorEntry (reg
, op
);
318 object o
= pairs
[oe
];
322 oe
= (OperatorEntry
) o
;
327 if (true_op
!= null){
328 if (false_op
== null)
329 Report
.Error (216, true_op
.Location
, "The operator `{0}' requires a matching operator `false' to also be defined",
330 true_op
.GetSignatureForError ());
331 } else if (false_op
!= null)
332 Report
.Error (216, false_op
.Location
, "The operator `{0}' requires a matching operator `true' to also be defined",
333 false_op
.GetSignatureForError ());
336 // Look for the mistakes.
338 foreach (DictionaryEntry de
in pairs
){
339 OperatorEntry oe
= (OperatorEntry
) de
.Key
;
346 case Operator
.OpType
.Equality
:
349 case Operator
.OpType
.Inequality
:
352 case Operator
.OpType
.GreaterThan
:
355 case Operator
.OpType
.LessThan
:
358 case Operator
.OpType
.GreaterThanOrEqual
:
361 case Operator
.OpType
.LessThanOrEqual
:
365 Report
.Error (216, oe
.op
.Location
,
366 "The operator `{0}' requires a matching operator `{1}' to also be defined",
367 oe
.op
.GetSignatureForError (), s
);
370 if (has_equality_or_inequality
&& (RootContext
.WarningLevel
> 2)) {
371 if (container
.Methods
== null || !container
.Methods
.HasEquals
)
372 Report
.Warning (660, 2, container
.Location
, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container
.GetSignatureForError ());
374 if (container
.Methods
== null || !container
.Methods
.HasGetHashCode
)
375 Report
.Warning (661, 2, container
.Location
, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container
.GetSignatureForError ());
379 public override void DefineContainerMembers ()
381 base.DefineContainerMembers ();
382 CheckPairedOperators ();
387 // Whether this is a struct, class or interface
388 public readonly Kind Kind
;
390 // Holds a list of classes and structures
391 protected ArrayList types
;
393 // Holds the list of properties
394 MemberCoreArrayList properties
;
396 // Holds the list of enumerations
397 MemberCoreArrayList enums
;
399 // Holds the list of delegates
400 MemberCoreArrayList delegates
;
402 // Holds the list of constructors
403 protected MemberCoreArrayList instance_constructors
;
405 // Holds the list of fields
406 MemberCoreArrayList fields
;
408 // Holds a list of fields that have initializers
409 protected ArrayList initialized_fields
;
411 // Holds a list of static fields that have initializers
412 protected ArrayList initialized_static_fields
;
414 // Holds the list of constants
415 MemberCoreArrayList constants
;
418 MemberCoreArrayList interfaces
;
420 // Holds the methods.
421 MethodArrayList methods
;
424 protected MemberCoreArrayList events
;
426 // Holds the indexers
427 IndexerArrayList indexers
;
429 // Holds the operators
430 MemberCoreArrayList operators
;
432 // Holds the iterators
436 // Pointers to the default constructor and the default static constructor
438 protected Constructor default_constructor
;
439 protected Constructor default_static_constructor
;
442 // Points to the first non-static field added to the container.
444 // This is an arbitrary choice. We are interested in looking at _some_ non-static field,
445 // and the first one's as good as any.
447 FieldBase first_nonstatic_field
= null;
450 // This one is computed after we can distinguish interfaces
451 // from classes from the arraylist `type_bases'
454 TypeExpr
[] iface_exprs
;
456 ArrayList type_bases
;
458 bool members_defined
;
459 bool members_defined_ok
;
461 // The interfaces we implement.
462 protected Type
[] ifaces
;
464 // The base member cache and our member cache
465 MemberCache base_cache
;
466 MemberCache member_cache
;
468 public const string DefaultIndexerName
= "Item";
471 GenericTypeParameterBuilder
[] gen_params
;
473 public TypeContainer PartialContainer
;
474 ArrayList partial_parts
;
477 /// The pending methods that need to be implemented
478 // (interfaces or abstract methods)
480 PendingImplementation pending
;
482 public TypeContainer (NamespaceEntry ns
, DeclSpace parent
, MemberName name
,
483 Attributes attrs
, Kind kind
)
484 : base (ns
, parent
, name
, attrs
)
486 if (parent
!= null && parent
!= RootContext
.Tree
.Types
&& parent
.NamespaceEntry
!= ns
)
487 throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
490 this.PartialContainer
= this;
493 public bool AddToMemberContainer (MemberCore symbol
)
495 return AddToContainer (symbol
, symbol
.MemberName
.MethodName
);
498 protected virtual bool AddToTypeContainer (DeclSpace ds
)
500 return AddToContainer (ds
, ds
.Basename
);
503 public void AddConstant (Const constant
)
505 if (!AddToMemberContainer (constant
))
508 if (constants
== null)
509 constants
= new MemberCoreArrayList ();
511 constants
.Add (constant
);
514 public void AddEnum (Mono
.CSharp
.Enum e
)
516 if (!AddToTypeContainer (e
))
520 enums
= new MemberCoreArrayList ();
525 public bool AddClassOrStruct (TypeContainer c
)
527 if (!AddToTypeContainer (c
))
531 types
= new ArrayList (2);
533 RootContext
.Tree
.RecordDecl (c
.NamespaceEntry
.NS
, c
.MemberName
, c
);
538 public virtual TypeContainer
AddPartial (TypeContainer nextPart
)
540 return AddPartial (nextPart
, nextPart
.Basename
);
543 protected TypeContainer
AddPartial (TypeContainer nextPart
, string name
)
545 nextPart
.ModFlags
|= Modifiers
.PARTIAL
;
546 TypeContainer tc
= defined_names
[name
] as TypeContainer
;
549 if (nextPart
is Interface
)
550 AddInterface (nextPart
);
552 AddClassOrStruct (nextPart
);
556 if ((tc
.ModFlags
& Modifiers
.PARTIAL
) == 0) {
557 Report
.SymbolRelatedToPreviousError (tc
);
558 Error_MissingPartialModifier (nextPart
);
562 if (tc
.Kind
!= nextPart
.Kind
) {
563 Report
.SymbolRelatedToPreviousError (tc
);
564 Report
.Error (261, nextPart
.Location
,
565 "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
566 nextPart
.GetSignatureForError ());
570 if ((tc
.ModFlags
& Modifiers
.Accessibility
) != (nextPart
.ModFlags
& Modifiers
.Accessibility
) &&
571 ((tc
.ModFlags
& Modifiers
.DEFAULT_ACCESS_MODIFER
) == 0 &&
572 (nextPart
.ModFlags
& Modifiers
.DEFAULT_ACCESS_MODIFER
) == 0)) {
573 Report
.SymbolRelatedToPreviousError (tc
);
574 Report
.Error (262, nextPart
.Location
,
575 "Partial declarations of `{0}' have conflicting accessibility modifiers",
576 nextPart
.GetSignatureForError ());
580 if (tc
.partial_parts
== null)
581 tc
.partial_parts
= new ArrayList (1);
583 tc
.ModFlags
|= nextPart
.ModFlags
;
584 if (nextPart
.attributes
!= null) {
585 if (tc
.attributes
== null)
586 tc
.attributes
= nextPart
.attributes
;
588 tc
.attributes
.AddAttributes (nextPart
.attributes
.Attrs
);
591 nextPart
.PartialContainer
= tc
;
592 tc
.partial_parts
.Add (nextPart
);
596 public void AddDelegate (Delegate d
)
598 if (!AddToTypeContainer (d
))
601 if (delegates
== null)
602 delegates
= new MemberCoreArrayList ();
607 public void AddMethod (Method method
)
609 if (!AddToMemberContainer (method
))
613 methods
= new MethodArrayList (this);
615 if (method
.MemberName
.Left
!= null)
616 methods
.Insert (0, method
);
618 methods
.Add (method
);
622 // Do not use this method: use AddMethod.
624 // This is only used by iterators.
626 public void AppendMethod (Method method
)
628 if (!AddToMemberContainer (method
))
632 methods
= new MethodArrayList (this);
634 methods
.Add (method
);
637 public void AddConstructor (Constructor c
)
639 if (c
.Name
!= MemberName
.Name
) {
640 Report
.Error (1520, c
.Location
, "Class, struct, or interface method must have a return type");
643 bool is_static
= (c
.ModFlags
& Modifiers
.STATIC
) != 0;
646 if (default_static_constructor
!= null) {
647 Report
.SymbolRelatedToPreviousError (default_static_constructor
);
648 Report
.Error (111, c
.Location
, Error111
, c
.GetSignatureForError ());
652 default_static_constructor
= c
;
654 if (c
.Parameters
.Empty
){
655 if (default_constructor
!= null) {
656 Report
.SymbolRelatedToPreviousError (default_constructor
);
657 Report
.Error (111, c
.Location
, Error111
, c
.GetSignatureForError ());
660 default_constructor
= c
;
663 if (instance_constructors
== null)
664 instance_constructors
= new MemberCoreArrayList ();
666 instance_constructors
.Add (c
);
670 internal static string Error111
{
672 return "`{0}' is already defined. Rename this member or use different parameter types";
676 public bool AddInterface (TypeContainer iface
)
678 if (!AddToTypeContainer (iface
))
681 if (interfaces
== null) {
682 interfaces
= new MemberCoreArrayList ();
685 RootContext
.Tree
.RecordDecl (iface
.NamespaceEntry
.NS
, iface
.MemberName
, iface
);
686 interfaces
.Add (iface
);
690 public void AddField (FieldMember field
)
692 if (!AddToMemberContainer (field
))
696 fields
= new MemberCoreArrayList ();
700 if ((field
.ModFlags
& Modifiers
.STATIC
) != 0)
703 if (first_nonstatic_field
== null) {
704 first_nonstatic_field
= field
;
708 if (Kind
== Kind
.Struct
&&
709 first_nonstatic_field
.Parent
!= field
.Parent
&&
710 RootContext
.WarningLevel
>= 3) {
711 Report
.SymbolRelatedToPreviousError (first_nonstatic_field
.Parent
);
712 Report
.Warning (282, 3, field
.Location
,
713 "struct instance field `{0}' found in different declaration from instance field `{1}'",
714 field
.GetSignatureForError (), first_nonstatic_field
.GetSignatureForError ());
718 public void AddProperty (Property prop
)
720 if (!AddToMemberContainer (prop
) ||
721 !AddToMemberContainer (prop
.Get
) || !AddToMemberContainer (prop
.Set
))
724 if (properties
== null)
725 properties
= new MemberCoreArrayList ();
727 if (prop
.MemberName
.Left
!= null)
728 properties
.Insert (0, prop
);
730 properties
.Add (prop
);
733 public void AddEvent (Event e
)
735 if (!AddToMemberContainer (e
))
738 if (e
is EventProperty
) {
739 if (!AddToMemberContainer (e
.Add
))
742 if (!AddToMemberContainer (e
.Remove
))
747 events
= new MemberCoreArrayList ();
753 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
755 public void AddIndexer (Indexer i
)
757 if (indexers
== null)
758 indexers
= new IndexerArrayList (this);
760 if (i
.IsExplicitImpl
)
761 indexers
.Insert (0, i
);
766 public void AddOperator (Operator op
)
768 if (!AddToMemberContainer (op
))
771 if (operators
== null)
772 operators
= new OperatorArrayList (this);
777 public void AddIterator (Iterator i
)
779 if (iterators
== null)
780 iterators
= new ArrayList ();
785 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
787 if (a
.Type
== TypeManager
.default_member_type
) {
788 if (Indexers
!= null) {
789 Report
.Error (646, a
.Location
, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
794 base.ApplyAttributeBuilder (a
, cb
);
797 public override AttributeTargets AttributeTargets
{
799 throw new NotSupportedException ();
803 public ArrayList Types
{
809 public MethodArrayList Methods
{
815 public ArrayList Constants
{
821 public ArrayList Interfaces
{
827 public ArrayList Iterators
{
833 protected Type BaseType
{
835 return TypeBuilder
.BaseType
;
839 public ArrayList Bases
{
849 public ArrayList Fields
{
855 public ArrayList InstanceConstructors
{
857 return instance_constructors
;
861 public ArrayList Properties
{
867 public ArrayList Events
{
873 public ArrayList Enums
{
879 public ArrayList Indexers
{
885 public ArrayList Operators
{
891 public ArrayList Delegates
{
897 protected override TypeAttributes TypeAttr
{
899 return Modifiers
.TypeAttr (ModFlags
, IsTopLevel
) | base.TypeAttr
;
903 public string IndexerName
{
905 return indexers
== null ? DefaultIndexerName
: indexers
.IndexerName
;
909 public bool IsComImport
{
911 if (OptAttributes
== null)
914 return OptAttributes
.Contains (TypeManager
.comimport_attr_type
);
918 public virtual void RegisterFieldForInitialization (FieldBase field
)
920 if ((field
.ModFlags
& Modifiers
.STATIC
) != 0){
921 if (initialized_static_fields
== null)
922 initialized_static_fields
= new ArrayList (4);
924 initialized_static_fields
.Add (field
);
926 if (initialized_fields
== null)
927 initialized_fields
= new ArrayList (4);
929 initialized_fields
.Add (field
);
934 // Emits the instance field initializers
936 public bool EmitFieldInitializers (EmitContext ec
)
941 fields
= initialized_static_fields
;
943 fields
= initialized_fields
;
949 foreach (FieldBase f
in fields
) {
950 f
.EmitInitializer (ec
);
955 public override string DocComment
{
967 public PendingImplementation PendingImplementations
{
968 get { return pending; }
971 public override bool GetClsCompliantAttributeValue ()
973 if (PartialContainer
!= this)
974 return PartialContainer
.GetClsCompliantAttributeValue ();
976 return base.GetClsCompliantAttributeValue ();
979 TypeExpr
[] GetNormalBases (out TypeExpr base_class
)
985 int count
= Bases
.Count
;
988 if (Kind
== Kind
.Class
){
989 TypeExpr name
= ((Expression
) Bases
[0]).ResolveAsBaseTerminal (this, false);
995 if (!name
.IsInterface
) {
996 // base_class could be a class, struct, enum, delegate.
997 // This is validated in GetClassBases.
1003 TypeExpr
[] ifaces
= new TypeExpr
[count
-start
];
1005 for (i
= start
, j
= 0; i
< count
; i
++, j
++){
1006 TypeExpr resolved
= ((Expression
) Bases
[i
]).ResolveAsTypeTerminal (this, false);
1007 if (resolved
== null) {
1011 ifaces
[j
] = resolved
;
1014 return ifaces
.Length
== 0 ? null : ifaces
;
1018 TypeExpr
[] GetNormalPartialBases (ref TypeExpr base_class
)
1020 ArrayList ifaces
= new ArrayList (0);
1021 if (iface_exprs
!= null)
1022 ifaces
.AddRange (iface_exprs
);
1024 foreach (TypeContainer part
in partial_parts
) {
1025 TypeExpr new_base_class
;
1026 TypeExpr
[] new_ifaces
= part
.GetClassBases (out new_base_class
);
1027 if (new_base_class
!= TypeManager
.system_object_expr
) {
1028 if (base_class
== TypeManager
.system_object_expr
)
1029 base_class
= new_base_class
;
1031 if (new_base_class
!= null && !new_base_class
.Equals (base_class
)) {
1032 Report
.SymbolRelatedToPreviousError (base_class
.Location
, "");
1033 Report
.Error (263, part
.Location
,
1034 "Partial declarations of `{0}' must not specify different base classes",
1035 part
.GetSignatureForError ());
1042 if (new_ifaces
== null)
1045 foreach (TypeExpr iface
in new_ifaces
) {
1046 if (ifaces
.Contains (iface
))
1053 if (ifaces
.Count
== 0)
1056 return (TypeExpr
[])ifaces
.ToArray (typeof (TypeExpr
));
1060 /// This function computes the Base class and also the
1061 /// list of interfaces that the class or struct @c implements.
1063 /// The return value is an array (might be null) of
1064 /// interfaces implemented (as Types).
1066 /// The @base_class argument is set to the base object or null
1067 /// if this is `System.Object'.
1069 public virtual TypeExpr
[] GetClassBases (out TypeExpr base_class
)
1071 TypeExpr
[] ifaces
= GetNormalBases (out base_class
);
1076 int count
= ifaces
.Length
;
1078 for (int i
= 0; i
< count
; i
++) {
1079 TypeExpr iface
= (TypeExpr
) ifaces
[i
];
1081 if (!iface
.IsInterface
) {
1082 if (Kind
!= Kind
.Class
) {
1083 // TODO: location of symbol related ....
1084 Error_TypeInListIsNotInterface (Location
, iface
.FullName
);
1086 else if (base_class
!= null)
1087 Report
.Error (1721, Location
, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
1088 GetSignatureForError (), base_class
.GetSignatureForError (), iface
.GetSignatureForError ());
1090 Report
.Error (1722, Location
, "`{0}': Base class `{1}' must be specified as first",
1091 GetSignatureForError (), iface
.GetSignatureForError ());
1096 for (int x
= 0; x
< i
; x
++) {
1097 if (iface
.Equals (ifaces
[x
])) {
1098 Report
.Error (528, Location
,
1099 "`{0}' is already listed in " +
1100 "interface list", iface
.GetSignatureForError ());
1105 if ((Kind
== Kind
.Interface
) &&
1106 !iface
.AsAccessible (Parent
, ModFlags
)) {
1107 Report
.Error (61, Location
,
1108 "Inconsistent accessibility: base " +
1109 "interface `{0}' is less accessible " +
1110 "than interface `{1}'", iface
.Name
,
1118 bool CheckGenericInterfaces (Type
[] ifaces
)
1120 ArrayList already_checked
= new ArrayList ();
1122 for (int i
= 0; i
< ifaces
.Length
; i
++) {
1123 Type iface
= ifaces
[i
];
1124 foreach (Type t
in already_checked
) {
1128 Type
[] infered
= new Type
[CountTypeParameters
];
1129 if (!TypeManager
.MayBecomeEqualGenericInstances (iface
, t
, infered
, null))
1132 Report
.Error (695, Location
,
1133 "`{0}' cannot implement both `{1}' and `{2}' " +
1134 "because they may unify for some type parameter substitutions",
1135 TypeManager
.CSharpName (TypeBuilder
), TypeManager
.CSharpName (iface
),
1136 TypeManager
.CSharpName (t
));
1140 already_checked
.Add (iface
);
1148 protected void Error_TypeInListIsNotInterface (Location loc
, string type
)
1150 Report
.Error (527, loc
, "Type `{0}' in interface list is not an interface", type
);
1153 bool DefineTypeBuilder ()
1157 if (TypeManager
.NamespaceClash (Name
, Location
)) {
1161 ModuleBuilder builder
= CodeGen
.Module
.Builder
;
1162 Type default_parent
= null;
1163 if (Kind
== Kind
.Struct
)
1164 default_parent
= TypeManager
.value_type
;
1165 TypeBuilder
= builder
.DefineType (
1166 Name
, TypeAttr
, default_parent
, null);
1168 TypeBuilder builder
= Parent
.TypeBuilder
;
1170 TypeBuilder
= builder
.DefineNestedType (
1171 Basename
, TypeAttr
, null, null);
1173 } catch (ArgumentException
) {
1174 Report
.RuntimeMissingSupport (Location
, "static classes");
1178 TypeManager
.AddUserType (this);
1181 string[] param_names
= new string [TypeParameters
.Length
];
1182 for (int i
= 0; i
< TypeParameters
.Length
; i
++)
1183 param_names
[i
] = TypeParameters
[i
].Name
;
1185 gen_params
= TypeBuilder
.DefineGenericParameters (param_names
);
1187 int offset
= CountTypeParameters
- CurrentTypeParameters
.Length
;
1188 for (int i
= offset
; i
< gen_params
.Length
; i
++)
1189 CurrentTypeParameters
[i
- offset
].Define (gen_params
[i
]);
1192 iface_exprs
= GetClassBases (out base_type
);
1193 if (partial_parts
!= null) {
1194 iface_exprs
= GetNormalPartialBases (ref base_type
);
1198 // GetClassBases calls ResolveBaseTypeExpr() on the various type expressions involved,
1199 // which in turn should have called DefineType()s on base types if necessary.
1201 // None of the code below should trigger DefineType()s on classes that we depend on.
1202 // Thus, we are eligible to be on the topological sort `type_container_resolve_order'.
1204 // Let's do it as soon as possible, since code below can call DefineType() on classes
1205 // that depend on us to be populated before they are.
1207 if (!(this is Iterator
))
1208 RootContext
.RegisterOrder (this);
1210 if (base_type
!= null) {
1211 if (IsGeneric
&& TypeManager
.IsAttributeType (base_type
.Type
)) {
1212 Report
.Error (698, base_type
.Location
,
1213 "A generic type cannot derive from `{0}' " +
1214 "because it is an attribute class",
1219 TypeBuilder
.SetParent (base_type
.Type
);
1221 ObsoleteAttribute obsolete_attr
= AttributeTester
.GetObsoleteAttribute (base_type
.Type
);
1222 if (obsolete_attr
!= null && !IsInObsoleteScope
) {
1223 AttributeTester
.Report_ObsoleteMessage (obsolete_attr
, base_type
.GetSignatureForError (), Location
);
1227 if (!CheckRecursiveDefinition (this)) {
1231 // add interfaces that were not added at type creation
1232 if (iface_exprs
!= null) {
1233 ifaces
= TypeManager
.ExpandInterfaces (iface_exprs
);
1234 if (ifaces
== null) {
1238 foreach (Type itype
in ifaces
)
1239 TypeBuilder
.AddInterfaceImplementation (itype
);
1241 if (!CheckGenericInterfaces (ifaces
)) {
1245 TypeManager
.RegisterBuilder (TypeBuilder
, ifaces
);
1248 if (this is Iterator
&& !ResolveType ()) {
1256 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1258 public override TypeBuilder
DefineType ()
1260 if (TypeBuilder
!= null)
1266 if (!DefineTypeBuilder ()) {
1271 if (partial_parts
!= null) {
1272 foreach (TypeContainer part
in partial_parts
)
1273 part
.TypeBuilder
= TypeBuilder
;
1276 DefineNestedTypes ();
1281 Constraints
[] constraints
;
1282 public override void SetParameterInfo (ArrayList constraints_list
)
1284 if (PartialContainer
== this) {
1285 base.SetParameterInfo (constraints_list
);
1289 if (constraints_list
== null)
1292 constraints
= new Constraints
[PartialContainer
.CountCurrentTypeParameters
];
1294 TypeParameter
[] current_params
= PartialContainer
.CurrentTypeParameters
;
1295 for (int i
= 0; i
< constraints
.Length
; i
++) {
1296 foreach (Constraints constraint
in constraints_list
) {
1297 if (constraint
.TypeParameter
== current_params
[i
].Name
) {
1298 constraints
[i
] = constraint
;
1305 bool UpdateTypeParameterConstraints ()
1308 TypeParameter
[] current_params
= PartialContainer
.CurrentTypeParameters
;
1310 if (constraints
== null)
1313 for (int i
= 0; i
< current_params
.Length
; i
++) {
1314 if (!current_params
[i
].UpdateConstraints (this, constraints
[i
])) {
1315 Report
.Error (265, Location
, "Partial declarations of `{0}' have " +
1316 "inconsistent constraints for type parameter `{1}'.",
1317 MemberName
.GetTypeName (), current_params
[i
].Name
);
1325 public bool ResolveType ()
1327 if ((base_type
!= null) &&
1328 (base_type
.ResolveAsTypeTerminal (this, false) == null)) {
1336 if (PartialContainer
!= this)
1337 throw new InternalErrorException ();
1339 TypeExpr current_type
= null;
1341 foreach (TypeParameter type_param
in CurrentTypeParameters
) {
1342 if (!type_param
.Resolve (this)) {
1348 if (partial_parts
!= null) {
1349 foreach (TypeContainer part
in partial_parts
) {
1350 if (!part
.UpdateTypeParameterConstraints ()) {
1357 foreach (TypeParameter type_param
in TypeParameters
) {
1358 if (!type_param
.DefineType (this)) {
1364 current_type
= new ConstructedType (TypeBuilder
, TypeParameters
, Location
);
1366 foreach (TypeParameter type_param
in TypeParameters
)
1367 if (!type_param
.CheckDependencies ()) {
1372 if (current_type
!= null) {
1373 current_type
= current_type
.ResolveAsTypeTerminal (this, false);
1374 if (current_type
== null) {
1379 CurrentType
= current_type
.Type
;
1385 protected virtual bool DefineNestedTypes ()
1387 if (Interfaces
!= null) {
1388 foreach (TypeContainer iface
in Interfaces
)
1389 if (iface
.DefineType () == null)
1393 if (Types
!= null) {
1394 foreach (TypeContainer tc
in Types
)
1395 if (tc
.DefineType () == null)
1399 if (Delegates
!= null) {
1400 foreach (Delegate d
in Delegates
)
1401 if (d
.DefineType () == null)
1405 if (Enums
!= null) {
1406 foreach (Enum en
in Enums
)
1407 if (en
.DefineType () == null)
1414 TypeContainer InTransit
;
1416 protected bool CheckRecursiveDefinition (TypeContainer tc
)
1418 if (InTransit
!= null) {
1419 Report
.SymbolRelatedToPreviousError (this);
1420 if (this is Interface
)
1422 529, tc
.Location
, "Inherited interface `{0}' causes a " +
1423 "cycle in the interface hierarchy of `{1}'",
1424 GetSignatureForError (), tc
.GetSignatureForError ());
1427 146, tc
.Location
, "Circular base class dependency " +
1428 "involving `{0}' and `{1}'",
1429 tc
.GetSignatureForError (), GetSignatureForError ());
1435 if (BaseType
!= null) {
1436 Type t
= TypeManager
.DropGenericTypeArguments (BaseType
);
1437 TypeContainer ptc
= TypeManager
.LookupTypeContainer (t
);
1438 if ((ptc
!= null) && !ptc
.CheckRecursiveDefinition (this))
1442 if (iface_exprs
!= null) {
1443 foreach (TypeExpr iface
in iface_exprs
) {
1444 Type itype
= TypeManager
.DropGenericTypeArguments (iface
.Type
);
1445 TypeContainer ptc
= TypeManager
.LookupTypeContainer (itype
);
1446 if ((ptc
!= null) && !ptc
.CheckRecursiveDefinition (this))
1455 public static void Error_KeywordNotAllowed (Location loc
)
1457 Report
.Error (1530, loc
, "Keyword `new' is not allowed on namespace elements");
1461 /// Populates our TypeBuilder with fields and methods
1463 public override bool DefineMembers ()
1465 if (members_defined
)
1466 return members_defined_ok
;
1468 if (!base.DefineMembers ())
1471 members_defined_ok
= DoDefineMembers ();
1472 members_defined
= true;
1474 return members_defined_ok
;
1477 protected virtual bool DoDefineMembers ()
1479 if (iface_exprs
!= null) {
1480 foreach (TypeExpr iface
in iface_exprs
) {
1481 ConstructedType ct
= iface
as ConstructedType
;
1482 if ((ct
!= null) && !ct
.CheckConstraints (this))
1487 if (base_type
!= null) {
1488 ConstructedType ct
= base_type
as ConstructedType
;
1489 if ((ct
!= null) && !ct
.CheckConstraints (this))
1494 MemberInfo conflict_symbol
= Parent
.MemberCache
.FindMemberWithSameName (Basename
, false, TypeBuilder
);
1495 if (conflict_symbol
== null) {
1496 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0))
1497 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1499 if ((ModFlags
& Modifiers
.NEW
) == 0) {
1500 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
1501 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
1502 GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
1507 DefineContainerMembers (constants
);
1508 DefineContainerMembers (fields
);
1510 if (Kind
== Kind
.Struct
|| Kind
== Kind
.Class
) {
1511 pending
= PendingImplementation
.GetPendingImplementations (this);
1515 // Constructors are not in the defined_names array
1517 DefineContainerMembers (instance_constructors
);
1519 DefineContainerMembers (properties
);
1520 DefineContainerMembers (events
);
1521 DefineContainerMembers (indexers
);
1522 DefineContainerMembers (methods
);
1523 DefineContainerMembers (operators
);
1524 DefineContainerMembers (enums
);
1525 DefineContainerMembers (delegates
);
1527 if (CurrentType
!= null) {
1528 GenericType
= CurrentType
;
1533 member_cache
= new MemberCache (this);
1534 if (partial_parts
!= null) {
1535 foreach (TypeContainer part
in partial_parts
)
1536 part
.member_cache
= member_cache
;
1539 if (iterators
!= null) {
1540 foreach (Iterator iterator
in iterators
) {
1541 if (iterator
.DefineType () == null)
1545 foreach (Iterator iterator
in iterators
) {
1546 if (!iterator
.DefineMembers ())
1554 protected virtual void DefineContainerMembers (MemberCoreArrayList mcal
)
1557 mcal
.DefineContainerMembers ();
1560 public override bool Define ()
1562 if (iterators
!= null) {
1563 foreach (Iterator iterator
in iterators
) {
1564 if (!iterator
.Define ())
1572 public MemberInfo
FindBaseMemberWithSameName (string name
, bool ignore_methods
)
1574 return BaseCache
.FindMemberWithSameName (name
, ignore_methods
, null);
1578 /// This function is based by a delegate to the FindMembers routine
1580 static bool AlwaysAccept (MemberInfo m
, object filterCriteria
)
1586 /// This filter is used by FindMembers, and we just keep
1587 /// a global for the filter to `AlwaysAccept'
1589 static MemberFilter accepting_filter
;
1592 static TypeContainer ()
1594 accepting_filter
= new MemberFilter (AlwaysAccept
);
1597 public MethodInfo
[] GetMethods ()
1599 ArrayList members
= new ArrayList ();
1603 if (methods
!= null) {
1604 int len
= methods
.Count
;
1605 for (int i
= 0; i
< len
; i
++) {
1606 Method m
= (Method
) methods
[i
];
1608 members
.Add (m
.MethodBuilder
);
1612 if (operators
!= null) {
1613 int len
= operators
.Count
;
1614 for (int i
= 0; i
< len
; i
++) {
1615 Operator o
= (Operator
) operators
[i
];
1617 members
.Add (o
.MethodBuilder
);
1621 if (properties
!= null) {
1622 int len
= properties
.Count
;
1623 for (int i
= 0; i
< len
; i
++) {
1624 Property p
= (Property
) properties
[i
];
1626 if (p
.GetBuilder
!= null)
1627 members
.Add (p
.GetBuilder
);
1628 if (p
.SetBuilder
!= null)
1629 members
.Add (p
.SetBuilder
);
1633 if (indexers
!= null) {
1634 int len
= indexers
.Count
;
1635 for (int i
= 0; i
< len
; i
++) {
1636 Indexer ix
= (Indexer
) indexers
[i
];
1638 if (ix
.GetBuilder
!= null)
1639 members
.Add (ix
.GetBuilder
);
1640 if (ix
.SetBuilder
!= null)
1641 members
.Add (ix
.SetBuilder
);
1645 if (events
!= null) {
1646 int len
= events
.Count
;
1647 for (int i
= 0; i
< len
; i
++) {
1648 Event e
= (Event
) events
[i
];
1650 if (e
.AddBuilder
!= null)
1651 members
.Add (e
.AddBuilder
);
1652 if (e
.RemoveBuilder
!= null)
1653 members
.Add (e
.RemoveBuilder
);
1657 MethodInfo
[] retMethods
= new MethodInfo
[members
.Count
];
1658 members
.CopyTo (retMethods
, 0);
1662 // Indicated whether container has StructLayout attribute set Explicit
1663 public bool HasExplicitLayout
{
1665 return (caching_flags
& Flags
.HasExplicitLayout
) != 0;
1668 caching_flags
|= Flags
.HasExplicitLayout
;
1672 public override Type
FindNestedType (string name
)
1674 if (PartialContainer
!= this)
1675 return PartialContainer
.FindNestedType (name
);
1677 ArrayList
[] lists
= { types, enums, delegates, interfaces }
;
1679 for (int j
= 0; j
< lists
.Length
; ++j
) {
1680 ArrayList list
= lists
[j
];
1684 int len
= list
.Count
;
1685 for (int i
= 0; i
< len
; ++i
) {
1686 DeclSpace ds
= (DeclSpace
) list
[i
];
1687 if (ds
.Basename
== name
) {
1688 return ds
.DefineType ();
1696 private void FindMembers_NestedTypes (int modflags
,
1697 BindingFlags bf
, MemberFilter filter
, object criteria
,
1698 ref ArrayList members
)
1700 ArrayList
[] lists
= { types, enums, delegates, interfaces }
;
1702 for (int j
= 0; j
< lists
.Length
; ++j
) {
1703 ArrayList list
= lists
[j
];
1707 int len
= list
.Count
;
1708 for (int i
= 0; i
< len
; i
++) {
1709 DeclSpace ds
= (DeclSpace
) list
[i
];
1711 if ((ds
.ModFlags
& modflags
) == 0)
1714 TypeBuilder tb
= ds
.TypeBuilder
;
1716 if (!(criteria
is string) || ds
.Basename
.Equals (criteria
))
1717 tb
= ds
.DefineType ();
1720 if (tb
!= null && (filter (tb
, criteria
) == true)) {
1721 if (members
== null)
1722 members
= new ArrayList ();
1731 /// This method returns the members of this type just like Type.FindMembers would
1732 /// Only, we need to use this for types which are _being_ defined because MS'
1733 /// implementation can't take care of that.
1736 // FIXME: return an empty static array instead of null, that cleans up
1737 // some code and is consistent with some coding conventions I just found
1741 // Notice that in various cases we check if our field is non-null,
1742 // something that would normally mean that there was a bug elsewhere.
1744 // The problem happens while we are defining p-invoke methods, as those
1745 // will trigger a FindMembers, but this happens before things are defined
1747 // Since the whole process is a no-op, it is fine to check for null here.
1749 public override MemberList
FindMembers (MemberTypes mt
, BindingFlags bf
,
1750 MemberFilter filter
, object criteria
)
1752 ArrayList members
= null;
1755 if ((bf
& BindingFlags
.Public
) != 0)
1756 modflags
|= Modifiers
.PUBLIC
| Modifiers
.PROTECTED
|
1758 if ((bf
& BindingFlags
.NonPublic
) != 0)
1759 modflags
|= Modifiers
.PRIVATE
;
1761 int static_mask
= 0, static_flags
= 0;
1762 switch (bf
& (BindingFlags
.Static
| BindingFlags
.Instance
)) {
1763 case BindingFlags
.Static
:
1764 static_mask
= static_flags
= Modifiers
.STATIC
;
1767 case BindingFlags
.Instance
:
1768 static_mask
= Modifiers
.STATIC
;
1773 static_mask
= static_flags
= 0;
1777 Timer
.StartTimer (TimerType
.TcFindMembers
);
1780 filter
= accepting_filter
;
1782 if ((mt
& MemberTypes
.Field
) != 0) {
1783 if (fields
!= null) {
1784 int len
= fields
.Count
;
1785 for (int i
= 0; i
< len
; i
++) {
1786 FieldMember f
= (FieldMember
) fields
[i
];
1788 if ((f
.ModFlags
& modflags
) == 0)
1790 if ((f
.ModFlags
& static_mask
) != static_flags
)
1793 FieldBuilder fb
= f
.FieldBuilder
;
1794 if (fb
!= null && filter (fb
, criteria
) == true) {
1795 if (members
== null)
1796 members
= new ArrayList ();
1803 if (constants
!= null) {
1804 int len
= constants
.Count
;
1805 for (int i
= 0; i
< len
; i
++) {
1806 Const con
= (Const
) constants
[i
];
1808 if ((con
.ModFlags
& modflags
) == 0)
1810 if ((con
.ModFlags
& static_mask
) != static_flags
)
1813 FieldBuilder fb
= con
.FieldBuilder
;
1816 fb
= con
.FieldBuilder
;
1818 if (fb
!= null && filter (fb
, criteria
) == true) {
1819 if (members
== null)
1820 members
= new ArrayList ();
1828 if ((mt
& MemberTypes
.Method
) != 0) {
1829 if (methods
!= null) {
1830 int len
= methods
.Count
;
1831 for (int i
= 0; i
< len
; i
++) {
1832 Method m
= (Method
) methods
[i
];
1834 if ((m
.ModFlags
& modflags
) == 0)
1836 if ((m
.ModFlags
& static_mask
) != static_flags
)
1839 MethodBuilder mb
= m
.MethodBuilder
;
1841 if (mb
!= null && filter (mb
, criteria
) == true) {
1842 if (members
== null)
1843 members
= new ArrayList ();
1850 if (operators
!= null) {
1851 int len
= operators
.Count
;
1852 for (int i
= 0; i
< len
; i
++) {
1853 Operator o
= (Operator
) operators
[i
];
1855 if ((o
.ModFlags
& modflags
) == 0)
1857 if ((o
.ModFlags
& static_mask
) != static_flags
)
1860 MethodBuilder ob
= o
.MethodBuilder
;
1861 if (ob
!= null && filter (ob
, criteria
) == true) {
1862 if (members
== null)
1863 members
= new ArrayList ();
1870 if (properties
!= null) {
1871 int len
= properties
.Count
;
1872 for (int i
= 0; i
< len
; i
++) {
1873 Property p
= (Property
) properties
[i
];
1875 if ((p
.ModFlags
& modflags
) == 0)
1877 if ((p
.ModFlags
& static_mask
) != static_flags
)
1883 if (b
!= null && filter (b
, criteria
) == true) {
1884 if (members
== null)
1885 members
= new ArrayList ();
1891 if (b
!= null && filter (b
, criteria
) == true) {
1892 if (members
== null)
1893 members
= new ArrayList ();
1900 if (indexers
!= null) {
1901 int len
= indexers
.Count
;
1902 for (int i
= 0; i
< len
; i
++) {
1903 Indexer ix
= (Indexer
) indexers
[i
];
1905 if ((ix
.ModFlags
& modflags
) == 0)
1907 if ((ix
.ModFlags
& static_mask
) != static_flags
)
1913 if (b
!= null && filter (b
, criteria
) == true) {
1914 if (members
== null)
1915 members
= new ArrayList ();
1921 if (b
!= null && filter (b
, criteria
) == true) {
1922 if (members
== null)
1923 members
= new ArrayList ();
1931 if ((mt
& MemberTypes
.Event
) != 0) {
1932 if (events
!= null) {
1933 int len
= events
.Count
;
1934 for (int i
= 0; i
< len
; i
++) {
1935 Event e
= (Event
) events
[i
];
1937 if ((e
.ModFlags
& modflags
) == 0)
1939 if ((e
.ModFlags
& static_mask
) != static_flags
)
1942 MemberInfo eb
= e
.EventBuilder
;
1943 if (eb
!= null && filter (eb
, criteria
) == true) {
1944 if (members
== null)
1945 members
= new ArrayList ();
1947 members
.Add (e
.EventBuilder
);
1953 if ((mt
& MemberTypes
.Property
) != 0){
1954 if (properties
!= null) {
1955 int len
= properties
.Count
;
1956 for (int i
= 0; i
< len
; i
++) {
1957 Property p
= (Property
) properties
[i
];
1959 if ((p
.ModFlags
& modflags
) == 0)
1961 if ((p
.ModFlags
& static_mask
) != static_flags
)
1964 MemberInfo pb
= p
.PropertyBuilder
;
1965 if (pb
!= null && filter (pb
, criteria
) == true) {
1966 if (members
== null)
1967 members
= new ArrayList ();
1969 members
.Add (p
.PropertyBuilder
);
1974 if (indexers
!= null) {
1975 int len
= indexers
.Count
;
1976 for (int i
= 0; i
< len
; i
++) {
1977 Indexer ix
= (Indexer
) indexers
[i
];
1979 if ((ix
.ModFlags
& modflags
) == 0)
1981 if ((ix
.ModFlags
& static_mask
) != static_flags
)
1984 MemberInfo ib
= ix
.PropertyBuilder
;
1985 if (ib
!= null && filter (ib
, criteria
) == true) {
1986 if (members
== null)
1987 members
= new ArrayList ();
1989 members
.Add (ix
.PropertyBuilder
);
1995 if ((mt
& MemberTypes
.NestedType
) != 0)
1996 FindMembers_NestedTypes (modflags
, bf
, filter
, criteria
, ref members
);
1998 if ((mt
& MemberTypes
.Constructor
) != 0){
1999 if (((bf
& BindingFlags
.Instance
) != 0) && (instance_constructors
!= null)){
2000 int len
= instance_constructors
.Count
;
2001 for (int i
= 0; i
< len
; i
++) {
2002 Constructor c
= (Constructor
) instance_constructors
[i
];
2004 ConstructorBuilder cb
= c
.ConstructorBuilder
;
2005 if (cb
!= null && filter (cb
, criteria
) == true) {
2006 if (members
== null)
2007 members
= new ArrayList ();
2014 if (((bf
& BindingFlags
.Static
) != 0) && (default_static_constructor
!= null)){
2015 ConstructorBuilder cb
=
2016 default_static_constructor
.ConstructorBuilder
;
2018 if (cb
!= null && filter (cb
, criteria
) == true) {
2019 if (members
== null)
2020 members
= new ArrayList ();
2028 // Lookup members in base if requested.
2030 if ((bf
& BindingFlags
.DeclaredOnly
) == 0) {
2031 if (TypeBuilder
.BaseType
!= null) {
2032 MemberList list
= FindMembers (TypeBuilder
.BaseType
, mt
, bf
, filter
, criteria
);
2033 if (list
.Count
> 0) {
2034 if (members
== null)
2035 members
= new ArrayList ();
2037 members
.AddRange (list
);
2043 Timer
.StopTimer (TimerType
.TcFindMembers
);
2045 if (members
== null)
2046 return MemberList
.Empty
;
2048 return new MemberList (members
);
2051 public override MemberCache MemberCache
{
2053 return member_cache
;
2057 public static MemberList
FindMembers (Type t
, MemberTypes mt
, BindingFlags bf
,
2058 MemberFilter filter
, object criteria
)
2060 DeclSpace ds
= TypeManager
.LookupDeclSpace (t
);
2063 return ds
.FindMembers (mt
, bf
, filter
, criteria
);
2065 return new MemberList (t
.FindMembers (mt
, bf
, filter
, criteria
));
2069 /// Emits the values for the constants
2071 public void EmitConstants ()
2073 if (constants
!= null)
2074 foreach (Const con
in constants
)
2079 static void CheckMemberUsage (MemberCoreArrayList al
, string member_type
)
2084 foreach (MemberCore mc
in al
) {
2085 if ((mc
.ModFlags
& Modifiers
.Accessibility
) != Modifiers
.PRIVATE
)
2089 Report
.Warning (169, 3, mc
.Location
, "The private {0} `{1}' is never used", member_type
, mc
.GetSignatureForError ());
2094 public virtual void VerifyMembers ()
2097 // Check for internal or private fields that were never assigned
2099 if (RootContext
.WarningLevel
>= 3) {
2100 CheckMemberUsage (properties
, "property");
2101 CheckMemberUsage (methods
, "method");
2102 CheckMemberUsage (constants
, "constant");
2104 if (fields
!= null){
2105 foreach (FieldMember f
in fields
) {
2106 if ((f
.ModFlags
& Modifiers
.Accessibility
) != Modifiers
.PRIVATE
)
2110 if ((f
.caching_flags
& Flags
.IsAssigned
) == 0)
2111 Report
.Warning (169, 3, f
.Location
, "The private field `{0}' is never used", f
.GetSignatureForError ());
2114 const int error_code
= 414;
2116 const int error_code
= 169;
2118 Report
.Warning (error_code
, 3, f
.Location
, "The private field `{0}' is assigned but its value is never used",
2119 f
.GetSignatureForError ());
2125 // Only report 649 on level 4
2127 if (RootContext
.WarningLevel
< 4)
2130 if ((f
.caching_flags
& Flags
.IsAssigned
) != 0)
2133 Report
.Warning (649, 4, f
.Location
, "Field `{0}' is never assigned to, and will always have its default value `{1}'",
2134 f
.GetSignatureForError (), f
.Type
.Type
.IsValueType
? Activator
.CreateInstance (f
.Type
.Type
).ToString() : "null");
2140 // TODO: move to ClassOrStruct
2141 void EmitConstructors ()
2143 if (instance_constructors
== null)
2146 if (TypeBuilder
.IsSubclassOf (TypeManager
.attribute_type
) && RootContext
.VerifyClsCompliance
&& IsClsComplianceRequired ()) {
2147 bool has_compliant_args
= false;
2149 foreach (Constructor c
in instance_constructors
) {
2152 if (has_compliant_args
)
2155 has_compliant_args
= c
.HasCompliantArgs
;
2157 if (!has_compliant_args
)
2158 Report
.Error (3015, Location
, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2160 foreach (Constructor c
in instance_constructors
)
2166 /// Emits the code, this step is performed after all
2167 /// the types, enumerations, constructors
2169 public virtual void EmitType ()
2171 if (OptAttributes
!= null)
2172 OptAttributes
.Emit ();
2175 int offset
= CountTypeParameters
- CurrentTypeParameters
.Length
;
2176 for (int i
= offset
; i
< gen_params
.Length
; i
++)
2177 CurrentTypeParameters
[i
- offset
].EmitAttributes ();
2181 // Structs with no fields need to have at least one byte.
2182 // The right thing would be to set the PackingSize in a DefineType
2183 // but there are no functions that allow interfaces *and* the size to
2187 if (Kind
== Kind
.Struct
&& first_nonstatic_field
== null){
2188 FieldBuilder fb
= TypeBuilder
.DefineField ("$PRIVATE$", TypeManager
.byte_type
,
2189 FieldAttributes
.Private
);
2191 if (HasExplicitLayout
){
2192 object [] ctor_args
= new object [1];
2195 CustomAttributeBuilder cba
= new CustomAttributeBuilder (
2196 TypeManager
.field_offset_attribute_ctor
, ctor_args
);
2197 fb
.SetCustomAttribute (cba
);
2203 EmitConstructors ();
2205 // Can not continue if constants are broken
2207 if (Report
.Errors
> 0)
2210 if (default_static_constructor
!= null)
2211 default_static_constructor
.Emit ();
2213 if (methods
!= null){
2214 foreach (Method m
in methods
)
2218 if (operators
!= null)
2219 foreach (Operator o
in operators
)
2222 if (properties
!= null)
2223 foreach (Property p
in properties
)
2226 if (indexers
!= null){
2231 foreach (FieldMember f
in fields
)
2234 if (events
!= null){
2235 foreach (Event e
in Events
)
2239 if (delegates
!= null) {
2240 foreach (Delegate d
in Delegates
) {
2245 if (enums
!= null) {
2246 foreach (Enum e
in enums
) {
2251 if (pending
!= null)
2252 if (pending
.VerifyPendingMethods ())
2255 if (iterators
!= null)
2256 foreach (Iterator iterator
in iterators
)
2257 iterator
.EmitType ();
2260 public override void CloseType ()
2262 if ((caching_flags
& Flags
.CloseTypeCreated
) != 0)
2266 caching_flags
|= Flags
.CloseTypeCreated
;
2267 TypeBuilder
.CreateType ();
2268 } catch (TypeLoadException
){
2270 // This is fine, the code still created the type
2272 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2273 // Console.WriteLine (e.Message);
2275 Console
.WriteLine ("In type: " + Name
);
2280 foreach (Enum en
in Enums
)
2284 foreach (TypeContainer tc
in Types
)
2285 if (tc
.Kind
== Kind
.Struct
)
2288 foreach (TypeContainer tc
in Types
)
2289 if (tc
.Kind
!= Kind
.Struct
)
2293 if (Delegates
!= null)
2294 foreach (Delegate d
in Delegates
)
2297 if (Iterators
!= null)
2298 foreach (Iterator i
in Iterators
)
2306 initialized_fields
= null;
2307 initialized_static_fields
= null;
2315 default_constructor
= null;
2316 default_static_constructor
= null;
2318 OptAttributes
= null;
2321 member_cache
= null;
2325 // Performs the validation on a Method's modifiers (properties have
2326 // the same properties).
2328 public bool MethodModifiersValid (MemberCore mc
)
2330 const int vao
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
| Modifiers
.OVERRIDE
);
2331 const int va
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
);
2332 const int nv
= (Modifiers
.NEW
| Modifiers
.VIRTUAL
);
2334 int flags
= mc
.ModFlags
;
2337 // At most one of static, virtual or override
2339 if ((flags
& Modifiers
.STATIC
) != 0){
2340 if ((flags
& vao
) != 0){
2341 Report
.Error (112, mc
.Location
, "A static member `{0}' cannot be marked as override, virtual or abstract",
2342 mc
.GetSignatureForError ());
2347 if (Kind
== Kind
.Struct
){
2348 if ((flags
& va
) != 0){
2349 Modifiers
.Error_InvalidModifier (mc
.Location
, "virtual or abstract");
2354 if ((flags
& Modifiers
.OVERRIDE
) != 0 && (flags
& nv
) != 0){
2355 Report
.Error (113, mc
.Location
, "A member `{0}' marked as override cannot be marked as new or virtual",
2356 mc
.GetSignatureForError ());
2361 // If the declaration includes the abstract modifier, then the
2362 // declaration does not include static, virtual or extern
2364 if ((flags
& Modifiers
.ABSTRACT
) != 0){
2365 if ((flags
& Modifiers
.EXTERN
) != 0){
2367 180, mc
.Location
, "`{0}' cannot be both extern and abstract", mc
.GetSignatureForError ());
2371 if ((flags
& Modifiers
.SEALED
) != 0) {
2372 Report
.Error (502, mc
.Location
, "`{0}' cannot be both abstract and sealed", mc
.GetSignatureForError ());
2376 if ((flags
& Modifiers
.VIRTUAL
) != 0){
2377 Report
.Error (503, mc
.Location
, "The abstract method `{0}' cannot be marked virtual", mc
.GetSignatureForError ());
2381 if ((ModFlags
& Modifiers
.ABSTRACT
) == 0){
2382 Report
.Error (513, mc
.Location
, "`{0}' is abstract but it is contained in nonabstract class", mc
.GetSignatureForError ());
2387 if ((flags
& Modifiers
.PRIVATE
) != 0){
2388 if ((flags
& vao
) != 0){
2389 Report
.Error (621, mc
.Location
, "`{0}': virtual or abstract members cannot be private", mc
.GetSignatureForError ());
2394 if ((flags
& Modifiers
.SEALED
) != 0){
2395 if ((flags
& Modifiers
.OVERRIDE
) == 0){
2396 Report
.Error (238, mc
.Location
, "`{0}' cannot be sealed because it is not an override", mc
.GetSignatureForError ());
2404 public Constructor DefaultStaticConstructor
{
2405 get { return default_static_constructor; }
2408 protected override bool VerifyClsCompliance ()
2410 if (!base.VerifyClsCompliance ())
2415 Type base_type
= TypeBuilder
.BaseType
;
2416 if (base_type
!= null && !AttributeTester
.IsClsCompliant (base_type
)) {
2417 Report
.Error (3009, Location
, "`{0}': base type `{1}' is not CLS-compliant", GetSignatureForError (), TypeManager
.CSharpName (base_type
));
2420 if (!Parent
.IsClsComplianceRequired ()) {
2421 Report
.Error (3018, Location
, "`{0}' cannot be marked as CLS-compliant because it is a member of non CLS-compliant type `{1}'",
2422 GetSignatureForError (), Parent
.GetSignatureForError ());
2429 /// Checks whether container name is CLS Compliant
2431 void VerifyClsName ()
2433 Hashtable base_members
= base_cache
== null ?
2435 base_cache
.GetPublicMembers ();
2436 Hashtable this_members
= new Hashtable ();
2438 foreach (DictionaryEntry entry
in defined_names
) {
2439 MemberCore mc
= (MemberCore
)entry
.Value
;
2440 if (!mc
.IsClsComplianceRequired ())
2443 string name
= (string) entry
.Key
;
2444 string basename
= name
.Substring (name
.LastIndexOf ('.') + 1);
2446 string lcase
= basename
.ToLower (System
.Globalization
.CultureInfo
.InvariantCulture
);
2447 object found
= base_members
[lcase
];
2448 if (found
== null) {
2449 found
= this_members
[lcase
];
2450 if (found
== null) {
2451 this_members
.Add (lcase
, mc
);
2456 if ((mc
.ModFlags
& Modifiers
.OVERRIDE
) != 0)
2459 if (found
is MemberInfo
) {
2460 if (basename
== ((MemberInfo
) found
).Name
)
2462 Report
.SymbolRelatedToPreviousError ((MemberInfo
) found
);
2464 Report
.SymbolRelatedToPreviousError ((MemberCore
) found
);
2466 Report
.Warning (3005, 1, mc
.Location
, "Identifier `{0}' differing only in case is not CLS-compliant", mc
.GetSignatureForError ());
2472 /// Performs checks for an explicit interface implementation. First it
2473 /// checks whether the `interface_type' is a base inteface implementation.
2474 /// Then it checks whether `name' exists in the interface type.
2476 public virtual bool VerifyImplements (MemberBase mb
)
2478 if (ifaces
!= null) {
2479 foreach (Type t
in ifaces
){
2480 if (t
== mb
.InterfaceType
)
2485 Report
.SymbolRelatedToPreviousError (mb
.InterfaceType
);
2486 Report
.Error (540, mb
.Location
, "`{0}': containing type does not implement interface `{1}'",
2487 mb
.GetSignatureForError (), TypeManager
.CSharpName (mb
.InterfaceType
));
2491 public void Mark_HasEquals ()
2493 Methods
.HasEquals
= true;
2496 public void Mark_HasGetHashCode ()
2498 Methods
.HasGetHashCode
= true;
2505 string IMemberContainer
.Name
{
2511 Type IMemberContainer
.Type
{
2517 MemberCache IMemberContainer
.MemberCache
{
2519 return member_cache
;
2523 bool IMemberContainer
.IsInterface
{
2525 return Kind
== Kind
.Interface
;
2529 MemberList IMemberContainer
.GetMembers (MemberTypes mt
, BindingFlags bf
)
2531 BindingFlags new_bf
= bf
| BindingFlags
.DeclaredOnly
;
2533 if (GenericType
!= null)
2534 return TypeManager
.FindMembers (GenericType
, mt
, new_bf
,
2537 return FindMembers (mt
, new_bf
, null, null);
2541 // Generates xml doc comments (if any), and if required,
2542 // handle warning report.
2544 internal override void GenerateDocComment (DeclSpace ds
)
2546 DocUtil
.GenerateTypeDocComment (this, ds
);
2549 public override string DocCommentHeader
{
2550 get { return "T:"; }
2553 public virtual MemberCache BaseCache
{
2555 if (base_cache
!= null)
2557 if (TypeBuilder
.BaseType
!= null)
2558 base_cache
= TypeManager
.LookupMemberCache (TypeBuilder
.BaseType
);
2559 if (TypeBuilder
.IsInterface
)
2560 base_cache
= TypeManager
.LookupBaseInterfacesCache (TypeBuilder
);
2567 public abstract class ClassOrStruct
: TypeContainer
{
2568 ListDictionary declarative_security
;
2570 public ClassOrStruct (NamespaceEntry ns
, DeclSpace parent
,
2571 MemberName name
, Attributes attrs
, Kind kind
)
2572 : base (ns
, parent
, name
, attrs
, kind
)
2576 protected override bool AddToContainer (MemberCore symbol
, string name
)
2578 if (name
== MemberName
.Name
) {
2579 if (symbol
is TypeParameter
) {
2580 Report
.Error (694, symbol
.Location
,
2581 "Type parameter `{0}' has same name as " +
2582 "containing type, or method", name
);
2586 Report
.SymbolRelatedToPreviousError (this);
2587 Report
.Error (542, symbol
.Location
, "`{0}': member names cannot be the same as their enclosing type",
2588 symbol
.GetSignatureForError ());
2592 return base.AddToContainer (symbol
, name
);
2595 public override void VerifyMembers ()
2597 base.VerifyMembers ();
2599 if ((events
!= null) && (RootContext
.WarningLevel
>= 3)) {
2600 foreach (Event e
in events
){
2601 if ((e
.caching_flags
& Flags
.IsAssigned
) == 0)
2602 Report
.Warning (67, 3, e
.Location
, "The event `{0}' is never used", e
.GetSignatureForError ());
2607 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
2609 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
2610 if (declarative_security
== null)
2611 declarative_security
= new ListDictionary ();
2613 a
.ExtractSecurityPermissionSet (declarative_security
);
2617 if (a
.Type
== TypeManager
.struct_layout_attribute_type
&& a
.GetLayoutKindValue () == LayoutKind
.Explicit
) {
2618 HasExplicitLayout
= true;
2621 base.ApplyAttributeBuilder (a
, cb
);
2625 /// Defines the default constructors
2627 protected void DefineDefaultConstructor (bool is_static
)
2629 // The default instance constructor is public
2630 // If the class is abstract, the default constructor is protected
2631 // The default static constructor is private
2635 mods
= Modifiers
.STATIC
| Modifiers
.PRIVATE
;
2637 mods
= ((ModFlags
& Modifiers
.ABSTRACT
) != 0) ? Modifiers
.PROTECTED
: Modifiers
.PUBLIC
;
2640 Constructor c
= new Constructor (this, MemberName
.Name
, mods
,
2641 Parameters
.EmptyReadOnlyParameters
,
2642 new GeneratedBaseInitializer (Location
),
2646 c
.Block
= new ToplevelBlock (null, Location
);
2649 void DefineFieldInitializers ()
2651 if (initialized_fields
!= null) {
2652 for (int i
= 0; i
< initialized_fields
.Count
; ++i
) {
2653 FieldBase fb
= (FieldBase
)initialized_fields
[i
];
2654 fb
.ResolveInitializer ();
2655 if (fb
.HasDefaultInitializer
&& RootContext
.Optimize
) {
2656 // Field is re-initialized to its default value => removed
2657 initialized_fields
.RemoveAt (i
);
2663 if (initialized_static_fields
!= null) {
2664 bool has_complex_initializer
= false;
2666 foreach (FieldBase fb
in initialized_static_fields
) {
2667 if (fb
.ResolveInitializer () is Constant
)
2670 has_complex_initializer
= true;
2673 // Need special check to not optimize code like this
2674 // static int a = b = 5;
2675 // static int b = 0;
2676 if (!has_complex_initializer
&& RootContext
.Optimize
) {
2677 for (int i
= 0; i
< initialized_static_fields
.Count
; ++i
) {
2678 FieldBase fb
= (FieldBase
)initialized_static_fields
[i
];
2679 if (fb
.HasDefaultInitializer
) {
2680 initialized_static_fields
.RemoveAt (i
);
2686 if (default_static_constructor
== null && initialized_static_fields
.Count
> 0) {
2687 DefineDefaultConstructor (true);
2693 public override bool Define ()
2695 DefineFieldInitializers ();
2697 if (default_static_constructor
!= null)
2698 default_static_constructor
.Define ();
2700 return base.Define ();
2703 public override void Emit ()
2707 if (declarative_security
!= null) {
2708 foreach (DictionaryEntry de
in declarative_security
) {
2709 TypeBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
2714 protected override TypeAttributes TypeAttr
{
2716 if (default_static_constructor
== null)
2717 return base.TypeAttr
| TypeAttributes
.BeforeFieldInit
;
2719 return base.TypeAttr
;
2725 // TODO: should be sealed
2726 public class Class
: ClassOrStruct
{
2727 const int AllowedModifiers
=
2730 Modifiers
.PROTECTED
|
2731 Modifiers
.INTERNAL
|
2733 Modifiers
.ABSTRACT
|
2738 public Class (NamespaceEntry ns
, DeclSpace parent
, MemberName name
, int mod
,
2740 : base (ns
, parent
, name
, attrs
, Kind
.Class
)
2742 int accmods
= Parent
.Parent
== null ? Modifiers
.INTERNAL
: Modifiers
.PRIVATE
;
2743 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, Location
);
2745 if (IsStatic
&& RootContext
.Version
== LanguageVersion
.ISO_1
) {
2746 Report
.FeatureIsNotStandardized (Location
, "static classes");
2750 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
2752 if (a
.Type
== TypeManager
.attribute_usage_type
) {
2753 if (BaseType
!= TypeManager
.attribute_type
&& !BaseType
.IsSubclassOf (TypeManager
.attribute_type
) &&
2754 TypeBuilder
.FullName
!= "System.Attribute") {
2755 Report
.Error (641, a
.Location
, "Attribute `{0}' is only valid on classes derived from System.Attribute", a
.GetSignatureForError ());
2759 if (a
.Type
== TypeManager
.conditional_attribute_type
&&
2760 !(BaseType
== TypeManager
.attribute_type
|| BaseType
.IsSubclassOf (TypeManager
.attribute_type
))) {
2761 Report
.Error (1689, a
.Location
, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2765 if (a
.Type
== TypeManager
.comimport_attr_type
&&
2766 !attributes
.Contains (TypeManager
.guid_attr_type
)) {
2767 a
.Error_MissingGuidAttribute ();
2771 if (AttributeTester
.IsAttributeExcluded (a
.Type
))
2774 base.ApplyAttributeBuilder (a
, cb
);
2777 public override AttributeTargets AttributeTargets
{
2779 return AttributeTargets
.Class
;
2783 protected override void DefineContainerMembers (MemberCoreArrayList list
)
2789 base.DefineContainerMembers (list
);
2793 foreach (MemberCore m
in list
) {
2794 if (m
is Operator
) {
2795 Report
.Error (715, m
.Location
, "`{0}': Static classes cannot contain user-defined operators", m
.GetSignatureForError ());
2799 if (m
is Destructor
) {
2800 Report
.Error (711, m
.Location
, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2804 if ((m
.ModFlags
& Modifiers
.PROTECTED
) != 0) {
2805 Report
.Error (1057, m
.Location
, "`{0}': Static classes cannot contain protected members", m
.GetSignatureForError ());
2810 Report
.Error (720, m
.Location
, "`{0}': cannot declare indexers in a static class", m
.GetSignatureForError ());
2814 if ((m
.ModFlags
& Modifiers
.STATIC
) != 0 || m
is Enum
|| m
is Delegate
)
2817 if (m
is Constructor
) {
2818 Report
.Error (710, m
.Location
, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2822 Report
.Error (708, m
.Location
, "`{0}': cannot declare instance members in a static class", m
.GetSignatureForError ());
2825 base.DefineContainerMembers (list
);
2828 public override TypeBuilder
DefineType ()
2830 if ((ModFlags
& Modifiers
.ABSTRACT
) == Modifiers
.ABSTRACT
&& (ModFlags
& (Modifiers
.SEALED
| Modifiers
.STATIC
)) != 0) {
2831 Report
.Error (418, Location
, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
2835 if ((ModFlags
& (Modifiers
.SEALED
| Modifiers
.STATIC
)) == (Modifiers
.SEALED
| Modifiers
.STATIC
)) {
2836 Report
.Error (441, Location
, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
2840 return base.DefineType ();
2843 protected override bool DoDefineMembers ()
2845 if (InstanceConstructors
== null && !IsStatic
)
2846 DefineDefaultConstructor (false);
2848 return base.DoDefineMembers ();
2851 public override TypeExpr
[] GetClassBases (out TypeExpr base_class
)
2853 TypeExpr
[] ifaces
= base.GetClassBases (out base_class
);
2855 if (base_class
== null) {
2856 if (RootContext
.StdLib
)
2857 base_class
= TypeManager
.system_object_expr
;
2858 else if (Name
!= "System.Object")
2859 base_class
= TypeManager
.system_object_expr
;
2861 if (Kind
== Kind
.Class
&& base_class
is TypeParameterExpr
){
2863 689, base_class
.Location
,
2864 "Cannot derive from `{0}' because it is a type parameter",
2865 base_class
.GetSignatureForError ());
2869 if (base_class
.Type
.IsArray
|| base_class
.Type
.IsPointer
) {
2870 Report
.Error (1521, base_class
.Location
, "Invalid base type");
2874 if (base_class
.IsSealed
){
2875 Report
.SymbolRelatedToPreviousError (base_class
.Type
);
2876 if (base_class
.Type
.IsAbstract
) {
2877 Report
.Error (709, Location
, "`{0}': Cannot derive from static class `{1}'",
2878 GetSignatureForError (), TypeManager
.CSharpName (base_class
.Type
));
2880 Report
.Error (509, Location
, "`{0}': cannot derive from sealed class `{1}'",
2881 GetSignatureForError (), TypeManager
.CSharpName (base_class
.Type
));
2886 if (!base_class
.CanInheritFrom ()){
2887 Report
.Error (644, Location
, "`{0}' cannot derive from special class `{1}'",
2888 GetSignatureForError (), base_class
.GetSignatureForError ());
2892 if (!base_class
.AsAccessible (this, ModFlags
)) {
2893 Report
.SymbolRelatedToPreviousError (base_class
.Type
);
2894 Report
.Error (60, Location
, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
2895 TypeManager
.CSharpName (base_class
.Type
), GetSignatureForError ());
2900 if (base_class
!= TypeManager
.system_object_expr
) {
2901 Report
.Error (713, Location
, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
2902 GetSignatureForError (), base_class
.GetSignatureForError ());
2906 if (ifaces
!= null) {
2907 foreach (TypeExpr t
in ifaces
)
2908 Report
.SymbolRelatedToPreviousError (t
.Type
);
2909 Report
.Error (714, Location
, "`{0}': static classes cannot implement interfaces", GetSignatureForError ());
2916 /// Search for at least one defined condition in ConditionalAttribute of attribute class
2917 /// Valid only for attribute classes.
2918 public bool IsExcluded ()
2920 if ((caching_flags
& Flags
.Excluded_Undetected
) == 0)
2921 return (caching_flags
& Flags
.Excluded
) != 0;
2923 caching_flags
&= ~Flags
.Excluded_Undetected
;
2925 if (OptAttributes
== null)
2928 Attribute
[] attrs
= OptAttributes
.SearchMulti (TypeManager
.conditional_attribute_type
);
2933 foreach (Attribute a
in attrs
) {
2934 string condition
= a
.GetConditionalAttributeValue ();
2935 if (RootContext
.AllDefines
.Contains (condition
))
2939 caching_flags
|= Flags
.Excluded
;
2945 return (ModFlags
& Modifiers
.STATIC
) != 0;
2950 // FIXME: How do we deal with the user specifying a different
2953 protected override TypeAttributes TypeAttr
{
2955 TypeAttributes ta
= base.TypeAttr
| TypeAttributes
.AutoLayout
| TypeAttributes
.Class
;
2957 ta
|= TypeAttributes
.Abstract
| TypeAttributes
.Sealed
;
2963 public sealed class Struct
: ClassOrStruct
{
2965 // Modifiers allowed in a struct declaration
2967 const int AllowedModifiers
=
2970 Modifiers
.PROTECTED
|
2971 Modifiers
.INTERNAL
|
2975 public Struct (NamespaceEntry ns
, DeclSpace parent
, MemberName name
,
2976 int mod
, Attributes attrs
)
2977 : base (ns
, parent
, name
, attrs
, Kind
.Struct
)
2981 if (parent
.Parent
== null)
2982 accmods
= Modifiers
.INTERNAL
;
2984 accmods
= Modifiers
.PRIVATE
;
2986 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, Location
);
2988 this.ModFlags
|= Modifiers
.SEALED
;
2991 public override AttributeTargets AttributeTargets
{
2993 return AttributeTargets
.Struct
;
2997 const TypeAttributes DefaultTypeAttributes
=
2998 TypeAttributes
.SequentialLayout
|
2999 TypeAttributes
.Sealed
|
3000 TypeAttributes
.BeforeFieldInit
;
3003 public override TypeExpr
[] GetClassBases (out TypeExpr base_class
)
3005 TypeExpr
[] ifaces
= base.GetClassBases (out base_class
);
3007 // If we are compiling our runtime,
3008 // and we are defining ValueType, then our
3009 // base is `System.Object'.
3011 if (base_class
== null) {
3012 if (!RootContext
.StdLib
&& Name
== "System.ValueType")
3013 base_class
= TypeManager
.system_object_expr
;
3015 base_class
= TypeManager
.system_valuetype_expr
;
3022 // FIXME: Allow the user to specify a different set of attributes
3023 // in some cases (Sealed for example is mandatory for a class,
3024 // but what SequentialLayout can be changed
3026 protected override TypeAttributes TypeAttr
{
3028 return base.TypeAttr
| DefaultTypeAttributes
;
3032 public override void RegisterFieldForInitialization (FieldBase field
)
3034 if ((field
.ModFlags
& Modifiers
.STATIC
) == 0) {
3035 Report
.Error (573, field
.Location
, "`{0}': Structs cannot have instance field initializers",
3036 field
.GetSignatureForError ());
3039 base.RegisterFieldForInitialization (field
);
3047 public sealed class Interface
: TypeContainer
, IMemberContainer
{
3050 /// Modifiers allowed in a class declaration
3052 public const int AllowedModifiers
=
3055 Modifiers
.PROTECTED
|
3056 Modifiers
.INTERNAL
|
3060 public Interface (NamespaceEntry ns
, DeclSpace parent
, MemberName name
, int mod
,
3062 : base (ns
, parent
, name
, attrs
, Kind
.Interface
)
3066 if (parent
.Parent
== null)
3067 accmods
= Modifiers
.INTERNAL
;
3069 accmods
= Modifiers
.PRIVATE
;
3071 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, name
.Location
);
3074 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
3076 if (a
.Type
== TypeManager
.comimport_attr_type
&&
3077 !attributes
.Contains (TypeManager
.guid_attr_type
)) {
3078 a
.Error_MissingGuidAttribute ();
3081 base.ApplyAttributeBuilder (a
, cb
);
3085 public override AttributeTargets AttributeTargets
{
3087 return AttributeTargets
.Interface
;
3091 const TypeAttributes DefaultTypeAttributes
=
3092 TypeAttributes
.AutoLayout
|
3093 TypeAttributes
.Abstract
|
3094 TypeAttributes
.Interface
;
3096 protected override TypeAttributes TypeAttr
{
3098 return base.TypeAttr
| DefaultTypeAttributes
;
3102 protected override bool VerifyClsCompliance ()
3104 if (!base.VerifyClsCompliance ())
3107 if (ifaces
!= null) {
3108 foreach (Type t
in ifaces
) {
3109 if (AttributeTester
.IsClsCompliant (t
))
3112 Report
.SymbolRelatedToPreviousError (t
);
3113 Report
.Warning (3027, 1, Location
, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3114 GetSignatureForError (), TypeManager
.CSharpName (t
));
3122 public abstract class MethodCore
: MemberBase
{
3123 public readonly Parameters Parameters
;
3124 protected ToplevelBlock block
;
3127 // The method we're overriding if this is an override method.
3129 protected MethodInfo base_method
= null;
3131 public MethodCore (DeclSpace parent
, GenericMethod generic
,
3132 Expression type
, int mod
, int allowed_mod
, bool is_iface
,
3133 MemberName name
, Attributes attrs
, Parameters parameters
)
3134 : base (parent
, generic
, type
, mod
, allowed_mod
, Modifiers
.PRIVATE
,
3137 Parameters
= parameters
;
3138 IsInterface
= is_iface
;
3142 // Returns the System.Type array for the parameters of this method
3144 public Type
[] ParameterTypes
{
3146 return Parameters
.Types
;
3150 public Parameters ParameterInfo
3157 public ToplevelBlock Block
{
3167 public void SetYields ()
3169 ModFlags
|= Modifiers
.METHOD_YIELDS
;
3172 protected override bool CheckBase ()
3174 if (!base.CheckBase ())
3177 // Check whether arguments were correct.
3178 if (!DoDefineParameters ())
3181 if ((caching_flags
& Flags
.TestMethodDuplication
) != 0 && !CheckForDuplications ())
3187 // Is null for System.Object while compiling corlib and base interfaces
3188 if (ParentContainer
.BaseCache
== null) {
3189 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0)) {
3190 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3195 Type base_ret_type
= null;
3196 base_method
= FindOutBaseMethod (ref base_ret_type
);
3198 // method is override
3199 if (base_method
!= null) {
3201 if (!CheckMethodAgainstBase ())
3204 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3205 if (!TypeManager
.IsEqual (MemberType
, TypeManager
.TypeToCoreType (base_ret_type
))) {
3206 Report
.SymbolRelatedToPreviousError (base_method
);
3207 if (this is PropertyBase
) {
3208 Report
.Error (1715, Location
, "`{0}': type must be `{1}' to match overridden member `{2}'",
3209 GetSignatureForError (), TypeManager
.CSharpName (base_ret_type
), TypeManager
.CSharpSignature (base_method
));
3212 Report
.Error (508, Location
, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3213 GetSignatureForError (), TypeManager
.CSharpName (base_ret_type
), TypeManager
.CSharpSignature (base_method
));
3218 if (base_method
.IsAbstract
&& !IsInterface
) {
3219 Report
.SymbolRelatedToPreviousError (base_method
);
3220 Report
.Error (533, Location
, "`{0}' hides inherited abstract member `{1}'",
3221 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3226 if (base_method
.IsSpecialName
&& !(this is PropertyBase
)) {
3227 Report
.Error (115, Location
, "`{0}': no suitable method found to override", GetSignatureForError ());
3231 if (Name
== "Equals" && Parameters
.Count
== 1 && ParameterTypes
[0] == TypeManager
.object_type
)
3232 ParentContainer
.Mark_HasEquals ();
3233 else if (Name
== "GetHashCode" && Parameters
.Empty
)
3234 ParentContainer
.Mark_HasGetHashCode ();
3236 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3237 ObsoleteAttribute oa
= AttributeTester
.GetMethodObsoleteAttribute (base_method
);
3239 if (OptAttributes
== null || !OptAttributes
.Contains (TypeManager
.obsolete_attribute_type
)) {
3240 Report
.SymbolRelatedToPreviousError (base_method
);
3241 Report
.Warning (672, 1, Location
, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3242 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
) );
3249 MemberInfo conflict_symbol
= ParentContainer
.FindBaseMemberWithSameName (Name
, !(this is Property
));
3250 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3251 if (conflict_symbol
!= null) {
3252 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
3253 if (this is PropertyBase
)
3254 Report
.Error (544, Location
, "`{0}': cannot override because `{1}' is not a property", GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3256 Report
.Error (505, Location
, "`{0}': cannot override because `{1}' is not a method", GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3258 Report
.Error (115, Location
, "`{0}': no suitable method found to override", GetSignatureForError ());
3262 if (conflict_symbol
== null) {
3263 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0)) {
3264 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3269 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3270 if (this is Method
&& conflict_symbol
is MethodBase
)
3273 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
3274 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3275 GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3282 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3283 // that have been defined.
3285 // `name' is the user visible name for reporting errors (this is used to
3286 // provide the right name regarding method names and properties)
3288 bool CheckMethodAgainstBase ()
3292 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0){
3293 if (!(base_method
.IsAbstract
|| base_method
.IsVirtual
)){
3294 Report
.Error (506, Location
,
3295 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3296 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3300 // Now we check that the overriden method is not final
3302 if (base_method
.IsFinal
) {
3303 Report
.SymbolRelatedToPreviousError (base_method
);
3304 Report
.Error (239, Location
, "`{0}': cannot override inherited member `{1}' because it is sealed",
3305 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3309 // Check that the permissions are not being changed
3311 MethodAttributes thisp
= flags
& MethodAttributes
.MemberAccessMask
;
3312 MethodAttributes base_classp
= base_method
.Attributes
& MethodAttributes
.MemberAccessMask
;
3314 if (!CheckAccessModifiers (thisp
, base_classp
, base_method
)) {
3315 Error_CannotChangeAccessModifiers (base_method
, base_classp
, null);
3320 if ((ModFlags
& (Modifiers
.NEW
| Modifiers
.OVERRIDE
)) == 0 && Name
!= "Finalize") {
3321 ModFlags
|= Modifiers
.NEW
;
3322 Report
.SymbolRelatedToPreviousError (base_method
);
3323 if (!IsInterface
&& (base_method
.IsVirtual
|| base_method
.IsAbstract
)) {
3324 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",
3325 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3327 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3328 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3335 protected bool CheckAccessModifiers (MethodAttributes thisp
, MethodAttributes base_classp
, MethodInfo base_method
)
3337 if ((base_classp
& MethodAttributes
.FamORAssem
) == MethodAttributes
.FamORAssem
){
3339 // when overriding protected internal, the method can be declared
3340 // protected internal only within the same assembly
3343 if ((thisp
& MethodAttributes
.FamORAssem
) == MethodAttributes
.FamORAssem
){
3344 if (Parent
.TypeBuilder
.Assembly
!= base_method
.DeclaringType
.Assembly
){
3346 // assemblies differ - report an error
3350 } else if (thisp
!= base_classp
) {
3352 // same assembly, but other attributes differ - report an error
3357 } else if ((thisp
& MethodAttributes
.Family
) != MethodAttributes
.Family
) {
3359 // if it's not "protected internal", it must be "protected"
3363 } else if (Parent
.TypeBuilder
.Assembly
== base_method
.DeclaringType
.Assembly
) {
3365 // protected within the same assembly - an error
3368 } else if ((thisp
& ~
(MethodAttributes
.Family
| MethodAttributes
.FamORAssem
)) !=
3369 (base_classp
& ~
(MethodAttributes
.Family
| MethodAttributes
.FamORAssem
))) {
3371 // protected ok, but other attributes differ - report an error
3377 return (thisp
== base_classp
);
3381 public bool CheckAbstractAndExtern (bool has_block
)
3383 if (ParentContainer
.Kind
== Kind
.Interface
)
3387 if ((ModFlags
& Modifiers
.EXTERN
) != 0) {
3388 Report
.Error (179, Location
, "`{0}' cannot declare a body because it is marked extern",
3389 GetSignatureForError ());
3393 if ((ModFlags
& Modifiers
.ABSTRACT
) != 0) {
3394 Report
.Error (500, Location
, "`{0}' cannot declare a body because it is marked abstract",
3395 GetSignatureForError ());
3399 if ((ModFlags
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) == 0) {
3400 Report
.Error (501, Location
, "`{0}' must declare a body because it is not marked abstract or extern",
3401 GetSignatureForError ());
3409 protected void Error_CannotChangeAccessModifiers (MemberInfo base_method
, MethodAttributes ma
, string suffix
)
3411 Report
.SymbolRelatedToPreviousError (base_method
);
3412 string base_name
= TypeManager
.GetFullNameSignature (base_method
);
3413 string this_name
= GetSignatureForError ();
3414 if (suffix
!= null) {
3415 base_name
+= suffix
;
3416 this_name
+= suffix
;
3419 Report
.Error (507, Location
, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3420 this_name
, Modifiers
.GetDescription (ma
), base_name
);
3423 protected static string Error722
{
3425 return "`{0}': static types cannot be used as return types";
3430 /// For custom member duplication search in a container
3432 protected abstract bool CheckForDuplications ();
3435 /// Gets base method and its return type
3437 protected abstract MethodInfo
FindOutBaseMethod (ref Type base_ret_type
);
3439 protected bool DoDefineParameters ()
3441 IResolveContext rc
= GenericMethod
== null ? this : (IResolveContext
)ds
;
3443 // Check if arguments were correct
3444 if (!Parameters
.Resolve (rc
))
3447 return CheckParameters (ParameterTypes
);
3450 bool CheckParameters (Type
[] parameters
)
3454 foreach (Type partype
in parameters
){
3455 if (partype
== TypeManager
.void_type
) {
3457 1547, Location
, "Keyword 'void' cannot " +
3458 "be used in this context");
3462 if (partype
.IsPointer
){
3463 if (!TypeManager
.VerifyUnManaged (TypeManager
.GetElementType (partype
), Location
))
3467 if (ds
.AsAccessible (partype
, ModFlags
))
3470 Report
.SymbolRelatedToPreviousError (partype
);
3471 if (this is Indexer
)
3472 Report
.Error (55, Location
,
3473 "Inconsistent accessibility: parameter type `" +
3474 TypeManager
.CSharpName (partype
) + "' is less " +
3475 "accessible than indexer `" + GetSignatureForError () + "'");
3476 else if (this is Operator
)
3477 Report
.Error (57, Location
,
3478 "Inconsistent accessibility: parameter type `" +
3479 TypeManager
.CSharpName (partype
) + "' is less " +
3480 "accessible than operator `" + GetSignatureForError () + "'");
3482 Report
.Error (51, Location
,
3483 "Inconsistent accessibility: parameter type `" +
3484 TypeManager
.CSharpName (partype
) + "' is less " +
3485 "accessible than method `" + GetSignatureForError () + "'");
3492 protected override bool VerifyClsCompliance ()
3494 if (!base.VerifyClsCompliance ()) {
3495 if ((ModFlags
& Modifiers
.ABSTRACT
) != 0 && IsExposedFromAssembly () && Parent
.IsClsComplianceRequired ()) {
3496 Report
.Error (3011, Location
, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3501 if (Parameters
.HasArglist
) {
3502 Report
.Error (3000, Location
, "Methods with variable arguments are not CLS-compliant");
3505 if (!AttributeTester
.IsClsCompliant (MemberType
)) {
3506 if (this is PropertyBase
)
3507 Report
.Error (3003, Location
, "Type of `{0}' is not CLS-compliant",
3508 GetSignatureForError ());
3510 Report
.Error (3002, Location
, "Return type of `{0}' is not CLS-compliant",
3511 GetSignatureForError ());
3514 Parameters
.VerifyClsCompliance ();
3519 protected bool IsDuplicateImplementation (MethodCore method
)
3521 if (method
== this || !(method
.MemberName
.Equals (MemberName
)))
3524 Type
[] param_types
= method
.ParameterTypes
;
3525 // This never happen. Rewrite this as Equal
3526 if (param_types
== null && ParameterTypes
== null)
3528 if (param_types
== null || ParameterTypes
== null)
3531 if (param_types
.Length
!= ParameterTypes
.Length
)
3534 if (method
.Parameters
.HasArglist
!= Parameters
.HasArglist
)
3539 for (int i
= 0; i
< param_types
.Length
; i
++) {
3540 if (param_types
[i
] != ParameterTypes
[i
])
3544 if (IsExplicitImpl
&& (method
.InterfaceType
!= InterfaceType
))
3547 // TODO: make operator compatible with MethodCore to avoid this
3548 if (this is Operator
&& method
is Operator
) {
3549 if (MemberType
!= method
.MemberType
)
3555 // Try to report 663: method only differs on out/ref
3557 Parameters info
= ParameterInfo
;
3558 Parameters other_info
= method
.ParameterInfo
;
3559 for (int i
= 0; i
< info
.Count
; i
++){
3561 if (info
.ParameterModifier (i
) != other_info
.ParameterModifier (i
)){
3562 Report
.SymbolRelatedToPreviousError (method
);
3563 Report
.Error (663, Location
, "`{0}': Methods cannot differ only on their use of ref and out on a parameters",
3564 GetSignatureForError ());
3567 Console
.WriteLine ("Method is: {0} {1}", method
.Location
, method
);
3568 Console
.WriteLine ("this is: {0} {1}", Location
, this);
3572 Report
.SymbolRelatedToPreviousError (method
);
3573 if (this is Operator
&& method
is Operator
)
3574 Report
.Error (557, Location
, "Duplicate user-defined conversion in type `{0}'", Parent
.Name
);
3576 Report
.Error (111, Location
, TypeContainer
.Error111
, GetSignatureForError ());
3584 public override bool IsUsed
{
3585 get { return IsExplicitImpl || base.IsUsed; }
3589 // Returns a string that represents the signature for this
3590 // member which should be used in XML documentation.
3592 public override string GetDocCommentName (DeclSpace ds
)
3594 return DocUtil
.GetMethodDocCommentName (this, ds
);
3598 // Raised (and passed an XmlElement that contains the comment)
3599 // when GenerateDocComment is writing documentation expectedly.
3601 // FIXME: with a few effort, it could be done with XmlReader,
3602 // that means removal of DOM use.
3604 internal override void OnGenerateDocComment (XmlElement el
)
3606 DocUtil
.OnMethodGenerateDocComment (this, el
);
3610 // Represents header string for documentation comment.
3612 public override string DocCommentHeader
{
3613 get { return "M:"; }
3618 public abstract class MethodOrOperator
: MethodCore
, IMethodData
3620 public MethodBuilder MethodBuilder
;
3621 ReturnParameter return_attributes
;
3622 ListDictionary declarative_security
;
3623 protected MethodData MethodData
;
3625 static string[] attribute_targets
= new string [] { "method", "return" }
;
3627 protected MethodOrOperator (DeclSpace parent
, GenericMethod generic
, Expression type
, int mod
,
3628 int allowed_mod
, bool is_interface
, MemberName name
,
3629 Attributes attrs
, Parameters parameters
)
3630 : base (parent
, generic
, type
, mod
, allowed_mod
, is_interface
, name
,
3635 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
3637 if (a
.Target
== AttributeTargets
.ReturnValue
) {
3638 if (return_attributes
== null)
3639 return_attributes
= new ReturnParameter (MethodBuilder
, Location
);
3641 return_attributes
.ApplyAttributeBuilder (a
, cb
);
3645 if (a
.Type
== TypeManager
.methodimpl_attr_type
&&
3646 (a
.GetMethodImplOptions () & MethodImplOptions
.InternalCall
) != 0) {
3647 MethodBuilder
.SetImplementationFlags (MethodImplAttributes
.InternalCall
| MethodImplAttributes
.Runtime
);
3650 if (a
.Type
== TypeManager
.dllimport_type
) {
3651 const int extern_static
= Modifiers
.EXTERN
| Modifiers
.STATIC
;
3652 if ((ModFlags
& extern_static
) != extern_static
) {
3653 Report
.Error (601, a
.Location
, "The DllImport attribute must be specified on a method marked `static' and `extern'");
3659 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
3660 if (declarative_security
== null)
3661 declarative_security
= new ListDictionary ();
3662 a
.ExtractSecurityPermissionSet (declarative_security
);
3666 MethodBuilder
.SetCustomAttribute (cb
);
3669 public override AttributeTargets AttributeTargets
{
3671 return AttributeTargets
.Method
;
3675 public EmitContext
CreateEmitContext (DeclSpace tc
, ILGenerator ig
)
3677 EmitContext ec
= new EmitContext (this,
3678 tc
, this.ds
, Location
, ig
, MemberType
, ModFlags
, false);
3680 Iterator iterator
= tc
as Iterator
;
3681 if (iterator
!= null)
3682 ec
.CurrentAnonymousMethod
= iterator
.Host
;
3687 public override bool Define ()
3689 if (!DoDefineBase ())
3692 MethodBuilder mb
= null;
3693 if (GenericMethod
!= null) {
3694 string method_name
= MemberName
.Name
;
3696 if (IsExplicitImpl
) {
3697 method_name
= TypeManager
.CSharpName (InterfaceType
) +
3701 mb
= Parent
.TypeBuilder
.DefineMethod (method_name
, flags
);
3703 if (!GenericMethod
.Define (mb
))
3710 if (!CheckAbstractAndExtern (block
!= null))
3716 MethodData
= new MethodData (this, ModFlags
, flags
, this, mb
, GenericMethod
, base_method
);
3718 if (!MethodData
.Define (ParentContainer
))
3721 MethodBuilder
= MethodData
.MethodBuilder
;
3723 if (MemberType
.IsAbstract
&& MemberType
.IsSealed
) {
3724 Report
.Error (722, Location
, Error722
, TypeManager
.CSharpName (MemberType
));
3731 public override void Emit ()
3733 if (OptAttributes
!= null)
3734 OptAttributes
.Emit ();
3736 if (declarative_security
!= null) {
3737 foreach (DictionaryEntry de
in declarative_security
) {
3738 MethodBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
3745 protected void Error_ConditionalAttributeIsNotValid ()
3747 Report
.Error (577, Location
,
3748 "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
3749 GetSignatureForError ());
3752 public override bool MarkForDuplicationCheck ()
3754 caching_flags
|= Flags
.TestMethodDuplication
;
3758 public override string[] ValidAttributeTargets
{
3760 return attribute_targets
;
3764 #region IMethodData Members
3766 public CallingConventions CallingConventions
{
3768 CallingConventions cc
= Parameters
.CallingConvention
;
3769 if (Parameters
.HasArglist
)
3770 block
.HasVarargs
= true;
3773 if ((ModFlags
& Modifiers
.STATIC
) == 0)
3774 cc
|= CallingConventions
.HasThis
;
3776 // FIXME: How is `ExplicitThis' used in C#?
3782 public Type ReturnType
{
3788 public MemberName MethodName
{
3794 public new Location Location
{
3796 return base.Location
;
3800 protected override bool CheckBase() {
3801 if (!base.CheckBase ())
3804 // TODO: Destructor should derive from MethodCore
3805 if (base_method
!= null && (ModFlags
& Modifiers
.OVERRIDE
) != 0 && Name
== "Finalize" &&
3806 base_method
.DeclaringType
== TypeManager
.object_type
&& !(this is Destructor
)) {
3807 Report
.Error (249, Location
, "Do not override object.Finalize. Instead, provide a destructor");
3815 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
3817 public bool IsExcluded () {
3818 if ((caching_flags
& Flags
.Excluded_Undetected
) == 0)
3819 return (caching_flags
& Flags
.Excluded
) != 0;
3821 caching_flags
&= ~Flags
.Excluded_Undetected
;
3823 if (base_method
== null) {
3824 if (OptAttributes
== null)
3827 Attribute
[] attrs
= OptAttributes
.SearchMulti (TypeManager
.conditional_attribute_type
);
3832 foreach (Attribute a
in attrs
) {
3833 string condition
= a
.GetConditionalAttributeValue ();
3834 if (condition
== null)
3837 if (RootContext
.AllDefines
.Contains (condition
))
3841 caching_flags
|= Flags
.Excluded
;
3845 IMethodData md
= TypeManager
.GetMethod (base_method
);
3847 if (AttributeTester
.IsConditionalMethodExcluded (base_method
)) {
3848 caching_flags
|= Flags
.Excluded
;
3854 if (md
.IsExcluded ()) {
3855 caching_flags
|= Flags
.Excluded
;
3861 GenericMethod IMethodData
.GenericMethod
{
3863 return GenericMethod
;
3871 public class SourceMethod
: ISourceMethod
3876 protected SourceMethod (DeclSpace parent
, MethodBase builder
,
3877 ISourceFile file
, Location start
, Location end
)
3879 this.parent
= parent
;
3880 this.builder
= builder
;
3882 CodeGen
.SymbolWriter
.OpenMethod (file
, this, start
.Row
, start
.Column
, end
.Row
, start
.Column
);
3885 public string Name
{
3886 get { return builder.Name; }
3889 public int NamespaceID
{
3890 get { return parent.NamespaceEntry.SymbolFileID; }
3895 if (builder
is MethodBuilder
)
3896 return ((MethodBuilder
) builder
).GetToken ().Token
;
3897 else if (builder
is ConstructorBuilder
)
3898 return ((ConstructorBuilder
) builder
).GetToken ().Token
;
3900 throw new NotSupportedException ();
3904 public void CloseMethod ()
3906 if (CodeGen
.SymbolWriter
!= null)
3907 CodeGen
.SymbolWriter
.CloseMethod ();
3910 public static SourceMethod
Create (DeclSpace parent
, MethodBase builder
, Block block
)
3912 if (CodeGen
.SymbolWriter
== null)
3917 Location start_loc
= block
.StartLocation
;
3918 if (start_loc
.IsNull
)
3921 Location end_loc
= block
.EndLocation
;
3925 ISourceFile file
= start_loc
.SourceFile
;
3929 return new SourceMethod (
3930 parent
, builder
, file
, start_loc
, end_loc
);
3934 public class Method
: MethodOrOperator
, IIteratorContainer
{
3937 /// Modifiers allowed in a class declaration
3939 const int AllowedModifiers
=
3942 Modifiers
.PROTECTED
|
3943 Modifiers
.INTERNAL
|
3948 Modifiers
.OVERRIDE
|
3949 Modifiers
.ABSTRACT
|
3951 Modifiers
.METHOD_YIELDS
|
3954 const int AllowedInterfaceModifiers
=
3955 Modifiers
.NEW
| Modifiers
.UNSAFE
;
3958 // return_type can be "null" for VOID values.
3960 public Method (DeclSpace parent
, GenericMethod generic
,
3961 Expression return_type
, int mod
, bool is_iface
,
3962 MemberName name
, Parameters parameters
, Attributes attrs
)
3963 : base (parent
, generic
, return_type
, mod
,
3964 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
3965 is_iface
, name
, attrs
, parameters
)
3969 public override string GetSignatureForError()
3971 return base.GetSignatureForError () + Parameters
.GetSignatureForError ();
3974 void Error_DuplicateEntryPoint (MethodInfo b
, Location location
)
3976 Report
.Error (17, location
,
3977 "Program `{0}' has more than one entry point defined: `{1}'",
3978 CodeGen
.FileName
, TypeManager
.CSharpSignature(b
));
3981 bool IsEntryPoint (MethodBuilder b
, Parameters pinfo
)
3983 if (b
.ReturnType
!= TypeManager
.void_type
&&
3984 b
.ReturnType
!= TypeManager
.int32_type
)
3987 if (pinfo
.Count
== 0)
3990 if (pinfo
.Count
> 1)
3993 Type t
= pinfo
.ParameterType(0);
3995 (t
.GetArrayRank() == 1) &&
3996 (TypeManager
.GetElementType(t
) == TypeManager
.string_type
) &&
3997 (pinfo
.ParameterModifier(0) == Parameter
.Modifier
.NONE
))
4003 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
4005 if (a
.Type
== TypeManager
.conditional_attribute_type
) {
4006 if (IsExplicitImpl
) {
4007 Error_ConditionalAttributeIsNotValid ();
4011 if (ReturnType
!= TypeManager
.void_type
) {
4012 Report
.Error (578, Location
, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
4016 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
4017 Report
.Error (243, Location
, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
4022 Report
.Error (582, Location
, "Conditional not valid on interface members");
4026 if (MethodData
.implementing
!= null) {
4027 Report
.Error (629, Location
, "Conditional member `{0}' cannot implement interface member `{1}'",
4028 GetSignatureForError (), TypeManager
.CSharpSignature (MethodData
.implementing
));
4032 for (int i
= 0; i
< ParameterInfo
.Count
; ++i
) {
4033 if ((ParameterInfo
.ParameterModifier (i
) & Parameter
.Modifier
.OUTMASK
) != 0) {
4034 Report
.Error (685, Location
, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
4040 base.ApplyAttributeBuilder (a
, cb
);
4043 protected override bool CheckForDuplications ()
4045 ArrayList ar
= ParentContainer
.Methods
;
4047 int arLen
= ar
.Count
;
4049 for (int i
= 0; i
< arLen
; i
++) {
4050 Method m
= (Method
) ar
[i
];
4051 if (IsDuplicateImplementation (m
))
4056 ar
= ParentContainer
.Properties
;
4058 for (int i
= 0; i
< ar
.Count
; ++i
) {
4059 PropertyBase pb
= (PropertyBase
) ar
[i
];
4060 if (pb
.AreAccessorsDuplicateImplementation (this))
4065 ar
= ParentContainer
.Indexers
;
4067 for (int i
= 0; i
< ar
.Count
; ++i
) {
4068 PropertyBase pb
= (PropertyBase
) ar
[i
];
4069 if (pb
.AreAccessorsDuplicateImplementation (this))
4074 ar
= ParentContainer
.Events
;
4076 for (int i
= 0; i
< ar
.Count
; ++i
) {
4077 Event ev
= (Event
) ar
[i
];
4078 if (ev
.AreAccessorsDuplicateImplementation (this))
4089 public override bool Define ()
4091 if (!base.Define ())
4094 if (RootContext
.StdLib
&& (ReturnType
== TypeManager
.arg_iterator_type
|| ReturnType
== TypeManager
.typed_reference_type
)) {
4095 Error1599 (Location
, ReturnType
);
4099 if (ReturnType
== TypeManager
.void_type
&& ParameterTypes
.Length
== 0 &&
4100 Name
== "Finalize" && !(this is Destructor
)) {
4101 Report
.Warning (465, 1, Location
, "Introducing a 'Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
4105 // Setup iterator if we are one
4107 if ((ModFlags
& Modifiers
.METHOD_YIELDS
) != 0){
4108 Iterator iterator
= new Iterator (
4109 this, Parent
, GenericMethod
, ModFlags
);
4111 if (!iterator
.DefineIterator ())
4116 // This is used to track the Entry Point,
4118 if (Name
== "Main" &&
4119 ((ModFlags
& Modifiers
.STATIC
) != 0) && RootContext
.NeedsEntryPoint
&&
4120 (RootContext
.MainClass
== null ||
4121 RootContext
.MainClass
== Parent
.TypeBuilder
.FullName
)){
4122 if (IsEntryPoint (MethodBuilder
, ParameterInfo
)) {
4123 IMethodData md
= TypeManager
.GetMethod (MethodBuilder
);
4124 md
.SetMemberIsUsed ();
4126 if (RootContext
.EntryPoint
== null) {
4127 if (Parent
.IsGeneric
){
4128 Report
.Error (-201, Location
,
4129 "Entry point can not be defined in a generic class");
4132 RootContext
.EntryPoint
= MethodBuilder
;
4133 RootContext
.EntryPointLocation
= Location
;
4135 Error_DuplicateEntryPoint (RootContext
.EntryPoint
, RootContext
.EntryPointLocation
);
4136 Error_DuplicateEntryPoint (MethodBuilder
, Location
);
4139 if (RootContext
.WarningLevel
>= 4)
4140 Report
.Warning (28, 4, Location
, "`{0}' has the wrong signature to be an entry point", TypeManager
.CSharpSignature(MethodBuilder
));
4150 public override void Emit ()
4152 MethodData
.Emit (Parent
);
4159 public static void Error1599 (Location loc
, Type t
)
4161 Report
.Error (1599, loc
, "Method or delegate cannot return type `{0}'", TypeManager
.CSharpName (t
));
4164 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
4166 MethodInfo mi
= (MethodInfo
) ParentContainer
.BaseCache
.FindMemberToOverride (
4167 Parent
.TypeBuilder
, Name
, ParameterTypes
, GenericMethod
, false);
4172 base_ret_type
= mi
.ReturnType
;
4176 protected override bool VerifyClsCompliance ()
4178 if (!base.VerifyClsCompliance ())
4181 if (ParameterInfo
.Count
> 0) {
4182 ArrayList al
= (ArrayList
)ParentContainer
.MemberCache
.Members
[Name
];
4184 MemberCache
.VerifyClsParameterConflict (al
, this, MethodBuilder
);
4191 public abstract class ConstructorInitializer
{
4192 ArrayList argument_list
;
4193 protected ConstructorInfo base_constructor
;
4196 public ConstructorInitializer (ArrayList argument_list
, Location loc
)
4198 this.argument_list
= argument_list
;
4202 public ArrayList Arguments
{
4204 return argument_list
;
4208 public bool Resolve (ConstructorBuilder caller_builder
, Block block
, EmitContext ec
)
4210 Expression base_constructor_group
;
4214 ec
.CurrentBlock
= block
;
4216 if (argument_list
!= null){
4217 foreach (Argument a
in argument_list
){
4218 if (!a
.Resolve (ec
, loc
))
4222 ec
.CurrentBlock
= null;
4224 if (this is ConstructorBaseInitializer
) {
4225 if (ec
.ContainerType
.BaseType
== null)
4228 t
= ec
.ContainerType
.BaseType
;
4229 if (ec
.ContainerType
.IsValueType
) {
4230 Report
.Error (522, loc
,
4231 "`{0}': Struct constructors cannot call base constructors", TypeManager
.CSharpSignature (caller_builder
));
4235 t
= ec
.ContainerType
;
4237 base_constructor_group
= Expression
.MemberLookup (
4238 ec
.ContainerType
, t
, ".ctor", MemberTypes
.Constructor
,
4239 BindingFlags
.Public
| BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
,
4242 if (base_constructor_group
== null){
4244 base_constructor_group
= Expression
.MemberLookup (
4245 t
, null, t
, ".ctor", MemberTypes
.Constructor
,
4246 BindingFlags
.NonPublic
| BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
,
4250 int errors
= Report
.Errors
;
4251 if (base_constructor_group
!= null)
4252 base_constructor
= (ConstructorInfo
) Invocation
.OverloadResolve (
4253 ec
, (MethodGroupExpr
) base_constructor_group
, argument_list
,
4256 if (base_constructor
== null) {
4257 if (errors
== Report
.Errors
)
4258 Invocation
.Error_WrongNumArguments (loc
, TypeManager
.CSharpSignature (caller_builder
),
4259 argument_list
== null ? 0 : argument_list
.Count
);
4264 Expression
.ErrorIsInaccesible (loc
, TypeManager
.CSharpSignature (base_constructor
));
4265 base_constructor
= null;
4269 if (base_constructor
== caller_builder
){
4270 Report
.Error (516, loc
, "Constructor `{0}' cannot call itself", TypeManager
.CSharpSignature (caller_builder
));
4277 public virtual void Emit (EmitContext ec
)
4279 if (base_constructor
!= null){
4280 ec
.Mark (loc
, false);
4282 Invocation
.EmitCall (ec
, true, true, null, base_constructor
, argument_list
, loc
);
4284 Invocation
.EmitCall (ec
, true, false, ec
.GetThis (loc
), base_constructor
, argument_list
, loc
);
4289 public class ConstructorBaseInitializer
: ConstructorInitializer
{
4290 public ConstructorBaseInitializer (ArrayList argument_list
, Location l
) :
4291 base (argument_list
, l
)
4296 class GeneratedBaseInitializer
: ConstructorBaseInitializer
{
4297 public GeneratedBaseInitializer (Location loc
):
4303 public class ConstructorThisInitializer
: ConstructorInitializer
{
4304 public ConstructorThisInitializer (ArrayList argument_list
, Location l
) :
4305 base (argument_list
, l
)
4310 public class Constructor
: MethodCore
, IMethodData
{
4311 public ConstructorBuilder ConstructorBuilder
;
4312 public ConstructorInitializer Initializer
;
4313 ListDictionary declarative_security
;
4316 // Modifiers allowed for a constructor.
4318 public const int AllowedModifiers
=
4320 Modifiers
.PROTECTED
|
4321 Modifiers
.INTERNAL
|
4327 static string[] attribute_targets
= new string [] { "method" }
;
4329 bool has_compliant_args
= false;
4331 // The spec claims that static is not permitted, but
4332 // my very own code has static constructors.
4334 public Constructor (DeclSpace parent
, string name
, int mod
, Parameters args
,
4335 ConstructorInitializer init
, Location loc
)
4336 : base (parent
, null, null, mod
, AllowedModifiers
, false,
4337 new MemberName (name
, loc
), null, args
)
4342 public bool HasCompliantArgs
{
4343 get { return has_compliant_args; }
4346 public override AttributeTargets AttributeTargets
{
4347 get { return AttributeTargets.Constructor; }
4352 // Returns true if this is a default constructor
4354 public bool IsDefault ()
4356 if ((ModFlags
& Modifiers
.STATIC
) != 0)
4357 return Parameters
.Empty
;
4359 return Parameters
.Empty
&&
4360 (Initializer
is ConstructorBaseInitializer
) &&
4361 (Initializer
.Arguments
== null);
4364 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
4366 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
4367 if (declarative_security
== null) {
4368 declarative_security
= new ListDictionary ();
4370 a
.ExtractSecurityPermissionSet (declarative_security
);
4374 if (a
.Type
== TypeManager
.methodimpl_attr_type
&&
4375 (a
.GetMethodImplOptions () & MethodImplOptions
.InternalCall
) != 0) {
4376 ConstructorBuilder
.SetImplementationFlags (MethodImplAttributes
.InternalCall
| MethodImplAttributes
.Runtime
);
4379 ConstructorBuilder
.SetCustomAttribute (cb
);
4382 protected override bool CheckForDuplications ()
4384 ArrayList ar
= ParentContainer
.InstanceConstructors
;
4386 int arLen
= ar
.Count
;
4388 for (int i
= 0; i
< arLen
; i
++) {
4389 Constructor m
= (Constructor
) ar
[i
];
4390 if (IsDuplicateImplementation (m
))
4397 protected override bool CheckBase ()
4399 if ((ModFlags
& Modifiers
.STATIC
) != 0) {
4400 if (!Parameters
.Empty
) {
4401 Report
.Error (132, Location
, "`{0}': The static constructor must be parameterless",
4402 GetSignatureForError ());
4406 // the rest can be ignored
4410 // Check whether arguments were correct.
4411 if (!DoDefineParameters ())
4414 if (!CheckForDuplications ())
4417 if (ParentContainer
.Kind
== Kind
.Struct
) {
4418 if (ParameterTypes
.Length
== 0) {
4419 Report
.Error (568, Location
,
4420 "Structs cannot contain explicit parameterless constructors");
4424 if ((ModFlags
& Modifiers
.PROTECTED
) != 0) {
4425 Report
.Error (666, Location
, "`{0}': new protected member declared in struct", GetSignatureForError ());
4430 if ((RootContext
.WarningLevel
>= 4) && ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0 && (ModFlags
& Modifiers
.PROTECTED
) != 0)) {
4431 Report
.Warning (628, 4, Location
, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
4438 // Creates the ConstructorBuilder
4440 public override bool Define ()
4442 if (ConstructorBuilder
!= null)
4445 MethodAttributes ca
= (MethodAttributes
.RTSpecialName
|
4446 MethodAttributes
.SpecialName
);
4448 if ((ModFlags
& Modifiers
.STATIC
) != 0){
4449 ca
|= MethodAttributes
.Static
| MethodAttributes
.Private
;
4451 ca
|= MethodAttributes
.HideBySig
;
4453 if ((ModFlags
& Modifiers
.PUBLIC
) != 0)
4454 ca
|= MethodAttributes
.Public
;
4455 else if ((ModFlags
& Modifiers
.PROTECTED
) != 0){
4456 if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
4457 ca
|= MethodAttributes
.FamORAssem
;
4459 ca
|= MethodAttributes
.Family
;
4460 } else if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
4461 ca
|= MethodAttributes
.Assembly
;
4463 ca
|= MethodAttributes
.Private
;
4466 if (!CheckAbstractAndExtern (block
!= null))
4469 // Check if arguments were correct.
4473 ConstructorBuilder
= Parent
.TypeBuilder
.DefineConstructor (
4474 ca
, CallingConventions
,
4477 if ((ModFlags
& Modifiers
.UNSAFE
) != 0)
4478 ConstructorBuilder
.InitLocals
= false;
4480 if (ParentContainer
.IsComImport
) {
4481 if (!IsDefault ()) {
4482 Report
.Error (669, Location
, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
4483 Parent
.GetSignatureForError ());
4486 ConstructorBuilder
.SetImplementationFlags (MethodImplAttributes
.InternalCall
);
4489 TypeManager
.AddMethod (ConstructorBuilder
, this);
4497 public override void Emit ()
4499 if (OptAttributes
!= null)
4500 OptAttributes
.Emit ();
4502 EmitContext ec
= CreateEmitContext (null, null);
4504 if (block
!= null) {
4505 // If this is a non-static `struct' constructor and doesn't have any
4506 // initializer, it must initialize all of the struct's fields.
4507 if ((ParentContainer
.Kind
== Kind
.Struct
) &&
4508 ((ModFlags
& Modifiers
.STATIC
) == 0) && (Initializer
== null))
4509 block
.AddThisVariable (Parent
, Location
);
4511 if (!block
.ResolveMeta (ec
, ParameterInfo
))
4515 if ((ModFlags
& Modifiers
.STATIC
) == 0){
4516 if (ParentContainer
.Kind
== Kind
.Class
&& Initializer
== null)
4517 Initializer
= new GeneratedBaseInitializer (Location
);
4521 // Spec mandates that Initializers will not have
4525 if ((Initializer
!= null) &&
4526 !Initializer
.Resolve (ConstructorBuilder
, block
, ec
))
4528 ec
.IsStatic
= false;
4531 Parameters
.ApplyAttributes (ConstructorBuilder
);
4533 SourceMethod source
= SourceMethod
.Create (
4534 Parent
, ConstructorBuilder
, block
);
4537 // Classes can have base initializers and instance field initializers.
4539 if (ParentContainer
.Kind
== Kind
.Class
){
4540 if ((ModFlags
& Modifiers
.STATIC
) == 0){
4543 // If we use a "this (...)" constructor initializer, then
4544 // do not emit field initializers, they are initialized in the other constructor
4546 if (!(Initializer
!= null && Initializer
is ConstructorThisInitializer
))
4547 ParentContainer
.EmitFieldInitializers (ec
);
4550 if (Initializer
!= null) {
4551 Initializer
.Emit (ec
);
4554 if ((ModFlags
& Modifiers
.STATIC
) != 0)
4555 ParentContainer
.EmitFieldInitializers (ec
);
4557 ec
.EmitTopBlock (this, block
);
4560 source
.CloseMethod ();
4564 if (declarative_security
!= null) {
4565 foreach (DictionaryEntry de
in declarative_security
) {
4566 ConstructorBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
4573 // Is never override
4574 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
4579 public override string GetSignatureForError()
4581 return base.GetSignatureForError () + Parameters
.GetSignatureForError ();
4584 public override string[] ValidAttributeTargets
{
4586 return attribute_targets
;
4590 protected override bool VerifyClsCompliance ()
4592 if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
4596 if (ParameterInfo
.Count
> 0) {
4597 ArrayList al
= (ArrayList
)Parent
.MemberCache
.Members
[".ctor"];
4599 MemberCache
.VerifyClsParameterConflict (al
, this, ConstructorBuilder
);
4601 if (Parent
.TypeBuilder
.IsSubclassOf (TypeManager
.attribute_type
)) {
4602 foreach (Type param
in ParameterTypes
) {
4603 if (param
.IsArray
) {
4609 has_compliant_args
= true;
4613 #region IMethodData Members
4615 public System
.Reflection
.CallingConventions CallingConventions
{
4617 CallingConventions cc
= Parameters
.CallingConvention
;
4619 if (ParentContainer
.Kind
== Kind
.Class
)
4620 if ((ModFlags
& Modifiers
.STATIC
) == 0)
4621 cc
|= CallingConventions
.HasThis
;
4623 // FIXME: How is `ExplicitThis' used in C#?
4629 public new Location Location
{
4631 return base.Location
;
4635 public MemberName MethodName
{
4641 public Type ReturnType
{
4647 public EmitContext
CreateEmitContext (DeclSpace ds
, ILGenerator ig
)
4649 ILGenerator ig_
= ConstructorBuilder
.GetILGenerator ();
4650 return new EmitContext (this, Parent
, Location
, ig_
, null, ModFlags
, true);
4653 public bool IsExcluded()
4658 GenericMethod IMethodData
.GenericMethod
{
4668 /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
4670 public interface IMethodData
4672 CallingConventions CallingConventions { get; }
4673 Location Location { get; }
4674 MemberName MethodName { get; }
4675 Type ReturnType { get; }
4676 GenericMethod GenericMethod { get; }
4677 Parameters ParameterInfo { get; }
4679 Attributes OptAttributes { get; }
4680 ToplevelBlock Block { get; set; }
4682 EmitContext
CreateEmitContext (DeclSpace ds
, ILGenerator ig
);
4683 ObsoleteAttribute
GetObsoleteAttribute ();
4684 string GetSignatureForError ();
4686 bool IsClsComplianceRequired ();
4687 void SetMemberIsUsed ();
4691 // Encapsulates most of the Method's state
4693 public class MethodData
{
4695 readonly IMethodData method
;
4697 public readonly GenericMethod GenericMethod
;
4700 // Are we implementing an interface ?
4702 public MethodInfo implementing
;
4707 protected MemberBase member
;
4708 protected int modifiers
;
4709 protected MethodAttributes flags
;
4710 protected Type declaring_type
;
4711 protected MethodInfo parent_method
;
4713 MethodBuilder builder
= null;
4714 public MethodBuilder MethodBuilder
{
4720 public Type DeclaringType
{
4722 return declaring_type
;
4726 public MethodData (MemberBase member
,
4727 int modifiers
, MethodAttributes flags
, IMethodData method
)
4729 this.member
= member
;
4730 this.modifiers
= modifiers
;
4733 this.method
= method
;
4736 public MethodData (MemberBase member
,
4737 int modifiers
, MethodAttributes flags
,
4738 IMethodData method
, MethodBuilder builder
,
4739 GenericMethod generic
, MethodInfo parent_method
)
4740 : this (member
, modifiers
, flags
, method
)
4742 this.builder
= builder
;
4743 this.GenericMethod
= generic
;
4744 this.parent_method
= parent_method
;
4747 public bool Define (DeclSpace parent
)
4749 string name
= method
.MethodName
.Basename
;
4750 string method_name
= method
.MethodName
.FullName
;
4752 TypeContainer container
= ((TypeContainer
) parent
).PartialContainer
;
4754 PendingImplementation pending
= container
.PendingImplementations
;
4755 if (pending
!= null){
4756 if (member
is Indexer
) // TODO: test it, but it should work without this IF
4757 implementing
= pending
.IsInterfaceIndexer (
4758 member
.InterfaceType
, method
.ReturnType
, method
.ParameterInfo
);
4760 implementing
= pending
.IsInterfaceMethod (
4761 member
.InterfaceType
, name
, method
.ReturnType
, method
.ParameterInfo
);
4763 if (member
.InterfaceType
!= null){
4764 if (implementing
== null){
4765 if (member
is PropertyBase
) {
4766 Report
.Error (550, method
.Location
, "`{0}' is an accessor not found in interface member `{1}{2}'",
4767 method
.GetSignatureForError (), TypeManager
.CSharpName (member
.InterfaceType
),
4768 member
.GetSignatureForError ().Substring (member
.GetSignatureForError ().LastIndexOf ('.')));
4771 Report
.Error (539, method
.Location
,
4772 "`{0}.{1}' in explicit interface declaration is not a member of interface",
4773 TypeManager
.CSharpName (member
.InterfaceType
), member
.ShortName
);
4777 if (implementing
.IsSpecialName
&& !(method
is AbstractPropertyEventMethod
)) {
4778 Report
.SymbolRelatedToPreviousError (implementing
);
4779 Report
.Error (683, method
.Location
, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
4780 member
.GetSignatureForError (), TypeManager
.CSharpSignature (implementing
));
4784 method_name
= TypeManager
.GetFullName (member
.InterfaceType
) +
4787 if (implementing
!= null) {
4788 AbstractPropertyEventMethod prop_method
= method
as AbstractPropertyEventMethod
;
4789 if (prop_method
!= null) {
4790 if (!implementing
.IsSpecialName
) {
4791 Report
.SymbolRelatedToPreviousError (implementing
);
4792 Report
.Error (686, method
.Location
, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
4793 method
.GetSignatureForError (), TypeManager
.CSharpSignature (implementing
), container
.GetSignatureForError ());
4796 PropertyBase
.PropertyMethod pm
= prop_method
as PropertyBase
.PropertyMethod
;
4797 if (pm
!= null && pm
.HasCustomAccessModifier
&& (pm
.ModFlags
& Modifiers
.PUBLIC
) == 0) {
4798 Report
.SymbolRelatedToPreviousError (implementing
);
4799 Report
.Error (277, method
.Location
, "Accessor `{0}' must be declared public to implement interface member `{1}'",
4800 method
.GetSignatureForError (), TypeManager
.CSharpSignature (implementing
, true));
4809 // For implicit implementations, make sure we are public, for
4810 // explicit implementations, make sure we are private.
4812 if (implementing
!= null){
4814 // Setting null inside this block will trigger a more
4815 // verbose error reporting for missing interface implementations
4817 // The "candidate" function has been flagged already
4818 // but it wont get cleared
4820 if (member
.IsExplicitImpl
){
4821 if ((modifiers
& (Modifiers
.PUBLIC
| Modifiers
.ABSTRACT
| Modifiers
.VIRTUAL
)) != 0){
4822 Modifiers
.Error_InvalidModifier (method
.Location
, "public, virtual or abstract");
4823 implementing
= null;
4825 } else if ((flags
& MethodAttributes
.MemberAccessMask
) != MethodAttributes
.Public
){
4826 if (TypeManager
.IsInterfaceType (implementing
.DeclaringType
)){
4828 // If this is an interface method implementation,
4829 // check for public accessibility
4831 implementing
= null;
4832 } else if ((flags
& MethodAttributes
.MemberAccessMask
) == MethodAttributes
.Private
){
4833 // We may never be private.
4834 implementing
= null;
4835 } else if ((modifiers
& Modifiers
.OVERRIDE
) == 0){
4837 // We may be protected if we're overriding something.
4839 implementing
= null;
4844 // Static is not allowed
4846 if ((modifiers
& Modifiers
.STATIC
) != 0){
4847 implementing
= null;
4852 // If implementing is still valid, set flags
4854 if (implementing
!= null){
4856 // When implementing interface methods, set NewSlot
4857 // unless, we are overwriting a method.
4859 if (implementing
.DeclaringType
.IsInterface
){
4860 if ((modifiers
& Modifiers
.OVERRIDE
) == 0)
4861 flags
|= MethodAttributes
.NewSlot
;
4864 MethodAttributes
.Virtual
|
4865 MethodAttributes
.HideBySig
;
4867 // Set Final unless we're virtual, abstract or already overriding a method.
4868 if ((modifiers
& (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
| Modifiers
.OVERRIDE
)) == 0)
4869 flags
|= MethodAttributes
.Final
;
4872 EmitContext ec
= method
.CreateEmitContext (container
, null);
4874 DefineMethodBuilder (container
, method_name
, method
.ParameterInfo
.Types
);
4876 if (builder
== null)
4879 if (container
.CurrentType
!= null)
4880 declaring_type
= container
.CurrentType
;
4882 declaring_type
= container
.TypeBuilder
;
4884 if ((modifiers
& Modifiers
.UNSAFE
) != 0)
4885 builder
.InitLocals
= false;
4887 if (implementing
!= null){
4889 // clear the pending implemntation flag
4891 if (member
is Indexer
) {
4892 pending
.ImplementIndexer (
4893 member
.InterfaceType
, builder
, method
.ReturnType
,
4894 method
.ParameterInfo
, member
.IsExplicitImpl
);
4896 pending
.ImplementMethod (
4897 member
.InterfaceType
, name
, method
.ReturnType
,
4898 method
.ParameterInfo
, member
.IsExplicitImpl
);
4900 if (member
.IsExplicitImpl
)
4901 container
.TypeBuilder
.DefineMethodOverride (
4902 builder
, implementing
);
4906 TypeManager
.AddMethod (builder
, method
);
4908 if (GenericMethod
!= null) {
4909 bool is_override
= member
.IsExplicitImpl
|
4910 ((modifiers
& Modifiers
.OVERRIDE
) != 0);
4912 if (implementing
!= null)
4913 parent_method
= implementing
;
4915 if (!GenericMethod
.DefineType (ec
, builder
, parent_method
, is_override
))
4924 /// Create the MethodBuilder for the method
4926 void DefineMethodBuilder (TypeContainer container
, string method_name
, Type
[] ParameterTypes
)
4928 const int extern_static
= Modifiers
.EXTERN
| Modifiers
.STATIC
;
4930 if ((modifiers
& extern_static
) == extern_static
) {
4932 if (method
.OptAttributes
!= null) {
4933 Attribute dllimport_attribute
= method
.OptAttributes
.Search (TypeManager
.dllimport_type
);
4934 if (dllimport_attribute
!= null) {
4935 flags
|= MethodAttributes
.PinvokeImpl
;
4936 builder
= dllimport_attribute
.DefinePInvokeMethod (
4937 container
.TypeBuilder
, method_name
, flags
,
4938 method
.ReturnType
, ParameterTypes
);
4944 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
4945 // We are more strict than Microsoft and report CS0626 like error
4946 if (method
.OptAttributes
== null ||
4947 !method
.OptAttributes
.Contains (TypeManager
.methodimpl_attr_type
)) {
4948 Report
.Error (626, method
.Location
, "Method, operator, or accessor `{0}' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation",
4949 method
.GetSignatureForError ());
4954 if (builder
== null) {
4955 builder
= container
.TypeBuilder
.DefineMethod (
4956 method_name
, flags
, method
.CallingConventions
,
4957 method
.ReturnType
, ParameterTypes
);
4961 builder
.SetGenericMethodSignature (
4962 flags
, method
.CallingConventions
,
4963 method
.ReturnType
, ParameterTypes
);
4970 public void Emit (DeclSpace parent
)
4973 if ((flags
& MethodAttributes
.PinvokeImpl
) == 0)
4974 ec
= method
.CreateEmitContext (parent
, builder
.GetILGenerator ());
4976 ec
= method
.CreateEmitContext (parent
, null);
4978 method
.ParameterInfo
.ApplyAttributes (MethodBuilder
);
4980 if (GenericMethod
!= null)
4981 GenericMethod
.EmitAttributes ();
4983 ToplevelBlock block
= method
.Block
;
4985 SourceMethod source
= SourceMethod
.Create (parent
, MethodBuilder
, method
.Block
);
4988 // Handle destructors specially
4990 // FIXME: This code generates buggy code
4992 if (member
is Destructor
)
4993 EmitDestructor (ec
, block
);
4995 ec
.EmitTopBlock (method
, block
);
4998 source
.CloseMethod ();
5001 void EmitDestructor (EmitContext ec
, ToplevelBlock block
)
5003 ILGenerator ig
= ec
.ig
;
5005 Label finish
= ig
.DefineLabel ();
5007 block
.SetDestructor ();
5009 ig
.BeginExceptionBlock ();
5010 ec
.ReturnLabel
= finish
;
5011 ec
.HasReturnLabel
= true;
5012 ec
.EmitTopBlock (method
, block
);
5014 // ig.MarkLabel (finish);
5015 ig
.BeginFinallyBlock ();
5017 if (ec
.ContainerType
.BaseType
!= null) {
5018 Expression member_lookup
= Expression
.MemberLookup (
5019 ec
.ContainerType
.BaseType
, null, ec
.ContainerType
.BaseType
,
5020 "Finalize", MemberTypes
.Method
, Expression
.AllBindingFlags
, method
.Location
);
5022 if (member_lookup
!= null){
5023 MethodGroupExpr base_destructor
= ((MethodGroupExpr
) member_lookup
);
5025 ig
.Emit (OpCodes
.Ldarg_0
);
5026 ig
.Emit (OpCodes
.Call
, (MethodInfo
) base_destructor
.Methods
[0]);
5030 ig
.EndExceptionBlock ();
5031 //ig.MarkLabel (ec.ReturnLabel);
5032 ig
.Emit (OpCodes
.Ret
);
5036 // TODO: Should derive from MethodCore
5037 public class Destructor
: Method
{
5039 static string[] attribute_targets
= new string [] { "method" }
;
5041 public Destructor (DeclSpace parent
, Expression return_type
, int mod
,
5042 string name
, Parameters parameters
, Attributes attrs
,
5044 : base (parent
, null, return_type
, mod
, false, new MemberName (name
, l
),
5048 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
5050 if (a
.Type
== TypeManager
.conditional_attribute_type
) {
5051 Error_ConditionalAttributeIsNotValid ();
5055 base.ApplyAttributeBuilder (a
, cb
);
5058 public override string GetSignatureForError ()
5060 return Parent
.GetSignatureForError () + ".~" + Parent
.MemberName
.Name
+ "()";
5063 public override string[] ValidAttributeTargets
{
5065 return attribute_targets
;
5070 abstract public class MemberBase
: MemberCore
{
5071 public Expression Type
;
5073 public MethodAttributes flags
;
5074 public readonly DeclSpace ds
;
5075 public readonly GenericMethod GenericMethod
;
5077 protected readonly int explicit_mod_flags
;
5080 // The "short" name of this property / indexer / event. This is the
5081 // name without the explicit interface.
5083 public string ShortName
{
5084 get { return MemberName.Name; }
5085 set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
5088 public TypeContainer ParentContainer
{
5089 get { return ((TypeContainer) Parent).PartialContainer; }
5093 // The type of this property / indexer / event
5095 protected Type member_type
;
5096 public Type MemberType
{
5098 if (member_type
== null && Type
!= null) {
5099 IResolveContext rc
= GenericMethod
== null ? this : (IResolveContext
)ds
;
5100 Type
= Type
.ResolveAsTypeTerminal (rc
, false);
5102 member_type
= Type
.Type
;
5110 // Whether this is an interface member.
5112 public bool IsInterface
;
5115 // If true, this is an explicit interface implementation
5117 public bool IsExplicitImpl
;
5120 // The interface type we are explicitly implementing
5122 public Type InterfaceType
= null;
5125 // The constructor is only exposed to our children
5127 protected MemberBase (DeclSpace parent
, GenericMethod generic
,
5128 Expression type
, int mod
, int allowed_mod
, int def_mod
,
5129 MemberName name
, Attributes attrs
)
5130 : base (parent
, name
, attrs
)
5132 this.ds
= generic
!= null ? generic
: (DeclSpace
) parent
;
5133 explicit_mod_flags
= mod
;
5135 ModFlags
= Modifiers
.Check (allowed_mod
, mod
, def_mod
, Location
);
5136 IsExplicitImpl
= (MemberName
.Left
!= null);
5137 GenericMethod
= generic
;
5138 if (GenericMethod
!= null)
5139 GenericMethod
.ModFlags
= ModFlags
;
5142 protected virtual bool CheckBase ()
5144 if ((ModFlags
& Modifiers
.PROTECTED
) != 0 && ParentContainer
.Kind
== Kind
.Struct
) {
5145 Report
.Error (666, Location
, "`{0}': new protected member declared in struct", GetSignatureForError ());
5149 if ((RootContext
.WarningLevel
>= 4) &&
5150 ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0) &&
5151 ((ModFlags
& Modifiers
.PROTECTED
) != 0) &&
5152 ((ModFlags
& Modifiers
.OVERRIDE
) == 0) && (Name
!= "Finalize")) {
5153 Report
.Warning (628, 4, Location
, "`{0}': new protected member declared in sealed class", GetSignatureForError ());
5158 protected virtual bool DoDefineBase ()
5161 throw new InternalErrorException ();
5164 ModFlags
= Modifiers
.PUBLIC
|
5165 Modifiers
.ABSTRACT
|
5166 Modifiers
.VIRTUAL
| (ModFlags
& Modifiers
.UNSAFE
) | (ModFlags
& Modifiers
.NEW
);
5168 flags
= MethodAttributes
.Public
|
5169 MethodAttributes
.Abstract
|
5170 MethodAttributes
.HideBySig
|
5171 MethodAttributes
.NewSlot
|
5172 MethodAttributes
.Virtual
;
5174 if (!ParentContainer
.MethodModifiersValid (this))
5177 flags
= Modifiers
.MethodAttr (ModFlags
);
5180 if (IsExplicitImpl
) {
5181 Expression expr
= MemberName
.Left
.GetTypeExpression ();
5182 TypeExpr iface_texpr
= expr
.ResolveAsTypeTerminal (this, false);
5183 if (iface_texpr
== null)
5186 InterfaceType
= iface_texpr
.Type
;
5188 if (!InterfaceType
.IsInterface
) {
5189 Report
.Error (538, Location
, "'{0}' in explicit interface declaration is not an interface", TypeManager
.CSharpName (InterfaceType
));
5193 if (!ParentContainer
.VerifyImplements (this))
5196 Modifiers
.Check (Modifiers
.AllowedExplicitImplFlags
, explicit_mod_flags
, 0, Location
);
5202 protected virtual bool DoDefine ()
5204 if (MemberType
== null)
5207 if ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0 &&
5208 (ModFlags
& (Modifiers
.VIRTUAL
|Modifiers
.ABSTRACT
)) != 0) {
5209 Report
.Error (549, Location
, "New virtual member `{0}' is declared in a sealed class `{1}'",
5210 GetSignatureForError (), Parent
.GetSignatureForError ());
5214 // verify accessibility
5215 if (!Parent
.AsAccessible (MemberType
, ModFlags
)) {
5216 Report
.SymbolRelatedToPreviousError (MemberType
);
5217 if (this is Property
)
5218 Report
.Error (53, Location
,
5219 "Inconsistent accessibility: property type `" +
5220 TypeManager
.CSharpName (MemberType
) + "' is less " +
5221 "accessible than property `" + GetSignatureForError () + "'");
5222 else if (this is Indexer
)
5223 Report
.Error (54, Location
,
5224 "Inconsistent accessibility: indexer return type `" +
5225 TypeManager
.CSharpName (MemberType
) + "' is less " +
5226 "accessible than indexer `" + GetSignatureForError () + "'");
5227 else if (this is MethodCore
) {
5228 if (this is Operator
)
5229 Report
.Error (56, Location
,
5230 "Inconsistent accessibility: return type `" +
5231 TypeManager
.CSharpName (MemberType
) + "' is less " +
5232 "accessible than operator `" + GetSignatureForError () + "'");
5234 Report
.Error (50, Location
,
5235 "Inconsistent accessibility: return type `" +
5236 TypeManager
.CSharpName (MemberType
) + "' is less " +
5237 "accessible than method `" + GetSignatureForError () + "'");
5239 Report
.Error (52, Location
,
5240 "Inconsistent accessibility: field type `" +
5241 TypeManager
.CSharpName (MemberType
) + "' is less " +
5242 "accessible than field `" + GetSignatureForError () + "'");
5247 if (IsExplicitImpl
) {
5248 Expression expr
= MemberName
.Left
.GetTypeExpression ();
5249 TypeExpr texpr
= expr
.ResolveAsTypeTerminal (this, false);
5253 InterfaceType
= texpr
.Type
;
5255 if (!InterfaceType
.IsInterface
) {
5256 Report
.Error (538, Location
, "`{0}' in explicit interface declaration is not an interface", TypeManager
.CSharpName (InterfaceType
));
5260 if (!ParentContainer
.VerifyImplements (this))
5263 Modifiers
.Check (Modifiers
.AllowedExplicitImplFlags
, explicit_mod_flags
, 0, Location
);
5269 protected bool IsTypePermitted ()
5271 if (MemberType
== TypeManager
.arg_iterator_type
|| MemberType
== TypeManager
.typed_reference_type
) {
5272 Report
.Error (610, Location
, "Field or property cannot be of type `{0}'", TypeManager
.CSharpName (MemberType
));
5278 protected override bool VerifyClsCompliance()
5280 if (base.VerifyClsCompliance ()) {
5284 if (IsInterface
&& HasClsCompliantAttribute
&& Parent
.IsClsComplianceRequired ()) {
5285 Report
.Error (3010, Location
, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
5293 // Fields and Events both generate FieldBuilders, we use this to share
5294 // their common bits. This is also used to flag usage of the field
5296 abstract public class FieldBase
: MemberBase
{
5297 public FieldBuilder FieldBuilder
;
5298 public Status status
;
5299 protected Expression initializer
;
5300 ExpressionStatement initializerStatement
;
5303 public enum Status
: byte {
5304 HAS_OFFSET
= 4 // Used by FieldMember.
5307 static string[] attribute_targets
= new string [] { "field" }
;
5310 /// Symbol with same name in base class/struct
5312 public MemberInfo conflict_symbol
;
5314 protected FieldBase (DeclSpace parent
, Expression type
, int mod
,
5315 int allowed_mod
, MemberName name
, Attributes attrs
)
5316 : base (parent
, null, type
, mod
, allowed_mod
, Modifiers
.PRIVATE
,
5321 public override AttributeTargets AttributeTargets
{
5323 return AttributeTargets
.Field
;
5327 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
5329 if (a
.Type
== TypeManager
.marshal_as_attr_type
) {
5330 UnmanagedMarshal marshal
= a
.GetMarshal (this);
5331 if (marshal
!= null) {
5332 FieldBuilder
.SetMarshal (marshal
);
5337 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
)) {
5338 a
.Error_InvalidSecurityParent ();
5342 FieldBuilder
.SetCustomAttribute (cb
);
5345 public void EmitInitializer (EmitContext ec
)
5347 initializerStatement
.EmitStatement (ec
);
5350 protected override bool CheckBase ()
5352 if (!base.CheckBase ())
5359 conflict_symbol
= ParentContainer
.FindBaseMemberWithSameName (Name
, false);
5360 if (conflict_symbol
== null) {
5361 if ((RootContext
.WarningLevel
>= 4) && ((ModFlags
& Modifiers
.NEW
) != 0)) {
5362 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5367 if ((ModFlags
& (Modifiers
.NEW
| Modifiers
.OVERRIDE
)) == 0) {
5368 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
5369 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5370 GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
5376 public Expression Initializer
{
5378 if (value != null) {
5379 this.initializer
= value;
5380 ParentContainer
.RegisterFieldForInitialization (this);
5385 protected virtual bool IsFieldClsCompliant
{
5387 if (FieldBuilder
== null)
5390 return AttributeTester
.IsClsCompliant (FieldBuilder
.FieldType
);
5394 public Expression
ResolveInitializer ()
5396 // TODO: again it's too heavy-weight
5397 EmitContext ec
= new EmitContext (this, Parent
, Location
, null, null, ModFlags
);
5398 ec
.IsFieldInitializer
= true;
5399 initializer
= initializer
.Resolve (ec
);
5400 if (initializer
== null)
5403 FieldExpr fe
= new FieldExpr (FieldBuilder
, Location
, true);
5404 if ((ModFlags
& Modifiers
.STATIC
) == 0)
5406 fe
.InstanceExpression
= CompilerGeneratedThis
.Instance
;
5409 initializerStatement
= new Assign (fe
, initializer
, Location
).ResolveStatement (ec
);
5413 public bool HasDefaultInitializer
5417 Constant c
= initializer
as Constant
;
5421 return c
.IsDefaultInitializer (MemberType
);
5425 public override string[] ValidAttributeTargets
5428 return attribute_targets
;
5432 protected override bool VerifyClsCompliance ()
5434 if (!base.VerifyClsCompliance ())
5437 if (!IsFieldClsCompliant
) {
5438 Report
.Error (3003, Location
, "Type of `{0}' is not CLS-compliant", GetSignatureForError ());
5444 public void SetAssigned ()
5446 caching_flags
|= Flags
.IsAssigned
;
5450 public abstract class FieldMember
: FieldBase
5452 protected FieldMember (DeclSpace parent
, Expression type
, int mod
,
5453 int allowed_mod
, MemberName name
, Attributes attrs
)
5454 : base (parent
, type
, mod
, allowed_mod
| Modifiers
.ABSTRACT
, name
, attrs
)
5456 if ((mod
& Modifiers
.ABSTRACT
) != 0)
5457 Report
.Error (681, Location
, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5460 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
5462 if (a
.Type
== TypeManager
.field_offset_attribute_type
)
5464 status
|= Status
.HAS_OFFSET
;
5466 if (!ParentContainer
.HasExplicitLayout
) {
5467 Report
.Error (636, Location
, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5471 if ((ModFlags
& Modifiers
.STATIC
) != 0 || this is Const
) {
5472 Report
.Error (637, Location
, "The FieldOffset attribute is not allowed on static or const fields");
5477 if (a
.Type
== TypeManager
.fixed_buffer_attr_type
) {
5478 Report
.Error (1716, Location
, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5482 base.ApplyAttributeBuilder (a
, cb
);
5485 public override bool Define()
5487 if (MemberType
== null || Type
== null)
5490 if (MemberType
== TypeManager
.void_type
) {
5491 Report
.Error (1547, Location
, "Keyword 'void' cannot be used in this context");
5498 if (!Parent
.AsAccessible (MemberType
, ModFlags
)) {
5499 Report
.Error (52, Location
,
5500 "Inconsistent accessibility: field type `" +
5501 TypeManager
.CSharpName (MemberType
) + "' is less " +
5502 "accessible than field `" + GetSignatureForError () + "'");
5506 if (!IsTypePermitted ())
5512 public override void Emit ()
5514 if (OptAttributes
!= null) {
5515 OptAttributes
.Emit ();
5518 if (((status
& Status
.HAS_OFFSET
) == 0) && (ModFlags
& Modifiers
.STATIC
) == 0 && ParentContainer
.HasExplicitLayout
) {
5519 Report
.Error (625, Location
, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
5526 // Represents header string for documentation comment.
5528 public override string DocCommentHeader
{
5529 get { return "F:"; }
5533 interface IFixedBuffer
5535 FieldInfo Element { get; }
5536 Type ElementType { get; }
5539 public class FixedFieldExternal
: IFixedBuffer
5541 FieldInfo element_field
;
5543 public FixedFieldExternal (FieldInfo fi
)
5545 element_field
= fi
.FieldType
.GetField (FixedField
.FixedElementName
);
5548 #region IFixedField Members
5550 public FieldInfo Element
{
5552 return element_field
;
5556 public Type ElementType
{
5558 return element_field
.FieldType
;
5566 /// Fixed buffer implementation
5568 public class FixedField
: FieldMember
, IFixedBuffer
5570 public const string FixedElementName
= "FixedElementField";
5571 static int GlobalCounter
= 0;
5572 static object[] ctor_args
= new object[] { (short)LayoutKind.Sequential }
;
5573 static FieldInfo
[] fi
;
5575 TypeBuilder fixed_buffer_type
;
5576 FieldBuilder element
;
5577 Expression size_expr
;
5580 const int AllowedModifiers
=
5583 Modifiers
.PROTECTED
|
5584 Modifiers
.INTERNAL
|
5587 public FixedField (DeclSpace parent
, Expression type
, int mod
, string name
,
5588 Expression size_expr
, Attributes attrs
, Location loc
):
5589 base (parent
, type
, mod
, AllowedModifiers
, new MemberName (name
, loc
), attrs
)
5591 if (RootContext
.Version
== LanguageVersion
.ISO_1
)
5592 Report
.FeatureIsNotStandardized (loc
, "fixed size buffers");
5594 this.size_expr
= size_expr
;
5597 public override bool Define()
5600 if ((ModFlags
& (Modifiers
.PUBLIC
| Modifiers
.PROTECTED
)) != 0)
5601 Report
.Warning (-23, 1, Location
, "Only private or internal fixed sized buffers are supported by .NET 1.x");
5604 if (ParentContainer
.Kind
!= Kind
.Struct
) {
5605 Report
.Error (1642, Location
, "`{0}': Fixed size buffer fields may only be members of structs",
5606 GetSignatureForError ());
5610 if (!base.Define ())
5613 if (!TypeManager
.IsPrimitiveType (MemberType
)) {
5614 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",
5615 GetSignatureForError ());
5619 EmitContext ec
= new EmitContext (this, Parent
, Location
, null, null, ModFlags
);
5620 Constant c
= size_expr
.ResolveAsConstant (ec
, this);
5624 IntConstant buffer_size_const
= c
.ToInt (Location
);
5625 if (buffer_size_const
== null)
5628 buffer_size
= buffer_size_const
.Value
;
5630 if (buffer_size
<= 0) {
5631 Report
.Error (1665, Location
, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5635 int type_size
= Expression
.GetTypeSize (MemberType
);
5637 if (buffer_size
> int.MaxValue
/ type_size
) {
5638 Report
.Error (1664, Location
, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5639 GetSignatureForError (), buffer_size
.ToString (), TypeManager
.CSharpName (MemberType
));
5643 buffer_size
*= type_size
;
5646 string name
= String
.Format ("<{0}>__FixedBuffer{1}", Name
, GlobalCounter
++);
5648 fixed_buffer_type
= Parent
.TypeBuilder
.DefineNestedType (name
,
5649 TypeAttributes
.NestedPublic
| TypeAttributes
.Sealed
| TypeAttributes
.BeforeFieldInit
, TypeManager
.value_type
);
5650 element
= fixed_buffer_type
.DefineField (FixedElementName
, MemberType
, FieldAttributes
.Public
);
5651 RootContext
.RegisterCompilerGeneratedType (fixed_buffer_type
);
5653 FieldBuilder
= Parent
.TypeBuilder
.DefineField (Name
, fixed_buffer_type
, Modifiers
.FieldAttr (ModFlags
));
5654 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
5659 public override void Emit()
5662 fi
= new FieldInfo
[] { TypeManager.struct_layout_attribute_type.GetField ("Size") }
;
5664 object[] fi_val
= new object[1];
5665 fi_val
[0] = buffer_size
;
5667 CustomAttributeBuilder cab
= new CustomAttributeBuilder (TypeManager
.struct_layout_attribute_ctor
,
5668 ctor_args
, fi
, fi_val
);
5669 fixed_buffer_type
.SetCustomAttribute (cab
);
5671 cab
= new CustomAttributeBuilder (TypeManager
.fixed_buffer_attr_ctor
, new object[] { MemberType, buffer_size }
);
5672 FieldBuilder
.SetCustomAttribute (cab
);
5676 protected override bool IsFieldClsCompliant
{
5682 #region IFixedField Members
5684 public FieldInfo Element
{
5690 public Type ElementType
{
5700 // The Field class is used to represents class/struct fields during parsing.
5702 public class Field
: FieldMember
{
5704 // Modifiers allowed in a class declaration
5706 const int AllowedModifiers
=
5709 Modifiers
.PROTECTED
|
5710 Modifiers
.INTERNAL
|
5713 Modifiers
.VOLATILE
|
5717 public Field (DeclSpace parent
, Expression type
, int mod
, string name
,
5718 Attributes attrs
, Location loc
)
5719 : base (parent
, type
, mod
, AllowedModifiers
, new MemberName (name
, loc
),
5724 public override bool Define ()
5726 if (!base.Define ())
5729 if (RootContext
.WarningLevel
> 1){
5730 Type ptype
= Parent
.TypeBuilder
.BaseType
;
5732 // ptype is only null for System.Object while compiling corlib.
5734 TypeContainer
.FindMembers (
5735 ptype
, MemberTypes
.Method
,
5736 BindingFlags
.Public
|
5737 BindingFlags
.Static
| BindingFlags
.Instance
,
5738 System
.Type
.FilterName
, Name
);
5742 if ((ModFlags
& Modifiers
.VOLATILE
) != 0){
5743 if (!MemberType
.IsClass
){
5744 Type vt
= MemberType
;
5746 if (TypeManager
.IsEnumType (vt
))
5747 vt
= TypeManager
.EnumToUnderlying (MemberType
);
5749 if (!((vt
== TypeManager
.bool_type
) ||
5750 (vt
== TypeManager
.sbyte_type
) ||
5751 (vt
== TypeManager
.byte_type
) ||
5752 (vt
== TypeManager
.short_type
) ||
5753 (vt
== TypeManager
.ushort_type
) ||
5754 (vt
== TypeManager
.int32_type
) ||
5755 (vt
== TypeManager
.uint32_type
) ||
5756 (vt
== TypeManager
.char_type
) ||
5757 (vt
== TypeManager
.float_type
) ||
5758 (!vt
.IsValueType
))){
5759 Report
.Error (677, Location
, "`{0}': A volatile field cannot be of the type `{1}'",
5760 GetSignatureForError (), TypeManager
.CSharpName (vt
));
5765 if ((ModFlags
& Modifiers
.READONLY
) != 0){
5766 Report
.Error (678, Location
, "`{0}': A field cannot be both volatile and readonly",
5767 GetSignatureForError ());
5772 FieldAttributes fa
= Modifiers
.FieldAttr (ModFlags
);
5774 if (ParentContainer
.Kind
== Kind
.Struct
&&
5775 ((fa
& FieldAttributes
.Static
) == 0) &&
5776 MemberType
== Parent
.TypeBuilder
&&
5777 !TypeManager
.IsBuiltinType (MemberType
)){
5778 Report
.Error (523, Location
, "Struct member `" + Parent
.Name
+ "." + Name
+
5779 "' causes a cycle in the structure layout");
5784 FieldBuilder
= Parent
.TypeBuilder
.DefineField (
5785 Name
, MemberType
, Modifiers
.FieldAttr (ModFlags
));
5787 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
5789 catch (ArgumentException
) {
5790 Report
.Warning (-24, 1, Location
, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
5797 protected override bool VerifyClsCompliance ()
5799 if (!base.VerifyClsCompliance ())
5802 if ((ModFlags
& Modifiers
.VOLATILE
) != 0) {
5803 Report
.Warning (3026, 1, Location
, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
5811 // `set' and `get' accessors are represented with an Accessor.
5813 public class Accessor
: IIteratorContainer
{
5815 // Null if the accessor is empty, or a Block if not
5817 public const int AllowedModifiers
=
5819 Modifiers
.PROTECTED
|
5820 Modifiers
.INTERNAL
|
5823 public ToplevelBlock Block
;
5824 public Attributes Attributes
;
5825 public Location Location
;
5826 public int ModFlags
;
5829 public Accessor (ToplevelBlock b
, int mod
, Attributes attrs
, Location loc
)
5834 ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, 0, loc
);
5837 public void SetYields ()
5843 // Ooouh Martin, templates are missing here.
5844 // When it will be possible move here a lot of child code and template method type.
5845 public abstract class AbstractPropertyEventMethod
: MemberCore
, IMethodData
{
5846 protected MethodData method_data
;
5847 protected ToplevelBlock block
;
5848 protected ListDictionary declarative_security
;
5850 // The accessor are created event if they are not wanted.
5851 // But we need them because their names are reserved.
5852 // Field says whether accessor will be emited or not
5853 public readonly bool IsDummy
;
5855 protected readonly string prefix
;
5857 ReturnParameter return_attributes
;
5859 public AbstractPropertyEventMethod (MemberBase member
, string prefix
)
5860 : base (member
.Parent
, SetupName (prefix
, member
, member
.Location
), null)
5862 this.prefix
= prefix
;
5866 public AbstractPropertyEventMethod (MemberBase member
, Accessor accessor
,
5868 : base (member
.Parent
, SetupName (prefix
, member
, accessor
.Location
),
5869 accessor
.Attributes
)
5871 this.prefix
= prefix
;
5872 this.block
= accessor
.Block
;
5875 static MemberName
SetupName (string prefix
, MemberBase member
, Location loc
)
5877 return new MemberName (member
.MemberName
.Left
, prefix
+ member
.ShortName
, loc
);
5880 public void UpdateName (MemberBase member
)
5882 SetMemberName (SetupName (prefix
, member
, Location
));
5885 #region IMethodData Members
5887 public ToplevelBlock Block
{
5897 public CallingConventions CallingConventions
{
5899 return CallingConventions
.Standard
;
5903 public bool IsExcluded ()
5908 GenericMethod IMethodData
.GenericMethod
{
5914 public MemberName MethodName
{
5920 public Type
[] ParameterTypes
{
5922 return ParameterInfo
.Types
;
5926 public abstract Parameters ParameterInfo { get ; }
5927 public abstract Type ReturnType { get; }
5928 public abstract EmitContext
CreateEmitContext (DeclSpace ds
, ILGenerator ig
);
5932 public override void ApplyAttributeBuilder(Attribute a
, CustomAttributeBuilder cb
)
5934 if (a
.Type
== TypeManager
.cls_compliant_attribute_type
|| a
.Type
== TypeManager
.obsolete_attribute_type
||
5935 a
.Type
== TypeManager
.conditional_attribute_type
) {
5936 Report
.Error (1667, a
.Location
,
5937 "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
5938 TypeManager
.CSharpName (a
.Type
), a
.GetValidTargets ());
5942 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
) && a
.CheckSecurityActionValidity (false)) {
5943 if (declarative_security
== null)
5944 declarative_security
= new ListDictionary ();
5945 a
.ExtractSecurityPermissionSet (declarative_security
);
5949 if (a
.Target
== AttributeTargets
.Method
) {
5950 method_data
.MethodBuilder
.SetCustomAttribute (cb
);
5954 if (a
.Target
== AttributeTargets
.ReturnValue
) {
5955 if (return_attributes
== null)
5956 return_attributes
= new ReturnParameter (method_data
.MethodBuilder
, Location
);
5958 return_attributes
.ApplyAttributeBuilder (a
, cb
);
5962 ApplyToExtraTarget (a
, cb
);
5965 virtual protected void ApplyToExtraTarget (Attribute a
, CustomAttributeBuilder cb
)
5967 System
.Diagnostics
.Debug
.Fail ("You forgot to define special attribute target handling");
5970 public override bool Define()
5972 throw new NotSupportedException ();
5975 public void Emit (DeclSpace parent
)
5977 EmitMethod (parent
);
5979 if (OptAttributes
!= null)
5980 OptAttributes
.Emit ();
5982 if (declarative_security
!= null) {
5983 foreach (DictionaryEntry de
in declarative_security
) {
5984 method_data
.MethodBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
5991 protected virtual void EmitMethod (DeclSpace parent
)
5993 method_data
.Emit (parent
);
5996 public override bool IsClsComplianceRequired()
6001 public bool IsDuplicateImplementation (MethodCore method
)
6003 if (!MemberName
.Equals (method
.MemberName
))
6006 Type
[] param_types
= method
.ParameterTypes
;
6008 if (param_types
.Length
!= ParameterTypes
.Length
)
6011 for (int i
= 0; i
< param_types
.Length
; i
++)
6012 if (param_types
[i
] != ParameterTypes
[i
])
6015 Report
.SymbolRelatedToPreviousError (method
);
6016 Report
.Error (111, Location
, TypeContainer
.Error111
, method
.GetSignatureForError ());
6020 public override bool IsUsed
6030 public new Location Location
{
6032 return base.Location
;
6037 // Represents header string for documentation comment.
6039 public override string DocCommentHeader
{
6040 get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6046 // Properties and Indexers both generate PropertyBuilders, we use this to share
6047 // their common bits.
6049 abstract public class PropertyBase
: MethodCore
{
6051 public class GetMethod
: PropertyMethod
6053 static string[] attribute_targets
= new string [] { "method", "return" }
;
6055 public GetMethod (MethodCore method
):
6056 base (method
, "get_")
6060 public GetMethod (MethodCore method
, Accessor accessor
):
6061 base (method
, accessor
, "get_")
6065 public override MethodBuilder
Define (DeclSpace parent
)
6067 base.Define (parent
);
6069 method_data
= new MethodData (method
, ModFlags
, flags
, this);
6071 if (!method_data
.Define (parent
))
6074 return method_data
.MethodBuilder
;
6077 public override Type ReturnType
{
6079 return method
.MemberType
;
6083 public override Parameters ParameterInfo
{
6085 return Parameters
.EmptyReadOnlyParameters
;
6089 public override string[] ValidAttributeTargets
{
6091 return attribute_targets
;
6096 public class SetMethod
: PropertyMethod
{
6098 static string[] attribute_targets
= new string [] { "method", "param", "return" }
;
6099 ImplicitParameter param_attr
;
6100 protected Parameters parameters
;
6102 public SetMethod (MethodCore method
):
6103 base (method
, "set_")
6107 public SetMethod (MethodCore method
, Accessor accessor
):
6108 base (method
, accessor
, "set_")
6112 protected override void ApplyToExtraTarget(Attribute a
, CustomAttributeBuilder cb
)
6114 if (a
.Target
== AttributeTargets
.Parameter
) {
6115 if (param_attr
== null)
6116 param_attr
= new ImplicitParameter (method_data
.MethodBuilder
);
6118 param_attr
.ApplyAttributeBuilder (a
, cb
);
6122 base.ApplyAttributeBuilder (a
, cb
);
6125 public override Parameters ParameterInfo
{
6131 protected virtual void DefineParameters ()
6133 parameters
= new Parameters (
6134 new Parameter
[] { new Parameter (method.MemberType, "value", Parameter.Modifier.NONE, null, Location) }
,
6135 new Type
[] { method.MemberType }
);
6138 public override MethodBuilder
Define (DeclSpace parent
)
6140 DefineParameters ();
6144 base.Define (parent
);
6146 method_data
= new MethodData (method
, ModFlags
, flags
, this);
6148 if (!method_data
.Define (parent
))
6151 return method_data
.MethodBuilder
;
6154 public override Type ReturnType
{
6156 return TypeManager
.void_type
;
6160 public override string[] ValidAttributeTargets
{
6162 return attribute_targets
;
6167 static string[] attribute_targets
= new string [] { "property" }
;
6169 public abstract class PropertyMethod
: AbstractPropertyEventMethod
6171 protected readonly MethodCore method
;
6172 protected MethodAttributes flags
;
6175 public PropertyMethod (MethodCore method
, string prefix
)
6176 : base (method
, prefix
)
6178 this.method
= method
;
6181 public PropertyMethod (MethodCore method
, Accessor accessor
,
6183 : base (method
, accessor
, prefix
)
6185 this.method
= method
;
6186 this.ModFlags
= accessor
.ModFlags
;
6187 yields
= accessor
.Yields
;
6189 if (accessor
.ModFlags
!= 0 && RootContext
.Version
== LanguageVersion
.ISO_1
) {
6190 Report
.FeatureIsNotStandardized (Location
, "access modifiers on properties");
6194 public override AttributeTargets AttributeTargets
{
6196 return AttributeTargets
.Method
;
6200 public override bool IsClsComplianceRequired ()
6202 return method
.IsClsComplianceRequired ();
6205 public virtual MethodBuilder
Define (DeclSpace parent
)
6207 if (!method
.CheckAbstractAndExtern (block
!= null))
6210 TypeContainer container
= ((TypeContainer
) parent
).PartialContainer
;
6213 // Check for custom access modifier
6215 if (ModFlags
== 0) {
6216 ModFlags
= method
.ModFlags
;
6217 flags
= method
.flags
;
6219 if (container
.Kind
== Kind
.Interface
)
6220 Report
.Error (275, Location
, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6221 GetSignatureForError ());
6223 if ((method
.ModFlags
& Modifiers
.ABSTRACT
) != 0 && (ModFlags
& Modifiers
.PRIVATE
) != 0) {
6224 Report
.Error (442, Location
, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6227 CheckModifiers (ModFlags
);
6228 ModFlags
|= (method
.ModFlags
& (~Modifiers
.Accessibility
));
6229 ModFlags
|= Modifiers
.PROPERTY_CUSTOM
;
6230 flags
= Modifiers
.MethodAttr (ModFlags
);
6231 flags
|= (method
.flags
& (~MethodAttributes
.MemberAccessMask
));
6235 // Setup iterator if we are one
6238 Iterator iterator
= new Iterator (this, Parent
as TypeContainer
, null, ModFlags
);
6240 if (!iterator
.DefineIterator ())
6247 public bool HasCustomAccessModifier
6250 return (ModFlags
& Modifiers
.PROPERTY_CUSTOM
) != 0;
6254 public override EmitContext
CreateEmitContext (DeclSpace ds
, ILGenerator ig
)
6256 return new EmitContext (method
,
6257 ds
, method
.ds
, method
.Location
, ig
, ReturnType
,
6258 method
.ModFlags
, false);
6261 public override ObsoleteAttribute
GetObsoleteAttribute ()
6263 return method
.GetObsoleteAttribute ();
6266 public override string GetSignatureForError()
6268 return method
.GetSignatureForError () + '.' + prefix
.Substring (0, 3);
6271 void CheckModifiers (int modflags
)
6274 int mflags
= method
.ModFlags
& Modifiers
.Accessibility
;
6276 if ((mflags
& Modifiers
.PUBLIC
) != 0) {
6277 flags
|= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
| Modifiers
.PRIVATE
;
6279 else if ((mflags
& Modifiers
.PROTECTED
) != 0) {
6280 if ((mflags
& Modifiers
.INTERNAL
) != 0)
6281 flags
|= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
;
6283 flags
|= Modifiers
.PRIVATE
;
6285 else if ((mflags
& Modifiers
.INTERNAL
) != 0)
6286 flags
|= Modifiers
.PRIVATE
;
6288 if ((mflags
== modflags
) || (modflags
& (~flags
)) != 0) {
6289 Report
.Error (273, Location
,
6290 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6291 GetSignatureForError (), method
.GetSignatureForError ());
6295 public override bool MarkForDuplicationCheck ()
6297 caching_flags
|= Flags
.TestMethodDuplication
;
6302 public PropertyMethod Get
, Set
;
6303 public PropertyBuilder PropertyBuilder
;
6304 public MethodBuilder GetBuilder
, SetBuilder
;
6306 protected EmitContext ec
;
6308 public PropertyBase (DeclSpace parent
, Expression type
, int mod_flags
,
6309 int allowed_mod
, bool is_iface
, MemberName name
,
6310 Parameters parameters
, Attributes attrs
)
6311 : base (parent
, null, type
, mod_flags
, allowed_mod
, is_iface
, name
,
6316 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
6318 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
)) {
6319 a
.Error_InvalidSecurityParent ();
6323 PropertyBuilder
.SetCustomAttribute (cb
);
6326 public override AttributeTargets AttributeTargets
{
6328 return AttributeTargets
.Property
;
6332 public override bool Define ()
6337 if (!IsTypePermitted ())
6343 protected override bool DoDefine ()
6345 if (!base.DoDefine ())
6349 // Accessors modifiers check
6351 if (Get
.ModFlags
!= 0 && Set
.ModFlags
!= 0) {
6352 Report
.Error (274, Location
, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6353 GetSignatureForError ());
6357 if ((Get
.IsDummy
|| Set
.IsDummy
)
6358 && (Get
.ModFlags
!= 0 || Set
.ModFlags
!= 0) && (ModFlags
& Modifiers
.OVERRIDE
) == 0) {
6359 Report
.Error (276, Location
,
6360 "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6361 GetSignatureForError ());
6365 if (MemberType
.IsAbstract
&& MemberType
.IsSealed
) {
6366 Report
.Error (722, Location
, Error722
, TypeManager
.CSharpName (MemberType
));
6370 ec
= new EmitContext (this, Parent
, Location
, null, MemberType
, ModFlags
);
6374 protected override bool CheckForDuplications ()
6376 ArrayList ar
= ParentContainer
.Indexers
;
6378 int arLen
= ar
.Count
;
6380 for (int i
= 0; i
< arLen
; i
++) {
6381 Indexer m
= (Indexer
) ar
[i
];
6382 if (IsDuplicateImplementation (m
))
6387 ar
= ParentContainer
.Properties
;
6389 int arLen
= ar
.Count
;
6391 for (int i
= 0; i
< arLen
; i
++) {
6392 Property m
= (Property
) ar
[i
];
6393 if (IsDuplicateImplementation (m
))
6401 // TODO: rename to Resolve......
6402 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
6404 PropertyInfo base_property
= ParentContainer
.BaseCache
.FindMemberToOverride (
6405 Parent
.TypeBuilder
, Name
, ParameterTypes
, null, true) as PropertyInfo
;
6407 if (base_property
== null)
6410 base_ret_type
= base_property
.PropertyType
;
6411 MethodInfo get_accessor
= base_property
.GetGetMethod (true);
6412 MethodInfo set_accessor
= base_property
.GetSetMethod (true);
6413 MethodAttributes get_accessor_access
, set_accessor_access
;
6415 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
6416 if (Get
!= null && !Get
.IsDummy
&& get_accessor
== null) {
6417 Report
.SymbolRelatedToPreviousError (base_property
);
6418 Report
.Error (545, Location
, "`{0}.get': cannot override because `{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager
.GetFullNameSignature (base_property
));
6421 if (Set
!= null && !Set
.IsDummy
&& set_accessor
== null) {
6422 Report
.SymbolRelatedToPreviousError (base_property
);
6423 Report
.Error (546, Location
, "`{0}.set': cannot override because `{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager
.GetFullNameSignature (base_property
));
6428 // Check base class accessors access
6431 // TODO: rewrite to reuse Get|Set.CheckAccessModifiers and share code there
6432 get_accessor_access
= set_accessor_access
= 0;
6433 if ((ModFlags
& Modifiers
.NEW
) == 0) {
6434 if (get_accessor
!= null) {
6435 MethodAttributes get_flags
= Modifiers
.MethodAttr (Get
.ModFlags
!= 0 ? Get
.ModFlags
: ModFlags
);
6436 get_accessor_access
= (get_accessor
.Attributes
& MethodAttributes
.MemberAccessMask
);
6438 if (!Get
.IsDummy
&& !CheckAccessModifiers (get_flags
& MethodAttributes
.MemberAccessMask
, get_accessor_access
, get_accessor
))
6439 Error_CannotChangeAccessModifiers (get_accessor
, get_accessor_access
, ".get");
6442 if (set_accessor
!= null) {
6443 MethodAttributes set_flags
= Modifiers
.MethodAttr (Set
.ModFlags
!= 0 ? Set
.ModFlags
: ModFlags
);
6444 set_accessor_access
= (set_accessor
.Attributes
& MethodAttributes
.MemberAccessMask
);
6446 if (!Set
.IsDummy
&& !CheckAccessModifiers (set_flags
& MethodAttributes
.MemberAccessMask
, set_accessor_access
, set_accessor
))
6447 Error_CannotChangeAccessModifiers (set_accessor
, set_accessor_access
, ".set");
6452 // Get the less restrictive access
6454 return get_accessor_access
> set_accessor_access
? get_accessor
: set_accessor
;
6457 public override void Emit ()
6460 // The PropertyBuilder can be null for explicit implementations, in that
6461 // case, we do not actually emit the ".property", so there is nowhere to
6462 // put the attribute
6464 if (PropertyBuilder
!= null && OptAttributes
!= null)
6465 OptAttributes
.Emit ();
6477 /// Tests whether accessors are not in collision with some method (CS0111)
6479 public bool AreAccessorsDuplicateImplementation (MethodCore mc
)
6481 return Get
.IsDuplicateImplementation (mc
) || Set
.IsDuplicateImplementation (mc
);
6484 public override bool IsUsed
6490 return Get
.IsUsed
| Set
.IsUsed
;
6494 protected override void SetMemberName (MemberName new_name
)
6496 base.SetMemberName (new_name
);
6498 Get
.UpdateName (this);
6499 Set
.UpdateName (this);
6502 public override string[] ValidAttributeTargets
{
6504 return attribute_targets
;
6509 // Represents header string for documentation comment.
6511 public override string DocCommentHeader
{
6512 get { return "P:"; }
6516 public class Property
: PropertyBase
{
6517 const int AllowedModifiers
=
6520 Modifiers
.PROTECTED
|
6521 Modifiers
.INTERNAL
|
6525 Modifiers
.OVERRIDE
|
6526 Modifiers
.ABSTRACT
|
6529 Modifiers
.METHOD_YIELDS
|
6532 const int AllowedInterfaceModifiers
=
6535 public Property (DeclSpace parent
, Expression type
, int mod
, bool is_iface
,
6536 MemberName name
, Attributes attrs
, Accessor get_block
,
6538 : base (parent
, type
, mod
,
6539 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
6540 is_iface
, name
, Parameters
.EmptyReadOnlyParameters
, attrs
)
6542 if (get_block
== null)
6543 Get
= new GetMethod (this);
6545 Get
= new GetMethod (this, get_block
);
6547 if (set_block
== null)
6548 Set
= new SetMethod (this);
6550 Set
= new SetMethod (this, set_block
);
6553 public override bool Define ()
6555 if (!DoDefineBase ())
6558 if (!base.Define ())
6564 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
6567 GetBuilder
= Get
.Define (Parent
);
6568 if (GetBuilder
== null)
6572 SetBuilder
= Set
.Define (Parent
);
6574 if (SetBuilder
== null)
6578 // FIXME - PropertyAttributes.HasDefault ?
6580 PropertyBuilder
= Parent
.TypeBuilder
.DefineProperty (
6581 MemberName
.ToString (), PropertyAttributes
.None
, MemberType
, null);
6584 PropertyBuilder
.SetGetMethod (GetBuilder
);
6587 PropertyBuilder
.SetSetMethod (SetBuilder
);
6589 TypeManager
.RegisterProperty (PropertyBuilder
, this);
6595 /// Gigantic workaround for lameness in SRE follows :
6596 /// This class derives from EventInfo and attempts to basically
6597 /// wrap around the EventBuilder so that FindMembers can quickly
6598 /// return this in it search for members
6600 public class MyEventBuilder
: EventInfo
{
6603 // We use this to "point" to our Builder which is
6604 // not really a MemberInfo
6606 EventBuilder MyBuilder
;
6609 // We "catch" and wrap these methods
6611 MethodInfo raise
, remove, add;
6613 EventAttributes attributes
;
6614 Type declaring_type
, reflected_type
, event_type
;
6619 public MyEventBuilder (Event ev
, TypeBuilder type_builder
, string name
, EventAttributes event_attr
, Type event_type
)
6621 MyBuilder
= type_builder
.DefineEvent (name
, event_attr
, event_type
);
6623 // And now store the values in our own fields.
6625 declaring_type
= type_builder
;
6627 reflected_type
= type_builder
;
6629 attributes
= event_attr
;
6632 this.event_type
= event_type
;
6636 // Methods that you have to override. Note that you only need
6637 // to "implement" the variants that take the argument (those are
6638 // the "abstract" methods, the others (GetAddMethod()) are
6641 public override MethodInfo
GetAddMethod (bool nonPublic
)
6646 public override MethodInfo
GetRemoveMethod (bool nonPublic
)
6651 public override MethodInfo
GetRaiseMethod (bool nonPublic
)
6657 // These methods make "MyEventInfo" look like a Builder
6659 public void SetRaiseMethod (MethodBuilder raiseMethod
)
6661 raise
= raiseMethod
;
6662 MyBuilder
.SetRaiseMethod (raiseMethod
);
6665 public void SetRemoveOnMethod (MethodBuilder removeMethod
)
6667 remove = removeMethod
;
6668 MyBuilder
.SetRemoveOnMethod (removeMethod
);
6671 public void SetAddOnMethod (MethodBuilder addMethod
)
6674 MyBuilder
.SetAddOnMethod (addMethod
);
6677 public void SetCustomAttribute (CustomAttributeBuilder cb
)
6679 MyBuilder
.SetCustomAttribute (cb
);
6682 public override object [] GetCustomAttributes (bool inherit
)
6684 // FIXME : There's nothing which can be seemingly done here because
6685 // we have no way of getting at the custom attribute objects of the
6690 public override object [] GetCustomAttributes (Type t
, bool inherit
)
6692 // FIXME : Same here !
6696 public override bool IsDefined (Type t
, bool b
)
6701 public override EventAttributes Attributes
{
6707 public override string Name
{
6713 public override Type DeclaringType
{
6715 return declaring_type
;
6719 public override Type ReflectedType
{
6721 return reflected_type
;
6725 public Type EventType
{
6731 public void SetUsed ()
6733 if (my_event
!= null) {
6734 my_event
.SetAssigned ();
6735 my_event
.SetMemberIsUsed ();
6741 /// For case when event is declared like property (with add and remove accessors).
6743 public class EventProperty
: Event
{
6745 static string[] attribute_targets
= new string [] { "event" }
; // "property" target was disabled for 2.0 version
6747 public EventProperty (DeclSpace parent
, Expression type
, int mod_flags
,
6748 bool is_iface
, MemberName name
,
6749 Attributes attrs
, Accessor
add, Accessor
remove)
6750 : base (parent
, type
, mod_flags
, is_iface
, name
, attrs
)
6752 Add
= new AddDelegateMethod (this, add);
6753 Remove
= new RemoveDelegateMethod (this, remove);
6755 // For this event syntax we don't report error CS0067
6756 // because it is hard to do it.
6760 public override string[] ValidAttributeTargets
{
6762 return attribute_targets
;
6768 /// Event is declared like field.
6770 public class EventField
: Event
{
6772 static string[] attribute_targets
= new string [] { "event", "field", "method" }
;
6773 static string[] attribute_targets_interface
= new string[] { "event", "method" }
;
6775 public EventField (DeclSpace parent
, Expression type
, int mod_flags
,
6776 bool is_iface
, MemberName name
,
6778 : base (parent
, type
, mod_flags
, is_iface
, name
, attrs
)
6780 Add
= new AddDelegateMethod (this);
6781 Remove
= new RemoveDelegateMethod (this);
6784 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
6786 if (a
.Target
== AttributeTargets
.Field
) {
6787 FieldBuilder
.SetCustomAttribute (cb
);
6791 if (a
.Target
== AttributeTargets
.Method
) {
6792 Add
.ApplyAttributeBuilder (a
, cb
);
6793 Remove
.ApplyAttributeBuilder (a
, cb
);
6797 base.ApplyAttributeBuilder (a
, cb
);
6800 public override bool Define()
6802 if (!base.Define ())
6805 if (initializer
!= null) {
6806 if (((ModFlags
& Modifiers
.ABSTRACT
) != 0)) {
6807 Report
.Error (74, Location
, "`{0}': abstract event cannot have an initializer",
6808 GetSignatureForError ());
6816 public override string[] ValidAttributeTargets
{
6818 return IsInterface
? attribute_targets_interface
: attribute_targets
;
6823 public abstract class Event
: FieldBase
{
6825 protected sealed class AddDelegateMethod
: DelegateMethod
6828 public AddDelegateMethod (Event method
):
6829 base (method
, "add_")
6833 public AddDelegateMethod (Event method
, Accessor accessor
):
6834 base (method
, accessor
, "add_")
6838 protected override MethodInfo DelegateMethodInfo
{
6840 return TypeManager
.delegate_combine_delegate_delegate
;
6846 protected sealed class RemoveDelegateMethod
: DelegateMethod
6848 public RemoveDelegateMethod (Event method
):
6849 base (method
, "remove_")
6853 public RemoveDelegateMethod (Event method
, Accessor accessor
):
6854 base (method
, accessor
, "remove_")
6858 protected override MethodInfo DelegateMethodInfo
{
6860 return TypeManager
.delegate_remove_delegate_delegate
;
6866 public abstract class DelegateMethod
: AbstractPropertyEventMethod
6868 protected readonly Event method
;
6869 ImplicitParameter param_attr
;
6871 static string[] attribute_targets
= new string [] { "method", "param", "return" }
;
6873 public DelegateMethod (Event method
, string prefix
)
6874 : base (method
, prefix
)
6876 this.method
= method
;
6879 public DelegateMethod (Event method
, Accessor accessor
, string prefix
)
6880 : base (method
, accessor
, prefix
)
6882 this.method
= method
;
6885 protected override void ApplyToExtraTarget(Attribute a
, CustomAttributeBuilder cb
)
6887 if (a
.Target
== AttributeTargets
.Parameter
) {
6888 if (param_attr
== null)
6889 param_attr
= new ImplicitParameter (method_data
.MethodBuilder
);
6891 param_attr
.ApplyAttributeBuilder (a
, cb
);
6895 base.ApplyAttributeBuilder (a
, cb
);
6898 public override AttributeTargets AttributeTargets
{
6900 return AttributeTargets
.Method
;
6904 public override bool IsClsComplianceRequired ()
6906 return method
.IsClsComplianceRequired ();
6909 public MethodBuilder
Define (DeclSpace parent
)
6911 method_data
= new MethodData (method
, method
.ModFlags
,
6912 method
.flags
| MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
, this);
6914 if (!method_data
.Define (parent
))
6917 MethodBuilder mb
= method_data
.MethodBuilder
;
6918 ParameterInfo
.ApplyAttributes (mb
);
6923 protected override void EmitMethod (DeclSpace parent
)
6925 if (block
!= null) {
6926 base.EmitMethod (parent
);
6930 if ((method
.ModFlags
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) != 0)
6933 ILGenerator ig
= method_data
.MethodBuilder
.GetILGenerator ();
6934 FieldInfo field_info
= (FieldInfo
)method
.FieldBuilder
;
6936 method_data
.MethodBuilder
.SetImplementationFlags (MethodImplAttributes
.Synchronized
);
6937 if ((method
.ModFlags
& Modifiers
.STATIC
) != 0) {
6938 ig
.Emit (OpCodes
.Ldsfld
, field_info
);
6939 ig
.Emit (OpCodes
.Ldarg_0
);
6940 ig
.Emit (OpCodes
.Call
, DelegateMethodInfo
);
6941 ig
.Emit (OpCodes
.Castclass
, method
.MemberType
);
6942 ig
.Emit (OpCodes
.Stsfld
, field_info
);
6944 ig
.Emit (OpCodes
.Ldarg_0
);
6945 ig
.Emit (OpCodes
.Ldarg_0
);
6946 ig
.Emit (OpCodes
.Ldfld
, field_info
);
6947 ig
.Emit (OpCodes
.Ldarg_1
);
6948 ig
.Emit (OpCodes
.Call
, DelegateMethodInfo
);
6949 ig
.Emit (OpCodes
.Castclass
, method
.MemberType
);
6950 ig
.Emit (OpCodes
.Stfld
, field_info
);
6952 ig
.Emit (OpCodes
.Ret
);
6955 protected abstract MethodInfo DelegateMethodInfo { get; }
6957 public override Type ReturnType
{
6959 return TypeManager
.void_type
;
6963 public override EmitContext
CreateEmitContext (DeclSpace ds
, ILGenerator ig
)
6965 return new EmitContext (
6966 ds
, method
.Parent
, Location
, ig
, ReturnType
,
6967 method
.ModFlags
, false);
6970 public override ObsoleteAttribute
GetObsoleteAttribute ()
6972 return method
.GetObsoleteAttribute ();
6975 public override string[] ValidAttributeTargets
{
6977 return attribute_targets
;
6981 public override Parameters ParameterInfo
{
6983 return method
.parameters
;
6990 const int AllowedModifiers
=
6993 Modifiers
.PROTECTED
|
6994 Modifiers
.INTERNAL
|
6999 Modifiers
.OVERRIDE
|
7003 const int AllowedInterfaceModifiers
=
7006 public DelegateMethod Add
, Remove
;
7007 public MyEventBuilder EventBuilder
;
7008 public MethodBuilder AddBuilder
, RemoveBuilder
;
7009 Parameters parameters
;
7011 protected Event (DeclSpace parent
, Expression type
, int mod_flags
,
7012 bool is_iface
, MemberName name
, Attributes attrs
)
7013 : base (parent
, type
, mod_flags
,
7014 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
7017 IsInterface
= is_iface
;
7020 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
7022 if (a
.Type
.IsSubclassOf (TypeManager
.security_attr_type
)) {
7023 a
.Error_InvalidSecurityParent ();
7027 EventBuilder
.SetCustomAttribute (cb
);
7030 public bool AreAccessorsDuplicateImplementation (MethodCore mc
)
7032 return Add
.IsDuplicateImplementation (mc
) || Remove
.IsDuplicateImplementation (mc
);
7035 public override AttributeTargets AttributeTargets
{
7037 return AttributeTargets
.Event
;
7041 public override bool Define ()
7043 EventAttributes e_attr
;
7044 e_attr
= EventAttributes
.None
;
7046 if (!DoDefineBase ())
7052 if (!TypeManager
.IsDelegateType (MemberType
)) {
7053 Report
.Error (66, Location
, "`{0}': event must be of a delegate type", GetSignatureForError ());
7057 parameters
= new Parameters (
7058 new Parameter
[] { new Parameter (MemberType, "value", Parameter.Modifier.NONE, null, Location) }
,
7059 new Type
[] { MemberType }
);
7065 // Now define the accessors
7068 AddBuilder
= Add
.Define (Parent
);
7069 if (AddBuilder
== null)
7072 RemoveBuilder
= Remove
.Define (Parent
);
7073 if (RemoveBuilder
== null)
7076 EventBuilder
= new MyEventBuilder (this, Parent
.TypeBuilder
, Name
, e_attr
, MemberType
);
7078 if (Add
.Block
== null && Remove
.Block
== null && !IsInterface
) {
7079 FieldBuilder
= Parent
.TypeBuilder
.DefineField (
7081 FieldAttributes
.Private
| ((ModFlags
& Modifiers
.STATIC
) != 0 ? FieldAttributes
.Static
: 0));
7082 TypeManager
.RegisterPrivateFieldOfEvent (
7083 (EventInfo
) EventBuilder
, FieldBuilder
);
7084 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
7087 EventBuilder
.SetAddOnMethod (AddBuilder
);
7088 EventBuilder
.SetRemoveOnMethod (RemoveBuilder
);
7090 TypeManager
.RegisterEvent (EventBuilder
, AddBuilder
, RemoveBuilder
);
7094 protected override bool CheckBase ()
7096 if (!base.CheckBase ())
7099 if (conflict_symbol
!= null && (ModFlags
& Modifiers
.NEW
) == 0) {
7100 if (!(conflict_symbol
is EventInfo
)) {
7101 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
7102 Report
.Error (72, Location
, "Event `{0}' can override only event", GetSignatureForError ());
7110 public override void Emit ()
7112 if (OptAttributes
!= null) {
7113 OptAttributes
.Emit ();
7117 Remove
.Emit (Parent
);
7122 public override string GetSignatureForError ()
7124 return base.GetSignatureForError ();
7128 // Represents header string for documentation comment.
7130 public override string DocCommentHeader
{
7131 get { return "E:"; }
7136 public class Indexer
: PropertyBase
, IIteratorContainer
{
7138 class GetIndexerMethod
: GetMethod
7140 public GetIndexerMethod (MethodCore method
):
7145 public GetIndexerMethod (MethodCore method
, Accessor accessor
):
7146 base (method
, accessor
)
7150 public override Parameters ParameterInfo
{
7152 return method
.ParameterInfo
;
7157 class SetIndexerMethod
: SetMethod
7159 public SetIndexerMethod (MethodCore method
):
7164 public SetIndexerMethod (MethodCore method
, Accessor accessor
):
7165 base (method
, accessor
)
7169 protected override void DefineParameters ()
7171 parameters
= Parameters
.MergeGenerated (method
.Parameters
,
7172 new Parameter (method
.MemberType
, "value", Parameter
.Modifier
.NONE
, null, method
.Location
));
7176 const int AllowedModifiers
=
7179 Modifiers
.PROTECTED
|
7180 Modifiers
.INTERNAL
|
7184 Modifiers
.OVERRIDE
|
7189 const int AllowedInterfaceModifiers
=
7193 // Are we implementing an interface ?
7195 public Indexer (DeclSpace parent
, Expression type
, MemberName name
, int mod
,
7196 bool is_iface
, Parameters parameters
, Attributes attrs
,
7197 Accessor get_block
, Accessor set_block
)
7198 : base (parent
, type
, mod
,
7199 is_iface
? AllowedInterfaceModifiers
: AllowedModifiers
,
7200 is_iface
, name
, parameters
, attrs
)
7202 if (get_block
== null)
7203 Get
= new GetIndexerMethod (this);
7205 Get
= new GetIndexerMethod (this, get_block
);
7207 if (set_block
== null)
7208 Set
= new SetIndexerMethod (this);
7210 Set
= new SetIndexerMethod (this, set_block
);
7213 public override bool Define ()
7215 if (!DoDefineBase ())
7218 if (!base.Define ())
7221 if (MemberType
== TypeManager
.void_type
) {
7222 Report
.Error (620, Location
, "Indexers cannot have void type");
7226 if (OptAttributes
!= null) {
7227 Attribute indexer_attr
= OptAttributes
.Search (TypeManager
.indexer_name_type
);
7228 if (indexer_attr
!= null) {
7229 // Remove the attribute from the list because it is not emitted
7230 OptAttributes
.Attrs
.Remove (indexer_attr
);
7232 string name
= indexer_attr
.GetIndexerAttributeValue ();
7238 if (IsExplicitImpl
) {
7239 Report
.Error (415, indexer_attr
.Location
,
7240 "The `IndexerName' attribute is valid only on an " +
7241 "indexer that is not an explicit interface member declaration");
7245 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
7246 Report
.Error (609, indexer_attr
.Location
,
7247 "Cannot set the `IndexerName' attribute on an indexer marked override");
7253 if (InterfaceType
!= null) {
7254 string base_IndexerName
= TypeManager
.IndexerPropertyName (InterfaceType
);
7255 if (base_IndexerName
!= Name
)
7256 ShortName
= base_IndexerName
;
7259 if (!ParentContainer
.AddToMemberContainer (this) ||
7260 !ParentContainer
.AddToMemberContainer (Get
) || !ParentContainer
.AddToMemberContainer (Set
))
7266 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
7268 GetBuilder
= Get
.Define (Parent
);
7269 if (GetBuilder
== null)
7273 // Setup iterator if we are one
7275 if ((ModFlags
& Modifiers
.METHOD_YIELDS
) != 0){
7276 Iterator iterator
= new Iterator (
7277 Get
, Parent
, null, ModFlags
);
7279 if (!iterator
.DefineIterator ())
7284 SetBuilder
= Set
.Define (Parent
);
7286 if (SetBuilder
== null)
7291 // Now name the parameters
7293 Parameter
[] p
= Parameters
.FixedParameters
;
7295 // TODO: should be done in parser and it needs to do cycle
7296 if ((p
[0].ModFlags
& Parameter
.Modifier
.ISBYREF
) != 0) {
7297 Report
.Error (631, Location
, "ref and out are not valid in this context");
7302 PropertyBuilder
= Parent
.TypeBuilder
.DefineProperty (
7303 Name
, PropertyAttributes
.None
, MemberType
, ParameterTypes
);
7306 PropertyBuilder
.SetGetMethod (GetBuilder
);
7309 PropertyBuilder
.SetSetMethod (SetBuilder
);
7311 TypeManager
.RegisterIndexer (PropertyBuilder
, GetBuilder
, SetBuilder
, ParameterTypes
);
7316 public override string GetSignatureForError ()
7318 StringBuilder sb
= new StringBuilder (Parent
.GetSignatureForError ());
7319 if (MemberName
.Left
!= null) {
7321 sb
.Append (MemberName
.Left
);
7324 sb
.Append (".this");
7325 sb
.Append (Parameters
.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7326 return sb
.ToString ();
7329 public override bool MarkForDuplicationCheck ()
7331 caching_flags
|= Flags
.TestMethodDuplication
;
7336 public class Operator
: MethodOrOperator
, IIteratorContainer
{
7338 const int AllowedModifiers
=
7344 public enum OpType
: byte {
7354 // Unary and Binary operators
7377 // Implicit and Explicit
7381 // Just because of enum
7385 public readonly OpType OperatorType
;
7387 public Operator (DeclSpace parent
, OpType type
, Expression ret_type
,
7388 int mod_flags
, Parameters parameters
,
7389 ToplevelBlock block
, Attributes attrs
, Location loc
)
7390 : base (parent
, null, ret_type
, mod_flags
, AllowedModifiers
, false,
7391 new MemberName ("op_" + type
, loc
), attrs
, parameters
)
7393 OperatorType
= type
;
7397 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
)
7399 if (a
.Type
== TypeManager
.conditional_attribute_type
) {
7400 Error_ConditionalAttributeIsNotValid ();
7404 base.ApplyAttributeBuilder (a
, cb
);
7407 protected override bool CheckForDuplications ()
7409 ArrayList ar
= ParentContainer
.Operators
;
7411 int arLen
= ar
.Count
;
7413 for (int i
= 0; i
< arLen
; i
++) {
7414 Operator o
= (Operator
) ar
[i
];
7415 if (IsDuplicateImplementation (o
))
7420 ar
= ParentContainer
.Methods
;
7422 int arLen
= ar
.Count
;
7424 for (int i
= 0; i
< arLen
; i
++) {
7425 Method m
= (Method
) ar
[i
];
7426 if (IsDuplicateImplementation (m
))
7434 public override bool Define ()
7436 const int RequiredModifiers
= Modifiers
.PUBLIC
| Modifiers
.STATIC
;
7437 if ((ModFlags
& RequiredModifiers
) != RequiredModifiers
){
7438 Report
.Error (558, Location
, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7442 if (!base.Define ())
7445 if (MemberType
== TypeManager
.void_type
) {
7446 Report
.Error (590, Location
, "User-defined operators cannot return void");
7450 Type declaring_type
= MethodData
.DeclaringType
;
7451 Type return_type
= MemberType
;
7452 Type first_arg_type
= ParameterTypes
[0];
7454 // Rules for conversion operators
7456 if (OperatorType
== OpType
.Implicit
|| OperatorType
== OpType
.Explicit
) {
7457 if (first_arg_type
== return_type
&& first_arg_type
== declaring_type
){
7458 Report
.Error (555, Location
,
7459 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7463 if (first_arg_type
!= declaring_type
&& return_type
!= declaring_type
){
7466 "User-defined conversion must convert to or from the " +
7471 if (first_arg_type
.IsInterface
|| return_type
.IsInterface
){
7472 Report
.Error (552, Location
, "User-defined conversion `{0}' cannot convert to or from an interface type",
7473 GetSignatureForError ());
7477 if (first_arg_type
.IsSubclassOf (return_type
) || return_type
.IsSubclassOf (first_arg_type
)) {
7478 if (declaring_type
.IsSubclassOf (return_type
) || declaring_type
.IsSubclassOf (first_arg_type
)) {
7479 Report
.Error (553, Location
, "User-defined conversion `{0}' cannot convert to or from base class",
7480 GetSignatureForError ());
7483 Report
.Error (554, Location
, "User-defined conversion `{0}' cannot convert to or from derived class",
7484 GetSignatureForError ());
7487 } else if (OperatorType
== OpType
.LeftShift
|| OperatorType
== OpType
.RightShift
) {
7488 if (first_arg_type
!= declaring_type
|| ParameterTypes
[1] != TypeManager
.int32_type
) {
7489 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");
7492 } else if (Parameters
.Count
== 1) {
7493 // Checks for Unary operators
7495 if (OperatorType
== OpType
.Increment
|| OperatorType
== OpType
.Decrement
) {
7496 if (return_type
!= declaring_type
&& !TypeManager
.IsSubclassOf (return_type
, declaring_type
)) {
7497 Report
.Error (448, Location
,
7498 "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7501 if (first_arg_type
!= declaring_type
) {
7503 559, Location
, "The parameter type for ++ or -- operator must be the containing type");
7508 if (first_arg_type
!= declaring_type
){
7511 "The parameter of a unary operator must be the " +
7516 if (OperatorType
== OpType
.True
|| OperatorType
== OpType
.False
) {
7517 if (return_type
!= TypeManager
.bool_type
){
7520 "The return type of operator True or False " +
7527 // Checks for Binary operators
7529 if (first_arg_type
!= declaring_type
&&
7530 ParameterTypes
[1] != declaring_type
){
7533 "One of the parameters of a binary operator must " +
7534 "be the containing type");
7542 protected override bool DoDefine ()
7544 if (!base.DoDefine ())
7547 flags
|= MethodAttributes
.SpecialName
| MethodAttributes
.HideBySig
;
7551 public override void Emit ()
7555 Parameters
.ApplyAttributes (MethodBuilder
);
7558 // abstract or extern methods have no bodies
7560 if ((ModFlags
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) != 0)
7564 if ((flags
& MethodAttributes
.PinvokeImpl
) == 0)
7565 ec
= CreateEmitContext (Parent
, MethodBuilder
.GetILGenerator ());
7567 ec
= CreateEmitContext (Parent
, null);
7569 SourceMethod source
= SourceMethod
.Create (Parent
, MethodBuilder
, Block
);
7570 ec
.EmitTopBlock (this, Block
);
7573 source
.CloseMethod ();
7578 // Operator cannot be override
7579 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
7584 public static string GetName (OpType ot
)
7587 case OpType
.LogicalNot
:
7589 case OpType
.OnesComplement
:
7591 case OpType
.Increment
:
7593 case OpType
.Decrement
:
7599 case OpType
.Addition
:
7601 case OpType
.Subtraction
:
7603 case OpType
.UnaryPlus
:
7605 case OpType
.UnaryNegation
:
7607 case OpType
.Multiply
:
7609 case OpType
.Division
:
7611 case OpType
.Modulus
:
7613 case OpType
.BitwiseAnd
:
7615 case OpType
.BitwiseOr
:
7617 case OpType
.ExclusiveOr
:
7619 case OpType
.LeftShift
:
7621 case OpType
.RightShift
:
7623 case OpType
.Equality
:
7625 case OpType
.Inequality
:
7627 case OpType
.GreaterThan
:
7629 case OpType
.LessThan
:
7631 case OpType
.GreaterThanOrEqual
:
7633 case OpType
.LessThanOrEqual
:
7635 case OpType
.Implicit
:
7637 case OpType
.Explicit
:
7643 public static OpType
GetOperatorType (string name
)
7645 if (name
.StartsWith ("op_")){
7646 for (int i
= 0; i
< Unary
.oper_names
.Length
; ++i
) {
7647 if (Unary
.oper_names
[i
] == name
)
7651 for (int i
= 0; i
< Binary
.oper_names
.Length
; ++i
) {
7652 if (Binary
.oper_names
[i
] == name
)
7659 public override string GetSignatureForError ()
7661 StringBuilder sb
= new StringBuilder ();
7662 if (OperatorType
== OpType
.Implicit
|| OperatorType
== OpType
.Explicit
) {
7663 sb
.AppendFormat ("{0}.{1} operator {2}", Parent
.GetSignatureForError (), GetName (OperatorType
), Type
.Type
== null ? Type
.ToString () : TypeManager
.CSharpName (Type
.Type
));
7666 sb
.AppendFormat ("{0}.operator {1}", Parent
.GetSignatureForError (), GetName (OperatorType
));
7669 sb
.Append (Parameters
.GetSignatureForError ());
7670 return sb
.ToString ();
7675 // This is used to compare method signatures
7677 struct MethodSignature
{
7679 public Type RetType
;
7680 public Type
[] Parameters
;
7683 /// This delegate is used to extract methods which have the
7684 /// same signature as the argument
7686 public static MemberFilter method_signature_filter
= new MemberFilter (MemberSignatureCompare
);
7688 public MethodSignature (string name
, Type ret_type
, Type
[] parameters
)
7693 if (parameters
== null)
7694 Parameters
= Type
.EmptyTypes
;
7696 Parameters
= parameters
;
7699 public override string ToString ()
7702 if (Parameters
.Length
!= 0){
7703 System
.Text
.StringBuilder sb
= new System
.Text
.StringBuilder ();
7704 for (int i
= 0; i
< Parameters
.Length
; i
++){
7705 sb
.Append (Parameters
[i
]);
7706 if (i
+1 < Parameters
.Length
)
7709 pars
= sb
.ToString ();
7712 return String
.Format ("{0} {1} ({2})", RetType
, Name
, pars
);
7715 public override int GetHashCode ()
7717 return Name
.GetHashCode ();
7720 public override bool Equals (Object o
)
7722 MethodSignature other
= (MethodSignature
) o
;
7724 if (other
.Name
!= Name
)
7727 if (other
.RetType
!= RetType
)
7730 if (Parameters
== null){
7731 if (other
.Parameters
== null)
7736 if (other
.Parameters
== null)
7739 int c
= Parameters
.Length
;
7740 if (other
.Parameters
.Length
!= c
)
7743 for (int i
= 0; i
< c
; i
++)
7744 if (other
.Parameters
[i
] != Parameters
[i
])
7750 static bool MemberSignatureCompare (MemberInfo m
, object filter_criteria
)
7752 MethodSignature sig
= (MethodSignature
) filter_criteria
;
7754 if (m
.Name
!= sig
.Name
)
7758 MethodInfo mi
= m
as MethodInfo
;
7759 PropertyInfo pi
= m
as PropertyInfo
;
7762 ReturnType
= mi
.ReturnType
;
7763 else if (pi
!= null)
7764 ReturnType
= pi
.PropertyType
;
7769 // we use sig.RetType == null to mean `do not check the
7770 // method return value.
7772 if (sig
.RetType
!= null)
7773 if (ReturnType
!= sig
.RetType
)
7778 args
= TypeManager
.GetParameterData (mi
).Types
;
7780 args
= TypeManager
.GetArgumentTypes (pi
);
7781 Type
[] sigp
= sig
.Parameters
;
7783 if (args
.Length
!= sigp
.Length
)
7786 for (int i
= args
.Length
; i
> 0; ){
7788 if (args
[i
] != sigp
[i
])