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 // Dual licensed under the terms of the MIT X11 or GNU GPL
10 // Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
11 // Copyright 2004-2008 Novell, Inc
15 using System
.Collections
;
16 using System
.Collections
.Specialized
;
17 using System
.Reflection
;
18 using System
.Reflection
.Emit
;
19 using System
.Runtime
.CompilerServices
;
20 using System
.Runtime
.InteropServices
;
21 using System
.Security
;
22 using System
.Security
.Permissions
;
26 using XmlElement
= System
.Object
;
31 using Mono
.CompilerServices
.SymbolWriter
;
33 namespace Mono
.CSharp
{
45 /// This is the base class for structs and classes.
47 public abstract class TypeContainer
: DeclSpace
, IMemberContainer
{
49 public class MemberCoreArrayList
: ArrayList
52 /// Defines the MemberCore objects that are in this array
54 public virtual void DefineContainerMembers ()
56 foreach (MemberCore mc
in this) {
59 } catch (Exception e
) {
60 throw new InternalErrorException (mc
, e
);
65 public virtual void Emit ()
67 foreach (MemberCore mc
in this)
72 public class OperatorArrayList
: MemberCoreArrayList
74 TypeContainer container
;
76 public OperatorArrayList (TypeContainer container
)
78 this.container
= container
;
82 // Checks that some operators come in pairs:
88 // They are matched based on the return type and the argument types
90 void CheckPairedOperators ()
92 bool has_equality_or_inequality
= false;
93 Operator
[] operators
= (Operator
[]) ToArray (typeof (Operator
));
94 bool [] has_pair
= new bool [operators
.Length
];
96 for (int i
= 0; i
< Count
; ++i
) {
97 if (operators
[i
] == null)
100 Operator o_a
= operators
[i
];
101 Operator
.OpType o_type
= o_a
.OperatorType
;
102 if (o_type
== Operator
.OpType
.Equality
|| o_type
== Operator
.OpType
.Inequality
)
103 has_equality_or_inequality
= true;
105 Operator
.OpType matching_type
= o_a
.GetMatchingOperator ();
106 if (matching_type
== Operator
.OpType
.TOP
) {
107 operators
[i
] = null;
111 for (int ii
= 0; ii
< Count
; ++ii
) {
112 Operator o_b
= operators
[ii
];
113 if (o_b
== null || o_b
.OperatorType
!= matching_type
)
116 if (!TypeManager
.IsEqual (o_a
.ReturnType
, o_b
.ReturnType
))
119 if (!TypeManager
.IsEqual (o_a
.ParameterTypes
, o_b
.ParameterTypes
))
122 operators
[i
] = null;
125 // Used to ignore duplicate user conversions
127 has_pair
[ii
] = true;
131 for (int i
= 0; i
< Count
; ++i
) {
132 if (operators
[i
] == null || has_pair
[i
])
135 Operator o
= operators
[i
];
136 container
.Report
.Error (216, o
.Location
,
137 "The operator `{0}' requires a matching operator `{1}' to also be defined",
138 o
.GetSignatureForError (), Operator
.GetName (o
.GetMatchingOperator ()));
141 if (has_equality_or_inequality
&& container
.Report
.WarningLevel
> 2) {
142 if (container
.Methods
== null || !container
.HasEquals
)
143 container
.Report
.Warning (660, 2, container
.Location
, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container
.GetSignatureForError ());
145 if (container
.Methods
== null || !container
.HasGetHashCode
)
146 container
.Report
.Warning (661, 2, container
.Location
, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container
.GetSignatureForError ());
150 public override void DefineContainerMembers ()
152 base.DefineContainerMembers ();
153 CheckPairedOperators ();
158 // Different context is needed when resolving type container base
159 // types. Type names come from the parent scope but type parameter
160 // names from the container scope.
162 struct BaseContext
: IMemberContext
166 public BaseContext (TypeContainer tc
)
171 #region IMemberContext Members
173 public CompilerContext Compiler
{
174 get { return tc.Compiler; }
177 public Type CurrentType
{
178 get { return tc.Parent.CurrentType; }
181 public TypeParameter
[] CurrentTypeParameters
{
182 get { return tc.PartialContainer.CurrentTypeParameters; }
185 public TypeContainer CurrentTypeDefinition
{
186 get { return tc.Parent.CurrentTypeDefinition; }
189 public bool IsObsolete
{
190 get { return tc.IsObsolete; }
193 public bool IsUnsafe
{
194 get { return tc.IsUnsafe; }
197 public bool IsStatic
{
198 get { return tc.IsStatic; }
201 public string GetSignatureForError ()
203 throw new NotImplementedException ();
206 public ExtensionMethodGroupExpr
LookupExtensionMethod (Type extensionType
, string name
, Location loc
)
211 public FullNamedExpression
LookupNamespaceAlias (string name
)
213 return tc
.Parent
.LookupNamespaceAlias (name
);
216 public FullNamedExpression
LookupNamespaceOrType (string name
, Location loc
, bool ignore_cs0104
)
218 TypeParameter
[] tp
= CurrentTypeParameters
;
220 TypeParameter t
= TypeParameter
.FindTypeParameter (tp
, name
);
222 return new TypeParameterExpr (t
, loc
);
225 return tc
.Parent
.LookupNamespaceOrType (name
, loc
, ignore_cs0104
);
235 GetHashCode
= 1 << 1,
236 HasStaticFieldInitializer
= 1 << 2
240 // Whether this is a struct, class or interface
241 public readonly Kind Kind
;
243 // Holds a list of classes and structures
244 protected ArrayList types
;
246 MemberCoreArrayList ordered_explicit_member_list
;
247 MemberCoreArrayList ordered_member_list
;
249 // Holds the list of properties
250 MemberCoreArrayList properties
;
252 // Holds the list of delegates
253 MemberCoreArrayList delegates
;
255 // Holds the list of constructors
256 protected MemberCoreArrayList instance_constructors
;
258 // Holds the list of fields
259 protected MemberCoreArrayList fields
;
261 // Holds a list of fields that have initializers
262 protected ArrayList initialized_fields
;
264 // Holds a list of static fields that have initializers
265 protected ArrayList initialized_static_fields
;
267 // Holds the list of constants
268 protected MemberCoreArrayList constants
;
270 // Holds the methods.
271 MemberCoreArrayList methods
;
274 protected MemberCoreArrayList events
;
276 // Holds the indexers
279 // Holds the operators
280 MemberCoreArrayList operators
;
282 // Holds the compiler generated classes
283 ArrayList compiler_generated
;
286 // Pointers to the default constructor and the default static constructor
288 protected Constructor default_constructor
;
289 protected Constructor default_static_constructor
;
292 // Points to the first non-static field added to the container.
294 // This is an arbitrary choice. We are interested in looking at _some_ non-static field,
295 // and the first one's as good as any.
297 FieldBase first_nonstatic_field
= null;
300 // This one is computed after we can distinguish interfaces
301 // from classes from the arraylist `type_bases'
304 TypeExpr
[] iface_exprs
;
306 GenericTypeParameterBuilder
[] nested_gen_params
;
308 protected ArrayList type_bases
;
310 protected bool members_defined
;
311 bool members_defined_ok
;
313 // The interfaces we implement.
314 protected Type
[] ifaces
;
316 // The base member cache and our member cache
317 MemberCache base_cache
;
318 protected MemberCache member_cache
;
320 public const string DefaultIndexerName
= "Item";
322 private bool seen_normal_indexers
= false;
323 private string indexer_name
= DefaultIndexerName
;
324 protected bool requires_delayed_unmanagedtype_check
;
326 private CachedMethods cached_method
;
328 ArrayList partial_parts
;
331 /// The pending methods that need to be implemented
332 // (interfaces or abstract methods)
334 PendingImplementation pending
;
336 public TypeContainer (NamespaceEntry ns
, DeclSpace parent
, MemberName name
,
337 Attributes attrs
, Kind kind
)
338 : base (ns
, parent
, name
, attrs
)
340 if (parent
!= null && parent
.NamespaceEntry
!= ns
)
341 throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
344 this.PartialContainer
= this;
347 public bool AddMember (MemberCore symbol
)
349 return AddToContainer (symbol
, symbol
.MemberName
.Basename
);
352 protected virtual bool AddMemberType (DeclSpace ds
)
354 return AddToContainer (ds
, ds
.Basename
);
357 protected virtual void RemoveMemberType (DeclSpace ds
)
359 RemoveFromContainer (ds
.Basename
);
362 public void AddConstant (Const constant
)
364 if (!AddMember (constant
))
367 if (constants
== null)
368 constants
= new MemberCoreArrayList ();
370 constants
.Add (constant
);
373 public TypeContainer
AddTypeContainer (TypeContainer tc
)
375 if (!AddMemberType (tc
))
379 types
= new MemberCoreArrayList ();
385 public virtual TypeContainer
AddPartial (TypeContainer next_part
)
387 return AddPartial (next_part
, next_part
.Basename
);
390 protected TypeContainer
AddPartial (TypeContainer next_part
, string name
)
392 next_part
.ModFlags
|= Modifiers
.PARTIAL
;
393 TypeContainer tc
= defined_names
[name
] as TypeContainer
;
396 return AddTypeContainer (next_part
);
398 if ((tc
.ModFlags
& Modifiers
.PARTIAL
) == 0) {
399 Report
.SymbolRelatedToPreviousError (next_part
);
400 Error_MissingPartialModifier (tc
);
403 if (tc
.Kind
!= next_part
.Kind
) {
404 Report
.SymbolRelatedToPreviousError (tc
);
405 Report
.Error (261, next_part
.Location
,
406 "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
407 next_part
.GetSignatureForError ());
410 if ((tc
.ModFlags
& Modifiers
.Accessibility
) != (next_part
.ModFlags
& Modifiers
.Accessibility
) &&
411 ((tc
.ModFlags
& Modifiers
.DEFAULT_ACCESS_MODIFER
) == 0 &&
412 (next_part
.ModFlags
& Modifiers
.DEFAULT_ACCESS_MODIFER
) == 0)) {
413 Report
.SymbolRelatedToPreviousError (tc
);
414 Report
.Error (262, next_part
.Location
,
415 "Partial declarations of `{0}' have conflicting accessibility modifiers",
416 next_part
.GetSignatureForError ());
419 if (tc
.partial_parts
== null)
420 tc
.partial_parts
= new ArrayList (1);
422 if ((next_part
.ModFlags
& Modifiers
.DEFAULT_ACCESS_MODIFER
) != 0) {
423 tc
.ModFlags
|= next_part
.ModFlags
& ~
(Modifiers
.DEFAULT_ACCESS_MODIFER
| Modifiers
.Accessibility
);
424 } else if ((tc
.ModFlags
& Modifiers
.DEFAULT_ACCESS_MODIFER
) != 0) {
425 tc
.ModFlags
&= ~
(Modifiers
.DEFAULT_ACCESS_MODIFER
| Modifiers
.Accessibility
);
426 tc
.ModFlags
|= next_part
.ModFlags
;
428 tc
.ModFlags
|= next_part
.ModFlags
;
431 if (next_part
.attributes
!= null) {
432 if (tc
.attributes
== null)
433 tc
.attributes
= next_part
.attributes
;
435 tc
.attributes
.AddAttributes (next_part
.attributes
.Attrs
);
438 next_part
.PartialContainer
= tc
;
439 tc
.partial_parts
.Add (next_part
);
443 public virtual void RemoveTypeContainer (TypeContainer next_part
)
446 types
.Remove (next_part
);
447 RemoveMemberType (next_part
);
450 public void AddDelegate (Delegate d
)
452 if (!AddMemberType (d
))
455 if (delegates
== null)
456 delegates
= new MemberCoreArrayList ();
461 private void AddMemberToList (MemberCore mc
, ArrayList alist
, bool isexplicit
)
463 if (ordered_explicit_member_list
== null) {
464 ordered_explicit_member_list
= new MemberCoreArrayList ();
465 ordered_member_list
= new MemberCoreArrayList ();
469 if (Kind
== Kind
.Interface
) {
470 Report
.Error (541, mc
.Location
,
471 "`{0}': explicit interface declaration can only be declared in a class or struct",
472 mc
.GetSignatureForError ());
475 ordered_explicit_member_list
.Add (mc
);
476 alist
.Insert (0, mc
);
478 ordered_member_list
.Add (mc
);
484 public void AddMethod (MethodOrOperator method
)
486 if (!AddToContainer (method
, method
.MemberName
.Basename
))
490 methods
= new MemberCoreArrayList ();
492 if (method
.MemberName
.Left
!= null)
493 AddMemberToList (method
, methods
, true);
495 AddMemberToList (method
, methods
, false);
498 public void AddConstructor (Constructor c
)
500 bool is_static
= (c
.ModFlags
& Modifiers
.STATIC
) != 0;
501 if (!AddToContainer (c
, is_static
?
502 ConstructorBuilder
.ConstructorName
: ConstructorBuilder
.TypeConstructorName
))
505 if (is_static
&& c
.Parameters
.IsEmpty
){
506 if (default_static_constructor
!= null) {
507 Report
.SymbolRelatedToPreviousError (default_static_constructor
);
508 Report
.Error (111, c
.Location
,
509 "A member `{0}' is already defined. Rename this member or use different parameter types",
510 c
.GetSignatureForError ());
514 default_static_constructor
= c
;
516 if (c
.Parameters
.IsEmpty
)
517 default_constructor
= c
;
519 if (instance_constructors
== null)
520 instance_constructors
= new MemberCoreArrayList ();
522 instance_constructors
.Add (c
);
526 public bool AddField (FieldBase field
)
528 if (!AddMember (field
))
532 fields
= new MemberCoreArrayList ();
536 if ((field
.ModFlags
& Modifiers
.STATIC
) != 0)
539 if (first_nonstatic_field
== null) {
540 first_nonstatic_field
= field
;
544 if (Kind
== Kind
.Struct
&& first_nonstatic_field
.Parent
!= field
.Parent
) {
545 Report
.SymbolRelatedToPreviousError (first_nonstatic_field
.Parent
);
546 Report
.Warning (282, 3, field
.Location
,
547 "struct instance field `{0}' found in different declaration from instance field `{1}'",
548 field
.GetSignatureForError (), first_nonstatic_field
.GetSignatureForError ());
553 public void AddProperty (Property prop
)
555 if (!AddMember (prop
) ||
556 !AddMember (prop
.Get
) || !AddMember (prop
.Set
))
559 if (properties
== null)
560 properties
= new MemberCoreArrayList ();
562 if (prop
.MemberName
.Left
!= null)
563 AddMemberToList (prop
, properties
, true);
565 AddMemberToList (prop
, properties
, false);
568 public void AddEvent (Event e
)
573 if (e
is EventProperty
) {
574 if (!AddMember (e
.Add
))
577 if (!AddMember (e
.Remove
))
582 events
= new MemberCoreArrayList ();
588 /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
590 public void AddIndexer (Indexer i
)
592 if (indexers
== null)
593 indexers
= new ArrayList ();
595 if (i
.IsExplicitImpl
)
596 AddMemberToList (i
, indexers
, true);
598 AddMemberToList (i
, indexers
, false);
601 public void AddOperator (Operator op
)
606 if (operators
== null)
607 operators
= new OperatorArrayList (this);
612 public void AddCompilerGeneratedClass (CompilerGeneratedClass c
)
614 Report
.Debug (64, "ADD COMPILER GENERATED CLASS", this, c
);
616 if (compiler_generated
== null)
617 compiler_generated
= new ArrayList ();
619 compiler_generated
.Add (c
);
622 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
624 if (a
.Type
== pa
.DefaultMember
) {
625 if (Indexers
!= null) {
626 Report
.Error (646, a
.Location
, "Cannot specify the `DefaultMember' attribute on type containing an indexer");
631 base.ApplyAttributeBuilder (a
, cb
, pa
);
634 public override AttributeTargets AttributeTargets
{
636 throw new NotSupportedException ();
640 public ArrayList Types
{
646 public MemberCoreArrayList Methods
{
652 public ArrayList Constants
{
658 protected Type BaseType
{
660 return TypeBuilder
.BaseType
;
664 public ArrayList Fields
{
670 public ArrayList InstanceConstructors
{
672 return instance_constructors
;
676 public ArrayList Properties
{
682 public ArrayList Events
{
688 public ArrayList Indexers
{
694 public ArrayList Operators
{
700 public ArrayList Delegates
{
706 protected override TypeAttributes TypeAttr
{
708 return Modifiers
.TypeAttr (ModFlags
, IsTopLevel
) | base.TypeAttr
;
712 public string IndexerName
{
714 return indexers
== null ? DefaultIndexerName
: indexer_name
;
718 public bool IsComImport
{
720 if (OptAttributes
== null)
723 return OptAttributes
.Contains (PredefinedAttributes
.Get
.ComImport
);
727 public virtual void RegisterFieldForInitialization (MemberCore field
, FieldInitializer expression
)
729 if ((field
.ModFlags
& Modifiers
.STATIC
) != 0){
730 if (initialized_static_fields
== null) {
731 PartialContainer
.HasStaticFieldInitializer
= true;
732 initialized_static_fields
= new ArrayList (4);
735 initialized_static_fields
.Add (expression
);
737 if (initialized_fields
== null)
738 initialized_fields
= new ArrayList (4);
740 initialized_fields
.Add (expression
);
744 public void ResolveFieldInitializers (BlockContext ec
)
746 if (partial_parts
!= null) {
747 foreach (TypeContainer part
in partial_parts
) {
748 part
.DoResolveFieldInitializers (ec
);
751 DoResolveFieldInitializers (ec
);
754 void DoResolveFieldInitializers (BlockContext ec
)
757 if (initialized_static_fields
== null)
760 bool has_complex_initializer
= !RootContext
.Optimize
;
762 ExpressionStatement
[] init
= new ExpressionStatement
[initialized_static_fields
.Count
];
763 for (i
= 0; i
< initialized_static_fields
.Count
; ++i
) {
764 FieldInitializer fi
= (FieldInitializer
) initialized_static_fields
[i
];
765 ExpressionStatement s
= fi
.ResolveStatement (ec
);
767 s
= EmptyExpressionStatement
.Instance
;
768 } else if (fi
.IsComplexInitializer
) {
769 has_complex_initializer
|= true;
775 for (i
= 0; i
< initialized_static_fields
.Count
; ++i
) {
776 FieldInitializer fi
= (FieldInitializer
) initialized_static_fields
[i
];
778 // Need special check to not optimize code like this
779 // static int a = b = 5;
782 if (!has_complex_initializer
&& fi
.IsDefaultInitializer
)
785 ec
.CurrentBlock
.AddScopeStatement (new StatementExpression (init
[i
]));
791 if (initialized_fields
== null)
794 for (int i
= 0; i
< initialized_fields
.Count
; ++i
) {
795 FieldInitializer fi
= (FieldInitializer
) initialized_fields
[i
];
796 ExpressionStatement s
= fi
.ResolveStatement (ec
);
801 // Field is re-initialized to its default value => removed
803 if (fi
.IsDefaultInitializer
&& RootContext
.Optimize
)
806 ec
.CurrentBlock
.AddScopeStatement (new StatementExpression (s
));
810 public override string DocComment
{
822 public PendingImplementation PendingImplementations
{
823 get { return pending; }
826 public override bool GetClsCompliantAttributeValue ()
828 if (PartialContainer
!= this)
829 return PartialContainer
.GetClsCompliantAttributeValue ();
831 return base.GetClsCompliantAttributeValue ();
834 public virtual void AddBasesForPart (DeclSpace part
, ArrayList bases
)
836 // FIXME: get rid of partial_parts and store lists of bases of each part here
837 // assumed, not verified: 'part' is in 'partial_parts'
838 ((TypeContainer
) part
).type_bases
= bases
;
842 /// This function computes the Base class and also the
843 /// list of interfaces that the class or struct @c implements.
845 /// The return value is an array (might be null) of
846 /// interfaces implemented (as Types).
848 /// The @base_class argument is set to the base object or null
849 /// if this is `System.Object'.
851 protected virtual TypeExpr
[] ResolveBaseTypes (out TypeExpr base_class
)
854 if (type_bases
== null)
857 int count
= type_bases
.Count
;
858 TypeExpr
[] ifaces
= null;
859 IMemberContext base_context
= new BaseContext (this);
860 for (int i
= 0, j
= 0; i
< count
; i
++){
861 FullNamedExpression fne
= (FullNamedExpression
) type_bases
[i
];
864 // Standard ResolveAsTypeTerminal cannot be used in this case because
865 // it does ObsoleteAttribute and constraint checks which require
866 // base type to be set
868 TypeExpr fne_resolved
= fne
.ResolveAsBaseTerminal (base_context
, false);
869 if (fne_resolved
== null)
872 if (i
== 0 && Kind
== Kind
.Class
&& !fne_resolved
.Type
.IsInterface
) {
873 if (fne_resolved
is DynamicTypeExpr
)
874 Report
.Error (1965, Location
, "Class `{0}' cannot derive from the dynamic type",
875 GetSignatureForError ());
877 base_class
= fne_resolved
;
882 ifaces
= new TypeExpr
[count
- i
];
884 if (fne_resolved
.Type
.IsInterface
) {
885 for (int ii
= 0; ii
< j
; ++ii
) {
886 if (TypeManager
.IsEqual (fne_resolved
.Type
, ifaces
[ii
].Type
)) {
887 Report
.Error (528, Location
, "`{0}' is already listed in interface list",
888 fne_resolved
.GetSignatureForError ());
893 if (Kind
== Kind
.Interface
&& !IsAccessibleAs (fne_resolved
.Type
)) {
894 Report
.Error (61, fne
.Location
,
895 "Inconsistent accessibility: base interface `{0}' is less accessible than interface `{1}'",
896 fne_resolved
.GetSignatureForError (), GetSignatureForError ());
899 Report
.SymbolRelatedToPreviousError (fne_resolved
.Type
);
900 if (Kind
!= Kind
.Class
) {
901 Report
.Error (527, fne
.Location
, "Type `{0}' in interface list is not an interface", fne_resolved
.GetSignatureForError ());
902 } else if (base_class
!= null)
903 Report
.Error (1721, fne
.Location
, "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')",
904 GetSignatureForError (), base_class
.GetSignatureForError (), fne_resolved
.GetSignatureForError ());
906 Report
.Error (1722, fne
.Location
, "`{0}': Base class `{1}' must be specified as first",
907 GetSignatureForError (), fne_resolved
.GetSignatureForError ());
911 ifaces
[j
++] = fne_resolved
;
917 TypeExpr
[] GetNormalPartialBases (ref TypeExpr base_class
)
919 ArrayList ifaces
= new ArrayList (0);
920 if (iface_exprs
!= null)
921 ifaces
.AddRange (iface_exprs
);
923 foreach (TypeContainer part
in partial_parts
) {
924 TypeExpr new_base_class
;
925 TypeExpr
[] new_ifaces
= part
.ResolveBaseTypes (out new_base_class
);
926 if (new_base_class
!= TypeManager
.system_object_expr
) {
927 if (base_class
== TypeManager
.system_object_expr
)
928 base_class
= new_base_class
;
930 if (new_base_class
!= null && !TypeManager
.IsEqual (new_base_class
.Type
, base_class
.Type
)) {
931 Report
.SymbolRelatedToPreviousError (base_class
.Location
, "");
932 Report
.Error (263, part
.Location
,
933 "Partial declarations of `{0}' must not specify different base classes",
934 part
.GetSignatureForError ());
941 if (new_ifaces
== null)
944 foreach (TypeExpr iface
in new_ifaces
) {
945 if (ifaces
.Contains (iface
))
952 if (ifaces
.Count
== 0)
955 return (TypeExpr
[])ifaces
.ToArray (typeof (TypeExpr
));
958 bool CheckGenericInterfaces (Type
[] ifaces
)
960 ArrayList already_checked
= new ArrayList ();
962 for (int i
= 0; i
< ifaces
.Length
; i
++) {
963 Type iface
= ifaces
[i
];
964 foreach (Type t
in already_checked
) {
968 Type
[] inferred
= new Type
[CountTypeParameters
];
969 if (!TypeManager
.MayBecomeEqualGenericInstances (iface
, t
, inferred
, null))
972 Report
.Error (695, Location
,
973 "`{0}' cannot implement both `{1}' and `{2}' " +
974 "because they may unify for some type parameter substitutions",
975 TypeManager
.CSharpName (TypeBuilder
), TypeManager
.CSharpName (iface
),
976 TypeManager
.CSharpName (t
));
980 already_checked
.Add (iface
);
988 bool CreateTypeBuilder ()
991 Type default_parent
= null;
992 if (Kind
== Kind
.Struct
)
993 default_parent
= TypeManager
.value_type
;
994 else if (Kind
== Kind
.Enum
)
995 default_parent
= TypeManager
.enum_type
;
996 else if (Kind
== Kind
.Delegate
)
997 default_parent
= TypeManager
.multicast_delegate_type
;
1000 // Sets .size to 1 for structs with no instance fields
1002 int type_size
= Kind
== Kind
.Struct
&& first_nonstatic_field
== null ? 1 : 0;
1005 if (GlobalRootNamespace
.Instance
.IsNamespace (Name
)) {
1006 Report
.Error (519, Location
, "`{0}' clashes with a predefined namespace", Name
);
1010 ModuleBuilder builder
= Module
.Compiled
.Builder
;
1011 TypeBuilder
= builder
.DefineType (
1012 Name
, TypeAttr
, default_parent
, type_size
);
1014 TypeBuilder builder
= Parent
.TypeBuilder
;
1016 TypeBuilder
= builder
.DefineNestedType (
1017 Basename
, TypeAttr
, default_parent
, type_size
);
1019 } catch (ArgumentException
) {
1020 Report
.RuntimeMissingSupport (Location
, "static classes");
1024 TypeManager
.AddUserType (this);
1027 string[] param_names
= new string [TypeParameters
.Length
];
1028 for (int i
= 0; i
< TypeParameters
.Length
; i
++)
1029 param_names
[i
] = TypeParameters
[i
].Name
;
1031 GenericTypeParameterBuilder
[] gen_params
= TypeBuilder
.DefineGenericParameters (param_names
);
1033 int offset
= CountTypeParameters
;
1034 if (CurrentTypeParameters
!= null)
1035 offset
-= CurrentTypeParameters
.Length
;
1038 nested_gen_params
= new GenericTypeParameterBuilder
[offset
];
1039 Array
.Copy (gen_params
, nested_gen_params
, offset
);
1042 for (int i
= offset
; i
< gen_params
.Length
; i
++)
1043 CurrentTypeParameters
[i
- offset
].Define (gen_params
[i
]);
1049 bool DefineBaseTypes ()
1051 iface_exprs
= ResolveBaseTypes (out base_type
);
1052 if (partial_parts
!= null) {
1053 iface_exprs
= GetNormalPartialBases (ref base_type
);
1057 // GetClassBases calls ResolveBaseTypeExpr() on the various type expressions involved,
1058 // which in turn should have called DefineType()s on base types if necessary.
1060 // None of the code below should trigger DefineType()s on classes that we depend on.
1061 // Thus, we are eligible to be on the topological sort `type_container_resolve_order'.
1063 // Let's do it as soon as possible, since code below can call DefineType() on classes
1064 // that depend on us to be populated before they are.
1066 if (!(this is CompilerGeneratedClass
) && !(this is Delegate
))
1067 RootContext
.RegisterOrder (this);
1069 if (!CheckRecursiveDefinition (this))
1072 if (base_type
!= null && base_type
.Type
!= null) {
1073 TypeBuilder
.SetParent (base_type
.Type
);
1076 // add interfaces that were not added at type creation
1077 if (iface_exprs
!= null) {
1078 ifaces
= TypeManager
.ExpandInterfaces (iface_exprs
);
1082 foreach (Type itype
in ifaces
)
1083 TypeBuilder
.AddInterfaceImplementation (itype
);
1085 if (!CheckGenericInterfaces (ifaces
))
1088 TypeManager
.RegisterBuilder (TypeBuilder
, ifaces
);
1095 // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
1097 public TypeBuilder
CreateType ()
1099 if (TypeBuilder
!= null)
1105 if (!CreateTypeBuilder ()) {
1110 if (partial_parts
!= null) {
1111 foreach (TypeContainer part
in partial_parts
)
1112 part
.TypeBuilder
= TypeBuilder
;
1115 if (Types
!= null) {
1116 foreach (TypeContainer tc
in Types
) {
1117 if (tc
.CreateType () == null) {
1129 public override TypeBuilder
DefineType ()
1136 type_defined
= true;
1138 if (CreateType () == null) {
1143 if (!DefineBaseTypes ()) {
1148 if (!DefineNestedTypes ()) {
1156 public override void SetParameterInfo (ArrayList constraints_list
)
1158 base.SetParameterInfo (constraints_list
);
1160 if (!is_generic
|| PartialContainer
== this)
1163 TypeParameter
[] tc_names
= PartialContainer
.TypeParameters
;
1164 for (int i
= 0; i
< tc_names
.Length
; ++i
) {
1165 if (tc_names
[i
].Name
!= type_params
[i
].Name
) {
1166 Report
.SymbolRelatedToPreviousError (PartialContainer
.Location
, "");
1167 Report
.Error (264, Location
, "Partial declarations of `{0}' must have the same type parameter names in the same order",
1168 GetSignatureForError ());
1172 if (tc_names
[i
].Variance
!= type_params
[i
].Variance
) {
1173 Report
.SymbolRelatedToPreviousError (PartialContainer
.Location
, "");
1174 Report
.Error (1067, Location
, "Partial declarations of `{0}' must have the same type parameter variance modifiers",
1175 GetSignatureForError ());
1181 void UpdateTypeParameterConstraints (TypeContainer part
)
1183 TypeParameter
[] current_params
= type_params
;
1184 for (int i
= 0; i
< current_params
.Length
; i
++) {
1185 Constraints c
= part
.type_params
[i
].Constraints
;
1189 if (current_params
[i
].UpdateConstraints (part
, c
))
1192 Report
.SymbolRelatedToPreviousError (Location
, "");
1193 Report
.Error (265, part
.Location
,
1194 "Partial declarations of `{0}' have inconsistent constraints for type parameter `{1}'",
1195 GetSignatureForError (), current_params
[i
].GetSignatureForError ());
1199 public bool ResolveType ()
1201 if (!DoResolveType ())
1204 if (compiler_generated
!= null) {
1205 foreach (CompilerGeneratedClass c
in compiler_generated
)
1206 if (!c
.ResolveType ())
1213 protected virtual bool DoResolveType ()
1218 if (PartialContainer
!= this)
1219 throw new InternalErrorException ();
1221 TypeExpr current_type
= null;
1222 if (CurrentTypeParameters
!= null) {
1223 foreach (TypeParameter type_param
in CurrentTypeParameters
) {
1224 if (!type_param
.Resolve (this)) {
1230 if (partial_parts
!= null) {
1231 foreach (TypeContainer part
in partial_parts
)
1232 UpdateTypeParameterConstraints (part
);
1236 for (int i
= 0; i
< TypeParameters
.Length
; ++i
) {
1238 // FIXME: Same should be done for delegates
1239 // TODO: Quite ugly way how to propagate constraints to
1242 if (nested_gen_params
!= null && i
< nested_gen_params
.Length
) {
1243 TypeParameters
[i
].SetConstraints (nested_gen_params
[i
]);
1245 if (!TypeParameters
[i
].DefineType (this)) {
1252 // TODO: Very strange, why not simple make generic type from
1253 // current type parameters
1254 current_type
= new GenericTypeExpr (this, Location
);
1255 current_type
= current_type
.ResolveAsTypeTerminal (this, false);
1256 if (current_type
== null) {
1261 currentType
= current_type
.Type
;
1265 protected virtual bool DefineNestedTypes ()
1267 if (Types
!= null) {
1268 foreach (TypeContainer tc
in Types
)
1269 if (tc
.DefineType () == null)
1273 if (Delegates
!= null) {
1274 foreach (Delegate d
in Delegates
)
1275 if (d
.DefineType () == null)
1282 TypeContainer InTransit
;
1284 protected bool CheckRecursiveDefinition (TypeContainer tc
)
1286 if (InTransit
!= null) {
1287 Report
.SymbolRelatedToPreviousError (this);
1288 if (this is Interface
)
1290 529, tc
.Location
, "Inherited interface `{0}' causes a " +
1291 "cycle in the interface hierarchy of `{1}'",
1292 GetSignatureForError (), tc
.GetSignatureForError ());
1295 146, tc
.Location
, "Circular base class dependency " +
1296 "involving `{0}' and `{1}'",
1297 tc
.GetSignatureForError (), GetSignatureForError ());
1303 if (base_type
!= null && base_type
.Type
!= null) {
1304 Type t
= TypeManager
.DropGenericTypeArguments (base_type
.Type
);
1305 TypeContainer ptc
= TypeManager
.LookupTypeContainer (t
);
1306 if ((ptc
!= null) && !ptc
.CheckRecursiveDefinition (this))
1310 if (iface_exprs
!= null) {
1311 foreach (TypeExpr iface
in iface_exprs
) {
1312 Type itype
= TypeManager
.DropGenericTypeArguments (iface
.Type
);
1313 TypeContainer ptc
= TypeManager
.LookupTypeContainer (itype
);
1314 if ((ptc
!= null) && !ptc
.CheckRecursiveDefinition (this))
1319 if (!IsTopLevel
&& !Parent
.PartialContainer
.CheckRecursiveDefinition (this))
1326 public override TypeParameter
[] CurrentTypeParameters
{
1328 return PartialContainer
.type_params
;
1333 /// Populates our TypeBuilder with fields and methods
1335 public override bool Define ()
1337 if (members_defined
)
1338 return members_defined_ok
;
1340 members_defined_ok
= DoDefineMembers ();
1341 members_defined
= true;
1343 return members_defined_ok
;
1346 protected virtual bool DoDefineMembers ()
1348 if (iface_exprs
!= null) {
1349 foreach (TypeExpr iface
in iface_exprs
) {
1350 ObsoleteAttribute oa
= AttributeTester
.GetObsoleteAttribute (iface
.Type
);
1351 if ((oa
!= null) && !IsObsolete
)
1352 AttributeTester
.Report_ObsoleteMessage (
1353 oa
, iface
.GetSignatureForError (), Location
, Report
);
1355 GenericTypeExpr ct
= iface
as GenericTypeExpr
;
1357 // TODO: passing `this' is wrong, should be base type iface instead
1358 TypeManager
.CheckTypeVariance (ct
.Type
, Variance
.Covariant
, this);
1360 if (!ct
.CheckConstraints (this))
1363 if (ct
.HasDynamicArguments ()) {
1364 Report
.Error (1966, iface
.Location
,
1365 "`{0}': cannot implement a dynamic interface `{1}'",
1366 GetSignatureForError (), iface
.GetSignatureForError ());
1373 if (base_type
!= null) {
1374 ObsoleteAttribute obsolete_attr
= AttributeTester
.GetObsoleteAttribute (base_type
.Type
);
1375 if (obsolete_attr
!= null && !IsObsolete
)
1376 AttributeTester
.Report_ObsoleteMessage (obsolete_attr
, base_type
.GetSignatureForError (), Location
, Report
);
1378 GenericTypeExpr ct
= base_type
as GenericTypeExpr
;
1379 if ((ct
!= null) && !ct
.CheckConstraints (this))
1382 TypeContainer baseContainer
= TypeManager
.LookupTypeContainer(base_type
.Type
);
1383 if (baseContainer
!= null)
1384 baseContainer
.Define();
1386 member_cache
= new MemberCache (base_type
.Type
, this);
1387 } else if (Kind
== Kind
.Interface
) {
1388 member_cache
= new MemberCache (null, this);
1389 Type
[] ifaces
= TypeManager
.GetInterfaces (TypeBuilder
);
1390 for (int i
= 0; i
< ifaces
.Length
; ++i
)
1391 member_cache
.AddInterface (TypeManager
.LookupMemberCache (ifaces
[i
]));
1393 member_cache
= new MemberCache (null, this);
1397 foreach (TypeContainer tc
in types
)
1398 member_cache
.AddNestedType (tc
);
1400 if (delegates
!= null)
1401 foreach (Delegate d
in delegates
)
1402 member_cache
.AddNestedType (d
);
1404 if (partial_parts
!= null) {
1405 foreach (TypeContainer part
in partial_parts
)
1406 part
.member_cache
= member_cache
;
1410 MemberInfo conflict_symbol
= Parent
.PartialContainer
.FindBaseMemberWithSameName (Basename
, false);
1411 if (conflict_symbol
== null) {
1412 if ((ModFlags
& Modifiers
.NEW
) != 0)
1413 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
1415 if ((ModFlags
& Modifiers
.NEW
) == 0) {
1416 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
1417 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
1418 GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
1423 DefineContainerMembers (constants
);
1424 DefineContainerMembers (fields
);
1426 if (Kind
== Kind
.Struct
|| Kind
== Kind
.Class
) {
1427 pending
= PendingImplementation
.GetPendingImplementations (this);
1429 if (requires_delayed_unmanagedtype_check
) {
1430 requires_delayed_unmanagedtype_check
= false;
1431 foreach (FieldBase f
in fields
) {
1432 if (f
.MemberType
!= null && f
.MemberType
.IsPointer
)
1433 TypeManager
.VerifyUnManaged (f
.MemberType
, f
.Location
);
1439 // Constructors are not in the defined_names array
1441 DefineContainerMembers (instance_constructors
);
1443 DefineContainerMembers (events
);
1444 DefineContainerMembers (ordered_explicit_member_list
);
1445 DefineContainerMembers (ordered_member_list
);
1447 DefineContainerMembers (operators
);
1448 DefineContainerMembers (delegates
);
1450 ComputeIndexerName();
1451 CheckEqualsAndGetHashCode();
1453 if (CurrentType
!= null) {
1454 GenericType
= CurrentType
;
1458 // FIXME: This hack is needed because member cache does not work
1459 // with generic types, we rely on runtime to inflate dynamic types.
1460 // TODO: This hack requires member cache refactoring to be removed
1462 if (TypeManager
.IsGenericType (TypeBuilder
))
1463 member_cache
= new MemberCache (this);
1468 protected virtual void DefineContainerMembers (MemberCoreArrayList mcal
)
1471 mcal
.DefineContainerMembers ();
1474 protected virtual void ComputeIndexerName ()
1476 if (indexers
== null)
1479 string class_indexer_name
= null;
1482 // If there's both an explicit and an implicit interface implementation, the
1483 // explicit one actually implements the interface while the other one is just
1484 // a normal indexer. See bug #37714.
1487 // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
1488 foreach (Indexer i
in indexers
) {
1489 if (i
.InterfaceType
!= null) {
1490 if (seen_normal_indexers
)
1491 throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
1495 seen_normal_indexers
= true;
1497 if (class_indexer_name
== null) {
1498 class_indexer_name
= i
.ShortName
;
1502 if (i
.ShortName
!= class_indexer_name
)
1503 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");
1506 if (class_indexer_name
!= null)
1507 indexer_name
= class_indexer_name
;
1510 protected virtual void EmitIndexerName ()
1512 if (!seen_normal_indexers
)
1515 PredefinedAttribute pa
= PredefinedAttributes
.Get
.DefaultMember
;
1516 if (pa
.Constructor
== null &&
1517 !pa
.ResolveConstructor (Location
, TypeManager
.string_type
))
1520 CustomAttributeBuilder cb
= new CustomAttributeBuilder (pa
.Constructor
, new string [] { IndexerName }
);
1521 TypeBuilder
.SetCustomAttribute (cb
);
1524 protected virtual void CheckEqualsAndGetHashCode ()
1526 if (methods
== null)
1529 if (HasEquals
&& !HasGetHashCode
) {
1530 Report
.Warning (659, 3, this.Location
, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", this.GetSignatureForError ());
1534 public MemberInfo
FindBaseMemberWithSameName (string name
, bool ignore_methods
)
1536 return BaseCache
== null ? null : BaseCache
.FindMemberWithSameName (name
, ignore_methods
, null);
1540 /// This function is based by a delegate to the FindMembers routine
1542 static bool AlwaysAccept (MemberInfo m
, object filterCriteria
)
1548 /// This filter is used by FindMembers, and we just keep
1549 /// a global for the filter to `AlwaysAccept'
1551 static MemberFilter accepting_filter
;
1554 static TypeContainer ()
1556 accepting_filter
= new MemberFilter (AlwaysAccept
);
1559 public MethodInfo
[] GetMethods ()
1561 ArrayList members
= new ArrayList ();
1565 if (methods
!= null) {
1566 int len
= methods
.Count
;
1567 for (int i
= 0; i
< len
; i
++) {
1568 Method m
= (Method
) methods
[i
];
1570 members
.Add (m
.MethodBuilder
);
1574 if (operators
!= null) {
1575 int len
= operators
.Count
;
1576 for (int i
= 0; i
< len
; i
++) {
1577 Operator o
= (Operator
) operators
[i
];
1579 members
.Add (o
.MethodBuilder
);
1583 if (properties
!= null) {
1584 int len
= properties
.Count
;
1585 for (int i
= 0; i
< len
; i
++) {
1586 Property p
= (Property
) properties
[i
];
1588 if (p
.GetBuilder
!= null)
1589 members
.Add (p
.GetBuilder
);
1590 if (p
.SetBuilder
!= null)
1591 members
.Add (p
.SetBuilder
);
1595 if (indexers
!= null) {
1596 int len
= indexers
.Count
;
1597 for (int i
= 0; i
< len
; i
++) {
1598 Indexer ix
= (Indexer
) indexers
[i
];
1600 if (ix
.GetBuilder
!= null)
1601 members
.Add (ix
.GetBuilder
);
1602 if (ix
.SetBuilder
!= null)
1603 members
.Add (ix
.SetBuilder
);
1607 if (events
!= null) {
1608 int len
= events
.Count
;
1609 for (int i
= 0; i
< len
; i
++) {
1610 Event e
= (Event
) events
[i
];
1612 if (e
.AddBuilder
!= null)
1613 members
.Add (e
.AddBuilder
);
1614 if (e
.RemoveBuilder
!= null)
1615 members
.Add (e
.RemoveBuilder
);
1619 MethodInfo
[] retMethods
= new MethodInfo
[members
.Count
];
1620 members
.CopyTo (retMethods
, 0);
1624 // Indicated whether container has StructLayout attribute set Explicit
1625 public bool HasExplicitLayout
{
1626 get { return (caching_flags & Flags.HasExplicitLayout) != 0; }
1627 set { caching_flags |= Flags.HasExplicitLayout; }
1630 public bool HasStructLayout
{
1631 get { return (caching_flags & Flags.HasStructLayout) != 0; }
1632 set { caching_flags |= Flags.HasStructLayout; }
1636 // Return the nested type with name @name. Ensures that the nested type
1637 // is defined if necessary. Do _not_ use this when you have a MemberCache handy.
1639 public Type
FindNestedType (string name
)
1641 if (PartialContainer
!= this)
1642 throw new InternalErrorException ("should not happen");
1644 ArrayList
[] lists
= { types, delegates }
;
1646 for (int j
= 0; j
< lists
.Length
; ++j
) {
1647 ArrayList list
= lists
[j
];
1651 int len
= list
.Count
;
1652 for (int i
= 0; i
< len
; ++i
) {
1653 DeclSpace ds
= (DeclSpace
) list
[i
];
1654 if (ds
.Basename
== name
) {
1655 return ds
.DefineType ();
1663 private void FindMembers_NestedTypes (int modflags
,
1664 BindingFlags bf
, MemberFilter filter
, object criteria
,
1665 ref ArrayList members
)
1667 ArrayList
[] lists
= { types, delegates }
;
1669 for (int j
= 0; j
< lists
.Length
; ++j
) {
1670 ArrayList list
= lists
[j
];
1674 int len
= list
.Count
;
1675 for (int i
= 0; i
< len
; i
++) {
1676 DeclSpace ds
= (DeclSpace
) list
[i
];
1678 if ((ds
.ModFlags
& modflags
) == 0)
1681 TypeBuilder tb
= ds
.TypeBuilder
;
1683 if (!(criteria
is string) || ds
.Basename
.Equals (criteria
))
1684 tb
= ds
.DefineType ();
1687 if (tb
!= null && (filter (tb
, criteria
) == true)) {
1688 if (members
== null)
1689 members
= new ArrayList ();
1698 /// This method returns the members of this type just like Type.FindMembers would
1699 /// Only, we need to use this for types which are _being_ defined because MS'
1700 /// implementation can't take care of that.
1703 // FIXME: return an empty static array instead of null, that cleans up
1704 // some code and is consistent with some coding conventions I just found
1708 // Notice that in various cases we check if our field is non-null,
1709 // something that would normally mean that there was a bug elsewhere.
1711 // The problem happens while we are defining p-invoke methods, as those
1712 // will trigger a FindMembers, but this happens before things are defined
1714 // Since the whole process is a no-op, it is fine to check for null here.
1716 // TODO: This approach will be one day completely removed, it's already
1717 // used at few places only
1720 public override MemberList
FindMembers (MemberTypes mt
, BindingFlags bf
,
1721 MemberFilter filter
, object criteria
)
1723 ArrayList members
= null;
1726 if ((bf
& BindingFlags
.Public
) != 0)
1727 modflags
|= Modifiers
.PUBLIC
| Modifiers
.PROTECTED
|
1729 if ((bf
& BindingFlags
.NonPublic
) != 0)
1730 modflags
|= Modifiers
.PRIVATE
;
1732 int static_mask
= 0, static_flags
= 0;
1733 switch (bf
& (BindingFlags
.Static
| BindingFlags
.Instance
)) {
1734 case BindingFlags
.Static
:
1735 static_mask
= static_flags
= Modifiers
.STATIC
;
1738 case BindingFlags
.Instance
:
1739 static_mask
= Modifiers
.STATIC
;
1744 static_mask
= static_flags
= 0;
1748 Timer
.StartTimer (TimerType
.TcFindMembers
);
1751 filter
= accepting_filter
;
1753 if ((mt
& MemberTypes
.Field
) != 0) {
1754 if (fields
!= null) {
1755 int len
= fields
.Count
;
1756 for (int i
= 0; i
< len
; i
++) {
1757 FieldBase f
= (FieldBase
) fields
[i
];
1759 if ((f
.ModFlags
& modflags
) == 0)
1761 if ((f
.ModFlags
& static_mask
) != static_flags
)
1764 FieldBuilder fb
= f
.FieldBuilder
;
1765 if (fb
!= null && filter (fb
, criteria
) == true) {
1766 if (members
== null)
1767 members
= new ArrayList ();
1774 if (constants
!= null) {
1775 int len
= constants
.Count
;
1776 for (int i
= 0; i
< len
; i
++) {
1777 Const con
= (Const
) constants
[i
];
1779 if ((con
.ModFlags
& modflags
) == 0)
1781 if ((con
.ModFlags
& static_mask
) != static_flags
)
1784 FieldBuilder fb
= con
.FieldBuilder
;
1786 // Define parent and not member, otherwise membercache can be null
1787 if (con
.Parent
.Define ())
1788 fb
= con
.FieldBuilder
;
1790 if (fb
!= null && filter (fb
, criteria
) == true) {
1791 if (members
== null)
1792 members
= new ArrayList ();
1800 if ((mt
& MemberTypes
.Method
) != 0) {
1801 if (methods
!= null) {
1802 int len
= methods
.Count
;
1803 for (int i
= 0; i
< len
; i
++) {
1804 MethodOrOperator m
= (MethodOrOperator
) methods
[i
];
1806 if ((m
.ModFlags
& modflags
) == 0)
1808 if ((m
.ModFlags
& static_mask
) != static_flags
)
1811 MethodBuilder mb
= m
.MethodBuilder
;
1813 if (mb
!= null && filter (mb
, criteria
) == true) {
1814 if (members
== null)
1815 members
= new ArrayList ();
1822 if (operators
!= null) {
1823 int len
= operators
.Count
;
1824 for (int i
= 0; i
< len
; i
++) {
1825 Operator o
= (Operator
) operators
[i
];
1827 if ((o
.ModFlags
& modflags
) == 0)
1829 if ((o
.ModFlags
& static_mask
) != static_flags
)
1832 MethodBuilder ob
= o
.MethodBuilder
;
1833 if (ob
!= null && filter (ob
, criteria
) == true) {
1834 if (members
== null)
1835 members
= new ArrayList ();
1842 if (events
!= null) {
1843 foreach (Event e
in events
) {
1844 if ((e
.ModFlags
& modflags
) == 0)
1846 if ((e
.ModFlags
& static_mask
) != static_flags
)
1849 MethodBuilder b
= e
.AddBuilder
;
1850 if (b
!= null && filter (b
, criteria
)) {
1851 if (members
== null)
1852 members
= new ArrayList (4);
1857 b
= e
.RemoveBuilder
;
1858 if (b
!= null && filter (b
, criteria
)) {
1859 if (members
== null)
1860 members
= new ArrayList (4);
1867 if (properties
!= null) {
1868 int len
= properties
.Count
;
1869 for (int i
= 0; i
< len
; i
++) {
1870 Property p
= (Property
) properties
[i
];
1872 if ((p
.ModFlags
& modflags
) == 0)
1874 if ((p
.ModFlags
& static_mask
) != static_flags
)
1880 if (b
!= null && filter (b
, criteria
) == true) {
1881 if (members
== null)
1882 members
= new ArrayList ();
1888 if (b
!= null && filter (b
, criteria
) == true) {
1889 if (members
== null)
1890 members
= new ArrayList ();
1897 if (indexers
!= null) {
1898 int len
= indexers
.Count
;
1899 for (int i
= 0; i
< len
; i
++) {
1900 Indexer ix
= (Indexer
) indexers
[i
];
1902 if ((ix
.ModFlags
& modflags
) == 0)
1904 if ((ix
.ModFlags
& static_mask
) != static_flags
)
1910 if (b
!= null && filter (b
, criteria
) == true) {
1911 if (members
== null)
1912 members
= new ArrayList ();
1918 if (b
!= null && filter (b
, criteria
) == true) {
1919 if (members
== null)
1920 members
= new ArrayList ();
1928 if ((mt
& MemberTypes
.Event
) != 0) {
1929 if (events
!= null) {
1930 int len
= events
.Count
;
1931 for (int i
= 0; i
< len
; i
++) {
1932 Event e
= (Event
) events
[i
];
1934 if ((e
.ModFlags
& modflags
) == 0)
1936 if ((e
.ModFlags
& static_mask
) != static_flags
)
1939 MemberInfo eb
= e
.EventBuilder
;
1940 if (eb
!= null && filter (eb
, criteria
) == true) {
1941 if (members
== null)
1942 members
= new ArrayList ();
1944 members
.Add (e
.EventBuilder
);
1950 if ((mt
& MemberTypes
.Property
) != 0){
1951 if (properties
!= null) {
1952 int len
= properties
.Count
;
1953 for (int i
= 0; i
< len
; i
++) {
1954 Property p
= (Property
) properties
[i
];
1956 if ((p
.ModFlags
& modflags
) == 0)
1958 if ((p
.ModFlags
& static_mask
) != static_flags
)
1961 MemberInfo pb
= p
.PropertyBuilder
;
1962 if (pb
!= null && filter (pb
, criteria
) == true) {
1963 if (members
== null)
1964 members
= new ArrayList ();
1966 members
.Add (p
.PropertyBuilder
);
1971 if (indexers
!= null) {
1972 int len
= indexers
.Count
;
1973 for (int i
= 0; i
< len
; i
++) {
1974 Indexer ix
= (Indexer
) indexers
[i
];
1976 if ((ix
.ModFlags
& modflags
) == 0)
1978 if ((ix
.ModFlags
& static_mask
) != static_flags
)
1981 MemberInfo ib
= ix
.PropertyBuilder
;
1982 if (ib
!= null && filter (ib
, criteria
) == true) {
1983 if (members
== null)
1984 members
= new ArrayList ();
1986 members
.Add (ix
.PropertyBuilder
);
1992 if ((mt
& MemberTypes
.NestedType
) != 0)
1993 FindMembers_NestedTypes (modflags
, bf
, filter
, criteria
, ref members
);
1995 if ((mt
& MemberTypes
.Constructor
) != 0){
1996 if (((bf
& BindingFlags
.Instance
) != 0) && (instance_constructors
!= null)){
1997 int len
= instance_constructors
.Count
;
1998 for (int i
= 0; i
< len
; i
++) {
1999 Constructor c
= (Constructor
) instance_constructors
[i
];
2001 ConstructorBuilder cb
= c
.ConstructorBuilder
;
2002 if (cb
!= null && filter (cb
, criteria
) == true) {
2003 if (members
== null)
2004 members
= new ArrayList ();
2011 if (((bf
& BindingFlags
.Static
) != 0) && (default_static_constructor
!= null)){
2012 ConstructorBuilder cb
=
2013 default_static_constructor
.ConstructorBuilder
;
2015 if (cb
!= null && filter (cb
, criteria
) == true) {
2016 if (members
== null)
2017 members
= new ArrayList ();
2025 // Lookup members in base if requested.
2027 if ((bf
& BindingFlags
.DeclaredOnly
) == 0) {
2028 if (TypeBuilder
.BaseType
!= null) {
2029 MemberList list
= FindMembers (TypeBuilder
.BaseType
, mt
, bf
, filter
, criteria
);
2030 if (list
.Count
> 0) {
2031 if (members
== null)
2032 members
= new ArrayList ();
2034 members
.AddRange (list
);
2039 Timer
.StopTimer (TimerType
.TcFindMembers
);
2041 if (members
== null)
2042 return MemberList
.Empty
;
2044 return new MemberList (members
);
2047 public override MemberCache MemberCache
{
2049 return member_cache
;
2053 public static MemberList
FindMembers (Type t
, MemberTypes mt
, BindingFlags bf
,
2054 MemberFilter filter
, object criteria
)
2056 DeclSpace ds
= TypeManager
.LookupDeclSpace (t
);
2059 return ds
.FindMembers (mt
, bf
, filter
, criteria
);
2061 return new MemberList (t
.FindMembers (mt
, bf
, filter
, criteria
));
2065 /// Emits the values for the constants
2067 public void EmitConstants ()
2069 if (constants
!= null)
2070 foreach (Const con
in constants
)
2075 void CheckMemberUsage (MemberCoreArrayList al
, string member_type
)
2080 foreach (MemberCore mc
in al
) {
2081 if ((mc
.ModFlags
& Modifiers
.Accessibility
) != Modifiers
.PRIVATE
)
2084 if (!mc
.IsUsed
&& (mc
.caching_flags
& Flags
.Excluded
) == 0) {
2085 Report
.Warning (169, 3, mc
.Location
, "The private {0} `{1}' is never used", member_type
, mc
.GetSignatureForError ());
2090 public virtual void VerifyMembers ()
2093 // Check for internal or private fields that were never assigned
2095 if (Report
.WarningLevel
>= 3) {
2096 CheckMemberUsage (properties
, "property");
2097 CheckMemberUsage (methods
, "method");
2098 CheckMemberUsage (constants
, "constant");
2100 if (fields
!= null){
2101 bool is_type_exposed
= Kind
== Kind
.Struct
|| IsExposedFromAssembly ();
2102 foreach (FieldBase f
in fields
) {
2103 if ((f
.ModFlags
& Modifiers
.Accessibility
) != Modifiers
.PRIVATE
) {
2104 if (is_type_exposed
)
2107 f
.SetMemberIsUsed ();
2111 if ((f
.caching_flags
& Flags
.IsAssigned
) == 0)
2112 Report
.Warning (169, 3, f
.Location
, "The private field `{0}' is never used", f
.GetSignatureForError ());
2114 Report
.Warning (414, 3, f
.Location
, "The private field `{0}' is assigned but its value is never used",
2115 f
.GetSignatureForError ());
2121 // Only report 649 on level 4
2123 if (Report
.WarningLevel
< 4)
2126 if ((f
.caching_flags
& Flags
.IsAssigned
) != 0)
2130 // Don't be pendatic over serializable attributes
2132 if (f
.OptAttributes
!= null || PartialContainer
.HasStructLayout
)
2135 Constant c
= New
.Constantify (f
.MemberType
);
2136 Report
.Warning (649, 4, f
.Location
, "Field `{0}' is never assigned to, and will always have its default value `{1}'",
2137 f
.GetSignatureForError (), c
== null ? "null" : c
.AsString ());
2143 // TODO: move to ClassOrStruct
2144 void EmitConstructors ()
2146 if (instance_constructors
== null)
2149 if (TypeBuilder
.IsSubclassOf (TypeManager
.attribute_type
) && RootContext
.VerifyClsCompliance
&& IsClsComplianceRequired ()) {
2150 bool has_compliant_args
= false;
2152 foreach (Constructor c
in instance_constructors
) {
2156 catch (Exception e
) {
2157 throw new InternalErrorException (c
, e
);
2160 if (has_compliant_args
)
2163 has_compliant_args
= c
.HasCompliantArgs
;
2165 if (!has_compliant_args
)
2166 Report
.Warning (3015, 1, Location
, "`{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
2168 foreach (Constructor c
in instance_constructors
) {
2172 catch (Exception e
) {
2173 throw new InternalErrorException (c
, e
);
2180 /// Emits the code, this step is performed after all
2181 /// the types, enumerations, constructors
2183 public virtual void EmitType ()
2185 if (OptAttributes
!= null)
2186 OptAttributes
.Emit ();
2190 EmitConstructors ();
2192 // Can not continue if constants are broken
2194 if (Report
.Errors
> 0)
2197 if (default_static_constructor
!= null)
2198 default_static_constructor
.Emit ();
2200 if (operators
!= null)
2201 foreach (Operator o
in operators
)
2204 if (properties
!= null)
2205 foreach (Property p
in properties
)
2208 if (indexers
!= null) {
2209 foreach (Indexer indx
in indexers
)
2214 if (events
!= null){
2215 foreach (Event e
in Events
)
2219 if (methods
!= null) {
2220 for (int i
= 0; i
< methods
.Count
; ++i
)
2221 ((MethodOrOperator
) methods
[i
]).Emit ();
2225 foreach (FieldBase f
in fields
)
2228 if (delegates
!= null) {
2229 foreach (Delegate d
in Delegates
) {
2234 if (pending
!= null)
2235 pending
.VerifyPendingMethods (Report
);
2237 if (Report
.Errors
> 0)
2240 if (compiler_generated
!= null) {
2241 for (int i
= 0; i
< compiler_generated
.Count
; ++i
)
2242 ((CompilerGeneratedClass
) compiler_generated
[i
]).EmitType ();
2246 public override void CloseType ()
2248 if ((caching_flags
& Flags
.CloseTypeCreated
) != 0)
2252 caching_flags
|= Flags
.CloseTypeCreated
;
2253 TypeBuilder
.CreateType ();
2254 } catch (TypeLoadException
){
2256 // This is fine, the code still created the type
2258 // Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
2259 // Console.WriteLine (e.Message);
2260 } catch (Exception e
) {
2261 throw new InternalErrorException (this, e
);
2265 foreach (TypeContainer tc
in Types
)
2266 if (tc
.Kind
== Kind
.Struct
)
2269 foreach (TypeContainer tc
in Types
)
2270 if (tc
.Kind
!= Kind
.Struct
)
2274 if (Delegates
!= null)
2275 foreach (Delegate d
in Delegates
)
2278 if (compiler_generated
!= null)
2279 foreach (CompilerGeneratedClass c
in compiler_generated
)
2282 PartialContainer
= null;
2284 // properties = null;
2287 initialized_fields
= null;
2288 initialized_static_fields
= null;
2290 ordered_explicit_member_list
= null;
2291 ordered_member_list
= null;
2296 compiler_generated
= null;
2297 default_constructor
= null;
2298 default_static_constructor
= null;
2300 OptAttributes
= null;
2303 member_cache
= null;
2307 // Performs the validation on a Method's modifiers (properties have
2308 // the same properties).
2310 public bool MethodModifiersValid (MemberCore mc
)
2312 const int vao
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
| Modifiers
.OVERRIDE
);
2313 const int va
= (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
);
2314 const int nv
= (Modifiers
.NEW
| Modifiers
.VIRTUAL
);
2316 int flags
= mc
.ModFlags
;
2319 // At most one of static, virtual or override
2321 if ((flags
& Modifiers
.STATIC
) != 0){
2322 if ((flags
& vao
) != 0){
2323 Report
.Error (112, mc
.Location
, "A static member `{0}' cannot be marked as override, virtual or abstract",
2324 mc
.GetSignatureForError ());
2329 if (Kind
== Kind
.Struct
){
2330 if ((flags
& va
) != 0){
2331 Modifiers
.Error_InvalidModifier (mc
.Location
, "virtual or abstract", Report
);
2336 if ((flags
& Modifiers
.OVERRIDE
) != 0 && (flags
& nv
) != 0){
2337 Report
.Error (113, mc
.Location
, "A member `{0}' marked as override cannot be marked as new or virtual",
2338 mc
.GetSignatureForError ());
2343 // If the declaration includes the abstract modifier, then the
2344 // declaration does not include static, virtual or extern
2346 if ((flags
& Modifiers
.ABSTRACT
) != 0){
2347 if ((flags
& Modifiers
.EXTERN
) != 0){
2349 180, mc
.Location
, "`{0}' cannot be both extern and abstract", mc
.GetSignatureForError ());
2353 if ((flags
& Modifiers
.SEALED
) != 0) {
2354 Report
.Error (502, mc
.Location
, "`{0}' cannot be both abstract and sealed", mc
.GetSignatureForError ());
2358 if ((flags
& Modifiers
.VIRTUAL
) != 0){
2359 Report
.Error (503, mc
.Location
, "The abstract method `{0}' cannot be marked virtual", mc
.GetSignatureForError ());
2363 if ((ModFlags
& Modifiers
.ABSTRACT
) == 0){
2364 Report
.SymbolRelatedToPreviousError (this);
2365 Report
.Error (513, mc
.Location
, "`{0}' is abstract but it is declared in the non-abstract class `{1}'",
2366 mc
.GetSignatureForError (), GetSignatureForError ());
2371 if ((flags
& Modifiers
.PRIVATE
) != 0){
2372 if ((flags
& vao
) != 0){
2373 Report
.Error (621, mc
.Location
, "`{0}': virtual or abstract members cannot be private", mc
.GetSignatureForError ());
2378 if ((flags
& Modifiers
.SEALED
) != 0){
2379 if ((flags
& Modifiers
.OVERRIDE
) == 0){
2380 Report
.Error (238, mc
.Location
, "`{0}' cannot be sealed because it is not an override", mc
.GetSignatureForError ());
2388 public Constructor DefaultStaticConstructor
{
2389 get { return default_static_constructor; }
2392 protected override bool VerifyClsCompliance ()
2394 if (!base.VerifyClsCompliance ())
2399 Type base_type
= TypeBuilder
.BaseType
;
2400 if (base_type
!= null && !AttributeTester
.IsClsCompliant (base_type
)) {
2401 Report
.Warning (3009, 1, Location
, "`{0}': base type `{1}' is not CLS-compliant", GetSignatureForError (), TypeManager
.CSharpName (base_type
));
2408 /// Checks whether container name is CLS Compliant
2410 void VerifyClsName ()
2412 Hashtable base_members
= base_cache
== null ?
2414 base_cache
.GetPublicMembers ();
2415 Hashtable this_members
= new Hashtable ();
2417 foreach (DictionaryEntry entry
in defined_names
) {
2418 MemberCore mc
= (MemberCore
)entry
.Value
;
2419 if (!mc
.IsClsComplianceRequired ())
2422 string name
= (string) entry
.Key
;
2423 string basename
= name
.Substring (name
.LastIndexOf ('.') + 1);
2425 string lcase
= basename
.ToLower (System
.Globalization
.CultureInfo
.InvariantCulture
);
2426 object found
= base_members
[lcase
];
2427 if (found
== null) {
2428 found
= this_members
[lcase
];
2429 if (found
== null) {
2430 this_members
.Add (lcase
, mc
);
2435 if ((mc
.ModFlags
& Modifiers
.OVERRIDE
) != 0)
2438 if (found
is MemberInfo
) {
2439 if (basename
== ((MemberInfo
) found
).Name
)
2441 Report
.SymbolRelatedToPreviousError ((MemberInfo
) found
);
2443 Report
.SymbolRelatedToPreviousError ((MemberCore
) found
);
2446 Report
.Warning (3005, 1, mc
.Location
, "Identifier `{0}' differing only in case is not CLS-compliant", mc
.GetSignatureForError ());
2452 /// Performs checks for an explicit interface implementation. First it
2453 /// checks whether the `interface_type' is a base inteface implementation.
2454 /// Then it checks whether `name' exists in the interface type.
2456 public bool VerifyImplements (InterfaceMemberBase mb
)
2458 if (ifaces
!= null) {
2459 foreach (Type t
in ifaces
){
2460 if (TypeManager
.IsEqual (t
, mb
.InterfaceType
))
2465 Report
.SymbolRelatedToPreviousError (mb
.InterfaceType
);
2466 Report
.Error (540, mb
.Location
, "`{0}': containing type does not implement interface `{1}'",
2467 mb
.GetSignatureForError (), TypeManager
.CSharpName (mb
.InterfaceType
));
2471 public override Type
LookupAnyGeneric (string typeName
)
2473 if (types
!= null) {
2474 foreach (TypeContainer tc
in types
) {
2478 int pos
= tc
.Basename
.LastIndexOf ('`');
2479 if (pos
== typeName
.Length
&& String
.Compare (typeName
, 0, tc
.Basename
, 0, pos
) == 0)
2480 return tc
.TypeBuilder
;
2484 return base.LookupAnyGeneric (typeName
);
2487 public void Mark_HasEquals ()
2489 cached_method
|= CachedMethods
.Equals
;
2492 public void Mark_HasGetHashCode ()
2494 cached_method
|= CachedMethods
.GetHashCode
;
2498 /// Method container contains Equals method
2500 public bool HasEquals
{
2502 return (cached_method
& CachedMethods
.Equals
) != 0;
2507 /// Method container contains GetHashCode method
2509 public bool HasGetHashCode
{
2511 return (cached_method
& CachedMethods
.GetHashCode
) != 0;
2515 public bool HasStaticFieldInitializer
{
2517 return (cached_method
& CachedMethods
.HasStaticFieldInitializer
) != 0;
2521 cached_method
|= CachedMethods
.HasStaticFieldInitializer
;
2523 cached_method
&= ~CachedMethods
.HasStaticFieldInitializer
;
2531 string IMemberContainer
.Name
{
2537 Type IMemberContainer
.Type
{
2543 bool IMemberContainer
.IsInterface
{
2545 return Kind
== Kind
.Interface
;
2549 MemberList IMemberContainer
.GetMembers (MemberTypes mt
, BindingFlags bf
)
2551 BindingFlags new_bf
= bf
| BindingFlags
.DeclaredOnly
;
2553 if (GenericType
!= null)
2554 return TypeManager
.FindMembers (GenericType
, mt
, new_bf
,
2557 return FindMembers (mt
, new_bf
, null, null);
2561 // Generates xml doc comments (if any), and if required,
2562 // handle warning report.
2564 internal override void GenerateDocComment (DeclSpace ds
)
2566 DocUtil
.GenerateTypeDocComment (this, ds
, Report
);
2569 public override string DocCommentHeader
{
2570 get { return "T:"; }
2573 public MemberCache BaseCache
{
2575 if (base_cache
!= null)
2577 if (TypeBuilder
.BaseType
!= null)
2578 base_cache
= TypeManager
.LookupMemberCache (TypeBuilder
.BaseType
);
2579 if (TypeBuilder
.IsInterface
)
2580 base_cache
= TypeManager
.LookupBaseInterfacesCache (TypeBuilder
);
2586 public abstract class ClassOrStruct
: TypeContainer
{
2587 ListDictionary declarative_security
;
2589 public ClassOrStruct (NamespaceEntry ns
, DeclSpace parent
,
2590 MemberName name
, Attributes attrs
, Kind kind
)
2591 : base (ns
, parent
, name
, attrs
, kind
)
2595 protected override bool AddToContainer (MemberCore symbol
, string name
)
2597 if (name
== MemberName
.Name
) {
2598 if (symbol
is TypeParameter
) {
2599 Report
.Error (694, symbol
.Location
,
2600 "Type parameter `{0}' has same name as containing type, or method",
2601 symbol
.GetSignatureForError ());
2605 InterfaceMemberBase imb
= symbol
as InterfaceMemberBase
;
2606 if (imb
== null || !imb
.IsExplicitImpl
) {
2607 Report
.SymbolRelatedToPreviousError (this);
2608 Report
.Error (542, symbol
.Location
, "`{0}': member names cannot be the same as their enclosing type",
2609 symbol
.GetSignatureForError ());
2614 return base.AddToContainer (symbol
, name
);
2617 public override void VerifyMembers ()
2619 base.VerifyMembers ();
2621 if ((events
!= null) && Report
.WarningLevel
>= 3) {
2622 foreach (Event e
in events
){
2623 // Note: The event can be assigned from same class only, so we can report
2624 // this warning for all accessibility modes
2625 if ((e
.caching_flags
& Flags
.IsUsed
) == 0)
2626 Report
.Warning (67, 3, e
.Location
, "The event `{0}' is never used", e
.GetSignatureForError ());
2631 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
2633 if (a
.IsValidSecurityAttribute ()) {
2634 if (declarative_security
== null)
2635 declarative_security
= new ListDictionary ();
2637 a
.ExtractSecurityPermissionSet (declarative_security
);
2641 if (a
.Type
== pa
.StructLayout
) {
2642 PartialContainer
.HasStructLayout
= true;
2644 if (a
.GetLayoutKindValue () == LayoutKind
.Explicit
)
2645 PartialContainer
.HasExplicitLayout
= true;
2648 if (a
.Type
== pa
.Dynamic
) {
2649 a
.Error_MisusedDynamicAttribute ();
2653 base.ApplyAttributeBuilder (a
, cb
, pa
);
2657 /// Defines the default constructors
2659 protected void DefineDefaultConstructor (bool is_static
)
2661 // The default instance constructor is public
2662 // If the class is abstract, the default constructor is protected
2663 // The default static constructor is private
2667 mods
= Modifiers
.STATIC
| Modifiers
.PRIVATE
;
2669 mods
= ((ModFlags
& Modifiers
.ABSTRACT
) != 0) ? Modifiers
.PROTECTED
: Modifiers
.PUBLIC
;
2672 Constructor c
= new Constructor (this, MemberName
.Name
, mods
,
2673 null, ParametersCompiled
.EmptyReadOnlyParameters
,
2674 new GeneratedBaseInitializer (Location
),
2678 c
.Block
= new ToplevelBlock (Compiler
, ParametersCompiled
.EmptyReadOnlyParameters
, Location
);
2681 public override bool Define ()
2683 CheckProtectedModifier ();
2687 if (default_static_constructor
!= null)
2688 default_static_constructor
.Define ();
2693 public override void Emit ()
2695 if (default_static_constructor
== null && PartialContainer
.HasStaticFieldInitializer
) {
2696 DefineDefaultConstructor (true);
2697 default_static_constructor
.Define ();
2702 if (declarative_security
!= null) {
2703 foreach (DictionaryEntry de
in declarative_security
) {
2704 TypeBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
2709 public override ExtensionMethodGroupExpr
LookupExtensionMethod (Type extensionType
, string name
, Location loc
)
2711 DeclSpace top_level
= Parent
;
2712 if (top_level
!= null) {
2713 while (top_level
.Parent
!= null)
2714 top_level
= top_level
.Parent
;
2716 ArrayList candidates
= NamespaceEntry
.NS
.LookupExtensionMethod (extensionType
, this, name
);
2717 if (candidates
!= null)
2718 return new ExtensionMethodGroupExpr (candidates
, NamespaceEntry
, extensionType
, loc
);
2721 return NamespaceEntry
.LookupExtensionMethod (extensionType
, name
, loc
);
2724 protected override TypeAttributes TypeAttr
{
2726 if (default_static_constructor
== null)
2727 return base.TypeAttr
| TypeAttributes
.BeforeFieldInit
;
2729 return base.TypeAttr
;
2735 // TODO: should be sealed
2736 public class Class
: ClassOrStruct
{
2737 const int AllowedModifiers
=
2740 Modifiers
.PROTECTED
|
2741 Modifiers
.INTERNAL
|
2743 Modifiers
.ABSTRACT
|
2748 public const TypeAttributes StaticClassAttribute
= TypeAttributes
.Abstract
| TypeAttributes
.Sealed
;
2750 public Class (NamespaceEntry ns
, DeclSpace parent
, MemberName name
, int mod
,
2752 : base (ns
, parent
, name
, attrs
, Kind
.Class
)
2754 int accmods
= Parent
.Parent
== null ? Modifiers
.INTERNAL
: Modifiers
.PRIVATE
;
2755 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, Location
, Report
);
2757 if (IsStatic
&& RootContext
.Version
== LanguageVersion
.ISO_1
) {
2758 Report
.FeatureIsNotAvailable (Location
, "static classes");
2762 public override void AddBasesForPart (DeclSpace part
, ArrayList bases
)
2764 if (part
.Name
== "System.Object")
2765 Report
.Error (537, part
.Location
,
2766 "The class System.Object cannot have a base class or implement an interface.");
2767 base.AddBasesForPart (part
, bases
);
2770 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
2772 if (a
.Type
== pa
.AttributeUsage
) {
2773 if (!TypeManager
.IsAttributeType (BaseType
) &&
2774 TypeBuilder
.FullName
!= "System.Attribute") {
2775 Report
.Error (641, a
.Location
, "Attribute `{0}' is only valid on classes derived from System.Attribute", a
.GetSignatureForError ());
2779 if (a
.Type
== pa
.Conditional
&& !TypeManager
.IsAttributeType (BaseType
)) {
2780 Report
.Error (1689, a
.Location
, "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes");
2784 if (a
.Type
== pa
.ComImport
&& !attributes
.Contains (pa
.Guid
)) {
2785 a
.Error_MissingGuidAttribute ();
2789 if (a
.Type
== pa
.Extension
) {
2790 a
.Error_MisusedExtensionAttribute ();
2794 if (AttributeTester
.IsAttributeExcluded (a
.Type
, Location
))
2797 base.ApplyAttributeBuilder (a
, cb
, pa
);
2800 public override AttributeTargets AttributeTargets
{
2802 return AttributeTargets
.Class
;
2806 protected override void DefineContainerMembers (MemberCoreArrayList list
)
2812 base.DefineContainerMembers (list
);
2816 foreach (MemberCore m
in list
) {
2817 if (m
is Operator
) {
2818 Report
.Error (715, m
.Location
, "`{0}': Static classes cannot contain user-defined operators", m
.GetSignatureForError ());
2822 if (m
is Destructor
) {
2823 Report
.Error (711, m
.Location
, "`{0}': Static classes cannot contain destructor", GetSignatureForError ());
2828 Report
.Error (720, m
.Location
, "`{0}': cannot declare indexers in a static class", m
.GetSignatureForError ());
2832 if ((m
.ModFlags
& Modifiers
.STATIC
) != 0 || m
is Enum
|| m
is Delegate
)
2835 if (m
is Constructor
) {
2836 Report
.Error (710, m
.Location
, "`{0}': Static classes cannot have instance constructors", GetSignatureForError ());
2840 Method method
= m
as Method
;
2841 if (method
!= null && method
.Parameters
.HasExtensionMethodType
) {
2842 Report
.Error (1105, m
.Location
, "`{0}': Extension methods must be declared static", m
.GetSignatureForError ());
2846 Report
.Error (708, m
.Location
, "`{0}': cannot declare instance members in a static class", m
.GetSignatureForError ());
2849 base.DefineContainerMembers (list
);
2852 public override bool Define ()
2854 if ((ModFlags
& Modifiers
.ABSTRACT
) == Modifiers
.ABSTRACT
&& (ModFlags
& (Modifiers
.SEALED
| Modifiers
.STATIC
)) != 0) {
2855 Report
.Error (418, Location
, "`{0}': an abstract class cannot be sealed or static", GetSignatureForError ());
2858 if ((ModFlags
& (Modifiers
.SEALED
| Modifiers
.STATIC
)) == (Modifiers
.SEALED
| Modifiers
.STATIC
)) {
2859 Report
.Error (441, Location
, "`{0}': a class cannot be both static and sealed", GetSignatureForError ());
2862 return base.Define ();
2865 protected override bool DoDefineMembers ()
2867 if (InstanceConstructors
== null && !IsStatic
)
2868 DefineDefaultConstructor (false);
2870 return base.DoDefineMembers ();
2873 public override void Emit ()
2877 if ((ModFlags
& Modifiers
.METHOD_EXTENSION
) != 0)
2878 PredefinedAttributes
.Get
.Extension
.EmitAttribute (TypeBuilder
);
2881 protected override TypeExpr
[] ResolveBaseTypes (out TypeExpr base_class
)
2883 TypeExpr
[] ifaces
= base.ResolveBaseTypes (out base_class
);
2885 if (base_class
== null) {
2886 if (RootContext
.StdLib
)
2887 base_class
= TypeManager
.system_object_expr
;
2888 else if (Name
!= "System.Object")
2889 base_class
= TypeManager
.system_object_expr
;
2891 if (Kind
== Kind
.Class
&& TypeManager
.IsGenericParameter (base_class
.Type
)){
2893 689, base_class
.Location
,
2894 "Cannot derive from `{0}' because it is a type parameter",
2895 base_class
.GetSignatureForError ());
2899 if (IsGeneric
&& TypeManager
.IsAttributeType (base_class
.Type
)) {
2900 Report
.Error (698, base_class
.Location
,
2901 "A generic type cannot derive from `{0}' because it is an attribute class",
2902 base_class
.GetSignatureForError ());
2905 if (base_class
.IsSealed
){
2906 Report
.SymbolRelatedToPreviousError (base_class
.Type
);
2907 if (base_class
.Type
.IsAbstract
) {
2908 Report
.Error (709, Location
, "`{0}': Cannot derive from static class `{1}'",
2909 GetSignatureForError (), TypeManager
.CSharpName (base_class
.Type
));
2911 Report
.Error (509, Location
, "`{0}': cannot derive from sealed type `{1}'",
2912 GetSignatureForError (), TypeManager
.CSharpName (base_class
.Type
));
2917 if (!base_class
.CanInheritFrom ()){
2918 Report
.Error (644, Location
, "`{0}' cannot derive from special class `{1}'",
2919 GetSignatureForError (), base_class
.GetSignatureForError ());
2923 if (!IsAccessibleAs (base_class
.Type
)) {
2924 Report
.SymbolRelatedToPreviousError (base_class
.Type
);
2925 Report
.Error (60, Location
, "Inconsistent accessibility: base class `{0}' is less accessible than class `{1}'",
2926 TypeManager
.CSharpName (base_class
.Type
), GetSignatureForError ());
2930 if (PartialContainer
.IsStaticClass
) {
2931 if (base_class
.Type
!= TypeManager
.object_type
) {
2932 Report
.Error (713, Location
, "Static class `{0}' cannot derive from type `{1}'. Static classes must derive from object",
2933 GetSignatureForError (), base_class
.GetSignatureForError ());
2937 if (ifaces
!= null) {
2938 foreach (TypeExpr t
in ifaces
)
2939 Report
.SymbolRelatedToPreviousError (t
.Type
);
2940 Report
.Error (714, Location
, "Static class `{0}' cannot implement interfaces", GetSignatureForError ());
2947 /// Search for at least one defined condition in ConditionalAttribute of attribute class
2948 /// Valid only for attribute classes.
2949 public bool IsExcluded ()
2951 if ((caching_flags
& Flags
.Excluded_Undetected
) == 0)
2952 return (caching_flags
& Flags
.Excluded
) != 0;
2954 caching_flags
&= ~Flags
.Excluded_Undetected
;
2956 if (OptAttributes
== null)
2959 Attribute
[] attrs
= OptAttributes
.SearchMulti (PredefinedAttributes
.Get
.Conditional
);
2963 foreach (Attribute a
in attrs
) {
2964 string condition
= a
.GetConditionalAttributeValue ();
2965 if (Location
.CompilationUnit
.IsConditionalDefined (condition
))
2969 caching_flags
|= Flags
.Excluded
;
2974 // FIXME: How do we deal with the user specifying a different
2977 protected override TypeAttributes TypeAttr
{
2979 TypeAttributes ta
= base.TypeAttr
| TypeAttributes
.AutoLayout
| TypeAttributes
.Class
;
2981 ta
|= StaticClassAttribute
;
2987 public sealed class Struct
: ClassOrStruct
{
2989 bool is_unmanaged
, has_unmanaged_check_done
;
2992 // Modifiers allowed in a struct declaration
2994 const int AllowedModifiers
=
2997 Modifiers
.PROTECTED
|
2998 Modifiers
.INTERNAL
|
3002 public Struct (NamespaceEntry ns
, DeclSpace parent
, MemberName name
,
3003 int mod
, Attributes attrs
)
3004 : base (ns
, parent
, name
, attrs
, Kind
.Struct
)
3008 if (parent
.Parent
== null)
3009 accmods
= Modifiers
.INTERNAL
;
3011 accmods
= Modifiers
.PRIVATE
;
3013 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, Location
, Report
);
3015 this.ModFlags
|= Modifiers
.SEALED
;
3018 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
3020 base.ApplyAttributeBuilder (a
, cb
, pa
);
3023 // When struct constains fixed fixed and struct layout has explicitly
3024 // set CharSet, its value has to be propagated to compiler generated
3025 // fixed field types
3027 if (a
.Type
== pa
.StructLayout
&& Fields
!= null && a
.HasField ("CharSet")) {
3028 for (int i
= 0; i
< Fields
.Count
; ++i
) {
3029 FixedField ff
= Fields
[i
] as FixedField
;
3031 ff
.SetCharSet (TypeBuilder
.Attributes
);
3036 public override AttributeTargets AttributeTargets
{
3038 return AttributeTargets
.Struct
;
3042 public override bool IsUnmanagedType ()
3047 if (requires_delayed_unmanagedtype_check
)
3050 if (has_unmanaged_check_done
)
3051 return is_unmanaged
;
3053 has_unmanaged_check_done
= true;
3055 foreach (FieldBase f
in fields
) {
3056 if ((f
.ModFlags
& Modifiers
.STATIC
) != 0)
3059 // It can happen when recursive unmanaged types are defined
3060 // struct S { S* s; }
3061 Type mt
= f
.MemberType
;
3063 has_unmanaged_check_done
= false;
3064 requires_delayed_unmanagedtype_check
= true;
3068 // TODO: Remove when pointer types are under mcs control
3069 while (mt
.IsPointer
)
3070 mt
= TypeManager
.GetElementType (mt
);
3071 if (TypeManager
.IsEqual (mt
, TypeBuilder
))
3074 if (TypeManager
.IsUnmanagedType (mt
))
3080 is_unmanaged
= true;
3084 protected override TypeExpr
[] ResolveBaseTypes (out TypeExpr base_class
)
3086 TypeExpr
[] ifaces
= base.ResolveBaseTypes (out base_class
);
3088 // If we are compiling our runtime,
3089 // and we are defining ValueType, then our
3090 // base is `System.Object'.
3092 if (base_class
== null) {
3093 if (!RootContext
.StdLib
&& Name
== "System.ValueType")
3094 base_class
= TypeManager
.system_object_expr
;
3096 base_class
= TypeManager
.system_valuetype_expr
;
3103 // FIXME: Allow the user to specify a different set of attributes
3104 // in some cases (Sealed for example is mandatory for a class,
3105 // but what SequentialLayout can be changed
3107 protected override TypeAttributes TypeAttr
{
3109 const TypeAttributes DefaultTypeAttributes
=
3110 TypeAttributes
.SequentialLayout
|
3111 TypeAttributes
.Sealed
;
3113 return base.TypeAttr
| DefaultTypeAttributes
;
3117 public override void RegisterFieldForInitialization (MemberCore field
, FieldInitializer expression
)
3119 if ((field
.ModFlags
& Modifiers
.STATIC
) == 0) {
3120 Report
.Error (573, field
.Location
, "`{0}': Structs cannot have instance field initializers",
3121 field
.GetSignatureForError ());
3124 base.RegisterFieldForInitialization (field
, expression
);
3132 public sealed class Interface
: TypeContainer
, IMemberContainer
{
3135 /// Modifiers allowed in a class declaration
3137 public const int AllowedModifiers
=
3140 Modifiers
.PROTECTED
|
3141 Modifiers
.INTERNAL
|
3145 public Interface (NamespaceEntry ns
, DeclSpace parent
, MemberName name
, int mod
,
3147 : base (ns
, parent
, name
, attrs
, Kind
.Interface
)
3151 if (parent
.Parent
== null)
3152 accmods
= Modifiers
.INTERNAL
;
3154 accmods
= Modifiers
.PRIVATE
;
3156 this.ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, accmods
, name
.Location
, Report
);
3159 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
3161 if (a
.Type
== pa
.ComImport
&& !attributes
.Contains (pa
.Guid
)) {
3162 a
.Error_MissingGuidAttribute ();
3166 base.ApplyAttributeBuilder (a
, cb
, pa
);
3170 public override AttributeTargets AttributeTargets
{
3172 return AttributeTargets
.Interface
;
3176 protected override TypeAttributes TypeAttr
{
3178 const TypeAttributes DefaultTypeAttributes
=
3179 TypeAttributes
.AutoLayout
|
3180 TypeAttributes
.Abstract
|
3181 TypeAttributes
.Interface
;
3183 return base.TypeAttr
| DefaultTypeAttributes
;
3187 protected override bool VerifyClsCompliance ()
3189 if (!base.VerifyClsCompliance ())
3192 if (ifaces
!= null) {
3193 foreach (Type t
in ifaces
) {
3194 if (AttributeTester
.IsClsCompliant (t
))
3197 Report
.SymbolRelatedToPreviousError (t
);
3198 Report
.Warning (3027, 1, Location
, "`{0}' is not CLS-compliant because base interface `{1}' is not CLS-compliant",
3199 GetSignatureForError (), TypeManager
.CSharpName (t
));
3207 // It is used as a base class for all property based members
3208 // This includes properties, indexers, and events
3209 public abstract class PropertyBasedMember
: InterfaceMemberBase
3211 public PropertyBasedMember (DeclSpace parent
, GenericMethod generic
,
3212 FullNamedExpression type
, int mod
, int allowed_mod
,
3213 MemberName name
, Attributes attrs
)
3214 : base (parent
, generic
, type
, mod
, allowed_mod
, name
, attrs
)
3218 protected override bool VerifyClsCompliance ()
3220 if (!base.VerifyClsCompliance ())
3223 if (!AttributeTester
.IsClsCompliant (MemberType
)) {
3224 Report
.Warning (3003, 1, Location
, "Type of `{0}' is not CLS-compliant",
3225 GetSignatureForError ());
3233 public abstract class MethodCore
: InterfaceMemberBase
3235 public readonly ParametersCompiled Parameters
;
3236 protected ToplevelBlock block
;
3238 public MethodCore (DeclSpace parent
, GenericMethod generic
,
3239 FullNamedExpression type
, int mod
, int allowed_mod
,
3240 MemberName name
, Attributes attrs
, ParametersCompiled parameters
)
3241 : base (parent
, generic
, type
, mod
, allowed_mod
, name
, attrs
)
3243 Parameters
= parameters
;
3247 // Returns the System.Type array for the parameters of this method
3249 public Type
[] ParameterTypes
{
3251 return Parameters
.Types
;
3255 public ParametersCompiled ParameterInfo
{
3261 public ToplevelBlock Block
{
3271 public CallingConventions CallingConventions
{
3273 CallingConventions cc
= Parameters
.CallingConvention
;
3275 if ((ModFlags
& Modifiers
.STATIC
) == 0)
3276 cc
|= CallingConventions
.HasThis
;
3278 // FIXME: How is `ExplicitThis' used in C#?
3284 protected override bool CheckBase ()
3286 // Check whether arguments were correct.
3287 if (!DefineParameters (Parameters
))
3290 return base.CheckBase ();
3294 // Returns a string that represents the signature for this
3295 // member which should be used in XML documentation.
3297 public override string GetDocCommentName (DeclSpace ds
)
3299 return DocUtil
.GetMethodDocCommentName (this, Parameters
, ds
);
3303 // Raised (and passed an XmlElement that contains the comment)
3304 // when GenerateDocComment is writing documentation expectedly.
3306 // FIXME: with a few effort, it could be done with XmlReader,
3307 // that means removal of DOM use.
3309 internal override void OnGenerateDocComment (XmlElement el
)
3311 DocUtil
.OnMethodGenerateDocComment (this, el
, Report
);
3315 // Represents header string for documentation comment.
3317 public override string DocCommentHeader
3319 get { return "M:"; }
3322 public override bool EnableOverloadChecks (MemberCore overload
)
3324 if (overload
is MethodCore
|| overload
is AbstractPropertyEventMethod
) {
3325 caching_flags
|= Flags
.MethodOverloadsExist
;
3329 return base.EnableOverloadChecks (overload
);
3332 protected override bool VerifyClsCompliance ()
3334 if (!base.VerifyClsCompliance ())
3337 if (Parameters
.HasArglist
) {
3338 Report
.Warning (3000, 1, Location
, "Methods with variable arguments are not CLS-compliant");
3341 if (!AttributeTester
.IsClsCompliant (MemberType
)) {
3342 Report
.Warning (3002, 1, Location
, "Return type of `{0}' is not CLS-compliant",
3343 GetSignatureForError ());
3346 Parameters
.VerifyClsCompliance ();
3352 public abstract class InterfaceMemberBase
: MemberBase
{
3354 // Whether this is an interface member.
3356 public bool IsInterface
;
3359 // If true, this is an explicit interface implementation
3361 public bool IsExplicitImpl
;
3363 protected bool is_external_implementation
;
3366 // The interface type we are explicitly implementing
3368 public Type InterfaceType
;
3371 // The method we're overriding if this is an override method.
3373 protected MethodInfo base_method
;
3375 readonly int explicit_mod_flags
;
3376 public MethodAttributes flags
;
3378 public InterfaceMemberBase (DeclSpace parent
, GenericMethod generic
,
3379 FullNamedExpression type
, int mod
, int allowed_mod
,
3380 MemberName name
, Attributes attrs
)
3381 : base (parent
, generic
, type
, mod
, allowed_mod
, Modifiers
.PRIVATE
,
3384 IsInterface
= parent
.PartialContainer
.Kind
== Kind
.Interface
;
3385 IsExplicitImpl
= (MemberName
.Left
!= null);
3386 explicit_mod_flags
= mod
;
3389 protected override bool CheckBase ()
3391 if (!base.CheckBase ())
3394 if ((caching_flags
& Flags
.MethodOverloadsExist
) != 0)
3395 CheckForDuplications ();
3400 // Is null for System.Object while compiling corlib and base interfaces
3401 if (Parent
.PartialContainer
.BaseCache
== null) {
3402 if ((ModFlags
& Modifiers
.NEW
) != 0) {
3403 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3408 Type base_ret_type
= null;
3409 base_method
= FindOutBaseMethod (ref base_ret_type
);
3411 // method is override
3412 if (base_method
!= null) {
3413 if (!CheckMethodAgainstBase (base_ret_type
))
3416 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3417 ObsoleteAttribute oa
= AttributeTester
.GetMethodObsoleteAttribute (base_method
);
3419 if (OptAttributes
== null || !OptAttributes
.Contains (PredefinedAttributes
.Get
.Obsolete
)) {
3420 Report
.SymbolRelatedToPreviousError (base_method
);
3421 Report
.Warning (672, 1, Location
, "Member `{0}' overrides obsolete member `{1}'. Add the Obsolete attribute to `{0}'",
3422 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3425 if (OptAttributes
!= null && OptAttributes
.Contains (PredefinedAttributes
.Get
.Obsolete
)) {
3426 Report
.SymbolRelatedToPreviousError (base_method
);
3427 Report
.Warning (809, 1, Location
, "Obsolete member `{0}' overrides non-obsolete member `{1}'",
3428 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3435 MemberInfo conflict_symbol
= Parent
.PartialContainer
.FindBaseMemberWithSameName (Name
, !((this is Event
) || (this is Property
)));
3436 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
3437 if (conflict_symbol
!= null) {
3438 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
3440 Report
.Error (72, Location
, "`{0}': cannot override because `{1}' is not an event", GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3441 else if (this is PropertyBase
)
3442 Report
.Error (544, Location
, "`{0}': cannot override because `{1}' is not a property", GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3444 Report
.Error (505, Location
, "`{0}': cannot override because `{1}' is not a method", GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3446 Report
.Error (115, Location
, "`{0}' is marked as an override but no suitable {1} found to override",
3447 GetSignatureForError (), SimpleName
.GetMemberType (this));
3452 if (conflict_symbol
== null) {
3453 if ((ModFlags
& Modifiers
.NEW
) != 0) {
3454 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
3459 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3460 if (this is MethodOrOperator
&& conflict_symbol
.MemberType
== MemberTypes
.Method
)
3463 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
3464 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3465 GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
3471 protected virtual bool CheckForDuplications ()
3473 return Parent
.MemberCache
.CheckExistingMembersOverloads (
3474 this, GetFullName (MemberName
), ParametersCompiled
.EmptyReadOnlyParameters
, Report
);
3478 // Performs various checks on the MethodInfo `mb' regarding the modifier flags
3479 // that have been defined.
3481 // `name' is the user visible name for reporting errors (this is used to
3482 // provide the right name regarding method names and properties)
3484 bool CheckMethodAgainstBase (Type base_method_type
)
3488 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0){
3489 if (!(base_method
.IsAbstract
|| base_method
.IsVirtual
)){
3490 Report
.SymbolRelatedToPreviousError (base_method
);
3491 Report
.Error (506, Location
,
3492 "`{0}': cannot override inherited member `{1}' because it is not marked virtual, abstract or override",
3493 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3497 // Now we check that the overriden method is not final
3499 if (base_method
.IsFinal
) {
3500 Report
.SymbolRelatedToPreviousError (base_method
);
3501 Report
.Error (239, Location
, "`{0}': cannot override inherited member `{1}' because it is sealed",
3502 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3506 // Check that the permissions are not being changed
3508 MethodAttributes thisp
= flags
& MethodAttributes
.MemberAccessMask
;
3509 MethodAttributes base_classp
= base_method
.Attributes
& MethodAttributes
.MemberAccessMask
;
3511 if (!CheckAccessModifiers (thisp
, base_classp
, base_method
)) {
3512 Error_CannotChangeAccessModifiers (Location
, base_method
, base_classp
, null);
3516 if (!TypeManager
.IsEqual (MemberType
, TypeManager
.TypeToCoreType (base_method_type
))) {
3517 Report
.SymbolRelatedToPreviousError (base_method
);
3518 if (this is PropertyBasedMember
) {
3519 Report
.Error (1715, Location
, "`{0}': type must be `{1}' to match overridden member `{2}'",
3520 GetSignatureForError (), TypeManager
.CSharpName (base_method_type
), TypeManager
.CSharpSignature (base_method
));
3523 Report
.Error (508, Location
, "`{0}': return type must be `{1}' to match overridden member `{2}'",
3524 GetSignatureForError (), TypeManager
.CSharpName (base_method_type
), TypeManager
.CSharpSignature (base_method
));
3530 if ((ModFlags
& Modifiers
.NEW
) == 0) {
3531 if ((ModFlags
& Modifiers
.OVERRIDE
) == 0) {
3532 ModFlags
|= Modifiers
.NEW
;
3533 Report
.SymbolRelatedToPreviousError (base_method
);
3534 if (!IsInterface
&& (base_method
.IsVirtual
|| base_method
.IsAbstract
)) {
3535 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",
3536 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3537 if (base_method
.IsAbstract
){
3538 Report
.Error (533, Location
, "`{0}' hides inherited abstract member `{1}'",
3539 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3543 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
3544 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3548 if (base_method
.IsAbstract
&& !IsInterface
) {
3549 Report
.SymbolRelatedToPreviousError (base_method
);
3550 Report
.Error (533, Location
, "`{0}' hides inherited abstract member `{1}'",
3551 GetSignatureForError (), TypeManager
.CSharpSignature (base_method
));
3559 protected bool CheckAccessModifiers (MethodAttributes thisp
, MethodAttributes base_classp
, MethodInfo base_method
)
3561 if ((base_classp
& MethodAttributes
.FamORAssem
) == MethodAttributes
.FamORAssem
){
3563 // when overriding protected internal, the method can be declared
3564 // protected internal only within the same assembly or assembly
3565 // which has InternalsVisibleTo
3567 if ((thisp
& MethodAttributes
.FamORAssem
) == MethodAttributes
.FamORAssem
){
3568 return TypeManager
.IsThisOrFriendAssembly (Parent
.Module
.Assembly
, base_method
.DeclaringType
.Assembly
);
3569 } else if ((thisp
& MethodAttributes
.Family
) != MethodAttributes
.Family
) {
3571 // if it's not "protected internal", it must be "protected"
3575 } else if (Parent
.TypeBuilder
.Assembly
== base_method
.DeclaringType
.Assembly
) {
3577 // protected within the same assembly - an error
3580 } else if ((thisp
& ~
(MethodAttributes
.Family
| MethodAttributes
.FamORAssem
)) !=
3581 (base_classp
& ~
(MethodAttributes
.Family
| MethodAttributes
.FamORAssem
))) {
3583 // protected ok, but other attributes differ - report an error
3589 return (thisp
== base_classp
);
3593 public override bool Define ()
3596 ModFlags
= Modifiers
.PUBLIC
| Modifiers
.ABSTRACT
|
3597 Modifiers
.VIRTUAL
| (ModFlags
& (Modifiers
.UNSAFE
| Modifiers
.NEW
));
3599 flags
= MethodAttributes
.Public
|
3600 MethodAttributes
.Abstract
|
3601 MethodAttributes
.HideBySig
|
3602 MethodAttributes
.NewSlot
|
3603 MethodAttributes
.Virtual
;
3605 Parent
.PartialContainer
.MethodModifiersValid (this);
3607 flags
= Modifiers
.MethodAttr (ModFlags
);
3610 if (IsExplicitImpl
) {
3611 TypeExpr iface_texpr
= MemberName
.Left
.GetTypeExpression ().ResolveAsTypeTerminal (this, false);
3612 if (iface_texpr
== null)
3615 if ((ModFlags
& Modifiers
.PARTIAL
) != 0) {
3616 Report
.Error (754, Location
, "A partial method `{0}' cannot explicitly implement an interface",
3617 GetSignatureForError ());
3620 InterfaceType
= iface_texpr
.Type
;
3622 if (!InterfaceType
.IsInterface
) {
3623 Report
.SymbolRelatedToPreviousError (InterfaceType
);
3624 Report
.Error (538, Location
, "The type `{0}' in explicit interface declaration is not an interface",
3625 TypeManager
.CSharpName (InterfaceType
));
3627 Parent
.PartialContainer
.VerifyImplements (this);
3630 Modifiers
.Check (Modifiers
.AllowedExplicitImplFlags
, explicit_mod_flags
, 0, Location
, Report
);
3633 return base.Define ();
3636 protected bool DefineParameters (ParametersCompiled parameters
)
3638 if (!parameters
.Resolve (this))
3642 for (int i
= 0; i
< parameters
.Count
; ++i
) {
3643 Parameter p
= parameters
[i
];
3645 if (p
.HasDefaultValue
&& (IsExplicitImpl
|| this is Operator
|| (this is Indexer
&& parameters
.Count
== 1)))
3646 p
.Warning_UselessOptionalParameter (Report
);
3648 if (p
.CheckAccessibility (this))
3651 Type t
= parameters
.Types
[i
];
3652 Report
.SymbolRelatedToPreviousError (t
);
3653 if (this is Indexer
)
3654 Report
.Error (55, Location
,
3655 "Inconsistent accessibility: parameter type `{0}' is less accessible than indexer `{1}'",
3656 TypeManager
.CSharpName (t
), GetSignatureForError ());
3657 else if (this is Operator
)
3658 Report
.Error (57, Location
,
3659 "Inconsistent accessibility: parameter type `{0}' is less accessible than operator `{1}'",
3660 TypeManager
.CSharpName (t
), GetSignatureForError ());
3662 Report
.Error (51, Location
,
3663 "Inconsistent accessibility: parameter type `{0}' is less accessible than method `{1}'",
3664 TypeManager
.CSharpName (t
), GetSignatureForError ());
3670 public override void Emit()
3672 // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
3673 // We are more strict than csc and report this as an error because SRE does not allow emit that
3674 if ((ModFlags
& Modifiers
.EXTERN
) != 0 && !is_external_implementation
) {
3675 if (this is Constructor
) {
3676 Report
.Error (824, Location
,
3677 "Constructor `{0}' is marked `external' but has no external implementation specified", GetSignatureForError ());
3679 Report
.Error (626, Location
,
3680 "`{0}' is marked as an external but has no DllImport attribute. Consider adding a DllImport attribute to specify the external implementation",
3681 GetSignatureForError ());
3688 public override bool EnableOverloadChecks (MemberCore overload
)
3691 // Two members can differ in their explicit interface
3692 // type parameter only
3694 InterfaceMemberBase imb
= overload
as InterfaceMemberBase
;
3695 if (imb
!= null && imb
.IsExplicitImpl
) {
3696 if (IsExplicitImpl
) {
3697 caching_flags
|= Flags
.MethodOverloadsExist
;
3702 return IsExplicitImpl
;
3705 protected void Error_CannotChangeAccessModifiers (Location loc
, MemberInfo base_method
, MethodAttributes ma
, string suffix
)
3707 Report
.SymbolRelatedToPreviousError (base_method
);
3708 string base_name
= TypeManager
.GetFullNameSignature (base_method
);
3709 string this_name
= GetSignatureForError ();
3710 if (suffix
!= null) {
3711 base_name
+= suffix
;
3712 this_name
+= suffix
;
3715 Report
.Error (507, loc
, "`{0}': cannot change access modifiers when overriding `{1}' inherited member `{2}'",
3716 this_name
, Modifiers
.GetDescription (ma
), base_name
);
3719 protected static string Error722
{
3721 return "`{0}': static types cannot be used as return types";
3726 /// Gets base method and its return type
3728 protected abstract MethodInfo
FindOutBaseMethod (ref Type base_ret_type
);
3731 // The "short" name of this property / indexer / event. This is the
3732 // name without the explicit interface.
3734 public string ShortName
3736 get { return MemberName.Name; }
3737 set { SetMemberName (new MemberName (MemberName.Left, value, Location)); }
3741 // Returns full metadata method name
3743 public string GetFullName (MemberName name
)
3745 if (!IsExplicitImpl
)
3749 // When dealing with explicit members a full interface type
3750 // name is added to member name to avoid possible name conflicts
3752 // We use CSharpName which gets us full name with benefit of
3753 // replacing predefined names which saves some space and name
3756 return TypeManager
.CSharpName (InterfaceType
) + "." + name
.Name
;
3759 protected override bool VerifyClsCompliance ()
3761 if (!base.VerifyClsCompliance ()) {
3762 if (IsInterface
&& HasClsCompliantAttribute
&& Parent
.IsClsComplianceRequired ()) {
3763 Report
.Warning (3010, 1, Location
, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
3766 if ((ModFlags
& Modifiers
.ABSTRACT
) != 0 && Parent
.TypeBuilder
.IsClass
&& IsExposedFromAssembly () && Parent
.IsClsComplianceRequired ()) {
3767 Report
.Warning (3011, 1, Location
, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
3772 if (GenericMethod
!= null)
3773 GenericMethod
.VerifyClsCompliance ();
3778 public override bool IsUsed
3780 get { return IsExplicitImpl || base.IsUsed; }
3785 public abstract class MethodOrOperator
: MethodCore
, IMethodData
3787 public MethodBuilder MethodBuilder
;
3788 ReturnParameter return_attributes
;
3789 ListDictionary declarative_security
;
3790 protected MethodData MethodData
;
3792 static string[] attribute_targets
= new string [] { "method", "return" }
;
3794 protected MethodOrOperator (DeclSpace parent
, GenericMethod generic
, FullNamedExpression type
, int mod
,
3795 int allowed_mod
, MemberName name
,
3796 Attributes attrs
, ParametersCompiled parameters
)
3797 : base (parent
, generic
, type
, mod
, allowed_mod
, name
,
3802 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
3804 if (a
.Target
== AttributeTargets
.ReturnValue
) {
3805 if (return_attributes
== null)
3806 return_attributes
= new ReturnParameter (MethodBuilder
, Location
);
3808 return_attributes
.ApplyAttributeBuilder (a
, cb
, pa
);
3812 if (a
.IsInternalMethodImplAttribute
) {
3813 is_external_implementation
= true;
3816 if (a
.Type
== pa
.DllImport
) {
3817 const int extern_static
= Modifiers
.EXTERN
| Modifiers
.STATIC
;
3818 if ((ModFlags
& extern_static
) != extern_static
) {
3819 Report
.Error (601, a
.Location
, "The DllImport attribute must be specified on a method marked `static' and `extern'");
3821 is_external_implementation
= true;
3824 if (a
.IsValidSecurityAttribute ()) {
3825 if (declarative_security
== null)
3826 declarative_security
= new ListDictionary ();
3827 a
.ExtractSecurityPermissionSet (declarative_security
);
3831 if (MethodBuilder
!= null)
3832 MethodBuilder
.SetCustomAttribute (cb
);
3835 public override AttributeTargets AttributeTargets
{
3837 return AttributeTargets
.Method
;
3841 protected override bool CheckForDuplications ()
3843 string name
= GetFullName (MemberName
);
3844 if (MemberName
.IsGeneric
)
3845 name
= MemberName
.MakeName (name
, MemberName
.TypeArguments
);
3847 return Parent
.MemberCache
.CheckExistingMembersOverloads (this, name
, Parameters
, Report
);
3850 public virtual EmitContext
CreateEmitContext (ILGenerator ig
)
3852 return new EmitContext (
3853 this, ig
, MemberType
);
3856 protected override bool ResolveMemberType ()
3858 if (GenericMethod
!= null) {
3859 MethodBuilder
= Parent
.TypeBuilder
.DefineMethod (GetFullName (MemberName
), flags
);
3860 if (!GenericMethod
.Define (this))
3864 return base.ResolveMemberType ();
3867 public override bool Define ()
3869 if (!base.Define ())
3875 if (block
!= null && block
.IsIterator
&& !(Parent
is IteratorStorey
)) {
3877 // Current method is turned into automatically generated
3878 // wrapper which creates an instance of iterator
3880 Iterator
.CreateIterator (this, Parent
.PartialContainer
, ModFlags
, Compiler
);
3881 ModFlags
|= Modifiers
.DEBUGGER_HIDDEN
;
3884 if (IsPartialDefinition
) {
3885 caching_flags
&= ~Flags
.Excluded_Undetected
;
3886 caching_flags
|= Flags
.Excluded
;
3887 // Add to member cache only when a partial method implementation is not there
3888 if ((caching_flags
& Flags
.MethodOverloadsExist
) == 0) {
3889 MethodBase mb
= new PartialMethodDefinitionInfo (this);
3890 Parent
.MemberCache
.AddMember (mb
, this);
3891 TypeManager
.AddMethod (mb
, this);
3897 MethodData
= new MethodData (
3898 this, ModFlags
, flags
, this, MethodBuilder
, GenericMethod
, base_method
);
3900 if (!MethodData
.Define (Parent
.PartialContainer
, GetFullName (MemberName
), Report
))
3903 MethodBuilder
= MethodData
.MethodBuilder
;
3905 if (TypeManager
.IsGenericMethod (MethodBuilder
))
3906 Parent
.MemberCache
.AddGenericMember (MethodBuilder
, this);
3908 Parent
.MemberCache
.AddMember (MethodBuilder
, this);
3913 protected override void DoMemberTypeIndependentChecks ()
3915 base.DoMemberTypeIndependentChecks ();
3917 CheckAbstractAndExtern (block
!= null);
3919 if ((ModFlags
& Modifiers
.PARTIAL
) != 0) {
3920 for (int i
= 0; i
< Parameters
.Count
; ++i
) {
3921 IParameterData p
= Parameters
.FixedParameters
[i
];
3922 if (p
.ModFlags
== Parameter
.Modifier
.OUT
) {
3923 Report
.Error (752, Location
, "`{0}': A partial method parameters cannot use `out' modifier",
3924 GetSignatureForError ());
3927 if (p
.HasDefaultValue
&& IsPartialImplementation
)
3928 ((Parameter
) p
).Warning_UselessOptionalParameter (Report
);
3933 protected override void DoMemberTypeDependentChecks ()
3935 base.DoMemberTypeDependentChecks ();
3937 if (!TypeManager
.IsGenericParameter (MemberType
)) {
3938 if (MemberType
.IsAbstract
&& MemberType
.IsSealed
) {
3939 Report
.Error (722, Location
, Error722
, TypeManager
.CSharpName (MemberType
));
3944 public override void Emit ()
3946 if ((ModFlags
& Modifiers
.COMPILER_GENERATED
) != 0 && !Parent
.IsCompilerGenerated
)
3947 PredefinedAttributes
.Get
.CompilerGenerated
.EmitAttribute (MethodBuilder
);
3948 if ((ModFlags
& Modifiers
.DEBUGGER_HIDDEN
) != 0)
3949 PredefinedAttributes
.Get
.DebuggerHidden
.EmitAttribute (MethodBuilder
);
3951 if (TypeManager
.IsDynamicType (ReturnType
)) {
3952 return_attributes
= new ReturnParameter (MethodBuilder
, Location
);
3953 PredefinedAttributes
.Get
.Dynamic
.EmitAttribute (return_attributes
.Builder
);
3956 if (OptAttributes
!= null)
3957 OptAttributes
.Emit ();
3959 if (declarative_security
!= null) {
3960 foreach (DictionaryEntry de
in declarative_security
) {
3961 MethodBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
3965 if (MethodData
!= null)
3966 MethodData
.Emit (Parent
);
3974 protected void Error_ConditionalAttributeIsNotValid ()
3976 Report
.Error (577, Location
,
3977 "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
3978 GetSignatureForError ());
3981 public bool IsPartialDefinition
{
3983 return (ModFlags
& Modifiers
.PARTIAL
) != 0 && Block
== null;
3987 public bool IsPartialImplementation
{
3989 return (ModFlags
& Modifiers
.PARTIAL
) != 0 && Block
!= null;
3993 public override string[] ValidAttributeTargets
{
3995 return attribute_targets
;
3999 #region IMethodData Members
4001 public Type ReturnType
{
4007 public MemberName MethodName
{
4014 /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
4016 public bool IsExcluded () {
4017 if ((caching_flags
& Flags
.Excluded_Undetected
) == 0)
4018 return (caching_flags
& Flags
.Excluded
) != 0;
4020 caching_flags
&= ~Flags
.Excluded_Undetected
;
4022 if (base_method
== null) {
4023 if (OptAttributes
== null)
4026 Attribute
[] attrs
= OptAttributes
.SearchMulti (PredefinedAttributes
.Get
.Conditional
);
4031 foreach (Attribute a
in attrs
) {
4032 string condition
= a
.GetConditionalAttributeValue ();
4033 if (condition
== null)
4036 if (Location
.CompilationUnit
.IsConditionalDefined (condition
))
4040 caching_flags
|= Flags
.Excluded
;
4044 IMethodData md
= TypeManager
.GetMethod (TypeManager
.DropGenericMethodArguments (base_method
));
4046 if (AttributeTester
.IsConditionalMethodExcluded (base_method
, Location
)) {
4047 caching_flags
|= Flags
.Excluded
;
4053 if (md
.IsExcluded ()) {
4054 caching_flags
|= Flags
.Excluded
;
4060 GenericMethod IMethodData
.GenericMethod
{
4062 return GenericMethod
;
4066 public virtual void EmitExtraSymbolInfo (SourceMethod source
)
4073 public class SourceMethod
: IMethodDef
4076 SourceMethodBuilder builder
;
4078 protected SourceMethod (DeclSpace parent
, MethodBase method
, ICompileUnit file
)
4080 this.method
= method
;
4082 builder
= SymbolWriter
.OpenMethod (file
, parent
.NamespaceEntry
.SymbolFileID
, this);
4085 public string Name
{
4086 get { return method.Name; }
4091 if (method
is MethodBuilder
)
4092 return ((MethodBuilder
) method
).GetToken ().Token
;
4093 else if (method
is ConstructorBuilder
)
4094 return ((ConstructorBuilder
) method
).GetToken ().Token
;
4096 throw new NotSupportedException ();
4100 public void CloseMethod ()
4102 SymbolWriter
.CloseMethod ();
4105 public void SetRealMethodName (string name
)
4107 if (builder
!= null)
4108 builder
.SetRealMethodName (name
);
4111 public static SourceMethod
Create (DeclSpace parent
, MethodBase method
, Block block
)
4113 if (!SymbolWriter
.HasSymbolWriter
)
4118 Location start_loc
= block
.StartLocation
;
4119 if (start_loc
.IsNull
)
4122 ICompileUnit compile_unit
= start_loc
.CompilationUnit
;
4123 if (compile_unit
== null)
4126 return new SourceMethod (parent
, method
, compile_unit
);
4130 public class Method
: MethodOrOperator
{
4133 /// Modifiers allowed in a class declaration
4135 const int AllowedModifiers
=
4138 Modifiers
.PROTECTED
|
4139 Modifiers
.INTERNAL
|
4144 Modifiers
.OVERRIDE
|
4145 Modifiers
.ABSTRACT
|
4149 const int AllowedInterfaceModifiers
=
4150 Modifiers
.NEW
| Modifiers
.UNSAFE
;
4152 Method partialMethodImplementation
;
4154 public Method (DeclSpace parent
, GenericMethod generic
,
4155 FullNamedExpression return_type
, int mod
,
4156 MemberName name
, ParametersCompiled parameters
, Attributes attrs
)
4157 : base (parent
, generic
, return_type
, mod
,
4158 parent
.PartialContainer
.Kind
== Kind
.Interface
? AllowedInterfaceModifiers
: AllowedModifiers
,
4159 name
, attrs
, parameters
)
4163 protected Method (DeclSpace parent
, FullNamedExpression return_type
, int mod
, int amod
,
4164 MemberName name
, ParametersCompiled parameters
, Attributes attrs
)
4165 : base (parent
, null, return_type
, mod
, amod
, name
, attrs
, parameters
)
4169 public override string GetSignatureForError()
4171 return base.GetSignatureForError () + Parameters
.GetSignatureForError ();
4174 void Error_DuplicateEntryPoint (Method b
)
4176 Report
.Error (17, b
.Location
,
4177 "Program `{0}' has more than one entry point defined: `{1}'",
4178 CodeGen
.FileName
, b
.GetSignatureForError ());
4181 bool IsEntryPoint ()
4183 if (ReturnType
!= TypeManager
.void_type
&&
4184 ReturnType
!= TypeManager
.int32_type
)
4187 if (Parameters
.Count
== 0)
4190 if (Parameters
.Count
> 1)
4193 Type t
= Parameters
.Types
[0];
4194 return t
.IsArray
&& t
.GetArrayRank () == 1 &&
4195 TypeManager
.GetElementType (t
) == TypeManager
.string_type
&&
4196 (Parameters
[0].ModFlags
& ~Parameter
.Modifier
.PARAMS
) == Parameter
.Modifier
.NONE
;
4199 public override FullNamedExpression
LookupNamespaceOrType (string name
, Location loc
, bool ignore_cs0104
)
4201 TypeParameter
[] tp
= CurrentTypeParameters
;
4203 TypeParameter t
= TypeParameter
.FindTypeParameter (tp
, name
);
4205 return new TypeParameterExpr (t
, loc
);
4208 return base.LookupNamespaceOrType (name
, loc
, ignore_cs0104
);
4211 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
4213 if (a
.Type
== pa
.Conditional
) {
4214 if (IsExplicitImpl
) {
4215 Error_ConditionalAttributeIsNotValid ();
4219 if (ReturnType
!= TypeManager
.void_type
) {
4220 Report
.Error (578, Location
, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
4224 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
4225 Report
.Error (243, Location
, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
4230 Report
.Error (582, Location
, "Conditional not valid on interface members");
4234 if (MethodData
.implementing
!= null) {
4235 Report
.SymbolRelatedToPreviousError (MethodData
.implementing
.DeclaringType
);
4236 Report
.Error (629, Location
, "Conditional member `{0}' cannot implement interface member `{1}'",
4237 GetSignatureForError (), TypeManager
.CSharpSignature (MethodData
.implementing
));
4241 for (int i
= 0; i
< Parameters
.Count
; ++i
) {
4242 if (Parameters
.FixedParameters
[i
].ModFlags
== Parameter
.Modifier
.OUT
) {
4243 Report
.Error (685, Location
, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
4249 if (a
.Type
== pa
.Extension
) {
4250 a
.Error_MisusedExtensionAttribute ();
4254 base.ApplyAttributeBuilder (a
, cb
, pa
);
4257 protected override bool CheckForDuplications ()
4259 if (!base.CheckForDuplications ())
4262 ArrayList ar
= Parent
.PartialContainer
.Properties
;
4264 for (int i
= 0; i
< ar
.Count
; ++i
) {
4265 PropertyBase pb
= (PropertyBase
) ar
[i
];
4266 if (pb
.AreAccessorsDuplicateImplementation (this))
4271 ar
= Parent
.PartialContainer
.Indexers
;
4273 for (int i
= 0; i
< ar
.Count
; ++i
) {
4274 PropertyBase pb
= (PropertyBase
) ar
[i
];
4275 if (pb
.AreAccessorsDuplicateImplementation (this))
4283 protected override bool CheckBase ()
4285 if (!base.CheckBase ())
4288 if (base_method
!= null && (ModFlags
& Modifiers
.OVERRIDE
) != 0 && Name
== Destructor
.MetadataName
) {
4289 Report
.Error (249, Location
, "Do not override `{0}'. Use destructor syntax instead",
4290 TypeManager
.CSharpSignature (base_method
));
4296 public override TypeParameter
[] CurrentTypeParameters
{
4298 if (GenericMethod
!= null)
4299 return GenericMethod
.CurrentTypeParameters
;
4308 public override bool Define ()
4310 if (type_name
== TypeManager
.system_void_expr
&& Parameters
.IsEmpty
&& Name
== Destructor
.MetadataName
) {
4311 Report
.Warning (465, 1, Location
, "Introducing `Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
4314 if (!base.Define ())
4317 if (partialMethodImplementation
!= null && IsPartialDefinition
)
4318 MethodBuilder
= partialMethodImplementation
.MethodBuilder
;
4320 if (RootContext
.StdLib
&& TypeManager
.IsSpecialType (ReturnType
)) {
4321 Error1599 (Location
, ReturnType
, Report
);
4325 if (base_method
!= null && (ModFlags
& Modifiers
.NEW
) == 0) {
4326 if (Parameters
.Count
== 1 && ParameterTypes
[0] == TypeManager
.object_type
&& Name
== "Equals")
4327 Parent
.PartialContainer
.Mark_HasEquals ();
4328 else if (Parameters
.IsEmpty
&& Name
== "GetHashCode")
4329 Parent
.PartialContainer
.Mark_HasGetHashCode ();
4332 if ((ModFlags
& Modifiers
.STATIC
) == 0)
4335 if (Parameters
.HasExtensionMethodType
) {
4336 if (Parent
.PartialContainer
.IsStaticClass
&& !Parent
.IsGeneric
) {
4337 if (!Parent
.IsTopLevel
)
4338 Report
.Error (1109, Location
, "`{0}': Extension methods cannot be defined in a nested class",
4339 GetSignatureForError ());
4341 PredefinedAttribute pa
= PredefinedAttributes
.Get
.Extension
;
4342 if (!pa
.IsDefined
) {
4343 Report
.Error (1110, Location
,
4344 "`{0}': Extension methods cannot be declared without a reference to System.Core.dll assembly. Add the assembly reference or remove `this' modifer from the first parameter",
4345 GetSignatureForError ());
4348 ModFlags
|= Modifiers
.METHOD_EXTENSION
;
4349 Parent
.PartialContainer
.ModFlags
|= Modifiers
.METHOD_EXTENSION
;
4350 CodeGen
.Assembly
.HasExtensionMethods
= true;
4352 Report
.Error (1106, Location
, "`{0}': Extension methods must be defined in a non-generic static class",
4353 GetSignatureForError ());
4358 // This is used to track the Entry Point,
4360 if (RootContext
.NeedsEntryPoint
&&
4362 (RootContext
.MainClass
== null ||
4363 RootContext
.MainClass
== Parent
.TypeBuilder
.FullName
)){
4364 if (IsEntryPoint ()) {
4366 if (RootContext
.EntryPoint
== null) {
4367 if (Parent
.IsGeneric
|| MemberName
.IsGeneric
) {
4368 Report
.Warning (402, 4, Location
, "`{0}': an entry point cannot be generic or in a generic type",
4369 GetSignatureForError ());
4372 RootContext
.EntryPoint
= this;
4375 Error_DuplicateEntryPoint (RootContext
.EntryPoint
);
4376 Error_DuplicateEntryPoint (this);
4379 Report
.Warning (28, 4, Location
, "`{0}' has the wrong signature to be an entry point",
4380 GetSignatureForError ());
4390 public override void Emit ()
4393 Report
.Debug (64, "METHOD EMIT", this, MethodBuilder
, Location
, Block
, MethodData
);
4394 if (IsPartialDefinition
) {
4396 // Use partial method implementation builder for partial method declaration attributes
4398 if (partialMethodImplementation
!= null) {
4399 MethodBuilder
= partialMethodImplementation
.MethodBuilder
;
4402 } else if ((ModFlags
& Modifiers
.PARTIAL
) != 0 && (caching_flags
& Flags
.PartialDefinitionExists
) == 0) {
4403 Report
.Error (759, Location
, "A partial method `{0}' implementation is missing a partial method declaration",
4404 GetSignatureForError ());
4409 if ((ModFlags
& Modifiers
.METHOD_EXTENSION
) != 0)
4410 PredefinedAttributes
.Get
.Extension
.EmitAttribute (MethodBuilder
);
4412 Console
.WriteLine ("Internal compiler error at {0}: exception caught while emitting {1}",
4413 Location
, MethodBuilder
);
4418 public override bool EnableOverloadChecks (MemberCore overload
)
4420 // TODO: It can be deleted when members will be defined in correct order
4421 if (overload
is Operator
)
4422 return overload
.EnableOverloadChecks (this);
4424 if (overload
is Indexer
)
4427 return base.EnableOverloadChecks (overload
);
4430 public static void Error1599 (Location loc
, Type t
, Report Report
)
4432 Report
.Error (1599, loc
, "Method or delegate cannot return type `{0}'", TypeManager
.CSharpName (t
));
4435 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
4437 MethodInfo mi
= (MethodInfo
) Parent
.PartialContainer
.BaseCache
.FindMemberToOverride (
4438 Parent
.TypeBuilder
, Name
, Parameters
, GenericMethod
, false);
4443 if (mi
.IsSpecialName
)
4446 base_ret_type
= TypeManager
.TypeToCoreType (mi
.ReturnType
);
4450 public void SetPartialDefinition (Method methodDefinition
)
4452 caching_flags
|= Flags
.PartialDefinitionExists
;
4453 methodDefinition
.partialMethodImplementation
= this;
4455 // Ensure we are always using method declaration parameters
4456 for (int i
= 0; i
< methodDefinition
.Parameters
.Count
; ++i
) {
4457 Parameters
[i
].Name
= methodDefinition
.Parameters
[i
].Name
;
4458 Parameters
[i
].DefaultValue
= methodDefinition
.Parameters
[i
].DefaultValue
;
4461 if (methodDefinition
.attributes
== null)
4464 if (attributes
== null) {
4465 attributes
= methodDefinition
.attributes
;
4467 attributes
.Attrs
.AddRange (methodDefinition
.attributes
.Attrs
);
4471 protected override bool VerifyClsCompliance ()
4473 if (!base.VerifyClsCompliance ())
4476 if (!Parameters
.IsEmpty
) {
4477 ArrayList al
= (ArrayList
)Parent
.PartialContainer
.MemberCache
.Members
[Name
];
4479 MemberCache
.VerifyClsParameterConflict (al
, this, MethodBuilder
, Report
);
4486 public abstract class ConstructorInitializer
: ExpressionStatement
4488 Arguments argument_list
;
4489 MethodGroupExpr base_constructor_group
;
4491 public ConstructorInitializer (Arguments argument_list
, Location loc
)
4493 this.argument_list
= argument_list
;
4497 public Arguments Arguments
{
4499 return argument_list
;
4503 public override Expression
CreateExpressionTree (ResolveContext ec
)
4505 throw new NotSupportedException ("ET");
4508 public override Expression
DoResolve (ResolveContext ec
)
4510 eclass
= ExprClass
.Value
;
4512 // TODO: ec.GetSignatureForError ()
4513 ConstructorBuilder caller_builder
= ((Constructor
) ec
.MemberContext
).ConstructorBuilder
;
4515 if (argument_list
!= null) {
4519 // Spec mandates that constructor initializer will not have `this' access
4521 using (ec
.Set (ResolveContext
.Options
.BaseInitializer
)) {
4522 argument_list
.Resolve (ec
, out dynamic);
4526 ec
.Report
.Error (1975, loc
,
4527 "The constructor call cannot be dynamically dispatched within constructor initializer");
4533 type
= ec
.CurrentType
;
4534 if (this is ConstructorBaseInitializer
) {
4535 if (ec
.CurrentType
.BaseType
== null)
4538 type
= ec
.CurrentType
.BaseType
;
4539 if (TypeManager
.IsStruct (ec
.CurrentType
)) {
4540 ec
.Report
.Error (522, loc
,
4541 "`{0}': Struct constructors cannot call base constructors", TypeManager
.CSharpSignature (caller_builder
));
4546 // It is legal to have "this" initializers that take no arguments
4547 // in structs, they are just no-ops.
4549 // struct D { public D (int a) : this () {}
4551 if (TypeManager
.IsStruct (ec
.CurrentType
) && argument_list
== null)
4555 base_constructor_group
= MemberLookupFinal (
4556 ec
, null, type
, ConstructorBuilder
.ConstructorName
, MemberTypes
.Constructor
,
4557 BindingFlags
.Public
| BindingFlags
.Instance
| BindingFlags
.DeclaredOnly
,
4558 loc
) as MethodGroupExpr
;
4560 if (base_constructor_group
== null)
4563 base_constructor_group
= base_constructor_group
.OverloadResolve (
4564 ec
, ref argument_list
, false, loc
);
4566 if (base_constructor_group
== null)
4570 base_constructor_group
.InstanceExpression
= ec
.GetThis (loc
);
4572 ConstructorInfo base_ctor
= (ConstructorInfo
)base_constructor_group
;
4574 if (base_ctor
== caller_builder
){
4575 ec
.Report
.Error (516, loc
, "Constructor `{0}' cannot call itself", TypeManager
.CSharpSignature (caller_builder
));
4581 public override void Emit (EmitContext ec
)
4583 // It can be null for static initializers
4584 if (base_constructor_group
== null)
4589 base_constructor_group
.EmitCall (ec
, argument_list
);
4592 public override void EmitStatement (EmitContext ec
)
4598 public class ConstructorBaseInitializer
: ConstructorInitializer
{
4599 public ConstructorBaseInitializer (Arguments argument_list
, Location l
) :
4600 base (argument_list
, l
)
4605 class GeneratedBaseInitializer
: ConstructorBaseInitializer
{
4606 public GeneratedBaseInitializer (Location loc
):
4612 public class ConstructorThisInitializer
: ConstructorInitializer
{
4613 public ConstructorThisInitializer (Arguments argument_list
, Location l
) :
4614 base (argument_list
, l
)
4619 public class Constructor
: MethodCore
, IMethodData
{
4620 public ConstructorBuilder ConstructorBuilder
;
4621 public ConstructorInitializer Initializer
;
4622 ListDictionary declarative_security
;
4623 bool has_compliant_args
;
4626 // Modifiers allowed for a constructor.
4628 public const int AllowedModifiers
=
4630 Modifiers
.PROTECTED
|
4631 Modifiers
.INTERNAL
|
4637 static readonly string[] attribute_targets
= new string [] { "method" }
;
4640 // The spec claims that static is not permitted, but
4641 // my very own code has static constructors.
4643 public Constructor (DeclSpace parent
, string name
, int mod
, Attributes attrs
, ParametersCompiled args
,
4644 ConstructorInitializer init
, Location loc
)
4645 : base (parent
, null, null, mod
, AllowedModifiers
,
4646 new MemberName (name
, loc
), attrs
, args
)
4651 public bool HasCompliantArgs
{
4652 get { return has_compliant_args; }
4655 public override AttributeTargets AttributeTargets
{
4656 get { return AttributeTargets.Constructor; }
4660 // Returns true if this is a default constructor
4662 public bool IsDefault ()
4664 if ((ModFlags
& Modifiers
.STATIC
) != 0)
4665 return Parameters
.IsEmpty
;
4667 return Parameters
.IsEmpty
&&
4668 (Initializer
is ConstructorBaseInitializer
) &&
4669 (Initializer
.Arguments
== null);
4672 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
4674 if (a
.IsValidSecurityAttribute ()) {
4675 if (declarative_security
== null) {
4676 declarative_security
= new ListDictionary ();
4678 a
.ExtractSecurityPermissionSet (declarative_security
);
4682 if (a
.IsInternalMethodImplAttribute
) {
4683 is_external_implementation
= true;
4686 ConstructorBuilder
.SetCustomAttribute (cb
);
4689 protected override bool CheckBase ()
4691 if ((ModFlags
& Modifiers
.STATIC
) != 0) {
4692 if (!Parameters
.IsEmpty
) {
4693 Report
.Error (132, Location
, "`{0}': The static constructor must be parameterless",
4694 GetSignatureForError ());
4698 // the rest can be ignored
4702 // Check whether arguments were correct.
4703 if (!DefineParameters (Parameters
))
4706 if ((caching_flags
& Flags
.MethodOverloadsExist
) != 0)
4707 Parent
.MemberCache
.CheckExistingMembersOverloads (this, ConstructorInfo
.ConstructorName
,
4708 Parameters
, Report
);
4710 if (Parent
.PartialContainer
.Kind
== Kind
.Struct
) {
4711 if (Parameters
.Count
== 0) {
4712 Report
.Error (568, Location
,
4713 "Structs cannot contain explicit parameterless constructors");
4718 CheckProtectedModifier ();
4724 // Creates the ConstructorBuilder
4726 public override bool Define ()
4728 if (ConstructorBuilder
!= null)
4731 MethodAttributes ca
= (MethodAttributes
.RTSpecialName
|
4732 MethodAttributes
.SpecialName
);
4734 if ((ModFlags
& Modifiers
.STATIC
) != 0) {
4735 ca
|= MethodAttributes
.Static
| MethodAttributes
.Private
;
4737 ca
|= MethodAttributes
.HideBySig
;
4739 if ((ModFlags
& Modifiers
.PUBLIC
) != 0)
4740 ca
|= MethodAttributes
.Public
;
4741 else if ((ModFlags
& Modifiers
.PROTECTED
) != 0){
4742 if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
4743 ca
|= MethodAttributes
.FamORAssem
;
4745 ca
|= MethodAttributes
.Family
;
4746 } else if ((ModFlags
& Modifiers
.INTERNAL
) != 0)
4747 ca
|= MethodAttributes
.Assembly
;
4749 ca
|= MethodAttributes
.Private
;
4752 if (!CheckAbstractAndExtern (block
!= null))
4755 // Check if arguments were correct.
4759 ConstructorBuilder
= Parent
.TypeBuilder
.DefineConstructor (
4760 ca
, CallingConventions
,
4761 Parameters
.GetEmitTypes ());
4763 if (Parent
.PartialContainer
.IsComImport
) {
4764 if (!IsDefault ()) {
4765 Report
.Error (669, Location
, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
4766 Parent
.GetSignatureForError ());
4768 ConstructorBuilder
.SetImplementationFlags (MethodImplAttributes
.InternalCall
);
4771 Parent
.MemberCache
.AddMember (ConstructorBuilder
, this);
4772 TypeManager
.AddMethod (ConstructorBuilder
, this);
4774 // It's here only to report an error
4775 if (block
!= null && block
.IsIterator
) {
4776 member_type
= TypeManager
.void_type
;
4777 Iterator
.CreateIterator (this, Parent
.PartialContainer
, ModFlags
, Compiler
);
4786 public override void Emit ()
4788 if ((ModFlags
& Modifiers
.DEBUGGER_HIDDEN
) != 0)
4789 PredefinedAttributes
.Get
.DebuggerHidden
.EmitAttribute (ConstructorBuilder
);
4791 if (OptAttributes
!= null)
4792 OptAttributes
.Emit ();
4797 // If we use a "this (...)" constructor initializer, then
4798 // do not emit field initializers, they are initialized in the other constructor
4800 bool emit_field_initializers
= ((ModFlags
& Modifiers
.STATIC
) != 0) ||
4801 !(Initializer
is ConstructorThisInitializer
);
4803 BlockContext bc
= new BlockContext (this, block
, TypeManager
.void_type
);
4804 bc
.Set (ResolveContext
.Options
.ConstructorScope
);
4806 if (emit_field_initializers
)
4807 Parent
.PartialContainer
.ResolveFieldInitializers (bc
);
4809 if (block
!= null) {
4810 // If this is a non-static `struct' constructor and doesn't have any
4811 // initializer, it must initialize all of the struct's fields.
4812 if ((Parent
.PartialContainer
.Kind
== Kind
.Struct
) &&
4813 ((ModFlags
& Modifiers
.STATIC
) == 0) && (Initializer
== null))
4814 block
.AddThisVariable (Parent
, Location
);
4816 if (block
!= null && (ModFlags
& Modifiers
.STATIC
) == 0){
4817 if (Parent
.PartialContainer
.Kind
== Kind
.Class
&& Initializer
== null)
4818 Initializer
= new GeneratedBaseInitializer (Location
);
4820 if (Initializer
!= null) {
4821 block
.AddScopeStatement (new StatementExpression (Initializer
));
4826 Parameters
.ApplyAttributes (ConstructorBuilder
);
4828 SourceMethod source
= SourceMethod
.Create (Parent
, ConstructorBuilder
, block
);
4830 if (block
!= null) {
4831 if (block
.Resolve (null, bc
, Parameters
, this)) {
4832 EmitContext ec
= new EmitContext (this, ConstructorBuilder
.GetILGenerator (), bc
.ReturnType
);
4833 ec
.With (EmitContext
.Options
.ConstructorScope
, true);
4835 if (!ec
.HasReturnLabel
&& bc
.HasReturnLabel
) {
4836 ec
.ReturnLabel
= bc
.ReturnLabel
;
4837 ec
.HasReturnLabel
= true;
4845 source
.CloseMethod ();
4847 if (declarative_security
!= null) {
4848 foreach (DictionaryEntry de
in declarative_security
) {
4849 ConstructorBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
4856 // Is never override
4857 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
4862 public override string GetSignatureForError()
4864 return base.GetSignatureForError () + Parameters
.GetSignatureForError ();
4867 public override string[] ValidAttributeTargets
{
4869 return attribute_targets
;
4873 protected override bool VerifyClsCompliance ()
4875 if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
4879 if (!Parameters
.IsEmpty
) {
4880 ArrayList al
= (ArrayList
)Parent
.MemberCache
.Members
[ConstructorInfo
.ConstructorName
];
4882 MemberCache
.VerifyClsParameterConflict (al
, this, ConstructorBuilder
, Report
);
4884 if (TypeManager
.IsSubclassOf (Parent
.TypeBuilder
, TypeManager
.attribute_type
)) {
4885 foreach (Type param
in Parameters
.Types
) {
4886 if (param
.IsArray
) {
4892 has_compliant_args
= true;
4896 #region IMethodData Members
4898 public MemberName MethodName
{
4904 public Type ReturnType
{
4910 public EmitContext
CreateEmitContext (ILGenerator ig
)
4912 throw new NotImplementedException ();
4915 public bool IsExcluded()
4920 GenericMethod IMethodData
.GenericMethod
{
4926 void IMethodData
.EmitExtraSymbolInfo (SourceMethod source
)
4933 /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
4935 public interface IMethodData
4937 CallingConventions CallingConventions { get; }
4938 Location Location { get; }
4939 MemberName MethodName { get; }
4940 Type ReturnType { get; }
4941 GenericMethod GenericMethod { get; }
4942 ParametersCompiled ParameterInfo { get; }
4944 Attributes OptAttributes { get; }
4945 ToplevelBlock Block { get; set; }
4947 EmitContext
CreateEmitContext (ILGenerator ig
);
4948 ObsoleteAttribute
GetObsoleteAttribute ();
4949 string GetSignatureForError ();
4951 bool IsClsComplianceRequired ();
4952 void SetMemberIsUsed ();
4953 void EmitExtraSymbolInfo (SourceMethod source
);
4957 // Encapsulates most of the Method's state
4959 public class MethodData
{
4960 static FieldInfo methodbuilder_attrs_field
;
4961 public readonly IMethodData method
;
4963 public readonly GenericMethod GenericMethod
;
4966 // Are we implementing an interface ?
4968 public MethodInfo implementing
;
4973 protected InterfaceMemberBase member
;
4974 protected int modifiers
;
4975 protected MethodAttributes flags
;
4976 protected Type declaring_type
;
4977 protected MethodInfo parent_method
;
4979 MethodBuilder builder
= null;
4980 public MethodBuilder MethodBuilder
{
4986 public Type DeclaringType
{
4988 return declaring_type
;
4992 public MethodData (InterfaceMemberBase member
,
4993 int modifiers
, MethodAttributes flags
, IMethodData method
)
4995 this.member
= member
;
4996 this.modifiers
= modifiers
;
4999 this.method
= method
;
5002 public MethodData (InterfaceMemberBase member
,
5003 int modifiers
, MethodAttributes flags
,
5004 IMethodData method
, MethodBuilder builder
,
5005 GenericMethod generic
, MethodInfo parent_method
)
5006 : this (member
, modifiers
, flags
, method
)
5008 this.builder
= builder
;
5009 this.GenericMethod
= generic
;
5010 this.parent_method
= parent_method
;
5013 public bool Define (DeclSpace parent
, string method_full_name
, Report Report
)
5015 string name
= method
.MethodName
.Basename
;
5017 TypeContainer container
= parent
.PartialContainer
;
5019 PendingImplementation pending
= container
.PendingImplementations
;
5020 if (pending
!= null){
5021 implementing
= pending
.IsInterfaceMethod (name
, member
.InterfaceType
, this);
5023 if (member
.InterfaceType
!= null){
5024 if (implementing
== null){
5025 if (member
is PropertyBase
) {
5026 Report
.Error (550, method
.Location
, "`{0}' is an accessor not found in interface member `{1}{2}'",
5027 method
.GetSignatureForError (), TypeManager
.CSharpName (member
.InterfaceType
),
5028 member
.GetSignatureForError ().Substring (member
.GetSignatureForError ().LastIndexOf ('.')));
5031 Report
.Error (539, method
.Location
,
5032 "`{0}.{1}' in explicit interface declaration is not a member of interface",
5033 TypeManager
.CSharpName (member
.InterfaceType
), member
.ShortName
);
5037 if (implementing
.IsSpecialName
&& !(method
is AbstractPropertyEventMethod
)) {
5038 Report
.SymbolRelatedToPreviousError (implementing
);
5039 Report
.Error (683, method
.Location
, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
5040 member
.GetSignatureForError (), TypeManager
.CSharpSignature (implementing
));
5044 if (implementing
!= null) {
5045 AbstractPropertyEventMethod prop_method
= method
as AbstractPropertyEventMethod
;
5046 if (prop_method
== null) {
5047 if (TypeManager
.IsSpecialMethod (implementing
)) {
5048 Report
.SymbolRelatedToPreviousError (implementing
);
5049 Report
.Error (470, method
.Location
, "Method `{0}' cannot implement interface accessor `{1}.{2}'",
5050 method
.GetSignatureForError (), TypeManager
.CSharpSignature (implementing
),
5051 implementing
.Name
.StartsWith ("get_") ? "get" : "set");
5053 } else if (implementing
.DeclaringType
.IsInterface
) {
5054 if (!implementing
.IsSpecialName
) {
5055 Report
.SymbolRelatedToPreviousError (implementing
);
5056 Report
.Error (686, method
.Location
, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
5057 method
.GetSignatureForError (), TypeManager
.CSharpSignature (implementing
), container
.GetSignatureForError ());
5060 PropertyBase
.PropertyMethod pm
= prop_method
as PropertyBase
.PropertyMethod
;
5061 if (pm
!= null && pm
.HasCustomAccessModifier
&& (pm
.ModFlags
& Modifiers
.PUBLIC
) == 0) {
5062 Report
.SymbolRelatedToPreviousError (implementing
);
5063 Report
.Error (277, method
.Location
, "Accessor `{0}' must be declared public to implement interface member `{1}'",
5064 method
.GetSignatureForError (), TypeManager
.CSharpSignature (implementing
, true));
5073 // For implicit implementations, make sure we are public, for
5074 // explicit implementations, make sure we are private.
5076 if (implementing
!= null){
5078 // Setting null inside this block will trigger a more
5079 // verbose error reporting for missing interface implementations
5081 // The "candidate" function has been flagged already
5082 // but it wont get cleared
5084 if (member
.IsExplicitImpl
){
5085 if (method
.ParameterInfo
.HasParams
&& !TypeManager
.GetParameterData (implementing
).HasParams
) {
5086 Report
.SymbolRelatedToPreviousError (implementing
);
5087 Report
.Error (466, method
.Location
, "`{0}': the explicit interface implementation cannot introduce the params modifier",
5088 method
.GetSignatureForError ());
5092 if (implementing
.DeclaringType
.IsInterface
) {
5094 // If this is an interface method implementation,
5095 // check for public accessibility
5097 if ((flags
& MethodAttributes
.MemberAccessMask
) != MethodAttributes
.Public
)
5099 implementing
= null;
5101 } else if ((flags
& MethodAttributes
.MemberAccessMask
) == MethodAttributes
.Private
){
5102 // We may never be private.
5103 implementing
= null;
5105 } else if ((modifiers
& Modifiers
.OVERRIDE
) == 0){
5107 // We may be protected if we're overriding something.
5109 implementing
= null;
5114 // Static is not allowed
5116 if ((modifiers
& Modifiers
.STATIC
) != 0){
5117 implementing
= null;
5122 // If implementing is still valid, set flags
5124 if (implementing
!= null){
5126 // When implementing interface methods, set NewSlot
5127 // unless, we are overwriting a method.
5129 if (implementing
.DeclaringType
.IsInterface
){
5130 if ((modifiers
& Modifiers
.OVERRIDE
) == 0)
5131 flags
|= MethodAttributes
.NewSlot
;
5134 MethodAttributes
.Virtual
|
5135 MethodAttributes
.HideBySig
;
5137 // Set Final unless we're virtual, abstract or already overriding a method.
5138 if ((modifiers
& (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
| Modifiers
.OVERRIDE
)) == 0)
5139 flags
|= MethodAttributes
.Final
;
5142 DefineMethodBuilder (container
, method_full_name
, method
.ParameterInfo
);
5144 if (builder
== null)
5147 if (container
.CurrentType
!= null)
5148 declaring_type
= container
.CurrentType
;
5150 declaring_type
= container
.TypeBuilder
;
5152 if (implementing
!= null && member
.IsExplicitImpl
) {
5153 container
.TypeBuilder
.DefineMethodOverride (builder
, implementing
);
5156 TypeManager
.AddMethod (builder
, method
);
5158 if (GenericMethod
!= null) {
5159 bool is_override
= member
.IsExplicitImpl
|
5160 ((modifiers
& Modifiers
.OVERRIDE
) != 0);
5162 if (implementing
!= null)
5163 parent_method
= implementing
;
5165 if (!GenericMethod
.DefineType (GenericMethod
, builder
, parent_method
, is_override
))
5174 /// Create the MethodBuilder for the method
5176 void DefineMethodBuilder (TypeContainer container
, string method_name
, ParametersCompiled param
)
5178 if (builder
== null) {
5179 builder
= container
.TypeBuilder
.DefineMethod (
5180 method_name
, flags
, method
.CallingConventions
,
5181 TypeManager
.TypeToReflectionType (method
.ReturnType
),
5182 param
.GetEmitTypes ());
5187 // Generic method has been already defined to resolve method parameters
5188 // correctly when they use type parameters
5190 builder
.SetParameters (param
.GetEmitTypes ());
5191 builder
.SetReturnType (method
.ReturnType
);
5192 if (builder
.Attributes
!= flags
) {
5194 if (methodbuilder_attrs_field
== null)
5195 methodbuilder_attrs_field
= typeof (MethodBuilder
).GetField ("attrs", BindingFlags
.NonPublic
| BindingFlags
.Instance
);
5196 methodbuilder_attrs_field
.SetValue (builder
, flags
);
5198 RootContext
.ToplevelTypes
.Compiler
.Report
.RuntimeMissingSupport (method
.Location
, "Generic method MethodAttributes");
5206 public void Emit (DeclSpace parent
)
5208 method
.ParameterInfo
.ApplyAttributes (MethodBuilder
);
5210 if (GenericMethod
!= null)
5211 GenericMethod
.EmitAttributes ();
5214 // clear the pending implementation flag
5216 if (implementing
!= null)
5217 parent
.PartialContainer
.PendingImplementations
.ImplementMethod (method
.MethodName
.Basename
,
5218 member
.InterfaceType
, this, member
.IsExplicitImpl
);
5220 SourceMethod source
= SourceMethod
.Create (parent
, MethodBuilder
, method
.Block
);
5222 ToplevelBlock block
= method
.Block
;
5223 if (block
!= null) {
5224 BlockContext bc
= new BlockContext ((IMemberContext
) method
, block
, method
.ReturnType
);
5225 if (block
.Resolve (null, bc
, method
.ParameterInfo
, method
)) {
5226 EmitContext ec
= method
.CreateEmitContext (MethodBuilder
.GetILGenerator ());
5227 if (!ec
.HasReturnLabel
&& bc
.HasReturnLabel
) {
5228 ec
.ReturnLabel
= bc
.ReturnLabel
;
5229 ec
.HasReturnLabel
= true;
5236 if (source
!= null) {
5237 method
.EmitExtraSymbolInfo (source
);
5238 source
.CloseMethod ();
5243 public class Destructor
: MethodOrOperator
5245 const int AllowedModifiers
=
5249 static readonly string[] attribute_targets
= new string [] { "method" }
;
5251 public static readonly string MetadataName
= "Finalize";
5253 public Destructor (DeclSpace parent
, int mod
, ParametersCompiled parameters
, Attributes attrs
, Location l
)
5254 : base (parent
, null, TypeManager
.system_void_expr
, mod
, AllowedModifiers
,
5255 new MemberName (MetadataName
, l
), attrs
, parameters
)
5257 ModFlags
&= ~Modifiers
.PRIVATE
;
5258 ModFlags
|= Modifiers
.PROTECTED
;
5261 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
5263 if (a
.Type
== pa
.Conditional
) {
5264 Error_ConditionalAttributeIsNotValid ();
5268 base.ApplyAttributeBuilder (a
, cb
, pa
);
5271 protected override bool CheckBase ()
5273 flags
|= MethodAttributes
.Virtual
;
5275 if (!base.CheckBase ())
5278 if (Parent
.PartialContainer
.BaseCache
== null)
5281 Type base_type
= Parent
.PartialContainer
.BaseCache
.Container
.Type
;
5282 if (base_type
!= null && Block
!= null) {
5283 MethodGroupExpr method_expr
= Expression
.MethodLookup (Parent
.Module
.Compiler
, Parent
.TypeBuilder
, base_type
, MetadataName
, Location
);
5284 if (method_expr
== null)
5285 throw new NotImplementedException ();
5287 method_expr
.IsBase
= true;
5288 method_expr
.InstanceExpression
= new CompilerGeneratedThis (Parent
.TypeBuilder
, Location
);
5290 ToplevelBlock new_block
= new ToplevelBlock (Compiler
, Block
.StartLocation
);
5291 new_block
.EndLocation
= Block
.EndLocation
;
5293 Block finaly_block
= new ExplicitBlock (new_block
, Location
, Location
);
5294 Block try_block
= new Block (new_block
, block
);
5297 // 0-size arguments to avoid CS0250 error
5298 // TODO: Should use AddScopeStatement or something else which emits correct
5301 finaly_block
.AddStatement (new StatementExpression (new Invocation (method_expr
, new Arguments (0))));
5302 new_block
.AddStatement (new TryFinally (try_block
, finaly_block
, Location
));
5310 public override string GetSignatureForError ()
5312 return Parent
.GetSignatureForError () + ".~" + Parent
.MemberName
.Name
+ "()";
5315 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
5320 public override string[] ValidAttributeTargets
{
5322 return attribute_targets
;
5327 public abstract class MemberBase
: MemberCore
5329 protected FullNamedExpression type_name
;
5330 protected Type member_type
;
5332 public readonly DeclSpace ds
;
5333 public readonly GenericMethod GenericMethod
;
5335 protected MemberBase (DeclSpace parent
, GenericMethod generic
,
5336 FullNamedExpression type
, int mod
, int allowed_mod
, int def_mod
,
5337 MemberName name
, Attributes attrs
)
5338 : base (parent
, name
, attrs
)
5340 this.ds
= generic
!= null ? generic
: (DeclSpace
) parent
;
5341 this.type_name
= type
;
5342 ModFlags
= Modifiers
.Check (allowed_mod
, mod
, def_mod
, Location
, Report
);
5343 GenericMethod
= generic
;
5344 if (GenericMethod
!= null)
5345 GenericMethod
.ModFlags
= ModFlags
;
5349 // Main member define entry
5351 public override bool Define ()
5353 DoMemberTypeIndependentChecks ();
5356 // Returns false only when type resolution failed
5358 if (!ResolveMemberType ())
5361 DoMemberTypeDependentChecks ();
5366 // Any type_name independent checks
5368 protected virtual void DoMemberTypeIndependentChecks ()
5370 if ((Parent
.ModFlags
& Modifiers
.SEALED
) != 0 &&
5371 (ModFlags
& (Modifiers
.VIRTUAL
| Modifiers
.ABSTRACT
)) != 0) {
5372 Report
.Error (549, Location
, "New virtual member `{0}' is declared in a sealed class `{1}'",
5373 GetSignatureForError (), Parent
.GetSignatureForError ());
5378 // Any type_name dependent checks
5380 protected virtual void DoMemberTypeDependentChecks ()
5382 // verify accessibility
5383 if (!IsAccessibleAs (MemberType
)) {
5384 Report
.SymbolRelatedToPreviousError (MemberType
);
5385 if (this is Property
)
5386 Report
.Error (53, Location
,
5387 "Inconsistent accessibility: property type `" +
5388 TypeManager
.CSharpName (MemberType
) + "' is less " +
5389 "accessible than property `" + GetSignatureForError () + "'");
5390 else if (this is Indexer
)
5391 Report
.Error (54, Location
,
5392 "Inconsistent accessibility: indexer return type `" +
5393 TypeManager
.CSharpName (MemberType
) + "' is less " +
5394 "accessible than indexer `" + GetSignatureForError () + "'");
5395 else if (this is MethodCore
) {
5396 if (this is Operator
)
5397 Report
.Error (56, Location
,
5398 "Inconsistent accessibility: return type `" +
5399 TypeManager
.CSharpName (MemberType
) + "' is less " +
5400 "accessible than operator `" + GetSignatureForError () + "'");
5402 Report
.Error (50, Location
,
5403 "Inconsistent accessibility: return type `" +
5404 TypeManager
.CSharpName (MemberType
) + "' is less " +
5405 "accessible than method `" + GetSignatureForError () + "'");
5407 Report
.Error (52, Location
,
5408 "Inconsistent accessibility: field type `" +
5409 TypeManager
.CSharpName (MemberType
) + "' is less " +
5410 "accessible than field `" + GetSignatureForError () + "'");
5414 Variance variance
= this is Event
? Variance
.Contravariant
: Variance
.Covariant
;
5415 TypeManager
.CheckTypeVariance (MemberType
, variance
, this);
5418 protected bool IsTypePermitted ()
5420 if (TypeManager
.IsSpecialType (MemberType
)) {
5421 Report
.Error (610, Location
, "Field or property cannot be of type `{0}'", TypeManager
.CSharpName (MemberType
));
5427 protected virtual bool CheckBase ()
5429 CheckProtectedModifier ();
5434 public Type MemberType
{
5435 get { return member_type; }
5438 protected virtual bool ResolveMemberType ()
5440 if (member_type
!= null)
5441 throw new InternalErrorException ("Multi-resolve");
5443 TypeExpr te
= type_name
.ResolveAsTypeTerminal (this, false);
5448 // Replace original type name, error reporting can use fully resolved name
5452 member_type
= te
.Type
;
5458 // Abstract class for all fields
5460 abstract public class FieldBase
: MemberBase
{
5461 public FieldBuilder FieldBuilder
;
5462 public Status status
;
5463 protected Expression initializer
;
5466 public enum Status
: byte {
5467 HAS_OFFSET
= 4 // Used by FieldMember.
5470 static readonly string[] attribute_targets
= new string [] { "field" }
;
5472 protected FieldBase (DeclSpace parent
, FullNamedExpression type
, int mod
,
5473 int allowed_mod
, MemberName name
, Attributes attrs
)
5474 : base (parent
, null, type
, mod
, allowed_mod
| Modifiers
.ABSTRACT
, Modifiers
.PRIVATE
,
5477 if ((mod
& Modifiers
.ABSTRACT
) != 0)
5478 Report
.Error (681, Location
, "The modifier 'abstract' is not valid on fields. Try using a property instead");
5481 public override AttributeTargets AttributeTargets
{
5483 return AttributeTargets
.Field
;
5487 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
5489 if (a
.Type
== pa
.FieldOffset
) {
5490 status
|= Status
.HAS_OFFSET
;
5492 if (!Parent
.PartialContainer
.HasExplicitLayout
) {
5493 Report
.Error (636, Location
, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
5497 if ((ModFlags
& Modifiers
.STATIC
) != 0 || this is Const
) {
5498 Report
.Error (637, Location
, "The FieldOffset attribute is not allowed on static or const fields");
5503 if (a
.Type
== pa
.FixedBuffer
) {
5504 Report
.Error (1716, Location
, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead");
5509 if (a
.Type
== pa
.MarshalAs
) {
5510 UnmanagedMarshal marshal
= a
.GetMarshal (this);
5511 if (marshal
!= null) {
5512 FieldBuilder
.SetMarshal (marshal
);
5517 if ((a
.HasSecurityAttribute
)) {
5518 a
.Error_InvalidSecurityParent ();
5522 if (a
.Type
== pa
.Dynamic
) {
5523 a
.Error_MisusedDynamicAttribute ();
5527 FieldBuilder
.SetCustomAttribute (cb
);
5530 protected override bool CheckBase ()
5532 if (!base.CheckBase ())
5535 MemberInfo conflict_symbol
= Parent
.PartialContainer
.FindBaseMemberWithSameName (Name
, false);
5536 if (conflict_symbol
== null) {
5537 if ((ModFlags
& Modifiers
.NEW
) != 0) {
5538 Report
.Warning (109, 4, Location
, "The member `{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
5543 if ((ModFlags
& (Modifiers
.NEW
| Modifiers
.OVERRIDE
| Modifiers
.BACKING_FIELD
)) == 0) {
5544 Report
.SymbolRelatedToPreviousError (conflict_symbol
);
5545 Report
.Warning (108, 2, Location
, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
5546 GetSignatureForError (), TypeManager
.GetFullNameSignature (conflict_symbol
));
5552 protected override void DoMemberTypeDependentChecks ()
5554 base.DoMemberTypeDependentChecks ();
5556 if (TypeManager
.IsGenericParameter (MemberType
))
5559 if (MemberType
.IsSealed
&& MemberType
.IsAbstract
) {
5560 Error_VariableOfStaticClass (Location
, GetSignatureForError (), MemberType
, Report
);
5568 // Represents header string for documentation comment.
5570 public override string DocCommentHeader
{
5571 get { return "F:"; }
5574 public override void Emit ()
5576 if (TypeManager
.IsDynamicType (member_type
))
5577 PredefinedAttributes
.Get
.Dynamic
.EmitAttribute (FieldBuilder
);
5579 if ((ModFlags
& Modifiers
.COMPILER_GENERATED
) != 0 && !Parent
.IsCompilerGenerated
)
5580 PredefinedAttributes
.Get
.CompilerGenerated
.EmitAttribute (FieldBuilder
);
5582 if (OptAttributes
!= null) {
5583 OptAttributes
.Emit ();
5586 if (((status
& Status
.HAS_OFFSET
) == 0) && (ModFlags
& (Modifiers
.STATIC
| Modifiers
.BACKING_FIELD
)) == 0 && Parent
.PartialContainer
.HasExplicitLayout
) {
5587 Report
.Error (625, Location
, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute", GetSignatureForError ());
5593 public static void Error_VariableOfStaticClass (Location loc
, string variable_name
, Type static_class
, Report Report
)
5595 Report
.SymbolRelatedToPreviousError (static_class
);
5596 Report
.Error (723, loc
, "`{0}': cannot declare variables of static types",
5600 public Expression Initializer
{
5602 if (value != null) {
5603 this.initializer
= value;
5608 protected virtual bool IsFieldClsCompliant
{
5610 if (FieldBuilder
== null)
5613 return AttributeTester
.IsClsCompliant (FieldBuilder
.FieldType
);
5617 public override string[] ValidAttributeTargets
5620 return attribute_targets
;
5624 protected override bool VerifyClsCompliance ()
5626 if (!base.VerifyClsCompliance ())
5629 if (!IsFieldClsCompliant
) {
5630 Report
.Warning (3003, 1, Location
, "Type of `{0}' is not CLS-compliant",
5631 GetSignatureForError ());
5636 public void SetAssigned ()
5638 caching_flags
|= Flags
.IsAssigned
;
5642 interface IFixedBuffer
5644 FieldInfo Element { get; }
5645 Type ElementType { get; }
5648 public class FixedFieldExternal
: IFixedBuffer
5650 FieldInfo element_field
;
5652 public FixedFieldExternal (FieldInfo fi
)
5654 element_field
= fi
.FieldType
.GetField (FixedField
.FixedElementName
);
5657 #region IFixedField Members
5659 public FieldInfo Element
{
5661 return element_field
;
5665 public Type ElementType
{
5667 return element_field
.FieldType
;
5675 /// Fixed buffer implementation
5677 public class FixedField
: FieldBase
, IFixedBuffer
5679 public const string FixedElementName
= "FixedElementField";
5680 static int GlobalCounter
= 0;
5681 static object[] ctor_args
= new object[] { (short)LayoutKind.Sequential }
;
5682 static FieldInfo
[] fi
;
5684 TypeBuilder fixed_buffer_type
;
5685 FieldBuilder element
;
5686 Expression size_expr
;
5688 const int AllowedModifiers
=
5691 Modifiers
.PROTECTED
|
5692 Modifiers
.INTERNAL
|
5695 public FixedField (DeclSpace parent
, FullNamedExpression type
, int mod
, string name
,
5696 Expression size_expr
, Attributes attrs
, Location loc
):
5697 base (parent
, type
, mod
, AllowedModifiers
, new MemberName (name
, loc
), attrs
)
5699 if (RootContext
.Version
< LanguageVersion
.ISO_2
)
5700 Report
.FeatureIsNotAvailable (loc
, "fixed size buffers");
5702 this.size_expr
= size_expr
;
5705 public override bool Define()
5707 if (!base.Define ())
5710 if (!TypeManager
.IsPrimitiveType (MemberType
)) {
5711 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",
5712 GetSignatureForError ());
5715 // Create nested fixed buffer container
5716 string name
= String
.Format ("<{0}>__FixedBuffer{1}", Name
, GlobalCounter
++);
5717 fixed_buffer_type
= Parent
.TypeBuilder
.DefineNestedType (name
, Parent
.Module
.DefaultCharSetType
|
5718 TypeAttributes
.NestedPublic
| TypeAttributes
.Sealed
| TypeAttributes
.BeforeFieldInit
, TypeManager
.value_type
);
5720 element
= fixed_buffer_type
.DefineField (FixedElementName
, MemberType
, FieldAttributes
.Public
);
5721 RootContext
.RegisterCompilerGeneratedType (fixed_buffer_type
);
5723 FieldBuilder
= Parent
.TypeBuilder
.DefineField (Name
, fixed_buffer_type
, Modifiers
.FieldAttr (ModFlags
));
5724 Parent
.MemberCache
.AddMember (FieldBuilder
, this);
5725 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
5730 protected override void DoMemberTypeIndependentChecks ()
5732 base.DoMemberTypeIndependentChecks ();
5734 if (!Parent
.IsUnsafe
)
5735 Expression
.UnsafeError (Report
, Location
);
5737 if (Parent
.PartialContainer
.Kind
!= Kind
.Struct
) {
5738 Report
.Error (1642, Location
, "`{0}': Fixed size buffer fields may only be members of structs",
5739 GetSignatureForError ());
5743 public override void Emit()
5745 ResolveContext rc
= new ResolveContext (this);
5746 Constant c
= size_expr
.ResolveAsConstant (rc
, this);
5750 IntConstant buffer_size_const
= c
.ImplicitConversionRequired (rc
, TypeManager
.int32_type
, Location
) as IntConstant
;
5751 if (buffer_size_const
== null)
5754 int buffer_size
= buffer_size_const
.Value
;
5756 if (buffer_size
<= 0) {
5757 Report
.Error (1665, Location
, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError ());
5761 int type_size
= Expression
.GetTypeSize (MemberType
);
5763 if (buffer_size
> int.MaxValue
/ type_size
) {
5764 Report
.Error (1664, Location
, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit",
5765 GetSignatureForError (), buffer_size
.ToString (), TypeManager
.CSharpName (MemberType
));
5769 buffer_size
*= type_size
;
5770 EmitFieldSize (buffer_size
);
5772 PredefinedAttributes
.Get
.UnsafeValueType
.EmitAttribute (fixed_buffer_type
);
5777 void EmitFieldSize (int buffer_size
)
5779 CustomAttributeBuilder cab
;
5780 PredefinedAttribute pa
;
5782 pa
= PredefinedAttributes
.Get
.StructLayout
;
5783 if (pa
.Constructor
== null &&
5784 !pa
.ResolveConstructor (Location
, TypeManager
.short_type
))
5787 // TODO: It's not cleared
5789 fi
= new FieldInfo
[] { pa.Type.GetField ("Size") }
;
5791 object[] fi_val
= new object[] { buffer_size }
;
5792 cab
= new CustomAttributeBuilder (pa
.Constructor
,
5793 ctor_args
, fi
, fi_val
);
5794 fixed_buffer_type
.SetCustomAttribute (cab
);
5797 // Don't emit FixedBufferAttribute attribute for private types
5799 if ((ModFlags
& Modifiers
.PRIVATE
) != 0)
5802 pa
= PredefinedAttributes
.Get
.FixedBuffer
;
5803 if (pa
.Constructor
== null &&
5804 !pa
.ResolveConstructor (Location
, TypeManager
.type_type
, TypeManager
.int32_type
))
5807 cab
= new CustomAttributeBuilder (pa
.Constructor
, new object[] { MemberType, buffer_size }
);
5808 FieldBuilder
.SetCustomAttribute (cab
);
5811 protected override bool IsFieldClsCompliant
{
5817 public void SetCharSet (TypeAttributes ta
)
5819 TypeAttributes cta
= fixed_buffer_type
.Attributes
;
5820 if ((cta
& TypeAttributes
.UnicodeClass
) != (ta
& TypeAttributes
.UnicodeClass
))
5821 SetTypeBuilderCharSet ((cta
& ~TypeAttributes
.AutoClass
) | TypeAttributes
.UnicodeClass
);
5822 else if ((cta
& TypeAttributes
.AutoClass
) != (ta
& TypeAttributes
.AutoClass
))
5823 SetTypeBuilderCharSet ((cta
& ~TypeAttributes
.UnicodeClass
) | TypeAttributes
.AutoClass
);
5824 else if (cta
== 0 && ta
!= 0)
5825 SetTypeBuilderCharSet (cta
& ~
(TypeAttributes
.UnicodeClass
| TypeAttributes
.AutoClass
));
5828 void SetTypeBuilderCharSet (TypeAttributes ta
)
5830 MethodInfo mi
= typeof (TypeBuilder
).GetMethod ("SetCharSet", BindingFlags
.Instance
| BindingFlags
.NonPublic
);
5832 Report
.RuntimeMissingSupport (Location
, "TypeBuilder::SetCharSet");
5834 mi
.Invoke (fixed_buffer_type
, new object [] { ta }
);
5838 #region IFixedField Members
5840 public FieldInfo Element
{
5846 public Type ElementType
{
5856 // The Field class is used to represents class/struct fields during parsing.
5858 public class Field
: FieldBase
{
5860 // Modifiers allowed in a class declaration
5862 const int AllowedModifiers
=
5865 Modifiers
.PROTECTED
|
5866 Modifiers
.INTERNAL
|
5869 Modifiers
.VOLATILE
|
5873 public Field (DeclSpace parent
, FullNamedExpression type
, int mod
, MemberName name
,
5875 : base (parent
, type
, mod
, AllowedModifiers
, name
, attrs
)
5879 bool CanBeVolatile ()
5881 if (TypeManager
.IsReferenceType (MemberType
))
5884 if (MemberType
== TypeManager
.bool_type
|| MemberType
== TypeManager
.char_type
||
5885 MemberType
== TypeManager
.sbyte_type
|| MemberType
== TypeManager
.byte_type
||
5886 MemberType
== TypeManager
.short_type
|| MemberType
== TypeManager
.ushort_type
||
5887 MemberType
== TypeManager
.int32_type
|| MemberType
== TypeManager
.uint32_type
||
5888 MemberType
== TypeManager
.float_type
||
5889 MemberType
== TypeManager
.intptr_type
|| MemberType
== TypeManager
.uintptr_type
)
5892 if (TypeManager
.IsEnumType (MemberType
))
5898 bool CheckStructLayout (Type type
, bool isStatic
)
5900 if (TypeManager
.IsBuiltinType (type
))
5904 if (!TypeManager
.IsValueType (type
) || TypeManager
.IsEqual (type
, Parent
.TypeBuilder
))
5908 if (!TypeManager
.IsEqual (TypeManager
.DropGenericTypeArguments (type
), Parent
.TypeBuilder
)) {
5909 if (!TypeManager
.IsGenericType (type
))
5912 foreach (Type t
in TypeManager
.GetTypeArguments (type
)) {
5913 if (!CheckStructLayout (t
, false))
5919 Report
.Error (523, Location
,
5920 "Struct member `{0}' of type `{1}' causes a cycle in the struct layout",
5921 GetSignatureForError (), TypeManager
.CSharpName (MemberType
));
5925 public override bool Define ()
5927 if (!base.Define ())
5931 Type
[] required_modifier
= null;
5932 if ((ModFlags
& Modifiers
.VOLATILE
) != 0) {
5933 if (TypeManager
.isvolatile_type
== null)
5934 TypeManager
.isvolatile_type
= TypeManager
.CoreLookupType (Compiler
,
5935 "System.Runtime.CompilerServices", "IsVolatile", Kind
.Class
, true);
5937 if (TypeManager
.isvolatile_type
!= null)
5938 required_modifier
= new Type
[] { TypeManager.isvolatile_type }
;
5941 FieldBuilder
= Parent
.TypeBuilder
.DefineField (
5942 Name
, MemberType
, required_modifier
, null, Modifiers
.FieldAttr (ModFlags
));
5944 // Don't cache inaccessible fields
5945 if ((ModFlags
& Modifiers
.BACKING_FIELD
) == 0) {
5946 Parent
.MemberCache
.AddMember (FieldBuilder
, this);
5949 TypeManager
.RegisterFieldBase (FieldBuilder
, this);
5951 catch (ArgumentException
) {
5952 Report
.RuntimeMissingSupport (Location
, "`void' or `void*' field type");
5956 if (initializer
!= null) {
5957 ((TypeContainer
) Parent
).RegisterFieldForInitialization (this,
5958 new FieldInitializer (FieldBuilder
, initializer
, this));
5960 if (Parent
.PartialContainer
.Kind
== Kind
.Struct
)
5961 CheckStructLayout (member_type
, (ModFlags
& Modifiers
.STATIC
) != 0);
5967 protected override void DoMemberTypeDependentChecks ()
5969 base.DoMemberTypeDependentChecks ();
5971 if ((ModFlags
& Modifiers
.VOLATILE
) != 0) {
5972 if (!CanBeVolatile ()) {
5973 Report
.Error (677, Location
, "`{0}': A volatile field cannot be of the type `{1}'",
5974 GetSignatureForError (), TypeManager
.CSharpName (MemberType
));
5977 if ((ModFlags
& Modifiers
.READONLY
) != 0) {
5978 Report
.Error (678, Location
, "`{0}': A field cannot be both volatile and readonly",
5979 GetSignatureForError ());
5984 protected override bool VerifyClsCompliance ()
5986 if (!base.VerifyClsCompliance ())
5989 if ((ModFlags
& Modifiers
.VOLATILE
) != 0) {
5990 Report
.Warning (3026, 1, Location
, "CLS-compliant field `{0}' cannot be volatile", GetSignatureForError ());
5998 // `set' and `get' accessors are represented with an Accessor.
6000 public class Accessor
{
6002 // Null if the accessor is empty, or a Block if not
6004 public const int AllowedModifiers
=
6006 Modifiers
.PROTECTED
|
6007 Modifiers
.INTERNAL
|
6010 public ToplevelBlock Block
;
6011 public Attributes Attributes
;
6012 public Location Location
;
6013 public int ModFlags
;
6014 public ParametersCompiled Parameters
;
6016 public Accessor (ToplevelBlock b
, int mod
, Attributes attrs
, ParametersCompiled p
, Location loc
)
6022 ModFlags
= Modifiers
.Check (AllowedModifiers
, mod
, 0, loc
, RootContext
.ToplevelTypes
.Compiler
.Report
);
6026 // Ooouh Martin, templates are missing here.
6027 // When it will be possible move here a lot of child code and template method type.
6028 public abstract class AbstractPropertyEventMethod
: MemberCore
, IMethodData
{
6029 protected MethodData method_data
;
6030 protected ToplevelBlock block
;
6031 protected ListDictionary declarative_security
;
6033 // The accessor are created even if they are not wanted.
6034 // But we need them because their names are reserved.
6035 // Field says whether accessor will be emited or not
6036 public readonly bool IsDummy
;
6038 protected readonly string prefix
;
6040 ReturnParameter return_attributes
;
6042 public AbstractPropertyEventMethod (PropertyBasedMember member
, string prefix
)
6043 : base (member
.Parent
, SetupName (prefix
, member
, member
.Location
), null)
6045 this.prefix
= prefix
;
6049 public AbstractPropertyEventMethod (InterfaceMemberBase member
, Accessor accessor
,
6051 : base (member
.Parent
, SetupName (prefix
, member
, accessor
.Location
),
6052 accessor
.Attributes
)
6054 this.prefix
= prefix
;
6055 this.block
= accessor
.Block
;
6058 static MemberName
SetupName (string prefix
, InterfaceMemberBase member
, Location loc
)
6060 return new MemberName (member
.MemberName
.Left
, prefix
+ member
.ShortName
, loc
);
6063 public void UpdateName (InterfaceMemberBase member
)
6065 SetMemberName (SetupName (prefix
, member
, Location
));
6068 #region IMethodData Members
6070 public ToplevelBlock Block
{
6080 public CallingConventions CallingConventions
{
6082 return CallingConventions
.Standard
;
6086 public EmitContext
CreateEmitContext (ILGenerator ig
)
6088 return new EmitContext (this, ig
, ReturnType
);
6091 public bool IsExcluded ()
6096 GenericMethod IMethodData
.GenericMethod
{
6102 public MemberName MethodName
{
6108 public Type
[] ParameterTypes
{
6110 return ParameterInfo
.Types
;
6114 public abstract ParametersCompiled ParameterInfo { get ; }
6115 public abstract Type ReturnType { get; }
6119 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
6121 if (a
.Type
== pa
.CLSCompliant
|| a
.Type
== pa
.Obsolete
|| a
.Type
== pa
.Conditional
) {
6122 Report
.Error (1667, a
.Location
,
6123 "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
6124 TypeManager
.CSharpName (a
.Type
), a
.GetValidTargets ());
6128 if (a
.IsValidSecurityAttribute ()) {
6129 if (declarative_security
== null)
6130 declarative_security
= new ListDictionary ();
6131 a
.ExtractSecurityPermissionSet (declarative_security
);
6135 if (a
.Target
== AttributeTargets
.Method
) {
6136 method_data
.MethodBuilder
.SetCustomAttribute (cb
);
6140 if (a
.Target
== AttributeTargets
.ReturnValue
) {
6141 if (return_attributes
== null)
6142 return_attributes
= new ReturnParameter (method_data
.MethodBuilder
, Location
);
6144 return_attributes
.ApplyAttributeBuilder (a
, cb
, pa
);
6148 ApplyToExtraTarget (a
, cb
, pa
);
6151 protected virtual void ApplyToExtraTarget (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
6153 throw new NotSupportedException ("You forgot to define special attribute target handling");
6156 // It is not supported for the accessors
6157 public sealed override bool Define()
6159 throw new NotSupportedException ();
6162 public virtual void Emit (DeclSpace parent
)
6164 method_data
.Emit (parent
);
6166 if ((ModFlags
& Modifiers
.COMPILER_GENERATED
) != 0 && !Parent
.IsCompilerGenerated
)
6167 PredefinedAttributes
.Get
.CompilerGenerated
.EmitAttribute (method_data
.MethodBuilder
);
6168 if (((ModFlags
& Modifiers
.DEBUGGER_HIDDEN
) != 0))
6169 PredefinedAttributes
.Get
.DebuggerHidden
.EmitAttribute (method_data
.MethodBuilder
);
6171 if (TypeManager
.IsDynamicType (ReturnType
)) {
6172 return_attributes
= new ReturnParameter (method_data
.MethodBuilder
, Location
);
6173 PredefinedAttributes
.Get
.Dynamic
.EmitAttribute (return_attributes
.Builder
);
6176 if (OptAttributes
!= null)
6177 OptAttributes
.Emit ();
6179 if (declarative_security
!= null) {
6180 foreach (DictionaryEntry de
in declarative_security
) {
6181 method_data
.MethodBuilder
.AddDeclarativeSecurity ((SecurityAction
)de
.Key
, (PermissionSet
)de
.Value
);
6188 public override bool EnableOverloadChecks (MemberCore overload
)
6190 // This can only happen with indexers and it will
6191 // be catched as indexer difference
6192 if (overload
is AbstractPropertyEventMethod
)
6195 if (overload
is MethodCore
) {
6196 caching_flags
|= Flags
.MethodOverloadsExist
;
6202 public override bool IsClsComplianceRequired()
6207 public bool IsDuplicateImplementation (MethodCore method
)
6209 if (!MemberName
.Equals (method
.MemberName
))
6212 Type
[] param_types
= method
.ParameterTypes
;
6214 if (param_types
== null || param_types
.Length
!= ParameterTypes
.Length
)
6217 for (int i
= 0; i
< param_types
.Length
; i
++)
6218 if (param_types
[i
] != ParameterTypes
[i
])
6221 Report
.SymbolRelatedToPreviousError (method
);
6222 Report
.Error (82, Location
, "A member `{0}' is already reserved",
6223 method
.GetSignatureForError ());
6227 public override bool IsUsed
6238 // Represents header string for documentation comment.
6240 public override string DocCommentHeader
{
6241 get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
6244 void IMethodData
.EmitExtraSymbolInfo (SourceMethod source
)
6249 // Properties and Indexers both generate PropertyBuilders, we use this to share
6250 // their common bits.
6252 abstract public class PropertyBase
: PropertyBasedMember
{
6254 public class GetMethod
: PropertyMethod
6256 static string[] attribute_targets
= new string [] { "method", "return" }
;
6258 public GetMethod (PropertyBase method
):
6259 base (method
, "get_")
6263 public GetMethod (PropertyBase method
, Accessor accessor
):
6264 base (method
, accessor
, "get_")
6268 public override MethodBuilder
Define (DeclSpace parent
)
6270 base.Define (parent
);
6275 method_data
= new MethodData (method
, ModFlags
, flags
, this);
6277 if (!method_data
.Define (parent
, method
.GetFullName (MemberName
), Report
))
6280 return method_data
.MethodBuilder
;
6283 public override Type ReturnType
{
6285 return method
.MemberType
;
6289 public override ParametersCompiled ParameterInfo
{
6291 return ParametersCompiled
.EmptyReadOnlyParameters
;
6295 public override string[] ValidAttributeTargets
{
6297 return attribute_targets
;
6302 public class SetMethod
: PropertyMethod
{
6304 static string[] attribute_targets
= new string [] { "method", "param", "return" }
;
6305 ImplicitParameter param_attr
;
6306 protected ParametersCompiled parameters
;
6308 public SetMethod (PropertyBase method
) :
6309 base (method
, "set_")
6311 parameters
= new ParametersCompiled (
6312 new Parameter (method
.type_name
, "value", Parameter
.Modifier
.NONE
, null, Location
));
6315 public SetMethod (PropertyBase method
, Accessor accessor
):
6316 base (method
, accessor
, "set_")
6318 this.parameters
= accessor
.Parameters
;
6321 protected override void ApplyToExtraTarget (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
6323 if (a
.Target
== AttributeTargets
.Parameter
) {
6324 if (param_attr
== null)
6325 param_attr
= new ImplicitParameter (method_data
.MethodBuilder
);
6327 param_attr
.ApplyAttributeBuilder (a
, cb
, pa
);
6331 base.ApplyAttributeBuilder (a
, cb
, pa
);
6334 public override ParametersCompiled ParameterInfo
{
6340 public override MethodBuilder
Define (DeclSpace parent
)
6342 parameters
.Resolve (this);
6344 base.Define (parent
);
6349 method_data
= new MethodData (method
, ModFlags
, flags
, this);
6351 if (!method_data
.Define (parent
, method
.GetFullName (MemberName
), Report
))
6354 return method_data
.MethodBuilder
;
6357 public override Type ReturnType
{
6359 return TypeManager
.void_type
;
6363 public override string[] ValidAttributeTargets
{
6365 return attribute_targets
;
6370 static string[] attribute_targets
= new string [] { "property" }
;
6372 public abstract class PropertyMethod
: AbstractPropertyEventMethod
6374 protected readonly PropertyBase method
;
6375 protected MethodAttributes flags
;
6377 public PropertyMethod (PropertyBase method
, string prefix
)
6378 : base (method
, prefix
)
6380 this.method
= method
;
6381 this.ModFlags
= method
.ModFlags
& (Modifiers
.STATIC
| Modifiers
.UNSAFE
);
6384 public PropertyMethod (PropertyBase method
, Accessor accessor
,
6386 : base (method
, accessor
, prefix
)
6388 this.method
= method
;
6389 this.ModFlags
= accessor
.ModFlags
| (method
.ModFlags
& (Modifiers
.STATIC
| Modifiers
.UNSAFE
));
6391 if (accessor
.ModFlags
!= 0 && RootContext
.Version
== LanguageVersion
.ISO_1
) {
6392 Report
.FeatureIsNotAvailable (Location
, "access modifiers on properties");
6396 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
6398 if (a
.IsInternalMethodImplAttribute
) {
6399 method
.is_external_implementation
= true;
6402 base.ApplyAttributeBuilder (a
, cb
, pa
);
6405 public override AttributeTargets AttributeTargets
{
6407 return AttributeTargets
.Method
;
6411 public override bool IsClsComplianceRequired ()
6413 return method
.IsClsComplianceRequired ();
6416 public virtual MethodBuilder
Define (DeclSpace parent
)
6418 CheckForDuplications ();
6421 if (method
.InterfaceType
!= null && parent
.PartialContainer
.PendingImplementations
!= null) {
6422 MethodInfo mi
= parent
.PartialContainer
.PendingImplementations
.IsInterfaceMethod (
6423 MethodName
.Name
, method
.InterfaceType
, new MethodData (method
, ModFlags
, flags
, this));
6425 Report
.SymbolRelatedToPreviousError (mi
);
6426 Report
.Error (551, Location
, "Explicit interface implementation `{0}' is missing accessor `{1}'",
6427 method
.GetSignatureForError (), TypeManager
.CSharpSignature (mi
, true));
6433 TypeContainer container
= parent
.PartialContainer
;
6436 // Check for custom access modifier
6438 if ((ModFlags
& Modifiers
.Accessibility
) == 0) {
6439 ModFlags
|= method
.ModFlags
;
6440 flags
= method
.flags
;
6442 if (container
.Kind
== Kind
.Interface
)
6443 Report
.Error (275, Location
, "`{0}': accessibility modifiers may not be used on accessors in an interface",
6444 GetSignatureForError ());
6446 if ((method
.ModFlags
& Modifiers
.ABSTRACT
) != 0 && (ModFlags
& Modifiers
.PRIVATE
) != 0) {
6447 Report
.Error (442, Location
, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
6450 CheckModifiers (ModFlags
);
6451 ModFlags
|= (method
.ModFlags
& (~Modifiers
.Accessibility
));
6452 ModFlags
|= Modifiers
.PROPERTY_CUSTOM
;
6453 flags
= Modifiers
.MethodAttr (ModFlags
);
6454 flags
|= (method
.flags
& (~MethodAttributes
.MemberAccessMask
));
6457 CheckAbstractAndExtern (block
!= null);
6458 CheckProtectedModifier ();
6460 if (block
!= null && block
.IsIterator
)
6461 Iterator
.CreateIterator (this, Parent
.PartialContainer
, ModFlags
, Compiler
);
6466 public bool HasCustomAccessModifier
{
6468 return (ModFlags
& Modifiers
.PROPERTY_CUSTOM
) != 0;
6472 public PropertyBase Property
{
6478 public override ObsoleteAttribute
GetObsoleteAttribute ()
6480 return method
.GetObsoleteAttribute ();
6483 public override string GetSignatureForError()
6485 return method
.GetSignatureForError () + '.' + prefix
.Substring (0, 3);
6488 void CheckModifiers (int modflags
)
6490 modflags
&= Modifiers
.Accessibility
;
6492 int mflags
= method
.ModFlags
& Modifiers
.Accessibility
;
6494 if ((mflags
& Modifiers
.PUBLIC
) != 0) {
6495 flags
|= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
| Modifiers
.PRIVATE
;
6497 else if ((mflags
& Modifiers
.PROTECTED
) != 0) {
6498 if ((mflags
& Modifiers
.INTERNAL
) != 0)
6499 flags
|= Modifiers
.PROTECTED
| Modifiers
.INTERNAL
;
6501 flags
|= Modifiers
.PRIVATE
;
6503 else if ((mflags
& Modifiers
.INTERNAL
) != 0)
6504 flags
|= Modifiers
.PRIVATE
;
6506 if ((mflags
== modflags
) || (modflags
& (~flags
)) != 0) {
6507 Report
.Error (273, Location
,
6508 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
6509 GetSignatureForError (), method
.GetSignatureForError ());
6513 protected bool CheckForDuplications ()
6515 if ((caching_flags
& Flags
.MethodOverloadsExist
) == 0)
6518 return Parent
.MemberCache
.CheckExistingMembersOverloads (this, Name
, ParameterInfo
, Report
);
6522 public PropertyMethod Get
, Set
;
6523 public PropertyBuilder PropertyBuilder
;
6524 public MethodBuilder GetBuilder
, SetBuilder
;
6526 protected bool define_set_first
= false;
6528 public PropertyBase (DeclSpace parent
, FullNamedExpression type
, int mod_flags
,
6529 int allowed_mod
, MemberName name
,
6530 Attributes attrs
, bool define_set_first
)
6531 : base (parent
, null, type
, mod_flags
, allowed_mod
, name
, attrs
)
6533 this.define_set_first
= define_set_first
;
6536 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
6538 if (a
.HasSecurityAttribute
) {
6539 a
.Error_InvalidSecurityParent ();
6543 if (a
.Type
== pa
.Dynamic
) {
6544 a
.Error_MisusedDynamicAttribute ();
6548 PropertyBuilder
.SetCustomAttribute (cb
);
6551 public override AttributeTargets AttributeTargets
{
6553 return AttributeTargets
.Property
;
6557 protected override void DoMemberTypeDependentChecks ()
6559 base.DoMemberTypeDependentChecks ();
6563 if (MemberType
.IsGenericParameter
)
6567 if ((MemberType
.Attributes
& Class
.StaticClassAttribute
) == Class
.StaticClassAttribute
) {
6568 Report
.Error (722, Location
, Error722
, TypeManager
.CSharpName (MemberType
));
6572 protected override void DoMemberTypeIndependentChecks ()
6574 base.DoMemberTypeIndependentChecks ();
6577 // Accessors modifiers check
6579 if ((Get
.ModFlags
& Modifiers
.Accessibility
) != 0 &&
6580 (Set
.ModFlags
& Modifiers
.Accessibility
) != 0) {
6581 Report
.Error (274, Location
, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
6582 GetSignatureForError ());
6585 if ((ModFlags
& Modifiers
.OVERRIDE
) == 0 &&
6586 (Get
.IsDummy
&& (Set
.ModFlags
& Modifiers
.Accessibility
) != 0) ||
6587 (Set
.IsDummy
&& (Get
.ModFlags
& Modifiers
.Accessibility
) != 0)) {
6588 Report
.Error (276, Location
,
6589 "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
6590 GetSignatureForError ());
6596 GetBuilder
= Get
.Define (Parent
);
6597 return (Get
.IsDummy
) ? true : GetBuilder
!= null;
6600 bool DefineSet (bool define
)
6605 SetBuilder
= Set
.Define (Parent
);
6606 return (Set
.IsDummy
) ? true : SetBuilder
!= null;
6609 protected bool DefineAccessors ()
6611 return DefineSet (define_set_first
) &&
6613 DefineSet (!define_set_first
);
6616 protected abstract PropertyInfo
ResolveBaseProperty ();
6618 // TODO: rename to Resolve......
6619 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
6621 PropertyInfo base_property
= ResolveBaseProperty ();
6622 if (base_property
== null)
6625 base_ret_type
= base_property
.PropertyType
;
6626 MethodInfo get_accessor
= base_property
.GetGetMethod (true);
6627 MethodInfo set_accessor
= base_property
.GetSetMethod (true);
6628 MethodAttributes get_accessor_access
= 0, set_accessor_access
= 0;
6631 // Check base property accessors conflict
6633 if ((ModFlags
& (Modifiers
.OVERRIDE
| Modifiers
.NEW
)) == Modifiers
.OVERRIDE
) {
6634 if (get_accessor
== null) {
6635 if (Get
!= null && !Get
.IsDummy
) {
6636 Report
.SymbolRelatedToPreviousError (base_property
);
6637 Report
.Error (545, Location
,
6638 "`{0}.get': cannot override because `{1}' does not have an overridable get accessor",
6639 GetSignatureForError (), TypeManager
.GetFullNameSignature (base_property
));
6642 get_accessor_access
= get_accessor
.Attributes
& MethodAttributes
.MemberAccessMask
;
6644 if (!Get
.IsDummy
&& !CheckAccessModifiers (
6645 Modifiers
.MethodAttr (Get
.ModFlags
) & MethodAttributes
.MemberAccessMask
, get_accessor_access
, get_accessor
))
6646 Error_CannotChangeAccessModifiers (Get
.Location
, get_accessor
, get_accessor_access
, ".get");
6649 if (set_accessor
== null) {
6650 if (Set
!= null && !Set
.IsDummy
) {
6651 Report
.SymbolRelatedToPreviousError (base_property
);
6652 Report
.Error (546, Location
,
6653 "`{0}.set': cannot override because `{1}' does not have an overridable set accessor",
6654 GetSignatureForError (), TypeManager
.GetFullNameSignature (base_property
));
6657 set_accessor_access
= set_accessor
.Attributes
& MethodAttributes
.MemberAccessMask
;
6659 if (!Set
.IsDummy
&& !CheckAccessModifiers (
6660 Modifiers
.MethodAttr (Set
.ModFlags
) & MethodAttributes
.MemberAccessMask
, set_accessor_access
, set_accessor
))
6661 Error_CannotChangeAccessModifiers (Set
.Location
, set_accessor
, set_accessor_access
, ".set");
6665 // When one accessor does not exist and property hides base one
6666 // we need to propagate this upwards
6667 if (set_accessor
== null)
6668 set_accessor
= get_accessor
;
6671 // Get the less restrictive access
6673 return get_accessor_access
> set_accessor_access
? get_accessor
: set_accessor
;
6676 public override void Emit ()
6679 // The PropertyBuilder can be null for explicit implementations, in that
6680 // case, we do not actually emit the ".property", so there is nowhere to
6681 // put the attribute
6683 if (PropertyBuilder
!= null) {
6684 if (OptAttributes
!= null)
6685 OptAttributes
.Emit ();
6687 if (TypeManager
.IsDynamicType (member_type
))
6688 PredefinedAttributes
.Get
.Dynamic
.EmitAttribute (PropertyBuilder
);
6701 /// Tests whether accessors are not in collision with some method (CS0111)
6703 public bool AreAccessorsDuplicateImplementation (MethodCore mc
)
6705 return Get
.IsDuplicateImplementation (mc
) || Set
.IsDuplicateImplementation (mc
);
6708 public override bool IsUsed
6714 return Get
.IsUsed
| Set
.IsUsed
;
6718 protected override void SetMemberName (MemberName new_name
)
6720 base.SetMemberName (new_name
);
6722 Get
.UpdateName (this);
6723 Set
.UpdateName (this);
6726 public override string[] ValidAttributeTargets
{
6728 return attribute_targets
;
6733 // Represents header string for documentation comment.
6735 public override string DocCommentHeader
{
6736 get { return "P:"; }
6740 public class Property
: PropertyBase
6742 public sealed class BackingField
: Field
6744 readonly Property property
;
6746 public BackingField (Property p
)
6747 : base (p
.Parent
, p
.type_name
,
6748 Modifiers
.BACKING_FIELD
| Modifiers
.COMPILER_GENERATED
| Modifiers
.PRIVATE
| (p
.ModFlags
& (Modifiers
.STATIC
| Modifiers
.UNSAFE
)),
6749 new MemberName ("<" + p
.GetFullName (p
.MemberName
) + ">k__BackingField", p
.Location
), null)
6754 public override string GetSignatureForError ()
6756 return property
.GetSignatureForError ();
6760 const int AllowedModifiers
=
6763 Modifiers
.PROTECTED
|
6764 Modifiers
.INTERNAL
|
6768 Modifiers
.OVERRIDE
|
6769 Modifiers
.ABSTRACT
|
6774 const int AllowedInterfaceModifiers
=
6777 public Property (DeclSpace parent
, FullNamedExpression type
, int mod
,
6778 MemberName name
, Attributes attrs
, Accessor get_block
,
6779 Accessor set_block
, bool define_set_first
)
6780 : this (parent
, type
, mod
, name
, attrs
, get_block
, set_block
,
6781 define_set_first
, null)
6785 public Property (DeclSpace parent
, FullNamedExpression type
, int mod
,
6786 MemberName name
, Attributes attrs
, Accessor get_block
,
6787 Accessor set_block
, bool define_set_first
, Block current_block
)
6788 : base (parent
, type
, mod
,
6789 parent
.PartialContainer
.Kind
== Kind
.Interface
? AllowedInterfaceModifiers
: AllowedModifiers
,
6790 name
, attrs
, define_set_first
)
6792 if (get_block
== null)
6793 Get
= new GetMethod (this);
6795 Get
= new GetMethod (this, get_block
);
6797 if (set_block
== null)
6798 Set
= new SetMethod (this);
6800 Set
= new SetMethod (this, set_block
);
6802 if (!IsInterface
&& (mod
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) == 0 &&
6803 get_block
!= null && get_block
.Block
== null &&
6804 set_block
!= null && set_block
.Block
== null) {
6805 if (RootContext
.Version
<= LanguageVersion
.ISO_2
)
6806 Report
.FeatureIsNotAvailable (Location
, "automatically implemented properties");
6808 Get
.ModFlags
|= Modifiers
.COMPILER_GENERATED
;
6809 Set
.ModFlags
|= Modifiers
.COMPILER_GENERATED
;
6813 void CreateAutomaticProperty ()
6815 // Create backing field
6816 Field field
= new BackingField (this);
6817 if (!field
.Define ())
6820 Parent
.PartialContainer
.AddField (field
);
6822 FieldExpr fe
= new FieldExpr (field
.FieldBuilder
, Location
);
6823 if ((field
.ModFlags
& Modifiers
.STATIC
) == 0)
6824 fe
.InstanceExpression
= new CompilerGeneratedThis (fe
.Type
, Location
);
6827 Get
.Block
= new ToplevelBlock (Compiler
, ParametersCompiled
.EmptyReadOnlyParameters
, Location
);
6828 Return r
= new Return (fe
, Location
);
6829 Get
.Block
.AddStatement (r
);
6832 Set
.Block
= new ToplevelBlock (Compiler
, Set
.ParameterInfo
, Location
);
6833 Assign a
= new SimpleAssign (fe
, new SimpleName ("value", Location
));
6834 Set
.Block
.AddStatement (new StatementExpression (a
));
6837 public override bool Define ()
6839 if (!base.Define ())
6842 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
6844 if ((Get
.ModFlags
& Modifiers
.COMPILER_GENERATED
) != 0)
6845 CreateAutomaticProperty ();
6847 if (!DefineAccessors ())
6853 // FIXME - PropertyAttributes.HasDefault ?
6855 PropertyBuilder
= Parent
.TypeBuilder
.DefineProperty (
6856 GetFullName (MemberName
), PropertyAttributes
.None
, MemberType
, null);
6859 PropertyBuilder
.SetGetMethod (GetBuilder
);
6860 Parent
.MemberCache
.AddMember (GetBuilder
, Get
);
6864 PropertyBuilder
.SetSetMethod (SetBuilder
);
6865 Parent
.MemberCache
.AddMember (SetBuilder
, Set
);
6868 TypeManager
.RegisterProperty (PropertyBuilder
, this);
6869 Parent
.MemberCache
.AddMember (PropertyBuilder
, this);
6873 public override void Emit ()
6875 if (((Set
.ModFlags
| Get
.ModFlags
) & (Modifiers
.STATIC
| Modifiers
.COMPILER_GENERATED
)) == Modifiers
.COMPILER_GENERATED
&& Parent
.PartialContainer
.HasExplicitLayout
) {
6876 Report
.Error (842, Location
,
6877 "Automatically implemented property `{0}' cannot be used inside a type with an explicit StructLayout attribute",
6878 GetSignatureForError ());
6884 protected override PropertyInfo
ResolveBaseProperty ()
6886 return Parent
.PartialContainer
.BaseCache
.FindMemberToOverride (
6887 Parent
.TypeBuilder
, Name
, ParametersCompiled
.EmptyReadOnlyParameters
, null, true) as PropertyInfo
;
6892 /// Gigantic workaround for lameness in SRE follows :
6893 /// This class derives from EventInfo and attempts to basically
6894 /// wrap around the EventBuilder so that FindMembers can quickly
6895 /// return this in it search for members
6897 public class MyEventBuilder
: EventInfo
{
6900 // We use this to "point" to our Builder which is
6901 // not really a MemberInfo
6903 EventBuilder MyBuilder
;
6906 // We "catch" and wrap these methods
6908 MethodInfo raise
, remove, add;
6910 EventAttributes attributes
;
6911 Type declaring_type
, reflected_type
, event_type
;
6916 public MyEventBuilder (Event ev
, TypeBuilder type_builder
, string name
, EventAttributes event_attr
, Type event_type
)
6918 MyBuilder
= type_builder
.DefineEvent (name
, event_attr
, event_type
);
6920 // And now store the values in our own fields.
6922 declaring_type
= type_builder
;
6924 reflected_type
= type_builder
;
6926 attributes
= event_attr
;
6929 this.event_type
= event_type
;
6933 // Methods that you have to override. Note that you only need
6934 // to "implement" the variants that take the argument (those are
6935 // the "abstract" methods, the others (GetAddMethod()) are
6938 public override MethodInfo
GetAddMethod (bool nonPublic
)
6943 public override MethodInfo
GetRemoveMethod (bool nonPublic
)
6948 public override MethodInfo
GetRaiseMethod (bool nonPublic
)
6954 // These methods make "MyEventInfo" look like a Builder
6956 public void SetRaiseMethod (MethodBuilder raiseMethod
)
6958 raise
= raiseMethod
;
6959 MyBuilder
.SetRaiseMethod (raiseMethod
);
6962 public void SetRemoveOnMethod (MethodBuilder removeMethod
)
6964 remove = removeMethod
;
6965 MyBuilder
.SetRemoveOnMethod (removeMethod
);
6968 public void SetAddOnMethod (MethodBuilder addMethod
)
6971 MyBuilder
.SetAddOnMethod (addMethod
);
6974 public void SetCustomAttribute (CustomAttributeBuilder cb
)
6976 MyBuilder
.SetCustomAttribute (cb
);
6979 public override object [] GetCustomAttributes (bool inherit
)
6981 // FIXME : There's nothing which can be seemingly done here because
6982 // we have no way of getting at the custom attribute objects of the
6987 public override object [] GetCustomAttributes (Type t
, bool inherit
)
6989 // FIXME : Same here !
6993 public override bool IsDefined (Type t
, bool b
)
6998 public override EventAttributes Attributes
{
7004 public override string Name
{
7010 public override Type DeclaringType
{
7012 return declaring_type
;
7016 public override Type ReflectedType
{
7018 return reflected_type
;
7022 public Type EventType
{
7028 public void SetUsed ()
7030 if (my_event
!= null) {
7031 // my_event.SetAssigned ();
7032 my_event
.SetMemberIsUsed ();
7038 /// For case when event is declared like property (with add and remove accessors).
7040 public class EventProperty
: Event
{
7041 abstract class AEventPropertyAccessor
: AEventAccessor
7043 protected AEventPropertyAccessor (Event method
, Accessor accessor
, string prefix
):
7044 base (method
, accessor
, prefix
)
7048 public override MethodBuilder
Define (DeclSpace ds
)
7050 CheckAbstractAndExtern (block
!= null);
7051 return base.Define (ds
);
7054 public override string GetSignatureForError ()
7056 return method
.GetSignatureForError () + "." + prefix
.Substring (0, prefix
.Length
- 1);
7060 sealed class AddDelegateMethod
: AEventPropertyAccessor
7062 public AddDelegateMethod (Event method
, Accessor accessor
):
7063 base (method
, accessor
, AddPrefix
)
7068 sealed class RemoveDelegateMethod
: AEventPropertyAccessor
7070 public RemoveDelegateMethod (Event method
, Accessor accessor
):
7071 base (method
, accessor
, RemovePrefix
)
7077 static readonly string[] attribute_targets
= new string [] { "event" }
; // "property" target was disabled for 2.0 version
7079 public EventProperty (DeclSpace parent
, FullNamedExpression type
, int mod_flags
,
7081 Attributes attrs
, Accessor
add, Accessor
remove)
7082 : base (parent
, type
, mod_flags
, name
, attrs
)
7084 Add
= new AddDelegateMethod (this, add);
7085 Remove
= new RemoveDelegateMethod (this, remove);
7088 public override bool Define()
7090 if (!base.Define ())
7097 public override string[] ValidAttributeTargets
{
7099 return attribute_targets
;
7105 /// Event is declared like field.
7107 public class EventField
: Event
{
7108 abstract class EventFieldAccessor
: AEventAccessor
7110 protected EventFieldAccessor (Event method
, string prefix
)
7111 : base (method
, prefix
)
7115 public override void Emit (DeclSpace parent
)
7117 if ((method
.ModFlags
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) == 0) {
7118 if (parent
is Class
) {
7119 MethodBuilder mb
= method_data
.MethodBuilder
;
7120 mb
.SetImplementationFlags (mb
.GetMethodImplementationFlags () | MethodImplAttributes
.Synchronized
);
7123 // TODO: because we cannot use generics yet
7124 FieldInfo field_info
= ((EventField
) method
).BackingField
.FieldBuilder
;
7125 FieldExpr f_expr
= new FieldExpr (field_info
, Location
);
7126 if ((method
.ModFlags
& Modifiers
.STATIC
) == 0)
7127 f_expr
.InstanceExpression
= new CompilerGeneratedThis (field_info
.FieldType
, Location
);
7129 block
= new ToplevelBlock (Compiler
, ParameterInfo
, Location
);
7130 block
.AddStatement (new StatementExpression (
7131 new CompoundAssign (Operation
,
7133 block
.GetParameterReference (ParameterInfo
[0].Name
, Location
))));
7139 protected abstract Binary
.Operator Operation { get; }
7142 sealed class AddDelegateMethod
: EventFieldAccessor
7144 public AddDelegateMethod (Event method
):
7145 base (method
, AddPrefix
)
7149 protected override Binary
.Operator Operation
{
7150 get { return Binary.Operator.Addition; }
7154 sealed class RemoveDelegateMethod
: EventFieldAccessor
7156 public RemoveDelegateMethod (Event method
):
7157 base (method
, RemovePrefix
)
7161 protected override Binary
.Operator Operation
{
7162 get { return Binary.Operator.Subtraction; }
7167 static readonly string[] attribute_targets
= new string [] { "event", "field", "method" }
;
7168 static readonly string[] attribute_targets_interface
= new string[] { "event", "method" }
;
7170 public Field BackingField
;
7171 public Expression Initializer
;
7173 public EventField (DeclSpace parent
, FullNamedExpression type
, int mod_flags
, MemberName name
, Attributes attrs
)
7174 : base (parent
, type
, mod_flags
, name
, attrs
)
7176 Add
= new AddDelegateMethod (this);
7177 Remove
= new RemoveDelegateMethod (this);
7180 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
7182 if (a
.Target
== AttributeTargets
.Field
) {
7183 BackingField
.ApplyAttributeBuilder (a
, cb
, pa
);
7187 if (a
.Target
== AttributeTargets
.Method
) {
7188 int errors
= Report
.Errors
;
7189 Add
.ApplyAttributeBuilder (a
, cb
, pa
);
7190 if (errors
== Report
.Errors
)
7191 Remove
.ApplyAttributeBuilder (a
, cb
, pa
);
7195 base.ApplyAttributeBuilder (a
, cb
, pa
);
7198 public override bool Define()
7200 if (!base.Define ())
7203 if (Initializer
!= null && (ModFlags
& Modifiers
.ABSTRACT
) != 0) {
7204 Report
.Error (74, Location
, "`{0}': abstract event cannot have an initializer",
7205 GetSignatureForError ());
7208 if (!HasBackingField
) {
7213 // FIXME: We are unable to detect whether generic event is used because
7214 // we are using FieldExpr instead of EventExpr for event access in that
7215 // case. When this issue will be fixed this hack can be removed.
7216 if (TypeManager
.IsGenericType (MemberType
))
7219 if (Add
.IsInterfaceImplementation
)
7222 TypeManager
.RegisterEventField (EventBuilder
, this);
7224 BackingField
= new Field (Parent
,
7225 new TypeExpression (MemberType
, Location
),
7226 Modifiers
.BACKING_FIELD
| Modifiers
.COMPILER_GENERATED
| Modifiers
.PRIVATE
| (ModFlags
& (Modifiers
.STATIC
| Modifiers
.UNSAFE
)),
7229 Parent
.PartialContainer
.AddField (BackingField
);
7230 BackingField
.Initializer
= Initializer
;
7231 BackingField
.ModFlags
&= ~Modifiers
.COMPILER_GENERATED
;
7233 // Call define because we passed fields definition
7234 return BackingField
.Define ();
7237 bool HasBackingField
{
7239 return !IsInterface
&& (ModFlags
& Modifiers
.ABSTRACT
) == 0;
7243 public override string[] ValidAttributeTargets
7246 return HasBackingField
? attribute_targets
: attribute_targets_interface
;
7251 public abstract class Event
: PropertyBasedMember
{
7252 public abstract class AEventAccessor
: AbstractPropertyEventMethod
7254 protected readonly Event method
;
7255 ImplicitParameter param_attr
;
7257 static readonly string[] attribute_targets
= new string [] { "method", "param", "return" }
;
7259 public const string AddPrefix
= "add_";
7260 public const string RemovePrefix
= "remove_";
7262 protected AEventAccessor (Event method
, string prefix
)
7263 : base (method
, prefix
)
7265 this.method
= method
;
7266 this.ModFlags
= method
.ModFlags
;
7269 protected AEventAccessor (Event method
, Accessor accessor
, string prefix
)
7270 : base (method
, accessor
, prefix
)
7272 this.method
= method
;
7273 this.ModFlags
= method
.ModFlags
;
7276 public bool IsInterfaceImplementation
{
7277 get { return method_data.implementing != null; }
7280 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
7282 if (a
.IsInternalMethodImplAttribute
) {
7283 method
.is_external_implementation
= true;
7286 base.ApplyAttributeBuilder (a
, cb
, pa
);
7289 protected override void ApplyToExtraTarget (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
7291 if (a
.Target
== AttributeTargets
.Parameter
) {
7292 if (param_attr
== null)
7293 param_attr
= new ImplicitParameter (method_data
.MethodBuilder
);
7295 param_attr
.ApplyAttributeBuilder (a
, cb
, pa
);
7299 base.ApplyAttributeBuilder (a
, cb
, pa
);
7302 public override AttributeTargets AttributeTargets
{
7304 return AttributeTargets
.Method
;
7308 public override bool IsClsComplianceRequired ()
7310 return method
.IsClsComplianceRequired ();
7313 public virtual MethodBuilder
Define (DeclSpace parent
)
7315 method_data
= new MethodData (method
, method
.ModFlags
,
7316 method
.flags
| MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
, this);
7318 if (!method_data
.Define (parent
, method
.GetFullName (MemberName
), Report
))
7321 MethodBuilder mb
= method_data
.MethodBuilder
;
7322 ParameterInfo
.ApplyAttributes (mb
);
7326 public override Type ReturnType
{
7328 return TypeManager
.void_type
;
7332 public override ObsoleteAttribute
GetObsoleteAttribute ()
7334 return method
.GetObsoleteAttribute ();
7337 public override string[] ValidAttributeTargets
{
7339 return attribute_targets
;
7343 public override ParametersCompiled ParameterInfo
{
7345 return method
.parameters
;
7351 const int AllowedModifiers
=
7354 Modifiers
.PROTECTED
|
7355 Modifiers
.INTERNAL
|
7360 Modifiers
.OVERRIDE
|
7362 Modifiers
.ABSTRACT
|
7365 const int AllowedInterfaceModifiers
=
7368 public AEventAccessor Add
, Remove
;
7369 public MyEventBuilder EventBuilder
;
7370 public MethodBuilder AddBuilder
, RemoveBuilder
;
7372 ParametersCompiled parameters
;
7374 protected Event (DeclSpace parent
, FullNamedExpression type
, int mod_flags
, MemberName name
, Attributes attrs
)
7375 : base (parent
, null, type
, mod_flags
,
7376 parent
.PartialContainer
.Kind
== Kind
.Interface
? AllowedInterfaceModifiers
: AllowedModifiers
,
7381 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
7383 if ((a
.HasSecurityAttribute
)) {
7384 a
.Error_InvalidSecurityParent ();
7388 EventBuilder
.SetCustomAttribute (cb
);
7391 public bool AreAccessorsDuplicateImplementation (MethodCore mc
)
7393 return Add
.IsDuplicateImplementation (mc
) || Remove
.IsDuplicateImplementation (mc
);
7396 public override AttributeTargets AttributeTargets
{
7398 return AttributeTargets
.Event
;
7402 public override bool Define ()
7404 if (!base.Define ())
7407 if (!TypeManager
.IsDelegateType (MemberType
)) {
7408 Report
.Error (66, Location
, "`{0}': event must be of a delegate type", GetSignatureForError ());
7411 parameters
= ParametersCompiled
.CreateFullyResolved (
7412 new Parameter (null, "value", Parameter
.Modifier
.NONE
, null, Location
), MemberType
);
7417 if (TypeManager
.delegate_combine_delegate_delegate
== null) {
7418 TypeManager
.delegate_combine_delegate_delegate
= TypeManager
.GetPredefinedMethod (
7419 TypeManager
.delegate_type
, "Combine", Location
,
7420 TypeManager
.delegate_type
, TypeManager
.delegate_type
);
7422 if (TypeManager
.delegate_remove_delegate_delegate
== null) {
7423 TypeManager
.delegate_remove_delegate_delegate
= TypeManager
.GetPredefinedMethod (
7424 TypeManager
.delegate_type
, "Remove", Location
,
7425 TypeManager
.delegate_type
, TypeManager
.delegate_type
);
7429 // Now define the accessors
7432 AddBuilder
= Add
.Define (Parent
);
7433 if (AddBuilder
== null)
7436 RemoveBuilder
= Remove
.Define (Parent
);
7437 if (RemoveBuilder
== null)
7440 EventBuilder
= new MyEventBuilder (this, Parent
.TypeBuilder
, Name
, EventAttributes
.None
, MemberType
);
7441 EventBuilder
.SetAddOnMethod (AddBuilder
);
7442 EventBuilder
.SetRemoveOnMethod (RemoveBuilder
);
7444 Parent
.MemberCache
.AddMember (EventBuilder
, this);
7445 Parent
.MemberCache
.AddMember (AddBuilder
, Add
);
7446 Parent
.MemberCache
.AddMember (RemoveBuilder
, Remove
);
7451 public override void Emit ()
7453 if (OptAttributes
!= null) {
7454 OptAttributes
.Emit ();
7458 Remove
.Emit (Parent
);
7463 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
7465 MethodInfo mi
= (MethodInfo
) Parent
.PartialContainer
.BaseCache
.FindBaseEvent (
7466 Parent
.TypeBuilder
, Name
);
7471 AParametersCollection pd
= TypeManager
.GetParameterData (mi
);
7472 base_ret_type
= pd
.Types
[0];
7477 // Represents header string for documentation comment.
7479 public override string DocCommentHeader
{
7480 get { return "E:"; }
7485 public class Indexer
: PropertyBase
7487 public class GetIndexerMethod
: GetMethod
7489 ParametersCompiled parameters
;
7491 public GetIndexerMethod (Indexer method
):
7494 this.parameters
= method
.parameters
;
7497 public GetIndexerMethod (PropertyBase method
, Accessor accessor
):
7498 base (method
, accessor
)
7500 parameters
= accessor
.Parameters
;
7503 public override MethodBuilder
Define (DeclSpace parent
)
7505 parameters
.Resolve (this);
7506 return base.Define (parent
);
7509 public override bool EnableOverloadChecks (MemberCore overload
)
7511 if (base.EnableOverloadChecks (overload
)) {
7512 overload
.caching_flags
|= Flags
.MethodOverloadsExist
;
7519 public override ParametersCompiled ParameterInfo
{
7526 public class SetIndexerMethod
: SetMethod
7528 public SetIndexerMethod (Indexer method
):
7531 parameters
= ParametersCompiled
.MergeGenerated (method
.parameters
, false, parameters
[0], null);
7534 public SetIndexerMethod (PropertyBase method
, Accessor accessor
):
7535 base (method
, accessor
)
7537 parameters
= method
.Get
.IsDummy
? accessor
.Parameters
: accessor
.Parameters
.Clone ();
7540 public override bool EnableOverloadChecks (MemberCore overload
)
7542 if (base.EnableOverloadChecks (overload
)) {
7543 overload
.caching_flags
|= Flags
.MethodOverloadsExist
;
7551 const int AllowedModifiers
=
7554 Modifiers
.PROTECTED
|
7555 Modifiers
.INTERNAL
|
7559 Modifiers
.OVERRIDE
|
7564 const int AllowedInterfaceModifiers
=
7567 public readonly ParametersCompiled parameters
;
7569 public Indexer (DeclSpace parent
, FullNamedExpression type
, MemberName name
, int mod
,
7570 ParametersCompiled parameters
, Attributes attrs
,
7571 Accessor get_block
, Accessor set_block
, bool define_set_first
)
7572 : base (parent
, type
, mod
,
7573 parent
.PartialContainer
.Kind
== Kind
.Interface
? AllowedInterfaceModifiers
: AllowedModifiers
,
7574 name
, attrs
, define_set_first
)
7576 this.parameters
= parameters
;
7578 if (get_block
== null)
7579 Get
= new GetIndexerMethod (this);
7581 Get
= new GetIndexerMethod (this, get_block
);
7583 if (set_block
== null)
7584 Set
= new SetIndexerMethod (this);
7586 Set
= new SetIndexerMethod (this, set_block
);
7589 protected override bool CheckForDuplications ()
7591 return Parent
.MemberCache
.CheckExistingMembersOverloads (this, GetFullName (MemberName
), parameters
, Report
);
7594 public override bool Define ()
7596 if (!base.Define ())
7599 if (!DefineParameters (parameters
))
7602 if (OptAttributes
!= null) {
7603 Attribute indexer_attr
= OptAttributes
.Search (PredefinedAttributes
.Get
.IndexerName
);
7604 if (indexer_attr
!= null) {
7605 // Remove the attribute from the list because it is not emitted
7606 OptAttributes
.Attrs
.Remove (indexer_attr
);
7608 string name
= indexer_attr
.GetIndexerAttributeValue ();
7614 if (IsExplicitImpl
) {
7615 Report
.Error (415, indexer_attr
.Location
,
7616 "The `IndexerName' attribute is valid only on an " +
7617 "indexer that is not an explicit interface member declaration");
7621 if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
7622 Report
.Error (609, indexer_attr
.Location
,
7623 "Cannot set the `IndexerName' attribute on an indexer marked override");
7629 if (InterfaceType
!= null) {
7630 string base_IndexerName
= TypeManager
.IndexerPropertyName (InterfaceType
);
7631 if (base_IndexerName
!= Name
)
7632 ShortName
= base_IndexerName
;
7635 if (!Parent
.PartialContainer
.AddMember (this) ||
7636 !Parent
.PartialContainer
.AddMember (Get
) || !Parent
.PartialContainer
.AddMember (Set
))
7639 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
7641 if (!DefineAccessors ())
7648 // Now name the parameters
7650 PropertyBuilder
= Parent
.TypeBuilder
.DefineProperty (
7651 GetFullName (MemberName
), PropertyAttributes
.None
, MemberType
, parameters
.GetEmitTypes ());
7654 PropertyBuilder
.SetGetMethod (GetBuilder
);
7655 Parent
.MemberCache
.AddMember (GetBuilder
, Get
);
7659 PropertyBuilder
.SetSetMethod (SetBuilder
);
7660 Parent
.MemberCache
.AddMember (SetBuilder
, Set
);
7663 TypeManager
.RegisterIndexer (PropertyBuilder
, parameters
);
7664 Parent
.MemberCache
.AddMember (PropertyBuilder
, this);
7668 public override bool EnableOverloadChecks (MemberCore overload
)
7670 if (overload
is Indexer
) {
7671 caching_flags
|= Flags
.MethodOverloadsExist
;
7675 return base.EnableOverloadChecks (overload
);
7678 public override string GetDocCommentName (DeclSpace ds
)
7680 return DocUtil
.GetMethodDocCommentName (this, parameters
, ds
);
7683 public override string GetSignatureForError ()
7685 StringBuilder sb
= new StringBuilder (Parent
.GetSignatureForError ());
7686 if (MemberName
.Left
!= null) {
7688 sb
.Append (MemberName
.Left
.GetSignatureForError ());
7691 sb
.Append (".this");
7692 sb
.Append (parameters
.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
7693 return sb
.ToString ();
7696 protected override PropertyInfo
ResolveBaseProperty ()
7698 return Parent
.PartialContainer
.BaseCache
.FindMemberToOverride (
7699 Parent
.TypeBuilder
, Name
, parameters
, null, true) as PropertyInfo
;
7702 protected override bool VerifyClsCompliance ()
7704 if (!base.VerifyClsCompliance ())
7707 parameters
.VerifyClsCompliance ();
7712 public class Operator
: MethodOrOperator
{
7714 const int AllowedModifiers
=
7720 public enum OpType
: byte {
7730 // Unary and Binary operators
7753 // Implicit and Explicit
7757 // Just because of enum
7761 public readonly OpType OperatorType
;
7763 static readonly string [] [] names
;
7767 names
= new string[(int)OpType
.TOP
][];
7768 names
[(int) OpType
.LogicalNot
] = new string [] { "!", "op_LogicalNot" }
;
7769 names
[(int) OpType
.OnesComplement
] = new string [] { "~", "op_OnesComplement" }
;
7770 names
[(int) OpType
.Increment
] = new string [] { "++", "op_Increment" }
;
7771 names
[(int) OpType
.Decrement
] = new string [] { "--", "op_Decrement" }
;
7772 names
[(int) OpType
.True
] = new string [] { "true", "op_True" }
;
7773 names
[(int) OpType
.False
] = new string [] { "false", "op_False" }
;
7774 names
[(int) OpType
.Addition
] = new string [] { "+", "op_Addition" }
;
7775 names
[(int) OpType
.Subtraction
] = new string [] { "-", "op_Subtraction" }
;
7776 names
[(int) OpType
.UnaryPlus
] = new string [] { "+", "op_UnaryPlus" }
;
7777 names
[(int) OpType
.UnaryNegation
] = new string [] { "-", "op_UnaryNegation" }
;
7778 names
[(int) OpType
.Multiply
] = new string [] { "*", "op_Multiply" }
;
7779 names
[(int) OpType
.Division
] = new string [] { "/", "op_Division" }
;
7780 names
[(int) OpType
.Modulus
] = new string [] { "%", "op_Modulus" }
;
7781 names
[(int) OpType
.BitwiseAnd
] = new string [] { "&", "op_BitwiseAnd" }
;
7782 names
[(int) OpType
.BitwiseOr
] = new string [] { "|", "op_BitwiseOr" }
;
7783 names
[(int) OpType
.ExclusiveOr
] = new string [] { "^", "op_ExclusiveOr" }
;
7784 names
[(int) OpType
.LeftShift
] = new string [] { "<<", "op_LeftShift" }
;
7785 names
[(int) OpType
.RightShift
] = new string [] { ">>", "op_RightShift" }
;
7786 names
[(int) OpType
.Equality
] = new string [] { "==", "op_Equality" }
;
7787 names
[(int) OpType
.Inequality
] = new string [] { "!=", "op_Inequality" }
;
7788 names
[(int) OpType
.GreaterThan
] = new string [] { ">", "op_GreaterThan" }
;
7789 names
[(int) OpType
.LessThan
] = new string [] { "<", "op_LessThan" }
;
7790 names
[(int) OpType
.GreaterThanOrEqual
] = new string [] { ">=", "op_GreaterThanOrEqual" }
;
7791 names
[(int) OpType
.LessThanOrEqual
] = new string [] { "<=", "op_LessThanOrEqual" }
;
7792 names
[(int) OpType
.Implicit
] = new string [] { "implicit", "op_Implicit" }
;
7793 names
[(int) OpType
.Explicit
] = new string [] { "explicit", "op_Explicit" }
;
7796 public Operator (DeclSpace parent
, OpType type
, FullNamedExpression ret_type
,
7797 int mod_flags
, ParametersCompiled parameters
,
7798 ToplevelBlock block
, Attributes attrs
, Location loc
)
7799 : base (parent
, null, ret_type
, mod_flags
, AllowedModifiers
,
7800 new MemberName (GetMetadataName (type
), loc
), attrs
, parameters
)
7802 OperatorType
= type
;
7806 public override void ApplyAttributeBuilder (Attribute a
, CustomAttributeBuilder cb
, PredefinedAttributes pa
)
7808 if (a
.Type
== pa
.Conditional
) {
7809 Error_ConditionalAttributeIsNotValid ();
7813 base.ApplyAttributeBuilder (a
, cb
, pa
);
7816 public override bool Define ()
7818 const int RequiredModifiers
= Modifiers
.PUBLIC
| Modifiers
.STATIC
;
7819 if ((ModFlags
& RequiredModifiers
) != RequiredModifiers
){
7820 Report
.Error (558, Location
, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
7823 if (!base.Define ())
7826 // imlicit and explicit operator of same types are not allowed
7827 if (OperatorType
== OpType
.Explicit
)
7828 Parent
.MemberCache
.CheckExistingMembersOverloads (this, GetMetadataName (OpType
.Implicit
), Parameters
, Report
);
7829 else if (OperatorType
== OpType
.Implicit
)
7830 Parent
.MemberCache
.CheckExistingMembersOverloads (this, GetMetadataName (OpType
.Explicit
), Parameters
, Report
);
7832 Type declaring_type
= MethodData
.DeclaringType
;
7833 Type return_type
= MemberType
;
7834 Type first_arg_type
= ParameterTypes
[0];
7836 Type first_arg_type_unwrap
= first_arg_type
;
7837 if (TypeManager
.IsNullableType (first_arg_type
))
7838 first_arg_type_unwrap
= TypeManager
.TypeToCoreType (TypeManager
.GetTypeArguments (first_arg_type
) [0]);
7840 Type return_type_unwrap
= return_type
;
7841 if (TypeManager
.IsNullableType (return_type
))
7842 return_type_unwrap
= TypeManager
.TypeToCoreType (TypeManager
.GetTypeArguments (return_type
) [0]);
7844 if (TypeManager
.IsDynamicType (return_type
) || TypeManager
.IsDynamicType (first_arg_type
)) {
7845 Report
.Error (1964, Location
,
7846 "User-defined operator `{0}' cannot convert to or from the dynamic type",
7847 GetSignatureForError ());
7853 // Rules for conversion operators
7855 if (OperatorType
== OpType
.Implicit
|| OperatorType
== OpType
.Explicit
) {
7856 if (first_arg_type_unwrap
== return_type_unwrap
&& first_arg_type_unwrap
== declaring_type
){
7857 Report
.Error (555, Location
,
7858 "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
7863 if (TypeManager
.IsEqual (declaring_type
, return_type
) || declaring_type
== return_type_unwrap
) {
7864 conv_type
= first_arg_type
;
7865 } else if (TypeManager
.IsEqual (declaring_type
, first_arg_type
) || declaring_type
== first_arg_type_unwrap
) {
7866 conv_type
= return_type
;
7868 Report
.Error (556, Location
,
7869 "User-defined conversion must convert to or from the enclosing type");
7874 // Because IsInterface and IsClass are not supported
7876 if (!TypeManager
.IsGenericParameter (conv_type
)) {
7877 if (conv_type
.IsInterface
) {
7878 Report
.Error (552, Location
, "User-defined conversion `{0}' cannot convert to or from an interface type",
7879 GetSignatureForError ());
7883 if (conv_type
.IsClass
) {
7884 if (TypeManager
.IsSubclassOf (declaring_type
, conv_type
)) {
7885 Report
.Error (553, Location
, "User-defined conversion `{0}' cannot convert to or from a base class",
7886 GetSignatureForError ());
7890 if (TypeManager
.IsSubclassOf (conv_type
, declaring_type
)) {
7891 Report
.Error (554, Location
, "User-defined conversion `{0}' cannot convert to or from a derived class",
7892 GetSignatureForError ());
7897 } else if (OperatorType
== OpType
.LeftShift
|| OperatorType
== OpType
.RightShift
) {
7898 if (first_arg_type
!= declaring_type
|| Parameters
.Types
[1] != TypeManager
.int32_type
) {
7899 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");
7902 } else if (Parameters
.Count
== 1) {
7903 // Checks for Unary operators
7905 if (OperatorType
== OpType
.Increment
|| OperatorType
== OpType
.Decrement
) {
7906 if (return_type
!= declaring_type
&& !TypeManager
.IsSubclassOf (return_type
, declaring_type
)) {
7907 Report
.Error (448, Location
,
7908 "The return type for ++ or -- operator must be the containing type or derived from the containing type");
7911 if (first_arg_type
!= declaring_type
) {
7913 559, Location
, "The parameter type for ++ or -- operator must be the containing type");
7918 if (!TypeManager
.IsEqual (first_arg_type_unwrap
, declaring_type
)){
7919 Report
.Error (562, Location
,
7920 "The parameter type of a unary operator must be the containing type");
7924 if (OperatorType
== OpType
.True
|| OperatorType
== OpType
.False
) {
7925 if (return_type
!= TypeManager
.bool_type
){
7928 "The return type of operator True or False " +
7934 } else if (!TypeManager
.IsEqual (first_arg_type_unwrap
, declaring_type
)) {
7935 // Checks for Binary operators
7937 var second_arg_type
= ParameterTypes
[1];
7938 if (TypeManager
.IsNullableType (second_arg_type
))
7939 second_arg_type
= TypeManager
.TypeToCoreType (TypeManager
.GetTypeArguments (second_arg_type
) [0]);
7941 if (!TypeManager
.IsEqual (second_arg_type
, declaring_type
)) {
7942 Report
.Error (563, Location
,
7943 "One of the parameters of a binary operator must be the containing type");
7951 protected override bool ResolveMemberType ()
7953 if (!base.ResolveMemberType ())
7956 flags
|= MethodAttributes
.SpecialName
| MethodAttributes
.HideBySig
;
7960 // Operator cannot be override
7961 protected override MethodInfo
FindOutBaseMethod (ref Type base_ret_type
)
7966 public static string GetName (OpType ot
)
7968 return names
[(int) ot
] [0];
7971 public static string GetName (string metadata_name
)
7973 for (int i
= 0; i
< names
.Length
; ++i
) {
7974 if (names
[i
] [1] == metadata_name
)
7975 return names
[i
] [0];
7980 public static string GetMetadataName (OpType ot
)
7982 return names
[(int) ot
] [1];
7985 public static string GetMetadataName (string name
)
7987 for (int i
= 0; i
< names
.Length
; ++i
) {
7988 if (names
[i
] [0] == name
)
7989 return names
[i
] [1];
7994 public OpType
GetMatchingOperator ()
7996 switch (OperatorType
) {
7997 case OpType
.Equality
:
7998 return OpType
.Inequality
;
7999 case OpType
.Inequality
:
8000 return OpType
.Equality
;
8002 return OpType
.False
;
8005 case OpType
.GreaterThan
:
8006 return OpType
.LessThan
;
8007 case OpType
.LessThan
:
8008 return OpType
.GreaterThan
;
8009 case OpType
.GreaterThanOrEqual
:
8010 return OpType
.LessThanOrEqual
;
8011 case OpType
.LessThanOrEqual
:
8012 return OpType
.GreaterThanOrEqual
;
8018 public override string GetSignatureForError ()
8020 StringBuilder sb
= new StringBuilder ();
8021 if (OperatorType
== OpType
.Implicit
|| OperatorType
== OpType
.Explicit
) {
8022 sb
.AppendFormat ("{0}.{1} operator {2}",
8023 Parent
.GetSignatureForError (), GetName (OperatorType
), type_name
.GetSignatureForError ());
8026 sb
.AppendFormat ("{0}.operator {1}", Parent
.GetSignatureForError (), GetName (OperatorType
));
8029 sb
.Append (Parameters
.GetSignatureForError ());
8030 return sb
.ToString ();
8035 // This is used to compare method signatures
8037 struct MethodSignature
{
8039 public Type RetType
;
8040 public Type
[] Parameters
;
8043 /// This delegate is used to extract methods which have the
8044 /// same signature as the argument
8046 public static MemberFilter method_signature_filter
= new MemberFilter (MemberSignatureCompare
);
8048 public MethodSignature (string name
, Type ret_type
, Type
[] parameters
)
8053 if (parameters
== null)
8054 Parameters
= Type
.EmptyTypes
;
8056 Parameters
= parameters
;
8059 public override string ToString ()
8062 if (Parameters
.Length
!= 0){
8063 System
.Text
.StringBuilder sb
= new System
.Text
.StringBuilder ();
8064 for (int i
= 0; i
< Parameters
.Length
; i
++){
8065 sb
.Append (Parameters
[i
]);
8066 if (i
+1 < Parameters
.Length
)
8069 pars
= sb
.ToString ();
8072 return String
.Format ("{0} {1} ({2})", RetType
, Name
, pars
);
8075 public override int GetHashCode ()
8077 return Name
.GetHashCode ();
8080 public override bool Equals (Object o
)
8082 MethodSignature other
= (MethodSignature
) o
;
8084 if (other
.Name
!= Name
)
8087 if (other
.RetType
!= RetType
)
8090 if (Parameters
== null){
8091 if (other
.Parameters
== null)
8096 if (other
.Parameters
== null)
8099 int c
= Parameters
.Length
;
8100 if (other
.Parameters
.Length
!= c
)
8103 for (int i
= 0; i
< c
; i
++)
8104 if (other
.Parameters
[i
] != Parameters
[i
])
8110 static bool MemberSignatureCompare (MemberInfo m
, object filter_criteria
)
8112 MethodSignature sig
= (MethodSignature
) filter_criteria
;
8114 if (m
.Name
!= sig
.Name
)
8118 MethodInfo mi
= m
as MethodInfo
;
8119 PropertyInfo pi
= m
as PropertyInfo
;
8122 ReturnType
= mi
.ReturnType
;
8123 else if (pi
!= null)
8124 ReturnType
= pi
.PropertyType
;
8129 // we use sig.RetType == null to mean `do not check the
8130 // method return value.
8132 if (sig
.RetType
!= null) {
8133 if (!TypeManager
.IsEqual (ReturnType
, sig
.RetType
))
8139 args
= TypeManager
.GetParameterData (mi
).Types
;
8141 args
= TypeManager
.GetParameterData (pi
).Types
;
8142 Type
[] sigp
= sig
.Parameters
;
8144 if (args
.Length
!= sigp
.Length
)
8147 for (int i
= args
.Length
- 1; i
>= 0; i
--)
8148 if (!TypeManager
.IsEqual (args
[i
], sigp
[i
]))